Skip to content

Commit 4b64be2

Browse files
committed
New attempt to use linkinator
1 parent 0e5e7c6 commit 4b64be2

File tree

3 files changed

+766
-2977
lines changed

3 files changed

+766
-2977
lines changed

docs/v3/gulpfile.js

Lines changed: 76 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,11 @@
1-
const fs = require('fs');
2-
const gulp = require('gulp');
3-
const { exec } = require('child_process');
4-
const express = require('express');
5-
const { glob } = require('glob');
6-
const cheerio = require('cheerio');
7-
8-
async function linkCheck(options) {
9-
const { LinkChecker } = await import('linkinator');
10-
const checker = new LinkChecker();
11-
12-
return await checker.check({
13-
path: options.pageUrls[0],
14-
linksToSkip: options.linksToSkip,
15-
recurse: true,
16-
concurrency: 5
17-
});
18-
}
1+
import { exec } from 'child_process';
2+
import { readFileSync } from 'fs';
3+
import gulp from 'gulp';
4+
import express from 'express';
5+
import { glob } from 'glob';
6+
import { LinkChecker } from 'linkinator';
7+
8+
const cheerio = await import('cheerio');
199

2010
function displayErrors(err, stdout, stderr) {
2111
if (err) {
@@ -30,7 +20,7 @@ function checkInternalLinksAndExit(htmlPath) {
3020
const duplicateHeadingIds = [];
3121
const seenHeadingIds = new Set();
3222
const badLinks = [];
33-
const $ = cheerio.load(fs.readFileSync(htmlPath, 'utf8'));
23+
const $ = cheerio.load(readFileSync(htmlPath, 'utf8'));
3424

3525
$('a').each((index, anchor) => {
3626
const href = $(anchor).attr('href') || '';
@@ -73,7 +63,7 @@ function checkInternalLinksAndExit(htmlPath) {
7363
}
7464

7565
function checkSyntaxErrorsAndExit(htmlPath) {
76-
const $ = cheerio.load(fs.readFileSync(htmlPath, 'utf8'));
66+
const $ = cheerio.load(readFileSync(htmlPath, 'utf8'));
7767
const syntaxErrors = $('code .err');
7868

7969
if (syntaxErrors.length) {
@@ -84,37 +74,65 @@ function checkSyntaxErrorsAndExit(htmlPath) {
8474
console.error('👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆\n')
8575
});
8676

87-
process.exit(1)
77+
process.exit(1);
8878
}
8979
}
9080

9181
async function checkPathAndExit(path, options, done) {
9282
const app = express();
9383
app.use(express.static(path));
9484
const server = app.listen({ port: 8001 });
95-
85+
86+
const url = 'http://localhost:8001/';
87+
88+
const config = {
89+
path: url,
90+
linksToSkip: options.linksToSkip || [],
91+
recurse: options.recurse,
92+
silent: options.silent,
93+
markdown: options.markdown,
94+
};
95+
9696
try {
97-
const result = await linkCheck({
98-
linksToSkip: options.linksToSkip,
99-
pageUrls: (options.pageUrls && options.pageUrls.length) ? options.pageUrls : ['http://localhost:8001/']
100-
});
97+
const checker = new LinkChecker();
98+
99+
if (path === '../v2') {
100+
const htmlFiles = await glob(path + '/**/*.html');
101+
let allResults = { links: [] };
102+
for (let file of htmlFiles) {
103+
const fileUrl = url + file.substr(path.length);
104+
const fileConfig = { ...config, path: fileUrl };
105+
const results = await checker.check(fileConfig);
106+
allResults.links = allResults.links.concat(results.links);
107+
}
108+
displayResults(allResults);
109+
} else {
110+
const results = await checker.check(config);
111+
displayResults(results);
112+
}
101113

102114
server.close();
103115
done();
104116

105-
if (result.passed === false) {
106-
// linkinator gives us a state for each link, e.g. 'BROKEN', 'OK', 'SKIPPED' etc.
107-
const brokenLinks = result.links.filter(x => x.state === 'BROKEN');
108-
console.error(`Found ${brokenLinks.length} broken links:`);
109-
brokenLinks.forEach((link) => {
110-
console.error(`- ${link.url}: ${link.status}`);
111-
});
112-
process.exit(1);
113-
}
114117
} catch (err) {
115118
server.close();
116-
done();
117-
displayErrors(err, '', '');
119+
done(err);
120+
process.exit(1);
121+
}
122+
}
123+
124+
function displayResults(results) {
125+
const totalLinks = results.links.length;
126+
const brokenLinks = results.links.filter(link => link.state === 'BROKEN');
127+
128+
console.log(`Total Links Checked: ${totalLinks}`);
129+
console.log(`Broken Links Found: ${brokenLinks.length}`);
130+
if (brokenLinks.length > 0) {
131+
console.log('Broken Links:');
132+
brokenLinks.forEach(link => {
133+
console.log(` - ${link.url} (status: ${link.status})`);
134+
});
135+
process.exitCode = 1;
118136
}
119137
}
120138

@@ -143,36 +161,29 @@ gulp.task('checkV3docs', gulp.series('build', done => {
143161
checkInternalLinksAndExit('build/index.html');
144162
checkSyntaxErrorsAndExit('build/index.html');
145163

146-
checkPathAndExit('build', {
147-
checkLinks: true,
148-
summary: true,
149-
terse: true,
150-
onlySameDomain: true,
151-
pageUrls: ['http://localhost:8001/'],
152-
linksToSkip: ['http://localhost:8001/version/release-candidate']
153-
}, done);
164+
try {
165+
checkPathAndExit('build', {
166+
linksToSkip: ['http://localhost:8001/version/release-candidate'],
167+
recurse: true,
168+
silent: true,
169+
markdown: true,
170+
}, done);
171+
} catch (err) {
172+
done(err);
173+
}
154174
}));
155175

156-
gulp.task('checkV2docs', async (done) => {
157-
const htmlFiles = await new Promise((resolve, reject) => {
158-
glob('../v2/**/*.html', (err, matches) => {
159-
if (err) return reject(err);
160-
resolve(matches);
161-
});
162-
});
163-
164-
const fixedFiles = htmlFiles.map(fname => {
165-
return 'http://localhost:8001' + fname.substr('../v2'.length);
166-
});
167-
168-
checkPathAndExit('../v2', {
169-
checkLinks: true,
170-
summary: true,
171-
terse: true,
172-
onlySameDomain: true,
173-
pageUrls: ['http://localhost:8001/'].concat(fixedFiles),
174-
linksToSkip: []
175-
}, done);
176+
gulp.task('checkV2docs', done => {
177+
try {
178+
checkPathAndExit('../v2', {
179+
linksToSkip: [],
180+
recurse: true,
181+
silent: true,
182+
markdown: true,
183+
}, done);
184+
} catch (err) {
185+
done(err);
186+
}
176187
});
177188

178189
gulp.task('checkdocs', gulp.parallel('checkV2docs', 'checkV3docs'));

0 commit comments

Comments
 (0)