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
2010function 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
7565function 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
9181async 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
178189gulp . task ( 'checkdocs' , gulp . parallel ( 'checkV2docs' , 'checkV3docs' ) ) ;
0 commit comments