Skip to content

Commit c86c25f

Browse files
committed
WIP: working on any conditional command
1 parent 40678de commit c86c25f

File tree

7 files changed

+180
-9
lines changed

7 files changed

+180
-9
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,38 @@
11
exports['commit-message-install getJsonBlock finds single json block 1'] = {
22
"foo": "bar"
33
}
4+
5+
exports['commit-message-install getCommand returns original command from array 1'] = {
6+
"args": [
7+
"echo",
8+
"foo",
9+
"bar"
10+
],
11+
"command": "echo foo bar"
12+
}
13+
14+
exports['commit-message-install getCommand removes -f and its argument 1'] = {
15+
"args": [
16+
"-f",
17+
"file.txt",
18+
"echo",
19+
"foo",
20+
"bar"
21+
],
22+
"command": "echo foo bar"
23+
}
24+
25+
exports['commit-message-install getCommand removes --file and its argument 1'] = {
26+
"args": [
27+
"--file",
28+
"file.txt",
29+
"echo",
30+
"foo",
31+
"bar"
32+
],
33+
"command": "echo foo bar"
34+
}
35+
36+
exports['commit-message-install getJsonBlock returns first found json block 1'] = {
37+
"foo": "bar"
38+
}

bin/commit-message-install.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,7 @@ start.then(getJsonBlock).then(json => {
2121
if (!json) {
2222
return
2323
}
24-
if (json) {
25-
console.log('got json block from the git commit message')
26-
console.log(JSON.stringify(json, null, 2))
27-
return npmInstall(json)
28-
}
24+
console.log('got json block from the git commit message')
25+
console.log(JSON.stringify(json, null, 2))
26+
return npmInstall(json)
2927
}, console.error)

bin/commit-message-run.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#!/usr/bin/env node
2+
3+
// runs any command if commit message
4+
// a: does not contain JSON
5+
// b: JSON does not specify a platform that disallows it
6+
// for example if commit message has
7+
// {"platform": "win32"}
8+
// and CI command has
9+
// run-if echo "I am running on Windows"
10+
// then Windows CI will show the message, and other CIs
11+
// will skip it
12+
13+
const debug = require('debug')('commit-message-install')
14+
15+
const allArgs = process.argv.slice(2)
16+
const args = require('minimist')(allArgs, {
17+
alias: {
18+
file: 'f'
19+
},
20+
string: 'file'
21+
})
22+
const { getMessage, getCommand, getJsonBlock, runIf } = require('..')
23+
24+
const actualCommand = getCommand(allArgs)
25+
debug('command to run:', actualCommand)
26+
27+
let start
28+
if (args.file) {
29+
console.log('loading message from file', args.file)
30+
const fs = require('fs')
31+
const message = fs.readFileSync(args.file, 'utf8')
32+
start = Promise.resolve(message)
33+
} else {
34+
start = getMessage().then(x => x.body)
35+
}
36+
start.then(getJsonBlock).then(json => {
37+
if (!json) {
38+
return runIf(actualCommand)
39+
}
40+
console.log('got json block from the git commit message')
41+
console.log(JSON.stringify(json, null, 2))
42+
return runIf(actualCommand, json)
43+
}, console.error)

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"bugs": "https://github.com/bahmutov/commit-message-install/issues",
77
"bin": {
88
"commit-message-install": "bin/commit-message-install.js",
9-
"cmi": "bin/commit-message-install.js"
9+
"cmi": "bin/commit-message-install.js",
10+
"run-if": "bin/commit-message-run.js"
1011
},
1112
"config": {
1213
"pre-git": {
@@ -67,7 +68,8 @@
6768
"size": "t=\"$(npm pack .)\"; wc -c \"${t}\"; tar tvf \"${t}\"; rm \"${t}\";",
6869
"test": "npm run unit",
6970
"unit": "mocha src/*-spec.js",
70-
"semantic-release": "semantic-release pre && npm publish && semantic-release post"
71+
"semantic-release": "semantic-release pre && npm publish && semantic-release post",
72+
"demo": "node bin/commit-message-run.js -f test/run-if.txt echo Foo is \\$FOO"
7173
},
7274
"release": {
7375
"analyzeCommits": "simple-commit-message",

src/commit-message-install-spec.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,32 @@ describe('commit-message-install', () => {
2121
})
2222
})
2323

