Skip to content

Commit b09a512

Browse files
authored
docs: detect and fix broken links (#16837)
* docs: detect and fix broken links * ci: build website before running lint:links * chore: update lint:links script * ci: refactor job * ci: increase memory * ci: fix * chore: use custom script * chore: fix script for windows * chore: fix script for windows * chore: update script * ci: remove unwanted changes * chore: fix script * chore: remove unwanted changes * docs: fix links
1 parent 92c1943 commit b09a512

8 files changed

Lines changed: 69 additions & 9 deletions

File tree

.github/workflows/ci.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ jobs:
3333
run: npm run lint:scss
3434
- name: Lint Docs JS Files
3535
run: node Makefile lintDocsJS
36+
- name: Build Docs Website
37+
working-directory: docs
38+
run: npm run build
39+
- name: Validate internal links
40+
working-directory: docs
41+
run: npm run lint:links
3642

3743
test_on_node:
3844
name: Test

conf/rule-type-list.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66
],
77
"deprecated": {
88
"name": "Deprecated",
9-
"description": "These rules have been deprecated in accordance with the <a href=\"/docs/use/rule-deprecation\">deprecation policy</a>, and replaced by newer rules:",
9+
"description": "These rules have been deprecated in accordance with the <a href=\"{{ '/use/rule-deprecation' | url }}\">deprecation policy</a>, and replaced by newer rules:",
1010
"rules": []
1111
},
1212
"removed": {
1313
"name": "Removed",
14-
"description": "These rules from older versions of ESLint (before the <a href=\"/docs/use/rule-deprecation\">deprecation policy</a> existed) have been replaced by newer rules:",
14+
"description": "These rules from older versions of ESLint (before the <a href=\"{{ '/use/rule-deprecation' | url }}\">deprecation policy</a> existed) have been replaced by newer rules:",
1515
"rules": [
1616
{ "removed": "generator-star", "replacedBy": ["generator-star-spacing"] },
1717
{ "removed": "global-strict", "replacedBy": ["strict"] },

docs/package.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"start": "npm-run-all build:sass build:postcss --parallel watch:*",
2020
"build": "npm-run-all build:sass build:postcss build:eleventy images",
2121
"lint:scss": "stylelint \"**/*.{scss,html}\"",
22+
"lint:links": "cross-env NODE_OPTIONS=--max-old-space-size=4096 node tools/validate-links.js",
2223
"lint:fix:scss": "npm run lint:scss -- --fix"
2324
},
2425
"devDependencies": {
@@ -27,15 +28,18 @@
2728
"@11ty/eleventy-navigation": "^0.3.2",
2829
"@11ty/eleventy-plugin-rss": "^1.1.1",
2930
"@11ty/eleventy-plugin-syntaxhighlight": "^3.1.2",
31+
"@munter/tap-render": "^0.2.0",
3032
"@types/markdown-it": "^12.2.3",
3133
"algoliasearch": "^4.12.1",
3234
"autoprefixer": "^10.4.13",
35+
"cross-env": "^7.0.3",
3336
"cssnano": "^5.1.14",
3437
"dom-parser": "^0.1.6",
3538
"eleventy-plugin-nesting-toc": "^1.3.0",
3639
"eleventy-plugin-page-assets": "^0.3.0",
3740
"eleventy-plugin-reading-time": "^0.0.1",
3841
"github-slugger": "^1.5.0",
42+
"hyperlink": "^5.0.4",
3943
"imagemin": "^8.0.1",
4044
"imagemin-cli": "^7.0.0",
4145
"js-yaml": "^3.14.1",
@@ -53,7 +57,8 @@
5357
"stylelint": "^14.13.0",
5458
"stylelint-config-html": "^1.1.0",
5559
"stylelint-config-standard": "^29.0.0",
56-
"stylelint-config-standard-scss": "^5.0.0"
60+
"stylelint-config-standard-scss": "^5.0.0",
61+
"tap-spot": "^1.1.2"
5762
},
5863
"engines": {
5964
"node": ">=14.0.0"

docs/src/_data/rules.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1893,7 +1893,7 @@
18931893
],
18941894
"deprecated": {
18951895
"name": "Deprecated",
1896-
"description": "These rules have been deprecated in accordance with the <a href=\"/docs/use/rule-deprecation\">deprecation policy</a>, and replaced by newer rules:",
1896+
"description": "These rules have been deprecated in accordance with the <a href=\"{{ '/use/rule-deprecation' | url }}\">deprecation policy</a>, and replaced by newer rules:",
18971897
"rules": [
18981898
{
18991899
"name": "callback-return",
@@ -2009,7 +2009,7 @@
20092009
},
20102010
"removed": {
20112011
"name": "Removed",
2012-
"description": "These rules from older versions of ESLint (before the <a href=\"/docs/use/rule-deprecation\">deprecation policy</a> existed) have been replaced by newer rules:",
2012+
"description": "These rules from older versions of ESLint (before the <a href=\"{{ '/use/rule-deprecation' | url }}\">deprecation policy</a> existed) have been replaced by newer rules:",
20132013
"rules": [
20142014
{
20152015
"removed": "generator-star",

docs/src/extend/custom-rules-deprecated.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ module.exports.schema = []; // no options
3737

3838
## Rule Basics
3939

40-
`schema` (array) specifies the [options](#options-schemas) so ESLint can prevent invalid [rule configurations](../use/configure/rules#configuring-rules)
40+
`schema` (array) specifies the [options](#options-schemas) so ESLint can prevent invalid [rule configurations](../use/configure/rules)
4141

4242
`create` (function) returns an object with methods that ESLint calls to "visit" nodes while traversing the abstract syntax tree (AST as defined by [ESTree](https://github.com/estree/estree)) of JavaScript code:
4343

docs/src/extend/custom-rules.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ The source file for a rule exports an object with the following properties.
6161

6262
**Important:** the `hasSuggestions` property is mandatory for rules that provide suggestions. If this property isn't set to `true`, ESLint will throw an error whenever the rule attempts to produce a suggestion. Omit the `hasSuggestions` property if the rule does not provide suggestions.
6363

64-
* `schema` (array) specifies the [options](#options-schemas) so ESLint can prevent invalid [rule configurations](../use/configure/rules#configuring-rules)
64+
* `schema` (array) specifies the [options](#options-schemas) so ESLint can prevent invalid [rule configurations](../use/configure/rules)
6565

6666
* `deprecated` (boolean) indicates whether the rule has been deprecated. You may omit the `deprecated` property if the rule has not been deprecated.
6767

@@ -110,7 +110,7 @@ The `context` object contains additional functionality that is helpful for rules
110110

111111
* `parserOptions` - the parser options configured for this run (more details [here](../use/configure/language-options#specifying-parser-options)).
112112
* `id` - the rule ID.
113-
* `options` - an array of the [configured options](../use/configure/rules#configuring-rules) for this rule. This array does not include the rule severity. For more information, see [here](#contextoptions).
113+
* `options` - an array of the [configured options](../use/configure/rules) for this rule. This array does not include the rule severity. For more information, see [here](#contextoptions).
114114
* `settings` - the [shared settings](../use/configure/configuration-files#adding-shared-settings) from configuration.
115115
* `parserPath` - the name of the `parser` from configuration.
116116
* `parserServices` - an object containing parser-provided services for rules. The default parser does not provide any services. However, if a rule is intended to be used with a custom parser, it could use `parserServices` to access anything provided by that parser. (For example, a TypeScript parser could provide the ability to get the computed type of a given node.)

docs/src/use/configure/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ All of these options give you fine-grained control over how ESLint treats your c
4242

4343
[**Configure Rules**](rules)
4444

45-
* [Configuring Rules](./rules#configuring-rules)
45+
* [Configuring Rules](./rules)
4646
* [Disabling Rules](./rules#disabling-rules)
4747

4848
[**Configure Plugins**](plugins)

docs/tools/validate-links.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
const path = require("path");
2+
const TapRender = require("@munter/tap-render");
3+
const spot = require("tap-spot");
4+
const hyperlink = require("hyperlink");
5+
6+
const tapRenderInstance = new TapRender();
7+
8+
tapRenderInstance.pipe(spot()).pipe(process.stdout);
9+
10+
const skipPatterns = [
11+
"https://",
12+
"fragment-redirect",
13+
"migrating-to",
14+
"/blog",
15+
"/play",
16+
"/team",
17+
"/donate",
18+
"/docs/latest",
19+
`src="null"`,
20+
];
21+
22+
const skipFilter = (report) =>
23+
Object.values(report).some((value) =>
24+
skipPatterns.some((pattern) => String(value).includes(pattern))
25+
);
26+
27+
(async () => {
28+
try {
29+
await hyperlink(
30+
{
31+
inputUrls: ["../_site/index.html"],
32+
root: path.resolve(__dirname, "../_site"),
33+
canonicalRoot: "https://eslint.org/docs/head/",
34+
recursive: true,
35+
internalOnly: true,
36+
pretty: true,
37+
concurrency: 25,
38+
skipFilter,
39+
},
40+
tapRenderInstance
41+
);
42+
} catch (err) {
43+
console.log(err.stack);
44+
process.exit(1);
45+
}
46+
const results = tapRenderInstance.close();
47+
48+
process.exit(results.fail ? 1 : 0);
49+
})();

0 commit comments

Comments
 (0)