forked from open-telemetry/opentelemetry-collector-contrib
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update check-links to ignore 429 errors (#1229)
Add custom `markdown-link-check` to ignore 429 responses. Diff with https://github.com/tcort/markdown-link-check/blob/v3.8.1/markdown-link-check: ``` < const markdownLinkCheck = require('markdown-link-check'); --- > const markdownLinkCheck = require('./'); 134,138d133 < // workaround to ignore 429 responses (too many requests) < if (result.statusCode === 429) { < result.status = 'ignored' < } < ``` **Link to tracking Issue:** **Testing:** Tested locally with `circleci` command line tool. **Documentation:** Updated .circleci/check-links/README.md.
- Loading branch information
Showing
4 changed files
with
180 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
#!/usr/bin/env node | ||
|
||
'use strict'; | ||
|
||
const chalk = require('chalk'); | ||
const fs = require('fs'); | ||
const markdownLinkCheck = require('markdown-link-check'); | ||
const program = require('commander'); | ||
const request = require('request'); | ||
const url = require('url'); | ||
const path = require('path'); | ||
|
||
const statusLabels = { | ||
alive: chalk.green('✓'), | ||
dead: chalk.red('✖'), | ||
ignored: chalk.gray('/'), | ||
error: chalk.yellow('⚠'), | ||
}; | ||
|
||
const opts = {}; | ||
let filenameForOutput = ''; | ||
let stream = process.stdin; // read from stdin unless a filename is given | ||
|
||
program | ||
.option('-p, --progress', 'show progress bar') | ||
.option('-c, --config [config]', 'apply a config file (JSON), holding e.g. url specific header configuration') | ||
.option('-q, --quiet', 'displays errors only') | ||
.option('-v, --verbose', 'displays detailed error information') | ||
.arguments('[filenameOrUrl]') | ||
.action(function (filenameOrUrl) { | ||
filenameForOutput = filenameOrUrl; | ||
if (/https?:/.test(filenameOrUrl)) { | ||
request(filenameOrUrl, function (error, response, body) { | ||
if (error) { | ||
console.error(chalk.red('\nERROR: Unable to connect! Please provide a valid URL as an argument.')); | ||
process.exit(1); | ||
} | ||
else if (response.statusCode === 404){ | ||
console.error(chalk.red('\nERROR: 404 - File not found! Please provide a valid URL as an argument.')); | ||
process.exit(1); | ||
} else { | ||
stream = request.get(filenameOrUrl); | ||
} | ||
|
||
}); | ||
try { // extract baseUrl from supplied URL | ||
const parsed = url.parse(filenameOrUrl); | ||
delete parsed.search; | ||
delete parsed.hash; | ||
if (parsed.pathname.lastIndexOf('/') !== -1) { | ||
parsed.pathname = parsed.pathname.substr(0, parsed.pathname.lastIndexOf('/') + 1); | ||
} | ||
opts.baseUrl = url.format(parsed); | ||
} catch (err) { /* ignore error */ | ||
} | ||
} else { | ||
fs.stat(filenameOrUrl, function(error , stats){ | ||
if (!error && stats.isDirectory()){ | ||
console.error(chalk.red('\nERROR: ' + filenameOrUrl + ' is a directory! Please provide a vaild filename as an argument.')); | ||
process.exit(1); | ||
} | ||
}); | ||
opts.baseUrl = 'file://' + path.dirname(path.resolve(filenameOrUrl)); | ||
stream = fs.createReadStream(filenameOrUrl); | ||
} | ||
|
||
}).parse(process.argv); | ||
|
||
opts.showProgressBar = (program.progress === true); // force true or undefined to be true or false. | ||
opts.quiet = (program.quiet === true); | ||
opts.verbose = (program.verbose === true); | ||
|
||
let markdown = ''; // collect the markdown data, then process it | ||
|
||
stream | ||
.on('data', function (chunk) { | ||
markdown += chunk.toString(); | ||
}) | ||
.on('error', function(error) { | ||
if (error.code === 'ENOENT') { | ||
console.error(chalk.red('\nERROR: File not found! Please provide a vaild filename as an argument.')); | ||
} else { | ||
console.error(chalk.red(error)); | ||
} | ||
return process.exit(1); | ||
}) | ||
.on('end', function () { | ||
if (filenameForOutput) { | ||
console.log(chalk.cyan('\nFILE: ' + filenameForOutput)); | ||
} | ||
|
||
if (program.config) { | ||
fs.access(program.config, (fs.constants || fs).R_OK, function (err) { | ||
if (!err) { | ||
let configStream = fs.createReadStream(program.config); | ||
let configData = ''; | ||
|
||
configStream.on('data', function (chunk) { | ||
configData += chunk.toString(); | ||
}).on('end', function () { | ||
let config = JSON.parse(configData); | ||
|
||
opts.ignorePatterns = config.ignorePatterns; | ||
opts.replacementPatterns = config.replacementPatterns; | ||
opts.httpHeaders = config.httpHeaders; | ||
opts.ignoreDisable = config.ignoreDisable; | ||
|
||
runMarkdownLinkCheck(markdown, opts); | ||
}); | ||
} | ||
else { | ||
console.error(chalk.red('\nERROR: Config file not accessible.')); | ||
process.exit(1); | ||
} | ||
}); | ||
} | ||
else { | ||
runMarkdownLinkCheck(markdown, opts); | ||
} | ||
}); | ||
|
||
function runMarkdownLinkCheck(markdown, opts) { | ||
markdownLinkCheck(markdown, opts, function (err, results) { | ||
if (err) { | ||
console.error(chalk.red('\nERROR: something went wrong!')); | ||
console.error(err.stack); | ||
process.exit(1); | ||
} | ||
|
||
if (results.length === 0 && !opts.quiet) { | ||
console.log(chalk.yellow('No hyperlinks found!')); | ||
} | ||
results.forEach(function (result) { | ||
// workaround to ignore 429 responses (too many requests) | ||
if (result.statusCode === 429) { | ||
result.status = 'ignored' | ||
} | ||
|
||
// Skip messages for non-deadlinks in quiet mode. | ||
if (opts.quiet && result.status !== 'dead') { | ||
return; | ||
} | ||
|
||
if (opts.verbose) { | ||
if (result.err) { | ||
console.log('[%s] %s → Status: %s %s', statusLabels[result.status], result.link, result.statusCode, result.err); | ||
} else { | ||
console.log('[%s] %s → Status: %s', statusLabels[result.status], result.link, result.statusCode); | ||
} | ||
} | ||
else { | ||
console.log('[%s] %s', statusLabels[result.status], result.link); | ||
} | ||
}); | ||
console.log('\n%s links checked.', results.length); | ||
if (results.some((result) => result.status === 'dead')) { | ||
let deadLinks = results.filter(result => { return result.status === 'dead'; }); | ||
console.error(chalk.red('\nERROR: %s dead links found!'), deadLinks.length); | ||
deadLinks.forEach(function (result) { | ||
console.log('[%s] %s → Status: %s', statusLabels[result.status], result.link, result.statusCode); | ||
}); | ||
process.exit(1); | ||
} | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -300,5 +300,8 @@ jobs: | |
- run: | ||
name: Check links in markdown docs | ||
command: | | ||
sudo npm install -g markdown-link-check | ||
pushd $HOME | ||
npm install --save-dev [email protected] | ||
popd | ||
export NODE_PATH=$HOME/node_modules | ||
bash .circleci/check-links/check-links.sh |