24+
context('getCommand', () => {
25+
const { getCommand } = require('.')
26+
27+
it('is a function', () => {
28+
la(is.fn(getCommand))
29+
})
30+
31+
it('returns original command from array', () => {
32+
const args = ['echo', 'foo', 'bar']
33+
const command = getCommand(args)
34+
snapshot({ args, command })
35+
})
36+
37+
it('removes -f and its argument', () => {
38+
const args = ['-f', 'file.txt', 'echo', 'foo', 'bar']
39+
const command = getCommand(args)
40+
snapshot({ args, command })
41+
})
42+
43+
it('removes --file and its argument', () => {
44+
const args = ['--file', 'file.txt', 'echo', 'foo', 'bar']
45+
const command = getCommand(args)
46+
snapshot({ args, command })
47+
})
48+
})
49+
2450
context('getJsonBlock', () => {
2551
it('is a function', () => {
2652
la(is.fn(getJsonBlock))
@@ -41,6 +67,26 @@ describe('commit-message-install', () => {
4167
snapshot(result)
4268
})
4369

70+
it('returns first found json block', () => {
71+
const message = stripIndent`
72+
some text
73+
\`\`\`json
74+
{
75+
"foo": "bar"
76+
}
77+
\`\`\`
78+
then second block
79+
\`\`\`json
80+
{
81+
"no": false
82+
}
83+
\`\`\`
84+
`
85+
const result = getJsonBlock(message)
86+
la(is.object(result), 'result should be an object', result)
87+
snapshot(result)
88+
})
89+
4490
it('ignores just the text', () => {
4591
const message = stripIndent`
4692
some text

src/index.js

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ const is = require('check-more-types')
77
const os = require('os')
88
const execa = require('execa')
99

10+
const prop = name => object => object[name]
11+
1012
function getMessage () {
1113
return ggit.lastCommitId().then(ggit.commitMessage)
1214
}
@@ -68,11 +70,36 @@ const isNpmInstall = is.schema({
6870
packages: is.unemptyString
6971
})
7072

73+
const isRunIf = is.schema({
74+
platform: is.maybe.unemptyString,
75+
env: is.maybe.object
76+
})
77+
7178
function isPlatformAllowed (platform) {
7279
la(is.unemptyString(platform), 'invalid allowed platform', platform)
7380
return platform === '*' || platform.indexOf(os.platform()) !== -1
7481
}
7582

83+
function getCommand (args) {
84+
la(is.array(args), 'expected arguments', args)
85+
const cloned = [...args]
86+
const flags = ['-f', '--file']
87+
if (flags.includes(cloned[0])) {
88+
debug('found flag', cloned[0])
89+
cloned.shift()
90+
cloned.shift()
91+
}
92+
const command = cloned.join(' ')
93+
debug('found command', command)
94+
return command
95+
}
96+
97+
function runIf (command, json) {
98+
la(is.unemptyString(command), 'missing command to run', command)
99+
la(isRunIf(json), 'invalid runIf json', json)
100+
return execa.shell(command, { env: json.env }).then(prop('stdout'))
101+
}
102+
76103
function npmInstall (json) {
77104
if (!json) {
78105
debug('missing json for npm install')
@@ -100,7 +127,14 @@ function npmInstall (json) {
100127
return execa('npm', ['install', json.packages], {
101128
env,
102129
stdio: 'inherit'
103-
}).then(x => x.stdout)
130+
}).then(prop('stdout'))
104131
}
105132

106-
module.exports = { getMessage, isPlatformAllowed, getJsonBlock, npmInstall }
133+
module.exports = {
134+
getMessage,
135+
getCommand,
136+
runIf,
137+
isPlatformAllowed,
138+
getJsonBlock,
139+
npmInstall
140+
}

test/run-if.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
this is a test message
2+
used to simulate commit message
3+
4+
```json
5+
{
6+
"platform": "*",
7+
"env": {
8+
"FOO": "bar"
9+
}
10+
}
11+
```
12+
13+
some other text

0 commit comments

Comments
 (0)