Skip to content
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

feat: Support theming and translations via config files #260

Merged
merged 48 commits into from
Mar 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
be0955c
feat: make log messages and styles configurable with theme.
sttk Feb 4, 2024
9034164
feat: enable to override log messages and theme with a config file.
sttk Feb 11, 2024
2d3a80d
fix: add handling for yargs message when cli options are invalid.
sttk Feb 12, 2024
a39ab8c
fix: rename msgs.tasks/tasksJson.gulpfile to msgs.tasks/tasksJson.des…
sttk Feb 12, 2024
3a95fd3
fix: modify positions of msgs and theme in config
sttk Feb 12, 2024
741ff5a
update: remove config.description because config.log.msgs.tasks.descr…
sttk Feb 12, 2024
a4bfdd5
fix: remove a comment ignoring coverage
sttk Feb 17, 2024
237cb58
fix: remove a comment for ignoring coverage and add a test case
sttk Feb 17, 2024
ba976ab
fix: add tests for overrideEnvConfig
sttk Feb 17, 2024
d8e01e8
fix: remove the version message from the configuration target
sttk Feb 17, 2024
883cc8e
Prototype of symbol messages
phated Mar 10, 2024
7051ab4
box drawing symbols and changes to see in diff
phated Mar 10, 2024
10f19b2
task start/stop/etc
phated Mar 10, 2024
d552e73
remove theme and requires
phated Mar 10, 2024
1bcefb6
linting
phated Mar 10, 2024
09bcae0
npm install messages
phated Mar 10, 2024
5b73bbd
using gulpfile
phated Mar 10, 2024
294bbfb
move description to messages
phated Mar 10, 2024
77f42fe
remove alphas
phated Mar 10, 2024
5e1fda2
Merge remote-tracking branch 'origin/master' into phated/translations
phated Mar 10, 2024
a1831c6
remove chalk from root
phated Mar 10, 2024
528a0d7
Merge remote-tracking branch 'origin/master' into phated/translations
phated Mar 10, 2024
6e5c790
fix some getMessage calls
phated Mar 10, 2024
ac44fe2
Merge remote-tracking branch 'origin/master' into phated/translations
phated Mar 17, 2024
1000066
load user messages and timestamps, integrate with liftoff 5
phated Mar 17, 2024
c1a8775
remove file re-added in merge
phated Mar 17, 2024
e51382d
remove timestamp logic in favor of util.inspect
phated Mar 17, 2024
2e6b0c5
original tests passing
phated Mar 17, 2024
6fd4796
todo for the messages package
phated Mar 17, 2024
b079083
move tildify into the default messages
phated Mar 17, 2024
69e7993
restore package.json
phated Mar 17, 2024
3bc91df
remove extra files
phated Mar 17, 2024
8b85be1
remove extra test step
phated Mar 17, 2024
2ebe2d7
Merge remote-tracking branch 'origin/master' into phated/translations
phated Mar 17, 2024
1cced02
cleanup messages
phated Mar 17, 2024
ee5385e
linting
phated Mar 17, 2024
7d8266a
update all theme tests and fix some impl
phated Mar 18, 2024
a53d0e7
reduce the package.json files in tests
phated Mar 18, 2024
655727a
pass message to the timestamp function
phated Mar 21, 2024
a2bd8d0
combine tag and data into one object
phated Mar 21, 2024
3cbda52
remove todo
phated Mar 21, 2024
2208e68
Merge remote-tracking branch 'origin/master' into phated/translations
phated Mar 22, 2024
9d3fc17
remove leftover file
phated Mar 22, 2024
8ff5be5
fix merge leftover
phated Mar 22, 2024
22ed426
message handling for task names/descriptions, task flags/descriptions
phated Mar 22, 2024
ff19cd5
add documentation
phated Mar 22, 2024
8e2b490
try-catch around user code
phated Mar 22, 2024
da31e9c
messages package
phated Mar 23, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"extends": "gulp",
"rules": {
"max-len": [1, 130],
"max-statements": [1, 40],
"max-statements": [1, 65],
"no-console": "off"
}
}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
*.log
node_modules
!test/fixtures/errors/bad-gulp-version/node_modules/
!test/fixtures/config/theming/UNSUPPORTED_GULP_VERSION/node_modules/
build
*.node
components
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ Supported configurations properties:
| flags.tasksDepth | Set default depth of task dependency tree. |
| flags.silent | Silence logging by default |
| flags.series | Run tasks given on the CLI in series (the default is parallel) |
| message(data) | A function used to translate messages that pass through gulp-cli. Can receive an object like `{ tag: Symbol(), ...props }` where the `tag` is a symbol from `@gulpjs/messages`. The string returned from this function will be logged. If `false` is explicitly returned, no message will be logged. |
| timestamp(data) | A function used to provide timestamps for gulp-cli. Can receive an object like `{ tag: Symbol(), ...props }` where the `tag` is a symbol from `@gulpjs/messages`. The string returned from this function will be output before any messages. If `false` is explicitly returned, no timestamp will be output. |

