Skip to content

Commit

Permalink
Merge branch 'master' of github.com:stylelint/stylelint into implemen…
Browse files Browse the repository at this point in the history
…t-caching

# Conflicts:
#	package.json
  • Loading branch information
sergesemashko committed Mar 8, 2017
2 parents bfce140 + 16e8cc7 commit 903d7c5
Show file tree
Hide file tree
Showing 22 changed files with 415 additions and 28 deletions.
11 changes: 7 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Head

- Added: support for asynchronous plugin rules ([#2351](https://github.com/stylelint/stylelint/pull/2351)).
- Added: `at-rule-semicolon-space-before` rule ([#2388](https://github.com/stylelint/stylelint/pull/2388)).
- Fixed: more helpful messages when file globs do not match any files ([#2328](https://github.com/stylelint/stylelint/pull/2328)).
- Fixed: `no-extra-semicolons` false positives for comments are custom property sets ([#2396](https://github.com/stylelint/stylelint/pull/2396)).

# 7.9.0

Expand Down Expand Up @@ -31,7 +34,7 @@
- `root-no-standard-properties`
- `selector-root-no-composition`.
- The following rules did not work well.
- `stylelint-disable-reason`. Please consider contributing to [#2292](https://github.com/stylelint/stylelint/issues/2292) for a replacement.
- `stylelint-disable-reason` could not enforce providing a reason.
- `declaration-block-no-ignored-properties` could not reliably account for *replaced elements*.
- Deprecated: 4 options ([#2213](https://github.com/stylelint/stylelint/pull/2213)).
- `"all-nested"` option for `at-rule-empty-line-before`. Use the `"inside-block"` option instead.
Expand Down Expand Up @@ -398,7 +401,7 @@

- Added: `selector-no-qualifying-type` rule.
- Fixed: `number-leading-zero` will not check `@import` at-rules.
- Fixed: `selector-class-pattern` now ignores non-ouputting Less mixin definitions and called Less mixins.
- Fixed: `selector-class-pattern` now ignores non-outputting Less mixin definitions and called Less mixins.
- Fixed: `value-keyword-case` now accounts for camelCase keywords (e.g. `optimizeSpeed`, `optimizeLegibility` and `geometricPrecision`) when the `lower` option is used.
- Fixed: `testUtils` and `stylelint.createRuleTester` module mistakes.

Expand Down Expand Up @@ -719,11 +722,11 @@
- support for YAML `.stylelintrc`
- support for `stylelint.config.js`
- support for `stylelint` property in `package.json`
- alternate config loading system, which stops at the first config foun
- alternate config loading system, which stops at the first config found
- Added: asynchronicity to the PostCSS plugin.
- Added: `ignoreFiles` option to config.
- Added: `configFile` option to Node.js API.
- Fixed: `comment-whitespace-inside` now ignores ignores copyright (`/*! `) and sourcemap (`/*# `) comments.
- Fixed: `comment-whitespace-inside` now ignores copyright (`/*! `) and sourcemap (`/*# `) comments.
- Fixed: `rule-no-duplicate-properties` now ignores the `src` property.

# 2.3.7
Expand Down
11 changes: 11 additions & 0 deletions decls/postcss.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,14 @@ export type postcss$rule = {
parent: Object,
nodes: Array<Object>,
}

export type postcss$result = {
css: string,
root: Object,
stylelint: {
disabledRanges: disabledRangeObject,
ruleSeverities?: Object,
customMessages?: Object,
quiet?: boolean,
},
}
4 changes: 2 additions & 2 deletions docs/developer-guide/plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Your plugin's rule name must be namespaced, e.g. `your-namespace/your-rule-name`

`stylelint.createPlugin(ruleName, ruleFunction)` ensures that your plugin will be setup properly alongside other rules.

In order for your plugin rule to work with the [standard configuration format](../user-guide/configuration.md#rules), `ruleFunction` should accept 2 arguments: the primary option and, optionally, an secondary options object.
In order for your plugin rule to work with the [standard configuration format](../user-guide/configuration.md#rules), `ruleFunction` should accept 2 arguments: the primary option and, optionally, a secondary options object.

`ruleFunction` should return a function that is essentially a little [PostCSS plugin](https://github.com/postcss/postcss/blob/master/docs/writing-a-plugin.md): it takes 2 arguments: the PostCSS Root (the parsed AST), and the PostCSS LazyResult. You'll have to [learn about the PostCSS API](https://github.com/postcss/postcss/blob/master/docs/api.md).

Expand Down Expand Up @@ -159,7 +159,7 @@ In addition to the standard parsers mentioned in the ["Working on rules"](rules.
- [postcss-resolve-nested-selector](https://github.com/davidtheclark/postcss-resolve-nested-selector): Given a (nested) selector in a PostCSS AST, return an array of resolved selectors.
- [style-search](https://github.com/davidtheclark/style-search): Search CSS (and CSS-like) strings, with sensitivity to whether matches occur inside strings, comments, and functions.

Have a look through [stylelint's internal utils](https://github.com/stylelint/stylelint/tree/master/lib/utils) and if you come across one that you need in your plugin, then please consider helping us extract it out into a external module.
Have a look through [stylelint's internal utils](https://github.com/stylelint/stylelint/tree/master/lib/utils) and if you come across one that you need in your plugin, then please consider helping us extract it out into an external module.

## Testing plugins

Expand Down
4 changes: 2 additions & 2 deletions docs/developer-guide/rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ Take the form of:

- Use complete CSS patterns i.e. avoid ellipses (`...`)
- Use standard CSS syntax (and use `css` code fences) by default.
- Use the minimum amount of code possible to communicate the patten e.g. if the rule targets selectors then use an empty rule e.g. `{}`.
- Use the minimum amount of code possible to communicate the pattern e.g. if the rule targets selectors then use an empty rule e.g. `{}`.
- Use `{}`, rather than `{ }` for empty rules.
- Use the `a` type selector by default.
- Use the `@media` at-rules by default.
Expand All @@ -195,7 +195,7 @@ The final step is to add references to the new rule in the following places:

Once you have something to show, you'll create a [pull request](https://github.com/stylelint/stylelint/compare) to continue the conversation.

## Adding a option to an existing rule
## Adding an option to an existing rule

First, open [an issue](https://github.com/stylelint/stylelint/issues/new) about the option you wish to add. We'll discuss its functionality and name there.

Expand Down
6 changes: 3 additions & 3 deletions docs/user-guide/about-rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ a { }

Notice how, for a rule like this, it does not make sense to have an option to enforce the opposite i.e. that every block *must* be empty.

### Max rules
### Max and min rules

`*-max-*` is used when a rule is *setting a limit* to something.
`*-max-*` and `*-min-*` rules are used when a rule is *setting a limit* to something.

For example, specifying the maximum number of digits after the "." in a number:

Expand Down Expand Up @@ -354,7 +354,7 @@ Say you want to disallow the value `none` for the `border` properties. You can d

Most `<color>` values are *functions*. As such, they can be (dis)allowed using either the `function-blacklist` or `function-whitelist` rules. There are two other color representations that aren't functions: named colors and hex colors. There are two specific rules that (dis)allow these: `color-named` and `color-no-hex`, respectively.

Say you want to enforce using a named color *if one exists for your chosen color* and use `hwb` color if one does not, e.g:
Say you want to enforce using a named color *if one exists for your chosen color* and use `hwb` color if one does not, e.g.:

```css
a {
Expand Down
2 changes: 1 addition & 1 deletion docs/user-guide/complementary-tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ A list of complementary tools built and maintained by the community.
## Build tool plugins

- [broccoli-stylelint](https://github.com/billybonks/broccoli-stylelint): A Broccoli plugin for stylelint.
- [ember-cli-stylelint](https://github.com/billybonks/ember-cli-stylelint): A Ember CLI plugin for stylelint.
- [ember-cli-stylelint](https://github.com/billybonks/ember-cli-stylelint): An Ember CLI plugin for stylelint.
- [grunt-stylelint](https://github.com/wikimedia/grunt-stylelint): A Grunt plugin for stylelint.
- [gulp-stylelint](https://github.com/olegskl/gulp-stylelint): A gulp plugin for stylelint.
- [stylelint-webpack-plugin](https://github.com/vieron/stylelint-webpack-plugin): A webpack plugin for stylelint.
Expand Down
4 changes: 2 additions & 2 deletions docs/user-guide/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ All rules accept a `message` secondary option that, if provided, will be substit
"message": "Lowercase letters are easier to distinguish from numbers"
} ],
"indentation": [ 2, {
"ignore": ["block"],
"except": ["block"],
"message": "Please use 2 spaces for indentation. Tabs make The Architect grumpy.",
"severity": "warning"
} ]
Expand Down Expand Up @@ -203,7 +203,7 @@ Or starting with `stylelint-config-standard`, then layering `myExtendableConfig`
}
```

The value of `"extends"` is a "locater" (or an array of "locaters") that is ultimately `require()`d, so can fit whatever format works with Node's `require.resolve()` algorithm. That means the a "locater" can be:
The value of `"extends"` is a "locater" (or an array of "locaters") that is ultimately `require()`d, so can fit whatever format works with Node's `require.resolve()` algorithm. That means a "locater" can be:

- The name of a module in `node_modules` (e.g. `stylelint-config-standard`; that module's `main` file must be a valid JSON configuration)
- An absolute path to a file (which makes sense if you're creating a JS object in a Node context and passing it in) with a `.js` or `.json` extension.
Expand Down
1 change: 1 addition & 0 deletions docs/user-guide/example-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ You might want to learn a little about [how rules are named and how they work to
"at-rule-no-unknown": true,
"at-rule-no-vendor-prefix": true,
"at-rule-semicolon-newline-after": "always",
"at-rule-semicolon-space-before": "always"|"never",
"at-rule-whitelist": string|[],
"block-closing-brace-empty-line-before": "always-multi-line"|"never",
"block-closing-brace-newline-after": "always"|"always-single-line"|"never-single-line"|"always-multi-line"|"never-multi-line",
Expand Down
2 changes: 1 addition & 1 deletion docs/user-guide/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ All these patterns disallow CSS identifiers that start with a digit, two hyphens

Use the [`defaultSeverity`](configuration.md#defaultseverity) configuration option.

## Can I bundle more than one sharable config within a npm package?
## Can I bundle more than one sharable config within an npm package?

A user can `require()` any file in your npm package, so all you need to do is document which paths point to configs (e.g. `require('my-package/config-2')`).

Expand Down
1 change: 1 addition & 0 deletions docs/user-guide/rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ Here are all the rules within stylelint, grouped by the [*thing*](http://apps.wo
- [`at-rule-no-unknown`](../../lib/rules/at-rule-no-unknown/README.md): Disallow unknown at-rules.
- [`at-rule-no-vendor-prefix`](../../lib/rules/at-rule-no-vendor-prefix/README.md): Disallow vendor prefixes for at-rules.
- [`at-rule-semicolon-newline-after`](../../lib/rules/at-rule-semicolon-newline-after/README.md): Require a newline after the semicolon of at-rules.
- [`at-rule-semicolon-space-before`](../../lib/rules/at-rule-semicolon-space-before/README.md): Require a single space or disallow whitespace before the semicolons of at rules.
- [`at-rule-whitelist`](../../lib/rules/at-rule-whitelist/README.md): Specify a whitelist of allowed at-rules.

### `stylelint-disable` comment
Expand Down
78 changes: 74 additions & 4 deletions lib/__tests__/standalone.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,21 +79,21 @@ it("standalone without input css and file(s) should throw error", () => {
})

it("standalone with non-existent-file should throw error with code 80", () => {
const expectedError = new Error("Files glob patterns specified did not match any files")
const expectedError = new Error(`${fixturesPath}/non-existent-file.css does not match any files`)
expectedError.code = 80

return standalone({
files: `${fixturesPath}/non-existent-file.css`,
config: configBlockNoEmpty,
}).then(() => {
throw new Error("should not have succeeded")
}).catch(actualError => {
}, actualError => {
expect(actualError).toEqual(expectedError)
})
})

it("standalone with non-existent-file and allowEmptyInput false should throw error with code 80", () => {
const expectedError = new Error("Files glob patterns specified did not match any files")
const expectedError = new Error(`${fixturesPath}/non-existent-file.css does not match any files`)
expectedError.code = 80

return standalone({
Expand All @@ -102,7 +102,77 @@ it("standalone with non-existent-file and allowEmptyInput false should throw err
allowEmptyInput: false,
}).then(() => {
throw new Error("should not have succeeded")
}).catch(actualError => {
}, actualError => {
expect(actualError).toEqual(expectedError)
})
})

it("standalone with two non-existent-files false should throw error with code 80", () => {
const expectedError = new Error(`${fixturesPath}/non-existent-file.css and ${fixturesPath}/another-non-existent-file.css do not match any files`)
expectedError.code = 80

return standalone({
files: [ `${fixturesPath}/non-existent-file.css`, `${fixturesPath}/another-non-existent-file.css` ],
config: configBlockNoEmpty,
}).then(() => {
throw new Error("should not have succeeded")
}, actualError => {
expect(actualError).toEqual(expectedError)
})
})

it("standalone with three or more non-existent-files false should throw error with code 80", () => {
const expectedError = new Error(`${fixturesPath}/non-existent-file.css, ${fixturesPath}/another-non-existent-file.css and ${fixturesPath}/third-non-existent-file.css do not match any files`)
expectedError.code = 80

return standalone({
files: [ `${fixturesPath}/non-existent-file.css`, `${fixturesPath}/another-non-existent-file.css`, `${fixturesPath}/third-non-existent-file.css` ],
config: configBlockNoEmpty,
}).then(() => {
throw new Error("should not have succeeded")
}, actualError => {
expect(actualError).toEqual(expectedError)
})
})

it("standalone with a glob that doesn't match anything false should throw error with code 80", () => {
const expectedError = new Error(`${fixturesPath}/nodir/**/*.css does not match any files`)
expectedError.code = 80

return standalone({
files: [`${fixturesPath}/nodir/**/*.css`],
config: configBlockNoEmpty,
}).then(() => {
throw new Error("should not have succeeded")
}, actualError => {
expect(actualError).toEqual(expectedError)
})
})

it("standalone with two globs that don't match anything should throw error with code 80", () => {
const expectedError = new Error(`${fixturesPath}/nodir/**/*.css and ${fixturesPath}/anotherdir/**/*.css do not match any files`)
expectedError.code = 80

return standalone({
files: [ `${fixturesPath}/nodir/**/*.css`, `${fixturesPath}/anotherdir/**/*.css` ],
config: configBlockNoEmpty,
}).then(() => {
throw new Error("should not have succeeded")
}, actualError => {
expect(actualError).toEqual(expectedError)
})
})

it("standalone with three globs that don't match anything false should throw error with code 80", () => {
const expectedError = new Error(`${fixturesPath}/nodir/**/*.css, ${fixturesPath}/anotherdir/**/*.css and ${fixturesPath}/athird/**/*.css do not match any files`)
expectedError.code = 80

return standalone({
files: [ `${fixturesPath}/nodir/**/*.css`, `${fixturesPath}/anotherdir/**/*.css`, `${fixturesPath}/athird/**/*.css` ],
config: configBlockNoEmpty,
}).then(() => {
throw new Error("should not have succeeded")
}, actualError => {
expect(actualError).toEqual(expectedError)
})
})
Expand Down
2 changes: 1 addition & 1 deletion lib/assignDisabledRanges.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const ALL_RULES = "all"
module.exports = function (
root/*: Object*/,
result/*: Object*/
) {
)/*: postcss$result*/ {
result.stylelint = result.stylelint || {}

// Most of the functions below work via side effects mutating
Expand Down
45 changes: 45 additions & 0 deletions lib/rules/at-rule-semicolon-space-before/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# at-rule-semicolon-space-before

Require a single space or disallow whitespace before the semicolons at-rules.

```css
@import "components/buttons";
/** ↑
* The space before this semicolon */
```

## Options

`string`: `"always"|"never"`

### `"always"`

There *must always* be a single space before the semicolons.

The following patterns is considered a warning:

```css
@import "components/buttons";
```

The following pattern is *not* considered a warning:

```css
@import "components/buttons" ;
```

### `"never"`

There *must never* be a single space before the semicolons.

The following patterns is considered a warning:

```css
@import "components/buttons" ;
```

The following pattern is *not* considered a warning:

```css
@import "components/buttons";
```

0 comments on commit 903d7c5

Please sign in to comment.