Restrict config properties (Implementation for Issue #92)#94
Restrict config properties (Implementation for Issue #92)#94phated merged 7 commits intogulpjs:masterfrom
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.
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. |
index.js
Outdated
| var getBlacklist = require('./lib/shared/getBlacklist'); | ||
| var toConsole = require('./lib/shared/log/toConsole'); | ||
|
|
||
| var loadConfigFiles = require('./lib/shared/config/loadfiles'); |
index.js
Outdated
| }, handleArguments); | ||
| }; | ||
|
|
||
| cli.launch(envOpts, function(env) { |
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.
Why does this have the chance to throw? Can it be rewritten to not throw?
There was a problem hiding this comment.
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.
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.
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.
This should be non-mutating (return a new object).
There was a problem hiding this comment.
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.
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.
This should be non-mutating (return a new object).
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.
This should be creating a new object instead of mutating
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.
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.
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.
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.
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.
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.
If it is good to use copy-props, I'll replace this to it.
There was a problem hiding this comment.
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.
What is validate doing in this scenario?
There was a problem hiding this comment.
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.
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
| 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.
About config object? It will be always exists.
There was a problem hiding this comment.
Is config.description always guaranteed to be undefined or a String?
There was a problem hiding this comment.
Yes. It will be checked and output errors if invalid.
There was a problem hiding this comment.
Put the isString check back in when the validation is removed.
sttk
left a comment
There was a problem hiding this comment.
I'll modify what you pointed out.
index.js
Outdated
| var getBlacklist = require('./lib/shared/getBlacklist'); | ||
| var toConsole = require('./lib/shared/log/toConsole'); | ||
|
|
||
| var loadConfigFiles = require('./lib/shared/config/loadfiles'); |
index.js
Outdated
| }, handleArguments); | ||
| }; | ||
|
|
||
| cli.launch(envOpts, function(env) { |
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.
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); |
index.js
Outdated
| } | ||
|
|
||
| mergeToCliFlags(opts, config, cliOptions); | ||
| mergeToEnvFlags(env, config, envOpts); |
There was a problem hiding this comment.
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); |
lib/shared/config/loadfiles.js
Outdated
| @@ -0,0 +1,33 @@ | |||
| 'use strict'; | |||
|
|
|||
| var get = require('lodash.get'); | |||
There was a problem hiding this comment.
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.
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.
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
| 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.
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. |
phated
left a comment
There was a problem hiding this comment.
Sorry this took me so long to review. I promise to review quicker on your next updates.
index.js
Outdated
| var fs = require('fs'); | ||
| var path = require('path'); | ||
| var log = require('gulplog'); | ||
| var fancyLog = require('fancy-log'); |
There was a problem hiding this comment.
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.
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)); |
index.js
Outdated
|
|
||
| cli.on('requireFail', function(name) { | ||
| log.error(chalk.red('Failed to load external module'), chalk.magenta(name)); | ||
| fancyLog.error( |
index.js
Outdated
|
|
||
| // The actual logic | ||
| function handleArguments(env) { | ||
| function configureAndInvoke(env) { |
There was a problem hiding this comment.
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'); |
| 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.
Put the isString check back in when the validation is removed.
lib/versioned/^4.0.0/index.js
Outdated
| 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.
Put the isString check back in when the validation is removed.
lib/versioned/^4.0.0/index.js
Outdated
| 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.
Put the isString check back in when the validation is removed.
| 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.
Put the isString check back in when the validation is removed.
package.json
Outdated
| }, | ||
| "dependencies": { | ||
| "archy": "^1.0.0", | ||
| "camelcase": "^3.0.0", |
There was a problem hiding this comment.
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.
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.
Named function (I can make this change during merge).
| return; | ||
| } | ||
|
|
||
| copyProps(require(filePath), config, function(value, name) { |
There was a problem hiding this comment.
Named function (I can make this change during merge).
|
|
||
| function toConsole(log, opts) { | ||
| // Remove previous listeners to enable to call this twice. | ||
| log.removeAllListeners(); |
There was a problem hiding this comment.
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.
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.gulpfilefirst.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
optsproperties, so config files took precedence over command line flags. I modified it.Since it would be confusing to control to change or not
optsproperties at the time of merging, the current code evacuatesoptsproperties specified by cli-flags before merging, merge with config by config files, and merge with the evacuated properties at the end.Add an object
dispfor 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.jsare 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
envto the merged targets becauseenv.cwd,env.configPathandenv.requireare used for configuration of cwd, gulpfile and require.