做一个CLI版的时间管理工具(六)

简介: 做一个CLI版的时间管理工具(六)

前言


上一篇文章主要阐述了生成一段时间内的报告指令:


  • timec -or --range <startTime>_<endTime> <filename1> <filename1> .....


有时候期望直接导出的某一天,某一月,甚至某一年的数据,为此将会拓展几个日期相关的指令


  • 某一天:timec -or --day [date]
  • 某一月:timec -or --month [month]
  • 将默认为今年
  • 某一年:timec -or --year [year]
  • 某年某月:timec -or -Y [year] -M [month]
  • --month--year组合使用
  • 其中-M-Y分别是上述两个指令的缩写

除了这部分内容,本节也将会进入新的篇章,开始开发使用指令管理任务与事务

本文将会涉及任务相关的指令开发:timec task [name]


本期效果


网络异常,图片无法展示
|


功能开发


本部分将会省略五官代码(前几篇文章已出现过)


日期相关指令

具体到天


首先是指定到某一天:

  • 通过option注册可选参数
  • 通过cmdObj的day属性拿到用户传入的值


.option('-D, --day [date]', 'One day')
// 省略actions code
const { day } = cmdObj


对输出报告的函数进行改造封装:


  • 参数分别是开始时间结束时间
  • 这样其余几个可选参数指令也可直接复用


const output = (s, e) => {
  const outPutPath = getFilePath(cwd, `report-${outFileName}.md`)
  const json = getJSONByRange(content, s, e)
  if (json.length === 0) {
      console.log('没有符合条件的数据');
      return
  }
  const data = outPutReport(json)
  createFile(outPutPath, data, false)
  console.log(`导出成功`);
}


判断日期是否存在,存在则直接导出


  • 开始与结束时间都是传入的日期


if (day) {
    return output(day, day)
}


具体到月


老规矩先注册相关指令


.option('-M, --month [month]', 'One month')


如果只有月,那么默认年就是今年,起止时间分别是


  • nowYear-month-01
  • nowYear-month-days


插播一条技巧:如何快速获取某年某月的天数:


  1. Date构造函数支持传入年,月,日三个参数的函数重载
  2. 其中月是从0开始计算:"1-12"分别对应"0-11"
  3. 当日部分的参数传入0时,表示上月最后一天的日期
  4. 此时再调用getDate方法获取日期,则获取到目标月份的天数


例如:2021-08月的天数:


  • new Date(2021,8,0)
  • 标识2021年9月开始的前一天日期,即2021年8月31日
  • getDate返回结果即为31


const days = new Date(year,month,0).getDate()


导出逻辑如下:


  • 今年的年份通过new Date().getFullYear()获取


if (month) {
    const year = new Date().getFullYear()
    return output(`${year}-${month}-01`, `${year}-${month}-${new Date(year, month, 0).getDate()}`)
}


具体到年


如果是年,那么起止时间分别就是:


  • year-01-01
  • year-12-31


这个没得太多说法,轻车熟路写好


.option('-Y, --year [year]', 'One year')
// ...more code
if (year) {
    return output(`${year}-01-01`, `${year}-12-31`)
}


具体到某年某月


这个就是-M与-Y参数组合使用时的场景


只需要将上述两种导出方式的逻辑做一个合并即可,逻辑简单


if (year && month) {
    return output(`${year}-${month}-01`, `${year}-${month}-${new Date(year, month, 0).getDate()}`)
}


几个日期相关的指令搞完,接着就开始整任务相关的指令


任务管理指令


指令格式如下


timec task [name]


name参数是可选的,有如下几种逻辑:


  • 当name为空时,展示所有的任务,并标记正在进行中的任务
  • 当name不存在时,将其添加进任务列表
  • 当name存在时,将其设置为正在进行中的任务


理清逻辑后,进入开发


初始化配置文件


在项目工程的根目录创建一个.config/record.json文件


/Users/sugar/Documents/fe-project/time-control
├── bin
├── src
├── test
├── .config
├────└──record.json
└── test2.md


配置文件结构如下:


{
    "recordFilepath": "",
    "tasks": [],
    "defaultTaskIdx": -1,
    "thing": {
        "name": "",
        "startTime": "2021-01-01",
        "endTime": "2021-12-31",
        "pauseTime": "2021-12-26"
    }
}


这里将主要用到tasksdefaultTaskIdx两个属性,前者记录所有的任务,后者记录当前正在进行的任务


注册指令


使用commander.command注册指令:


  • 其中使用[]包裹的参数标识可选参数


/**
 * 创建任务、切换任务、查看任务列表
 */
commander.command("task [name]")
    .alias('t')
    .description('check tasks/add task/checkout task')
    .action((name) => {
        // ...code 后文介绍
    })


配置文件的路径


  • 通过__dirname与配置文件的相对路径定位配置文件


const configPath = path.join(__dirname, '../.config/record.json')


通过require方法引入json配置文件


  • 引入的内容就是一个对象,无需调用JSON.parse进行转换


const config = require(configPath)


下面就到具体的业务逻辑代码

  • 先判断是否传入任务名name
  • 没有,判断是否有任务,有则顺序打印,无则打印提示信息
  • 如果任务名不存在,则加入任务列表tasks
  • 存在,则将这个任务设置为正在进行的任务,即更新defaultTaskIdx的值
  • 最后更新配置文件的内容


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))


这个指令就开发完了,时间仓促,代码质量可能不会太高


TODO:后续优化


小结


到目前为止已经支持如下指令:


网络异常,图片无法展示
|


这些指令都还不是最终版本,由于时间太紧凑,设计时间也较短,后期会不断完善


其它


由于每天空闲时间有限,本文就先到这


如果读者还感觉意犹未尽,敬请期待后续更新,或持续关注一下仓库的状态


欢迎评论区提需求,交流探讨


本系列会不断的更新迭代,直至产品初代完成


相关文章
|
4天前
|
JavaScript 前端开发 数据安全/隐私保护
NodeJS 下构建 命令行工具(CLI) 与 交互式命令界面 的实践
NodeJS 下构建 命令行工具(CLI) 与 交互式命令界面 的实践
248 1
|
缓存 资源调度 前端开发
📒十分钟快速入门Yarn包管理工具
📒十分钟快速入门Yarn包管理工具
219 4
📒十分钟快速入门Yarn包管理工具
|
开发者 Python
发布CLI|学习笔记
快速学习发布CLI
发布CLI|学习笔记
|
Python
使用CLI工具
使用CLI工具
123 0
|
JSON 数据格式
做一个CLI版的时间管理工具(四)
做一个CLI版的时间管理工具(四)
|
数据可视化 JavaScript Shell
做一个CLI版的时间管理工具(12)
做一个CLI版的时间管理工具(12)
|
JavaScript 计算机视觉
做一个CLI版的时间管理工具(11)
做一个CLI版的时间管理工具(11)
|
JSON 数据格式
做一个CLI版的时间管理工具(三)
做一个CLI版的时间管理工具(三)
|
JSON 数据可视化 数据格式
做一个CLI版的时间管理工具(14)
做一个CLI版的时间管理工具(14)