## Flags

Expand Down
134 changes: 71 additions & 63 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,20 @@ var yargs = require('yargs');
var Liftoff = require('liftoff');
var interpret = require('interpret');
var v8flags = require('v8flags');
var messages = require('@gulpjs/messages');
var findRange = require('semver-greatest-satisfied-range');
var chalk = require('chalk');

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

var arrayFind = require('./lib/shared/array-find');
var makeTitle = require('./lib/shared/make-title');
var makeHelp = require('./lib/shared/options/make-help');
var cliOptions = require('./lib/shared/options/cli-options');
var completion = require('./lib/shared/completion');
var cliVersion = require('./package.json').version;
var toConsole = require('./lib/shared/log/to-console');
var mergeCliOpts = require('./lib/shared/config/cli-flags');
var buildTranslations = require('./lib/shared/translate');

// Get supported ranges
var ranges = fs.readdirSync(path.join(__dirname, '/lib/versioned/'));
Expand All @@ -31,7 +33,6 @@ process.env.INIT_CWD = process.cwd();
var cli = new Liftoff({
name: 'gulp',
processTitle: makeTitle('gulp', process.argv.slice(2)),
completions: completion,
extensions: interpret.jsVariants,
v8flags: v8flags,
configFiles: [
Expand All @@ -49,38 +50,34 @@ var cli = new Liftoff({
],
});

var usage =
'\n' + chalk.bold('Usage:') +
' gulp ' + chalk.blue('[options]') + ' tasks';

var parser = yargs
.help(false)
.version(false)
.detectLocale(false)
.usage(usage)
.showHelpOnFail(false)
.exitProcess(false)
.fail(onFail)
.options(cliOptions);

var opts = parser.parse();

// Set up event listeners for logging temporarily.
toConsole(log, opts);
// TODO: Rework console logging before we can set up proper config
// Possibly by batching messages in gulplog until listeners are attached
var cleanupListeners = toConsole(log, opts, buildTranslations());
phated marked this conversation as resolved.
Show resolved Hide resolved

cli.on('preload:before', function(name) {
log.info('Preloading external module:', chalk.magenta(name));
log.info({ tag: messages.PRELOAD_BEFORE, name: name });
});

cli.on('preload:success', function(name) {
log.info('Preloaded external module:', chalk.magenta(name));
log.info({ tag: messages.PRELOAD_SUCCESS, name: name });
});

cli.on('preload:failure', function(name, error) {
log.warn(
chalk.yellow('Failed to preload external module:'),
chalk.magenta(name)
);
/* istanbul ignore else */
log.warn({ tag: messages.PRELOAD_FAILURE, name: name });
if (error) {
log.warn(chalk.yellow(error.toString()));
log.warn({ tag: messages.PRELOAD_ERROR, error: error });
}
});

Expand All @@ -90,34 +87,27 @@ cli.on('loader:success', function(name) {
// However, we don't want to show the mjs-stub loader in the logs
/* istanbul ignore else */
if (path.basename(name, '.js') !== 'mjs-stub') {
log.info('Loaded external module:', chalk.magenta(name));
log.info({ tag: messages.LOADER_SUCCESS, name: name });
}
});

cli.on('loader:failure', function(name, error) {
log.warn(
chalk.yellow('Failed to load external module:'),
chalk.magenta(name)
);
/* istanbul ignore else */
log.warn({ tag: messages.LOADER_FAILURE, name: name });
if (error) {
log.warn(chalk.yellow(error.toString()));
log.warn({ tag: messages.LOADER_ERROR, error: error });
}
});

cli.on('respawn', function(flags, child) {
var nodeFlags = chalk.magenta(flags.join(', '));
var pid = chalk.magenta(child.pid);
log.info('Node flags detected:', nodeFlags);
log.info('Respawned to PID:', pid);
log.info({ tag: messages.NODE_FLAGS, flags: flags });
log.info({ tag: messages.RESPAWNED, pid: child.pid });
});

function run() {
cli.prepare({
cwd: opts.cwd,
configPath: opts.gulpfile,
preload: opts.preload,
completion: opts.completion,
}, onPrepare);
}

Expand All @@ -127,22 +117,50 @@ function isDefined(cfg) {
return cfg != null;
}

function onFail(message, error) {
// Run Liftoff#prepare to get the env. Primarily to load themes.
cli.prepare({}, function (env) {
// We only use the first config found, which is a departure from
// the previous implementation that merged with the home
var cfg = arrayFind(env.config, isDefined);
var translate = buildTranslations(cfg);

var errorMsg = translate.message({ tag: messages.ARGV_ERROR, message: message, error: error });
if (errorMsg) {
console.error(errorMsg);
}

makeHelp(parser, translate).showHelp(console.error);
exit(1);
});
}

function onPrepare(env) {
// We only use the first config found, which is a departure from
// the previous implementation that merged with the home
var cfg = arrayFind(env.config, isDefined);
var flags = mergeCliOpts(opts, cfg);

// Set up event listeners for logging after configuring.
toConsole(log, flags);
// Remove the previous listeners since we have appropriate config now
cleanupListeners();

var translate = buildTranslations(cfg);

// Set up event listeners for logging again after configuring.
toConsole(log, flags, translate);

cli.execute(env, cfg.nodeFlags, function (env) {
onExecute(env, cfg, flags);
onExecute(env, flags, translate);
});
}

// The actual logic
function onExecute(env, cfg, flags) {
function onExecute(env, flags, translate) {
// Moved the completion logic outside of Liftoff since we need to include translations
if (flags.completion) {
return completion(flags.completion, translate);
}

// This translates the --continue flag in gulp
// To the settle env variable for undertaker
// We use the process.env so the user's gulpfile
Expand All @@ -152,7 +170,7 @@ function onExecute(env, cfg, flags) {
}

if (flags.help) {
parser.showHelp(console.log);
makeHelp(parser, translate).showHelp(console.log);
exit(0);
}

Expand All @@ -164,60 +182,50 @@ function onExecute(env, cfg, flags) {
}

if (!env.modulePath) {
/* istanbul ignore next */
var missingNodeModules =
fs.existsSync(path.join(env.cwd, 'package.json'))
&& !fs.existsSync(path.join(env.cwd, 'node_modules'));

/* istanbul ignore next */
var missingGulpMessage =
missingNodeModules
? 'Local modules not found in'
: 'Local gulp not found in';
log.error(
chalk.red(missingGulpMessage),
chalk.magenta(tildify(env.cwd))
);
var hasYarn = fs.existsSync(path.join(env.cwd, 'yarn.lock'));
/* istanbul ignore next */
var installCommand =
missingNodeModules
? hasYarn
? 'yarn install'
: 'npm install'
: hasYarn
? 'yarn add gulp'
: 'npm install gulp';
log.error(chalk.red('Try running: ' + installCommand));
if (missingNodeModules) {
log.error({ tag: messages.MISSING_NODE_MODULES, cwd: env.cwd });
if (hasYarn) {
log.error({ tag: messages.YARN_INSTALL })
} else {
log.error({ tag: messages.NPM_INSTALL })
}
} else {
log.error({ tag: messages.MISSING_GULP, cwd: env.cwd });
if (hasYarn) {
log.error({ tag: messages.YARN_INSTALL_GULP });
} else {
log.error({ tag: messages.NPM_INSTALL_GULP });
}
}
exit(1);
}

if (!env.configPath) {
log.error(chalk.red('No gulpfile found'));
log.error({ tag: messages.MISSING_GULPFILE });
exit(1);
}

// Chdir before requiring gulpfile to make sure
// we let them chdir as needed
if (process.cwd() !== env.cwd) {
process.chdir(env.cwd);
log.info(
'Working directory changed to',
chalk.magenta(tildify(env.cwd))
);
log.info({ tag: messages.CWD_CHANGED, cwd: env.cwd });
}

// Find the correct CLI version to run
var range = findRange(env.modulePackage.version, ranges);

if (!range) {
log.error(
chalk.red('Unsupported gulp version', env.modulePackage.version)
);
log.error({ tag: messages.UNSUPPORTED_GULP_VERSION, version: env.modulePackage.version });
exit(1);
}

// Load and execute the CLI version
var versionedDir = path.join(__dirname, '/lib/versioned/', range, '/');
require(versionedDir)(env, cfg, flags);
require(versionedDir)(env, flags, translate);
}
12 changes: 5 additions & 7 deletions lib/shared/completion.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,18 @@
var fs = require('fs');
var path = require('path');

module.exports = function(name) {
var messages = require('@gulpjs/messages');

module.exports = function(name, translate) {
if (typeof name !== 'string') {
throw new Error('Missing completion type');
throw new Error(translate.message({ tag: messages.COMPLETION_TYPE_MISSING }));
}
var file = path.join(__dirname, '../../completion', name);
try {
console.log(fs.readFileSync(file, 'utf8'));
process.exit(0);
} catch (err) {
console.log(
'echo "gulp autocompletion rules for',
'\'' + name + '\'',
'not found"'
);
console.log(translate.message({ tag: messages.COMPLETION_TYPE_UNKNOWN, name: name }));
process.exit(5);
}
};
Loading
Loading