* Checks a given markdown file for dead links. * * @param {string} file * @return {!Promise<{file: string, containsDeadLinks: boolean}>}
(file)
| 95 | * @return {!Promise<{file: string, containsDeadLinks: boolean}>} |
| 96 | */ |
| 97 | function checkLinksInFile(file) { |
| 98 | let markdown = fs.readFileSync(file).toString(); |
| 99 | |
| 100 | // Links inside <code> blocks are illustrative and not always valid. Must be |
| 101 | // removed because markdownLinkCheck() does not ignore them like <pre> blocks. |
| 102 | markdown = markdown.replace(/<code>([^]*?)<\/code>/g, ''); |
| 103 | |
| 104 | const opts = { |
| 105 | // Relative links start at the markdown file's path. |
| 106 | baseUrl: 'file://' + path.dirname(path.resolve(file)), |
| 107 | ignorePatterns: [ |
| 108 | // Please note: This list is for links that are present many times in the repository. |
| 109 | // If a single link is failing, you can remove it directly using a surrounding |
| 110 | // comment directive markdown-link-check-disable / markdown-link-check-enable. |
| 111 | |
| 112 | // Localhost links don't work unless a `amp` server is running. |
| 113 | {pattern: /localhost/}, |
| 114 | // codepen returns a 503 for these link checks |
| 115 | {pattern: /https:\/\/codepen.*/}, |
| 116 | // developers.google.com links are assumed to exist |
| 117 | {pattern: /https:\/\/developers.google.com\/.*/}, |
| 118 | // anchor links should be ignored |
| 119 | {pattern: /^#/}, |
| 120 | // GitHub PRs and Issues can be assumed to exist |
| 121 | {pattern: /https:\/\/github.com\/ampproject\/amphtml\/(pull|issue)\/.*/}, |
| 122 | // Templated links are merely used to generate other markdown files. |
| 123 | {pattern: /\$\{[a-z]*\}/}, |
| 124 | {pattern: /https:.*?__component_name\w*__/}, |
| 125 | ], |
| 126 | httpHeaders: [ |
| 127 | { |
| 128 | urls: ['https://'], |
| 129 | headers: { |
| 130 | 'User-Agent': USER_AGENT, |
| 131 | }, |
| 132 | }, |
| 133 | ], |
| 134 | // Ignore: |
| 135 | // - 403 [Forbidden], some sites block automated requests. |
| 136 | // - 429 [Too Many Requests], some sites rate-limit requests. |
| 137 | aliveStatusCodes: [200, 403, 429], |
| 138 | }; |
| 139 | |
| 140 | return new Promise((resolve, reject) => { |
| 141 | markdownLinkCheck(markdown, opts, (err, results) => { |
| 142 | if (err) { |
| 143 | reject(err); |
| 144 | return; |
| 145 | } |
| 146 | let containsDeadLinks = false; |
| 147 | for (const result of results) { |
| 148 | const {link, statusCode} = result; |
| 149 | let {status} = result; |
| 150 | // Skip links to files that were introduced by the PR. |
| 151 | if (isLinkToFileIntroducedByPR(link) && status == 'dead') { |
| 152 | // Log links with the correct github base as alive, otherwise flag deadlinks. |
| 153 | const isValid = filesIntroducedByPr.some((file) => { |
| 154 | return link === GITHUB_BASE_PATH + file; |
nothing calls this directly
no test coverage detected