| |
| |
| |
| |
| |
| |
|
|
| import fs from 'fs' |
| import path from 'path' |
| import { program, Option, InvalidArgumentError } from 'commander' |
| import renderedContentLinkChecker from './rendered-content-link-checker' |
| import { getCoreInject, getUploadArtifactInject } from '@/links/scripts/action-injections' |
| import { allVersions } from '@/versions/lib/all-versions' |
| import github from '@/workflows/github' |
|
|
| const STATIC_PREFIXES = { |
| assets: path.resolve('assets'), |
| public: path.resolve(path.join('src', 'graphql', 'data')), |
| } |
| |
| for (const [key, value] of Object.entries(STATIC_PREFIXES)) { |
| if (!fs.existsSync(value)) { |
| throw new Error(`Can't find static prefix (${key}): ${value}`) |
| } |
| } |
|
|
| program |
| .description('Analyze all checked content files, render them, and check for flaws.') |
| .addOption( |
| new Option( |
| '-L, --level <LEVEL>', |
| 'Level of broken link to be marked as a flaw (default: "warning")', |
| ).choices(['all', 'warning', 'critical']), |
| ) |
| .option('-f, --filter <FILTER...>', 'Search filter(s) on the paths') |
| .option( |
| '-V, --version <VERSION...>', |
| "Specific versions to only do (e.g. 'free-pro-team@latest')", |
| (version) => { |
| if (!(version in allVersions)) { |
| for (const [key, data] of Object.entries(allVersions)) { |
| if (version === data.miscVersionName) { |
| return key |
| } |
| } |
| throw new InvalidArgumentError( |
| `'${version}' is not a recognized version. (not one of ${Object.keys(allVersions)})`, |
| ) |
| } |
| return version |
| }, |
| ) |
| .option('-v, --verbose', 'Verbose outputs') |
| .option( |
| '--create-report', |
| 'Create a report issue in report-repository if there are flaws. (default: false)', |
| ) |
| .option( |
| '--report-repository <REPOSITORY>', |
| 'Repository to create issue in. (default: "github/docs-content")', |
| ) |
| .option( |
| '--link-reports', |
| 'If comments should be made on previous report and new report "linking" them. (default: false)', |
| ) |
| .option( |
| '--report-author <AUTHOR>', |
| 'Previous author of report PR for linking. (default: "docs-bot")', |
| ) |
| .option( |
| '--report-label <LABEL>', |
| 'Label to assign to report issue. (default: "broken link report")', |
| ) |
| .option( |
| '--comment-on-pr <URI>', |
| 'For debugging. Comment on a PR in form "owner/repo-name:pr_number"', |
| ) |
| .option('--should-comment', 'Comments failed links on PR') |
| .option('--check-anchors', "Validate links that start with a '#' too") |
| .option('--check-images', 'Validate local images too') |
| .option('--check-external-links', 'Check external URLs too') |
| .option('--debug', "Loud about everything it's doing") |
| .option('--patient', 'Give external link checking longer timeouts and more retries') |
| .option('--random', 'Load pages in a random order (useful for debugging)') |
| .option('--bail', 'Exit on the first possible flaw') |
| .option('--verbose-url <BASE_URL>', 'Print the absolute URL if set') |
| .option('--fail-on-flaw', 'Throw error on link flaws (default: false)') |
| .option('--external-server-errors-as-warning', 'Treat server errors as warning (default: false)') |
| .option('--max <number>', 'integer argument (default: none)', (value) => { |
| const parsed = parseInt(value, 10) |
| if (isNaN(parsed)) { |
| throw new InvalidArgumentError('Not a number.') |
| } |
| return parsed |
| }) |
| .option( |
| '--list <file>.json', |
| 'JSON file containing an array of specific files to check (default: none)', |
| (filePath) => { |
| const resolvedPath = path.resolve(filePath) |
|
|
| let stats |
| try { |
| stats = fs.statSync(resolvedPath) |
| } catch { |
| |
| } |
|
|
| if (!stats || !stats.isFile()) { |
| throw new InvalidArgumentError('Not an existing file.') |
| } |
|
|
| return resolvedPath |
| }, |
| ) |
| .arguments('[files...]') |
| .parse(process.argv) |
|
|
| const opts = program.opts() |
| const files = program.args || opts.list |
| const octokit = github() |
|
|
| if (opts.list && Array.isArray(files) && files.length > 0) { |
| throw new InvalidArgumentError('Cannot specify both --list and a file list.') |
| } |
|
|
| |
| if (opts.commentOnPr) { |
| const [owner, repoPRNumber] = opts.commentOnPr.split('/') |
| const [repo, number] = repoPRNumber.split(':') |
| opts.shouldComment = true |
| opts.actionContext = { |
| owner, |
| repo, |
| pull_request: { |
| number, |
| }, |
| } |
| } |
|
|
| renderedContentLinkChecker( |
| getCoreInject(opts.debug), |
| octokit, |
| getUploadArtifactInject(opts.debug), |
| { |
| ...opts, |
| files, |
| }, |
| ) |
|
|