Skip to content

Commit

Permalink
feat: add yml/file-extension rule (#188)
Browse files Browse the repository at this point in the history
* feat: add `yml/file-extension` rule

* Create fluffy-grapes-raise.md
  • Loading branch information
ota-meshi authored Sep 6, 2022
1 parent e9fbf41 commit 2691fab
Show file tree
Hide file tree
Showing 9 changed files with 188 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/fluffy-grapes-raise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"eslint-plugin-yml": minor
---

feat: add `yml/file-extension` rule
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ The rules with the following star :star: are included in the config.
| [yml/block-mapping](https://ota-meshi.github.io/eslint-plugin-yml/rules/block-mapping.html) | require or disallow block style mappings. | :wrench: | | :star: |
| [yml/block-sequence-hyphen-indicator-newline](https://ota-meshi.github.io/eslint-plugin-yml/rules/block-sequence-hyphen-indicator-newline.html) | enforce consistent line breaks after `-` indicator | :wrench: | | :star: |
| [yml/block-sequence](https://ota-meshi.github.io/eslint-plugin-yml/rules/block-sequence.html) | require or disallow block style sequences. | :wrench: | | :star: |
| [yml/file-extension](https://ota-meshi.github.io/eslint-plugin-yml/rules/file-extension.html) | enforce YAML file extension | | | |
| [yml/indent](https://ota-meshi.github.io/eslint-plugin-yml/rules/indent.html) | enforce consistent indentation | :wrench: | | :star: |
| [yml/key-name-casing](https://ota-meshi.github.io/eslint-plugin-yml/rules/key-name-casing.html) | enforce naming convention to key names | | | |
| [yml/no-empty-document](https://ota-meshi.github.io/eslint-plugin-yml/rules/no-empty-document.html) | disallow empty document | | :star: | :star: |
Expand Down
1 change: 1 addition & 0 deletions docs/rules/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ The rules with the following star :star: are included in the `plugin:yml/recomme
| [yml/block-mapping](./block-mapping.md) | require or disallow block style mappings. | :wrench: | | :star: |
| [yml/block-sequence-hyphen-indicator-newline](./block-sequence-hyphen-indicator-newline.md) | enforce consistent line breaks after `-` indicator | :wrench: | | :star: |
| [yml/block-sequence](./block-sequence.md) | require or disallow block style sequences. | :wrench: | | :star: |
| [yml/file-extension](./file-extension.md) | enforce YAML file extension | | | |
| [yml/indent](./indent.md) | enforce consistent indentation | :wrench: | | :star: |
| [yml/key-name-casing](./key-name-casing.md) | enforce naming convention to key names | | | |
| [yml/no-empty-document](./no-empty-document.md) | disallow empty document | | :star: | :star: |
Expand Down
1 change: 0 additions & 1 deletion docs/rules/block-mapping-colon-indicator-newline.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ description: "enforce consistent line breaks after `:` indicator"
> enforce consistent line breaks after `:` indicator
- :exclamation: <badge text="This rule has not been released yet." vertical="middle" type="error"> **_This rule has not been released yet._** </badge>
- :gear: This rule is included in .
- :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule.

## :book: Rule Details
Expand Down
60 changes: 60 additions & 0 deletions docs/rules/file-extension.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
pageClass: "rule-details"
sidebarDepth: 0
title: "yml/file-extension"
description: "enforce YAML file extension"
---

# yml/file-extension

> enforce YAML file extension
- :exclamation: <badge text="This rule has not been released yet." vertical="middle" type="error"> **_This rule has not been released yet._** </badge>

## :book: Rule Details

This rule aims to enforce YAML file extension.

<eslint-code-block file-name="example.yaml">

<!-- eslint-skip -->

```yaml
# ✓ GOOD
# filename is `example.yaml`

# eslint yml/file-extension: 'error'
```

</eslint-code-block>

<eslint-code-block file-name="example.yaml">

<!-- eslint-skip -->

```yaml
# ✗ BAD
# filename is `example.yml`

# eslint yml/file-extension: 'error'
```

</eslint-code-block>

## :wrench: Options

```yaml
yml/file-extension:
- error
- extension: yaml # or 'yml'
caseSensitive: true
```
- `extension` ... The extension you want to enforce. Default is `"yaml"`.
- `caseSensitive` ... Specify `true` to enforce lowercase extension. Default is `true`.

## :mag: Implementation

- [Rule source](https://github.com/ota-meshi/eslint-plugin-yml/blob/master/src/rules/file-extension.ts)
- [Test source](https://github.com/ota-meshi/eslint-plugin-yml/blob/master/tests/src/rules/file-extension.ts)
- [Test fixture sources](https://github.com/ota-meshi/eslint-plugin-yml/tree/master/tests/fixtures/rules/file-extension)
60 changes: 60 additions & 0 deletions src/rules/file-extension.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import path from "path";
import { createRule } from "../utils";

export default createRule("file-extension", {
meta: {
docs: {
description: "enforce YAML file extension",
categories: [],
extensionRule: false,
layout: false,
},
schema: [
{
type: "object",
properties: {
extension: {
enum: ["yaml", "yml"],
},
caseSensitive: {
type: "boolean",
},
},
additionalProperties: false,
},
],
messages: {
unexpected: `Expected extension '{{expected}}' but used extension '{{actual}}'.`,
},
type: "suggestion",
},
create(context) {
if (!context.parserServices.isYAML) {
return {};
}
const expected: string = context.options[0]?.extension || "yaml";
const caseSensitive: string = context.options[0]?.caseSensitive ?? true;

return {
Program(node) {
const filename = context.getFilename();
const actual = path.extname(filename);
if (
(caseSensitive ? actual : actual.toLocaleLowerCase()) ===
`.${expected}`
) {
return;
}
context.report({
node,
loc: node.loc.start,
messageId: "unexpected",
data: {
expected: `.${expected}`,
actual,
},
});
},
};
},
});
2 changes: 2 additions & 0 deletions src/utils/rules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import blockMappingQuestionIndicatorNewline from "../rules/block-mapping-questio
import blockMapping from "../rules/block-mapping";
import blockSequenceHyphenIndicatorNewline from "../rules/block-sequence-hyphen-indicator-newline";
import blockSequence from "../rules/block-sequence";
import fileExtension from "../rules/file-extension";
import flowMappingCurlyNewline from "../rules/flow-mapping-curly-newline";
import flowMappingCurlySpacing from "../rules/flow-mapping-curly-spacing";
import flowSequenceBracketNewline from "../rules/flow-sequence-bracket-newline";
Expand Down Expand Up @@ -32,6 +33,7 @@ export const rules = [
blockMapping,
blockSequenceHyphenIndicatorNewline,
blockSequence,
fileExtension,
flowMappingCurlyNewline,
flowMappingCurlySpacing,
flowSequenceBracketNewline,
Expand Down
58 changes: 58 additions & 0 deletions tests/src/rules/file-extension.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { RuleTester } from "eslint";
import rule from "../../../src/rules/file-extension";

const tester = new RuleTester({
parser: require.resolve("yaml-eslint-parser"),
parserOptions: {
ecmaVersion: 2020,
},
});

tester.run("file-extension", rule as any, {
valid: [
{
filename: "test.yaml",
code: "a: b",
},
{
filename: "test.yml",
code: "a: b",
options: [{ extension: "yml" }],
},
{
filename: "test.yaml",
code: "a: b",
options: [{ extension: "yaml" }],
},
{
filename: "test.YAML",
code: "a: b",
options: [{ extension: "yaml", caseSensitive: false }],
},
],
invalid: [
{
filename: "test.yml",
code: "a: b",
errors: ["Expected extension '.yaml' but used extension '.yml'."],
},
{
filename: "test.yaml",
code: "a: b",
options: [{ extension: "yml" }],
errors: ["Expected extension '.yml' but used extension '.yaml'."],
},
{
filename: "test.yml",
code: "a: b",
options: [{ extension: "yaml" }],
errors: ["Expected extension '.yaml' but used extension '.yml'."],
},
{
filename: "test.YAML",
code: "a: b",
options: [{ extension: "yaml" }],
errors: ["Expected extension '.yaml' but used extension '.YAML'."],
},
],
});
2 changes: 1 addition & 1 deletion tools/update-docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ class DocFile {
notes.push("- :warning: This rule was **deprecated**.");
}
} else {
if (categories) {
if (categories && categories.length) {
const presets = [];
// eslint-disable-next-line @typescript-eslint/require-array-sort-compare -- ignore
for (const cat of categories.sort()) {
Expand Down

0 comments on commit 2691fab

Please sign in to comment.