Skip to content

Commit

Permalink
Recreate for issue gulpjs#92.
Browse files Browse the repository at this point in the history
  • Loading branch information
sttk committed Oct 10, 2016
1 parent 9b053ed commit 92a9107
Show file tree
Hide file tree
Showing 28 changed files with 1,524 additions and 45 deletions.
54 changes: 40 additions & 14 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ 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 @@ -20,6 +18,12 @@ var cliVersion = require('./package.json').version;
var getBlacklist = require('./lib/shared/getBlacklist');
var toConsole = require('./lib/shared/log/toConsole');

var Config = require('./lib/shared/config');
var getCliFlags = require('./lib/shared/config/cli-flags');
var getEnvFlags = require('./lib/shared/config/env-flags');
var configSpecs = require('./lib/shared/config/cfg-specs');
var assign = require('lodash.assign');

// Logging functions
var logVerify = require('./lib/shared/log/verify');
var logBlacklistError = require('./lib/shared/log/blacklistError');
Expand Down Expand Up @@ -84,26 +88,47 @@ cli.on('respawn', function(flags, child) {
});

function run() {
cli.launch({
var cliFlags = getCliFlags(cliOptions);

var envOpts = {
cwd: opts.cwd,
configPath: opts.gulpfile,
require: opts.require,
completion: opts.completion,
}, handleArguments);
};

cli.launch(envOpts, function(env) {
var envFlags = getEnvFlags(env, envOpts);

var config = new Config(env.configFiles);

try {
config.loadFiles('.gulp', ['home', 'cwd'], configSpecs);
} catch (e) {
log.error(chalk.red(e.message));
exit(1);
}

config.copyTo(opts, {
'flags.help': 'help',
});

config.copyTo(env, {
'flags.configPath': 'configPath',
'flags.cwd': 'cwd',
});

assign(opts, cliFlags);
assign(env, envFlags);

handleArguments(env, opts, config);
});
}

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));
});
function handleArguments(env, opts, config) {

if (opts.help) {
console.log(parser.help());
Expand Down Expand Up @@ -169,5 +194,6 @@ function handleArguments(env) {
}

// Load and execute the CLI version
require(path.join(__dirname, '/lib/versioned/', range, '/'))(opts, env);
require(path.join(__dirname, '/lib/versioned/', range, '/'))(opts, env,
config);
}
28 changes: 28 additions & 0 deletions lib/shared/config/cfg-specs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
'use strict';

module.exports = {

description: {
type: 'string',
requiresArg: true,
},

flags: {
help: {
type: 'boolean',
},

cwd: {
type: 'string',
requiresArg: true,
resolvePath: true,
},

configPath: {
type: 'string',
requiresArg: true,
resolvePath: true,
},
},

};
24 changes: 24 additions & 0 deletions lib/shared/config/cli-flags.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'use strict';

var yargs = require('yargs');
var camelCase = require('lodash.camelcase');
var eachProps = require('each-props');
var copyProps = require('copy-props');

module.exports = function(cliSpecs, usage) {
var argv = yargs(process.argv.slice(2)).argv;

var usedNames = [];
var usedSpecs = {};

eachProps(cliSpecs, function(spec, name) {
if (argv[name] != null || argv[spec.alias] != null) {
usedNames.push(camelCase(name));
usedSpecs[name] = spec;
}
return true;
});

var argvBySpecs = yargs.usage(usage, usedSpecs).argv;
return copyProps(argvBySpecs, {}, usedNames);
};
40 changes: 40 additions & 0 deletions lib/shared/config/env-flags.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
'use strict';

var eachProps = require('each-props');

module.exports = function(env, envOpts) {
var usedEnv = {};

eachProps(env, function(value, key) {
switch (key) {

case 'cwd':
case 'require':
case 'configPath': {
if (value != null && envOpts[key] != null) {
usedEnv[key] = value;
}
break;
}

case 'configBase': {
if (env.configPath != null && envOpts.configPath != null) {
usedEnv[key] = value;
usedEnv.configBase = value;
}
break;
}

default: {
if (value != null) {
usedEnv[key] = value;
}
break;
}
}

return true;
});

return usedEnv;
};
68 changes: 68 additions & 0 deletions lib/shared/config/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
'use strict';

var path = require('path');
var setDeep = require('lodash.set');
var getDeep = require('lodash.get');
var endsWith = require('lodash.endswith');
var isString = require('lodash.isstring');
var eachProps = require('each-props');
var copyProps = require('copy-props');
var validator = require('./validator');

function Config(configFiles) {
function Constructor(configFiles) {
this.content = {};
this.configFiles = configFiles || {};
}
Constructor.prototype = Config.prototype;
return new Constructor(configFiles);
}

Config.prototype.loadFiles = function(base, keysInOrder, specs) {
var content = this.content;

loadDefaultConfig(content, specs);

var configFileBase = this.configFiles[base] || {};
var configPathFiles = keysInOrder.map(function(key) {
return configFileBase[key];
}).filter(isString);

var validate = validator(specs);
configPathFiles.forEach(function(filePath) {
var thisObj = { filename: filePath, dirname: path.dirname(filePath) };
copyProps(require(filePath), content, validate.bind(thisObj));
});

return this;
};

Config.prototype.copyFrom = function(obj, props) {
copyProps(obj, this.content, props);
return this;
};

Config.prototype.copyTo = function(obj, props) {
copyProps(this.content, obj, props);
return this;
};

Config.prototype.is = function(key) {
return !!getDeep(this.content, key);
};

Config.prototype.get = function(key) {
return getDeep(this.content, key);
};

function loadDefaultConfig(content, specs) {
eachProps(specs, function(value, key) {
if (endsWith(key, '.default')) {
var dstKey = key.slice(0, -'.default'.length);
setDeep(content, dstKey, value);
return true;
}
});
}

module.exports = Config;
49 changes: 49 additions & 0 deletions lib/shared/config/validator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
'use strict';

var path = require('path');
var getDeep = require('lodash.get');
var isString = require('lodash.isstring');

module.exports = function(specs) {
return function(value, key) {
try {
return validate.call(this, value, key);
} catch (e) {
e.message += ' in ' + path.resolve(this.filename);
throw e;
}
};

/* $lab:coverage:off$ */
function validate(value, key) {
/* $lab:coverage:on$ */

var spec = getDeep(specs, key);
if (!spec) {
throw new Error('Undefined config: ' + key);
}

switch (spec.type) {

case 'string': {
if (!isString(value)) {
throw new TypeError('Invalid type of config: ' + key);
}
if (spec.requiresArg && !value) {
throw new Error('Required value of config: ' + key);
}
if (spec.resolvePath) {
return path.resolve(this.dirname, value);
}
return value;
}

default: {
if (typeof value !== spec.type) {
throw new TypeError('Invalid type of config: ' + key);
}
return value;
}
}
}
};
8 changes: 4 additions & 4 deletions lib/versioned/^3.7.0/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@ 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');
var logEvents = require('./log/events');
var logTasksSimple = require('./log/tasksSimple');
var registerExports = require('../../shared/registerExports');

function execute(opts, env) {
function execute(opts, env, config) {
var tasks = opts._;
var toRun = tasks.length ? tasks : ['default'];

Expand All @@ -39,8 +38,9 @@ function execute(opts, env) {
}
if (opts.tasks) {
var tree = taskTree(gulpInst.tasks);
if (opts.description && isString(opts.description)) {
tree.label = opts.description;
var desc = config.get('description');
if (desc) {
tree.label = desc;
} else {
tree.label = 'Tasks for ' + chalk.magenta(tildify(env.configPath));
}
Expand Down
8 changes: 4 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,7 +6,6 @@ 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 All @@ -16,7 +15,7 @@ var logSyncTask = require('../^4.0.0/log/syncTask');
var logTasksSimple = require('../^4.0.0/log/tasksSimple');
var registerExports = require('../../shared/registerExports');

function execute(opts, env) {
function execute(opts, env, config) {

var tasks = opts._;
var toRun = tasks.length ? tasks : ['default'];
Expand Down Expand Up @@ -44,8 +43,9 @@ function execute(opts, env) {
}
if (opts.tasks) {
var tree = {};
if (opts.description && isString(opts.description)) {
tree.label = opts.description;
var desc = config.get('description');
if (desc) {
tree.label = desc;
} else {
tree.label = 'Tasks for ' + chalk.magenta(tildify(env.configPath));
}
Expand Down
Loading

0 comments on commit 92a9107

Please sign in to comment.