Running on *nix platforms
On a *nix platform npm utilizes sh
by default to execute the npm script(s). In this scenario you can simply use a shell function and reference the git message argument passed via the CLI using the $1
positional parameter.
Your npm script would be redefined like this:
"scripts": {
"build": "...",
"buildAndCommit": "func() { npm run build && git add . && git commit -m "BUILD - $1"; }; func"
}
Cross platform
Unfortunately, via Windows Powershell the solution is not quite as simple and terse.
When using Powershell npm utilizes cmd
by default to execute npm script(s). Likewise npm utilizes cmd
by default via other Windows consoles too, such as Command Prompt.
One way to achieve your requirement is to invoke a node.js via your npm script. The following provides two different methods that are essentially the same. Either will run successfully cross-platform (in your case via Powershell).
Method A - Using a separate node.js script
Create the following node.js script. Let's name the file script.js and save it in the root of the project directory, i.e. in the same directory where package.json resides.
script.js
const execSync = require('child_process').execSync;
const mssg = 'BUILD - ' + process.argv[2];
execSync('npm run build && git add . && git commit -m "' + mssg + '"', { stdio:[0, 1, 2] });
Explanation
The node.js builtin process.argv
captures the argument at index two, i.e. the git commit message, that was provided via the CLI. The git commit message is concatenated with with the substring BUILD -
to form the desired commit message. The resultant string is assigned to the variable mssg
.
We then utilize the node.js builtin execSync()
to execute your given npm script. As you can see, the value of the mssg
variable is used as the git commit message.
The stdio
option is utilized to ensure the correct configuration of the pipes, i.e. stdin
, stdout
, 'stderr', are established between the parent and child process.
Define your npm script named buildAndCommit
as follows:
package.json
"scripts": {
"build": "...",
"buildAndCommit": "node script"
}
Above node
invokes script.js
.
Method B - Inline the node.js script in npm script
Alternatively, the aforementioned node.js script (i.e. script.js) can be provided inline in your npm script instead - therefore negating the use of a separate .js
file.
package.json
"scripts": {
"build": "...",
"buildAndCommit": "node -e "const mssg = 'BUILD - ' + process.argv[1]; require('child_process').execSync('npm run build && git add . && git commit -m "' + mssg + '"', { stdio:[0, 1, 2] })""
}
This utilizes the same code from Method A albeit it slightly refactored. The notable differences are:
- The nodejs command line option
-e
is utilized to evaluate the inline JavaScript.
process.argv
this time will capture the argument, i.e. the git commit message, at index one in the array of arguments.
- Additional escaping of the double quotes is necessary, i.e.
"
Running the npm script
Using either Method A or Method B run the command via your CLI as desired: For instance:
$ npm run buildAndCommit -- "commit for a new build"
This will produce the following git commit message:
BUILD - commit for a new build
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…