@@ -4,7 +4,7 @@ const path = require('path')
44const fs = require ( 'fs' )
55const linkinator = require ( 'linkinator' )
66const program = require ( 'commander' )
7- const { pull } = require ( 'lodash' )
7+ const { pull, uniq } = require ( 'lodash' )
88const checker = new linkinator . LinkChecker ( )
99const rimraf = require ( 'rimraf' ) . sync
1010const mkdirp = require ( 'mkdirp' ) . sync
@@ -16,14 +16,11 @@ const got = require('got')
1616// Links with these codes may or may not really be broken
1717const retryStatusCodes = [ 429 , 503 , 'Undefined' ]
1818
19- // Broken S3 image URLs result in 403s, broken docs URLs results in 404s
20- const allBrokenStatusCodes = [ 403 , 404 , ...retryStatusCodes ]
21-
2219// [start-readme]
2320//
2421// This script runs once per day via a scheduled GitHub Action to check all links in
2522// English content, not including deprecated Enterprise Server content. It opens an issue
26- // if it finds broken links. To exclude a link, add it to `lib/excluded-links.js`.
23+ // if it finds broken links. To exclude a link path , add it to `lib/excluded-links.js`.
2724//
2825// [end-readme]
2926
6562async function main ( ) {
6663 // Clear and recreate a directory for logs.
6764 const logFile = path . join ( __dirname , '../.linkinator/full.log' )
68- rimraf ( path . dirname ( logFile ) )
69- mkdirp ( path . dirname ( logFile ) )
65+ rimraf ( logFile )
66+ mkdirp ( logFile )
7067
7168 // Update CLI output and append to logfile after each checked link.
7269 checker . on ( 'link' , result => {
@@ -79,7 +76,7 @@ async function main () {
7976 // Scan is complete! Filter the results for broken links.
8077 const brokenLinks = result
8178 . filter ( link => link . state === 'BROKEN' )
82- // Coerce undefined status codes into strings so we can filter for them like the other status codes.
79+ // Coerce undefined status codes into strings so we can filter and display them (otherwise they stringify as 0)
8380 . map ( link => {
8481 if ( ! link . status ) link . status = 'Undefined'
8582 return link
@@ -92,12 +89,11 @@ async function main () {
9289 await Promise . all ( linksToRetry
9390 . map ( async ( link ) => {
9491 try {
95- const r = await got ( link . url )
96- // Remove the link from the list if got can access it.
97- if ( ! allBrokenStatusCodes . find ( brokenStatusCode => r . statusCode === brokenStatusCode ) ) {
98- pull ( brokenLinks , link )
99- }
100- // Do nothing if the URL is invalid, since it's already captured in the broken list.
92+ // got throws an HTTPError if response code is not 2xx or 3xx.
93+ // If got succeeds, we can remove the link from the list.
94+ await got ( link . url )
95+ pull ( brokenLinks , link )
96+ // If got fails, do nothing. The link is already in the broken list.
10197 } catch ( err ) {
10298 // noop
10399 }
@@ -111,22 +107,24 @@ async function main () {
111107
112108 // Format and display the results.
113109 console . log ( `${ brokenLinks . length } broken links found on docs.github.com\n` )
114- allBrokenStatusCodes
115- . forEach ( statusCode => displayBrokenLinks ( statusCode , brokenLinks ) )
110+ displayBrokenLinks ( brokenLinks )
116111
117112 // Exit unsuccessfully if broken links are found.
118113 process . exit ( 1 )
119114}
120115
121- function displayBrokenLinks ( statusCode , brokenLinks ) {
122- const brokenLinksForStatus = brokenLinks . filter ( x => x . status === statusCode )
116+ function displayBrokenLinks ( brokenLinks ) {
117+ // Sort results by status code.
118+ const allStatusCodes = uniq ( brokenLinks . map ( x => x . status ) )
123119
124- if ( ! brokenLinksForStatus . length ) return
120+ allStatusCodes . forEach ( statusCode => {
121+ const brokenLinksForStatus = brokenLinks . filter ( x => x . status === statusCode )
125122
126- console . log ( `## Status code ${ statusCode } : Found ${ brokenLinksForStatus . length } broken links` )
127- console . log ( '```' )
128- brokenLinksForStatus . forEach ( brokenLinkObj => {
129- console . log ( JSON . stringify ( brokenLinkObj , null , 2 ) )
123+ console . log ( `## Status code ${ statusCode } : Found ${ brokenLinksForStatus . length } broken links` )
124+ console . log ( '```' )
125+ brokenLinksForStatus . forEach ( brokenLinkObj => {
126+ console . log ( JSON . stringify ( brokenLinkObj , null , 2 ) )
127+ } )
128+ console . log ( '```' )
130129 } )
131- console . log ( '```' )
132130}
0 commit comments