如何在 Windows 和跨平台中为 git commit 消息在 npm 脚本中传递当前日期时间?

Chr*_*isK 5 windows git terminal cross-platform npm-scripts

我在 Windows 10 中工作,并尝试使用 npm 脚本进行 git commit,其中包含包含提交日期和时间的消息:

"deploy": "cd dist && git add . && git commit -m \"Release at $(date)\" && git push"
Run Code Online (Sandbox Code Playgroud)

结果 git commit 消息是

在 $(date) 发布

代替

于 03/06/2019 11:43:57 发布

我在终端中运行相同的命令时得到:

git commit -m "Release at $(date)"
Run Code Online (Sandbox Code Playgroud)

什么是跨平台解决方案?

你能解释导致不同结果的原因吗?

Rob*_*obC 6

使用*nix平台date上可用 的shell 命令无法实现跨平台兼容性。这是因为 Windows/ cmd.exe命令的行为不同。区别在于: DATE

  • *nixdate命令打印日期/时间。
  • Windows/ cmd.exe DATE命令提示用户设置系统日期/时间。

还有命令替换,即该$(...)部分是大多数 *nix shell 上的 bash 功能 - 它会通过 Windows cmd.exe失败。

对于跨平台解决方案(即在 Windows、Linux 和 macOS 上成功运行的解决方案...),请考虑以下方法:

  • 利用脚本的NodeJS到壳出cdgit使用内置命令execSync()
  • 使用moment包获取日期,或者使用Date()类似于此答案的 JavaScript对象。
  • package.jsonscripts部分调用 nodejs 脚本

解决方案:

如以下两个小节所述,有几种不同的方法可以解决这个问题:

  • 使用外部 nodejs (.js) 文件
  • package.json 中内联你的 JavaScript 。

注意:两种方法都有效地产生了相同的预期结果。

使用外部 nodejs (.js) 文件

  1. 以下moment用于获取日期。要安装它,请在您的项目目录中运行以下命令:

    npm i -D moment
    
    Run Code Online (Sandbox Code Playgroud)
  2. 如下创建一个nodejs脚本,让我们将文件命名为deploy.js并将其保存在您项目目录的根目录下,即package.json当前所在的目录中:

    部署.js

    const moment = require('moment');
    const execSync = require('child_process').execSync;
    
    const dateTime = moment().format('MM/DD/YYYY HH:mm:ss');
    
    execSync(`cd dist && git add . && git commit -m \"Release at ${dateTime}\" && git push`, { stdio: [0, 1, 2]} );
    
    Run Code Online (Sandbox Code Playgroud)
  3. package.jsonscripts部分中,将当前脚本替换为以下内容:deploy

    包.json

    "scripts": {
      "deploy": "node deploy"
    }
    
    Run Code Online (Sandbox Code Playgroud)
  4. deploy通过 CLI 运行以下命令,按正常方式调用 npm脚本:

    npm run deploy
    
    Run Code Online (Sandbox Code Playgroud)

解释:

  • deploy.js 中,我们需要moment包和内置的 nodejs execSync()
  • 要获取当前日期/时间,我们调用moment()并调用其format()方法以匹配您给定的格式,即MM/DD/YYYY HH:mm:ss.
  • 然后,我们壳出cdgit命令中使用execSyncgit使用模板文字在消息部分中提供了对日期/时间的引用,即${dateTime}
  • options.stdio选项配置父子进程之间的管道-[0, 1, 2]有效继承的stdinstdoutstderr

在 package.json 中内联您的 JavaScript。

或者,您可以在package.jsonscripts部分内联您的 nodejs/JavaScript 代码。

  1. package.json的脚本部分,将当前deploy脚本替换为以下内容:

    包.json

    "scripts": {
      "deploy": "node -e \"const dateTime = require('moment')().format('MM/DD/YYYY HH:mm:ss'); require('child_process').execSync(`cd dist && git add . && git commit -m \"Release at ${dateTime}\" && git push`, { stdio: [0, 1, 2]} );\""
    }
    
    Run Code Online (Sandbox Code Playgroud)

解释:

  • 这实际上与上述使用单独.js文件的解决方案相同(尽管稍微重构)。使用单独的 nodejs 脚本/文件现在是多余的。
  • nodejs 命令行选项-e用于评估内联 JavaScript。