renovate 44.46.2 → 44.46.4

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.
@@ -14,13 +14,17 @@ const bunyanFields = [
14
14
  "msg",
15
15
  "start_time"
16
16
  ];
17
+ /**
18
+ * If a log contains any of these meta fields in the meta, promote them up to the log line, rather than rendering them with other meta fields.
19
+ *
20
+ * This only applies when these fields have a string value, otherwise they are treated as a regular meta field.
21
+ */
17
22
  const metaFields = [
18
23
  "repository",
19
24
  "baseBranch",
20
25
  "packageFile",
21
26
  "depType",
22
27
  "dependency",
23
- "dependencies",
24
28
  "branch"
25
29
  ];
26
30
  const levels = {
@@ -45,7 +49,7 @@ function indent(str, leading = false) {
45
49
  function getMeta(rec, colorize = true) {
46
50
  if (!rec) return "";
47
51
  let res = rec.module ? ` [${rec.module}]` : ``;
48
- const filteredMeta = metaFields.filter((elem) => rec[elem]);
52
+ const filteredMeta = metaFields.filter((elem) => isString(rec[elem]));
49
53
  if (!filteredMeta.length) return res;
50
54
  res = ` (${filteredMeta.map((field) => `${field}=${String(rec[field])}`).join(", ")})${res}`;
51
55
  return colorize ? util$1.styleText("gray", res) : res;
@@ -55,7 +59,7 @@ function getDetails(rec) {
55
59
  const recFiltered = { ...rec };
56
60
  delete recFiltered.module;
57
61
  Object.keys(recFiltered).forEach((key) => {
58
- if (key === "logContext" || bunyanFields.includes(key) || metaFields.includes(key)) delete recFiltered[key];
62
+ if (key === "logContext" || bunyanFields.includes(key) || metaFields.includes(key) && isString(recFiltered[key])) delete recFiltered[key];
59
63
  });
60
64
  const remainingKeys = Object.keys(recFiltered);
61
65
  if (remainingKeys.length === 0) return "";
@@ -1 +1 @@
1
- {"version":3,"file":"pretty-stdout.js","names":["util"],"sources":["../../lib/logger/pretty-stdout.ts"],"sourcesContent":["// Code originally derived from https://github.com/hadfieldn/node-bunyan-prettystream but since heavily edited\n// Neither fork nor original repo appear to be maintained\n\nimport { Writable } from 'node:stream';\nimport * as util from 'node:util';\nimport { isNonEmptyObject, isPlainObject, isString } from '@sindresorhus/is';\nimport stringify from 'json-stringify-pretty-compact';\nimport { regEx } from '../util/regex.ts';\nimport type { BunyanRecord } from './types.ts';\n\nconst bunyanFields = [\n 'name',\n 'hostname',\n 'pid',\n 'level',\n 'v',\n 'time',\n 'msg',\n 'start_time',\n];\nconst metaFields = [\n 'repository',\n 'baseBranch',\n 'packageFile',\n 'depType',\n 'dependency',\n 'dependencies',\n 'branch',\n];\n\nconst levels: Record<number, string> = {\n 10: 'TRACE',\n 20: 'DEBUG',\n 30: ' INFO',\n 40: ' WARN',\n 50: 'ERROR',\n 60: 'FATAL',\n};\n\nconst colorizedLevels: Record<number, string> = {\n 10: util.styleText('gray', 'TRACE'),\n 20: util.styleText('blue', 'DEBUG'),\n 30: util.styleText('green', ' INFO'),\n 40: util.styleText('magenta', ' WARN'),\n 50: util.styleText('red', 'ERROR'),\n 60: util.styleText('bgRed', 'FATAL'),\n};\n\nexport function indent(str: string, leading = false): string {\n const prefix = leading ? ' ' : '';\n return prefix + str.split(regEx(/\\r?\\n/)).join('\\n ');\n}\n\nexport function getMeta(rec: BunyanRecord, colorize = true): string {\n if (!rec) {\n return '';\n }\n let res = rec.module ? ` [${rec.module}]` : ``;\n const filteredMeta = metaFields.filter((elem) => rec[elem]);\n if (!filteredMeta.length) {\n return res;\n }\n const metaStr = filteredMeta\n .map((field) => `${field}=${String(rec[field])}`)\n .join(', ');\n res = ` (${metaStr})${res}`;\n return colorize ? util.styleText('gray', res) : res;\n}\n\nexport function getDetails(rec: BunyanRecord): string {\n if (!rec) {\n return '';\n }\n const recFiltered = { ...rec };\n delete recFiltered.module;\n Object.keys(recFiltered).forEach((key) => {\n if (\n key === 'logContext' ||\n bunyanFields.includes(key) ||\n metaFields.includes(key)\n ) {\n delete recFiltered[key];\n }\n });\n const remainingKeys = Object.keys(recFiltered);\n if (remainingKeys.length === 0) {\n return '';\n }\n\n // Handle err.stack specially for readable multi-line output\n const err = recFiltered.err;\n if (isPlainObject(err) && isString(err.stack)) {\n const { stack, ...errRest } = err;\n recFiltered.err = isNonEmptyObject(errRest) ? errRest : undefined;\n const parts: string[] = [];\n for (const key of remainingKeys) {\n if (key === 'err' && recFiltered.err === undefined) {\n continue;\n }\n parts.push(indent(`\"${key}\": ${stringify(recFiltered[key])}`, true));\n }\n const jsonPart = parts.join(',\\n');\n const stackPart = indent(stack, true);\n return jsonPart ? `${jsonPart}\\n${stackPart}\\n` : `${stackPart}\\n`;\n }\n\n return `${remainingKeys\n .map((key) => `${indent(`\"${key}\": ${stringify(recFiltered[key])}`, true)}`)\n .join(',\\n')}\\n`;\n}\n\nexport function formatRecord(rec: BunyanRecord, colorize = true): string {\n const level = colorize ? colorizedLevels[rec.level] : levels[rec.level];\n const msg = `${indent(rec.msg)}`;\n const meta = getMeta(rec, colorize);\n const details = getDetails(rec);\n return util.format('%s: %s%s\\n%s', level, msg, meta, details);\n}\n\nexport class PrettyStdoutStream extends Writable {\n constructor() {\n super({ objectMode: true });\n }\n\n override _write(\n data: BunyanRecord,\n _encoding: string,\n callback: (error?: Error | null) => void,\n ): void {\n process.stdout.write(formatRecord(data));\n callback();\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"pretty-stdout.js","names":["util"],"sources":["../../lib/logger/pretty-stdout.ts"],"sourcesContent":["// Code originally derived from https://github.com/hadfieldn/node-bunyan-prettystream but since heavily edited\n// Neither fork nor original repo appear to be maintained\n\nimport { Writable } from 'node:stream';\nimport * as util from 'node:util';\nimport { isNonEmptyObject, isPlainObject, isString } from '@sindresorhus/is';\nimport stringify from 'json-stringify-pretty-compact';\nimport { regEx } from '../util/regex.ts';\nimport type { BunyanRecord } from './types.ts';\n\nconst bunyanFields = [\n 'name',\n 'hostname',\n 'pid',\n 'level',\n 'v',\n 'time',\n 'msg',\n 'start_time',\n];\n/**\n * If a log contains any of these meta fields in the meta, promote them up to the log line, rather than rendering them with other meta fields.\n *\n * This only applies when these fields have a string value, otherwise they are treated as a regular meta field.\n */\nconst metaFields = [\n 'repository',\n 'baseBranch',\n 'packageFile',\n 'depType',\n 'dependency',\n 'branch',\n];\n\nconst levels: Record<number, string> = {\n 10: 'TRACE',\n 20: 'DEBUG',\n 30: ' INFO',\n 40: ' WARN',\n 50: 'ERROR',\n 60: 'FATAL',\n};\n\nconst colorizedLevels: Record<number, string> = {\n 10: util.styleText('gray', 'TRACE'),\n 20: util.styleText('blue', 'DEBUG'),\n 30: util.styleText('green', ' INFO'),\n 40: util.styleText('magenta', ' WARN'),\n 50: util.styleText('red', 'ERROR'),\n 60: util.styleText('bgRed', 'FATAL'),\n};\n\nexport function indent(str: string, leading = false): string {\n const prefix = leading ? ' ' : '';\n return prefix + str.split(regEx(/\\r?\\n/)).join('\\n ');\n}\n\nexport function getMeta(rec: BunyanRecord, colorize = true): string {\n if (!rec) {\n return '';\n }\n let res = rec.module ? ` [${rec.module}]` : ``;\n const filteredMeta = metaFields.filter((elem) => isString(rec[elem]));\n if (!filteredMeta.length) {\n return res;\n }\n const metaStr = filteredMeta\n .map((field) => `${field}=${String(rec[field])}`)\n .join(', ');\n res = ` (${metaStr})${res}`;\n return colorize ? util.styleText('gray', res) : res;\n}\n\nexport function getDetails(rec: BunyanRecord): string {\n if (!rec) {\n return '';\n }\n const recFiltered = { ...rec };\n delete recFiltered.module;\n Object.keys(recFiltered).forEach((key) => {\n if (\n key === 'logContext' ||\n bunyanFields.includes(key) ||\n (metaFields.includes(key) && isString(recFiltered[key]))\n ) {\n delete recFiltered[key];\n }\n });\n const remainingKeys = Object.keys(recFiltered);\n if (remainingKeys.length === 0) {\n return '';\n }\n\n // Handle err.stack specially for readable multi-line output\n const err = recFiltered.err;\n if (isPlainObject(err) && isString(err.stack)) {\n const { stack, ...errRest } = err;\n recFiltered.err = isNonEmptyObject(errRest) ? errRest : undefined;\n const parts: string[] = [];\n for (const key of remainingKeys) {\n if (key === 'err' && recFiltered.err === undefined) {\n continue;\n }\n parts.push(indent(`\"${key}\": ${stringify(recFiltered[key])}`, true));\n }\n const jsonPart = parts.join(',\\n');\n const stackPart = indent(stack, true);\n return jsonPart ? `${jsonPart}\\n${stackPart}\\n` : `${stackPart}\\n`;\n }\n\n return `${remainingKeys\n .map((key) => `${indent(`\"${key}\": ${stringify(recFiltered[key])}`, true)}`)\n .join(',\\n')}\\n`;\n}\n\nexport function formatRecord(rec: BunyanRecord, colorize = true): string {\n const level = colorize ? colorizedLevels[rec.level] : levels[rec.level];\n const msg = `${indent(rec.msg)}`;\n const meta = getMeta(rec, colorize);\n const details = getDetails(rec);\n return util.format('%s: %s%s\\n%s', level, msg, meta, details);\n}\n\nexport class PrettyStdoutStream extends Writable {\n constructor() {\n super({ objectMode: true });\n }\n\n override _write(\n data: BunyanRecord,\n _encoding: string,\n callback: (error?: Error | null) => void,\n ): void {\n process.stdout.write(formatRecord(data));\n callback();\n }\n}\n"],"mappings":"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"}
@@ -45,7 +45,7 @@ async function extractPackageFile(content, packageFile) {
45
45
  const depObject = {
46
46
  ...dep,
47
47
  depTypes,
48
- managerData: { lineNumber: Number(dep.managerData?.lineNumber) + groupLineNumber + 1 }
48
+ managerData: { lineNumber: (dep.managerData?.lineNumber ?? NaN) + groupLineNumber + 1 }
49
49
  };
50
50
  if (repositoryUrl) depObject.registryUrls = [repositoryUrl];
51
51
  return depObject;
@@ -138,7 +138,7 @@ async function extractPackageFile(content, packageFile) {
138
138
  if (sourceRes) res.deps = res.deps.concat(sourceRes.deps.map((dep) => ({
139
139
  ...dep,
140
140
  registryUrls: [repositoryUrl],
141
- managerData: { lineNumber: Number(dep.managerData?.lineNumber) + sourceLineNumber + 1 }
141
+ managerData: { lineNumber: (dep.managerData?.lineNumber ?? NaN) + sourceLineNumber + 1 }
142
142
  })));
143
143
  }
144
144
  }
@@ -163,7 +163,7 @@ async function extractPackageFile(content, packageFile) {
163
163
  const platformsRes = await extractPackageFile(platformsContent);
164
164
  if (platformsRes) res.deps = res.deps.concat(platformsRes.deps.map((dep) => ({
165
165
  ...dep,
166
- managerData: { lineNumber: Number(dep.managerData?.lineNumber) + platformsLineNumber + 1 }
166
+ managerData: { lineNumber: (dep.managerData?.lineNumber ?? NaN) + platformsLineNumber + 1 }
167
167
  })));
168
168
  }
169
169
  if (regEx(/^if\s+(.*?)/).test(line)) {
@@ -187,7 +187,7 @@ async function extractPackageFile(content, packageFile) {
187
187
  const ifRes = await extractPackageFile(ifContent);
188
188
  if (ifRes) res.deps = res.deps.concat(ifRes.deps.map((dep) => ({
189
189
  ...dep,
190
- managerData: { lineNumber: Number(dep.managerData?.lineNumber) + ifLineNumber + 1 }
190
+ managerData: { lineNumber: (dep.managerData?.lineNumber ?? NaN) + ifLineNumber + 1 }
191
191
  })));
192
192
  }
193
193
  }
@@ -1 +1 @@
1
- {"version":3,"file":"extract.js","names":[],"sources":["../../../../lib/modules/manager/bundler/extract.ts"],"sourcesContent":["import { isString } from '@sindresorhus/is';\nimport { logger } from '../../../logger/index.ts';\nimport { readLocalFile } from '../../../util/fs/index.ts';\nimport { newlineRegex, regEx } from '../../../util/regex.ts';\nimport { isHttpUrl } from '../../../util/url.ts';\nimport { GitRefsDatasource } from '../../datasource/git-refs/index.ts';\nimport { RubyVersionDatasource } from '../../datasource/ruby-version/index.ts';\nimport { RubygemsDatasource } from '../../datasource/rubygems/index.ts';\nimport type { PackageDependency, PackageFileContent } from '../types.ts';\nimport { delimiters, extractRubyVersion, getLockFilePath } from './common.ts';\nimport { extractLockFileEntries } from './locked-version.ts';\n\nfunction formatContent(input: string): string {\n return `${input.replace(regEx(/^ {2}/), '')}\\n`; //remove leading whitespace and add a new line at the end\n}\n\nconst variableMatchRegex = regEx(\n `^(?<key>\\\\w+)\\\\s*=\\\\s*['\"](?<value>[^'\"]+)['\"]`,\n);\nconst gemMatchRegex = regEx(\n `^\\\\s*gem\\\\s+(['\"])(?<depName>[^'\"]+)(['\"])(\\\\s*,\\\\s*(?<currentValue>(['\"])[^'\"]+['\"](\\\\s*,\\\\s*['\"][^'\"]+['\"])?))?`,\n);\nconst sourceMatchRegex = regEx(\n `source:\\\\s*((?:['\"](?<registryUrl>[^'\"]+)['\"])|(?<sourceName>\\\\w+))?`,\n);\nconst gitRefsMatchRegex = regEx(\n `((git:\\\\s*['\"](?<gitUrl>[^'\"]+)['\"])|(\\\\s*,\\\\s*github:\\\\s*['\"](?<repoName>[^'\"]+)['\"]))(\\\\s*,\\\\s*branch:\\\\s*['\"](?<branchName>[^'\"]+)['\"])?(\\\\s*,\\\\s*ref:\\\\s*['\"](?<refName>[^'\"]+)['\"])?(\\\\s*,\\\\s*tag:\\\\s*['\"](?<tagName>[^'\"]+)['\"])?`,\n);\nconst pathMatchRegex = regEx(`path:\\\\s*['\"](?<path>[^'\"]+)['\"]`);\n\nexport async function extractPackageFile(\n content: string,\n packageFile?: string,\n): Promise<PackageFileContent | null> {\n let lineNumber: number;\n async function processGroupBlock(\n line: string,\n repositoryUrl?: string,\n trimGroupLine = false,\n ): Promise<void> {\n const groupMatch = regEx(/^group\\s+(.*?)\\s+do/).exec(line);\n if (groupMatch) {\n const depTypes = groupMatch[1]\n .split(',')\n .map((group) => group.trim())\n .map((group) => group.replace(regEx(/^:/), ''));\n\n const groupLineNumber = lineNumber;\n let groupContent = '';\n let groupLine = '';\n\n while (\n lineNumber < lines.length &&\n (trimGroupLine ? groupLine.trim() !== 'end' : groupLine !== 'end')\n ) {\n lineNumber += 1;\n groupLine = lines[lineNumber];\n\n // istanbul ignore if\n if (!isString(groupLine)) {\n logger.debug(\n { content, packageFile, type: 'groupLine' },\n 'Bundler parsing error',\n );\n groupLine = 'end';\n }\n if (trimGroupLine ? groupLine.trim() !== 'end' : groupLine !== 'end') {\n groupContent += formatContent(groupLine);\n }\n }\n\n const groupRes = await extractPackageFile(groupContent);\n if (groupRes) {\n res.deps = res.deps.concat(\n groupRes.deps.map((dep) => {\n const depObject = {\n ...dep,\n depTypes,\n managerData: {\n lineNumber:\n Number(dep.managerData?.lineNumber) + groupLineNumber + 1,\n },\n };\n if (repositoryUrl) {\n depObject.registryUrls = [repositoryUrl];\n }\n return depObject;\n }),\n );\n }\n }\n }\n const res: PackageFileContent = {\n registryUrls: [],\n deps: [],\n };\n\n const variables: Record<string, string> = {};\n\n const lines = content.split(newlineRegex);\n for (lineNumber = 0; lineNumber < lines.length; lineNumber += 1) {\n const line = lines[lineNumber];\n let sourceMatch: RegExpMatchArray | null = null;\n for (const delimiter of delimiters) {\n sourceMatch =\n sourceMatch ??\n regEx(\n `^source ((${delimiter}(?<registryUrl>[^${delimiter}]+)${delimiter})|(?<sourceName>\\\\w+))\\\\s*$`,\n ).exec(line);\n }\n if (sourceMatch) {\n if (sourceMatch.groups?.registryUrl) {\n res.registryUrls?.push(sourceMatch.groups.registryUrl);\n }\n if (sourceMatch.groups?.sourceName) {\n const registryUrl = variables[sourceMatch.groups.sourceName];\n if (registryUrl) {\n res.registryUrls?.push(registryUrl);\n }\n }\n }\n\n const rubyMatch = extractRubyVersion(line);\n if (rubyMatch) {\n res.deps.push({\n depName: 'ruby',\n currentValue: rubyMatch,\n datasource: RubyVersionDatasource.id,\n registryUrls: null,\n });\n }\n\n const variableMatch = variableMatchRegex.exec(line);\n if (variableMatch?.groups?.key) {\n variables[variableMatch.groups?.key] = variableMatch.groups?.value;\n }\n\n const gemMatch = gemMatchRegex.exec(line)?.groups;\n\n if (gemMatch) {\n const dep: PackageDependency = {\n depName: gemMatch.depName,\n managerData: { lineNumber },\n datasource: RubygemsDatasource.id,\n };\n\n if (gemMatch.currentValue) {\n const currentValue = gemMatch.currentValue;\n dep.currentValue = currentValue;\n }\n\n const pathMatch = pathMatchRegex.exec(line)?.groups;\n if (pathMatch) {\n dep.skipReason = 'internal-package';\n }\n\n const sourceMatch = sourceMatchRegex.exec(line)?.groups;\n if (sourceMatch) {\n if (sourceMatch.registryUrl) {\n dep.registryUrls = [sourceMatch.registryUrl];\n } else if (sourceMatch.sourceName) {\n dep.registryUrls = [variables[sourceMatch.sourceName]];\n }\n }\n\n const gitRefsMatch = gitRefsMatchRegex.exec(line)?.groups;\n if (gitRefsMatch) {\n if (gitRefsMatch.gitUrl) {\n const gitUrl = gitRefsMatch.gitUrl;\n dep.packageName = gitUrl;\n\n if (isHttpUrl(gitUrl)) {\n dep.sourceUrl = gitUrl.replace(regEx(/\\.git$/), '');\n }\n } else {\n // we always have repoName, as `gitRefsMatchRegex`'s first group requires either `gitUrl` or `repoName`\n dep.packageName = `https://github.com/${gitRefsMatch.repoName}`;\n dep.sourceUrl = dep.packageName;\n }\n if (gitRefsMatch.refName) {\n dep.currentDigest = gitRefsMatch.refName;\n } else if (gitRefsMatch.branchName) {\n dep.currentValue = gitRefsMatch.branchName;\n } else if (gitRefsMatch.tagName) {\n dep.currentValue = gitRefsMatch.tagName;\n }\n dep.datasource = GitRefsDatasource.id;\n }\n res.deps.push(dep);\n }\n\n await processGroupBlock(line);\n\n for (const delimiter of delimiters) {\n const sourceBlockMatch = regEx(\n `^source\\\\s+((${delimiter}(?<registryUrl>[^${delimiter}]+)${delimiter})|(?<sourceName>\\\\w+))\\\\s+do`,\n ).exec(line);\n if (sourceBlockMatch) {\n let repositoryUrl = '';\n if (sourceBlockMatch.groups?.registryUrl) {\n repositoryUrl = sourceBlockMatch.groups.registryUrl;\n }\n if (\n sourceBlockMatch.groups?.sourceName &&\n variables[sourceBlockMatch.groups.sourceName]\n ) {\n repositoryUrl = variables[sourceBlockMatch.groups.sourceName];\n }\n const sourceLineNumber = lineNumber;\n let sourceContent = '';\n let sourceLine = '';\n\n while (lineNumber < lines.length && sourceLine.trim() !== 'end') {\n lineNumber += 1;\n sourceLine = lines[lineNumber];\n // istanbul ignore if\n if (!isString(sourceLine)) {\n logger.debug(\n { content, packageFile, type: 'sourceLine' },\n 'Bundler parsing error',\n );\n sourceLine = 'end';\n }\n\n await processGroupBlock(sourceLine.trim(), repositoryUrl, true);\n\n if (sourceLine.trim() !== 'end') {\n sourceContent += formatContent(sourceLine);\n }\n }\n\n const sourceRes = await extractPackageFile(sourceContent);\n\n if (sourceRes) {\n res.deps = res.deps.concat(\n sourceRes.deps.map((dep) => ({\n ...dep,\n registryUrls: [repositoryUrl],\n managerData: {\n lineNumber:\n Number(dep.managerData?.lineNumber) + sourceLineNumber + 1,\n },\n })),\n );\n }\n }\n }\n const platformsMatch = regEx(/^platforms\\s+(.*?)\\s+do/).test(line);\n if (platformsMatch) {\n const platformsLineNumber = lineNumber;\n let platformsContent = '';\n let platformsLine = '';\n while (lineNumber < lines.length && platformsLine !== 'end') {\n lineNumber += 1;\n platformsLine = lines[lineNumber];\n // istanbul ignore if\n if (!isString(platformsLine)) {\n logger.debug(\n { content, packageFile, type: 'platformsLine' },\n 'Bundler parsing error',\n );\n platformsLine = 'end';\n }\n if (platformsLine !== 'end') {\n platformsContent += formatContent(platformsLine);\n }\n }\n const platformsRes = await extractPackageFile(platformsContent);\n if (platformsRes) {\n res.deps = res.deps.concat(\n platformsRes.deps.map((dep) => ({\n ...dep,\n managerData: {\n lineNumber:\n Number(dep.managerData?.lineNumber) + platformsLineNumber + 1,\n },\n })),\n );\n }\n }\n const ifMatch = regEx(/^if\\s+(.*?)/).test(line);\n if (ifMatch) {\n const ifLineNumber = lineNumber;\n let ifContent = '';\n let ifLine = '';\n while (lineNumber < lines.length && ifLine !== 'end') {\n lineNumber += 1;\n ifLine = lines[lineNumber];\n // istanbul ignore if\n if (!isString(ifLine)) {\n logger.debug(\n { content, packageFile, type: 'ifLine' },\n 'Bundler parsing error',\n );\n ifLine = 'end';\n }\n if (ifLine !== 'end') {\n ifContent += formatContent(ifLine);\n }\n }\n const ifRes = await extractPackageFile(ifContent);\n if (ifRes) {\n res.deps = res.deps.concat(\n ifRes.deps.map((dep) => ({\n ...dep,\n managerData: {\n lineNumber:\n Number(dep.managerData?.lineNumber) + ifLineNumber + 1,\n },\n })),\n );\n }\n }\n }\n if (!res.deps.length && !res.registryUrls?.length) {\n return null;\n }\n\n if (packageFile) {\n const gemfileLockPath = await getLockFilePath(packageFile);\n const lockContent = await readLocalFile(gemfileLockPath, 'utf8');\n if (lockContent) {\n logger.debug(\n `Found lock file ${gemfileLockPath} for packageFile: ${packageFile}`,\n );\n res.lockFiles = [gemfileLockPath];\n const lockedEntries = extractLockFileEntries(lockContent);\n for (const dep of res.deps) {\n // TODO: types (#22198)\n const lockedDepValue = lockedEntries.get(`${dep.depName!}`);\n if (lockedDepValue) {\n dep.lockedVersion = lockedDepValue;\n }\n }\n }\n }\n return res;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"extract.js","names":[],"sources":["../../../../lib/modules/manager/bundler/extract.ts"],"sourcesContent":["import { isString } from '@sindresorhus/is';\nimport { logger } from '../../../logger/index.ts';\nimport { readLocalFile } from '../../../util/fs/index.ts';\nimport { newlineRegex, regEx } from '../../../util/regex.ts';\nimport { isHttpUrl } from '../../../util/url.ts';\nimport { GitRefsDatasource } from '../../datasource/git-refs/index.ts';\nimport { RubyVersionDatasource } from '../../datasource/ruby-version/index.ts';\nimport { RubygemsDatasource } from '../../datasource/rubygems/index.ts';\nimport type { PackageDependency, PackageFileContent } from '../types.ts';\nimport { delimiters, extractRubyVersion, getLockFilePath } from './common.ts';\nimport { extractLockFileEntries } from './locked-version.ts';\n\nfunction formatContent(input: string): string {\n return `${input.replace(regEx(/^ {2}/), '')}\\n`; //remove leading whitespace and add a new line at the end\n}\n\nconst variableMatchRegex = regEx(\n `^(?<key>\\\\w+)\\\\s*=\\\\s*['\"](?<value>[^'\"]+)['\"]`,\n);\nconst gemMatchRegex = regEx(\n `^\\\\s*gem\\\\s+(['\"])(?<depName>[^'\"]+)(['\"])(\\\\s*,\\\\s*(?<currentValue>(['\"])[^'\"]+['\"](\\\\s*,\\\\s*['\"][^'\"]+['\"])?))?`,\n);\nconst sourceMatchRegex = regEx(\n `source:\\\\s*((?:['\"](?<registryUrl>[^'\"]+)['\"])|(?<sourceName>\\\\w+))?`,\n);\nconst gitRefsMatchRegex = regEx(\n `((git:\\\\s*['\"](?<gitUrl>[^'\"]+)['\"])|(\\\\s*,\\\\s*github:\\\\s*['\"](?<repoName>[^'\"]+)['\"]))(\\\\s*,\\\\s*branch:\\\\s*['\"](?<branchName>[^'\"]+)['\"])?(\\\\s*,\\\\s*ref:\\\\s*['\"](?<refName>[^'\"]+)['\"])?(\\\\s*,\\\\s*tag:\\\\s*['\"](?<tagName>[^'\"]+)['\"])?`,\n);\nconst pathMatchRegex = regEx(`path:\\\\s*['\"](?<path>[^'\"]+)['\"]`);\n\nexport async function extractPackageFile(\n content: string,\n packageFile?: string,\n): Promise<PackageFileContent | null> {\n let lineNumber: number;\n async function processGroupBlock(\n line: string,\n repositoryUrl?: string,\n trimGroupLine = false,\n ): Promise<void> {\n const groupMatch = regEx(/^group\\s+(.*?)\\s+do/).exec(line);\n if (groupMatch) {\n const depTypes = groupMatch[1]\n .split(',')\n .map((group) => group.trim())\n .map((group) => group.replace(regEx(/^:/), ''));\n\n const groupLineNumber = lineNumber;\n let groupContent = '';\n let groupLine = '';\n\n while (\n lineNumber < lines.length &&\n (trimGroupLine ? groupLine.trim() !== 'end' : groupLine !== 'end')\n ) {\n lineNumber += 1;\n groupLine = lines[lineNumber];\n\n // istanbul ignore if\n if (!isString(groupLine)) {\n logger.debug(\n { content, packageFile, type: 'groupLine' },\n 'Bundler parsing error',\n );\n groupLine = 'end';\n }\n if (trimGroupLine ? groupLine.trim() !== 'end' : groupLine !== 'end') {\n groupContent += formatContent(groupLine);\n }\n }\n\n const groupRes = await extractPackageFile(groupContent);\n if (groupRes) {\n res.deps = res.deps.concat(\n groupRes.deps.map((dep) => {\n const depObject = {\n ...dep,\n depTypes,\n managerData: {\n lineNumber:\n (dep.managerData?.lineNumber ?? NaN) + groupLineNumber + 1,\n },\n };\n if (repositoryUrl) {\n depObject.registryUrls = [repositoryUrl];\n }\n return depObject;\n }),\n );\n }\n }\n }\n const res: PackageFileContent = {\n registryUrls: [],\n deps: [],\n };\n\n const variables: Record<string, string> = {};\n\n const lines = content.split(newlineRegex);\n for (lineNumber = 0; lineNumber < lines.length; lineNumber += 1) {\n const line = lines[lineNumber];\n let sourceMatch: RegExpMatchArray | null = null;\n for (const delimiter of delimiters) {\n sourceMatch =\n sourceMatch ??\n regEx(\n `^source ((${delimiter}(?<registryUrl>[^${delimiter}]+)${delimiter})|(?<sourceName>\\\\w+))\\\\s*$`,\n ).exec(line);\n }\n if (sourceMatch) {\n if (sourceMatch.groups?.registryUrl) {\n res.registryUrls?.push(sourceMatch.groups.registryUrl);\n }\n if (sourceMatch.groups?.sourceName) {\n const registryUrl = variables[sourceMatch.groups.sourceName];\n if (registryUrl) {\n res.registryUrls?.push(registryUrl);\n }\n }\n }\n\n const rubyMatch = extractRubyVersion(line);\n if (rubyMatch) {\n res.deps.push({\n depName: 'ruby',\n currentValue: rubyMatch,\n datasource: RubyVersionDatasource.id,\n registryUrls: null,\n });\n }\n\n const variableMatch = variableMatchRegex.exec(line);\n if (variableMatch?.groups?.key) {\n variables[variableMatch.groups?.key] = variableMatch.groups?.value;\n }\n\n const gemMatch = gemMatchRegex.exec(line)?.groups;\n\n if (gemMatch) {\n const dep: PackageDependency = {\n depName: gemMatch.depName,\n managerData: { lineNumber },\n datasource: RubygemsDatasource.id,\n };\n\n if (gemMatch.currentValue) {\n const currentValue = gemMatch.currentValue;\n dep.currentValue = currentValue;\n }\n\n const pathMatch = pathMatchRegex.exec(line)?.groups;\n if (pathMatch) {\n dep.skipReason = 'internal-package';\n }\n\n const sourceMatch = sourceMatchRegex.exec(line)?.groups;\n if (sourceMatch) {\n if (sourceMatch.registryUrl) {\n dep.registryUrls = [sourceMatch.registryUrl];\n } else if (sourceMatch.sourceName) {\n dep.registryUrls = [variables[sourceMatch.sourceName]];\n }\n }\n\n const gitRefsMatch = gitRefsMatchRegex.exec(line)?.groups;\n if (gitRefsMatch) {\n if (gitRefsMatch.gitUrl) {\n const gitUrl = gitRefsMatch.gitUrl;\n dep.packageName = gitUrl;\n\n if (isHttpUrl(gitUrl)) {\n dep.sourceUrl = gitUrl.replace(regEx(/\\.git$/), '');\n }\n } else {\n // we always have repoName, as `gitRefsMatchRegex`'s first group requires either `gitUrl` or `repoName`\n dep.packageName = `https://github.com/${gitRefsMatch.repoName}`;\n dep.sourceUrl = dep.packageName;\n }\n if (gitRefsMatch.refName) {\n dep.currentDigest = gitRefsMatch.refName;\n } else if (gitRefsMatch.branchName) {\n dep.currentValue = gitRefsMatch.branchName;\n } else if (gitRefsMatch.tagName) {\n dep.currentValue = gitRefsMatch.tagName;\n }\n dep.datasource = GitRefsDatasource.id;\n }\n res.deps.push(dep);\n }\n\n await processGroupBlock(line);\n\n for (const delimiter of delimiters) {\n const sourceBlockMatch = regEx(\n `^source\\\\s+((${delimiter}(?<registryUrl>[^${delimiter}]+)${delimiter})|(?<sourceName>\\\\w+))\\\\s+do`,\n ).exec(line);\n if (sourceBlockMatch) {\n let repositoryUrl = '';\n if (sourceBlockMatch.groups?.registryUrl) {\n repositoryUrl = sourceBlockMatch.groups.registryUrl;\n }\n if (\n sourceBlockMatch.groups?.sourceName &&\n variables[sourceBlockMatch.groups.sourceName]\n ) {\n repositoryUrl = variables[sourceBlockMatch.groups.sourceName];\n }\n const sourceLineNumber = lineNumber;\n let sourceContent = '';\n let sourceLine = '';\n\n while (lineNumber < lines.length && sourceLine.trim() !== 'end') {\n lineNumber += 1;\n sourceLine = lines[lineNumber];\n // istanbul ignore if\n if (!isString(sourceLine)) {\n logger.debug(\n { content, packageFile, type: 'sourceLine' },\n 'Bundler parsing error',\n );\n sourceLine = 'end';\n }\n\n await processGroupBlock(sourceLine.trim(), repositoryUrl, true);\n\n if (sourceLine.trim() !== 'end') {\n sourceContent += formatContent(sourceLine);\n }\n }\n\n const sourceRes = await extractPackageFile(sourceContent);\n\n if (sourceRes) {\n res.deps = res.deps.concat(\n sourceRes.deps.map((dep) => ({\n ...dep,\n registryUrls: [repositoryUrl],\n managerData: {\n lineNumber:\n (dep.managerData?.lineNumber ?? NaN) + sourceLineNumber + 1,\n },\n })),\n );\n }\n }\n }\n const platformsMatch = regEx(/^platforms\\s+(.*?)\\s+do/).test(line);\n if (platformsMatch) {\n const platformsLineNumber = lineNumber;\n let platformsContent = '';\n let platformsLine = '';\n while (lineNumber < lines.length && platformsLine !== 'end') {\n lineNumber += 1;\n platformsLine = lines[lineNumber];\n // istanbul ignore if\n if (!isString(platformsLine)) {\n logger.debug(\n { content, packageFile, type: 'platformsLine' },\n 'Bundler parsing error',\n );\n platformsLine = 'end';\n }\n if (platformsLine !== 'end') {\n platformsContent += formatContent(platformsLine);\n }\n }\n const platformsRes = await extractPackageFile(platformsContent);\n if (platformsRes) {\n res.deps = res.deps.concat(\n platformsRes.deps.map((dep) => ({\n ...dep,\n managerData: {\n lineNumber:\n (dep.managerData?.lineNumber ?? NaN) + platformsLineNumber + 1,\n },\n })),\n );\n }\n }\n const ifMatch = regEx(/^if\\s+(.*?)/).test(line);\n if (ifMatch) {\n const ifLineNumber = lineNumber;\n let ifContent = '';\n let ifLine = '';\n while (lineNumber < lines.length && ifLine !== 'end') {\n lineNumber += 1;\n ifLine = lines[lineNumber];\n // istanbul ignore if\n if (!isString(ifLine)) {\n logger.debug(\n { content, packageFile, type: 'ifLine' },\n 'Bundler parsing error',\n );\n ifLine = 'end';\n }\n if (ifLine !== 'end') {\n ifContent += formatContent(ifLine);\n }\n }\n const ifRes = await extractPackageFile(ifContent);\n if (ifRes) {\n res.deps = res.deps.concat(\n ifRes.deps.map((dep) => ({\n ...dep,\n managerData: {\n lineNumber:\n (dep.managerData?.lineNumber ?? NaN) + ifLineNumber + 1,\n },\n })),\n );\n }\n }\n }\n if (!res.deps.length && !res.registryUrls?.length) {\n return null;\n }\n\n if (packageFile) {\n const gemfileLockPath = await getLockFilePath(packageFile);\n const lockContent = await readLocalFile(gemfileLockPath, 'utf8');\n if (lockContent) {\n logger.debug(\n `Found lock file ${gemfileLockPath} for packageFile: ${packageFile}`,\n );\n res.lockFiles = [gemfileLockPath];\n const lockedEntries = extractLockFileEntries(lockContent);\n for (const dep of res.deps) {\n // TODO: types (#22198)\n const lockedDepValue = lockedEntries.get(`${dep.depName!}`);\n if (lockedDepValue) {\n dep.lockedVersion = lockedDepValue;\n }\n }\n }\n }\n return res;\n}\n"],"mappings":";;;;;;;;;;;AAYA,SAAS,cAAc,OAAuB;CAC5C,OAAO,GAAG,MAAM,QAAQ,MAAM,OAAO,GAAG,EAAE,EAAE;AAC9C;AAEA,MAAM,qBAAqB,MACzB,gDACF;AACA,MAAM,gBAAgB,MACpB,mHACF;AACA,MAAM,mBAAmB,MACvB,sEACF;AACA,MAAM,oBAAoB,MACxB,yOACF;AACA,MAAM,iBAAiB,MAAM,kCAAkC;AAE/D,eAAsB,mBACpB,SACA,aACoC;CACpC,IAAI;CACJ,eAAe,kBACb,MACA,eACA,gBAAgB,OACD;EACf,MAAM,aAAa,MAAM,qBAAqB,CAAC,CAAC,KAAK,IAAI;EACzD,IAAI,YAAY;GACd,MAAM,WAAW,WAAW,EAAE,CAC3B,MAAM,GAAG,CAAC,CACV,KAAK,UAAU,MAAM,KAAK,CAAC,CAAC,CAC5B,KAAK,UAAU,MAAM,QAAQ,MAAM,IAAI,GAAG,EAAE,CAAC;GAEhD,MAAM,kBAAkB;GACxB,IAAI,eAAe;GACnB,IAAI,YAAY;GAEhB,OACE,aAAa,MAAM,WAClB,gBAAgB,UAAU,KAAK,MAAM,QAAQ,cAAc,QAC5D;IACA,cAAc;IACd,YAAY,MAAM;;IAGlB,IAAI,CAAC,SAAS,SAAS,GAAG;KACxB,OAAO,MACL;MAAE;MAAS;MAAa,MAAM;KAAY,GAC1C,uBACF;KACA,YAAY;IACd;IACA,IAAI,gBAAgB,UAAU,KAAK,MAAM,QAAQ,cAAc,OAC7D,gBAAgB,cAAc,SAAS;GAE3C;GAEA,MAAM,WAAW,MAAM,mBAAmB,YAAY;GACtD,IAAI,UACF,IAAI,OAAO,IAAI,KAAK,OAClB,SAAS,KAAK,KAAK,QAAQ;IACzB,MAAM,YAAY;KAChB,GAAG;KACH;KACA,aAAa,EACX,aACG,IAAI,aAAa,cAAc,OAAO,kBAAkB,EAC7D;IACF;IACA,IAAI,eACF,UAAU,eAAe,CAAC,aAAa;IAEzC,OAAO;GACT,CAAC,CACH;EAEJ;CACF;CACA,MAAM,MAA0B;EAC9B,cAAc,CAAC;EACf,MAAM,CAAC;CACT;CAEA,MAAM,YAAoC,CAAC;CAE3C,MAAM,QAAQ,QAAQ,MAAM,YAAY;CACxC,KAAK,aAAa,GAAG,aAAa,MAAM,QAAQ,cAAc,GAAG;EAC/D,MAAM,OAAO,MAAM;EACnB,IAAI,cAAuC;EAC3C,KAAK,MAAM,aAAa,YACtB,cACE,eACA,MACE,aAAa,UAAU,mBAAmB,UAAU,KAAK,UAAU,4BACrE,CAAC,CAAC,KAAK,IAAI;EAEf,IAAI,aAAa;GACf,IAAI,YAAY,QAAQ,aACtB,IAAI,cAAc,KAAK,YAAY,OAAO,WAAW;GAEvD,IAAI,YAAY,QAAQ,YAAY;IAClC,MAAM,cAAc,UAAU,YAAY,OAAO;IACjD,IAAI,aACF,IAAI,cAAc,KAAK,WAAW;GAEtC;EACF;EAEA,MAAM,YAAY,mBAAmB,IAAI;EACzC,IAAI,WACF,IAAI,KAAK,KAAK;GACZ,SAAS;GACT,cAAc;GACd,YAAY,sBAAsB;GAClC,cAAc;EAChB,CAAC;EAGH,MAAM,gBAAgB,mBAAmB,KAAK,IAAI;EAClD,IAAI,eAAe,QAAQ,KACzB,UAAU,cAAc,QAAQ,OAAO,cAAc,QAAQ;EAG/D,MAAM,WAAW,cAAc,KAAK,IAAI,CAAC,EAAE;EAE3C,IAAI,UAAU;GACZ,MAAM,MAAyB;IAC7B,SAAS,SAAS;IAClB,aAAa,EAAE,WAAW;IAC1B,YAAY,mBAAmB;GACjC;GAEA,IAAI,SAAS,cAEX,IAAI,eADiB,SAAS;GAKhC,IADkB,eAAe,KAAK,IAAI,CAAC,EAAE,QAE3C,IAAI,aAAa;GAGnB,MAAM,cAAc,iBAAiB,KAAK,IAAI,CAAC,EAAE;GACjD,IAAI,aAAa;IACf,IAAI,YAAY,aACd,IAAI,eAAe,CAAC,YAAY,WAAW;SACtC,IAAI,YAAY,YACrB,IAAI,eAAe,CAAC,UAAU,YAAY,WAAW;GAEzD;GAEA,MAAM,eAAe,kBAAkB,KAAK,IAAI,CAAC,EAAE;GACnD,IAAI,cAAc;IAChB,IAAI,aAAa,QAAQ;KACvB,MAAM,SAAS,aAAa;KAC5B,IAAI,cAAc;KAElB,IAAI,UAAU,MAAM,GAClB,IAAI,YAAY,OAAO,QAAQ,MAAM,QAAQ,GAAG,EAAE;IAEtD,OAAO;KAEL,IAAI,cAAc,sBAAsB,aAAa;KACrD,IAAI,YAAY,IAAI;IACtB;IACA,IAAI,aAAa,SACf,IAAI,gBAAgB,aAAa;SAC5B,IAAI,aAAa,YACtB,IAAI,eAAe,aAAa;SAC3B,IAAI,aAAa,SACtB,IAAI,eAAe,aAAa;IAElC,IAAI,aAAa,kBAAkB;GACrC;GACA,IAAI,KAAK,KAAK,GAAG;EACnB;EAEA,MAAM,kBAAkB,IAAI;EAE5B,KAAK,MAAM,aAAa,YAAY;GAClC,MAAM,mBAAmB,MACvB,gBAAgB,UAAU,mBAAmB,UAAU,KAAK,UAAU,6BACxE,CAAC,CAAC,KAAK,IAAI;GACX,IAAI,kBAAkB;IACpB,IAAI,gBAAgB;IACpB,IAAI,iBAAiB,QAAQ,aAC3B,gBAAgB,iBAAiB,OAAO;IAE1C,IACE,iBAAiB,QAAQ,cACzB,UAAU,iBAAiB,OAAO,aAElC,gBAAgB,UAAU,iBAAiB,OAAO;IAEpD,MAAM,mBAAmB;IACzB,IAAI,gBAAgB;IACpB,IAAI,aAAa;IAEjB,OAAO,aAAa,MAAM,UAAU,WAAW,KAAK,MAAM,OAAO;KAC/D,cAAc;KACd,aAAa,MAAM;;KAEnB,IAAI,CAAC,SAAS,UAAU,GAAG;MACzB,OAAO,MACL;OAAE;OAAS;OAAa,MAAM;MAAa,GAC3C,uBACF;MACA,aAAa;KACf;KAEA,MAAM,kBAAkB,WAAW,KAAK,GAAG,eAAe,IAAI;KAE9D,IAAI,WAAW,KAAK,MAAM,OACxB,iBAAiB,cAAc,UAAU;IAE7C;IAEA,MAAM,YAAY,MAAM,mBAAmB,aAAa;IAExD,IAAI,WACF,IAAI,OAAO,IAAI,KAAK,OAClB,UAAU,KAAK,KAAK,SAAS;KAC3B,GAAG;KACH,cAAc,CAAC,aAAa;KAC5B,aAAa,EACX,aACG,IAAI,aAAa,cAAc,OAAO,mBAAmB,EAC9D;IACF,EAAE,CACJ;GAEJ;EACF;EAEA,IADuB,MAAM,yBAAyB,CAAC,CAAC,KAAK,IAC5C,GAAG;GAClB,MAAM,sBAAsB;GAC5B,IAAI,mBAAmB;GACvB,IAAI,gBAAgB;GACpB,OAAO,aAAa,MAAM,UAAU,kBAAkB,OAAO;IAC3D,cAAc;IACd,gBAAgB,MAAM;;IAEtB,IAAI,CAAC,SAAS,aAAa,GAAG;KAC5B,OAAO,MACL;MAAE;MAAS;MAAa,MAAM;KAAgB,GAC9C,uBACF;KACA,gBAAgB;IAClB;IACA,IAAI,kBAAkB,OACpB,oBAAoB,cAAc,aAAa;GAEnD;GACA,MAAM,eAAe,MAAM,mBAAmB,gBAAgB;GAC9D,IAAI,cACF,IAAI,OAAO,IAAI,KAAK,OAClB,aAAa,KAAK,KAAK,SAAS;IAC9B,GAAG;IACH,aAAa,EACX,aACG,IAAI,aAAa,cAAc,OAAO,sBAAsB,EACjE;GACF,EAAE,CACJ;EAEJ;EAEA,IADgB,MAAM,aAAa,CAAC,CAAC,KAAK,IAChC,GAAG;GACX,MAAM,eAAe;GACrB,IAAI,YAAY;GAChB,IAAI,SAAS;GACb,OAAO,aAAa,MAAM,UAAU,WAAW,OAAO;IACpD,cAAc;IACd,SAAS,MAAM;;IAEf,IAAI,CAAC,SAAS,MAAM,GAAG;KACrB,OAAO,MACL;MAAE;MAAS;MAAa,MAAM;KAAS,GACvC,uBACF;KACA,SAAS;IACX;IACA,IAAI,WAAW,OACb,aAAa,cAAc,MAAM;GAErC;GACA,MAAM,QAAQ,MAAM,mBAAmB,SAAS;GAChD,IAAI,OACF,IAAI,OAAO,IAAI,KAAK,OAClB,MAAM,KAAK,KAAK,SAAS;IACvB,GAAG;IACH,aAAa,EACX,aACG,IAAI,aAAa,cAAc,OAAO,eAAe,EAC1D;GACF,EAAE,CACJ;EAEJ;CACF;CACA,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC,IAAI,cAAc,QACzC,OAAO;CAGT,IAAI,aAAa;EACf,MAAM,kBAAkB,MAAM,gBAAgB,WAAW;EACzD,MAAM,cAAc,MAAM,cAAc,iBAAiB,MAAM;EAC/D,IAAI,aAAa;GACf,OAAO,MACL,mBAAmB,gBAAgB,oBAAoB,aACzD;GACA,IAAI,YAAY,CAAC,eAAe;GAChC,MAAM,gBAAgB,uBAAuB,WAAW;GACxD,KAAK,MAAM,OAAO,IAAI,MAAM;IAE1B,MAAM,iBAAiB,cAAc,IAAI,GAAG,IAAI,SAAU;IAC1D,IAAI,gBACF,IAAI,gBAAgB;GAExB;EACF;CACF;CACA,OAAO;AACT"}
@@ -3,7 +3,7 @@ import { logger } from "../../../logger/index.js";
3
3
  import { api, id } from "../../versioning/debian/index.js";
4
4
  import { id as id$1 } from "../../versioning/ubuntu/index.js";
5
5
  import { DockerDatasource } from "../../datasource/docker/index.js";
6
- import { isNonEmptyStringAndNotWhitespace, isString } from "@sindresorhus/is";
6
+ import { isNonEmptyStringAndNotWhitespace, isNumericString, isString } from "@sindresorhus/is";
7
7
  //#region lib/modules/manager/dockerfile/extract.ts
8
8
  const variableMarker = "$";
9
9
  function extractVariables(image) {
@@ -203,7 +203,8 @@ function extractPackageFile(content, _packageFile, config) {
203
203
  const copyFromMatch = instruction.match(copyFromRegex);
204
204
  if (copyFromMatch?.groups?.image) {
205
205
  if (stageNames.includes(copyFromMatch.groups.image)) logger.debug({ image: copyFromMatch.groups.image }, "Skipping alias COPY --from");
206
- else if (Number.isNaN(Number(copyFromMatch.groups.image))) {
206
+ else if (isNumericString(copyFromMatch.groups.image)) logger.debug({ image: copyFromMatch.groups.image }, "Skipping index reference COPY --from");
207
+ else {
207
208
  const dep = getDep(copyFromMatch.groups.image, true, config.registryAliases);
208
209
  processDepForAutoReplace(dep, [[lineNumberInstrStart, lineNumber]], lines, lineFeed);
209
210
  logger.debug({
@@ -212,7 +213,7 @@ function extractPackageFile(content, _packageFile, config) {
212
213
  currentDigest: dep.currentDigest
213
214
  }, "Dockerfile COPY --from");
214
215
  deps.push(dep);
215
- } else logger.debug({ image: copyFromMatch.groups.image }, "Skipping index reference COPY --from");
216
+ }
216
217
  }
217
218
  const runMountFromRegex = regEx(`^[ \\t]*RUN(?:${escapeChar}[ \\t]*\\r?\\n| |\\t|#.*?\\r?\\n|--[a-z]+(?:=[a-zA-Z0-9_.:-]+?)?)+--mount=(?:\\S*=\\S*,)*from=(?<image>[^, ]+)`, "im");
218
219
  const runMountFromMatch = instruction.match(runMountFromRegex);
@@ -1 +1 @@
1
- {"version":3,"file":"extract.js","names":["ubuntuVersioning.id","debianVersioning.id"],"sources":["../../../../lib/modules/manager/dockerfile/extract.ts"],"sourcesContent":["import { isNonEmptyStringAndNotWhitespace, isString } from '@sindresorhus/is';\nimport { logger } from '../../../logger/index.ts';\nimport { newlineRegex, regEx } from '../../../util/regex.ts';\nimport { DockerDatasource } from '../../datasource/docker/index.ts';\nimport * as debianVersioning from '../../versioning/debian/index.ts';\nimport * as ubuntuVersioning from '../../versioning/ubuntu/index.ts';\nimport type {\n ExtractConfig,\n PackageDependency,\n PackageFileContent,\n} from '../types.ts';\n\nconst variableMarker = '$';\n\nexport function extractVariables(image: string): Record<string, string> {\n const variables: Record<string, string> = {};\n const variableRegex = regEx(\n /(?<fullvariable>\\\\?\\$(?<simplearg>\\w+)|\\\\?\\${(?<complexarg>\\w+)(?::.+?)?}+)/gi,\n );\n\n let match: RegExpExecArray | null;\n do {\n match = variableRegex.exec(image);\n if (match?.groups?.fullvariable) {\n variables[match.groups.fullvariable] =\n match.groups?.simplearg || match.groups?.complexarg;\n }\n } while (match);\n\n return variables;\n}\n\nfunction getAutoReplaceTemplate(dep: PackageDependency): string | undefined {\n let template = dep.replaceString;\n\n if (dep.currentValue) {\n let placeholder = '{{#if newValue}}{{newValue}}{{/if}}';\n if (!dep.currentDigest) {\n placeholder += '{{#if newDigest}}@{{newDigest}}{{/if}}';\n }\n template = template?.replace(dep.currentValue, placeholder);\n }\n\n if (dep.currentDigest) {\n template = template?.replace(\n dep.currentDigest,\n '{{#if newDigest}}{{newDigest}}{{/if}}',\n );\n }\n\n return template;\n}\n\nfunction processDepForAutoReplace(\n dep: PackageDependency,\n lineNumberRanges: number[][],\n lines: string[],\n linefeed: string,\n): void {\n const lineNumberRangesToReplace: number[][] = [];\n for (const lineNumberRange of lineNumberRanges) {\n for (const lineNumber of lineNumberRange) {\n if (\n (isString(dep.currentValue) &&\n lines[lineNumber].includes(dep.currentValue)) ||\n (isString(dep.currentDigest) &&\n lines[lineNumber].includes(dep.currentDigest))\n ) {\n lineNumberRangesToReplace.push(lineNumberRange);\n }\n }\n }\n\n lineNumberRangesToReplace.sort((a, b) => {\n return a[0] - b[0];\n });\n\n const minLine = lineNumberRangesToReplace[0]?.[0];\n const maxLine = lineNumberRangesToReplace.at(-1)?.[1];\n if (\n lineNumberRanges.length === 1 ||\n minLine === undefined ||\n maxLine === undefined\n ) {\n return;\n }\n\n const unfoldedLineNumbers = Array.from(\n { length: maxLine - minLine + 1 },\n (_v, k) => k + minLine,\n );\n\n dep.replaceString = unfoldedLineNumbers\n .map((lineNumber) => lines[lineNumber])\n .join(linefeed);\n\n if (!dep.currentDigest) {\n dep.replaceString += linefeed;\n }\n\n dep.autoReplaceStringTemplate = getAutoReplaceTemplate(dep);\n}\n\nexport function splitImageParts(currentFrom: string): PackageDependency {\n let isVariable = false;\n let cleanedCurrentFrom = currentFrom;\n\n // Check if we have a variable in format of \"${VARIABLE:-<image>:<defaultVal>@<digest>}\"\n // If so, remove everything except the image, defaultVal and digest.\n if (cleanedCurrentFrom?.includes(variableMarker)) {\n const defaultValueRegex = regEx(/^\\${.+?:-\"?(?<value>.*?)\"?}$/);\n const defaultValueMatch =\n defaultValueRegex.exec(cleanedCurrentFrom)?.groups;\n if (defaultValueMatch?.value) {\n isVariable = true;\n cleanedCurrentFrom = defaultValueMatch.value;\n }\n\n if (cleanedCurrentFrom?.includes(variableMarker)) {\n // If cleanedCurrentFrom contains a variable, after cleaning, e.g. \"$REGISTRY/alpine\", we do not support this.\n return {\n skipReason: 'contains-variable',\n };\n }\n }\n\n const [currentDepTag, currentDigest] = cleanedCurrentFrom.split('@');\n const depTagSplit = currentDepTag.split(':');\n let depName: string;\n let currentValue: string | undefined;\n if (depTagSplit.length === 1 || depTagSplit.at(-1)!.includes('/')) {\n depName = currentDepTag;\n } else {\n currentValue = depTagSplit.pop();\n depName = depTagSplit.join(':');\n }\n\n const dep: PackageDependency = {\n depName,\n packageName: depName,\n currentValue,\n currentDigest,\n };\n\n if (isVariable) {\n dep.replaceString = cleanedCurrentFrom;\n\n if (!dep.currentValue) {\n delete dep.currentValue;\n }\n\n if (!dep.currentDigest) {\n delete dep.currentDigest;\n }\n }\n\n return dep;\n}\n\nconst quayRegex = regEx(/^quay\\.io(?::[1-9][0-9]{0,4})?/i);\n\nexport function getDep(\n currentFrom: string | null | undefined,\n specifyReplaceString = true,\n registryAliases?: Record<string, string>,\n): PackageDependency {\n if (\n !isString(currentFrom) ||\n !isNonEmptyStringAndNotWhitespace(currentFrom)\n ) {\n return {\n skipReason: 'invalid-value',\n };\n }\n\n // Resolve registry aliases first so that we don't need special casing later on:\n for (const [name, value] of Object.entries(registryAliases ?? {})) {\n if (currentFrom.startsWith(`${name}/`)) {\n const depName = currentFrom.substring(name.length + 1);\n const dep = getDep(`${value}/${depName}`, false);\n // retain depName, not sure if condition is necessary\n if (dep.depName?.startsWith(value)) {\n dep.packageName = dep.depName;\n dep.depName = `${name}/${dep.depName.substring(value.length + 1)}`;\n }\n if (specifyReplaceString) {\n dep.replaceString = currentFrom;\n dep.autoReplaceStringTemplate = getAutoReplaceTemplate(dep);\n }\n return dep;\n }\n }\n\n const dep = splitImageParts(currentFrom);\n if (specifyReplaceString) {\n dep.replaceString ??= currentFrom;\n dep.autoReplaceStringTemplate =\n '{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}';\n }\n dep.datasource = DockerDatasource.id;\n\n // Pretty up special prefixes\n if (dep.depName) {\n const specialPrefixes = ['amd64', 'arm64', 'library'];\n for (const prefix of specialPrefixes) {\n if (dep.depName.startsWith(`${prefix}/`)) {\n dep.depName = dep.depName.replace(`${prefix}/`, '');\n if (specifyReplaceString) {\n dep.autoReplaceStringTemplate =\n '{{packageName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}';\n }\n }\n }\n }\n\n if (dep.depName === 'ubuntu' || dep.depName?.endsWith('/ubuntu')) {\n dep.versioning = ubuntuVersioning.id;\n }\n\n if (\n (dep.depName === 'debian' || dep.depName?.endsWith('/debian')) &&\n debianVersioning.api.isVersion(dep.currentValue)\n ) {\n dep.versioning = debianVersioning.id;\n }\n\n // Don't display quay.io ports\n if (dep.depName && quayRegex.test(dep.depName)) {\n const depName = dep.depName.replace(quayRegex, 'quay.io');\n if (depName !== dep.depName) {\n dep.depName = depName;\n dep.autoReplaceStringTemplate =\n '{{packageName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}';\n }\n }\n\n return dep;\n}\n\nexport function extractPackageFile(\n content: string,\n _packageFile: string,\n config: ExtractConfig,\n): PackageFileContent | null {\n const sanitizedContent = content.replace(regEx(/^\\uFEFF/), ''); // remove bom marker\n const deps: PackageDependency[] = [];\n const stageNames: string[] = [];\n const args: Record<string, string> = {};\n const argsLines: Record<string, number[]> = {};\n\n let escapeChar = '\\\\\\\\';\n let lookForEscapeChar = true;\n let lookForSyntaxDirective = true;\n\n const lineFeed = sanitizedContent.includes('\\r\\n') ? '\\r\\n' : '\\n';\n const lines = sanitizedContent.split(newlineRegex);\n for (let lineNumber = 0; lineNumber < lines.length; ) {\n const lineNumberInstrStart = lineNumber;\n let instruction = lines[lineNumber];\n\n if (lookForEscapeChar) {\n const directivesMatch = regEx(\n /^[ \\t]*#[ \\t]*(?<directive>syntax|escape)[ \\t]*=[ \\t]*(?<escapeChar>\\S)/i,\n ).exec(instruction);\n if (!directivesMatch) {\n lookForEscapeChar = false;\n } else if (directivesMatch.groups?.directive.toLowerCase() === 'escape') {\n if (directivesMatch.groups?.escapeChar === '`') {\n escapeChar = '`';\n }\n lookForEscapeChar = false;\n }\n }\n\n if (lookForSyntaxDirective) {\n const syntaxRegex = regEx(\n '^#[ \\\\t]*syntax[ \\\\t]*=[ \\\\t]*(?<image>\\\\S+)',\n 'im',\n );\n const syntaxMatch = instruction.match(syntaxRegex);\n if (syntaxMatch?.groups?.image) {\n const syntaxImage = syntaxMatch.groups.image;\n const lineNumberRanges: number[][] = [\n [lineNumberInstrStart, lineNumber],\n ];\n const dep = getDep(syntaxImage, true, config.registryAliases);\n dep.depType = 'syntax';\n processDepForAutoReplace(dep, lineNumberRanges, lines, lineFeed);\n logger.trace(\n {\n depName: dep.depName,\n currentValue: dep.currentValue,\n currentDigest: dep.currentDigest,\n },\n 'Dockerfile # syntax',\n );\n deps.push(dep);\n }\n lookForSyntaxDirective = false;\n }\n\n const lineContinuationRegex = regEx(`${escapeChar}[ \\\\t]*$|^[ \\\\t]*#`, 'm');\n let lineLookahead = instruction;\n while (\n !lookForEscapeChar &&\n !instruction.trimStart().startsWith('#') &&\n lineContinuationRegex.test(lineLookahead)\n ) {\n lineLookahead = lines[++lineNumber] || '';\n instruction += `\\n${lineLookahead}`;\n }\n\n const argRegex = regEx(\n `^[ \\\\t]*ARG(?:${escapeChar}[ \\\\t]*\\\\r?\\\\n| |\\\\t|#.*?\\\\r?\\\\n)+(?<name>\\\\w+)[ =](?<value>\\\\S*)`,\n 'im',\n );\n const argMatch = argRegex.exec(instruction);\n if (argMatch?.groups?.name) {\n argsLines[argMatch.groups.name] = [lineNumberInstrStart, lineNumber];\n let argMatchValue = argMatch.groups?.value;\n\n if (\n (argMatchValue.startsWith('\"') && argMatchValue.endsWith('\"')) ||\n (argMatchValue.startsWith(\"'\") && argMatchValue.endsWith(\"'\"))\n ) {\n argMatchValue = argMatchValue.slice(1, -1);\n }\n\n args[argMatch.groups.name] = argMatchValue || '';\n }\n\n const fromRegex = regEx(\n `^[ \\\\t]*FROM(?:${escapeChar}[ \\\\t]*\\\\r?\\\\n| |\\\\t|#.*?\\\\r?\\\\n|--platform=\\\\S+)+(?<image>\\\\S+)(?:(?:${escapeChar}[ \\\\t]*\\\\r?\\\\n| |\\\\t|#.*?\\\\r?\\\\n)+as[ \\\\t]+(?<name>\\\\S+))?`,\n 'im',\n );\n const fromMatch = instruction.match(fromRegex);\n if (fromMatch?.groups?.image) {\n let fromImage = fromMatch.groups.image;\n const lineNumberRanges: number[][] = [[lineNumberInstrStart, lineNumber]];\n\n if (fromImage.includes(variableMarker)) {\n const variables = extractVariables(fromImage);\n for (const [fullVariable, argName] of Object.entries(variables)) {\n const resolvedArgValue = args[argName];\n if (resolvedArgValue || resolvedArgValue === '') {\n fromImage = fromImage.replaceAll(fullVariable, resolvedArgValue);\n lineNumberRanges.push(argsLines[argName]);\n }\n }\n }\n\n if (fromMatch.groups?.name) {\n logger.debug(\n `Found a multistage build stage name: ${fromMatch.groups.name}`,\n );\n stageNames.push(fromMatch.groups.name);\n }\n if (fromImage === 'scratch') {\n logger.debug('Skipping scratch');\n } else if (fromImage && stageNames.includes(fromImage)) {\n logger.debug(`Skipping alias FROM image:${fromImage}`);\n } else {\n const dep = getDep(fromImage, true, config.registryAliases);\n processDepForAutoReplace(dep, lineNumberRanges, lines, lineFeed);\n logger.trace(\n {\n depName: dep.depName,\n currentValue: dep.currentValue,\n currentDigest: dep.currentDigest,\n },\n 'Dockerfile FROM',\n );\n deps.push(dep);\n }\n }\n\n const copyFromRegex = regEx(\n `^[ \\\\t]*COPY(?:${escapeChar}[ \\\\t]*\\\\r?\\\\n| |\\\\t|#.*?\\\\r?\\\\n|--[a-z]+(?:=[a-zA-Z0-9_.:-]+?)?)+--from=(?<image>\\\\S+)`,\n 'im',\n );\n const copyFromMatch = instruction.match(copyFromRegex);\n if (copyFromMatch?.groups?.image) {\n if (stageNames.includes(copyFromMatch.groups.image)) {\n logger.debug(\n { image: copyFromMatch.groups.image },\n 'Skipping alias COPY --from',\n );\n } else if (Number.isNaN(Number(copyFromMatch.groups.image))) {\n const dep = getDep(\n copyFromMatch.groups.image,\n true,\n config.registryAliases,\n );\n const lineNumberRanges: number[][] = [\n [lineNumberInstrStart, lineNumber],\n ];\n processDepForAutoReplace(dep, lineNumberRanges, lines, lineFeed);\n logger.debug(\n {\n depName: dep.depName,\n currentValue: dep.currentValue,\n currentDigest: dep.currentDigest,\n },\n 'Dockerfile COPY --from',\n );\n deps.push(dep);\n } else {\n logger.debug(\n { image: copyFromMatch.groups.image },\n 'Skipping index reference COPY --from',\n );\n }\n }\n\n const runMountFromRegex = regEx(\n `^[ \\\\t]*RUN(?:${escapeChar}[ \\\\t]*\\\\r?\\\\n| |\\\\t|#.*?\\\\r?\\\\n|--[a-z]+(?:=[a-zA-Z0-9_.:-]+?)?)+--mount=(?:\\\\S*=\\\\S*,)*from=(?<image>[^, ]+)`,\n 'im',\n );\n const runMountFromMatch = instruction.match(runMountFromRegex);\n if (runMountFromMatch?.groups?.image) {\n if (stageNames.includes(runMountFromMatch.groups.image)) {\n logger.debug(\n { image: runMountFromMatch.groups.image },\n 'Skipping alias RUN --mount=from',\n );\n } else {\n const dep = getDep(\n runMountFromMatch.groups.image,\n true,\n config.registryAliases,\n );\n const lineNumberRanges: number[][] = [\n [lineNumberInstrStart, lineNumber],\n ];\n processDepForAutoReplace(dep, lineNumberRanges, lines, lineFeed);\n logger.debug(\n {\n depName: dep.depName,\n currentValue: dep.currentValue,\n currentDigest: dep.currentDigest,\n },\n 'Dockerfile RUN --mount=from',\n );\n deps.push(dep);\n }\n }\n\n lineNumber += 1;\n }\n\n if (!deps.length) {\n return null;\n }\n for (const d of deps) {\n d.depType ??= 'stage';\n }\n deps.at(-1)!.depType = 'final';\n return { deps };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"extract.js","names":["ubuntuVersioning.id","debianVersioning.id"],"sources":["../../../../lib/modules/manager/dockerfile/extract.ts"],"sourcesContent":["import {\n isNonEmptyStringAndNotWhitespace,\n isNumericString,\n isString,\n} from '@sindresorhus/is';\nimport { logger } from '../../../logger/index.ts';\nimport { newlineRegex, regEx } from '../../../util/regex.ts';\nimport { DockerDatasource } from '../../datasource/docker/index.ts';\nimport * as debianVersioning from '../../versioning/debian/index.ts';\nimport * as ubuntuVersioning from '../../versioning/ubuntu/index.ts';\nimport type {\n ExtractConfig,\n PackageDependency,\n PackageFileContent,\n} from '../types.ts';\n\nconst variableMarker = '$';\n\nexport function extractVariables(image: string): Record<string, string> {\n const variables: Record<string, string> = {};\n const variableRegex = regEx(\n /(?<fullvariable>\\\\?\\$(?<simplearg>\\w+)|\\\\?\\${(?<complexarg>\\w+)(?::.+?)?}+)/gi,\n );\n\n let match: RegExpExecArray | null;\n do {\n match = variableRegex.exec(image);\n if (match?.groups?.fullvariable) {\n variables[match.groups.fullvariable] =\n match.groups?.simplearg || match.groups?.complexarg;\n }\n } while (match);\n\n return variables;\n}\n\nfunction getAutoReplaceTemplate(dep: PackageDependency): string | undefined {\n let template = dep.replaceString;\n\n if (dep.currentValue) {\n let placeholder = '{{#if newValue}}{{newValue}}{{/if}}';\n if (!dep.currentDigest) {\n placeholder += '{{#if newDigest}}@{{newDigest}}{{/if}}';\n }\n template = template?.replace(dep.currentValue, placeholder);\n }\n\n if (dep.currentDigest) {\n template = template?.replace(\n dep.currentDigest,\n '{{#if newDigest}}{{newDigest}}{{/if}}',\n );\n }\n\n return template;\n}\n\nfunction processDepForAutoReplace(\n dep: PackageDependency,\n lineNumberRanges: number[][],\n lines: string[],\n linefeed: string,\n): void {\n const lineNumberRangesToReplace: number[][] = [];\n for (const lineNumberRange of lineNumberRanges) {\n for (const lineNumber of lineNumberRange) {\n if (\n (isString(dep.currentValue) &&\n lines[lineNumber].includes(dep.currentValue)) ||\n (isString(dep.currentDigest) &&\n lines[lineNumber].includes(dep.currentDigest))\n ) {\n lineNumberRangesToReplace.push(lineNumberRange);\n }\n }\n }\n\n lineNumberRangesToReplace.sort((a, b) => {\n return a[0] - b[0];\n });\n\n const minLine = lineNumberRangesToReplace[0]?.[0];\n const maxLine = lineNumberRangesToReplace.at(-1)?.[1];\n if (\n lineNumberRanges.length === 1 ||\n minLine === undefined ||\n maxLine === undefined\n ) {\n return;\n }\n\n const unfoldedLineNumbers = Array.from(\n { length: maxLine - minLine + 1 },\n (_v, k) => k + minLine,\n );\n\n dep.replaceString = unfoldedLineNumbers\n .map((lineNumber) => lines[lineNumber])\n .join(linefeed);\n\n if (!dep.currentDigest) {\n dep.replaceString += linefeed;\n }\n\n dep.autoReplaceStringTemplate = getAutoReplaceTemplate(dep);\n}\n\nexport function splitImageParts(currentFrom: string): PackageDependency {\n let isVariable = false;\n let cleanedCurrentFrom = currentFrom;\n\n // Check if we have a variable in format of \"${VARIABLE:-<image>:<defaultVal>@<digest>}\"\n // If so, remove everything except the image, defaultVal and digest.\n if (cleanedCurrentFrom?.includes(variableMarker)) {\n const defaultValueRegex = regEx(/^\\${.+?:-\"?(?<value>.*?)\"?}$/);\n const defaultValueMatch =\n defaultValueRegex.exec(cleanedCurrentFrom)?.groups;\n if (defaultValueMatch?.value) {\n isVariable = true;\n cleanedCurrentFrom = defaultValueMatch.value;\n }\n\n if (cleanedCurrentFrom?.includes(variableMarker)) {\n // If cleanedCurrentFrom contains a variable, after cleaning, e.g. \"$REGISTRY/alpine\", we do not support this.\n return {\n skipReason: 'contains-variable',\n };\n }\n }\n\n const [currentDepTag, currentDigest] = cleanedCurrentFrom.split('@');\n const depTagSplit = currentDepTag.split(':');\n let depName: string;\n let currentValue: string | undefined;\n if (depTagSplit.length === 1 || depTagSplit.at(-1)!.includes('/')) {\n depName = currentDepTag;\n } else {\n currentValue = depTagSplit.pop();\n depName = depTagSplit.join(':');\n }\n\n const dep: PackageDependency = {\n depName,\n packageName: depName,\n currentValue,\n currentDigest,\n };\n\n if (isVariable) {\n dep.replaceString = cleanedCurrentFrom;\n\n if (!dep.currentValue) {\n delete dep.currentValue;\n }\n\n if (!dep.currentDigest) {\n delete dep.currentDigest;\n }\n }\n\n return dep;\n}\n\nconst quayRegex = regEx(/^quay\\.io(?::[1-9][0-9]{0,4})?/i);\n\nexport function getDep(\n currentFrom: string | null | undefined,\n specifyReplaceString = true,\n registryAliases?: Record<string, string>,\n): PackageDependency {\n if (\n !isString(currentFrom) ||\n !isNonEmptyStringAndNotWhitespace(currentFrom)\n ) {\n return {\n skipReason: 'invalid-value',\n };\n }\n\n // Resolve registry aliases first so that we don't need special casing later on:\n for (const [name, value] of Object.entries(registryAliases ?? {})) {\n if (currentFrom.startsWith(`${name}/`)) {\n const depName = currentFrom.substring(name.length + 1);\n const dep = getDep(`${value}/${depName}`, false);\n // retain depName, not sure if condition is necessary\n if (dep.depName?.startsWith(value)) {\n dep.packageName = dep.depName;\n dep.depName = `${name}/${dep.depName.substring(value.length + 1)}`;\n }\n if (specifyReplaceString) {\n dep.replaceString = currentFrom;\n dep.autoReplaceStringTemplate = getAutoReplaceTemplate(dep);\n }\n return dep;\n }\n }\n\n const dep = splitImageParts(currentFrom);\n if (specifyReplaceString) {\n dep.replaceString ??= currentFrom;\n dep.autoReplaceStringTemplate =\n '{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}';\n }\n dep.datasource = DockerDatasource.id;\n\n // Pretty up special prefixes\n if (dep.depName) {\n const specialPrefixes = ['amd64', 'arm64', 'library'];\n for (const prefix of specialPrefixes) {\n if (dep.depName.startsWith(`${prefix}/`)) {\n dep.depName = dep.depName.replace(`${prefix}/`, '');\n if (specifyReplaceString) {\n dep.autoReplaceStringTemplate =\n '{{packageName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}';\n }\n }\n }\n }\n\n if (dep.depName === 'ubuntu' || dep.depName?.endsWith('/ubuntu')) {\n dep.versioning = ubuntuVersioning.id;\n }\n\n if (\n (dep.depName === 'debian' || dep.depName?.endsWith('/debian')) &&\n debianVersioning.api.isVersion(dep.currentValue)\n ) {\n dep.versioning = debianVersioning.id;\n }\n\n // Don't display quay.io ports\n if (dep.depName && quayRegex.test(dep.depName)) {\n const depName = dep.depName.replace(quayRegex, 'quay.io');\n if (depName !== dep.depName) {\n dep.depName = depName;\n dep.autoReplaceStringTemplate =\n '{{packageName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}';\n }\n }\n\n return dep;\n}\n\nexport function extractPackageFile(\n content: string,\n _packageFile: string,\n config: ExtractConfig,\n): PackageFileContent | null {\n const sanitizedContent = content.replace(regEx(/^\\uFEFF/), ''); // remove bom marker\n const deps: PackageDependency[] = [];\n const stageNames: string[] = [];\n const args: Record<string, string> = {};\n const argsLines: Record<string, number[]> = {};\n\n let escapeChar = '\\\\\\\\';\n let lookForEscapeChar = true;\n let lookForSyntaxDirective = true;\n\n const lineFeed = sanitizedContent.includes('\\r\\n') ? '\\r\\n' : '\\n';\n const lines = sanitizedContent.split(newlineRegex);\n for (let lineNumber = 0; lineNumber < lines.length; ) {\n const lineNumberInstrStart = lineNumber;\n let instruction = lines[lineNumber];\n\n if (lookForEscapeChar) {\n const directivesMatch = regEx(\n /^[ \\t]*#[ \\t]*(?<directive>syntax|escape)[ \\t]*=[ \\t]*(?<escapeChar>\\S)/i,\n ).exec(instruction);\n if (!directivesMatch) {\n lookForEscapeChar = false;\n } else if (directivesMatch.groups?.directive.toLowerCase() === 'escape') {\n if (directivesMatch.groups?.escapeChar === '`') {\n escapeChar = '`';\n }\n lookForEscapeChar = false;\n }\n }\n\n if (lookForSyntaxDirective) {\n const syntaxRegex = regEx(\n '^#[ \\\\t]*syntax[ \\\\t]*=[ \\\\t]*(?<image>\\\\S+)',\n 'im',\n );\n const syntaxMatch = instruction.match(syntaxRegex);\n if (syntaxMatch?.groups?.image) {\n const syntaxImage = syntaxMatch.groups.image;\n const lineNumberRanges: number[][] = [\n [lineNumberInstrStart, lineNumber],\n ];\n const dep = getDep(syntaxImage, true, config.registryAliases);\n dep.depType = 'syntax';\n processDepForAutoReplace(dep, lineNumberRanges, lines, lineFeed);\n logger.trace(\n {\n depName: dep.depName,\n currentValue: dep.currentValue,\n currentDigest: dep.currentDigest,\n },\n 'Dockerfile # syntax',\n );\n deps.push(dep);\n }\n lookForSyntaxDirective = false;\n }\n\n const lineContinuationRegex = regEx(`${escapeChar}[ \\\\t]*$|^[ \\\\t]*#`, 'm');\n let lineLookahead = instruction;\n while (\n !lookForEscapeChar &&\n !instruction.trimStart().startsWith('#') &&\n lineContinuationRegex.test(lineLookahead)\n ) {\n lineLookahead = lines[++lineNumber] || '';\n instruction += `\\n${lineLookahead}`;\n }\n\n const argRegex = regEx(\n `^[ \\\\t]*ARG(?:${escapeChar}[ \\\\t]*\\\\r?\\\\n| |\\\\t|#.*?\\\\r?\\\\n)+(?<name>\\\\w+)[ =](?<value>\\\\S*)`,\n 'im',\n );\n const argMatch = argRegex.exec(instruction);\n if (argMatch?.groups?.name) {\n argsLines[argMatch.groups.name] = [lineNumberInstrStart, lineNumber];\n let argMatchValue = argMatch.groups?.value;\n\n if (\n (argMatchValue.startsWith('\"') && argMatchValue.endsWith('\"')) ||\n (argMatchValue.startsWith(\"'\") && argMatchValue.endsWith(\"'\"))\n ) {\n argMatchValue = argMatchValue.slice(1, -1);\n }\n\n args[argMatch.groups.name] = argMatchValue || '';\n }\n\n const fromRegex = regEx(\n `^[ \\\\t]*FROM(?:${escapeChar}[ \\\\t]*\\\\r?\\\\n| |\\\\t|#.*?\\\\r?\\\\n|--platform=\\\\S+)+(?<image>\\\\S+)(?:(?:${escapeChar}[ \\\\t]*\\\\r?\\\\n| |\\\\t|#.*?\\\\r?\\\\n)+as[ \\\\t]+(?<name>\\\\S+))?`,\n 'im',\n );\n const fromMatch = instruction.match(fromRegex);\n if (fromMatch?.groups?.image) {\n let fromImage = fromMatch.groups.image;\n const lineNumberRanges: number[][] = [[lineNumberInstrStart, lineNumber]];\n\n if (fromImage.includes(variableMarker)) {\n const variables = extractVariables(fromImage);\n for (const [fullVariable, argName] of Object.entries(variables)) {\n const resolvedArgValue = args[argName];\n if (resolvedArgValue || resolvedArgValue === '') {\n fromImage = fromImage.replaceAll(fullVariable, resolvedArgValue);\n lineNumberRanges.push(argsLines[argName]);\n }\n }\n }\n\n if (fromMatch.groups?.name) {\n logger.debug(\n `Found a multistage build stage name: ${fromMatch.groups.name}`,\n );\n stageNames.push(fromMatch.groups.name);\n }\n if (fromImage === 'scratch') {\n logger.debug('Skipping scratch');\n } else if (fromImage && stageNames.includes(fromImage)) {\n logger.debug(`Skipping alias FROM image:${fromImage}`);\n } else {\n const dep = getDep(fromImage, true, config.registryAliases);\n processDepForAutoReplace(dep, lineNumberRanges, lines, lineFeed);\n logger.trace(\n {\n depName: dep.depName,\n currentValue: dep.currentValue,\n currentDigest: dep.currentDigest,\n },\n 'Dockerfile FROM',\n );\n deps.push(dep);\n }\n }\n\n const copyFromRegex = regEx(\n `^[ \\\\t]*COPY(?:${escapeChar}[ \\\\t]*\\\\r?\\\\n| |\\\\t|#.*?\\\\r?\\\\n|--[a-z]+(?:=[a-zA-Z0-9_.:-]+?)?)+--from=(?<image>\\\\S+)`,\n 'im',\n );\n const copyFromMatch = instruction.match(copyFromRegex);\n if (copyFromMatch?.groups?.image) {\n if (stageNames.includes(copyFromMatch.groups.image)) {\n logger.debug(\n { image: copyFromMatch.groups.image },\n 'Skipping alias COPY --from',\n );\n } else if (isNumericString(copyFromMatch.groups.image)) {\n logger.debug(\n { image: copyFromMatch.groups.image },\n 'Skipping index reference COPY --from',\n );\n } else {\n const dep = getDep(\n copyFromMatch.groups.image,\n true,\n config.registryAliases,\n );\n const lineNumberRanges: number[][] = [\n [lineNumberInstrStart, lineNumber],\n ];\n processDepForAutoReplace(dep, lineNumberRanges, lines, lineFeed);\n logger.debug(\n {\n depName: dep.depName,\n currentValue: dep.currentValue,\n currentDigest: dep.currentDigest,\n },\n 'Dockerfile COPY --from',\n );\n deps.push(dep);\n }\n }\n\n const runMountFromRegex = regEx(\n `^[ \\\\t]*RUN(?:${escapeChar}[ \\\\t]*\\\\r?\\\\n| |\\\\t|#.*?\\\\r?\\\\n|--[a-z]+(?:=[a-zA-Z0-9_.:-]+?)?)+--mount=(?:\\\\S*=\\\\S*,)*from=(?<image>[^, ]+)`,\n 'im',\n );\n const runMountFromMatch = instruction.match(runMountFromRegex);\n if (runMountFromMatch?.groups?.image) {\n if (stageNames.includes(runMountFromMatch.groups.image)) {\n logger.debug(\n { image: runMountFromMatch.groups.image },\n 'Skipping alias RUN --mount=from',\n );\n } else {\n const dep = getDep(\n runMountFromMatch.groups.image,\n true,\n config.registryAliases,\n );\n const lineNumberRanges: number[][] = [\n [lineNumberInstrStart, lineNumber],\n ];\n processDepForAutoReplace(dep, lineNumberRanges, lines, lineFeed);\n logger.debug(\n {\n depName: dep.depName,\n currentValue: dep.currentValue,\n currentDigest: dep.currentDigest,\n },\n 'Dockerfile RUN --mount=from',\n );\n deps.push(dep);\n }\n }\n\n lineNumber += 1;\n }\n\n if (!deps.length) {\n return null;\n }\n for (const d of deps) {\n d.depType ??= 'stage';\n }\n deps.at(-1)!.depType = 'final';\n return { deps };\n}\n"],"mappings":"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"}
@@ -105,7 +105,7 @@ var GerritScm = class extends DefaultGitScm {
105
105
  */
106
106
  function nextPatchSetRef(currentRef) {
107
107
  const lastSlash = currentRef.lastIndexOf("/");
108
- const patchSet = Number(currentRef.slice(lastSlash + 1));
108
+ const patchSet = parseInt(currentRef.slice(lastSlash + 1), 10);
109
109
  return `${currentRef.slice(0, lastSlash + 1)}${patchSet + 1}`;
110
110
  }
111
111
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"scm.js","names":["git.pushCommit","git.prepareCommit","git.setVirtualBranch"],"sources":["../../../../lib/modules/platform/gerrit/scm.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport { isNonEmptyArray, isString } from '@sindresorhus/is';\nimport { logger } from '../../../logger/index.ts';\nimport * as git from '../../../util/git/index.ts';\nimport type { CommitFilesConfig, FileChange } from '../../../util/git/types.ts';\nimport { hash } from '../../../util/hash.ts';\nimport type { LongCommitSha } from '../../../util/schema-utils/git.ts';\nimport { DefaultGitScm } from '../default-scm.ts';\nimport { client } from './client.ts';\nimport type { GerritLabels } from './schema.ts';\nimport { mapBranchStatusToLabel } from './utils.ts';\n\nconst CODE_REVIEW_LABEL = 'Code-Review';\n\n/**\n * Gerrit SCM strategy:\n * Instead of implementing custom branch operations, we fetch all open Gerrit changes\n * as virtual branches (refs/remotes/origin/<branchName>) after repository initialization.\n * This allows us to leverage DefaultGitScm for most operations, treating virtual branches\n * as regular Git branches, while minimizing Gerrit API requests.\n */\n\nlet repository: string;\nlet projectLabels: GerritLabels = {};\nexport function configureScm(repo: string, labels: GerritLabels = {}): void {\n repository = repo;\n projectLabels = labels;\n}\n\n/**\n * Returns the max vote value for the \"Code-Review\" label (some Gerrit\n * projects only allow up to +1), or `null` if the label isn't defined on\n * the project, so the caller can skip voting instead of failing the push.\n */\nfunction getAutoApproveLabelValue(): number | null {\n const codeReviewLabel = projectLabels[CODE_REVIEW_LABEL];\n if (!codeReviewLabel) {\n logger.warn(\n { repository, label: CODE_REVIEW_LABEL },\n 'Cannot auto-approve: label is not defined on the project',\n );\n return null;\n }\n return mapBranchStatusToLabel('green', codeReviewLabel);\n}\n\nexport async function pushForReview(options: {\n sourceRef: string;\n targetBranch: string;\n files: FileChange[];\n autoApprove?: boolean;\n labels?: string[];\n}): Promise<boolean> {\n const pushOptions = ['notify=NONE', 'ready'];\n if (options.autoApprove) {\n const value = getAutoApproveLabelValue();\n if (value !== null) {\n pushOptions.push(`label=${CODE_REVIEW_LABEL}+${value}`);\n }\n }\n if (isNonEmptyArray(options.labels)) {\n for (const label of options.labels) {\n pushOptions.push(`hashtag=${label}`);\n }\n }\n\n return git.pushCommit({\n sourceRef: options.sourceRef,\n targetRef: `refs/for/${options.targetBranch}`,\n files: options.files,\n pushOptions,\n });\n}\n\nexport class GerritScm extends DefaultGitScm {\n override async commitAndPush(\n commit: CommitFilesConfig,\n ): Promise<LongCommitSha | null> {\n logger.debug(`commitAndPush(${commit.branchName})`);\n\n const existingChange = await client.getBranchChange(repository, {\n branchName: commit.branchName,\n state: 'open',\n targetBranch: commit.baseBranch,\n requestDetails: ['CURRENT_REVISION'],\n });\n\n const message = isString(commit.message)\n ? [commit.message]\n : commit.message;\n\n // In Gerrit, the change subject/title is the first line of the commit message\n // v8 ignore else -- TODO: add test #40625\n if (commit.prTitle) {\n const firstMessageLines = message[0].split('\\n');\n firstMessageLines[0] = commit.prTitle;\n message[0] = firstMessageLines.join('\\n');\n }\n\n const changeId = existingChange?.change_id ?? generateChangeId();\n commit.message = message;\n commit.trailers = [\n ...(commit.trailers ?? []).filter(\n (trailer) =>\n !trailer.startsWith('Renovate-Branch:') &&\n !trailer.startsWith('Change-Id:'),\n ),\n `Renovate-Branch: ${commit.branchName}`,\n `Change-Id: ${changeId}`,\n ];\n // prepareCommit already checks hasDiff('HEAD', 'origin/<branchName>') when\n // force is not set, which works because virtual branches are fetched as\n // refs/remotes/origin/<branchName> during init. This avoids pushing empty\n // patch sets without a separate diff check.\n const commitResult = await git.prepareCommit(commit);\n if (commitResult) {\n const { commitSha } = commitResult;\n if (existingChange) {\n // Since the change already exists, we push to the same target branch to\n // avoid creating a new change if the base branch has changed.\n // updatePr() will later take care of moving the existing change to a\n // different base branch if needed.\n const pushResult = await pushForReview({\n sourceRef: commit.branchName,\n targetBranch: existingChange.branch,\n files: commit.files,\n autoApprove: commit.autoApprove,\n });\n /* v8 ignore else -- should never happen */\n if (pushResult) {\n const currentRef =\n existingChange.revisions![existingChange.current_revision!].ref;\n await git.setVirtualBranch(\n commit.branchName,\n nextPatchSetRef(currentRef),\n commitSha,\n );\n return commitSha;\n }\n } else {\n logger.debug(`Commit prepared, push deferred to createPr()`);\n return commitSha;\n }\n }\n return null; // empty commit, no changes in this Gerrit Change\n }\n}\n\n/**\n * Derive the next patch-set ref from a Gerrit change ref.\n * Gerrit refs follow the pattern `refs/changes/<NN>/<change>/<patchset>`.\n * After a push, Gerrit creates the next patch-set, so we increment the\n * trailing number to keep the virtual branch in sync.\n */\nexport function nextPatchSetRef(currentRef: string): string {\n const lastSlash = currentRef.lastIndexOf('/');\n const patchSet = Number(currentRef.slice(lastSlash + 1));\n return `${currentRef.slice(0, lastSlash + 1)}${patchSet + 1}`;\n}\n\n/**\n * This function should generate a Gerrit Change-ID analogous to the commit hook. We avoid the commit hook cause of security concerns.\n * random=$( (whoami ; hostname ; date; cat $1 ; echo $RANDOM) | git hash-object --stdin) prefixed with an 'I'.\n * TODO: Gerrit don't accept longer Change-IDs (sha256), but what happens with this https://git-scm.com/docs/hash-function-transition/ ?\n */\nfunction generateChangeId(): string {\n return `I${hash(randomUUID(), 'sha1')}`;\n}\n"],"mappings":";;;;;;;;;AAYA,MAAM,oBAAoB;;;;;;;;AAU1B,IAAI;AACJ,IAAI,gBAA8B,CAAC;AACnC,SAAgB,aAAa,MAAc,SAAuB,CAAC,GAAS;CAC1E,aAAa;CACb,gBAAgB;AAClB;;;;;;AAOA,SAAS,2BAA0C;CACjD,MAAM,kBAAkB,cAAc;CACtC,IAAI,CAAC,iBAAiB;EACpB,OAAO,KACL;GAAE;GAAY,OAAO;EAAkB,GACvC,0DACF;EACA,OAAO;CACT;CACA,OAAO,uBAAuB,SAAS,eAAe;AACxD;AAEA,eAAsB,cAAc,SAMf;CACnB,MAAM,cAAc,CAAC,eAAe,OAAO;CAC3C,IAAI,QAAQ,aAAa;EACvB,MAAM,QAAQ,yBAAyB;EACvC,IAAI,UAAU,MACZ,YAAY,KAAK,SAAS,kBAAkB,GAAG,OAAO;CAE1D;CACA,IAAI,gBAAgB,QAAQ,MAAM,GAChC,KAAK,MAAM,SAAS,QAAQ,QAC1B,YAAY,KAAK,WAAW,OAAO;CAIvC,OAAOA,WAAe;EACpB,WAAW,QAAQ;EACnB,WAAW,YAAY,QAAQ;EAC/B,OAAO,QAAQ;EACf;CACF,CAAC;AACH;AAEA,IAAa,YAAb,cAA+B,cAAc;CAC3C,MAAe,cACb,QAC+B;EAC/B,OAAO,MAAM,iBAAiB,OAAO,WAAW,EAAE;EAElD,MAAM,iBAAiB,MAAM,OAAO,gBAAgB,YAAY;GAC9D,YAAY,OAAO;GACnB,OAAO;GACP,cAAc,OAAO;GACrB,gBAAgB,CAAC,kBAAkB;EACrC,CAAC;EAED,MAAM,UAAU,SAAS,OAAO,OAAO,IACnC,CAAC,OAAO,OAAO,IACf,OAAO;;EAIX,IAAI,OAAO,SAAS;GAClB,MAAM,oBAAoB,QAAQ,EAAE,CAAC,MAAM,IAAI;GAC/C,kBAAkB,KAAK,OAAO;GAC9B,QAAQ,KAAK,kBAAkB,KAAK,IAAI;EAC1C;EAEA,MAAM,WAAW,gBAAgB,aAAa,iBAAiB;EAC/D,OAAO,UAAU;EACjB,OAAO,WAAW;GAChB,IAAI,OAAO,YAAY,CAAC,EAAA,CAAG,QACxB,YACC,CAAC,QAAQ,WAAW,kBAAkB,KACtC,CAAC,QAAQ,WAAW,YAAY,CACpC;GACA,oBAAoB,OAAO;GAC3B,cAAc;EAChB;EAKA,MAAM,eAAe,MAAMC,cAAkB,MAAM;EACnD,IAAI,cAAc;GAChB,MAAM,EAAE,cAAc;GACtB,IAAI,gBAYE;;QAAA,MAPqB,cAAc;KACrC,WAAW,OAAO;KAClB,cAAc,eAAe;KAC7B,OAAO,OAAO;KACd,aAAa,OAAO;IACtB,CAAC,GAEe;KACd,MAAM,aACJ,eAAe,UAAW,eAAe,iBAAkB,CAAC;KAC9D,MAAMC,iBACJ,OAAO,YACP,gBAAgB,UAAU,GAC1B,SACF;KACA,OAAO;IACT;UACK;IACL,OAAO,MAAM,8CAA8C;IAC3D,OAAO;GACT;EACF;EACA,OAAO;CACT;AACF;;;;;;;AAQA,SAAgB,gBAAgB,YAA4B;CAC1D,MAAM,YAAY,WAAW,YAAY,GAAG;CAC5C,MAAM,WAAW,OAAO,WAAW,MAAM,YAAY,CAAC,CAAC;CACvD,OAAO,GAAG,WAAW,MAAM,GAAG,YAAY,CAAC,IAAI,WAAW;AAC5D;;;;;;AAOA,SAAS,mBAA2B;CAClC,OAAO,IAAI,KAAK,WAAW,GAAG,MAAM;AACtC"}
1
+ {"version":3,"file":"scm.js","names":["git.pushCommit","git.prepareCommit","git.setVirtualBranch"],"sources":["../../../../lib/modules/platform/gerrit/scm.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport { isNonEmptyArray, isString } from '@sindresorhus/is';\nimport { logger } from '../../../logger/index.ts';\nimport * as git from '../../../util/git/index.ts';\nimport type { CommitFilesConfig, FileChange } from '../../../util/git/types.ts';\nimport { hash } from '../../../util/hash.ts';\nimport type { LongCommitSha } from '../../../util/schema-utils/git.ts';\nimport { DefaultGitScm } from '../default-scm.ts';\nimport { client } from './client.ts';\nimport type { GerritLabels } from './schema.ts';\nimport { mapBranchStatusToLabel } from './utils.ts';\n\nconst CODE_REVIEW_LABEL = 'Code-Review';\n\n/**\n * Gerrit SCM strategy:\n * Instead of implementing custom branch operations, we fetch all open Gerrit changes\n * as virtual branches (refs/remotes/origin/<branchName>) after repository initialization.\n * This allows us to leverage DefaultGitScm for most operations, treating virtual branches\n * as regular Git branches, while minimizing Gerrit API requests.\n */\n\nlet repository: string;\nlet projectLabels: GerritLabels = {};\nexport function configureScm(repo: string, labels: GerritLabels = {}): void {\n repository = repo;\n projectLabels = labels;\n}\n\n/**\n * Returns the max vote value for the \"Code-Review\" label (some Gerrit\n * projects only allow up to +1), or `null` if the label isn't defined on\n * the project, so the caller can skip voting instead of failing the push.\n */\nfunction getAutoApproveLabelValue(): number | null {\n const codeReviewLabel = projectLabels[CODE_REVIEW_LABEL];\n if (!codeReviewLabel) {\n logger.warn(\n { repository, label: CODE_REVIEW_LABEL },\n 'Cannot auto-approve: label is not defined on the project',\n );\n return null;\n }\n return mapBranchStatusToLabel('green', codeReviewLabel);\n}\n\nexport async function pushForReview(options: {\n sourceRef: string;\n targetBranch: string;\n files: FileChange[];\n autoApprove?: boolean;\n labels?: string[];\n}): Promise<boolean> {\n const pushOptions = ['notify=NONE', 'ready'];\n if (options.autoApprove) {\n const value = getAutoApproveLabelValue();\n if (value !== null) {\n pushOptions.push(`label=${CODE_REVIEW_LABEL}+${value}`);\n }\n }\n if (isNonEmptyArray(options.labels)) {\n for (const label of options.labels) {\n pushOptions.push(`hashtag=${label}`);\n }\n }\n\n return git.pushCommit({\n sourceRef: options.sourceRef,\n targetRef: `refs/for/${options.targetBranch}`,\n files: options.files,\n pushOptions,\n });\n}\n\nexport class GerritScm extends DefaultGitScm {\n override async commitAndPush(\n commit: CommitFilesConfig,\n ): Promise<LongCommitSha | null> {\n logger.debug(`commitAndPush(${commit.branchName})`);\n\n const existingChange = await client.getBranchChange(repository, {\n branchName: commit.branchName,\n state: 'open',\n targetBranch: commit.baseBranch,\n requestDetails: ['CURRENT_REVISION'],\n });\n\n const message = isString(commit.message)\n ? [commit.message]\n : commit.message;\n\n // In Gerrit, the change subject/title is the first line of the commit message\n // v8 ignore else -- TODO: add test #40625\n if (commit.prTitle) {\n const firstMessageLines = message[0].split('\\n');\n firstMessageLines[0] = commit.prTitle;\n message[0] = firstMessageLines.join('\\n');\n }\n\n const changeId = existingChange?.change_id ?? generateChangeId();\n commit.message = message;\n commit.trailers = [\n ...(commit.trailers ?? []).filter(\n (trailer) =>\n !trailer.startsWith('Renovate-Branch:') &&\n !trailer.startsWith('Change-Id:'),\n ),\n `Renovate-Branch: ${commit.branchName}`,\n `Change-Id: ${changeId}`,\n ];\n // prepareCommit already checks hasDiff('HEAD', 'origin/<branchName>') when\n // force is not set, which works because virtual branches are fetched as\n // refs/remotes/origin/<branchName> during init. This avoids pushing empty\n // patch sets without a separate diff check.\n const commitResult = await git.prepareCommit(commit);\n if (commitResult) {\n const { commitSha } = commitResult;\n if (existingChange) {\n // Since the change already exists, we push to the same target branch to\n // avoid creating a new change if the base branch has changed.\n // updatePr() will later take care of moving the existing change to a\n // different base branch if needed.\n const pushResult = await pushForReview({\n sourceRef: commit.branchName,\n targetBranch: existingChange.branch,\n files: commit.files,\n autoApprove: commit.autoApprove,\n });\n /* v8 ignore else -- should never happen */\n if (pushResult) {\n const currentRef =\n existingChange.revisions![existingChange.current_revision!].ref;\n await git.setVirtualBranch(\n commit.branchName,\n nextPatchSetRef(currentRef),\n commitSha,\n );\n return commitSha;\n }\n } else {\n logger.debug(`Commit prepared, push deferred to createPr()`);\n return commitSha;\n }\n }\n return null; // empty commit, no changes in this Gerrit Change\n }\n}\n\n/**\n * Derive the next patch-set ref from a Gerrit change ref.\n * Gerrit refs follow the pattern `refs/changes/<NN>/<change>/<patchset>`.\n * After a push, Gerrit creates the next patch-set, so we increment the\n * trailing number to keep the virtual branch in sync.\n */\nexport function nextPatchSetRef(currentRef: string): string {\n const lastSlash = currentRef.lastIndexOf('/');\n const patchSet = parseInt(currentRef.slice(lastSlash + 1), 10);\n return `${currentRef.slice(0, lastSlash + 1)}${patchSet + 1}`;\n}\n\n/**\n * This function should generate a Gerrit Change-ID analogous to the commit hook. We avoid the commit hook cause of security concerns.\n * random=$( (whoami ; hostname ; date; cat $1 ; echo $RANDOM) | git hash-object --stdin) prefixed with an 'I'.\n * TODO: Gerrit don't accept longer Change-IDs (sha256), but what happens with this https://git-scm.com/docs/hash-function-transition/ ?\n */\nfunction generateChangeId(): string {\n return `I${hash(randomUUID(), 'sha1')}`;\n}\n"],"mappings":";;;;;;;;;AAYA,MAAM,oBAAoB;;;;;;;;AAU1B,IAAI;AACJ,IAAI,gBAA8B,CAAC;AACnC,SAAgB,aAAa,MAAc,SAAuB,CAAC,GAAS;CAC1E,aAAa;CACb,gBAAgB;AAClB;;;;;;AAOA,SAAS,2BAA0C;CACjD,MAAM,kBAAkB,cAAc;CACtC,IAAI,CAAC,iBAAiB;EACpB,OAAO,KACL;GAAE;GAAY,OAAO;EAAkB,GACvC,0DACF;EACA,OAAO;CACT;CACA,OAAO,uBAAuB,SAAS,eAAe;AACxD;AAEA,eAAsB,cAAc,SAMf;CACnB,MAAM,cAAc,CAAC,eAAe,OAAO;CAC3C,IAAI,QAAQ,aAAa;EACvB,MAAM,QAAQ,yBAAyB;EACvC,IAAI,UAAU,MACZ,YAAY,KAAK,SAAS,kBAAkB,GAAG,OAAO;CAE1D;CACA,IAAI,gBAAgB,QAAQ,MAAM,GAChC,KAAK,MAAM,SAAS,QAAQ,QAC1B,YAAY,KAAK,WAAW,OAAO;CAIvC,OAAOA,WAAe;EACpB,WAAW,QAAQ;EACnB,WAAW,YAAY,QAAQ;EAC/B,OAAO,QAAQ;EACf;CACF,CAAC;AACH;AAEA,IAAa,YAAb,cAA+B,cAAc;CAC3C,MAAe,cACb,QAC+B;EAC/B,OAAO,MAAM,iBAAiB,OAAO,WAAW,EAAE;EAElD,MAAM,iBAAiB,MAAM,OAAO,gBAAgB,YAAY;GAC9D,YAAY,OAAO;GACnB,OAAO;GACP,cAAc,OAAO;GACrB,gBAAgB,CAAC,kBAAkB;EACrC,CAAC;EAED,MAAM,UAAU,SAAS,OAAO,OAAO,IACnC,CAAC,OAAO,OAAO,IACf,OAAO;;EAIX,IAAI,OAAO,SAAS;GAClB,MAAM,oBAAoB,QAAQ,EAAE,CAAC,MAAM,IAAI;GAC/C,kBAAkB,KAAK,OAAO;GAC9B,QAAQ,KAAK,kBAAkB,KAAK,IAAI;EAC1C;EAEA,MAAM,WAAW,gBAAgB,aAAa,iBAAiB;EAC/D,OAAO,UAAU;EACjB,OAAO,WAAW;GAChB,IAAI,OAAO,YAAY,CAAC,EAAA,CAAG,QACxB,YACC,CAAC,QAAQ,WAAW,kBAAkB,KACtC,CAAC,QAAQ,WAAW,YAAY,CACpC;GACA,oBAAoB,OAAO;GAC3B,cAAc;EAChB;EAKA,MAAM,eAAe,MAAMC,cAAkB,MAAM;EACnD,IAAI,cAAc;GAChB,MAAM,EAAE,cAAc;GACtB,IAAI,gBAYE;;QAAA,MAPqB,cAAc;KACrC,WAAW,OAAO;KAClB,cAAc,eAAe;KAC7B,OAAO,OAAO;KACd,aAAa,OAAO;IACtB,CAAC,GAEe;KACd,MAAM,aACJ,eAAe,UAAW,eAAe,iBAAkB,CAAC;KAC9D,MAAMC,iBACJ,OAAO,YACP,gBAAgB,UAAU,GAC1B,SACF;KACA,OAAO;IACT;UACK;IACL,OAAO,MAAM,8CAA8C;IAC3D,OAAO;GACT;EACF;EACA,OAAO;CACT;AACF;;;;;;;AAQA,SAAgB,gBAAgB,YAA4B;CAC1D,MAAM,YAAY,WAAW,YAAY,GAAG;CAC5C,MAAM,WAAW,SAAS,WAAW,MAAM,YAAY,CAAC,GAAG,EAAE;CAC7D,OAAO,GAAG,WAAW,MAAM,GAAG,YAAY,CAAC,IAAI,WAAW;AAC5D;;;;;;AAOA,SAAS,mBAA2B;CAClC,OAAO,IAAI,KAAK,WAAW,GAAG,MAAM;AACtC"}
@@ -11,7 +11,7 @@ function getMajor(version) {
11
11
  const options = getOptions(version);
12
12
  options.includePrerelease = true;
13
13
  const cleanerVersion = makeVersion(cleanedVersion, options);
14
- if (isString(cleanerVersion)) return Number(cleanerVersion.split(".")[0]);
14
+ if (isString(cleanerVersion)) return parseInt(cleanerVersion.split(".")[0], 10);
15
15
  return null;
16
16
  }
17
17
  function getMinor(version) {
@@ -19,7 +19,7 @@ function getMinor(version) {
19
19
  const options = getOptions(version);
20
20
  options.includePrerelease = true;
21
21
  const cleanerVersion = makeVersion(cleanedVersion, options);
22
- if (isString(cleanerVersion)) return Number(cleanerVersion.split(".")[1]);
22
+ if (isString(cleanerVersion)) return parseInt(cleanerVersion.split(".")[1], 10);
23
23
  return null;
24
24
  }
25
25
  function getPatch(version) {
@@ -29,7 +29,8 @@ function getPatch(version) {
29
29
  const cleanerVersion = makeVersion(cleanedVersion, options);
30
30
  if (isString(cleanerVersion)) {
31
31
  const newVersion = semver$1.valid(semver$1.coerce(cleanedVersion, { loose: false }), options);
32
- return Number(newVersion?.split(".")[2]);
32
+ /* v8 ignore next -- newVersion always has a patch segment once cleanerVersion is a valid, coercible semver string */
33
+ return parseInt(coerceString(newVersion).split(".")[2] ?? "", 10);
33
34
  }
34
35
  return null;
35
36
  }
@@ -1 +1 @@
1
- {"version":3,"file":"range.js","names":["semver"],"sources":["../../../../lib/modules/versioning/conan/range.ts"],"sourcesContent":["import { isString } from '@sindresorhus/is';\nimport * as semver from 'semver';\nimport type { SemVer } from 'semver-utils';\nimport { parseRange } from 'semver-utils';\nimport { logger } from '../../../logger/index.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { coerceString } from '../../../util/string.ts';\nimport type { NewValueConfig } from '../types.ts';\nimport {\n cleanVersion,\n containsOperators,\n getOptions,\n makeVersion,\n matchesWithOptions,\n} from './common.ts';\n\n// always include prereleases\nexport function getMajor(version: string): null | number {\n const cleanedVersion = cleanVersion(version);\n const options = getOptions(version);\n options.includePrerelease = true;\n const cleanerVersion = makeVersion(cleanedVersion, options);\n if (isString(cleanerVersion)) {\n return Number(cleanerVersion.split('.')[0]);\n }\n return null;\n}\n\n// always include prereleases\nexport function getMinor(version: string): null | number {\n const cleanedVersion = cleanVersion(version);\n const options = getOptions(version);\n options.includePrerelease = true;\n const cleanerVersion = makeVersion(cleanedVersion, options);\n if (isString(cleanerVersion)) {\n return Number(cleanerVersion.split('.')[1]);\n }\n return null;\n}\n\n// always include prereleases\nexport function getPatch(version: string): null | number {\n const cleanedVersion = cleanVersion(version);\n const options = getOptions(version);\n options.includePrerelease = true;\n const cleanerVersion = makeVersion(cleanedVersion, options);\n\n if (isString(cleanerVersion)) {\n const newVersion = semver.valid(\n semver.coerce(cleanedVersion, {\n loose: false,\n }),\n options,\n );\n return Number(newVersion?.split('.')[2]);\n }\n return null;\n}\n\nexport function fixParsedRange(range: string): any {\n const ordValues = [];\n\n // don't bump or'd single version values\n const originalSplit = range.split(' ');\n for (let i = 0; i < originalSplit.length; i += 1) {\n if (\n !containsOperators(originalSplit[i]) &&\n !originalSplit[i].includes('||')\n ) {\n if (i !== 0 && originalSplit[i - 1].includes('||')) {\n ordValues.push(`|| ${originalSplit[i]}`);\n } else if (i !== originalSplit.length && originalSplit[i + 1] === '||') {\n ordValues.push(`${originalSplit[i]} ||`);\n }\n } else {\n ordValues.push(originalSplit[i]);\n }\n }\n\n const parsedRange = parseRange(range);\n const cleanRange = range.replace(regEx(/([<=>^~])( )?/g), '');\n const splitRange = cleanRange.split(' ');\n const semverRange: SemVer[] = [];\n\n for (let i = 0; i < splitRange.length; i += 1) {\n if (!splitRange[i].includes('||')) {\n const splitVersion = splitRange[i].split('.');\n const major = splitVersion[0];\n const minor = splitVersion[1];\n const patch = splitVersion[2];\n const operator = ordValues[i].includes('||')\n ? '||'\n : parsedRange[i].operator;\n const NewSemVer: SemVer = {\n major,\n };\n\n let full = `${coerceString(operator)}${major}`;\n if (minor) {\n NewSemVer.minor = minor;\n full = `${full}.${minor}`;\n if (patch) {\n NewSemVer.patch = patch;\n full = `${full}.${patch}`;\n }\n }\n /* v8 ignore next -- a segment with no operator is only reachable when adjacent to `||`, which always makes `operator` truthy (`'||'`) above; any other bare segment throws earlier at ordValues[i] */\n if (operator) {\n NewSemVer.operator = operator;\n full = range.includes(`${operator} `)\n ? `${operator} ${full.replace(operator, '')}`\n : `${operator}${full.replace(operator, '')}`;\n }\n\n full = ordValues[i].includes('||') ? ordValues[i] : full;\n\n NewSemVer.semver = full;\n\n semverRange.push(NewSemVer);\n }\n }\n return semverRange;\n}\n\nexport function replaceRange({\n currentValue,\n newVersion,\n}: NewValueConfig): string {\n const parsedRange = parseRange(currentValue);\n const element = parsedRange.at(-1)!;\n const toVersionMajor = getMajor(newVersion);\n const toVersionMinor = getMinor(newVersion);\n const toVersionPatch = getPatch(newVersion);\n const suffix = semver.prerelease(newVersion)\n ? `-${String(semver.prerelease(newVersion)?.[0])}`\n : '';\n\n if (element.operator === '~>') {\n return `~> ${toVersionMajor}.${toVersionMinor}.0`;\n }\n if (element.operator === '=') {\n return `=${newVersion}`;\n }\n if (element.operator === '~') {\n if (suffix.length) {\n return `~${toVersionMajor}.${toVersionMinor}.${toVersionPatch}${suffix}`;\n }\n return `~${toVersionMajor}.${toVersionMinor}.0`;\n }\n if (element.operator === '<=') {\n let res;\n if (!!element.patch || suffix.length) {\n res = `<=${newVersion}`;\n } else if (element.minor) {\n res = `<=${toVersionMajor}.${toVersionMinor}`;\n } else {\n res = `<=${toVersionMajor}`;\n }\n if (currentValue.includes('<= ')) {\n res = res.replace('<=', '<= ');\n }\n return res;\n }\n if (element.operator === '<' && toVersionMajor) {\n let res;\n if (currentValue.endsWith('.0.0')) {\n const newMajor = toVersionMajor + 1;\n res = `<${newMajor}.0.0`;\n } else if (element.patch) {\n res = `<${semver.inc(newVersion, 'patch')}`;\n } else if (element.minor && toVersionMinor) {\n res = `<${toVersionMajor}.${toVersionMinor + 1}`;\n } else {\n res = `<${toVersionMajor + 1}`;\n }\n if (currentValue.includes('< ')) {\n res = res.replace(regEx(/</g), '< ');\n }\n return res;\n }\n if (element.operator === '>') {\n let res;\n if (currentValue.endsWith('.0.0') && toVersionMajor) {\n const newMajor = toVersionMajor + 1;\n res = `>${newMajor}.0.0`;\n } else if (element.patch) {\n res = `>${toVersionMajor}.${toVersionMinor}.${toVersionPatch}`;\n } else if (element.minor) {\n res = `>${toVersionMajor}.${toVersionMinor}`;\n } else {\n res = `>${toVersionMajor}`;\n }\n if (currentValue.includes('> ')) {\n res = res.replace(regEx(/</g), '> ');\n }\n return res;\n }\n if (!element.operator) {\n if (element.minor) {\n if (element.minor === 'x') {\n return `${toVersionMajor}.x`;\n }\n if (element.minor === '*') {\n return `${toVersionMajor}.*`;\n }\n if (element.patch === 'x') {\n return `${toVersionMajor}.${toVersionMinor}.x`;\n }\n if (element.patch === '*') {\n return `${toVersionMajor}.${toVersionMinor}.*`;\n }\n return `${newVersion}`;\n }\n return `${toVersionMajor}`;\n }\n return newVersion;\n}\n\nexport function widenRange(\n { currentValue, currentVersion, newVersion }: NewValueConfig,\n options: semver.Options,\n): string | null {\n const parsedRange = parseRange(currentValue);\n const element = parsedRange.at(-1)!;\n\n if (matchesWithOptions(newVersion, currentValue, options)) {\n return currentValue;\n }\n const newValue = replaceRange({\n currentValue,\n rangeStrategy: 'replace',\n currentVersion,\n newVersion,\n });\n if (element.operator?.startsWith('<')) {\n const splitCurrent = currentValue.split(element.operator);\n splitCurrent.pop();\n return splitCurrent.join(element.operator) + newValue;\n }\n if (parsedRange.length > 1) {\n const previousElement = parsedRange.at(-2)!;\n if (previousElement.operator === '-') {\n const splitCurrent = currentValue.split('-');\n splitCurrent.pop();\n return `${splitCurrent.join('-')}- ${newValue}`;\n }\n if (element.operator?.startsWith('>')) {\n logger.warn(`Complex ranges ending in greater than are not supported`);\n return null;\n }\n }\n return `${currentValue} || ${newValue}`;\n}\n\nexport function bumpRange(\n { currentValue, currentVersion, newVersion }: NewValueConfig,\n options: semver.Options,\n): string | null {\n if (!containsOperators(currentValue) && currentValue.includes('||')) {\n return widenRange(\n {\n currentValue,\n rangeStrategy: 'widen',\n currentVersion,\n newVersion,\n },\n options,\n );\n }\n const parsedRange = parseRange(currentValue);\n const element = parsedRange.at(-1)!;\n\n const toVersionMajor = getMajor(newVersion);\n const toVersionMinor = getMinor(newVersion);\n const suffix = semver.prerelease(newVersion)\n ? `-${String(semver.prerelease(newVersion)?.[0])}`\n : '';\n\n if (parsedRange.length === 1) {\n if (!element.operator) {\n return replaceRange({\n currentValue,\n rangeStrategy: 'replace',\n currentVersion,\n newVersion,\n });\n }\n if (element.operator.startsWith('~')) {\n const split = currentValue.split('.');\n if (suffix.length) {\n return `${element.operator}${newVersion}`;\n }\n if (split.length === 1) {\n // ~4\n return `${element.operator}${toVersionMajor}`;\n }\n if (split.length === 2) {\n // ~4.1\n return `${element.operator}${toVersionMajor}.${toVersionMinor}`;\n }\n return `${element.operator}${newVersion}`;\n }\n if (element.operator === '=') {\n return `=${newVersion}`;\n }\n if (element.operator === '>=') {\n return currentValue.includes('>= ')\n ? `>= ${newVersion}`\n : `>=${newVersion}`;\n }\n if (element.operator.startsWith('<')) {\n return currentValue;\n }\n } else {\n const newRange = fixParsedRange(currentValue);\n const versions = newRange.map((x: any) => {\n // don't bump or'd single version values\n if (x.operator === '||') {\n return x.semver;\n }\n /* v8 ignore next -- fixParsedRange only ever produces elements with `operator === '||'` (handled above) or a real comparator operator; a falsy, non-`||` operator would have already thrown inside fixParsedRange */\n if (x.operator) {\n const bumpedSubRange = bumpRange(\n {\n currentValue: x.semver,\n rangeStrategy: 'bump',\n currentVersion,\n newVersion,\n },\n options,\n );\n if (\n bumpedSubRange &&\n matchesWithOptions(newVersion, bumpedSubRange, options)\n ) {\n return bumpedSubRange;\n }\n }\n\n return replaceRange({\n currentValue: x.semver,\n rangeStrategy: 'replace',\n currentVersion,\n newVersion,\n });\n });\n return versions.filter((x: any) => x !== null && x !== '').join(' ');\n }\n logger.debug(\n `Unsupported range type for rangeStrategy=bump: ${currentValue}`,\n );\n return null;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"range.js","names":["semver"],"sources":["../../../../lib/modules/versioning/conan/range.ts"],"sourcesContent":["import { isString } from '@sindresorhus/is';\nimport * as semver from 'semver';\nimport type { SemVer } from 'semver-utils';\nimport { parseRange } from 'semver-utils';\nimport { logger } from '../../../logger/index.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { coerceString } from '../../../util/string.ts';\nimport type { NewValueConfig } from '../types.ts';\nimport {\n cleanVersion,\n containsOperators,\n getOptions,\n makeVersion,\n matchesWithOptions,\n} from './common.ts';\n\n// always include prereleases\nexport function getMajor(version: string): null | number {\n const cleanedVersion = cleanVersion(version);\n const options = getOptions(version);\n options.includePrerelease = true;\n const cleanerVersion = makeVersion(cleanedVersion, options);\n if (isString(cleanerVersion)) {\n return parseInt(cleanerVersion.split('.')[0], 10);\n }\n return null;\n}\n\n// always include prereleases\nexport function getMinor(version: string): null | number {\n const cleanedVersion = cleanVersion(version);\n const options = getOptions(version);\n options.includePrerelease = true;\n const cleanerVersion = makeVersion(cleanedVersion, options);\n if (isString(cleanerVersion)) {\n return parseInt(cleanerVersion.split('.')[1], 10);\n }\n return null;\n}\n\n// always include prereleases\nexport function getPatch(version: string): null | number {\n const cleanedVersion = cleanVersion(version);\n const options = getOptions(version);\n options.includePrerelease = true;\n const cleanerVersion = makeVersion(cleanedVersion, options);\n\n if (isString(cleanerVersion)) {\n const newVersion = semver.valid(\n semver.coerce(cleanedVersion, {\n loose: false,\n }),\n options,\n );\n /* v8 ignore next -- newVersion always has a patch segment once cleanerVersion is a valid, coercible semver string */\n return parseInt(coerceString(newVersion).split('.')[2] ?? '', 10);\n }\n return null;\n}\n\nexport function fixParsedRange(range: string): any {\n const ordValues = [];\n\n // don't bump or'd single version values\n const originalSplit = range.split(' ');\n for (let i = 0; i < originalSplit.length; i += 1) {\n if (\n !containsOperators(originalSplit[i]) &&\n !originalSplit[i].includes('||')\n ) {\n if (i !== 0 && originalSplit[i - 1].includes('||')) {\n ordValues.push(`|| ${originalSplit[i]}`);\n } else if (i !== originalSplit.length && originalSplit[i + 1] === '||') {\n ordValues.push(`${originalSplit[i]} ||`);\n }\n } else {\n ordValues.push(originalSplit[i]);\n }\n }\n\n const parsedRange = parseRange(range);\n const cleanRange = range.replace(regEx(/([<=>^~])( )?/g), '');\n const splitRange = cleanRange.split(' ');\n const semverRange: SemVer[] = [];\n\n for (let i = 0; i < splitRange.length; i += 1) {\n if (!splitRange[i].includes('||')) {\n const splitVersion = splitRange[i].split('.');\n const major = splitVersion[0];\n const minor = splitVersion[1];\n const patch = splitVersion[2];\n const operator = ordValues[i].includes('||')\n ? '||'\n : parsedRange[i].operator;\n const NewSemVer: SemVer = {\n major,\n };\n\n let full = `${coerceString(operator)}${major}`;\n if (minor) {\n NewSemVer.minor = minor;\n full = `${full}.${minor}`;\n if (patch) {\n NewSemVer.patch = patch;\n full = `${full}.${patch}`;\n }\n }\n /* v8 ignore next -- a segment with no operator is only reachable when adjacent to `||`, which always makes `operator` truthy (`'||'`) above; any other bare segment throws earlier at ordValues[i] */\n if (operator) {\n NewSemVer.operator = operator;\n full = range.includes(`${operator} `)\n ? `${operator} ${full.replace(operator, '')}`\n : `${operator}${full.replace(operator, '')}`;\n }\n\n full = ordValues[i].includes('||') ? ordValues[i] : full;\n\n NewSemVer.semver = full;\n\n semverRange.push(NewSemVer);\n }\n }\n return semverRange;\n}\n\nexport function replaceRange({\n currentValue,\n newVersion,\n}: NewValueConfig): string {\n const parsedRange = parseRange(currentValue);\n const element = parsedRange.at(-1)!;\n const toVersionMajor = getMajor(newVersion);\n const toVersionMinor = getMinor(newVersion);\n const toVersionPatch = getPatch(newVersion);\n const suffix = semver.prerelease(newVersion)\n ? `-${String(semver.prerelease(newVersion)?.[0])}`\n : '';\n\n if (element.operator === '~>') {\n return `~> ${toVersionMajor}.${toVersionMinor}.0`;\n }\n if (element.operator === '=') {\n return `=${newVersion}`;\n }\n if (element.operator === '~') {\n if (suffix.length) {\n return `~${toVersionMajor}.${toVersionMinor}.${toVersionPatch}${suffix}`;\n }\n return `~${toVersionMajor}.${toVersionMinor}.0`;\n }\n if (element.operator === '<=') {\n let res;\n if (!!element.patch || suffix.length) {\n res = `<=${newVersion}`;\n } else if (element.minor) {\n res = `<=${toVersionMajor}.${toVersionMinor}`;\n } else {\n res = `<=${toVersionMajor}`;\n }\n if (currentValue.includes('<= ')) {\n res = res.replace('<=', '<= ');\n }\n return res;\n }\n if (element.operator === '<' && toVersionMajor) {\n let res;\n if (currentValue.endsWith('.0.0')) {\n const newMajor = toVersionMajor + 1;\n res = `<${newMajor}.0.0`;\n } else if (element.patch) {\n res = `<${semver.inc(newVersion, 'patch')}`;\n } else if (element.minor && toVersionMinor) {\n res = `<${toVersionMajor}.${toVersionMinor + 1}`;\n } else {\n res = `<${toVersionMajor + 1}`;\n }\n if (currentValue.includes('< ')) {\n res = res.replace(regEx(/</g), '< ');\n }\n return res;\n }\n if (element.operator === '>') {\n let res;\n if (currentValue.endsWith('.0.0') && toVersionMajor) {\n const newMajor = toVersionMajor + 1;\n res = `>${newMajor}.0.0`;\n } else if (element.patch) {\n res = `>${toVersionMajor}.${toVersionMinor}.${toVersionPatch}`;\n } else if (element.minor) {\n res = `>${toVersionMajor}.${toVersionMinor}`;\n } else {\n res = `>${toVersionMajor}`;\n }\n if (currentValue.includes('> ')) {\n res = res.replace(regEx(/</g), '> ');\n }\n return res;\n }\n if (!element.operator) {\n if (element.minor) {\n if (element.minor === 'x') {\n return `${toVersionMajor}.x`;\n }\n if (element.minor === '*') {\n return `${toVersionMajor}.*`;\n }\n if (element.patch === 'x') {\n return `${toVersionMajor}.${toVersionMinor}.x`;\n }\n if (element.patch === '*') {\n return `${toVersionMajor}.${toVersionMinor}.*`;\n }\n return `${newVersion}`;\n }\n return `${toVersionMajor}`;\n }\n return newVersion;\n}\n\nexport function widenRange(\n { currentValue, currentVersion, newVersion }: NewValueConfig,\n options: semver.Options,\n): string | null {\n const parsedRange = parseRange(currentValue);\n const element = parsedRange.at(-1)!;\n\n if (matchesWithOptions(newVersion, currentValue, options)) {\n return currentValue;\n }\n const newValue = replaceRange({\n currentValue,\n rangeStrategy: 'replace',\n currentVersion,\n newVersion,\n });\n if (element.operator?.startsWith('<')) {\n const splitCurrent = currentValue.split(element.operator);\n splitCurrent.pop();\n return splitCurrent.join(element.operator) + newValue;\n }\n if (parsedRange.length > 1) {\n const previousElement = parsedRange.at(-2)!;\n if (previousElement.operator === '-') {\n const splitCurrent = currentValue.split('-');\n splitCurrent.pop();\n return `${splitCurrent.join('-')}- ${newValue}`;\n }\n if (element.operator?.startsWith('>')) {\n logger.warn(`Complex ranges ending in greater than are not supported`);\n return null;\n }\n }\n return `${currentValue} || ${newValue}`;\n}\n\nexport function bumpRange(\n { currentValue, currentVersion, newVersion }: NewValueConfig,\n options: semver.Options,\n): string | null {\n if (!containsOperators(currentValue) && currentValue.includes('||')) {\n return widenRange(\n {\n currentValue,\n rangeStrategy: 'widen',\n currentVersion,\n newVersion,\n },\n options,\n );\n }\n const parsedRange = parseRange(currentValue);\n const element = parsedRange.at(-1)!;\n\n const toVersionMajor = getMajor(newVersion);\n const toVersionMinor = getMinor(newVersion);\n const suffix = semver.prerelease(newVersion)\n ? `-${String(semver.prerelease(newVersion)?.[0])}`\n : '';\n\n if (parsedRange.length === 1) {\n if (!element.operator) {\n return replaceRange({\n currentValue,\n rangeStrategy: 'replace',\n currentVersion,\n newVersion,\n });\n }\n if (element.operator.startsWith('~')) {\n const split = currentValue.split('.');\n if (suffix.length) {\n return `${element.operator}${newVersion}`;\n }\n if (split.length === 1) {\n // ~4\n return `${element.operator}${toVersionMajor}`;\n }\n if (split.length === 2) {\n // ~4.1\n return `${element.operator}${toVersionMajor}.${toVersionMinor}`;\n }\n return `${element.operator}${newVersion}`;\n }\n if (element.operator === '=') {\n return `=${newVersion}`;\n }\n if (element.operator === '>=') {\n return currentValue.includes('>= ')\n ? `>= ${newVersion}`\n : `>=${newVersion}`;\n }\n if (element.operator.startsWith('<')) {\n return currentValue;\n }\n } else {\n const newRange = fixParsedRange(currentValue);\n const versions = newRange.map((x: any) => {\n // don't bump or'd single version values\n if (x.operator === '||') {\n return x.semver;\n }\n /* v8 ignore next -- fixParsedRange only ever produces elements with `operator === '||'` (handled above) or a real comparator operator; a falsy, non-`||` operator would have already thrown inside fixParsedRange */\n if (x.operator) {\n const bumpedSubRange = bumpRange(\n {\n currentValue: x.semver,\n rangeStrategy: 'bump',\n currentVersion,\n newVersion,\n },\n options,\n );\n if (\n bumpedSubRange &&\n matchesWithOptions(newVersion, bumpedSubRange, options)\n ) {\n return bumpedSubRange;\n }\n }\n\n return replaceRange({\n currentValue: x.semver,\n rangeStrategy: 'replace',\n currentVersion,\n newVersion,\n });\n });\n return versions.filter((x: any) => x !== null && x !== '').join(' ');\n }\n logger.debug(\n `Unsupported range type for rangeStrategy=bump: ${currentValue}`,\n );\n return null;\n}\n"],"mappings":"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"}
@@ -13,17 +13,17 @@ function isGreaterThan(version, other) {
13
13
  function getMajor(version) {
14
14
  const parts = getParts(version);
15
15
  if (parts === null) return null;
16
- return Number(parts.major.join("."));
16
+ return parseFloat(parts.major.join("."));
17
17
  }
18
18
  function getMinor(version) {
19
19
  const parts = getParts(version);
20
20
  if (parts === null || parts.minor.length === 0) return null;
21
- return Number(parts.minor.join("."));
21
+ return parseFloat(parts.minor.join("."));
22
22
  }
23
23
  function getPatch(version) {
24
24
  const parts = getParts(version);
25
25
  if (parts === null || parts.patch.length === 0) return null;
26
- return Number(`${parts.patch[0]}.${parts.patch.slice(1).join("")}`);
26
+ return parseFloat(`${parts.patch[0]}.${parts.patch.slice(1).join("")}`);
27
27
  }
28
28
  function matches(version, range) {
29
29
  const parsed = parseRange(range);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../../lib/modules/versioning/pvp/index.ts"],"sourcesContent":["import { isString } from '@sindresorhus/is';\nimport { logger } from '../../../logger/index.ts';\nimport type { RangeStrategy } from '../../../types/versioning.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport type { NewValueConfig, VersioningApi } from '../types.ts';\nimport { parseRange } from './range.ts';\nimport { compareIntArray, extractAllParts, getParts, plusOne } from './util.ts';\n\nexport const id = 'pvp';\nexport const displayName = 'Package Versioning Policy (Haskell)';\nexport const urls = [\n '[Haskell Package Versioning Policy](https://pvp.haskell.org)',\n];\nexport const supportsRanges = true;\nexport const supportedRangeStrategies: RangeStrategy[] = ['widen'];\n\nconst digitsAndDots = regEx(/^[\\d.]+$/);\n\nfunction isGreaterThan(version: string, other: string): boolean {\n const versionIntMajor = extractAllParts(version);\n const otherIntMajor = extractAllParts(other);\n if (versionIntMajor === null || otherIntMajor === null) {\n return false;\n }\n return compareIntArray(versionIntMajor, otherIntMajor) === 'gt';\n}\n\nfunction getMajor(version: string): number | null {\n // This basically can't be implemented correctly, since\n // 1.1 and 1.10 become equal when converted to float.\n // Consumers should use isSame instead.\n const parts = getParts(version);\n if (parts === null) {\n return null;\n }\n return Number(parts.major.join('.'));\n}\n\nfunction getMinor(version: string): number | null {\n const parts = getParts(version);\n if (parts === null || parts.minor.length === 0) {\n return null;\n }\n return Number(parts.minor.join('.'));\n}\n\nfunction getPatch(version: string): number | null {\n const parts = getParts(version);\n if (parts === null || parts.patch.length === 0) {\n return null;\n }\n return Number(`${parts.patch[0]}.${parts.patch.slice(1).join('')}`);\n}\n\nfunction matches(version: string, range: string): boolean {\n const parsed = parseRange(range);\n if (parsed === null) {\n return false;\n }\n const ver = extractAllParts(version);\n const lower = extractAllParts(parsed.lower);\n const upper = extractAllParts(parsed.upper);\n if (ver === null || lower === null || upper === null) {\n return false;\n }\n return (\n 'gt' === compareIntArray(upper, ver) &&\n ['eq', 'lt'].includes(compareIntArray(lower, ver))\n );\n}\n\nfunction satisfyingVersion(\n versions: string[],\n range: string,\n reverse: boolean,\n): string | null {\n const copy = versions.slice(0);\n copy.sort((a, b) => {\n const multiplier = reverse ? 1 : -1;\n return sortVersions(a, b) * multiplier;\n });\n const result = copy.find((v) => matches(v, range));\n return result ?? null;\n}\n\nfunction getSatisfyingVersion(\n versions: string[],\n range: string,\n): string | null {\n return satisfyingVersion(versions, range, false);\n}\n\nfunction minSatisfyingVersion(\n versions: string[],\n range: string,\n): string | null {\n return satisfyingVersion(versions, range, true);\n}\n\nfunction isLessThanRange(version: string, range: string): boolean {\n const parsed = parseRange(range);\n if (parsed === null) {\n return false;\n }\n const compos = extractAllParts(version);\n const lower = extractAllParts(parsed.lower);\n if (compos === null || lower === null) {\n return false;\n }\n return 'lt' === compareIntArray(compos, lower);\n}\n\nfunction getNewValue({\n currentValue,\n newVersion,\n rangeStrategy,\n}: NewValueConfig): string | null {\n if (rangeStrategy !== 'widen') {\n logger.info(\n { rangeStrategy, currentValue, newVersion },\n `PVP can't handle this range strategy.`,\n );\n return null;\n }\n const parsed = parseRange(currentValue);\n if (parsed === null) {\n logger.info(\n { currentValue, newVersion },\n 'could not parse PVP version range',\n );\n return null;\n }\n if (isLessThanRange(newVersion, currentValue)) {\n // ignore new releases in old release series\n return null;\n }\n if (matches(newVersion, currentValue)) {\n // the upper bound is already high enough\n return null;\n }\n const compos = getParts(newVersion);\n if (compos === null) {\n return null;\n }\n const majorPlusOne = plusOne(compos.major);\n // istanbul ignore next: since all versions that can be parsed, can also be bumped, this can never happen\n if (!matches(newVersion, `>=${parsed.lower} && <${majorPlusOne}`)) {\n logger.warn(\n { newVersion },\n \"Even though the major bound was bumped, the newVersion still isn't accepted.\",\n );\n return null;\n }\n return `>=${parsed.lower} && <${majorPlusOne}`;\n}\n\nfunction isSame(\n type: 'major' | 'minor' | 'patch',\n a: string,\n b: string,\n): boolean {\n const aParts = getParts(a);\n const bParts = getParts(b);\n if (aParts === null || bParts === null) {\n return false;\n }\n if (type === 'major') {\n return 'eq' === compareIntArray(aParts.major, bParts.major);\n }\n if (type === 'minor') {\n return 'eq' === compareIntArray(aParts.minor, bParts.minor);\n }\n return 'eq' === compareIntArray(aParts.patch, bParts.patch);\n}\n\nfunction subset(subRange: string, superRange: string): boolean | undefined {\n const sub = parseRange(subRange);\n const sup = parseRange(superRange);\n if (sub === null || sup === null) {\n return undefined;\n }\n const subLower = extractAllParts(sub.lower);\n const subUpper = extractAllParts(sub.upper);\n const supLower = extractAllParts(sup.lower);\n const supUpper = extractAllParts(sup.upper);\n if (\n subLower === null ||\n subUpper === null ||\n supLower === null ||\n supUpper === null\n ) {\n return undefined;\n }\n if ('lt' === compareIntArray(subLower, supLower)) {\n return false;\n }\n if ('gt' === compareIntArray(subUpper, supUpper)) {\n return false;\n }\n return true;\n}\n\nfunction isVersion(maybeRange: string | undefined | null): boolean {\n return isString(maybeRange) && parseRange(maybeRange) === null;\n}\n\nfunction isValid(ver: string): boolean {\n return extractAllParts(ver) !== null || parseRange(ver) !== null;\n}\n\nfunction isSingleVersion(range: string): boolean {\n const noSpaces = range.trim();\n return noSpaces.startsWith('==') && digitsAndDots.test(noSpaces.slice(2));\n}\n\nfunction equals(a: string, b: string): boolean {\n const aParts = extractAllParts(a);\n const bParts = extractAllParts(b);\n if (aParts === null || bParts === null) {\n return false;\n }\n return 'eq' === compareIntArray(aParts, bParts);\n}\n\nfunction sortVersions(a: string, b: string): number {\n if (equals(a, b)) {\n return 0;\n }\n return isGreaterThan(a, b) ? 1 : -1;\n}\n\nfunction isStable(_version: string): boolean {\n return true;\n}\n\nfunction isCompatible(_version: string): boolean {\n return true;\n}\n\nexport const api: VersioningApi = {\n isValid,\n isVersion,\n isStable,\n isCompatible,\n getMajor,\n getMinor,\n getPatch,\n isSingleVersion,\n sortVersions,\n equals,\n matches,\n getSatisfyingVersion,\n minSatisfyingVersion,\n isLessThanRange,\n isGreaterThan,\n getNewValue,\n isSame,\n subset,\n};\nexport default api;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../lib/modules/versioning/pvp/index.ts"],"sourcesContent":["import { isString } from '@sindresorhus/is';\nimport { logger } from '../../../logger/index.ts';\nimport type { RangeStrategy } from '../../../types/versioning.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport type { NewValueConfig, VersioningApi } from '../types.ts';\nimport { parseRange } from './range.ts';\nimport { compareIntArray, extractAllParts, getParts, plusOne } from './util.ts';\n\nexport const id = 'pvp';\nexport const displayName = 'Package Versioning Policy (Haskell)';\nexport const urls = [\n '[Haskell Package Versioning Policy](https://pvp.haskell.org)',\n];\nexport const supportsRanges = true;\nexport const supportedRangeStrategies: RangeStrategy[] = ['widen'];\n\nconst digitsAndDots = regEx(/^[\\d.]+$/);\n\nfunction isGreaterThan(version: string, other: string): boolean {\n const versionIntMajor = extractAllParts(version);\n const otherIntMajor = extractAllParts(other);\n if (versionIntMajor === null || otherIntMajor === null) {\n return false;\n }\n return compareIntArray(versionIntMajor, otherIntMajor) === 'gt';\n}\n\nfunction getMajor(version: string): number | null {\n // This basically can't be implemented correctly, since\n // 1.1 and 1.10 become equal when converted to float.\n // Consumers should use isSame instead.\n const parts = getParts(version);\n if (parts === null) {\n return null;\n }\n return parseFloat(parts.major.join('.'));\n}\n\nfunction getMinor(version: string): number | null {\n const parts = getParts(version);\n if (parts === null || parts.minor.length === 0) {\n return null;\n }\n return parseFloat(parts.minor.join('.'));\n}\n\nfunction getPatch(version: string): number | null {\n const parts = getParts(version);\n if (parts === null || parts.patch.length === 0) {\n return null;\n }\n return parseFloat(`${parts.patch[0]}.${parts.patch.slice(1).join('')}`);\n}\n\nfunction matches(version: string, range: string): boolean {\n const parsed = parseRange(range);\n if (parsed === null) {\n return false;\n }\n const ver = extractAllParts(version);\n const lower = extractAllParts(parsed.lower);\n const upper = extractAllParts(parsed.upper);\n if (ver === null || lower === null || upper === null) {\n return false;\n }\n return (\n 'gt' === compareIntArray(upper, ver) &&\n ['eq', 'lt'].includes(compareIntArray(lower, ver))\n );\n}\n\nfunction satisfyingVersion(\n versions: string[],\n range: string,\n reverse: boolean,\n): string | null {\n const copy = versions.slice(0);\n copy.sort((a, b) => {\n const multiplier = reverse ? 1 : -1;\n return sortVersions(a, b) * multiplier;\n });\n const result = copy.find((v) => matches(v, range));\n return result ?? null;\n}\n\nfunction getSatisfyingVersion(\n versions: string[],\n range: string,\n): string | null {\n return satisfyingVersion(versions, range, false);\n}\n\nfunction minSatisfyingVersion(\n versions: string[],\n range: string,\n): string | null {\n return satisfyingVersion(versions, range, true);\n}\n\nfunction isLessThanRange(version: string, range: string): boolean {\n const parsed = parseRange(range);\n if (parsed === null) {\n return false;\n }\n const compos = extractAllParts(version);\n const lower = extractAllParts(parsed.lower);\n if (compos === null || lower === null) {\n return false;\n }\n return 'lt' === compareIntArray(compos, lower);\n}\n\nfunction getNewValue({\n currentValue,\n newVersion,\n rangeStrategy,\n}: NewValueConfig): string | null {\n if (rangeStrategy !== 'widen') {\n logger.info(\n { rangeStrategy, currentValue, newVersion },\n `PVP can't handle this range strategy.`,\n );\n return null;\n }\n const parsed = parseRange(currentValue);\n if (parsed === null) {\n logger.info(\n { currentValue, newVersion },\n 'could not parse PVP version range',\n );\n return null;\n }\n if (isLessThanRange(newVersion, currentValue)) {\n // ignore new releases in old release series\n return null;\n }\n if (matches(newVersion, currentValue)) {\n // the upper bound is already high enough\n return null;\n }\n const compos = getParts(newVersion);\n if (compos === null) {\n return null;\n }\n const majorPlusOne = plusOne(compos.major);\n // istanbul ignore next: since all versions that can be parsed, can also be bumped, this can never happen\n if (!matches(newVersion, `>=${parsed.lower} && <${majorPlusOne}`)) {\n logger.warn(\n { newVersion },\n \"Even though the major bound was bumped, the newVersion still isn't accepted.\",\n );\n return null;\n }\n return `>=${parsed.lower} && <${majorPlusOne}`;\n}\n\nfunction isSame(\n type: 'major' | 'minor' | 'patch',\n a: string,\n b: string,\n): boolean {\n const aParts = getParts(a);\n const bParts = getParts(b);\n if (aParts === null || bParts === null) {\n return false;\n }\n if (type === 'major') {\n return 'eq' === compareIntArray(aParts.major, bParts.major);\n }\n if (type === 'minor') {\n return 'eq' === compareIntArray(aParts.minor, bParts.minor);\n }\n return 'eq' === compareIntArray(aParts.patch, bParts.patch);\n}\n\nfunction subset(subRange: string, superRange: string): boolean | undefined {\n const sub = parseRange(subRange);\n const sup = parseRange(superRange);\n if (sub === null || sup === null) {\n return undefined;\n }\n const subLower = extractAllParts(sub.lower);\n const subUpper = extractAllParts(sub.upper);\n const supLower = extractAllParts(sup.lower);\n const supUpper = extractAllParts(sup.upper);\n if (\n subLower === null ||\n subUpper === null ||\n supLower === null ||\n supUpper === null\n ) {\n return undefined;\n }\n if ('lt' === compareIntArray(subLower, supLower)) {\n return false;\n }\n if ('gt' === compareIntArray(subUpper, supUpper)) {\n return false;\n }\n return true;\n}\n\nfunction isVersion(maybeRange: string | undefined | null): boolean {\n return isString(maybeRange) && parseRange(maybeRange) === null;\n}\n\nfunction isValid(ver: string): boolean {\n return extractAllParts(ver) !== null || parseRange(ver) !== null;\n}\n\nfunction isSingleVersion(range: string): boolean {\n const noSpaces = range.trim();\n return noSpaces.startsWith('==') && digitsAndDots.test(noSpaces.slice(2));\n}\n\nfunction equals(a: string, b: string): boolean {\n const aParts = extractAllParts(a);\n const bParts = extractAllParts(b);\n if (aParts === null || bParts === null) {\n return false;\n }\n return 'eq' === compareIntArray(aParts, bParts);\n}\n\nfunction sortVersions(a: string, b: string): number {\n if (equals(a, b)) {\n return 0;\n }\n return isGreaterThan(a, b) ? 1 : -1;\n}\n\nfunction isStable(_version: string): boolean {\n return true;\n}\n\nfunction isCompatible(_version: string): boolean {\n return true;\n}\n\nexport const api: VersioningApi = {\n isValid,\n isVersion,\n isStable,\n isCompatible,\n getMajor,\n getMinor,\n getPatch,\n isSingleVersion,\n sortVersions,\n equals,\n matches,\n getSatisfyingVersion,\n minSatisfyingVersion,\n isLessThanRange,\n isGreaterThan,\n getNewValue,\n isSame,\n subset,\n};\nexport default api;\n"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { GlobalConfig } from "../../config/global.js";
2
2
  import { logger } from "../../logger/index.js";
3
+ import { isNumber } from "@sindresorhus/is";
3
4
  import upath from "upath";
4
5
  import { parse } from "editorconfig";
5
6
  //#region lib/util/json-writer/editor-config.ts
@@ -24,8 +25,8 @@ var EditorConfig = class EditorConfig {
24
25
  if (indentStyle === "space") return "space";
25
26
  }
26
27
  static getIndentationSize(knownProps) {
27
- const indentSize = Number(knownProps.indent_size);
28
- if (!Number.isNaN(indentSize) && Number.isInteger(indentSize)) return indentSize;
28
+ const { indent_size: indentSize } = knownProps;
29
+ if (isNumber(indentSize) && Number.isInteger(indentSize)) return indentSize;
29
30
  }
30
31
  };
31
32
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"editor-config.js","names":[],"sources":["../../../lib/util/json-writer/editor-config.ts"],"sourcesContent":["import type { Props } from 'editorconfig';\nimport { parse } from 'editorconfig';\nimport upath from 'upath';\nimport { GlobalConfig } from '../../config/global.ts';\nimport { logger } from '../../logger/index.ts';\nimport type { CodeFormat } from './code-format.ts';\nimport type { IndentationType } from './indentation-type.ts';\n\nexport class EditorConfig {\n public static async getCodeFormat(fileName: string): Promise<CodeFormat> {\n const localDir = GlobalConfig.get('localDir');\n try {\n const knownProps = await parse(upath.join(localDir, fileName));\n return {\n indentationSize: EditorConfig.getIndentationSize(knownProps),\n indentationType: EditorConfig.getIndentationType(knownProps),\n maxLineLength: knownProps.max_line_length as number | 'off' | undefined,\n };\n } catch (err) {\n logger.warn({ err }, 'Failed to parse editor config');\n return {};\n }\n }\n\n private static getIndentationType(\n knownProps: Props,\n ): IndentationType | undefined {\n const { indent_style: indentStyle } = knownProps;\n\n if (indentStyle === 'tab') {\n return 'tab';\n }\n\n if (indentStyle === 'space') {\n return 'space';\n }\n\n return undefined;\n }\n\n private static getIndentationSize(knownProps: Props): number | undefined {\n const indentSize = Number(knownProps.indent_size);\n\n if (!Number.isNaN(indentSize) && Number.isInteger(indentSize)) {\n return indentSize;\n }\n\n return undefined;\n }\n}\n"],"mappings":";;;;;AAQA,IAAa,eAAb,MAAa,aAAa;CACxB,aAAoB,cAAc,UAAuC;EACvE,MAAM,WAAW,aAAa,IAAI,UAAU;EAC5C,IAAI;GACF,MAAM,aAAa,MAAM,MAAM,MAAM,KAAK,UAAU,QAAQ,CAAC;GAC7D,OAAO;IACL,iBAAiB,aAAa,mBAAmB,UAAU;IAC3D,iBAAiB,aAAa,mBAAmB,UAAU;IAC3D,eAAe,WAAW;GAC5B;EACF,SAAS,KAAK;GACZ,OAAO,KAAK,EAAE,IAAI,GAAG,+BAA+B;GACpD,OAAO,CAAC;EACV;CACF;CAEA,OAAe,mBACb,YAC6B;EAC7B,MAAM,EAAE,cAAc,gBAAgB;EAEtC,IAAI,gBAAgB,OAClB,OAAO;EAGT,IAAI,gBAAgB,SAClB,OAAO;CAIX;CAEA,OAAe,mBAAmB,YAAuC;EACvE,MAAM,aAAa,OAAO,WAAW,WAAW;EAEhD,IAAI,CAAC,OAAO,MAAM,UAAU,KAAK,OAAO,UAAU,UAAU,GAC1D,OAAO;CAIX;AACF"}
1
+ {"version":3,"file":"editor-config.js","names":[],"sources":["../../../lib/util/json-writer/editor-config.ts"],"sourcesContent":["import { isNumber } from '@sindresorhus/is';\nimport type { Props } from 'editorconfig';\nimport { parse } from 'editorconfig';\nimport upath from 'upath';\nimport { GlobalConfig } from '../../config/global.ts';\nimport { logger } from '../../logger/index.ts';\nimport type { CodeFormat } from './code-format.ts';\nimport type { IndentationType } from './indentation-type.ts';\n\nexport class EditorConfig {\n public static async getCodeFormat(fileName: string): Promise<CodeFormat> {\n const localDir = GlobalConfig.get('localDir');\n try {\n const knownProps = await parse(upath.join(localDir, fileName));\n return {\n indentationSize: EditorConfig.getIndentationSize(knownProps),\n indentationType: EditorConfig.getIndentationType(knownProps),\n maxLineLength: knownProps.max_line_length as number | 'off' | undefined,\n };\n } catch (err) {\n logger.warn({ err }, 'Failed to parse editor config');\n return {};\n }\n }\n\n private static getIndentationType(\n knownProps: Props,\n ): IndentationType | undefined {\n const { indent_style: indentStyle } = knownProps;\n\n if (indentStyle === 'tab') {\n return 'tab';\n }\n\n if (indentStyle === 'space') {\n return 'space';\n }\n\n return undefined;\n }\n\n private static getIndentationSize(knownProps: Props): number | undefined {\n const { indent_size: indentSize } = knownProps;\n\n if (isNumber(indentSize) && Number.isInteger(indentSize)) {\n return indentSize;\n }\n\n return undefined;\n }\n}\n"],"mappings":";;;;;;AASA,IAAa,eAAb,MAAa,aAAa;CACxB,aAAoB,cAAc,UAAuC;EACvE,MAAM,WAAW,aAAa,IAAI,UAAU;EAC5C,IAAI;GACF,MAAM,aAAa,MAAM,MAAM,MAAM,KAAK,UAAU,QAAQ,CAAC;GAC7D,OAAO;IACL,iBAAiB,aAAa,mBAAmB,UAAU;IAC3D,iBAAiB,aAAa,mBAAmB,UAAU;IAC3D,eAAe,WAAW;GAC5B;EACF,SAAS,KAAK;GACZ,OAAO,KAAK,EAAE,IAAI,GAAG,+BAA+B;GACpD,OAAO,CAAC;EACV;CACF;CAEA,OAAe,mBACb,YAC6B;EAC7B,MAAM,EAAE,cAAc,gBAAgB;EAEtC,IAAI,gBAAgB,OAClB,OAAO;EAGT,IAAI,gBAAgB,SAClB,OAAO;CAIX;CAEA,OAAe,mBAAmB,YAAuC;EACvE,MAAM,EAAE,aAAa,eAAe;EAEpC,IAAI,SAAS,UAAU,KAAK,OAAO,UAAU,UAAU,GACrD,OAAO;CAIX;AACF"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "renovate",
3
3
  "description": "Automated dependency updates. Flexible so you don't need to be.",
4
- "version": "44.46.2",
4
+ "version": "44.46.4",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "renovate": "dist/renovate.js",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$id": "https://docs.renovatebot.com/renovate-schema.json",
3
- "title": "JSON schema for Renovate 44.46.2 config files (https://renovatebot.com/)",
3
+ "title": "JSON schema for Renovate 44.46.4 config files (https://renovatebot.com/)",
4
4
  "$schema": "http://json-schema.org/draft-07/schema#",
5
- "x-renovate-version": "44.46.2",
5
+ "x-renovate-version": "44.46.4",
6
6
  "allowComments": true,
7
7
  "type": "object",
8
8
  "definitions": {