salesforce-lightning-cli
Version:
Lightning CLI Heroku Plugin
147 lines (130 loc) • 5.6 kB
JavaScript
/*
* Copyright (C) 2016 salesforce.com, inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
const { SfdxCommand, flags } = require('@salesforce/command');
const { env } = require("@salesforce/kit");
const linter = require('../../lib/linter.js');
const trace = require('debug')('sfdx:LintCommand');
const debug = require('debug')('sfdx:LintCommand');
class LintCommand extends SfdxCommand {
constructor(...params) {
super(...params);
this.hasError = false;
}
async init() {
await super.init();
this.initLoggers();
// Get the JSON flag from environment variable.
// TODO: Read from other places per
// https://developer.salesforce.com/docs/atlas.en-us.sfdx_cli_plugins.meta/sfdx_cli_plugins/cli_plugins_customize_parameters_resolution.htm
if (env.getBoolean("SFDX_JSON_TO_STDOUT") === true) {
this.loggers.trace("Output enabled by environment variable, emulating --json flag.");
this.flags.json = "true"; // Not exactly true, but gets the behavior we want.
this.ux.isOutputEnabled = false;
}
}
async run() {
this.loggers.trace("Calling linter.");
return linter(
this.args.path,
this.flags,
this.loggers
);
}
/**
* We handle errors without raising an exception* to SfdxCommand.
* SfdxCommand doesn't know there was an error (and output) so the runner
* wants to print the `{ status: 0 }` message.
*
* We set a flag when we log errors so we can check that flag to determine
* if we should lie to their finally that there was an error.
* Because they expect errors to be handled before the finally, they do nothing for errors.
*
* * We don't raise an exception because the work wasn't done when this was ported
* to oclif to leverage the parent class's loggers and the SfdxResult interface.
* Doing this work would simplify our logging logic and let us benefit from the
* work that SfdxCommand does to read environment and config settings.
*/
finally() {
super.finally(this.hasError ? new Error("LintErrorAlreadyHandled") : undefined);
}
initLoggers() {
this.loggers = {
trace: (msg) => {
trace("TRACE " + msg);
},
debug: (msg) => {
debug("DEBUG " + msg);
},
warn: (msg) => {
if (this.ux.isOutputEnabled) {
this.ux.warn(msg);
}
else {
this.ux.log(msg);
}
},
log: this.ux.log.bind(this.ux),
logJson: this.ux.logJson.bind(this.ux),
error: (msg) => {
this.ux.error(msg);
this.hasError = true;
},
errorJson: (msg) => {
this.ux.errorJson(msg);
this.hasError = true;
}
}
}
}
LintCommand.description = 'analyze (lint) Aura component code';
LintCommand.longDescription = 'Runs a static analysis, or “lint,” tool on your Aura component code. ' +
'The default rules include recommended best practices and Lightning Locker requirements. ' +
'For details, including how to customize the rules for your org, see the Lightning Aura Components Developer Guide.';
LintCommand.examples = ['<%= config.bin %> <%= command.id %> ./path/to/be/linted/']
LintCommand.args = [{ name: 'path' }]
LintCommand.flagsConfig = {
ignore: flags.string({
char: 'i',
description: 'pattern used to ignore some folders',
longDescription: 'A “glob” pattern used to filter folders (and their contents) out of the analysis. ' +
'For example: --ignore **/foo/**.'
}),
files: flags.string({
description: 'pattern used to include specific files',
longDescription: 'A “glob” pattern used to add specific files to the analysis. ' +
'For example, to only analyse your controller files, use --files **/*Controller.js. ' +
'When specified, this value overrides the --ignore flag. ' +
'The default is all .js files.'
}),
config: flags.string({
description: 'path to a custom ESLint configuration file',
longDescription: 'Path to a custom ESLint configuration file. ' +
'Only code style rules are used, while the rest are ignored. ' +
'For example: --config path/to/.eslintrc.'
}),
verbose: flags.builtin({
description: 'report warnings in addition to errors',
longDescription: 'Report both warnings and errors. The default is to report only errors.'
}),
exit: flags.boolean({
hasValue: false,
description: 'exit with error code 1 if there are lint issues',
longDescription: 'Exit with error code 1 if there are lint issues. ' +
'The default exits without an error code.'
})
};
module.exports = LintCommand;