-
-
Notifications
You must be signed in to change notification settings - Fork 112
Restrict config properties (Implementation for Issue #92) #94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
In addition, we should consider about following points:
|
index.js
Outdated
|
||
function customizeByEachConfig(config, opts, env, disp, filePath) { | ||
try { | ||
var config = require(filePath); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found that this line is redundant with line 182. I'll remove this line or line 182.
I've removed the redundant code. |
@sttk any idea why the tests failed on node 6? |
The cause of this error is seemed to be an accidental timeout of the test for Actually, the same test for my repository is successful. |
@sttk Sorry for not having a chance to fully review this yet. I don't think |
92a9107
to
62594e9
Compare
62594e9
to
8ce1dbe
Compare
I re-created the code for this PR. This code supports and restricts only the config properties: One problem about the property Tentatively, I moved |
@sttk ugh, sorry that I still haven't had a chance to review this PR. Life has been hectic for me. I will try to review soon. |
@sttk this will need to be updated after I merge the mocha/expect changes. |
Feel free to rebase/update this based on the merge of #99 |
@phated I'll update this PR. |
8ce1dbe
to
3c3ff53
Compare
@phated I finished updating this PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sttk The tests are looking solid but I had some questions and code style changes inline.
index.js
Outdated
@@ -20,6 +19,10 @@ var cliVersion = require('./package.json').version; | |||
var getBlacklist = require('./lib/shared/getBlacklist'); | |||
var toConsole = require('./lib/shared/log/toConsole'); | |||
|
|||
var loadConfigFiles = require('./lib/shared/config/loadfiles'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rename to load-files
please.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got it.
index.js
Outdated
}, handleArguments); | ||
}; | ||
|
||
cli.launch(envOpts, function(env) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be a named function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got it.
index.js
Outdated
cli.launch(envOpts, function(env) { | ||
var config; | ||
try { | ||
config = loadConfigFiles(env.configFiles['.gulp'], ['home', 'cwd']); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this have the chance to throw? Can it be rewritten to not throw?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This exception is caused by validation of config files. Does your comment mean that outputting error and exiting should be done in loadConfigFiles
, or it is unnecessary to validate config files?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to validate the config? Could we just ignore and log a warning or error if it's the wrong type?
I don't like the throw/try/catch pattern and we shouldn't be exiting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got it. I'll make display errors but not exit.
index.js
Outdated
} | ||
|
||
mergeToCliFlags(opts, config, cliOptions); | ||
mergeToEnvFlags(env, config, envOpts); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we pass envOpts in here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be non-mutating (return a new object).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we pass envOpts in here?
To exclude env
property names related to command-line arguments.
This should be non-mutating (return a new object).
I got it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To exclude env property names related to command-line arguments.
Can you explain this further?
index.js
Outdated
exit(1); | ||
} | ||
|
||
mergeToCliFlags(opts, config, cliOptions); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be non-mutating (return a new object).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got it.
lib/shared/config/env-flags.js
Outdated
|
||
if (!envOpts.configPath && cfgFlags.gulpfile) { | ||
envFlags.configPath = cfgFlags.gulpfile; | ||
envFlags.configBase = path.dirname(cfgFlags.gulpfile); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be creating a new object instead of mutating
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got it.
lib/shared/config/loadfiles.js
Outdated
function loadConfigFiles(configFilesBase, keysInOrder) { | ||
var config = {}; | ||
|
||
var configFilePaths = keysInOrder.map(function(key) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does fined
not do this for us automatically? It's okay if it doesn't but my mind is fuzzy on it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Properties order in objects is not guaranteed, though Object.keys
looks like returning in definition order actually. I think it is needed to specify the order explicitly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I meant that fined
crawls the file system and only gives us the config file that matches. Or are we using it differently?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If config files are found in user home directory and project directory, both file paths are given by fined
. In that case each config in both project dir should be given priority over each config in user home dir, I think.
Though this order might be determined by descriptions at Liftoff
constructor, I want to specify it explicitly.
--
EDIT: erase the word "both"
lib/shared/config/loadfiles.js
Outdated
@@ -0,0 +1,33 @@ | |||
'use strict'; | |||
|
|||
var get = require('lodash.get'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm going to be removing lodash. It's okay for us to leave it in for this implementation unless you want to find replacements
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it is good to use copy-props
, I'll replace this to it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we using it in other places? I'm fine with using it since you will be able to fix anything needed.
lib/shared/config/loadfiles.js
Outdated
return; | ||
} | ||
|
||
set(config, keyPath, spec.validate(value, filePath)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is validate
doing in this scenario?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Validating each config value comming from config files, and convert file path (e.g. gulpfile) from relative path from .gulp.*
to absolute path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like the validate
stuff. I think there's a better way to do this.
lib/versioned/^3.7.0/index.js
Outdated
@@ -39,8 +38,8 @@ function execute(opts, env) { | |||
} | |||
if (opts.tasks) { | |||
var tree = taskTree(gulpInst.tasks); | |||
if (opts.description && isString(opts.description)) { | |||
tree.label = opts.description; | |||
if (config.description) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will this always exist now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
About config
object? It will be always exists.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is config.description
always guaranteed to be undefined
or a String?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. It will be checked and output errors if invalid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Put the isString
check back in when the validation is removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll modify what you pointed out.
index.js
Outdated
@@ -20,6 +19,10 @@ var cliVersion = require('./package.json').version; | |||
var getBlacklist = require('./lib/shared/getBlacklist'); | |||
var toConsole = require('./lib/shared/log/toConsole'); | |||
|
|||
var loadConfigFiles = require('./lib/shared/config/loadfiles'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got it.
index.js
Outdated
}, handleArguments); | ||
}; | ||
|
||
cli.launch(envOpts, function(env) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got it.
index.js
Outdated
cli.launch(envOpts, function(env) { | ||
var config; | ||
try { | ||
config = loadConfigFiles(env.configFiles['.gulp'], ['home', 'cwd']); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This exception is caused by validation of config files. Does your comment mean that outputting error and exiting should be done in loadConfigFiles
, or it is unnecessary to validate config files?
index.js
Outdated
exit(1); | ||
} | ||
|
||
mergeToCliFlags(opts, config, cliOptions); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got it.
index.js
Outdated
} | ||
|
||
mergeToCliFlags(opts, config, cliOptions); | ||
mergeToEnvFlags(env, config, envOpts); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we pass envOpts in here?
To exclude env
property names related to command-line arguments.
This should be non-mutating (return a new object).
I got it.
lib/shared/config/env-flags.js
Outdated
|
||
if (!envOpts.configPath && cfgFlags.gulpfile) { | ||
envFlags.configPath = cfgFlags.gulpfile; | ||
envFlags.configBase = path.dirname(cfgFlags.gulpfile); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got it.
lib/shared/config/loadfiles.js
Outdated
@@ -0,0 +1,33 @@ | |||
'use strict'; | |||
|
|||
var get = require('lodash.get'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it is good to use copy-props
, I'll replace this to it.
lib/shared/config/loadfiles.js
Outdated
function loadConfigFiles(configFilesBase, keysInOrder) { | ||
var config = {}; | ||
|
||
var configFilePaths = keysInOrder.map(function(key) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Properties order in objects is not guaranteed, though Object.keys
looks like returning in definition order actually. I think it is needed to specify the order explicitly.
lib/shared/config/loadfiles.js
Outdated
return; | ||
} | ||
|
||
set(config, keyPath, spec.validate(value, filePath)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Validating each config value comming from config files, and convert file path (e.g. gulpfile) from relative path from .gulp.*
to absolute path.
lib/versioned/^3.7.0/index.js
Outdated
@@ -39,8 +38,8 @@ function execute(opts, env) { | |||
} | |||
if (opts.tasks) { | |||
var tree = taskTree(gulpInst.tasks); | |||
if (opts.description && isString(opts.description)) { | |||
tree.label = opts.description; | |||
if (config.description) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
About config
object? It will be always exists.
@sttk Don't mean to pester you but do you know when you'll have a chance to work on the changes? |
@phated I'll work on the changes this weekend. Why? |
No reason, I've just been really active on the project lately. I know how hard it is to get me to review, haha! |
3c3ff53
to
2984265
Compare
Since I've modified matters pointed out by you, please review. |
@sttk I'm terrible. Sorry! Looking at this now. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry this took me so long to review. I promise to review quicker on your next updates.
index.js
Outdated
@@ -3,14 +3,13 @@ | |||
var fs = require('fs'); | |||
var path = require('path'); | |||
var log = require('gulplog'); | |||
var fancyLog = require('fancy-log'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really don't like using fancy-log directly, it means that someone using --silent
will still see the messages. Looking into re-binding the logger after we parse the config.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
toConsole
can be updated to remove previous listeners if called a 2nd time. You can then use it at the beginning of this file and call it again after you normalize the config.
index.js
Outdated
cli.on('require', function(name) { | ||
log.info('Requiring external module', chalk.magenta(name)); | ||
fancyLog('Requiring external module', chalk.magenta(name)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above about fancy-log
index.js
Outdated
}); | ||
|
||
cli.on('requireFail', function(name) { | ||
log.error(chalk.red('Failed to load external module'), chalk.magenta(name)); | ||
fancyLog.error( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above about fancy-log
index.js
Outdated
} | ||
|
||
module.exports = run; | ||
|
||
// The actual logic | ||
function handleArguments(env) { | ||
function configureAndInvoke(env) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this just split out due to the linting complaining about number of statements? I'd be happier increasing the limit and putting it inside handleArguments
.
lib/shared/config/convert-config.js
Outdated
'use strict'; | ||
|
||
var path = require('path'); | ||
var logger = require('fancy-log'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above about fancy-log
@@ -49,8 +48,8 @@ function execute(opts, env) { | |||
} | |||
if (opts.tasks) { | |||
tree = gulpInst.tree({ deep: true }); | |||
if (opts.description && isString(opts.description)) { | |||
tree.label = opts.description; | |||
if (config.description) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Put the isString
check back in when the validation is removed.
lib/versioned/^4.0.0/index.js
Outdated
@@ -49,8 +48,8 @@ function execute(opts, env) { | |||
} | |||
if (opts.tasks) { | |||
tree = gulpInst.tree({ deep: true }); | |||
if (opts.description && isString(opts.description)) { | |||
tree.label = opts.description; | |||
if (config.description) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Put the isString
check back in when the validation is removed.
lib/versioned/^4.0.0/index.js
Outdated
@@ -59,8 +58,8 @@ function execute(opts, env) { | |||
} | |||
if (opts.tasksJson) { | |||
tree = gulpInst.tree({ deep: true }); | |||
if (opts.description && isString(opts.description)) { | |||
tree.label = opts.description; | |||
if (config.description) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Put the isString
check back in when the validation is removed.
@@ -59,8 +58,8 @@ function execute(opts, env) { | |||
} | |||
if (opts.tasksJson) { | |||
tree = gulpInst.tree({ deep: true }); | |||
if (opts.description && isString(opts.description)) { | |||
tree.label = opts.description; | |||
if (config.description) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Put the isString
check back in when the validation is removed.
package.json
Outdated
"cover": "nyc --reporter=lcov --reporter=text-summary npm test", | ||
"coveralls": "nyc --reporter=text-lcov npm test | coveralls", | ||
"changelog": "github-changes -o gulpjs -r gulp-cli -b master -f ./CHANGELOG.md --order-semver --use-commit-body" | ||
}, | ||
"dependencies": { | ||
"archy": "^1.0.0", | ||
"camelcase": "^3.0.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be removed when excludeCliArgs
is removed.
@phated Thanks for your reviewing. I'll address what you pointed out this week end. |
@phated I've modified. -- |
|
||
copyProps(require(filePath), config, function(value, name) { | ||
if (name === 'flags.gulpfile') { | ||
return path.resolve(path.dirname(filePath), value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh interesting, this is making the path in the config file relative its location.
function loadConfigFiles(configFiles, configFileOrder) { | ||
var config = {}; | ||
|
||
configFileOrder.forEach(function(key) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Named function (I can make this change during merge).
return; | ||
} | ||
|
||
copyProps(require(filePath), config, function(value, name) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Named function (I can make this change during merge).
@@ -14,6 +14,9 @@ var levels = [ | |||
]; | |||
|
|||
function toConsole(log, opts) { | |||
// Remove previous listeners to enable to call this twice. | |||
log.removeAllListeners(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be more specific to avoid removing other listeners someone else might have attached (we are using a global, after all). I can change this in the merge.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, you are exactly right. Thanks.
@sttk amazing work, as always. I'll get this merged and make a couple changes I commented about. |
@phated Thank you for merging! |
This PR is for the issue #92.
I only implemented about the properties:
description
,flags.help
, andflags.gulpfile
first.The points that I modified from #90 are as follows:
Config properties by cli-flags take precedence over them by config files.
I made a mistake in the previous implementation to merge properties of config files over
opts
properties, so config files took precedence over command line flags. I modified it.Since it would be confusing to control to change or not
opts
properties at the time of merging, the current code evacuatesopts
properties specified by cli-flags before merging, merge with config by config files, and merge with the evacuated properties at the end.Add an object
disp
for display settings.This object is used for outputing description for gulpfile and will be used for various display configurations.
For this object, the api of the versioned cli modules in
lib/versioned/*/index.js
are added 3rd argument.Add validations for config properties of each config file.
And if a validation fails, outputs the error and quits immediately.
Add convert for config properties of each config file.
Because it is needed to convert a property value into an absolute path with a base directory path if the property value is a path string.
Add
env
to the merged targets becauseenv.cwd
,env.configPath
andenv.require
are used for configuration of cwd, gulpfile and require.