Making a TIME Management Tool for the CLI (part 6)
This is the seventh day of my participation in the August More Text Challenge. For details, see “August More Text Challenge”.
preface
The previous article focused on generating report directives over a period of time:
timec -or --range <startTime>_<endTime> <filename1> <filename1> .....
Sometimes it is expected to directly export data for a day, month, or even a year, for which several date-related instructions will be extended
- One day,
timec -or --day [date]
- One month:
timec -or --month [month]
- The default value is this year
- One year:
timec -or --year [year]
- A month or a year:
timec -or -Y [year] -M [month]
--month
与--year
Use a combination of- Among them
-M
.-Y
These are abbreviations for the above two instructions
In addition to this section, this section will also move into a new chapter that begins the development of using instructions to manage tasks and transactions
This article will cover task-related instruction development: timec task [name]
This effect
The function development
This section will omit the five senses (which have appeared in previous articles)
Date-dependent instruction
Specific to day
The first is to designate a day:
- through
option
This parameter is optional - through
cmdObj
The day attribute of gets the value passed in by the user
.option('-D, --day [date]'.'One day')
// Omit the actions code
const { day } = cmdObj
Copy the code
Repackage the function that outputs the report:
- The parameters are
The start time
withThe end of time
- In this way, the remaining several optional parameter instructions can be directly reused
const output = (s, e) = > {
const outPutPath = getFilePath(cwd, `report-${outFileName}.md`)
const json = getJSONByRange(content, s, e)
if (json.length === 0) {
console.log('No eligible data');
return
}
const data = outPutReport(json)
createFile(outPutPath, data, false)
console.log('Export succeeded');
}
Copy the code
Check whether the date exists. If yes, the date is directly exported
- The start and end times are both incoming dates
if (day) {
return output(day, day)
}
Copy the code
Specific to the month
The usual rule is to register the instructions
.option('-M, --month [month]'.'One month')
Copy the code
If there are only months, the default year is this year, and the start and end time are respectively
nowYear-month-01
nowYear-month-days
How to quickly get the number of days in a month or year:
Date
The constructor supports overloading of functions that take the year, month, and day arguments- Which month is
We start at 0
: “1-12” corresponds to “0-11” respectively - When the parameter of the day part is passed in 0, it indicates the date of the last day of last month
- Call again at this point
getDate
Method, the number of days in the target month is obtained
For example, the number of days from 2021 to August:
New Date (2021,8,0)
- logo
In September 2021
The date of the day before commencement, i.eAugust 31, 2021
getDate
The returned result is31
const days = new Date(year,month,0).getDate()
Copy the code
The export logic is as follows:
- This year’s year is passed
new Date().getFullYear()
To obtain
if (month) {
const year = new Date().getFullYear()
return output(`${year}-${month}- 01 `.`${year}-${month}-The ${new Date(year, month, 0).getDate()}`)}Copy the code
Specific to the years
If it is a year, then the starting and ending times are:
year-01-01
year-12-31
There’s not much to say about this, just write it like you know it
.option('-Y, --year [year]'.'One year')
/ /... more code
if (year) {
return output(`${year}- 01-01 `.`${year}- 12-31 `)}Copy the code
Specific to certain year certain month
This is what happens when the -m and -y arguments are used together
Only need to do a combination of the above two export logic, logic is simple
if (year && month) {
return output(`${year}-${month}- 01 `.`${year}-${month}-The ${new Date(year, month, 0).getDate()}`)}Copy the code
A few date-related instructions are completed, and then the task related instructions begin
Task management command
The instruction format is as follows
timec task [name]
Copy the code
The name argument is optional and has the following logic:
- When name is empty, all tasks are displayed and tasks in progress are marked
- If the name does not exist, add it to the task list
- When the name exists, set it to the task in progress
With the logic clear, go to development
Initialize the configuration file
Create a.config/record.json file in the project root directory
/ Users/sugar/Documents/fe - project/time - control ├ ─ ─ bin ├ ─ ─ the SRC ├ ─ ─test├─── ├─ ├─ ch.htm.pdf.pdf.pdf.pdf.pdf.pdf.pdf.pdf.PDF.PDF.PDF.PDF.PDFCopy the code
The configuration file structure is as follows:
{
"recordFilepath": ""."tasks": []."defaultTaskIdx": - 1."thing": {
"name": ""."startTime": "2021-01-01"."endTime": "2021-12-31"."pauseTime": "2021-12-26"}}Copy the code
The tasks property, which records all tasks, and the defaultTaskIdx property, which records the tasks currently in progress, are mainly used here
Registration instructions
Use commander.command to register a command:
- Which USES
[]
Package parameter identifier This parameter is optional
/** * Create a task, switch tasks, and view the task list */
commander.command("task [name]")
.alias('t')
.description('check tasks/add task/checkout task')
.action((name) = > {
/ /... The following section describes code
})
Copy the code
Path of the configuration file
- through
__dirname
Locate the configuration file in a path relative to the configuration file
const configPath = path.join(__dirname, '.. /.config/record.json')
Copy the code
The JSON configuration file is imported through the require method
- The content introduced is just an object, and you don’t need to call it
JSON.parse
convert
const config = require(configPath)
Copy the code
Next comes the concrete business logic code
- First determine whether to pass in the task name
name
- If no, determine whether there is a task. If there is a task, print it in sequence. If there is no task, print the prompt information
- If the task name does not exist, it is added to the task list
tasks
- If yes, the task is set to an ongoing task, that is, update
defaultTaskIdx
The value of the
- If yes, the task is set to an ongoing task, that is, update
- The content of the configuration file is updated
const { tasks, defaultTaskIdx } = config
const idx = tasks.findIndex(v= > v === name)
if(! name){if(tasks.length===0) {console.log('no tasks, you can use command add task');
console.log('timec task [name]');
return
}
tasks.forEach((v,i) = >{
let mark = '[]'
if(i===+defaultTaskIdx){
mark = '[*]'
}
console.log(mark,v);
})
return
}
if (idx === -1) {
tasks.push(name)
if(tasks.length===1){
config.defaultTaskIdx = 0
}
console.log('add task success');
}else{
config.defaultTaskIdx = idx
console.log('now use task:',tasks[idx]);
}
writeFileSync(configPath,JSON.stringify(config))
Copy the code
This directive is developed, the time is short, the code quality may not be too high
TODO: Follow-up optimization
summary
So far the following directives have been supported:
These instructions are not the final version, because the time is too tight, the design time is also short, later will continue to improve
other
Because of the limited free time each day, this article will stop there
If you don’t have enough, stay tuned for updates, or keep an eye on the status of the warehouse
Welcome to comment section to raise demand, exchange discussion
This series will continue to be updated and iterated until the first generation of the product is completed
- The warehouse address