skuba 9.0.0-renovate-eslint-9.x-20240923103202 → 9.0.1-upgrade-cdk-template-20241002233314

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/lib/api/github/issueComment.js.map +2 -2
  2. package/lib/cli/adapter/eslint.js +4 -4
  3. package/lib/cli/adapter/eslint.js.map +2 -2
  4. package/lib/cli/lint/autofix.js +0 -15
  5. package/lib/cli/lint/autofix.js.map +2 -2
  6. package/lib/cli/lint/internalLints/upgrade/patches/8.2.1/collapseDuplicateMergeKeys.js +15 -6
  7. package/lib/cli/lint/internalLints/upgrade/patches/8.2.1/collapseDuplicateMergeKeys.js.map +2 -2
  8. package/lib/cli/lint/internalLints/upgrade/patches/8.2.1/index.js +10 -0
  9. package/lib/cli/lint/internalLints/upgrade/patches/8.2.1/index.js.map +2 -2
  10. package/lib/cli/lint/internalLints/upgrade/patches/8.2.1/moveNpmrcMounts.d.ts +2 -0
  11. package/lib/cli/lint/internalLints/upgrade/patches/8.2.1/moveNpmrcMounts.js +82 -0
  12. package/lib/cli/lint/internalLints/upgrade/patches/8.2.1/moveNpmrcMounts.js.map +7 -0
  13. package/lib/cli/lint/internalLints/upgrade/patches/8.2.1/patchDockerCompose.js +1 -3
  14. package/lib/cli/lint/internalLints/upgrade/patches/8.2.1/patchDockerCompose.js.map +2 -2
  15. package/lib/cli/lint/internalLints/upgrade/patches/8.2.1/patchDockerImages.d.ts +2 -0
  16. package/lib/cli/lint/internalLints/upgrade/patches/8.2.1/patchDockerImages.js +141 -0
  17. package/lib/cli/lint/internalLints/upgrade/patches/8.2.1/patchDockerImages.js.map +7 -0
  18. package/lib/cli/lint/internalLints/upgrade/patches/8.2.1/upgradeESLint.js +5 -3
  19. package/lib/cli/lint/internalLints/upgrade/patches/8.2.1/upgradeESLint.js.map +2 -2
  20. package/lib/wrapper/requestListener.js.map +2 -2
  21. package/package.json +9 -9
  22. package/template/express-rest-api/.buildkite/pipeline.yml +2 -2
  23. package/template/express-rest-api/Dockerfile +1 -1
  24. package/template/express-rest-api/Dockerfile.dev-deps +1 -1
  25. package/template/express-rest-api/package.json +1 -1
  26. package/template/greeter/.buildkite/pipeline.yml +2 -2
  27. package/template/greeter/Dockerfile +1 -1
  28. package/template/greeter/package.json +1 -1
  29. package/template/koa-rest-api/.buildkite/pipeline.yml +2 -2
  30. package/template/koa-rest-api/Dockerfile +1 -1
  31. package/template/koa-rest-api/Dockerfile.dev-deps +1 -1
  32. package/template/koa-rest-api/package.json +4 -4
  33. package/template/koa-rest-api/src/framework/bodyParser.ts +1 -1
  34. package/template/koa-rest-api/src/framework/server.test.ts +0 -1
  35. package/template/lambda-sqs-worker/.buildkite/pipeline.yml +2 -2
  36. package/template/lambda-sqs-worker/Dockerfile +1 -1
  37. package/template/lambda-sqs-worker/package.json +2 -2
  38. package/template/lambda-sqs-worker/serverless.yml +1 -1
  39. package/template/lambda-sqs-worker-cdk/.buildkite/pipeline.yml +2 -2
  40. package/template/lambda-sqs-worker-cdk/.env +1 -0
  41. package/template/lambda-sqs-worker-cdk/Dockerfile +1 -1
  42. package/template/lambda-sqs-worker-cdk/README.md +145 -0
  43. package/template/lambda-sqs-worker-cdk/infra/__snapshots__/appStack.test.ts.snap +102 -134
  44. package/template/lambda-sqs-worker-cdk/infra/appStack.test.ts +13 -2
  45. package/template/lambda-sqs-worker-cdk/infra/appStack.ts +52 -6
  46. package/template/lambda-sqs-worker-cdk/infra/config.ts +3 -0
  47. package/template/lambda-sqs-worker-cdk/package.json +9 -2
  48. package/template/lambda-sqs-worker-cdk/src/app.test.ts +116 -0
  49. package/template/lambda-sqs-worker-cdk/src/app.ts +43 -21
  50. package/template/lambda-sqs-worker-cdk/src/config.ts +15 -0
  51. package/template/lambda-sqs-worker-cdk/src/framework/handler.test.ts +61 -0
  52. package/template/lambda-sqs-worker-cdk/src/framework/handler.ts +43 -0
  53. package/template/lambda-sqs-worker-cdk/src/framework/logging.ts +27 -0
  54. package/template/lambda-sqs-worker-cdk/src/framework/metrics.ts +14 -0
  55. package/template/lambda-sqs-worker-cdk/src/framework/validation.test.ts +84 -0
  56. package/template/lambda-sqs-worker-cdk/src/framework/validation.ts +10 -0
  57. package/template/lambda-sqs-worker-cdk/src/mapping/jobScorer.ts +22 -0
  58. package/template/lambda-sqs-worker-cdk/src/services/aws.ts +5 -0
  59. package/template/lambda-sqs-worker-cdk/src/services/jobScorer.test.ts +44 -0
  60. package/template/lambda-sqs-worker-cdk/src/services/jobScorer.ts +59 -0
  61. package/template/lambda-sqs-worker-cdk/src/services/pipelineEventSender.test.ts +40 -0
  62. package/template/lambda-sqs-worker-cdk/src/services/pipelineEventSender.ts +33 -0
  63. package/template/lambda-sqs-worker-cdk/src/testing/handler.ts +13 -0
  64. package/template/lambda-sqs-worker-cdk/src/testing/logging.ts +19 -0
  65. package/template/lambda-sqs-worker-cdk/src/testing/services.ts +28 -0
  66. package/template/lambda-sqs-worker-cdk/src/testing/types.ts +33 -0
  67. package/template/lambda-sqs-worker-cdk/src/types/jobScorer.ts +15 -0
  68. package/template/lambda-sqs-worker-cdk/src/types/pipelineEvents.ts +21 -0
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/api/github/issueComment.ts"],
4
- "sourcesContent": ["import type { Octokit } from '@octokit/rest';\n\nimport * as Git from '../git';\n\nimport { apiTokenFromEnvironment } from './environment';\nimport { createRestClient } from './octokit';\nimport { getPullRequestNumber } from './pullRequest';\n\nconst getUserId = async (client: Octokit): Promise<number> => {\n const { data } = await client.users.getAuthenticated();\n\n return data.id;\n};\n\n/**\n * https://docs.github.com/en/rest/reference/issues#create-an-issue-comment\n */\ninterface PutIssueCommentParameters {\n /**\n * The body of the issue comment.\n */\n body: string;\n\n /**\n * An internal identifier for the issue comment.\n *\n * This can be used to scope a given `put` to a particular comment, preventing\n * it from clobbering other comments from the same bot or user.\n *\n * The identifier is embedded as hidden content in the comment body.\n */\n internalId?: string;\n\n env?: Record<string, string | undefined>;\n\n /**\n * The number that identifies the GitHub issue.\n *\n * If this is not provided, the number will be inferred from the GitHub Repos\n * API by finding the latest pull request associated with the head commit.\n *\n * https://docs.github.com/en/rest/reference/repos#list-pull-requests-associated-with-a-commit\n */\n issueNumber?: number;\n\n /**\n * The ID of authenticated bot or user that is putting the issue comment.\n *\n * This drives our `put` behaviour, which tries to locate and edit an existing\n * comment before creating a new one. If this is not provided, the ID will be\n * inferred from the GitHub Users API.\n *\n * https://docs.github.com/en/rest/reference/users#get-the-authenticated-user\n *\n * If you're at SEEK and using BuildAgency's GitHub API integration, you may\n * use `'seek-build-agency'` as an optimisation to skip the user lookup.\n *\n * https://api.github.com/users/buildagencygitapitoken[bot]\n */\n userId?: number | 'seek-build-agency';\n}\n\ninterface IssueComment {\n id: number;\n}\n\n/**\n * Asynchronously creates or updates a GitHub issue comment.\n *\n * This emulates `put` behaviour by overwriting the first existing comment by\n * the same author on the issue, enabling use cases like a persistent bot\n * comment at the top of the pull request that reflects the current status of a\n * CI check.\n *\n * A `GITHUB_API_TOKEN` or `GITHUB_TOKEN` with write permissions must be present\n * on the environment.\n */\nexport const putIssueComment = async (\n params: PutIssueCommentParameters,\n): Promise<IssueComment> => {\n const env = params.env ?? process.env;\n\n const dir = process.cwd();\n\n const { owner, repo } = await Git.getOwnerAndRepo({ dir });\n\n const client = await createRestClient({ auth: apiTokenFromEnvironment() });\n\n const issueNumber =\n params.issueNumber ?? (await getPullRequestNumber({ client, env }));\n\n if (!issueNumber) {\n throw new Error('Failed to infer an issue number');\n }\n\n const comments = await client.issues.listComments({\n issue_number: issueNumber,\n owner,\n repo,\n });\n\n const userId: number =\n params.userId === 'seek-build-agency'\n ? // https://api.github.com/users/buildagencygitapitoken[bot]\n 87109344\n : params.userId ?? (await getUserId(client));\n\n const commentId = comments.data.find(\n (comment) =>\n comment.user?.id === userId &&\n (params.internalId\n ? comment.body?.endsWith(`\\n\\n<!-- ${params.internalId} -->`)\n : true),\n )?.id;\n\n const body = params.internalId\n ? [params.body.trim(), `<!-- ${params.internalId} -->`].join('\\n\\n')\n : params.body.trim();\n\n const response = await (commentId\n ? client.issues.updateComment({\n body,\n comment_id: commentId,\n issue_number: issueNumber,\n owner,\n repo,\n })\n : client.issues.createComment({\n body,\n issue_number: issueNumber,\n owner,\n repo,\n }));\n\n return {\n id: response.data.id,\n };\n};\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,UAAqB;AAErB,yBAAwC;AACxC,qBAAiC;AACjC,yBAAqC;AAErC,MAAM,YAAY,OAAO,WAAqC;AAC5D,QAAM,EAAE,KAAK,IAAI,MAAM,OAAO,MAAM,iBAAiB;AAErD,SAAO,KAAK;AACd;AAiEO,MAAM,kBAAkB,OAC7B,WAC0B;AAC1B,QAAM,MAAM,OAAO,OAAO,QAAQ;AAElC,QAAM,MAAM,QAAQ,IAAI;AAExB,QAAM,EAAE,OAAO,KAAK,IAAI,MAAM,IAAI,gBAAgB,EAAE,IAAI,CAAC;AAEzD,QAAM,SAAS,UAAM,iCAAiB,EAAE,UAAM,4CAAwB,EAAE,CAAC;AAEzE,QAAM,cACJ,OAAO,eAAgB,UAAM,yCAAqB,EAAE,QAAQ,IAAI,CAAC;AAEnE,MAAI,CAAC,aAAa;AAChB,UAAM,IAAI,MAAM,iCAAiC;AAAA,EACnD;AAEA,QAAM,WAAW,MAAM,OAAO,OAAO,aAAa;AAAA,IAChD,cAAc;AAAA,IACd;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,SACJ,OAAO,WAAW;AAAA;AAAA,IAEd;AAAA,MACA,OAAO,UAAW,MAAM,UAAU,MAAM;AAE9C,QAAM,YAAY,SAAS,KAAK;AAAA,IAC9B,CAAC,YACC,QAAQ,MAAM,OAAO,WACpB,OAAO,aACJ,QAAQ,MAAM,SAAS;AAAA;AAAA,OAAY,OAAO,UAAU,MAAM,IAC1D;AAAA,EACR,GAAG;AAEH,QAAM,OAAO,OAAO,aAChB,CAAC,OAAO,KAAK,KAAK,GAAG,QAAQ,OAAO,UAAU,MAAM,EAAE,KAAK,MAAM,IACjE,OAAO,KAAK,KAAK;AAErB,QAAM,WAAW,OAAO,YACpB,OAAO,OAAO,cAAc;AAAA,IAC1B;AAAA,IACA,YAAY;AAAA,IACZ,cAAc;AAAA,IACd;AAAA,IACA;AAAA,EACF,CAAC,IACD,OAAO,OAAO,cAAc;AAAA,IAC1B;AAAA,IACA,cAAc;AAAA,IACd;AAAA,IACA;AAAA,EACF,CAAC;AAEL,SAAO;AAAA,IACL,IAAI,SAAS,KAAK;AAAA,EACpB;AACF;",
4
+ "sourcesContent": ["import type { Octokit } from '@octokit/rest';\n\nimport * as Git from '../git';\n\nimport { apiTokenFromEnvironment } from './environment';\nimport { createRestClient } from './octokit';\nimport { getPullRequestNumber } from './pullRequest';\n\nconst getUserId = async (client: Octokit): Promise<number> => {\n const { data } = await client.users.getAuthenticated();\n\n return data.id;\n};\n\n/**\n * https://docs.github.com/en/rest/reference/issues#create-an-issue-comment\n */\ninterface PutIssueCommentParameters {\n /**\n * The body of the issue comment.\n */\n body: string;\n\n /**\n * An internal identifier for the issue comment.\n *\n * This can be used to scope a given `put` to a particular comment, preventing\n * it from clobbering other comments from the same bot or user.\n *\n * The identifier is embedded as hidden content in the comment body.\n */\n internalId?: string;\n\n env?: Record<string, string | undefined>;\n\n /**\n * The number that identifies the GitHub issue.\n *\n * If this is not provided, the number will be inferred from the GitHub Repos\n * API by finding the latest pull request associated with the head commit.\n *\n * https://docs.github.com/en/rest/reference/repos#list-pull-requests-associated-with-a-commit\n */\n issueNumber?: number;\n\n /**\n * The ID of authenticated bot or user that is putting the issue comment.\n *\n * This drives our `put` behaviour, which tries to locate and edit an existing\n * comment before creating a new one. If this is not provided, the ID will be\n * inferred from the GitHub Users API.\n *\n * https://docs.github.com/en/rest/reference/users#get-the-authenticated-user\n *\n * If you're at SEEK and using BuildAgency's GitHub API integration, you may\n * use `'seek-build-agency'` as an optimisation to skip the user lookup.\n *\n * https://api.github.com/users/buildagencygitapitoken[bot]\n */\n userId?: number | 'seek-build-agency';\n}\n\ninterface IssueComment {\n id: number;\n}\n\n/**\n * Asynchronously creates or updates a GitHub issue comment.\n *\n * This emulates `put` behaviour by overwriting the first existing comment by\n * the same author on the issue, enabling use cases like a persistent bot\n * comment at the top of the pull request that reflects the current status of a\n * CI check.\n *\n * A `GITHUB_API_TOKEN` or `GITHUB_TOKEN` with write permissions must be present\n * on the environment.\n */\nexport const putIssueComment = async (\n params: PutIssueCommentParameters,\n): Promise<IssueComment> => {\n const env = params.env ?? process.env;\n\n const dir = process.cwd();\n\n const { owner, repo } = await Git.getOwnerAndRepo({ dir });\n\n const client = await createRestClient({ auth: apiTokenFromEnvironment() });\n\n const issueNumber =\n params.issueNumber ?? (await getPullRequestNumber({ client, env }));\n\n if (!issueNumber) {\n throw new Error('Failed to infer an issue number');\n }\n\n const comments = await client.issues.listComments({\n issue_number: issueNumber,\n owner,\n repo,\n });\n\n const userId: number =\n params.userId === 'seek-build-agency'\n ? // https://api.github.com/users/buildagencygitapitoken[bot]\n 87109344\n : (params.userId ?? (await getUserId(client)));\n\n const commentId = comments.data.find(\n (comment) =>\n comment.user?.id === userId &&\n (params.internalId\n ? comment.body?.endsWith(`\\n\\n<!-- ${params.internalId} -->`)\n : true),\n )?.id;\n\n const body = params.internalId\n ? [params.body.trim(), `<!-- ${params.internalId} -->`].join('\\n\\n')\n : params.body.trim();\n\n const response = await (commentId\n ? client.issues.updateComment({\n body,\n comment_id: commentId,\n issue_number: issueNumber,\n owner,\n repo,\n })\n : client.issues.createComment({\n body,\n issue_number: issueNumber,\n owner,\n repo,\n }));\n\n return {\n id: response.data.id,\n };\n};\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,UAAqB;AAErB,yBAAwC;AACxC,qBAAiC;AACjC,yBAAqC;AAErC,MAAM,YAAY,OAAO,WAAqC;AAC5D,QAAM,EAAE,KAAK,IAAI,MAAM,OAAO,MAAM,iBAAiB;AAErD,SAAO,KAAK;AACd;AAiEO,MAAM,kBAAkB,OAC7B,WAC0B;AAC1B,QAAM,MAAM,OAAO,OAAO,QAAQ;AAElC,QAAM,MAAM,QAAQ,IAAI;AAExB,QAAM,EAAE,OAAO,KAAK,IAAI,MAAM,IAAI,gBAAgB,EAAE,IAAI,CAAC;AAEzD,QAAM,SAAS,UAAM,iCAAiB,EAAE,UAAM,4CAAwB,EAAE,CAAC;AAEzE,QAAM,cACJ,OAAO,eAAgB,UAAM,yCAAqB,EAAE,QAAQ,IAAI,CAAC;AAEnE,MAAI,CAAC,aAAa;AAChB,UAAM,IAAI,MAAM,iCAAiC;AAAA,EACnD;AAEA,QAAM,WAAW,MAAM,OAAO,OAAO,aAAa;AAAA,IAChD,cAAc;AAAA,IACd;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,SACJ,OAAO,WAAW;AAAA;AAAA,IAEd;AAAA,MACC,OAAO,UAAW,MAAM,UAAU,MAAM;AAE/C,QAAM,YAAY,SAAS,KAAK;AAAA,IAC9B,CAAC,YACC,QAAQ,MAAM,OAAO,WACpB,OAAO,aACJ,QAAQ,MAAM,SAAS;AAAA;AAAA,OAAY,OAAO,UAAU,MAAM,IAC1D;AAAA,EACR,GAAG;AAEH,QAAM,OAAO,OAAO,aAChB,CAAC,OAAO,KAAK,KAAK,GAAG,QAAQ,OAAO,UAAU,MAAM,EAAE,KAAK,MAAM,IACjE,OAAO,KAAK,KAAK;AAErB,QAAM,WAAW,OAAO,YACpB,OAAO,OAAO,cAAc;AAAA,IAC1B;AAAA,IACA,YAAY;AAAA,IACZ,cAAc;AAAA,IACd;AAAA,IACA;AAAA,EACF,CAAC,IACD,OAAO,OAAO,cAAc;AAAA,IAC1B;AAAA,IACA,cAAc;AAAA,IACd;AAAA,IACA;AAAA,EACF,CAAC;AAEL,SAAO;AAAA,IACL,IAAI,SAAS,KAAK;AAAA,EACpB;AACF;",
6
6
  "names": []
7
7
  }
@@ -98,10 +98,10 @@ const runESLint = async (mode, logger, overrideConfigFile) => {
98
98
  }
99
99
  const ok = errors.length === 0;
100
100
  await ESLint.outputFixes(results);
101
- const output = await formatter.format(results, {
102
- cwd,
103
- rulesMeta: engine.getRulesMetaForResults(results)
104
- });
101
+ const output = await formatter.format(
102
+ results,
103
+ engine.getRulesMetaForResults(results)
104
+ );
105
105
  if (output) {
106
106
  logger.plain(output);
107
107
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/cli/adapter/eslint.ts"],
4
- "sourcesContent": ["import path from 'path';\n\nimport chalk from 'chalk';\nimport { type ESLint, type Linter, loadESLint } from 'eslint';\n\nimport { type Logger, pluralise } from '../../utils/logging';\n\nconst symbolForResult = (result: ESLint.LintResult) => {\n if (result.errorCount) {\n return chalk.red('\u25CB');\n }\n\n return result.warningCount ? chalk.yellow('\u25CD') : chalk.green('\u25CB');\n};\n\nexport interface ESLintResult {\n messages: Linter.LintMessage[];\n filePath: string;\n}\n\nexport interface ESLintOutput {\n errors: ESLintResult[];\n fixable: boolean;\n ok: boolean;\n output: string;\n warnings: ESLintResult[];\n}\n\nexport const runESLint = async (\n mode: 'format' | 'lint',\n logger: Logger,\n overrideConfigFile?: string,\n): Promise<ESLintOutput> => {\n logger.debug('Initialising ESLint...');\n\n const cwd = process.cwd();\n\n const ESLint = await loadESLint({ useFlatConfig: true });\n const engine = new ESLint({\n cache: true,\n fix: mode === 'format',\n overrideConfigFile,\n overrideConfig: {\n linterOptions: {\n reportUnusedDisableDirectives: true,\n },\n },\n });\n\n logger.debug('Processing files...');\n\n const start = process.hrtime.bigint();\n\n const [formatter, { type, results }] = await Promise.all([\n engine.loadFormatter(),\n lintFiles(engine),\n ]);\n\n if (type === 'no-config') {\n logger.plain(\n 'skuba could not find an eslint config file. Do you need to run format or configure?',\n );\n return { ok: false, fixable: false, errors: [], warnings: [], output: '' };\n }\n\n const end = process.hrtime.bigint();\n\n logger.plain(\n `Processed ${pluralise(results.length, 'file')} in ${logger.timing(\n start,\n end,\n )}.`,\n );\n\n const errors: ESLintResult[] = [];\n const warnings: ESLintResult[] = [];\n let fixable = false;\n\n for (const result of results) {\n const relativePath = path.relative(cwd, result.filePath);\n if (result.fixableErrorCount + result.fixableWarningCount) {\n fixable = true;\n }\n\n if (result.errorCount) {\n errors.push({\n filePath: relativePath,\n messages: result.messages,\n });\n }\n\n if (result.warningCount) {\n warnings.push({\n filePath: relativePath,\n messages: result.messages,\n });\n }\n\n logger.debug(symbolForResult(result), relativePath);\n }\n\n const ok = errors.length === 0;\n\n await ESLint.outputFixes(results);\n\n const output = await formatter.format(results, {\n cwd,\n rulesMeta: engine.getRulesMetaForResults(results),\n });\n\n if (output) {\n logger.plain(output);\n }\n\n return { errors, fixable, ok, output, warnings };\n};\n\nconst lintFiles = async (engine: ESLint) => {\n try {\n const result = await engine.lintFiles([]);\n return { type: 'results', results: result } as const;\n } catch (error) {\n if (\n error instanceof Error &&\n error.message === 'Could not find config file.'\n ) {\n return { type: 'no-config', results: undefined } as const;\n }\n throw error;\n }\n};\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAiB;AAEjB,mBAAkB;AAClB,oBAAqD;AAErD,qBAAuC;AAEvC,MAAM,kBAAkB,CAAC,WAA8B;AACrD,MAAI,OAAO,YAAY;AACrB,WAAO,aAAAA,QAAM,IAAI,QAAG;AAAA,EACtB;AAEA,SAAO,OAAO,eAAe,aAAAA,QAAM,OAAO,QAAG,IAAI,aAAAA,QAAM,MAAM,QAAG;AAClE;AAeO,MAAM,YAAY,OACvB,MACA,QACA,uBAC0B;AAC1B,SAAO,MAAM,wBAAwB;AAErC,QAAM,MAAM,QAAQ,IAAI;AAExB,QAAM,SAAS,UAAM,0BAAW,EAAE,eAAe,KAAK,CAAC;AACvD,QAAM,SAAS,IAAI,OAAO;AAAA,IACxB,OAAO;AAAA,IACP,KAAK,SAAS;AAAA,IACd;AAAA,IACA,gBAAgB;AAAA,MACd,eAAe;AAAA,QACb,+BAA+B;AAAA,MACjC;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO,MAAM,qBAAqB;AAElC,QAAM,QAAQ,QAAQ,OAAO,OAAO;AAEpC,QAAM,CAAC,WAAW,EAAE,MAAM,QAAQ,CAAC,IAAI,MAAM,QAAQ,IAAI;AAAA,IACvD,OAAO,cAAc;AAAA,IACrB,UAAU,MAAM;AAAA,EAClB,CAAC;AAED,MAAI,SAAS,aAAa;AACxB,WAAO;AAAA,MACL;AAAA,IACF;AACA,WAAO,EAAE,IAAI,OAAO,SAAS,OAAO,QAAQ,CAAC,GAAG,UAAU,CAAC,GAAG,QAAQ,GAAG;AAAA,EAC3E;AAEA,QAAM,MAAM,QAAQ,OAAO,OAAO;AAElC,SAAO;AAAA,IACL,iBAAa,0BAAU,QAAQ,QAAQ,MAAM,CAAC,OAAO,OAAO;AAAA,MAC1D;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,SAAyB,CAAC;AAChC,QAAM,WAA2B,CAAC;AAClC,MAAI,UAAU;AAEd,aAAW,UAAU,SAAS;AAC5B,UAAM,eAAe,YAAAC,QAAK,SAAS,KAAK,OAAO,QAAQ;AACvD,QAAI,OAAO,oBAAoB,OAAO,qBAAqB;AACzD,gBAAU;AAAA,IACZ;AAEA,QAAI,OAAO,YAAY;AACrB,aAAO,KAAK;AAAA,QACV,UAAU;AAAA,QACV,UAAU,OAAO;AAAA,MACnB,CAAC;AAAA,IACH;AAEA,QAAI,OAAO,cAAc;AACvB,eAAS,KAAK;AAAA,QACZ,UAAU;AAAA,QACV,UAAU,OAAO;AAAA,MACnB,CAAC;AAAA,IACH;AAEA,WAAO,MAAM,gBAAgB,MAAM,GAAG,YAAY;AAAA,EACpD;AAEA,QAAM,KAAK,OAAO,WAAW;AAE7B,QAAM,OAAO,YAAY,OAAO;AAEhC,QAAM,SAAS,MAAM,UAAU,OAAO,SAAS;AAAA,IAC7C;AAAA,IACA,WAAW,OAAO,uBAAuB,OAAO;AAAA,EAClD,CAAC;AAED,MAAI,QAAQ;AACV,WAAO,MAAM,MAAM;AAAA,EACrB;AAEA,SAAO,EAAE,QAAQ,SAAS,IAAI,QAAQ,SAAS;AACjD;AAEA,MAAM,YAAY,OAAO,WAAmB;AAC1C,MAAI;AACF,UAAM,SAAS,MAAM,OAAO,UAAU,CAAC,CAAC;AACxC,WAAO,EAAE,MAAM,WAAW,SAAS,OAAO;AAAA,EAC5C,SAAS,OAAO;AACd,QACE,iBAAiB,SACjB,MAAM,YAAY,+BAClB;AACA,aAAO,EAAE,MAAM,aAAa,SAAS,OAAU;AAAA,IACjD;AACA,UAAM;AAAA,EACR;AACF;",
4
+ "sourcesContent": ["import path from 'path';\n\nimport chalk from 'chalk';\nimport { type ESLint, type Linter, loadESLint } from 'eslint';\n\nimport { type Logger, pluralise } from '../../utils/logging';\n\nconst symbolForResult = (result: ESLint.LintResult) => {\n if (result.errorCount) {\n return chalk.red('\u25CB');\n }\n\n return result.warningCount ? chalk.yellow('\u25CD') : chalk.green('\u25CB');\n};\n\nexport interface ESLintResult {\n messages: Linter.LintMessage[];\n filePath: string;\n}\n\nexport interface ESLintOutput {\n errors: ESLintResult[];\n fixable: boolean;\n ok: boolean;\n output: string;\n warnings: ESLintResult[];\n}\n\nexport const runESLint = async (\n mode: 'format' | 'lint',\n logger: Logger,\n overrideConfigFile?: string,\n): Promise<ESLintOutput> => {\n logger.debug('Initialising ESLint...');\n\n const cwd = process.cwd();\n\n const ESLint = await loadESLint({ useFlatConfig: true });\n const engine = new ESLint({\n cache: true,\n fix: mode === 'format',\n overrideConfigFile,\n overrideConfig: {\n linterOptions: {\n reportUnusedDisableDirectives: true,\n },\n },\n });\n\n logger.debug('Processing files...');\n\n const start = process.hrtime.bigint();\n\n const [formatter, { type, results }] = await Promise.all([\n engine.loadFormatter(),\n lintFiles(engine),\n ]);\n\n if (type === 'no-config') {\n logger.plain(\n 'skuba could not find an eslint config file. Do you need to run format or configure?',\n );\n return { ok: false, fixable: false, errors: [], warnings: [], output: '' };\n }\n\n const end = process.hrtime.bigint();\n\n logger.plain(\n `Processed ${pluralise(results.length, 'file')} in ${logger.timing(\n start,\n end,\n )}.`,\n );\n\n const errors: ESLintResult[] = [];\n const warnings: ESLintResult[] = [];\n let fixable = false;\n\n for (const result of results) {\n const relativePath = path.relative(cwd, result.filePath);\n if (result.fixableErrorCount + result.fixableWarningCount) {\n fixable = true;\n }\n\n if (result.errorCount) {\n errors.push({\n filePath: relativePath,\n messages: result.messages,\n });\n }\n\n if (result.warningCount) {\n warnings.push({\n filePath: relativePath,\n messages: result.messages,\n });\n }\n\n logger.debug(symbolForResult(result), relativePath);\n }\n\n const ok = errors.length === 0;\n\n await ESLint.outputFixes(results);\n\n const output = await formatter.format(\n results,\n engine.getRulesMetaForResults(results),\n );\n\n if (output) {\n logger.plain(output);\n }\n\n return { errors, fixable, ok, output, warnings };\n};\n\nconst lintFiles = async (engine: ESLint) => {\n try {\n const result = await engine.lintFiles([]);\n return { type: 'results', results: result } as const;\n } catch (error) {\n if (\n error instanceof Error &&\n error.message === 'Could not find config file.'\n ) {\n return { type: 'no-config', results: undefined } as const;\n }\n throw error;\n }\n};\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAiB;AAEjB,mBAAkB;AAClB,oBAAqD;AAErD,qBAAuC;AAEvC,MAAM,kBAAkB,CAAC,WAA8B;AACrD,MAAI,OAAO,YAAY;AACrB,WAAO,aAAAA,QAAM,IAAI,QAAG;AAAA,EACtB;AAEA,SAAO,OAAO,eAAe,aAAAA,QAAM,OAAO,QAAG,IAAI,aAAAA,QAAM,MAAM,QAAG;AAClE;AAeO,MAAM,YAAY,OACvB,MACA,QACA,uBAC0B;AAC1B,SAAO,MAAM,wBAAwB;AAErC,QAAM,MAAM,QAAQ,IAAI;AAExB,QAAM,SAAS,UAAM,0BAAW,EAAE,eAAe,KAAK,CAAC;AACvD,QAAM,SAAS,IAAI,OAAO;AAAA,IACxB,OAAO;AAAA,IACP,KAAK,SAAS;AAAA,IACd;AAAA,IACA,gBAAgB;AAAA,MACd,eAAe;AAAA,QACb,+BAA+B;AAAA,MACjC;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO,MAAM,qBAAqB;AAElC,QAAM,QAAQ,QAAQ,OAAO,OAAO;AAEpC,QAAM,CAAC,WAAW,EAAE,MAAM,QAAQ,CAAC,IAAI,MAAM,QAAQ,IAAI;AAAA,IACvD,OAAO,cAAc;AAAA,IACrB,UAAU,MAAM;AAAA,EAClB,CAAC;AAED,MAAI,SAAS,aAAa;AACxB,WAAO;AAAA,MACL;AAAA,IACF;AACA,WAAO,EAAE,IAAI,OAAO,SAAS,OAAO,QAAQ,CAAC,GAAG,UAAU,CAAC,GAAG,QAAQ,GAAG;AAAA,EAC3E;AAEA,QAAM,MAAM,QAAQ,OAAO,OAAO;AAElC,SAAO;AAAA,IACL,iBAAa,0BAAU,QAAQ,QAAQ,MAAM,CAAC,OAAO,OAAO;AAAA,MAC1D;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,SAAyB,CAAC;AAChC,QAAM,WAA2B,CAAC;AAClC,MAAI,UAAU;AAEd,aAAW,UAAU,SAAS;AAC5B,UAAM,eAAe,YAAAC,QAAK,SAAS,KAAK,OAAO,QAAQ;AACvD,QAAI,OAAO,oBAAoB,OAAO,qBAAqB;AACzD,gBAAU;AAAA,IACZ;AAEA,QAAI,OAAO,YAAY;AACrB,aAAO,KAAK;AAAA,QACV,UAAU;AAAA,QACV,UAAU,OAAO;AAAA,MACnB,CAAC;AAAA,IACH;AAEA,QAAI,OAAO,cAAc;AACvB,eAAS,KAAK;AAAA,QACZ,UAAU;AAAA,QACV,UAAU,OAAO;AAAA,MACnB,CAAC;AAAA,IACH;AAEA,WAAO,MAAM,gBAAgB,MAAM,GAAG,YAAY;AAAA,EACpD;AAEA,QAAM,KAAK,OAAO,WAAW;AAE7B,QAAM,OAAO,YAAY,OAAO;AAEhC,QAAM,SAAS,MAAM,UAAU;AAAA,IAC7B;AAAA,IACA,OAAO,uBAAuB,OAAO;AAAA,EACvC;AAEA,MAAI,QAAQ;AACV,WAAO,MAAM,MAAM;AAAA,EACrB;AAEA,SAAO,EAAE,QAAQ,SAAS,IAAI,QAAQ,SAAS;AACjD;AAEA,MAAM,YAAY,OAAO,WAAmB;AAC1C,MAAI;AACF,UAAM,SAAS,MAAM,OAAO,UAAU,CAAC,CAAC;AACxC,WAAO,EAAE,MAAM,WAAW,SAAS,OAAO;AAAA,EAC5C,SAAS,OAAO;AACd,QACE,iBAAiB,SACjB,MAAM,YAAY,+BAClB;AACA,aAAO,EAAE,MAAM,aAAa,SAAS,OAAU;AAAA,IACjD;AACA,UAAM;AAAA,EACR;AACF;",
6
6
  "names": ["chalk", "path"]
7
7
  }
@@ -35,7 +35,6 @@ __export(autofix_exports, {
35
35
  module.exports = __toCommonJS(autofix_exports);
36
36
  var import_util = require("util");
37
37
  var import_simple_git = __toESM(require("simple-git"));
38
- var Buildkite = __toESM(require("../../api/buildkite"));
39
38
  var Git = __toESM(require("../../api/git"));
40
39
  var GitHub = __toESM(require("../../api/github"));
41
40
  var import_env = require("../../utils/env");
@@ -46,7 +45,6 @@ var import_eslint = require("../adapter/eslint");
46
45
  var import_prettier = require("../adapter/prettier");
47
46
  var import_project = require("../configure/analysis/project");
48
47
  var import_internal = require("./internal");
49
- const RENOVATE_DEFAULT_PREFIX = "renovate";
50
48
  const AUTOFIX_COMMIT_MESSAGE = "Run `skuba format`";
51
49
  const AUTOFIX_IGNORE_FILES_BASE = [
52
50
  {
@@ -78,19 +76,6 @@ const shouldPush = async ({
78
76
  if (isDefaultBuildkiteBranch || isProtectedGitHubBranch) {
79
77
  return false;
80
78
  }
81
- if (currentBranch?.startsWith(RENOVATE_DEFAULT_PREFIX)) {
82
- try {
83
- await GitHub.getPullRequestNumber();
84
- } catch {
85
- const warning = "An autofix is available, but it was not pushed because an open pull request for this Renovate branch could not be found. If a pull request has since been created, retry the lint step to push the fix.";
86
- import_logging.log.warn(warning);
87
- try {
88
- await Buildkite.annotate(Buildkite.md.terminal(warning));
89
- } catch {
90
- }
91
- return false;
92
- }
93
- }
94
79
  let headCommitMessage;
95
80
  try {
96
81
  headCommitMessage = await Git.getHeadCommitMessage({ dir });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/cli/lint/autofix.ts"],
4
- "sourcesContent": ["import { inspect } from 'util';\n\nimport simpleGit from 'simple-git';\n\nimport * as Buildkite from '../../api/buildkite';\nimport * as Git from '../../api/git';\nimport * as GitHub from '../../api/github';\nimport { isCiEnv } from '../../utils/env';\nimport { createLogger, log } from '../../utils/logging';\nimport { hasNpmrcSecret } from '../../utils/npmrc';\nimport { throwOnTimeout } from '../../utils/wait';\nimport { runESLint } from '../adapter/eslint';\nimport { runPrettier } from '../adapter/prettier';\nimport { createDestinationFileReader } from '../configure/analysis/project';\n\nimport { internalLint } from './internal';\nimport type { Input } from './types';\n\nconst RENOVATE_DEFAULT_PREFIX = 'renovate';\n\nconst AUTOFIX_COMMIT_MESSAGE = 'Run `skuba format`';\n\nexport const AUTOFIX_IGNORE_FILES_BASE: Git.ChangedFile[] = [\n {\n path: 'Dockerfile-incunabulum',\n state: 'added',\n },\n];\n\nexport const AUTOFIX_IGNORE_FILES_NPMRC: Git.ChangedFile[] = [\n {\n path: '.npmrc',\n state: 'added',\n },\n {\n path: '.npmrc',\n state: 'modified',\n },\n];\n\nconst shouldPush = async ({\n currentBranch,\n dir,\n}: {\n currentBranch?: string;\n dir: string;\n}) => {\n if (!isCiEnv()) {\n // We're not running in a CI environment so we don't need to push autofixes.\n // Ideally we'd drive this off of repository write permissions, but that is\n // non-trivial to infer without attempting an actual write.\n return false;\n }\n\n const isDefaultBuildkiteBranch =\n currentBranch &&\n [process.env.BUILDKITE_PIPELINE_DEFAULT_BRANCH, 'master', 'main'].includes(\n currentBranch,\n );\n\n const isProtectedGitHubBranch = process.env.GITHUB_REF_PROTECTED === 'true';\n\n if (isDefaultBuildkiteBranch || isProtectedGitHubBranch) {\n // The current branch is a protected branch.\n // We respect GitHub Flow; avoid pushing directly to the default branch.\n return false;\n }\n\n if (currentBranch?.startsWith(RENOVATE_DEFAULT_PREFIX)) {\n try {\n await GitHub.getPullRequestNumber();\n } catch {\n const warning =\n 'An autofix is available, but it was not pushed because an open pull request for this Renovate branch could not be found. If a pull request has since been created, retry the lint step to push the fix.';\n log.warn(warning);\n try {\n await Buildkite.annotate(Buildkite.md.terminal(warning));\n } catch {}\n\n return false;\n }\n }\n\n let headCommitMessage;\n try {\n headCommitMessage = await Git.getHeadCommitMessage({ dir });\n } catch {}\n\n if (headCommitMessage?.startsWith(AUTOFIX_COMMIT_MESSAGE)) {\n // Short circuit when the head commit appears to be one of our autofixes.\n // Repeating the same operation is unlikely to correct outstanding issues.\n return false;\n }\n\n // Allow the push attempt to go ahead if our guards have been cleared.\n return true;\n};\n\nconst getIgnores = async (dir: string): Promise<Git.ChangedFile[]> => {\n const contents = await createDestinationFileReader(dir)('.npmrc');\n\n // If an .npmrc has secrets, we need to ignore it\n if (hasNpmrcSecret(contents ?? '')) {\n return [...AUTOFIX_IGNORE_FILES_BASE, ...AUTOFIX_IGNORE_FILES_NPMRC];\n }\n\n return AUTOFIX_IGNORE_FILES_BASE;\n};\n\ninterface AutofixParameters {\n debug: Input['debug'];\n\n eslint: boolean;\n prettier: boolean;\n internal: boolean;\n\n eslintConfigFile?: string;\n}\n\nexport const autofix = async (params: AutofixParameters): Promise<void> => {\n const dir = process.cwd();\n\n if (!params.eslint && !params.prettier && !params.internal) {\n return;\n }\n\n let currentBranch;\n try {\n currentBranch = await Git.currentBranch({ dir });\n } catch {}\n\n if (!(await shouldPush({ currentBranch, dir }))) {\n return;\n }\n\n try {\n log.newline();\n\n log.warn(\n `Attempting to autofix issues (${[\n params.eslint ? 'ESLint' : undefined,\n params.internal ? 'skuba' : undefined,\n 'Prettier', // Prettier is always run\n ]\n .filter((s) => s !== undefined)\n .join(', ')})...`,\n );\n\n const logger = createLogger(params.debug);\n\n if (params.internal) {\n await internalLint('format');\n }\n\n if (params.eslint) {\n await runESLint('format', logger, params.eslintConfigFile);\n }\n\n // Unconditionally re-run Prettier; reaching here means we have pre-existing\n // format violations or may have created new ones through ESLint/internal fixes.\n await runPrettier('format', logger);\n\n if (process.env.GITHUB_ACTIONS) {\n // GitHub runners have Git installed locally\n const ref = await Git.commitAllChanges({\n dir,\n message: AUTOFIX_COMMIT_MESSAGE,\n\n ignore: await getIgnores(dir),\n });\n\n if (!ref) {\n return log.warn('No autofixes detected.');\n }\n\n await throwOnTimeout(simpleGit().push(), { s: 30 });\n log.warn(`Pushed fix commit ${ref}.`);\n return;\n }\n\n // Other CI Environments, use GitHub API\n if (!currentBranch) {\n log.warn('Could not determine the current branch.');\n log.warn(\n 'Please propagate BUILDKITE_BRANCH, GITHUB_HEAD_REF, GITHUB_REF_NAME, or the .git directory to your container.',\n );\n return;\n }\n\n const ref = await throwOnTimeout(\n GitHub.uploadAllFileChanges({\n branch: currentBranch,\n dir,\n messageHeadline: AUTOFIX_COMMIT_MESSAGE,\n\n ignore: await getIgnores(dir),\n }),\n { s: 30 },\n );\n\n if (!ref) {\n return log.warn('No autofixes detected.');\n }\n\n log.warn(`Pushed fix commit ${ref}.`);\n } catch (err) {\n log.warn(log.bold('Failed to push fix commit.'));\n log.warn(\n log.bold(\n 'Does your CI environment have write access to your Git repository?',\n ),\n );\n log.subtle(inspect(err));\n }\n};\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAwB;AAExB,wBAAsB;AAEtB,gBAA2B;AAC3B,UAAqB;AACrB,aAAwB;AACxB,iBAAwB;AACxB,qBAAkC;AAClC,mBAA+B;AAC/B,kBAA+B;AAC/B,oBAA0B;AAC1B,sBAA4B;AAC5B,qBAA4C;AAE5C,sBAA6B;AAG7B,MAAM,0BAA0B;AAEhC,MAAM,yBAAyB;AAExB,MAAM,4BAA+C;AAAA,EAC1D;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,EACT;AACF;AAEO,MAAM,6BAAgD;AAAA,EAC3D;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,OAAO;AAAA,EACT;AACF;AAEA,MAAM,aAAa,OAAO;AAAA,EACxB;AAAA,EACA;AACF,MAGM;AACJ,MAAI,KAAC,oBAAQ,GAAG;AAId,WAAO;AAAA,EACT;AAEA,QAAM,2BACJ,iBACA,CAAC,QAAQ,IAAI,mCAAmC,UAAU,MAAM,EAAE;AAAA,IAChE;AAAA,EACF;AAEF,QAAM,0BAA0B,QAAQ,IAAI,yBAAyB;AAErE,MAAI,4BAA4B,yBAAyB;AAGvD,WAAO;AAAA,EACT;AAEA,MAAI,eAAe,WAAW,uBAAuB,GAAG;AACtD,QAAI;AACF,YAAM,OAAO,qBAAqB;AAAA,IACpC,QAAQ;AACN,YAAM,UACJ;AACF,yBAAI,KAAK,OAAO;AAChB,UAAI;AACF,cAAM,UAAU,SAAS,UAAU,GAAG,SAAS,OAAO,CAAC;AAAA,MACzD,QAAQ;AAAA,MAAC;AAET,aAAO;AAAA,IACT;AAAA,EACF;AAEA,MAAI;AACJ,MAAI;AACF,wBAAoB,MAAM,IAAI,qBAAqB,EAAE,IAAI,CAAC;AAAA,EAC5D,QAAQ;AAAA,EAAC;AAET,MAAI,mBAAmB,WAAW,sBAAsB,GAAG;AAGzD,WAAO;AAAA,EACT;AAGA,SAAO;AACT;AAEA,MAAM,aAAa,OAAO,QAA4C;AACpE,QAAM,WAAW,UAAM,4CAA4B,GAAG,EAAE,QAAQ;AAGhE,UAAI,6BAAe,YAAY,EAAE,GAAG;AAClC,WAAO,CAAC,GAAG,2BAA2B,GAAG,0BAA0B;AAAA,EACrE;AAEA,SAAO;AACT;AAYO,MAAM,UAAU,OAAO,WAA6C;AACzE,QAAM,MAAM,QAAQ,IAAI;AAExB,MAAI,CAAC,OAAO,UAAU,CAAC,OAAO,YAAY,CAAC,OAAO,UAAU;AAC1D;AAAA,EACF;AAEA,MAAI;AACJ,MAAI;AACF,oBAAgB,MAAM,IAAI,cAAc,EAAE,IAAI,CAAC;AAAA,EACjD,QAAQ;AAAA,EAAC;AAET,MAAI,CAAE,MAAM,WAAW,EAAE,eAAe,IAAI,CAAC,GAAI;AAC/C;AAAA,EACF;AAEA,MAAI;AACF,uBAAI,QAAQ;AAEZ,uBAAI;AAAA,MACF,iCAAiC;AAAA,QAC/B,OAAO,SAAS,WAAW;AAAA,QAC3B,OAAO,WAAW,UAAU;AAAA,QAC5B;AAAA;AAAA,MACF,EACG,OAAO,CAAC,MAAM,MAAM,MAAS,EAC7B,KAAK,IAAI,CAAC;AAAA,IACf;AAEA,UAAM,aAAS,6BAAa,OAAO,KAAK;AAExC,QAAI,OAAO,UAAU;AACnB,gBAAM,8BAAa,QAAQ;AAAA,IAC7B;AAEA,QAAI,OAAO,QAAQ;AACjB,gBAAM,yBAAU,UAAU,QAAQ,OAAO,gBAAgB;AAAA,IAC3D;AAIA,cAAM,6BAAY,UAAU,MAAM;AAElC,QAAI,QAAQ,IAAI,gBAAgB;AAE9B,YAAMA,OAAM,MAAM,IAAI,iBAAiB;AAAA,QACrC;AAAA,QACA,SAAS;AAAA,QAET,QAAQ,MAAM,WAAW,GAAG;AAAA,MAC9B,CAAC;AAED,UAAI,CAACA,MAAK;AACR,eAAO,mBAAI,KAAK,wBAAwB;AAAA,MAC1C;AAEA,gBAAM,gCAAe,kBAAAC,SAAU,EAAE,KAAK,GAAG,EAAE,GAAG,GAAG,CAAC;AAClD,yBAAI,KAAK,qBAAqBD,IAAG,GAAG;AACpC;AAAA,IACF;AAGA,QAAI,CAAC,eAAe;AAClB,yBAAI,KAAK,yCAAyC;AAClD,yBAAI;AAAA,QACF;AAAA,MACF;AACA;AAAA,IACF;AAEA,UAAM,MAAM,UAAM;AAAA,MAChB,OAAO,qBAAqB;AAAA,QAC1B,QAAQ;AAAA,QACR;AAAA,QACA,iBAAiB;AAAA,QAEjB,QAAQ,MAAM,WAAW,GAAG;AAAA,MAC9B,CAAC;AAAA,MACD,EAAE,GAAG,GAAG;AAAA,IACV;AAEA,QAAI,CAAC,KAAK;AACR,aAAO,mBAAI,KAAK,wBAAwB;AAAA,IAC1C;AAEA,uBAAI,KAAK,qBAAqB,GAAG,GAAG;AAAA,EACtC,SAAS,KAAK;AACZ,uBAAI,KAAK,mBAAI,KAAK,4BAA4B,CAAC;AAC/C,uBAAI;AAAA,MACF,mBAAI;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,uBAAI,WAAO,qBAAQ,GAAG,CAAC;AAAA,EACzB;AACF;",
4
+ "sourcesContent": ["import { inspect } from 'util';\n\nimport simpleGit from 'simple-git';\n\nimport * as Git from '../../api/git';\nimport * as GitHub from '../../api/github';\nimport { isCiEnv } from '../../utils/env';\nimport { createLogger, log } from '../../utils/logging';\nimport { hasNpmrcSecret } from '../../utils/npmrc';\nimport { throwOnTimeout } from '../../utils/wait';\nimport { runESLint } from '../adapter/eslint';\nimport { runPrettier } from '../adapter/prettier';\nimport { createDestinationFileReader } from '../configure/analysis/project';\n\nimport { internalLint } from './internal';\nimport type { Input } from './types';\n\nconst AUTOFIX_COMMIT_MESSAGE = 'Run `skuba format`';\n\nexport const AUTOFIX_IGNORE_FILES_BASE: Git.ChangedFile[] = [\n {\n path: 'Dockerfile-incunabulum',\n state: 'added',\n },\n];\n\nexport const AUTOFIX_IGNORE_FILES_NPMRC: Git.ChangedFile[] = [\n {\n path: '.npmrc',\n state: 'added',\n },\n {\n path: '.npmrc',\n state: 'modified',\n },\n];\n\nconst shouldPush = async ({\n currentBranch,\n dir,\n}: {\n currentBranch?: string;\n dir: string;\n}) => {\n if (!isCiEnv()) {\n // We're not running in a CI environment so we don't need to push autofixes.\n // Ideally we'd drive this off of repository write permissions, but that is\n // non-trivial to infer without attempting an actual write.\n return false;\n }\n\n const isDefaultBuildkiteBranch =\n currentBranch &&\n [process.env.BUILDKITE_PIPELINE_DEFAULT_BRANCH, 'master', 'main'].includes(\n currentBranch,\n );\n\n const isProtectedGitHubBranch = process.env.GITHUB_REF_PROTECTED === 'true';\n\n if (isDefaultBuildkiteBranch || isProtectedGitHubBranch) {\n // The current branch is a protected branch.\n // We respect GitHub Flow; avoid pushing directly to the default branch.\n return false;\n }\n\n let headCommitMessage;\n try {\n headCommitMessage = await Git.getHeadCommitMessage({ dir });\n } catch {}\n\n if (headCommitMessage?.startsWith(AUTOFIX_COMMIT_MESSAGE)) {\n // Short circuit when the head commit appears to be one of our autofixes.\n // Repeating the same operation is unlikely to correct outstanding issues.\n return false;\n }\n\n // Allow the push attempt to go ahead if our guards have been cleared.\n return true;\n};\n\nconst getIgnores = async (dir: string): Promise<Git.ChangedFile[]> => {\n const contents = await createDestinationFileReader(dir)('.npmrc');\n\n // If an .npmrc has secrets, we need to ignore it\n if (hasNpmrcSecret(contents ?? '')) {\n return [...AUTOFIX_IGNORE_FILES_BASE, ...AUTOFIX_IGNORE_FILES_NPMRC];\n }\n\n return AUTOFIX_IGNORE_FILES_BASE;\n};\n\ninterface AutofixParameters {\n debug: Input['debug'];\n\n eslint: boolean;\n prettier: boolean;\n internal: boolean;\n\n eslintConfigFile?: string;\n}\n\nexport const autofix = async (params: AutofixParameters): Promise<void> => {\n const dir = process.cwd();\n\n if (!params.eslint && !params.prettier && !params.internal) {\n return;\n }\n\n let currentBranch;\n try {\n currentBranch = await Git.currentBranch({ dir });\n } catch {}\n\n if (!(await shouldPush({ currentBranch, dir }))) {\n return;\n }\n\n try {\n log.newline();\n\n log.warn(\n `Attempting to autofix issues (${[\n params.eslint ? 'ESLint' : undefined,\n params.internal ? 'skuba' : undefined,\n 'Prettier', // Prettier is always run\n ]\n .filter((s) => s !== undefined)\n .join(', ')})...`,\n );\n\n const logger = createLogger(params.debug);\n\n if (params.internal) {\n await internalLint('format');\n }\n\n if (params.eslint) {\n await runESLint('format', logger, params.eslintConfigFile);\n }\n\n // Unconditionally re-run Prettier; reaching here means we have pre-existing\n // format violations or may have created new ones through ESLint/internal fixes.\n await runPrettier('format', logger);\n\n if (process.env.GITHUB_ACTIONS) {\n // GitHub runners have Git installed locally\n const ref = await Git.commitAllChanges({\n dir,\n message: AUTOFIX_COMMIT_MESSAGE,\n\n ignore: await getIgnores(dir),\n });\n\n if (!ref) {\n return log.warn('No autofixes detected.');\n }\n\n await throwOnTimeout(simpleGit().push(), { s: 30 });\n log.warn(`Pushed fix commit ${ref}.`);\n return;\n }\n\n // Other CI Environments, use GitHub API\n if (!currentBranch) {\n log.warn('Could not determine the current branch.');\n log.warn(\n 'Please propagate BUILDKITE_BRANCH, GITHUB_HEAD_REF, GITHUB_REF_NAME, or the .git directory to your container.',\n );\n return;\n }\n\n const ref = await throwOnTimeout(\n GitHub.uploadAllFileChanges({\n branch: currentBranch,\n dir,\n messageHeadline: AUTOFIX_COMMIT_MESSAGE,\n\n ignore: await getIgnores(dir),\n }),\n { s: 30 },\n );\n\n if (!ref) {\n return log.warn('No autofixes detected.');\n }\n\n log.warn(`Pushed fix commit ${ref}.`);\n } catch (err) {\n log.warn(log.bold('Failed to push fix commit.'));\n log.warn(\n log.bold(\n 'Does your CI environment have write access to your Git repository?',\n ),\n );\n log.subtle(inspect(err));\n }\n};\n"],
5
+ "mappings": "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",
6
6
  "names": ["ref", "simpleGit"]
7
7
  }
@@ -29,7 +29,7 @@ const collapseDuplicateMergeKeys = async ({
29
29
  mode
30
30
  }) => {
31
31
  const buildkiteFiles = await (0, import_fast_glob.glob)(
32
- [".buildkite/**/*.yml", ".buildkite/**/*.yaml"],
32
+ ["{apps/*/,packages/*/,./}.buildkite/**/*.y*ml"],
33
33
  { onlyFiles: true }
34
34
  );
35
35
  if (buildkiteFiles.length === 0) {
@@ -46,16 +46,25 @@ const collapseDuplicateMergeKeys = async ({
46
46
  return { result: "apply" };
47
47
  }
48
48
  await Promise.all(
49
- buildkiteFiles.map((name, i) => [name, i]).filter(([, i]) => replaced[i] !== input[i]).map(([name, i]) => import_fs_extra.promises.writeFile(name, replaced[i]))
49
+ buildkiteFiles.flatMap(
50
+ (name, i) => (
51
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
52
+ replaced[i] !== input[i] ? [import_fs_extra.promises.writeFile(name, replaced[i])] : []
53
+ )
54
+ )
50
55
  );
51
56
  return { result: "apply" };
52
57
  };
53
58
  const collapseDuplicateMergeKeysInFile = (input) => replaceAllUntilStable(
54
59
  input,
55
- /^([ \-]*)<<: \[?(\*[^\n\]]+)\]?$\n^( *)<<: \[?(\*[^\n\]]+)\]?$/gm,
56
- (match, a, b, c, d) => {
57
- if (a.length === c.length) {
58
- return `${a}<<: [${b}, ${d}]`;
60
+ /^([ \-]*)<<: \[?(\*[^\n#\]]+)\]?(\s*#.*)?$\n^( *)<<: \[?(\*[^\n#\]]+)\]?(\s*#.*)?$/gm,
61
+ (match, prefixA, keyA, commentA, prefixB, keyB, commentB) => {
62
+ if (prefixA.length === prefixB.length) {
63
+ return [
64
+ ...commentA ? [`${" ".repeat(prefixA.length)}${commentA.trim()}`] : [],
65
+ ...commentB ? [`${" ".repeat(prefixA.length)}${commentB.trim()}`] : [],
66
+ `${prefixA}<<: [${keyA.trim()}, ${keyB.trim()}]`
67
+ ].join("\n");
59
68
  }
60
69
  return match;
61
70
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../src/cli/lint/internalLints/upgrade/patches/8.2.1/collapseDuplicateMergeKeys.ts"],
4
- "sourcesContent": ["import { inspect } from 'util';\n\nimport { glob } from 'fast-glob';\nimport { promises as fs } from 'fs-extra';\n\nimport type { PatchFunction, PatchReturnType } from '../..';\nimport { log } from '../../../../../../utils/logging';\n\nconst collapseDuplicateMergeKeys: PatchFunction = async ({\n mode,\n}): Promise<PatchReturnType> => {\n const buildkiteFiles = await glob(\n ['.buildkite/**/*.yml', '.buildkite/**/*.yaml'],\n { onlyFiles: true },\n );\n\n if (buildkiteFiles.length === 0) {\n return { result: 'skip', reason: 'no Buildkite files found' };\n }\n\n const input = await Promise.all(\n buildkiteFiles.map((name) => fs.readFile(name, 'utf-8')),\n );\n\n const replaced = input.map(collapseDuplicateMergeKeysInFile);\n\n if (replaced.every((r, i) => r === input[i])) {\n return { result: 'skip', reason: 'no duplicate merge keys found' };\n }\n\n if (mode === 'lint') {\n return { result: 'apply' };\n }\n\n await Promise.all(\n buildkiteFiles\n .map((name, i) => [name, i] as const)\n .filter(([, i]) => replaced[i] !== input[i])\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n .map(([name, i]) => fs.writeFile(name, replaced[i]!)),\n );\n\n return { result: 'apply' };\n};\n\nconst collapseDuplicateMergeKeysInFile = (input: string) =>\n replaceAllUntilStable(\n input,\n /^([ \\-]*)<<: \\[?(\\*[^\\n\\]]+)\\]?$\\n^( *)<<: \\[?(\\*[^\\n\\]]+)\\]?$/gm,\n (match, a, b, c, d) => {\n if (a.length === c.length) {\n return `${a}<<: [${b}, ${d}]`;\n }\n return match;\n },\n );\n\nconst replaceAllUntilStable = (\n input: string,\n searchValue: RegExp,\n replacer: (substring: string, ...args: string[]) => string,\n): string => {\n let output = input;\n let previousOutput;\n\n do {\n previousOutput = output;\n output = output.replace(searchValue, replacer);\n } while (output !== previousOutput);\n\n return output;\n};\n\nexport const tryCollapseDuplicateMergeKeys: PatchFunction = async (config) => {\n try {\n return await collapseDuplicateMergeKeys(config);\n } catch (err) {\n log.warn('Failed to collapse duplicate merge keys.');\n log.subtle(inspect(err));\n return { result: 'skip', reason: 'due to an error' };\n }\n};\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAwB;AAExB,uBAAqB;AACrB,sBAA+B;AAG/B,qBAAoB;AAEpB,MAAM,6BAA4C,OAAO;AAAA,EACvD;AACF,MAAgC;AAC9B,QAAM,iBAAiB,UAAM;AAAA,IAC3B,CAAC,uBAAuB,sBAAsB;AAAA,IAC9C,EAAE,WAAW,KAAK;AAAA,EACpB;AAEA,MAAI,eAAe,WAAW,GAAG;AAC/B,WAAO,EAAE,QAAQ,QAAQ,QAAQ,2BAA2B;AAAA,EAC9D;AAEA,QAAM,QAAQ,MAAM,QAAQ;AAAA,IAC1B,eAAe,IAAI,CAAC,SAAS,gBAAAA,SAAG,SAAS,MAAM,OAAO,CAAC;AAAA,EACzD;AAEA,QAAM,WAAW,MAAM,IAAI,gCAAgC;AAE3D,MAAI,SAAS,MAAM,CAAC,GAAG,MAAM,MAAM,MAAM,CAAC,CAAC,GAAG;AAC5C,WAAO,EAAE,QAAQ,QAAQ,QAAQ,gCAAgC;AAAA,EACnE;AAEA,MAAI,SAAS,QAAQ;AACnB,WAAO,EAAE,QAAQ,QAAQ;AAAA,EAC3B;AAEA,QAAM,QAAQ;AAAA,IACZ,eACG,IAAI,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,CAAU,EACnC,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,SAAS,CAAC,MAAM,MAAM,CAAC,CAAC,EAE1C,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,gBAAAA,SAAG,UAAU,MAAM,SAAS,CAAC,CAAE,CAAC;AAAA,EACxD;AAEA,SAAO,EAAE,QAAQ,QAAQ;AAC3B;AAEA,MAAM,mCAAmC,CAAC,UACxC;AAAA,EACE;AAAA,EACA;AAAA,EACA,CAAC,OAAO,GAAG,GAAG,GAAG,MAAM;AACrB,QAAI,EAAE,WAAW,EAAE,QAAQ;AACzB,aAAO,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC;AAAA,IAC5B;AACA,WAAO;AAAA,EACT;AACF;AAEF,MAAM,wBAAwB,CAC5B,OACA,aACA,aACW;AACX,MAAI,SAAS;AACb,MAAI;AAEJ,KAAG;AACD,qBAAiB;AACjB,aAAS,OAAO,QAAQ,aAAa,QAAQ;AAAA,EAC/C,SAAS,WAAW;AAEpB,SAAO;AACT;AAEO,MAAM,gCAA+C,OAAO,WAAW;AAC5E,MAAI;AACF,WAAO,MAAM,2BAA2B,MAAM;AAAA,EAChD,SAAS,KAAK;AACZ,uBAAI,KAAK,0CAA0C;AACnD,uBAAI,WAAO,qBAAQ,GAAG,CAAC;AACvB,WAAO,EAAE,QAAQ,QAAQ,QAAQ,kBAAkB;AAAA,EACrD;AACF;",
4
+ "sourcesContent": ["import { inspect } from 'util';\n\nimport { glob } from 'fast-glob';\nimport { promises as fs } from 'fs-extra';\n\nimport type { PatchFunction, PatchReturnType } from '../..';\nimport { log } from '../../../../../../utils/logging';\n\nconst collapseDuplicateMergeKeys: PatchFunction = async ({\n mode,\n}): Promise<PatchReturnType> => {\n const buildkiteFiles = await glob(\n ['{apps/*/,packages/*/,./}.buildkite/**/*.y*ml'],\n { onlyFiles: true },\n );\n\n if (buildkiteFiles.length === 0) {\n return { result: 'skip', reason: 'no Buildkite files found' };\n }\n\n const input = await Promise.all(\n buildkiteFiles.map((name) => fs.readFile(name, 'utf-8')),\n );\n\n const replaced = input.map(collapseDuplicateMergeKeysInFile);\n\n if (replaced.every((r, i) => r === input[i])) {\n return { result: 'skip', reason: 'no duplicate merge keys found' };\n }\n\n if (mode === 'lint') {\n return { result: 'apply' };\n }\n\n await Promise.all(\n buildkiteFiles.flatMap((name, i) =>\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n replaced[i] !== input[i] ? [fs.writeFile(name, replaced[i]!)] : [],\n ),\n );\n\n return { result: 'apply' };\n};\n\nconst collapseDuplicateMergeKeysInFile = (input: string) =>\n replaceAllUntilStable(\n input,\n /^([ \\-]*)<<: \\[?(\\*[^\\n#\\]]+)\\]?(\\s*#.*)?$\\n^( *)<<: \\[?(\\*[^\\n#\\]]+)\\]?(\\s*#.*)?$/gm,\n (match, prefixA, keyA, commentA, prefixB, keyB, commentB) => {\n if (prefixA.length === prefixB.length) {\n return [\n ...(commentA\n ? [`${' '.repeat(prefixA.length)}${commentA.trim()}`]\n : []),\n ...(commentB\n ? [`${' '.repeat(prefixA.length)}${commentB.trim()}`]\n : []),\n `${prefixA}<<: [${keyA.trim()}, ${keyB.trim()}]`,\n ].join('\\n');\n }\n return match;\n },\n );\n\nconst replaceAllUntilStable = (\n input: string,\n searchValue: RegExp,\n replacer: (substring: string, ...args: string[]) => string,\n): string => {\n let output = input;\n let previousOutput;\n\n do {\n previousOutput = output;\n output = output.replace(searchValue, replacer);\n } while (output !== previousOutput);\n\n return output;\n};\n\nexport const tryCollapseDuplicateMergeKeys: PatchFunction = async (config) => {\n try {\n return await collapseDuplicateMergeKeys(config);\n } catch (err) {\n log.warn('Failed to collapse duplicate merge keys.');\n log.subtle(inspect(err));\n return { result: 'skip', reason: 'due to an error' };\n }\n};\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAwB;AAExB,uBAAqB;AACrB,sBAA+B;AAG/B,qBAAoB;AAEpB,MAAM,6BAA4C,OAAO;AAAA,EACvD;AACF,MAAgC;AAC9B,QAAM,iBAAiB,UAAM;AAAA,IAC3B,CAAC,8CAA8C;AAAA,IAC/C,EAAE,WAAW,KAAK;AAAA,EACpB;AAEA,MAAI,eAAe,WAAW,GAAG;AAC/B,WAAO,EAAE,QAAQ,QAAQ,QAAQ,2BAA2B;AAAA,EAC9D;AAEA,QAAM,QAAQ,MAAM,QAAQ;AAAA,IAC1B,eAAe,IAAI,CAAC,SAAS,gBAAAA,SAAG,SAAS,MAAM,OAAO,CAAC;AAAA,EACzD;AAEA,QAAM,WAAW,MAAM,IAAI,gCAAgC;AAE3D,MAAI,SAAS,MAAM,CAAC,GAAG,MAAM,MAAM,MAAM,CAAC,CAAC,GAAG;AAC5C,WAAO,EAAE,QAAQ,QAAQ,QAAQ,gCAAgC;AAAA,EACnE;AAEA,MAAI,SAAS,QAAQ;AACnB,WAAO,EAAE,QAAQ,QAAQ;AAAA,EAC3B;AAEA,QAAM,QAAQ;AAAA,IACZ,eAAe;AAAA,MAAQ,CAAC,MAAM;AAAA;AAAA,QAE5B,SAAS,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,gBAAAA,SAAG,UAAU,MAAM,SAAS,CAAC,CAAE,CAAC,IAAI,CAAC;AAAA;AAAA,IACnE;AAAA,EACF;AAEA,SAAO,EAAE,QAAQ,QAAQ;AAC3B;AAEA,MAAM,mCAAmC,CAAC,UACxC;AAAA,EACE;AAAA,EACA;AAAA,EACA,CAAC,OAAO,SAAS,MAAM,UAAU,SAAS,MAAM,aAAa;AAC3D,QAAI,QAAQ,WAAW,QAAQ,QAAQ;AACrC,aAAO;AAAA,QACL,GAAI,WACA,CAAC,GAAG,IAAI,OAAO,QAAQ,MAAM,CAAC,GAAG,SAAS,KAAK,CAAC,EAAE,IAClD,CAAC;AAAA,QACL,GAAI,WACA,CAAC,GAAG,IAAI,OAAO,QAAQ,MAAM,CAAC,GAAG,SAAS,KAAK,CAAC,EAAE,IAClD,CAAC;AAAA,QACL,GAAG,OAAO,QAAQ,KAAK,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC;AAAA,MAC/C,EAAE,KAAK,IAAI;AAAA,IACb;AACA,WAAO;AAAA,EACT;AACF;AAEF,MAAM,wBAAwB,CAC5B,OACA,aACA,aACW;AACX,MAAI,SAAS;AACb,MAAI;AAEJ,KAAG;AACD,qBAAiB;AACjB,aAAS,OAAO,QAAQ,aAAa,QAAQ;AAAA,EAC/C,SAAS,WAAW;AAEpB,SAAO;AACT;AAEO,MAAM,gCAA+C,OAAO,WAAW;AAC5E,MAAI;AACF,WAAO,MAAM,2BAA2B,MAAM;AAAA,EAChD,SAAS,KAAK;AACZ,uBAAI,KAAK,0CAA0C;AACnD,uBAAI,WAAO,qBAAQ,GAAG,CAAC;AACvB,WAAO,EAAE,QAAQ,QAAQ,QAAQ,kBAAkB;AAAA,EACrD;AACF;",
6
6
  "names": ["fs"]
7
7
  }
@@ -22,7 +22,9 @@ __export(__exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(__exports);
24
24
  var import_collapseDuplicateMergeKeys = require("./collapseDuplicateMergeKeys");
25
+ var import_moveNpmrcMounts = require("./moveNpmrcMounts");
25
26
  var import_patchDockerCompose = require("./patchDockerCompose");
27
+ var import_patchDockerImages = require("./patchDockerImages");
26
28
  var import_upgradeESLint = require("./upgradeESLint");
27
29
  const patches = [
28
30
  {
@@ -36,6 +38,14 @@ const patches = [
36
38
  {
37
39
  apply: import_patchDockerCompose.tryPatchDockerComposeFiles,
38
40
  description: "Remove version field from docker-compose files"
41
+ },
42
+ {
43
+ apply: import_patchDockerImages.tryPatchDockerImages,
44
+ description: "Update docker image references to use public.ecr.aws and remove --platform flag"
45
+ },
46
+ {
47
+ apply: import_moveNpmrcMounts.tryMoveNpmrcMounts,
48
+ description: "Move .npmrc mounts from tmp/.npmrc to /tmp/.npmrc"
39
49
  }
40
50
  ];
41
51
  // Annotate the CommonJS export names for ESM import in node:
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../src/cli/lint/internalLints/upgrade/patches/8.2.1/index.ts"],
4
- "sourcesContent": ["import type { Patches } from '../..';\n\nimport { tryCollapseDuplicateMergeKeys } from './collapseDuplicateMergeKeys';\nimport { tryPatchDockerComposeFiles } from './patchDockerCompose';\nimport { tryUpgradeESLint } from './upgradeESLint';\n\nexport const patches: Patches = [\n {\n apply: tryCollapseDuplicateMergeKeys,\n description: 'Collapse duplicate merge keys in .buildkite files',\n },\n {\n apply: tryUpgradeESLint,\n description: 'Upgrade to ESLint flat config',\n },\n {\n apply: tryPatchDockerComposeFiles,\n description: 'Remove version field from docker-compose files',\n },\n];\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,wCAA8C;AAC9C,gCAA2C;AAC3C,2BAAiC;AAE1B,MAAM,UAAmB;AAAA,EAC9B;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AACF;",
4
+ "sourcesContent": ["import type { Patches } from '../..';\n\nimport { tryCollapseDuplicateMergeKeys } from './collapseDuplicateMergeKeys';\nimport { tryMoveNpmrcMounts } from './moveNpmrcMounts';\nimport { tryPatchDockerComposeFiles } from './patchDockerCompose';\nimport { tryPatchDockerImages } from './patchDockerImages';\nimport { tryUpgradeESLint } from './upgradeESLint';\n\nexport const patches: Patches = [\n {\n apply: tryCollapseDuplicateMergeKeys,\n description: 'Collapse duplicate merge keys in .buildkite files',\n },\n {\n apply: tryUpgradeESLint,\n description: 'Upgrade to ESLint flat config',\n },\n {\n apply: tryPatchDockerComposeFiles,\n description: 'Remove version field from docker-compose files',\n },\n {\n apply: tryPatchDockerImages,\n description:\n 'Update docker image references to use public.ecr.aws and remove --platform flag',\n },\n {\n apply: tryMoveNpmrcMounts,\n description: 'Move .npmrc mounts from tmp/.npmrc to /tmp/.npmrc',\n },\n];\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,wCAA8C;AAC9C,6BAAmC;AACnC,gCAA2C;AAC3C,+BAAqC;AACrC,2BAAiC;AAE1B,MAAM,UAAmB;AAAA,EAC9B;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aACE;AAAA,EACJ;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AACF;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,2 @@
1
+ import type { PatchFunction } from '../..';
2
+ export declare const tryMoveNpmrcMounts: PatchFunction;
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var moveNpmrcMounts_exports = {};
20
+ __export(moveNpmrcMounts_exports, {
21
+ tryMoveNpmrcMounts: () => tryMoveNpmrcMounts
22
+ });
23
+ module.exports = __toCommonJS(moveNpmrcMounts_exports);
24
+ var import_util = require("util");
25
+ var import_fast_glob = require("fast-glob");
26
+ var import_fs_extra = require("fs-extra");
27
+ var import_logging = require("../../../../../../utils/logging");
28
+ const moveNpmrcMounts = async ({
29
+ mode
30
+ }) => {
31
+ const buildkiteFiles = await (0, import_fast_glob.glob)(
32
+ ["{apps/*/,packages/*/,./}.buildkite/**/*.y*ml"],
33
+ { onlyFiles: true }
34
+ );
35
+ if (buildkiteFiles.length === 0) {
36
+ return { result: "skip", reason: "no Buildkite files found" };
37
+ }
38
+ const input = await Promise.all(
39
+ buildkiteFiles.map((name) => import_fs_extra.promises.readFile(name, "utf-8"))
40
+ );
41
+ const replaced = input.map(moveNpmrcMountsInFile);
42
+ if (replaced.every((r, i) => r === input[i])) {
43
+ return {
44
+ result: "skip",
45
+ reason: "no .npmrc mounts found need to be updated"
46
+ };
47
+ }
48
+ if (mode === "lint") {
49
+ return { result: "apply" };
50
+ }
51
+ await Promise.all(
52
+ buildkiteFiles.flatMap(
53
+ (name, i) => (
54
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
55
+ replaced[i] !== input[i] ? [import_fs_extra.promises.writeFile(name, replaced[i])] : []
56
+ )
57
+ )
58
+ );
59
+ return { result: "apply" };
60
+ };
61
+ const secret = /^(\s*)secrets: id=npm,src=tmp\/\.npmrc(\s*#?.*)$/gm;
62
+ const outputPath = /^(\s*)output-path: tmp\/(\s*#?.*)$/gm;
63
+ const moveNpmrcMountsInFile = (input) => {
64
+ if (!secret.test(input) || !outputPath.test(input)) {
65
+ return input;
66
+ }
67
+ return input.replaceAll(secret, "$1secrets: id=npm,src=/tmp/.npmrc$2").replaceAll(outputPath, "$1output-path: /tmp/$2");
68
+ };
69
+ const tryMoveNpmrcMounts = async (config) => {
70
+ try {
71
+ return await moveNpmrcMounts(config);
72
+ } catch (err) {
73
+ import_logging.log.warn("Failed to move .npmrc mounts");
74
+ import_logging.log.subtle((0, import_util.inspect)(err));
75
+ return { result: "skip", reason: "due to an error" };
76
+ }
77
+ };
78
+ // Annotate the CommonJS export names for ESM import in node:
79
+ 0 && (module.exports = {
80
+ tryMoveNpmrcMounts
81
+ });
82
+ //# sourceMappingURL=moveNpmrcMounts.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../../src/cli/lint/internalLints/upgrade/patches/8.2.1/moveNpmrcMounts.ts"],
4
+ "sourcesContent": ["import { inspect } from 'util';\n\nimport { glob } from 'fast-glob';\nimport { promises as fs } from 'fs-extra';\n\nimport type { PatchFunction, PatchReturnType } from '../..';\nimport { log } from '../../../../../../utils/logging';\n\nconst moveNpmrcMounts: PatchFunction = async ({\n mode,\n}): Promise<PatchReturnType> => {\n const buildkiteFiles = await glob(\n ['{apps/*/,packages/*/,./}.buildkite/**/*.y*ml'],\n { onlyFiles: true },\n );\n\n if (buildkiteFiles.length === 0) {\n return { result: 'skip', reason: 'no Buildkite files found' };\n }\n\n const input = await Promise.all(\n buildkiteFiles.map((name) => fs.readFile(name, 'utf-8')),\n );\n\n const replaced = input.map(moveNpmrcMountsInFile);\n\n if (replaced.every((r, i) => r === input[i])) {\n return {\n result: 'skip',\n reason: 'no .npmrc mounts found need to be updated',\n };\n }\n\n if (mode === 'lint') {\n return { result: 'apply' };\n }\n\n await Promise.all(\n buildkiteFiles.flatMap((name, i) =>\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n replaced[i] !== input[i] ? [fs.writeFile(name, replaced[i]!)] : [],\n ),\n );\n\n return { result: 'apply' };\n};\n\nconst secret = /^(\\s*)secrets: id=npm,src=tmp\\/\\.npmrc(\\s*#?.*)$/gm;\nconst outputPath = /^(\\s*)output-path: tmp\\/(\\s*#?.*)$/gm;\n\nconst moveNpmrcMountsInFile = (input: string) => {\n if (!secret.test(input) || !outputPath.test(input)) {\n return input;\n }\n\n return input\n .replaceAll(secret, '$1secrets: id=npm,src=/tmp/.npmrc$2')\n .replaceAll(outputPath, '$1output-path: /tmp/$2');\n};\n\nexport const tryMoveNpmrcMounts: PatchFunction = async (config) => {\n try {\n return await moveNpmrcMounts(config);\n } catch (err) {\n log.warn('Failed to move .npmrc mounts');\n log.subtle(inspect(err));\n return { result: 'skip', reason: 'due to an error' };\n }\n};\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAwB;AAExB,uBAAqB;AACrB,sBAA+B;AAG/B,qBAAoB;AAEpB,MAAM,kBAAiC,OAAO;AAAA,EAC5C;AACF,MAAgC;AAC9B,QAAM,iBAAiB,UAAM;AAAA,IAC3B,CAAC,8CAA8C;AAAA,IAC/C,EAAE,WAAW,KAAK;AAAA,EACpB;AAEA,MAAI,eAAe,WAAW,GAAG;AAC/B,WAAO,EAAE,QAAQ,QAAQ,QAAQ,2BAA2B;AAAA,EAC9D;AAEA,QAAM,QAAQ,MAAM,QAAQ;AAAA,IAC1B,eAAe,IAAI,CAAC,SAAS,gBAAAA,SAAG,SAAS,MAAM,OAAO,CAAC;AAAA,EACzD;AAEA,QAAM,WAAW,MAAM,IAAI,qBAAqB;AAEhD,MAAI,SAAS,MAAM,CAAC,GAAG,MAAM,MAAM,MAAM,CAAC,CAAC,GAAG;AAC5C,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,MAAI,SAAS,QAAQ;AACnB,WAAO,EAAE,QAAQ,QAAQ;AAAA,EAC3B;AAEA,QAAM,QAAQ;AAAA,IACZ,eAAe;AAAA,MAAQ,CAAC,MAAM;AAAA;AAAA,QAE5B,SAAS,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,gBAAAA,SAAG,UAAU,MAAM,SAAS,CAAC,CAAE,CAAC,IAAI,CAAC;AAAA;AAAA,IACnE;AAAA,EACF;AAEA,SAAO,EAAE,QAAQ,QAAQ;AAC3B;AAEA,MAAM,SAAS;AACf,MAAM,aAAa;AAEnB,MAAM,wBAAwB,CAAC,UAAkB;AAC/C,MAAI,CAAC,OAAO,KAAK,KAAK,KAAK,CAAC,WAAW,KAAK,KAAK,GAAG;AAClD,WAAO;AAAA,EACT;AAEA,SAAO,MACJ,WAAW,QAAQ,qCAAqC,EACxD,WAAW,YAAY,wBAAwB;AACpD;AAEO,MAAM,qBAAoC,OAAO,WAAW;AACjE,MAAI;AACF,WAAO,MAAM,gBAAgB,MAAM;AAAA,EACrC,SAAS,KAAK;AACZ,uBAAI,KAAK,8BAA8B;AACvC,uBAAI,WAAO,qBAAQ,GAAG,CAAC;AACvB,WAAO,EAAE,QAAQ,QAAQ,QAAQ,kBAAkB;AAAA,EACrD;AACF;",
6
+ "names": ["fs"]
7
+ }
@@ -48,9 +48,7 @@ const fetchFiles = async (files) => Promise.all(
48
48
  const patchDockerComposeFiles = async ({
49
49
  mode
50
50
  }) => {
51
- const maybeDockerComposeFiles = await Promise.resolve(
52
- (0, import_fast_glob.default)(["docker-compose*.yml"])
53
- );
51
+ const maybeDockerComposeFiles = await (0, import_fast_glob.default)(["docker-compose*.yml"]);
54
52
  if (!maybeDockerComposeFiles.length) {
55
53
  return {
56
54
  result: "skip",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../src/cli/lint/internalLints/upgrade/patches/8.2.1/patchDockerCompose.ts"],
4
- "sourcesContent": ["import { inspect } from 'util';\n\nimport fg from 'fast-glob';\nimport { readFile, writeFile } from 'fs-extra';\n\nimport type { PatchFunction, PatchReturnType } from '../..';\nimport { log } from '../../../../../../utils/logging';\n\nconst DOCKER_COMPOSE_VERSION_REGEX = /^version: ['\"]?\\d+(\\.\\d+)*['\"]?\\n*/m;\n\nconst fetchFiles = async (files: string[]) =>\n Promise.all(\n files.map(async (file) => {\n const contents = await readFile(file, 'utf8');\n\n return {\n file,\n contents,\n };\n }),\n );\n\nconst patchDockerComposeFiles: PatchFunction = async ({\n mode,\n}): Promise<PatchReturnType> => {\n const maybeDockerComposeFiles = await Promise.resolve(\n fg(['docker-compose*.yml']),\n );\n\n if (!maybeDockerComposeFiles.length) {\n return {\n result: 'skip',\n reason: 'no docker-compose files found',\n };\n }\n\n const dockerComposeFiles = await fetchFiles(maybeDockerComposeFiles);\n\n const dockerComposeFilesToPatch = dockerComposeFiles.filter(({ contents }) =>\n DOCKER_COMPOSE_VERSION_REGEX.exec(contents),\n );\n\n if (!dockerComposeFilesToPatch.length) {\n return {\n result: 'skip',\n reason: 'no docker-compose files to patch',\n };\n }\n\n if (mode === 'lint') {\n return {\n result: 'apply',\n };\n }\n\n await Promise.all(\n dockerComposeFilesToPatch.map(async ({ file, contents }) => {\n const patchedContents = contents.replace(\n DOCKER_COMPOSE_VERSION_REGEX,\n '',\n );\n await writeFile(file, patchedContents);\n }),\n );\n\n return { result: 'apply' };\n};\n\nexport const tryPatchDockerComposeFiles: PatchFunction = async (config) => {\n try {\n return await patchDockerComposeFiles(config);\n } catch (err) {\n log.warn('Failed to patch pnpm packageManager CI configuration.');\n log.subtle(inspect(err));\n return { result: 'skip', reason: 'due to an error' };\n }\n};\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAwB;AAExB,uBAAe;AACf,sBAAoC;AAGpC,qBAAoB;AAEpB,MAAM,+BAA+B;AAErC,MAAM,aAAa,OAAO,UACxB,QAAQ;AAAA,EACN,MAAM,IAAI,OAAO,SAAS;AACxB,UAAM,WAAW,UAAM,0BAAS,MAAM,MAAM;AAE5C,WAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEF,MAAM,0BAAyC,OAAO;AAAA,EACpD;AACF,MAAgC;AAC9B,QAAM,0BAA0B,MAAM,QAAQ;AAAA,QAC5C,iBAAAA,SAAG,CAAC,qBAAqB,CAAC;AAAA,EAC5B;AAEA,MAAI,CAAC,wBAAwB,QAAQ;AACnC,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,QAAM,qBAAqB,MAAM,WAAW,uBAAuB;AAEnE,QAAM,4BAA4B,mBAAmB;AAAA,IAAO,CAAC,EAAE,SAAS,MACtE,6BAA6B,KAAK,QAAQ;AAAA,EAC5C;AAEA,MAAI,CAAC,0BAA0B,QAAQ;AACrC,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,MAAI,SAAS,QAAQ;AACnB,WAAO;AAAA,MACL,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,QAAM,QAAQ;AAAA,IACZ,0BAA0B,IAAI,OAAO,EAAE,MAAM,SAAS,MAAM;AAC1D,YAAM,kBAAkB,SAAS;AAAA,QAC/B;AAAA,QACA;AAAA,MACF;AACA,gBAAM,2BAAU,MAAM,eAAe;AAAA,IACvC,CAAC;AAAA,EACH;AAEA,SAAO,EAAE,QAAQ,QAAQ;AAC3B;AAEO,MAAM,6BAA4C,OAAO,WAAW;AACzE,MAAI;AACF,WAAO,MAAM,wBAAwB,MAAM;AAAA,EAC7C,SAAS,KAAK;AACZ,uBAAI,KAAK,uDAAuD;AAChE,uBAAI,WAAO,qBAAQ,GAAG,CAAC;AACvB,WAAO,EAAE,QAAQ,QAAQ,QAAQ,kBAAkB;AAAA,EACrD;AACF;",
4
+ "sourcesContent": ["import { inspect } from 'util';\n\nimport fg from 'fast-glob';\nimport { readFile, writeFile } from 'fs-extra';\n\nimport type { PatchFunction, PatchReturnType } from '../..';\nimport { log } from '../../../../../../utils/logging';\n\nconst DOCKER_COMPOSE_VERSION_REGEX = /^version: ['\"]?\\d+(\\.\\d+)*['\"]?\\n*/m;\n\nconst fetchFiles = async (files: string[]) =>\n Promise.all(\n files.map(async (file) => {\n const contents = await readFile(file, 'utf8');\n\n return {\n file,\n contents,\n };\n }),\n );\n\nconst patchDockerComposeFiles: PatchFunction = async ({\n mode,\n}): Promise<PatchReturnType> => {\n const maybeDockerComposeFiles = await fg(['docker-compose*.yml']);\n\n if (!maybeDockerComposeFiles.length) {\n return {\n result: 'skip',\n reason: 'no docker-compose files found',\n };\n }\n\n const dockerComposeFiles = await fetchFiles(maybeDockerComposeFiles);\n\n const dockerComposeFilesToPatch = dockerComposeFiles.filter(({ contents }) =>\n DOCKER_COMPOSE_VERSION_REGEX.exec(contents),\n );\n\n if (!dockerComposeFilesToPatch.length) {\n return {\n result: 'skip',\n reason: 'no docker-compose files to patch',\n };\n }\n\n if (mode === 'lint') {\n return {\n result: 'apply',\n };\n }\n\n await Promise.all(\n dockerComposeFilesToPatch.map(async ({ file, contents }) => {\n const patchedContents = contents.replace(\n DOCKER_COMPOSE_VERSION_REGEX,\n '',\n );\n await writeFile(file, patchedContents);\n }),\n );\n\n return { result: 'apply' };\n};\n\nexport const tryPatchDockerComposeFiles: PatchFunction = async (config) => {\n try {\n return await patchDockerComposeFiles(config);\n } catch (err) {\n log.warn('Failed to patch pnpm packageManager CI configuration.');\n log.subtle(inspect(err));\n return { result: 'skip', reason: 'due to an error' };\n }\n};\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAwB;AAExB,uBAAe;AACf,sBAAoC;AAGpC,qBAAoB;AAEpB,MAAM,+BAA+B;AAErC,MAAM,aAAa,OAAO,UACxB,QAAQ;AAAA,EACN,MAAM,IAAI,OAAO,SAAS;AACxB,UAAM,WAAW,UAAM,0BAAS,MAAM,MAAM;AAE5C,WAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEF,MAAM,0BAAyC,OAAO;AAAA,EACpD;AACF,MAAgC;AAC9B,QAAM,0BAA0B,UAAM,iBAAAA,SAAG,CAAC,qBAAqB,CAAC;AAEhE,MAAI,CAAC,wBAAwB,QAAQ;AACnC,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,QAAM,qBAAqB,MAAM,WAAW,uBAAuB;AAEnE,QAAM,4BAA4B,mBAAmB;AAAA,IAAO,CAAC,EAAE,SAAS,MACtE,6BAA6B,KAAK,QAAQ;AAAA,EAC5C;AAEA,MAAI,CAAC,0BAA0B,QAAQ;AACrC,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,MAAI,SAAS,QAAQ;AACnB,WAAO;AAAA,MACL,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,QAAM,QAAQ;AAAA,IACZ,0BAA0B,IAAI,OAAO,EAAE,MAAM,SAAS,MAAM;AAC1D,YAAM,kBAAkB,SAAS;AAAA,QAC/B;AAAA,QACA;AAAA,MACF;AACA,gBAAM,2BAAU,MAAM,eAAe;AAAA,IACvC,CAAC;AAAA,EACH;AAEA,SAAO,EAAE,QAAQ,QAAQ;AAC3B;AAEO,MAAM,6BAA4C,OAAO,WAAW;AACzE,MAAI;AACF,WAAO,MAAM,wBAAwB,MAAM;AAAA,EAC7C,SAAS,KAAK;AACZ,uBAAI,KAAK,uDAAuD;AAChE,uBAAI,WAAO,qBAAQ,GAAG,CAAC;AACvB,WAAO,EAAE,QAAQ,QAAQ,QAAQ,kBAAkB;AAAA,EACrD;AACF;",
6
6
  "names": ["fg"]
7
7
  }
@@ -0,0 +1,2 @@
1
+ import type { PatchFunction } from '../..';
2
+ export declare const tryPatchDockerImages: PatchFunction;
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var patchDockerImages_exports = {};
30
+ __export(patchDockerImages_exports, {
31
+ tryPatchDockerImages: () => tryPatchDockerImages
32
+ });
33
+ module.exports = __toCommonJS(patchDockerImages_exports);
34
+ var import_util = require("util");
35
+ var import_fast_glob = __toESM(require("fast-glob"));
36
+ var import_fs_extra = require("fs-extra");
37
+ var import_logging = require("../../../../../../utils/logging");
38
+ const DOCKER_IMAGE_REGEX = /^(FROM\s?.*)(\s)(node|python)(:.*)/gm;
39
+ const DOCKER_IMAGE_PLATFORM_REGEX = /^(FROM\s?.*)(--platform=[^\s]+) /gm;
40
+ const DOCKER_COMPOSE_IMAGE_REGEX = /^(\s+image:\s)(node|python)(:.*)/gm;
41
+ const PUBLIC_ECR = "public.ecr.aws/docker/library/";
42
+ const fetchFiles = async (files) => Promise.all(
43
+ files.map(async (file) => {
44
+ const contents = await (0, import_fs_extra.readFile)(file, "utf8");
45
+ return {
46
+ file,
47
+ contents
48
+ };
49
+ })
50
+ );
51
+ const isInvalidPlatformFlagUsage = (contents) => {
52
+ const matches = [...contents.matchAll(DOCKER_IMAGE_PLATFORM_REGEX)];
53
+ if (!matches.length) {
54
+ return false;
55
+ }
56
+ const uniquePlatforms = [
57
+ ...new Set(matches.map(([, , platform]) => platform))
58
+ ];
59
+ if (uniquePlatforms.length > 1) {
60
+ return false;
61
+ }
62
+ if (uniquePlatforms[0]?.startsWith("--platform=$")) {
63
+ return false;
64
+ }
65
+ return true;
66
+ };
67
+ const patchDockerImages = async ({
68
+ mode
69
+ }) => {
70
+ const [maybeDockerFilesPaths, maybeDockerComposePaths] = await Promise.all([
71
+ (0, import_fast_glob.default)(["Dockerfile*"]),
72
+ (0, import_fast_glob.default)(["docker-compose*.y*ml"])
73
+ ]);
74
+ if (!maybeDockerFilesPaths.length && !maybeDockerComposePaths.length) {
75
+ return {
76
+ result: "skip",
77
+ reason: "no Dockerfile or docker-compose files found"
78
+ };
79
+ }
80
+ const [dockerFiles, dockerComposeFiles] = await Promise.all([
81
+ fetchFiles(maybeDockerFilesPaths),
82
+ fetchFiles(maybeDockerComposePaths)
83
+ ]);
84
+ const dockerFilesToPatch = dockerFiles.filter(
85
+ ({ contents }) => DOCKER_IMAGE_REGEX.exec(contents) ?? isInvalidPlatformFlagUsage(contents)
86
+ );
87
+ const dockerComposeFilesToPatch = dockerComposeFiles.filter(
88
+ ({ contents }) => DOCKER_COMPOSE_IMAGE_REGEX.exec(contents)
89
+ );
90
+ if (!dockerFilesToPatch.length && !dockerComposeFilesToPatch.length) {
91
+ return {
92
+ result: "skip",
93
+ reason: "no Dockerfile or docker-compose files to patch"
94
+ };
95
+ }
96
+ if (mode === "lint") {
97
+ return {
98
+ result: "apply"
99
+ };
100
+ }
101
+ const dockerFilePatches = dockerFilesToPatch.map(
102
+ async ({ file, contents }) => {
103
+ let patchedContents = contents.replace(
104
+ DOCKER_IMAGE_REGEX,
105
+ `$1$2${PUBLIC_ECR}$3$4`
106
+ );
107
+ if (isInvalidPlatformFlagUsage(contents)) {
108
+ patchedContents = patchedContents.replace(
109
+ DOCKER_IMAGE_PLATFORM_REGEX,
110
+ "$1"
111
+ );
112
+ }
113
+ await (0, import_fs_extra.writeFile)(file, patchedContents);
114
+ }
115
+ );
116
+ const dockerComposeFilePatches = dockerComposeFilesToPatch.map(
117
+ async ({ file, contents }) => {
118
+ const patchedContents = contents.replace(
119
+ DOCKER_COMPOSE_IMAGE_REGEX,
120
+ `$1${PUBLIC_ECR}$2$3`
121
+ );
122
+ await (0, import_fs_extra.writeFile)(file, patchedContents);
123
+ }
124
+ );
125
+ await Promise.all([...dockerFilePatches, ...dockerComposeFilePatches]);
126
+ return { result: "apply" };
127
+ };
128
+ const tryPatchDockerImages = async (config) => {
129
+ try {
130
+ return await patchDockerImages(config);
131
+ } catch (err) {
132
+ import_logging.log.warn("Failed to patch Docker images");
133
+ import_logging.log.subtle((0, import_util.inspect)(err));
134
+ return { result: "skip", reason: "due to an error" };
135
+ }
136
+ };
137
+ // Annotate the CommonJS export names for ESM import in node:
138
+ 0 && (module.exports = {
139
+ tryPatchDockerImages
140
+ });
141
+ //# sourceMappingURL=patchDockerImages.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../../src/cli/lint/internalLints/upgrade/patches/8.2.1/patchDockerImages.ts"],
4
+ "sourcesContent": ["import { inspect } from 'util';\n\nimport fg from 'fast-glob';\nimport { readFile, writeFile } from 'fs-extra';\n\nimport type { PatchFunction, PatchReturnType } from '../..';\nimport { log } from '../../../../../../utils/logging';\n\nconst DOCKER_IMAGE_REGEX = /^(FROM\\s?.*)(\\s)(node|python)(:.*)/gm;\nconst DOCKER_IMAGE_PLATFORM_REGEX = /^(FROM\\s?.*)(--platform=[^\\s]+) /gm;\nconst DOCKER_COMPOSE_IMAGE_REGEX = /^(\\s+image:\\s)(node|python)(:.*)/gm;\nconst PUBLIC_ECR = 'public.ecr.aws/docker/library/';\n\nconst fetchFiles = async (files: string[]) =>\n Promise.all(\n files.map(async (file) => {\n const contents = await readFile(file, 'utf8');\n\n return {\n file,\n contents,\n };\n }),\n );\n\nconst isInvalidPlatformFlagUsage = (contents: string) => {\n const matches = [...contents.matchAll(DOCKER_IMAGE_PLATFORM_REGEX)];\n\n if (!matches.length) {\n return false;\n }\n\n const uniquePlatforms = [\n ...new Set(matches.map(([, , platform]) => platform as string)),\n ];\n\n // Multiple --platform flags are used which may indicate a multi arch build\n if (uniquePlatforms.length > 1) {\n return false;\n }\n\n // Avoid patching as they may be using args to set the platform\n if (uniquePlatforms[0]?.startsWith('--platform=$')) {\n return false;\n }\n\n return true;\n};\n\nconst patchDockerImages: PatchFunction = async ({\n mode,\n}): Promise<PatchReturnType> => {\n const [maybeDockerFilesPaths, maybeDockerComposePaths] = await Promise.all([\n fg(['Dockerfile*']),\n fg(['docker-compose*.y*ml']),\n ]);\n\n if (!maybeDockerFilesPaths.length && !maybeDockerComposePaths.length) {\n return {\n result: 'skip',\n reason: 'no Dockerfile or docker-compose files found',\n };\n }\n\n const [dockerFiles, dockerComposeFiles] = await Promise.all([\n fetchFiles(maybeDockerFilesPaths),\n fetchFiles(maybeDockerComposePaths),\n ]);\n\n const dockerFilesToPatch = dockerFiles.filter(\n ({ contents }) =>\n DOCKER_IMAGE_REGEX.exec(contents) ?? isInvalidPlatformFlagUsage(contents),\n );\n\n const dockerComposeFilesToPatch = dockerComposeFiles.filter(({ contents }) =>\n DOCKER_COMPOSE_IMAGE_REGEX.exec(contents),\n );\n\n if (!dockerFilesToPatch.length && !dockerComposeFilesToPatch.length) {\n return {\n result: 'skip',\n reason: 'no Dockerfile or docker-compose files to patch',\n };\n }\n\n if (mode === 'lint') {\n return {\n result: 'apply',\n };\n }\n\n const dockerFilePatches = dockerFilesToPatch.map(\n async ({ file, contents }) => {\n let patchedContents = contents.replace(\n DOCKER_IMAGE_REGEX,\n `$1$2${PUBLIC_ECR}$3$4`,\n );\n\n if (isInvalidPlatformFlagUsage(contents)) {\n patchedContents = patchedContents.replace(\n DOCKER_IMAGE_PLATFORM_REGEX,\n '$1',\n );\n }\n\n await writeFile(file, patchedContents);\n },\n );\n\n const dockerComposeFilePatches = dockerComposeFilesToPatch.map(\n async ({ file, contents }) => {\n const patchedContents = contents.replace(\n DOCKER_COMPOSE_IMAGE_REGEX,\n `$1${PUBLIC_ECR}$2$3`,\n );\n await writeFile(file, patchedContents);\n },\n );\n\n await Promise.all([...dockerFilePatches, ...dockerComposeFilePatches]);\n\n return { result: 'apply' };\n};\n\nexport const tryPatchDockerImages: PatchFunction = async (config) => {\n try {\n return await patchDockerImages(config);\n } catch (err) {\n log.warn('Failed to patch Docker images');\n log.subtle(inspect(err));\n return { result: 'skip', reason: 'due to an error' };\n }\n};\n"],
5
+ "mappings": "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",
6
+ "names": ["fg"]
7
+ }
@@ -98,9 +98,11 @@ const upgradeESLint = async ({
98
98
  };
99
99
  const writeTemporaryFiles = async (contents) => {
100
100
  const dir = await fsp.mkdtemp("eslint-migrate-config");
101
- for (const [file, content] of Object.entries(contents)) {
102
- await fsp.writeFile(import_path.default.join(dir, file), content);
103
- }
101
+ await Promise.all(
102
+ Object.entries(contents).map(
103
+ ([file, content]) => fsp.writeFile(import_path.default.join(dir, file), content)
104
+ )
105
+ );
104
106
  return dir;
105
107
  };
106
108
  const fiddleWithOutput = (input) => {