Skip to content

Commit

Permalink
Add --print-config CLI flag (fixes #3127) (#3532)
Browse files Browse the repository at this point in the history
  • Loading branch information
thibaudcolas authored and jeddy3 committed Aug 15, 2018
1 parent e327558 commit 2dd1834
Show file tree
Hide file tree
Showing 8 changed files with 183 additions and 5 deletions.
4 changes: 4 additions & 0 deletions docs/user-guide/cli.md
Expand Up @@ -104,6 +104,10 @@ If you're using both these special comments and autofixing, please run stylelint

For CSS with standard syntax, stylelint will use [postcss-safe-parser](https://github.com/postcss/postcss-safe-parser) to fix syntax errors.

### Troubleshooting configurations

With the `--print-config` option, stylelint outputs the configuration to be used for the file passed. When present, no linting is performed and only config-related options are valid.

## Syntax errors

The CLI informs you about syntax errors in your CSS.
Expand Down
1 change: 1 addition & 0 deletions flow-typed/stylelint.js
Expand Up @@ -137,6 +137,7 @@ export type stylelint$standaloneOptions = {
configFile?: string,
configBasedir?: string,
configOverrides?: Object,
printConfig?: string,
ignoreDisables?: boolean,
ignorePath?: string,
ignorePattern?: RegExp,
Expand Down
64 changes: 64 additions & 0 deletions lib/__tests__/printConfig.test.js
@@ -0,0 +1,64 @@
"use strict";

const path = require("path");
const pluginWarnAboutFoo = require("./fixtures/plugin-warn-about-foo");
const printConfig = require("../printConfig");

it("printConfig uses getConfigForFile to retrieve the config", () => {
const filepath = path.join(
__dirname,
"fixtures/getConfigForFile/a/b/foo.css"
);
printConfig({
files: [filepath]
}).then(result => {
expect(result).toEqual({
plugins: [path.join(__dirname, "/fixtures/plugin-warn-about-foo.js")],
rules: {
"block-no-empty": [true],
"plugin/warn-about-foo": ["always"]
},
pluginFunctions: {
"plugin/warn-about-foo": pluginWarnAboutFoo.rule
}
});
});
});

it("printConfig with input css should throw", () => {
expect(
printConfig({
code: "a {}"
})
).rejects.toThrow(
"The --print-config option must be used with exactly one file path."
);
});

it("printConfig with no path should throw", () => {
expect(
printConfig({
files: []
})
).rejects.toThrow(
"The --print-config option must be used with exactly one file path."
);
});

it("printConfig with multiple paths should throw", () => {
expect(
printConfig({
files: ["./first-path.css", "./second-path.css"]
})
).rejects.toThrow(
"The --print-config option must be used with exactly one file path."
);
});

it("printConfig with globs should throw", () => {
expect(
printConfig({
files: ["./*.css"]
})
).rejects.toThrow("The --print-config option does not support globs.");
});
33 changes: 28 additions & 5 deletions lib/cli.js
Expand Up @@ -10,6 +10,7 @@ const getStdin = require("get-stdin");
const meow = require("meow");
const needlessDisablesStringFormatter = require("./formatters/needlessDisablesStringFormatter");
const path = require("path");
const printConfig = require("./printConfig");
const resolveFrom = require("resolve-from");
const standalone = require("./standalone");

Expand All @@ -32,6 +33,9 @@ const standalone = require("./standalone");
"config-basedir": {
type: string
},
"print-config": {
type: string
},
color: {
type: string
},
Expand Down Expand Up @@ -101,6 +105,7 @@ const standalone = require("./standalone");
cacheLocation: any,
config: any,
configBasedir: any,
printConfig: boolean,
customFormatter: any,
customSyntax: any,
disableDefaultIgnores: boolean,
Expand Down Expand Up @@ -136,6 +141,7 @@ const standalone = require("./standalone");
configOverrides: {
quiet?: any,
},
printConfig?: any,
customSyntax?: any,
fix?: any,
ignoreDisables?: any,
Expand Down Expand Up @@ -181,6 +187,10 @@ const meowOptions /*: meowOptionsType*/ = {
and "plugins" are *relative to*. Only necessary if these values are
relative paths.
--print-config
Print the configuration for the given path.
--ignore-path, -i
Path to a file containing patterns that describe files to ignore. The
Expand Down Expand Up @@ -280,6 +290,9 @@ const meowOptions /*: meowOptionsType*/ = {
"config-basedir": {
type: "string"
},
"print-config": {
type: "boolean"
},
color: {
type: "boolean"
},
Expand Down Expand Up @@ -462,6 +475,14 @@ module.exports = (argv /*: string[]*/) /*: Promise<void>|void*/ => {
);
})
.then(options => {
if (cli.flags.printConfig) {
return printConfig(options)
.then(config => {
process.stdout.write(JSON.stringify(config, null, " "));
})
.catch(handleError);
}

if (!options.files && !options.code) {
cli.showHelp();
return;
Expand Down Expand Up @@ -500,10 +521,12 @@ module.exports = (argv /*: string[]*/) /*: Promise<void>|void*/ => {
process.exitCode = 2;
}
})
.catch((err /*: { stack: any, code: any }*/) => {
console.log(err.stack); // eslint-disable-line no-console
const exitCode = typeof err.code === "number" ? err.code : 1;
process.exit(exitCode); // eslint-disable-line no-process-exit
});
.catch(handleError);
});
};

function handleError(err /*: { stack: any, code: any }*/) /*: void */ {
console.log(err.stack); // eslint-disable-line no-console
const exitCode = typeof err.code === "number" ? err.code : 1;
process.exit(exitCode); // eslint-disable-line no-process-exit
}
54 changes: 54 additions & 0 deletions lib/printConfig.js
@@ -0,0 +1,54 @@
/* @flow */
"use strict";

const _ = require("lodash");
const createStylelint = require("./createStylelint");
const globby /*: Function*/ = require("globby");
const path = require("path");

module.exports = function(
options /*: stylelint$standaloneOptions */
) /*: Promise<stylelint$config>*/ {
const code = options.code;
const config = options.config;
const configBasedir = options.configBasedir;
const configFile = options.configFile;
const configOverrides = options.configOverrides;
const globbyOptions = options.globbyOptions;
const files = options.files;

const isCodeNotFile = code !== undefined;
if (!files || files.length !== 1 || isCodeNotFile) {
return Promise.reject(
new Error(
"The --print-config option must be used with exactly one file path."
)
);
}

const filePath = files[0];

if (globby.hasMagic(filePath)) {
return Promise.reject(
new Error("The --print-config option does not support globs.")
);
}

const stylelint = createStylelint({
config,
configFile,
configBasedir,
configOverrides
});

const cwd = _.get(globbyOptions, "cwd", process.cwd());
const absoluteFilePath = !path.isAbsolute(filePath)
? path.join(cwd, filePath)
: path.normalize(filePath);

const configSearchPath = stylelint._options.configFile || absoluteFilePath;

return stylelint
.getConfigForFile(configSearchPath)
.then(result => result.config);
};
27 changes: 27 additions & 0 deletions system-tests/cli/cli.test.js
@@ -1,6 +1,7 @@
/* eslint no-console: off */
"use strict";
const cli = require("../../lib/cli");
const path = require("path");
const pkg = require("../../package.json");

jest.mock("get-stdin");
Expand All @@ -23,6 +24,7 @@ describe("CLI", () => {
beforeEach(function() {
process.exitCode = undefined;
console.log = jest.fn();
process.stdout.write = jest.fn();
if (parseInt(process.versions.node) < 7) {
// https://github.com/sindresorhus/get-stdin/issues/13
process.nextTick(() => {
Expand Down Expand Up @@ -60,4 +62,29 @@ describe("CLI", () => {
expect(lastCallArgs.pop()).toMatch(pkg.version);
});
});

it("--print-config", () => {
return Promise.resolve(
cli([
"--print-config",
"--config",
path.join(__dirname, "config.json"),
path.join(__dirname, "stylesheet.css")
])
).then(() => {
expect(process.exitCode).toBe(undefined);
expect(process.stdout.write).toHaveBeenCalledTimes(1);
expect(process.stdout.write).toHaveBeenLastCalledWith(
JSON.stringify(
{
rules: {
"block-no-empty": [true]
}
},
null,
" "
)
);
});
});
});
5 changes: 5 additions & 0 deletions system-tests/cli/config.json
@@ -0,0 +1,5 @@
{
"rules": {
"block-no-empty": true
}
}
Empty file added system-tests/cli/stylesheet.css
Empty file.

0 comments on commit 2dd1834

Please sign in to comment.