Skip to content

Commit 0d4e0d5

Browse files
marioneblLinusU
authored andcommitted
refactor: remove gulp-git dependency (#256)
* gets rid of gulp dependency * gets rid of gulp-git dependency * solves gulp-related deprecation warnings * improves install times considerably * use child_process.exec for git commands
1 parent 9aeeddb commit 0d4e0d5

File tree

10 files changed

+106
-112
lines changed

10 files changed

+106
-112
lines changed

package.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,6 @@
7373
"find-node-modules": "1.0.3",
7474
"find-root": "1.0.0",
7575
"glob": "7.0.5",
76-
"gulp": "3.9.1",
77-
"gulp-git": "1.7.2",
7876
"home-or-tmp": "2.0.0",
7977
"inquirer": "1.1.2",
8078
"lodash": "4.14.1",

src/cli/strategies/git-cz.js

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,20 +47,31 @@ function gitCz(rawGitArgs, environment, adapterConfig) {
4747
let resolvedAdapterRootPath = findRoot(resolvedAdapterConfigPath);
4848
let prompter = getPrompter(adapterConfig.path);
4949

50-
isClean(process.cwd(), function(stagingIsClean){
50+
isClean(process.cwd(), function(error, stagingIsClean){
51+
if (error) {
52+
throw error;
53+
}
54+
5155
if(stagingIsClean) {
52-
console.error('Error: No files added to staging! Did you forget to run git add?')
53-
} else {
54-
// OH GOD IM SORRY FOR THIS SECTION
55-
let adapterPackageJson = getParsedPackageJsonFromPath(resolvedAdapterRootPath);
56-
let cliPackageJson = getParsedPackageJsonFromPath(environment.cliPath);
57-
console.log(`cz-cli@${cliPackageJson.version}, ${adapterPackageJson.name}@${adapterPackageJson.version}\n`);
58-
commit(sh, inquirer, process.cwd(), prompter, {args: parsedGitCzArgs, disableAppendPaths:true, emitData:true, quiet:false, retryLastCommit}, function() {
59-
// console.log('commit happened');
60-
});
61-
56+
throw new Error('No files added to staging! Did you forget to run git add?');
6257
}
58+
59+
// OH GOD IM SORRY FOR THIS SECTION
60+
let adapterPackageJson = getParsedPackageJsonFromPath(resolvedAdapterRootPath);
61+
let cliPackageJson = getParsedPackageJsonFromPath(environment.cliPath);
62+
console.log(`cz-cli@${cliPackageJson.version}, ${adapterPackageJson.name}@${adapterPackageJson.version}\n`);
63+
commit(sh, inquirer, process.cwd(), prompter, {
64+
args: parsedGitCzArgs,
65+
disableAppendPaths:true,
66+
emitData:true,
67+
quiet:false,
68+
retryLastCommit
69+
}, function(error) {
70+
if (error) {
71+
throw error;
72+
}
73+
// console.log('commit happened');
74+
});
6375
});
64-
6576

6677
}

src/cli/strategies/git.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ function git(rawGitArgs, environment) {
1616

1717
child.on('error', function (e, code) {
1818
console.error(e);
19+
throw e;
1920
});
2021
}
21-
}
22+
}

src/commitizen/adapter.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ function getPrompter(adapterPath) {
112112

113113
// Load the adapter
114114
let adapter = require(resolvedAdapterPath);
115-
115+
116116
if(adapter && adapter.prompter && isFunction(adapter.prompter)) {
117117
return adapter.prompter;
118118
} else {

src/commitizen/staging.js

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
1-
import git from 'gulp-git';
2-
import {isString} from '../common/util';
1+
import {exec} from 'child_process';
32

43
export {isClean};
54

65
/**
76
* Asynchrounously determines if the staging area is clean
87
*/
98
function isClean(repoPath, done) {
10-
git.exec({cwd:repoPath, args: '--no-pager diff --cached --name-only', quiet: true}, function (err, stdout) {
11-
let stagingIsClean;
12-
if(stdout && isString(stdout) && stdout.trim().length>0)
13-
{
14-
stagingIsClean = false;
15-
} else {
16-
stagingIsClean = true;
9+
exec('git diff --cached --name-only', {
10+
maxBuffer: Infinity,
11+
cwd: repoPath || process.cwd()
12+
}, function(error, stdout) {
13+
if (error) {
14+
return done(error);
1715
}
18-
done(stagingIsClean);
16+
let output = stdout || '';
17+
done(null, output.trim().length === 0);
1918
});
2019
}

src/git/commit.js

Lines changed: 27 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,38 @@
11
import os from 'os';
2-
import git from 'gulp-git';
3-
import gulp from 'gulp';
2+
import {exec} from 'child_process';
3+
44
import dedent from 'dedent';
55
import {isString} from '../common/util';
66

77
export { commit };
88

9+
function normalizeCommitMessage(message) {
10+
const signs = os.platform() === 'win32' ?
11+
/(")/g :
12+
/(["|`])/g;
13+
14+
return dedent(message)
15+
.replace(signs, '\\$1')
16+
.split(/\r?\n/)
17+
.map(line => `-m "${line}"`)
18+
.join(' ');
19+
}
20+
921
/**
1022
* Asynchronously git commit at a given path with a message
1123
*/
1224
function commit(sh, repoPath, message, options, done) {
25+
let args = options.args || '';
26+
let commitMessage = normalizeCommitMessage(message);
1327

14-
var alreadyEnded = false;
15-
let dedentedMessage = dedent(message);
16-
let escapedMessage = dedentedMessage.replace(/"/g, '\\"');
17-
let operatingSystemNormalizedMessage;
18-
// On windows we must use an array in gulp-git instead of a string because
19-
// command line parsing works differently
20-
if(os.platform()=="win32") {
21-
operatingSystemNormalizedMessage = escapedMessage.split(/\r?\n/);
22-
} else {
23-
operatingSystemNormalizedMessage = escapedMessage.replace(/`/g, '\\`');
24-
}
25-
26-
// Get a gulp stream based off the config
27-
gulp.src(repoPath)
28-
29-
// Format then commit
30-
.pipe(git.commit(operatingSystemNormalizedMessage, options))
31-
32-
// Write progress to the screen
33-
.on('data',function(data) {
34-
35-
// Ignore this for code coverage since it is only there
36-
// to make our testing suite pretty
37-
/* istanbul ignore if */
38-
if(!options.quiet) {
39-
if(isString(data))
40-
{
41-
process.stdout.write(data);
42-
}
43-
}
44-
})
45-
46-
// Handle commit success
47-
.on('end', function() {
48-
// TODO: Bug? Done is fired twice :(
49-
if(!alreadyEnded)
50-
{
51-
done();
52-
alreadyEnded=true;
53-
}
54-
})
55-
56-
// Handle commit failure
57-
.on('error', function (err) {
58-
console.error(err);
59-
done(err);
60-
});
61-
62-
}
28+
exec(`git commit ${commitMessage} ${args}`, {
29+
maxBuffer: Infinity,
30+
cwd: repoPath,
31+
stdio: options.quiet ? 'ignore' : 'inherit'
32+
}, function(error, stdout, stderror) {
33+
if (error) {
34+
return done(error);
35+
}
36+
done();
37+
});
38+
}

src/git/init.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ export { init };
55
*/
66
function init(sh, repoPath) {
77
sh.cd(repoPath);
8-
sh.exec('git init');
9-
}
8+
sh.exec('git init');
9+
}

src/git/log.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
1-
import git from 'gulp-git';
1+
import {exec} from 'child_process';
22

33
export { log };
44

55
/**
66
* Asynchronously gets the git log output
77
*/
88
function log(repoPath, done) {
9-
// Get a gulp stream based off the config
10-
git.exec({cwd: repoPath, args: 'log', quiet: true}, function(err, stdout) {
9+
exec('git log', {
10+
maxBuffer: Infinity,
11+
cwd: repoPath
12+
}, function(error, stdout, stderr) {
13+
if (error) {
14+
done();
15+
}
1116
done(stdout);
1217
});
13-
}
18+
}

test/tests/commit.js

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ describe('commit', function() {
6161

6262
// Quick setup the repos, adapter, and grab a simple prompter
6363
let prompter = quickPrompterSetup(sh, repoConfig, adapterConfig, dummyCommitMessage);
64-
// TEST
64+
// TEST
6565

6666
// Pass in inquirer but it never gets used since we've mocked out a different
6767
// version of prompter.
@@ -128,20 +128,20 @@ describe('commit', function() {
128128
// Don't trim or delete the spacing in this commit message!
129129

130130
// Git on *nix retains spaces on lines with only spaces
131-
// The blank line of this block should have 4 spaces.
132-
let nixCommitMessage =
131+
// The blank line of this block should have 4 spaces.
132+
let nixCommitMessage =
133133
`sip sip sippin on jnkjnkjn
134134
135135
some sizzurp`;
136136

137137
// Git on win32 removes spaces from lines with only spaces
138138
// The blank line of this block should have no spaces
139-
let windowsCommitMessage =
139+
let windowsCommitMessage =
140140
`sip sip sippin on jnkjnkjn
141141
142142
some sizzurp`;
143143

144-
let dummyCommitMessage = (os.platform == 'win32') ? windowsCommitMessage : nixCommitMessage;
144+
let dummyCommitMessage = (os.platform == 'win32') ? windowsCommitMessage : nixCommitMessage;
145145

146146
// Describe a repo and some files to add and commit
147147
let repoConfig = {
@@ -166,7 +166,7 @@ describe('commit', function() {
166166

167167
// Quick setup the repos, adapter, and grab a simple prompter
168168
let prompter = quickPrompterSetup(sh, repoConfig, adapterConfig, dummyCommitMessage);
169-
// TEST
169+
// TEST
170170

171171
// Pass in inquirer but it never gets used since we've mocked out a different
172172
// version of prompter.
@@ -179,7 +179,7 @@ describe('commit', function() {
179179

180180
});
181181

182-
it('should allow to override options passed to gulp-git', function(done) {
182+
it('should allow to override git commit options', function(done) {
183183

184184
this.timeout(config.maxTimeout); // this could take a while
185185

@@ -215,7 +215,7 @@ describe('commit', function() {
215215

216216
// Quick setup the repos, adapter, and grab a simple prompter
217217
let prompter = quickPrompterSetup(sh, repoConfig, adapterConfig, dummyCommitMessage, options);
218-
// TEST
218+
// TEST
219219

220220
// Pass in inquirer but it never gets used since we've mocked out a different
221221
// version of prompter.
@@ -234,13 +234,13 @@ describe('commit', function() {
234234
afterEach(function() {
235235
// All this should do is archive the tmp path to the artifacts
236236
clean.afterEach(sh, config.paths.tmp, config.preserve);
237-
});
237+
});
238238

239239
after(function() {
240-
// Once everything is done, the artifacts should be cleaned up based on
240+
// Once everything is done, the artifacts should be cleaned up based on
241241
// the preserve setting in the config
242242
clean.after(sh, config.paths.tmp, config.preserve);
243-
});
243+
});
244244

245245
/**
246246
* This is just a helper for testing. NOTE that prompter
@@ -267,5 +267,5 @@ function quickPrompterSetup(sh, repoConfig, adapterConfig, commitMessage, option
267267
// NOTE: In the real world we would not be returning
268268
// this we would instead be just making the commented
269269
// out getPrompter() call to get user input (above).
270-
return prompter;
271-
}
270+
return prompter;
271+
}

test/tests/staging.js

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -49,32 +49,36 @@ describe('staging', function() {
4949

5050
gitInit(sh, repoConfig.path);
5151

52-
staging.isClean(repoConfig.path, function(stagingIsClean) {
53-
54-
expect(stagingIsClean).to.be.true;
55-
56-
writeFilesToPath(repoConfig.files, repoConfig.path);
57-
58-
gitAdd(sh, repoConfig.path);
59-
60-
staging.isClean(repoConfig.path, function(afterWriteStagingIsClean) {
61-
expect(afterWriteStagingIsClean).to.be.false;
62-
done();
52+
staging.isClean('./@this-actually-does-not-exist', function(stagingError) {
53+
expect(stagingError).to.be.an.instanceof(Error);
54+
55+
staging.isClean(repoConfig.path, function(stagingIsCleanError, stagingIsClean) {
56+
expect(stagingIsCleanError).to.be.null;
57+
expect(stagingIsClean).to.be.true;
58+
59+
writeFilesToPath(repoConfig.files, repoConfig.path);
60+
61+
gitAdd(sh, repoConfig.path);
62+
63+
staging.isClean(repoConfig.path, function(afterWriteStagingIsCleanError, afterWriteStagingIsClean) {
64+
expect(afterWriteStagingIsCleanError).to.be.null;
65+
expect(afterWriteStagingIsClean).to.be.false;
66+
done();
67+
});
68+
6369
});
64-
6570
});
66-
6771
});
6872

6973
});
7074

7175
afterEach(function() {
7276
// All this should do is archive the tmp path to the artifacts
7377
clean.afterEach(sh, config.paths.tmp, config.preserve);
74-
});
78+
});
7579

7680
after(function() {
77-
// Once everything is done, the artifacts should be cleaned up based on
81+
// Once everything is done, the artifacts should be cleaned up based on
7882
// the preserve setting in the config
7983
clean.after(sh, config.paths.tmp, config.preserve);
80-
});
84+
});

0 commit comments

Comments
 (0)