Skip to content

Commit

Permalink
New: Support configuration with .gulp.* files (closes #69) (#90)
Browse files Browse the repository at this point in the history
Includes implementation for description configuration (closes #70)
  • Loading branch information
sttk authored and phated committed Dec 21, 2017
1 parent a77b353 commit 1d27f81
Show file tree
Hide file tree
Showing 44 changed files with 531 additions and 98 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,18 @@ You can find a list of supported languages at https://github.com/js-cli/js-inter

The CLI adds process.env.INIT_CWD which is the original cwd it was launched from.

## Configuration

Configuration is supported through the use of a `.gulp.*` file (e.g. `.gulp.json`, `.gulp.yml`). You can find a list of supported languages at https://github.com/js-cli/js-interpret.

Configuration from the home directory (`~`) and current working directory (`cwd`) are merged with `cwd` taking precedence.

Supported configurations properties:

| Property | Description |
|-------------|-------------|
| description | Top-level description of the project/gulpfile (Replaces "Tasks for ~/path/of/gulpfile.js") |

## Flags

gulp has very few flags to know about. All other flags are for tasks to use if needed.
Expand Down
23 changes: 23 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ var Liftoff = require('liftoff');
var tildify = require('tildify');
var interpret = require('interpret');
var v8flags = require('v8flags');
var merge = require('lodash.merge');
var isString = require('lodash.isstring');
var findRange = require('semver-greatest-satisfied-range');
var exit = require('./lib/shared/exit');
var cliOptions = require('./lib/shared/cliOptions');
Expand All @@ -34,6 +36,18 @@ var cli = new Liftoff({
completions: completion,
extensions: interpret.jsVariants,
v8flags: v8flags,
configFiles: {
'.gulp': {
home: {
path: '~',
extensions: interpret.extensions,
},
cwd: {
path: '.',
extensions: interpret.extensions,
},
},
},
});

var usage =
Expand Down Expand Up @@ -82,6 +96,15 @@ module.exports = run;

// The actual logic
function handleArguments(env) {

// Map an array of keys to preserve order
var configFilePaths = ['home', 'cwd'].map(function(key) {
return env.configFiles['.gulp'][key];
});
configFilePaths.filter(isString).forEach(function(filePath) {
merge(opts, require(filePath));
});

if (opts.help) {
console.log(parser.help());
exit(0);
Expand Down
7 changes: 6 additions & 1 deletion lib/versioned/^3.7.0/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ var chalk = require('chalk');
var log = require('gulplog');
var stdout = require('mute-stdout');
var tildify = require('tildify');
var isString = require('lodash.isstring');

var taskTree = require('./taskTree');
var logTasks = require('../../shared/log/tasks');
Expand Down Expand Up @@ -38,7 +39,11 @@ function execute(opts, env) {
}
if (opts.tasks) {
var tree = taskTree(gulpInst.tasks);
tree.label = 'Tasks for ' + chalk.magenta(tildify(env.configPath));
if (opts.description && isString(opts.description)) {
tree.label = opts.description;
} else {
tree.label = 'Tasks for ' + chalk.magenta(tildify(env.configPath));
}
return logTasks(tree, opts.depth, function(task) {
return gulpInst.tasks[task].fn;
});
Expand Down
12 changes: 8 additions & 4 deletions lib/versioned/^4.0.0-alpha.1/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ var log = require('gulplog');
var chalk = require('chalk');
var stdout = require('mute-stdout');
var tildify = require('tildify');
var isString = require('lodash.isstring');

var exit = require('../../shared/exit');

Expand Down Expand Up @@ -42,10 +43,13 @@ function execute(opts, env) {
return logTasksSimple(gulpInst.tree());
}
if (opts.tasks) {
var tree = {
label: 'Tasks for ' + chalk.magenta(tildify(env.configPath)),
nodes: gulpInst.tree({ deep: true }),
};
var tree = {};
if (opts.description && isString(opts.description)) {
tree.label = opts.description;
} else {
tree.label = 'Tasks for ' + chalk.magenta(tildify(env.configPath));
}
tree.nodes = gulpInst.tree({ deep: true });
return logTasks(tree, opts.depth, function(taskname) {
return gulpInst.task(taskname);
});
Expand Down
13 changes: 11 additions & 2 deletions lib/versioned/^4.0.0-alpha.2/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ var log = require('gulplog');
var chalk = require('chalk');
var stdout = require('mute-stdout');
var tildify = require('tildify');
var isString = require('lodash.isstring');

var exit = require('../../shared/exit');

Expand Down Expand Up @@ -48,13 +49,21 @@ function execute(opts, env) {
}
if (opts.tasks) {
tree = gulpInst.tree({ deep: true });
tree.label = 'Tasks for ' + chalk.magenta(tildify(env.configPath));
if (opts.description && isString(opts.description)) {
tree.label = opts.description;
} else {
tree.label = 'Tasks for ' + chalk.magenta(tildify(env.configPath));
}

return logTasks(tree, opts.depth, getTask(gulpInst));
}
if (opts.tasksJson) {
tree = gulpInst.tree({ deep: true });
tree.label = 'Tasks for ' + tildify(env.configPath);
if (opts.description && isString(opts.description)) {
tree.label = opts.description;
} else {
tree.label = 'Tasks for ' + tildify(env.configPath);
}

var output = JSON.stringify(tree);

Expand Down
13 changes: 11 additions & 2 deletions lib/versioned/^4.0.0/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ var log = require('gulplog');
var chalk = require('chalk');
var stdout = require('mute-stdout');
var tildify = require('tildify');
var isString = require('lodash.isstring');

var exit = require('../../shared/exit');

Expand Down Expand Up @@ -48,13 +49,21 @@ function execute(opts, env) {
}
if (opts.tasks) {
tree = gulpInst.tree({ deep: true });
tree.label = 'Tasks for ' + chalk.magenta(tildify(env.configPath));
if (opts.description && isString(opts.description)) {
tree.label = opts.description;
} else {
tree.label = 'Tasks for ' + chalk.magenta(tildify(env.configPath));
}

return logTasks(tree, opts.depth, getTask(gulpInst));
}
if (opts.tasksJson) {
tree = gulpInst.tree({ deep: true });
tree.label = 'Tasks for ' + tildify(env.configPath);
if (opts.description && isString(opts.description)) {
tree.label = opts.description;
} else {
tree.label = 'Tasks for ' + tildify(env.configPath);
}

var output = JSON.stringify(tree);

Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,11 @@
"fancy-log": "^1.1.0",
"gulplog": "^1.0.0",
"interpret": "^1.0.0",
"liftoff": "^2.1.0",
"liftoff": "^2.3.0",
"lodash.isfunction": "^3.0.8",
"lodash.isplainobject": "^4.0.4",
"lodash.isstring": "^4.0.1",
"lodash.merge": "^4.5.1",
"lodash.sortby": "^4.5.0",
"matchdep": "^1.0.0",
"mute-stdout": "^1.0.0",
Expand Down
67 changes: 67 additions & 0 deletions test/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
'use strict';

var lab = exports.lab = require('lab').script();
var expect = require('code').expect;
var path = require('path');
var fs = require('fs');

var skipLines = require('./tools/skip-lines');
var eraseTime = require('./tools/erase-time');
var runner = require('./tools/run-gulp');

var fixturesDir = path.join(__dirname, 'fixtures', 'config');
var expectedDir = path.join(__dirname, 'expected', 'config');

lab.experiment('gulp configuration', function() {

lab.test('Should configure with a .gulp.* file in cwd',
function(done) {
runner({ verbose: false })
.basedir(fixturesDir)
.chdir('foo/bar')
.gulp('--tasks')
.run(cb);

function cb(err, stdout) {
var expected = fs.readFileSync(path.join(expectedDir, 'output0.txt'),
'utf-8');
stdout = eraseTime(stdout);
expect(stdout).to.equal(expected);
done(err);
}
});

lab.test('Should configure with a .gulp.* file in cwd found up',
function(done) {
runner({ verbose: false })
.basedir(fixturesDir)
.chdir('foo/bar/baz')
.gulp('--tasks')
.run(cb);

function cb(err, stdout) {
var expected = fs.readFileSync(path.join(expectedDir, 'output0.txt'),
'utf-8');
stdout = eraseTime(skipLines(stdout, 1));
expect(stdout).to.equal(expected);
done(err);
}
});

lab.test('Should configure with a .gulp.* file in cwd by --cwd',
function(done) {
runner({ verbose: false })
.basedir(fixturesDir)
.chdir('qux')
.gulp('--tasks', '--gulpfile ../foo/bar/gulpfile.js', '--cwd .')
.run(cb);

function cb(err, stdout) {
var expected = fs.readFileSync(path.join(expectedDir, 'output1.txt'),
'utf-8');
stdout = eraseTime(stdout);
expect(stdout).to.equal(expected);
done(err);
}
});
});
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
gulp-cli/test
gulp-cli/test/fixtures
├─┬ default
│ └─┬ <series>
│ ├── task1
Expand Down
2 changes: 2 additions & 0 deletions test/expected/config/output0.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Description by .gulp.json in directory foo/bar
└── default
2 changes: 2 additions & 0 deletions test/expected/config/output1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
description by .gulp.js in directory qux
└── default
2 changes: 1 addition & 1 deletion test/expected/flags-tasks-json.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"label":"Tasks for {{path}}","nodes":[{"label":"test1","type":"task","nodes":[{"label":"<series>","type":"function","branch":true,"nodes":[{"label":"noop","type":"function","nodes":[]}]}]},{"label":"test2","type":"task","nodes":[{"label":"<series>","type":"function","branch":true,"nodes":[{"label":"test1","type":"task","nodes":[{"label":"<series>","type":"function","branch":true,"nodes":[{"label":"noop","type":"function","nodes":[]}]}]},{"label":"noop","type":"function","nodes":[]}]}]},{"label":"test3","type":"task","nodes":[{"label":"<series>","type":"function","branch":true,"nodes":[{"label":"described","type":"function","nodes":[]}]}]},{"label":"test4","type":"task","nodes":[{"label":"<series>","type":"function","branch":true,"nodes":[{"label":"errorFunction","type":"function","nodes":[]},{"label":"anon","type":"function","nodes":[]}]}]},{"label":"default","type":"task","nodes":[{"label":"<series>","type":"function","branch":true,"nodes":[{"label":"test1","type":"task","nodes":[{"label":"<series>","type":"function","branch":true,"nodes":[{"label":"noop","type":"function","nodes":[]}]}]},{"label":"test3","type":"task","nodes":[{"label":"<series>","type":"function","branch":true,"nodes":[{"label":"described","type":"function","nodes":[]}]}]},{"label":"noop","type":"function","nodes":[]}]}]}]}
{"label":"gulp-cli/test/fixtures/gulpfiles","nodes":[{"label":"test1","type":"task","nodes":[{"label":"<series>","type":"function","branch":true,"nodes":[{"label":"noop","type":"function","nodes":[]}]}]},{"label":"test2","type":"task","nodes":[{"label":"<series>","type":"function","branch":true,"nodes":[{"label":"test1","type":"task","nodes":[{"label":"<series>","type":"function","branch":true,"nodes":[{"label":"noop","type":"function","nodes":[]}]}]},{"label":"noop","type":"function","nodes":[]}]}]},{"label":"test3","type":"task","nodes":[{"label":"<series>","type":"function","branch":true,"nodes":[{"label":"described","type":"function","nodes":[]}]}]},{"label":"test4","type":"task","nodes":[{"label":"<series>","type":"function","branch":true,"nodes":[{"label":"errorFunction","type":"function","nodes":[]},{"label":"anon","type":"function","nodes":[]}]}]},{"label":"default","type":"task","nodes":[{"label":"<series>","type":"function","branch":true,"nodes":[{"label":"test1","type":"task","nodes":[{"label":"<series>","type":"function","branch":true,"nodes":[{"label":"noop","type":"function","nodes":[]}]}]},{"label":"test3","type":"task","nodes":[{"label":"<series>","type":"function","branch":true,"nodes":[{"label":"described","type":"function","nodes":[]}]}]},{"label":"noop","type":"function","nodes":[]}]}]}]}
2 changes: 1 addition & 1 deletion test/expected/flags-tasks.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
gulp-cli/test
gulp-cli/test/fixtures/gulpfiles
├─┬ default
│ └─┬ <series>
│ ├─┬ test1
Expand Down
2 changes: 1 addition & 1 deletion test/expected/tasks-as-exports.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
gulp-cli/test
gulp-cli/test/fixtures/gulpfiles
├── build
├── clean
└─┬ dist
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
gulp-cli/test
gulp-cli/test/fixtures
├─┬ build Build all the things!
│ │ --dev …un-minified
│ │ --production …compressed into single bundle
Expand Down
29 changes: 17 additions & 12 deletions test/exports-as-tasks.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,31 @@
'use strict';

var lab = exports.lab = require('lab').script();
var code = require('code');
var expect = require('code').expect;
var fs = require('fs');
var child = require('child_process');
var path = require('path');
var skipLines = require('./tools/skip-lines');
var eraseTime = require('./tools/erase-time');
var runner = require('./tools/run-gulp');

var output = fs.readFileSync(__dirname + '/expected/tasks-as-exports.txt', 'utf8').replace(/(\r\n|\n|\r)/gm,'\n');
var expectedDir = path.join(__dirname, 'expected');

// Long timeout is required because parse time is slow
lab.experiment('exports as tasks', { timeout: 0 }, function() {

lab.test('prints the task list', function(done) {
runner({ verbose: false })
.gulp('--tasks',
'--gulpfile ./fixtures/gulpfiles/gulpfile-exports.babel.js')
.run(cb);

child.exec('node ' + __dirname + '/../bin/gulp.js --tasks --gulpfile "./test/fixtures/gulpfile-exports.babel.js"', function(err, stdout) {
code.expect(stdout).to.contain('Tasks for');
stdout = stdout.replace(/\\/g, '/').split('Tasks for')[1].split('\n');
var outputArray = output.split('\n');
for (var i = 0; i < stdout.length; i++) {
code.expect(stdout[i]).to.contain(outputArray[i]);
}
done(err);
});
function cb(err, stdout) {
var filepath = path.join(expectedDir, 'tasks-as-exports.txt');
var expected = fs.readFileSync(filepath, 'utf-8');
stdout = eraseTime(skipLines(stdout, 2));
expect(stdout).to.equal(expected);
done();
}
});

});
3 changes: 3 additions & 0 deletions test/fixtures/.gulp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"description" : "gulp-cli/test/fixtures"
}
3 changes: 3 additions & 0 deletions test/fixtures/config/foo/bar/.gulp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"description": "Description by .gulp.json in directory foo/bar"
}
3 changes: 3 additions & 0 deletions test/fixtures/config/foo/bar/baz/.gulp.babel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// jscs:disable

exports.description = 'DESCRIPTION BY .gulp.babel.js in directory foo/bar/baz'
7 changes: 7 additions & 0 deletions test/fixtures/config/foo/bar/gulpfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
'use strict';

var gulp = require('gulp');

gulp.task('default', function(done) {
done();
});
5 changes: 5 additions & 0 deletions test/fixtures/config/qux/.gulp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
'use strict';

module.exports = {
description: 'description by .gulp.js in directory qux',
};
3 changes: 3 additions & 0 deletions test/fixtures/gulpfiles/.gulp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"description" : "gulp-cli/test/fixtures/gulpfiles"
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions test/flags-continue.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ var child = require('child_process');
lab.experiment('flag: --continue', function() {

lab.test('continues execution when flag is set', function(done) {
child.exec('node ' + __dirname + '/../bin/gulp.js test4 --continue --cwd ./test/fixtures', function(err, stdout, stderr) {
child.exec('node ' + __dirname + '/../bin/gulp.js test4 --continue --cwd ./test/fixtures/gulpfiles', function(err, stdout, stderr) {
code.expect(stdout).to.contain('Starting \'errorFunction\'');
code.expect(stderr).to.contain('\'errorFunction\' errored after');
stdout = stdout.replace(/\\/g, '/').split('\n');
Expand All @@ -19,7 +19,7 @@ lab.experiment('flag: --continue', function() {
});

lab.test('stops execution when flag is not set', function(done) {
child.exec('node ' + __dirname + '/../bin/gulp.js test4 --cwd ./test/fixtures', function(err, stdout, stderr) {
child.exec('node ' + __dirname + '/../bin/gulp.js test4 --cwd ./test/fixtures/gulpfiles', function(err, stdout, stderr) {
code.expect(stdout).to.contain('Starting \'errorFunction\'');
code.expect(stderr).to.contain('\'errorFunction\' errored after');
code.expect(stdout[4]).to.not.contain('Starting \'anon\'');
Expand Down
4 changes: 2 additions & 2 deletions test/flags-gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ var child = require('child_process');
lab.experiment('flag: --gulpfile', function() {

lab.test('Manually set path of gulpfile', function(done) {
child.exec('node ' + __dirname + '/../bin/gulp.js --gulpfile "./test/fixtures/gulpfile-2.js"', function(err, stdout) {
child.exec('node ' + __dirname + '/../bin/gulp.js --gulpfile "./test/fixtures/gulpfiles/gulpfile-2.js"', function(err, stdout) {
stdout = stdout.replace(/\\/g, '/').split('\n');
code.expect(stdout[1]).to.contain('test/fixtures/gulpfile-2.js');
code.expect(stdout[1]).to.contain('test/fixtures/gulpfiles/gulpfile-2.js');
code.expect(stdout[5]).to.contain('Finished \'default\'');
done(err);
});
Expand Down
Loading

0 comments on commit 1d27f81

Please sign in to comment.