Skip to content

Commit

Permalink
🏗 Ignore markdown templates in link checker by convention (ampproject…
Browse files Browse the repository at this point in the history
…#25226)

Also some modernizing and cleanup.

(Offshoot of ampproject#25164)
  • Loading branch information
alanorozco authored and Micajuine Ho committed Dec 27, 2019
1 parent 6667d56 commit c2dd8fd
Showing 1 changed file with 47 additions and 59 deletions.
106 changes: 47 additions & 59 deletions build-system/tasks/check-links.js
Expand Up @@ -51,68 +51,51 @@ function getMarkdownFiles() {
async function checkLinks() {
maybeUpdatePackages();
const markdownFiles = getMarkdownFiles();
const linkCheckers = markdownFiles.map(function(markdownFile) {
return runLinkChecker(markdownFile);
});
return BBPromise.all(linkCheckers).then(function(allResults) {
let deadLinksFound = false;
const filesWithDeadLinks = [];
allResults.map(function(results, index) {
// Skip files that were deleted by the PR.
if (!fs.existsSync(markdownFiles[index])) {
return;
}
const allResults = await Promise.all(markdownFiles.map(runLinkChecker));

const filesWithDeadLinks = allResults
.map((results, index) => {
let deadLinksFoundInFile = false;
results.forEach(function(result) {
for (const {link, status, statusCode} of results || []) {
// Skip links to files that were introduced by the PR.
if (isLinkToFileIntroducedByPR(result.link)) {
return;
if (isLinkToFileIntroducedByPR(link)) {
continue;
}
if (result.status === 'dead') {
deadLinksFound = true;
if (status === 'dead') {
deadLinksFoundInFile = true;
log(`[${red('✖')}] ${result.link} (${red(result.statusCode)})`);
log(`[${red('✖')}] ${link} (${red(statusCode)})`);
} else if (!isTravisBuild()) {
log(`[${green('✔')}] ${result.link}`);
log(`[${green('✔')}] ${link}`);
}
});
}
const filename = markdownFiles[index];
if (deadLinksFoundInFile) {
filesWithDeadLinks.push(markdownFiles[index]);
log(
red('ERROR'),
'Possible dead link(s) found in',
magenta(markdownFiles[index])
);
} else {
log(
green('SUCCESS'),
'All links in',
magenta(markdownFiles[index]),
'are alive.'
);
log(red('ERROR'), 'Possible dead link(s) found in', magenta(filename));
return filename;
}
});
if (deadLinksFound) {
log(
red('ERROR'),
'Please update dead link(s) in',
magenta(filesWithDeadLinks.join(',')),
'or whitelist them in build-system/tasks/check-links.js'
);
log(
yellow('NOTE'),
'If the link(s) above are not meant to resolve to a real webpage',
'surrounding them with backticks will exempt them from the link',
'checker.'
);
process.exitCode = 1;
} else {
log(
green('SUCCESS'),
'All links in all markdown files in this branch are alive.'
);
}
});
log(green('SUCCESS'), 'All links in', magenta(filename), 'are alive.');
})
.filter(filenameOrUndef => filenameOrUndef);

if (filesWithDeadLinks.length > 0) {
log(
red('ERROR'),
'Please update dead link(s) in',
magenta(filesWithDeadLinks.join(',')),
'or add them to allow-list in build-system/tasks/check-links.js'
);
log(
yellow('NOTE'),
'If the link(s) above are not meant to resolve to a real webpage,',
'surrounding them with backticks will exempt them from the link checker.'
);
process.exitCode = 1;
return;
}
log(
green('SUCCESS'),
'All links in all markdown files in this branch are alive.'
);
}

/**
Expand All @@ -128,12 +111,12 @@ function isLinkToFileIntroducedByPR(link) {
}

/**
* Filters out whitelisted links before running the link checker.
* Filters out links in allow-list before running the link checker.
*
* @param {string} markdown Original markdown.
* @return {string} Markdown after filtering out whitelisted links.
* @return {string} Markdown after filtering out allowed links.
*/
function filterWhitelistedLinks(markdown) {
function filterAllowedLinks(markdown) {
let filteredMarkdown = markdown;

// localhost links optionally preceded by ( or [ (not served on Travis)
Expand All @@ -151,7 +134,7 @@ function filterWhitelistedLinks(markdown) {
// Links inside a <pre> block (illustrative, and not always valid)
filteredMarkdown = filteredMarkdown.replace(/<pre>([^]*?)<\/pre>/g, '');

// After all whitelisting is done, clean up any remaining empty blocks bounded
// After allow-listing is done, clean up any remaining empty blocks bounded
// by backticks. Otherwise, `` will be treated as the start of a code block
// and confuse the link extractor.
filteredMarkdown = filteredMarkdown.replace(/\ \`\`\ /g, '');
Expand All @@ -167,12 +150,17 @@ function filterWhitelistedLinks(markdown) {
* @return {Promise} Used to wait until the async link checker is done.
*/
function runLinkChecker(markdownFile) {
// `.template.md` is a common suffix for files that may have interpolation
// tokens, possibly as part of their links. So we skip them.
if (path.basename(markdownFile).endsWith('.template.md')) {
return Promise.resolve();
}
// Skip files that were deleted by the PR.
if (!fs.existsSync(markdownFile)) {
return Promise.resolve();
}
const markdown = fs.readFileSync(markdownFile).toString();
const filteredMarkdown = filterWhitelistedLinks(markdown);
const filteredMarkdown = filterAllowedLinks(markdown);
const opts = {
baseUrl: 'file://' + path.dirname(path.resolve(markdownFile)),
};
Expand Down

0 comments on commit c2dd8fd

Please sign in to comment.