Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass current datetime in npm script for git commit message in Windows and cross platform?

I am working in Windows 10 and trying to use npm script for git commit with message that includes date and time of the commit:

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

Resulting git commit message is

Release at $(date)

instead of

Release at 03/06/2019 11:43:57

that I get when running in terminal the same command:

git commit -m "Release at $(date)"

What is a cross platform solution ?

Can you explain what causes different results ?

like image 201
ChrisK Avatar asked Mar 06 '19 10:03

ChrisK


1 Answers

Cross-platform compatibility cannot be realized by utilizing the shell command date that is available on *nix platforms. This is because the Windows/cmd.exe DATE command behaves differently. The differences are:

  • The *nix date command prints the date/time.
  • The Windows/cmd.exe DATE command prompts the user to set the system date/time.

Also command substitution, i.e. the $(...) part is a bash feature found on most *nix shells - it will fail via Windows cmd.exe.

For a cross-platform solution (i.e. one that runs successfully on Windows, Linux, and macOS...), consider the following approach:

  • Utilize a nodejs script to shell-out your cd and git commands using the built-in execSync().
  • Obtain the date using the moment package, or alternatively using the JavaScript Date() object similar to this answer instead.
  • Invoke the nodejs script from the scripts section of your package.json

Solution:

There are a couple of different ways to approach this as described in the following two sub-sections titled:

  • Using an external nodejs (.js) file
  • Inlining your JavaScript in package.json.

Note: both approaches effectively yield the same desired result.

Using an external nodejs (.js) file

  1. The following utilizes moment for obtaining the date. To install that run the following command in your project directory:

    npm i -D moment
    
  2. Create a nodejs script as follows, let's name the file deploy.js and save it in the root of your project directory, i.e. in the same directory where package.json currently resides::

    deploy.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]} );
    
  3. In the scripts section of your package.json replace your current deploy script with the following:

    package.json

    "scripts": {
      "deploy": "node deploy"
    }
    
  4. Invoke the npm deploy script as per normal by running the following via your CLI:

    npm run deploy
    

Explanation:

  • In deploy.js we require the moment package and the nodejs built-in execSync().
  • To obtain the current date/time we invoke moment() and call its format() method to match your given formatting, i.e. MM/DD/YYYY HH:mm:ss.
  • We then shell-out your cd and gitcommands using execSync. A reference to the date/time is provided in the git message part using Template literals, i.e.${dateTime}
  • The options.stdio option configures the pipes between the parent and child process - [0, 1, 2] effectively inherit's stdin, stdout, and stderr.

Inlining your JavaScript in package.json.

Alternatively, you can inline your nodejs/JavaScript code in the scripts section of your package.json.

  1. In the scripts section of your package.json replace your current deploy script with the following instead:

    package.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]} );\""
    }
    

Explanation:

  • This is effectively the same as the aforementioned solution that utilized a separate .js file (albeit slightly refactored). The use of a separate nodejs script/file is now redundant.
  • The nodejs command line option -e is utilized to evaluate the inline JavaScript.
like image 161
RobC Avatar answered Oct 20 '22 04:10

RobC