renovate 44.85.0 → 44.86.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/dist/constants/error-messages.d.ts +3 -2
  2. package/dist/constants/error-messages.js +3 -1
  3. package/dist/constants/error-messages.js.map +1 -1
  4. package/dist/modules/manager/apm/artifacts.js +2 -1
  5. package/dist/modules/manager/apm/artifacts.js.map +1 -1
  6. package/dist/modules/manager/bazel-module/artifacts.js +2 -1
  7. package/dist/modules/manager/bazel-module/artifacts.js.map +1 -1
  8. package/dist/modules/manager/bazelisk/artifacts.js +2 -1
  9. package/dist/modules/manager/bazelisk/artifacts.js.map +1 -1
  10. package/dist/modules/manager/bun/artifacts.js +2 -1
  11. package/dist/modules/manager/bun/artifacts.js.map +1 -1
  12. package/dist/modules/manager/bundler/artifacts.js +1 -1
  13. package/dist/modules/manager/bundler/artifacts.js.map +1 -1
  14. package/dist/modules/manager/bundler/common.js +11 -16
  15. package/dist/modules/manager/bundler/common.js.map +1 -1
  16. package/dist/modules/manager/cargo/artifacts.js +5 -3
  17. package/dist/modules/manager/cargo/artifacts.js.map +1 -1
  18. package/dist/modules/manager/composer/artifacts.js +6 -7
  19. package/dist/modules/manager/composer/artifacts.js.map +1 -1
  20. package/dist/modules/manager/composer/utils.js +1 -10
  21. package/dist/modules/manager/composer/utils.js.map +1 -1
  22. package/dist/modules/manager/conan/artifacts.js +2 -1
  23. package/dist/modules/manager/conan/artifacts.js.map +1 -1
  24. package/dist/modules/manager/copier/artifacts.js +3 -3
  25. package/dist/modules/manager/copier/artifacts.js.map +1 -1
  26. package/dist/modules/manager/deno/artifacts.js +2 -1
  27. package/dist/modules/manager/deno/artifacts.js.map +1 -1
  28. package/dist/modules/manager/devbox/artifacts.js +8 -5
  29. package/dist/modules/manager/devbox/artifacts.js.map +1 -1
  30. package/dist/modules/manager/fingerprint.generated.js +34 -34
  31. package/dist/modules/manager/fingerprint.generated.js.map +1 -1
  32. package/dist/modules/manager/github-actions/artifacts.js +6 -4
  33. package/dist/modules/manager/github-actions/artifacts.js.map +1 -1
  34. package/dist/modules/manager/gleam/artifacts.js +2 -1
  35. package/dist/modules/manager/gleam/artifacts.js.map +1 -1
  36. package/dist/modules/manager/gomod/artifacts.js +8 -6
  37. package/dist/modules/manager/gomod/artifacts.js.map +1 -1
  38. package/dist/modules/manager/gradle/artifacts.js +2 -1
  39. package/dist/modules/manager/gradle/artifacts.js.map +1 -1
  40. package/dist/modules/manager/gradle-wrapper/artifacts.js +2 -1
  41. package/dist/modules/manager/gradle-wrapper/artifacts.js.map +1 -1
  42. package/dist/modules/manager/helmfile/artifacts.js +4 -3
  43. package/dist/modules/manager/helmfile/artifacts.js.map +1 -1
  44. package/dist/modules/manager/helmv3/artifacts.js +2 -1
  45. package/dist/modules/manager/helmv3/artifacts.js.map +1 -1
  46. package/dist/modules/manager/jsonnet-bundler/artifacts.js +2 -1
  47. package/dist/modules/manager/jsonnet-bundler/artifacts.js.map +1 -1
  48. package/dist/modules/manager/kustomize/artifacts.js +4 -2
  49. package/dist/modules/manager/kustomize/artifacts.js.map +1 -1
  50. package/dist/modules/manager/kustomize/common.js +2 -2
  51. package/dist/modules/manager/kustomize/common.js.map +1 -1
  52. package/dist/modules/manager/maven-wrapper/artifacts.js +2 -1
  53. package/dist/modules/manager/maven-wrapper/artifacts.js.map +1 -1
  54. package/dist/modules/manager/mise/artifacts.js +13 -11
  55. package/dist/modules/manager/mise/artifacts.js.map +1 -1
  56. package/dist/modules/manager/mix/artifacts.js +3 -2
  57. package/dist/modules/manager/mix/artifacts.js.map +1 -1
  58. package/dist/modules/manager/nix/artifacts.js +2 -1
  59. package/dist/modules/manager/nix/artifacts.js.map +1 -1
  60. package/dist/modules/manager/npm/artifacts.js +2 -1
  61. package/dist/modules/manager/npm/artifacts.js.map +1 -1
  62. package/dist/modules/manager/npm/post-update/node-version.js +2 -1
  63. package/dist/modules/manager/npm/post-update/node-version.js.map +1 -1
  64. package/dist/modules/manager/npm/post-update/npm.js +2 -1
  65. package/dist/modules/manager/npm/post-update/npm.js.map +1 -1
  66. package/dist/modules/manager/npm/post-update/pnpm.js +2 -1
  67. package/dist/modules/manager/npm/post-update/pnpm.js.map +1 -1
  68. package/dist/modules/manager/npm/post-update/yarn.js +5 -3
  69. package/dist/modules/manager/npm/post-update/yarn.js.map +1 -1
  70. package/dist/modules/manager/nuget/artifacts.js +2 -1
  71. package/dist/modules/manager/nuget/artifacts.js.map +1 -1
  72. package/dist/modules/manager/pep621/processors/pdm.js +3 -2
  73. package/dist/modules/manager/pep621/processors/pdm.js.map +1 -1
  74. package/dist/modules/manager/pep621/processors/pixi.js +4 -3
  75. package/dist/modules/manager/pep621/processors/pixi.js.map +1 -1
  76. package/dist/modules/manager/pep621/processors/uv.js +3 -3
  77. package/dist/modules/manager/pep621/processors/uv.js.map +1 -1
  78. package/dist/modules/manager/pip-compile/common.js +14 -36
  79. package/dist/modules/manager/pip-compile/common.js.map +1 -1
  80. package/dist/modules/manager/pip_requirements/artifacts.js +3 -2
  81. package/dist/modules/manager/pip_requirements/artifacts.js.map +1 -1
  82. package/dist/modules/manager/pipenv/artifacts.js +3 -2
  83. package/dist/modules/manager/pipenv/artifacts.js.map +1 -1
  84. package/dist/modules/manager/pixi/artifacts.js +2 -1
  85. package/dist/modules/manager/pixi/artifacts.js.map +1 -1
  86. package/dist/modules/manager/poetry/artifacts.js +3 -2
  87. package/dist/modules/manager/poetry/artifacts.js.map +1 -1
  88. package/dist/modules/manager/pub/artifacts.js +11 -10
  89. package/dist/modules/manager/pub/artifacts.js.map +1 -1
  90. package/dist/modules/manager/types.d.ts +23 -3
  91. package/dist/modules/manager/util.js +28 -1
  92. package/dist/modules/manager/util.js.map +1 -1
  93. package/dist/modules/manager/vendir/artifacts.js +3 -2
  94. package/dist/modules/manager/vendir/artifacts.js.map +1 -1
  95. package/dist/modules/platform/gitlab/index.js +11 -3
  96. package/dist/modules/platform/gitlab/index.js.map +1 -1
  97. package/dist/workers/repository/error.js +5 -0
  98. package/dist/workers/repository/error.js.map +1 -1
  99. package/dist/workers/repository/process/lookup/index.js +2 -2
  100. package/dist/workers/repository/process/lookup/index.js.map +1 -1
  101. package/dist/workers/repository/updates/generate.js +11 -4
  102. package/dist/workers/repository/updates/generate.js.map +1 -1
  103. package/package.json +1 -1
  104. package/renovate-schema.json +2 -2
  105. package/dist/modules/manager/copier/utils.js +0 -24
  106. package/dist/modules/manager/copier/utils.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"pdm.js","names":[],"sources":["../../../../../lib/modules/manager/pep621/processors/pdm.ts"],"sourcesContent":["import { quote } from 'shlex';\nimport { TEMPORARY_ERROR } from '../../../../constants/error-messages.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport type {\n ExecOptions,\n ToolConstraint,\n} from '../../../../util/exec/types.ts';\nimport {\n getSiblingFileName,\n readLocalFile,\n} from '../../../../util/fs/index.ts';\nimport { withGitEnvironment } from '../../../../util/git/exec.ts';\nimport { Result } from '../../../../util/result.ts';\nimport { PypiDatasource } from '../../../datasource/pypi/index.ts';\nimport type {\n PackageDependency,\n UpdateArtifact,\n UpdateArtifactsResult,\n Upgrade,\n} from '../../types.ts';\nimport { PdmLockfile, type PyProject } from '../schema.ts';\nimport type { Pep621ManagerData } from '../types.ts';\nimport { depTypes } from '../utils.ts';\nimport { BasePyProjectProcessor } from './abstract.ts';\n\nconst pdmUpdateCMD = 'pdm update --no-sync --update-eager';\nconst gitExec = withGitEnvironment(['pep621']);\n\nexport class PdmProcessor extends BasePyProjectProcessor {\n override lockfileName = 'pdm.lock';\n\n process(\n project: PyProject,\n deps: PackageDependency[],\n ): PackageDependency<Pep621ManagerData>[] {\n const devDependencies = project.tool?.pdm?.devDependencies;\n if (devDependencies) {\n deps.push(...devDependencies);\n }\n\n const registryUrls = project.tool?.pdm?.registryUrls;\n if (registryUrls) {\n for (const dep of deps) {\n if (dep.datasource === PypiDatasource.id) {\n dep.registryUrls = registryUrls;\n }\n }\n }\n\n return deps;\n }\n\n async extractLockedVersions(\n project: PyProject,\n deps: PackageDependency[],\n packageFile: string,\n ): Promise<PackageDependency[]> {\n if (\n !project.tool?.pdm &&\n project['build-system']?.['build-backend'] !== 'pdm.backend'\n ) {\n return Promise.resolve(deps);\n }\n\n const lockFileName = getSiblingFileName(packageFile, 'pdm.lock');\n const lockFileContent = await readLocalFile(lockFileName, 'utf8');\n if (lockFileContent) {\n const lockFileMapping = Result.parse(\n lockFileContent,\n PdmLockfile.transform(({ lock }) => lock),\n ).unwrapOr({});\n\n for (const dep of deps) {\n const packageName = dep.packageName;\n if (packageName && packageName in lockFileMapping) {\n dep.lockedVersion = lockFileMapping[packageName];\n }\n }\n }\n\n return Promise.resolve(deps);\n }\n\n async updateArtifacts(\n updateArtifact: UpdateArtifact,\n project: PyProject,\n ): Promise<UpdateArtifactsResult[] | null> {\n const { config, updatedDeps, packageFileName } = updateArtifact;\n\n const { isLockFileMaintenance } = config;\n\n // abort if no lockfile is defined\n const lockFileName = getSiblingFileName(packageFileName, this.lockfileName);\n try {\n const existingLockFileContent = await readLocalFile(lockFileName, 'utf8');\n if (!existingLockFileContent) {\n logger.debug('No pdm.lock found');\n return null;\n }\n\n const pythonConstraint: ToolConstraint = {\n toolName: 'python',\n constraint:\n config.constraints?.python ?? project.project?.['requires-python'],\n };\n const pdmConstraint: ToolConstraint = {\n toolName: 'pdm',\n constraint: config.constraints?.pdm,\n };\n\n const execOptions: ExecOptions = {\n cwdFile: packageFileName,\n docker: {},\n toolConstraints: [pythonConstraint, pdmConstraint],\n };\n\n // on lockFileMaintenance do not specify any packages and update the complete lock file\n // else only update specific packages\n const cmds: string[] = [];\n if (isLockFileMaintenance) {\n cmds.push(pdmUpdateCMD);\n } else {\n cmds.push(...generateCMDs(updatedDeps));\n }\n await gitExec(cmds, execOptions);\n\n // check for changes\n const fileChanges: UpdateArtifactsResult[] = [];\n const newLockContent = await readLocalFile(lockFileName, 'utf8');\n const isLockFileChanged = existingLockFileContent !== newLockContent;\n if (isLockFileChanged) {\n fileChanges.push({\n file: {\n type: 'addition',\n path: lockFileName,\n contents: newLockContent,\n },\n });\n } else {\n logger.debug('pdm.lock is unchanged');\n }\n\n return fileChanges.length ? fileChanges : null;\n } catch (err) {\n if (err.message === TEMPORARY_ERROR) {\n throw err;\n }\n logger.debug({ err }, 'Failed to update PDM lock file');\n return [\n {\n artifactError: {\n fileName: lockFileName,\n stderr: err.message,\n },\n },\n ];\n }\n }\n}\n\nfunction generateCMDs(updatedDeps: Upgrade<Pep621ManagerData>[]): string[] {\n const cmds: string[] = [];\n const packagesByCMD: Record<string, string[]> = {};\n for (const dep of updatedDeps) {\n switch (dep.depType) {\n case depTypes.optionalDependencies: {\n if (!dep.managerData?.depGroup) {\n logger.once.warn(\n { dep: dep.depName },\n 'Unexpected optional dependency without group',\n );\n continue;\n }\n addPackageToCMDRecord(\n packagesByCMD,\n `${pdmUpdateCMD} -G ${quote(dep.managerData.depGroup)}`,\n dep.packageName!,\n );\n break;\n }\n case depTypes.dependencyGroups:\n case depTypes.pdmDevDependencies: {\n if (!dep.managerData?.depGroup) {\n logger.once.warn(\n { dep: dep.depName },\n 'Unexpected dev dependency without group',\n );\n continue;\n }\n addPackageToCMDRecord(\n packagesByCMD,\n `${pdmUpdateCMD} -dG ${quote(dep.managerData.depGroup)}`,\n dep.packageName!,\n );\n break;\n }\n case depTypes.buildSystemRequires:\n // build requirements are not locked in the lock files, no need to update.\n // Reference: https://github.com/pdm-project/pdm/discussions/2869\n break;\n default: {\n addPackageToCMDRecord(packagesByCMD, pdmUpdateCMD, dep.packageName!);\n }\n }\n }\n\n for (const commandPrefix in packagesByCMD) {\n const packageList = packagesByCMD[commandPrefix].map(quote).join(' ');\n const cmd = `${commandPrefix} ${packageList}`;\n cmds.push(cmd);\n }\n\n return cmds;\n}\n\nfunction addPackageToCMDRecord(\n packagesByCMD: Record<string, string[]>,\n commandPrefix: string,\n packageName: string,\n): void {\n if (!packagesByCMD[commandPrefix]) {\n packagesByCMD[commandPrefix] = [];\n }\n packagesByCMD[commandPrefix].push(packageName);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"pdm.js","names":[],"sources":["../../../../../lib/modules/manager/pep621/processors/pdm.ts"],"sourcesContent":["import { quote } from 'shlex';\nimport { TEMPORARY_ERROR } from '../../../../constants/error-messages.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport type {\n ExecOptions,\n ToolConstraint,\n} from '../../../../util/exec/types.ts';\nimport {\n getSiblingFileName,\n readLocalFile,\n} from '../../../../util/fs/index.ts';\nimport { withGitEnvironment } from '../../../../util/git/exec.ts';\nimport { Result } from '../../../../util/result.ts';\nimport { PypiDatasource } from '../../../datasource/pypi/index.ts';\nimport type {\n PackageDependency,\n UpdateArtifact,\n UpdateArtifactsResult,\n Upgrade,\n} from '../../types.ts';\nimport { resolveToolConstraint } from '../../util.ts';\nimport { PdmLockfile, type PyProject } from '../schema.ts';\nimport type { Pep621ManagerData } from '../types.ts';\nimport { depTypes } from '../utils.ts';\nimport { BasePyProjectProcessor } from './abstract.ts';\n\nconst pdmUpdateCMD = 'pdm update --no-sync --update-eager';\nconst gitExec = withGitEnvironment(['pep621']);\n\nexport class PdmProcessor extends BasePyProjectProcessor {\n override lockfileName = 'pdm.lock';\n\n process(\n project: PyProject,\n deps: PackageDependency[],\n ): PackageDependency<Pep621ManagerData>[] {\n const devDependencies = project.tool?.pdm?.devDependencies;\n if (devDependencies) {\n deps.push(...devDependencies);\n }\n\n const registryUrls = project.tool?.pdm?.registryUrls;\n if (registryUrls) {\n for (const dep of deps) {\n if (dep.datasource === PypiDatasource.id) {\n dep.registryUrls = registryUrls;\n }\n }\n }\n\n return deps;\n }\n\n async extractLockedVersions(\n project: PyProject,\n deps: PackageDependency[],\n packageFile: string,\n ): Promise<PackageDependency[]> {\n if (\n !project.tool?.pdm &&\n project['build-system']?.['build-backend'] !== 'pdm.backend'\n ) {\n return Promise.resolve(deps);\n }\n\n const lockFileName = getSiblingFileName(packageFile, 'pdm.lock');\n const lockFileContent = await readLocalFile(lockFileName, 'utf8');\n if (lockFileContent) {\n const lockFileMapping = Result.parse(\n lockFileContent,\n PdmLockfile.transform(({ lock }) => lock),\n ).unwrapOr({});\n\n for (const dep of deps) {\n const packageName = dep.packageName;\n if (packageName && packageName in lockFileMapping) {\n dep.lockedVersion = lockFileMapping[packageName];\n }\n }\n }\n\n return Promise.resolve(deps);\n }\n\n async updateArtifacts(\n updateArtifact: UpdateArtifact,\n project: PyProject,\n ): Promise<UpdateArtifactsResult[] | null> {\n const { config, updatedDeps, packageFileName } = updateArtifact;\n\n const { isLockFileMaintenance } = config;\n\n // abort if no lockfile is defined\n const lockFileName = getSiblingFileName(packageFileName, this.lockfileName);\n try {\n const existingLockFileContent = await readLocalFile(lockFileName, 'utf8');\n if (!existingLockFileContent) {\n logger.debug('No pdm.lock found');\n return null;\n }\n\n const pythonConstraint: ToolConstraint = {\n toolName: 'python',\n constraint: await resolveToolConstraint(\n config,\n 'python',\n () => project.project?.['requires-python'],\n ),\n };\n const pdmConstraint: ToolConstraint = {\n toolName: 'pdm',\n constraint: await resolveToolConstraint(config, 'pdm'),\n };\n\n const execOptions: ExecOptions = {\n cwdFile: packageFileName,\n docker: {},\n toolConstraints: [pythonConstraint, pdmConstraint],\n };\n\n // on lockFileMaintenance do not specify any packages and update the complete lock file\n // else only update specific packages\n const cmds: string[] = [];\n if (isLockFileMaintenance) {\n cmds.push(pdmUpdateCMD);\n } else {\n cmds.push(...generateCMDs(updatedDeps));\n }\n await gitExec(cmds, execOptions);\n\n // check for changes\n const fileChanges: UpdateArtifactsResult[] = [];\n const newLockContent = await readLocalFile(lockFileName, 'utf8');\n const isLockFileChanged = existingLockFileContent !== newLockContent;\n if (isLockFileChanged) {\n fileChanges.push({\n file: {\n type: 'addition',\n path: lockFileName,\n contents: newLockContent,\n },\n });\n } else {\n logger.debug('pdm.lock is unchanged');\n }\n\n return fileChanges.length ? fileChanges : null;\n } catch (err) {\n if (err.message === TEMPORARY_ERROR) {\n throw err;\n }\n logger.debug({ err }, 'Failed to update PDM lock file');\n return [\n {\n artifactError: {\n fileName: lockFileName,\n stderr: err.message,\n },\n },\n ];\n }\n }\n}\n\nfunction generateCMDs(updatedDeps: Upgrade<Pep621ManagerData>[]): string[] {\n const cmds: string[] = [];\n const packagesByCMD: Record<string, string[]> = {};\n for (const dep of updatedDeps) {\n switch (dep.depType) {\n case depTypes.optionalDependencies: {\n if (!dep.managerData?.depGroup) {\n logger.once.warn(\n { dep: dep.depName },\n 'Unexpected optional dependency without group',\n );\n continue;\n }\n addPackageToCMDRecord(\n packagesByCMD,\n `${pdmUpdateCMD} -G ${quote(dep.managerData.depGroup)}`,\n dep.packageName!,\n );\n break;\n }\n case depTypes.dependencyGroups:\n case depTypes.pdmDevDependencies: {\n if (!dep.managerData?.depGroup) {\n logger.once.warn(\n { dep: dep.depName },\n 'Unexpected dev dependency without group',\n );\n continue;\n }\n addPackageToCMDRecord(\n packagesByCMD,\n `${pdmUpdateCMD} -dG ${quote(dep.managerData.depGroup)}`,\n dep.packageName!,\n );\n break;\n }\n case depTypes.buildSystemRequires:\n // build requirements are not locked in the lock files, no need to update.\n // Reference: https://github.com/pdm-project/pdm/discussions/2869\n break;\n default: {\n addPackageToCMDRecord(packagesByCMD, pdmUpdateCMD, dep.packageName!);\n }\n }\n }\n\n for (const commandPrefix in packagesByCMD) {\n const packageList = packagesByCMD[commandPrefix].map(quote).join(' ');\n const cmd = `${commandPrefix} ${packageList}`;\n cmds.push(cmd);\n }\n\n return cmds;\n}\n\nfunction addPackageToCMDRecord(\n packagesByCMD: Record<string, string[]>,\n commandPrefix: string,\n packageName: string,\n): void {\n if (!packagesByCMD[commandPrefix]) {\n packagesByCMD[commandPrefix] = [];\n }\n packagesByCMD[commandPrefix].push(packageName);\n}\n"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { logger } from "../../../../logger/index.js";
2
2
  import { getSiblingFileName, localPathExists } from "../../../../util/fs/index.js";
3
+ import { resolveToolConstraint } from "../../util.js";
3
4
  import { BasePyProjectProcessor } from "./abstract.js";
4
5
  import { updatePixiLockfile } from "../../pixi/lockfile.js";
5
6
  //#region lib/modules/manager/pep621/processors/pixi.ts
@@ -16,9 +17,9 @@ var PixiProcessor = class extends BasePyProjectProcessor {
16
17
  logger.debug({ packageFile }, "No pixi.lock found");
17
18
  return [];
18
19
  }
19
- updateArtifacts({ config, updatedDeps, packageFileName }, project) {
20
- const constraint = config.constraints?.pixi ?? project.tool?.pixi?.["requires-pixi"];
21
- return updatePixiLockfile({
20
+ async updateArtifacts({ config, updatedDeps, packageFileName }, project) {
21
+ const constraint = await resolveToolConstraint(config, "pixi", () => project.tool?.pixi?.["requires-pixi"]);
22
+ return await updatePixiLockfile({
22
23
  packageFileName,
23
24
  updatedDeps,
24
25
  isLockFileMaintenance: config.isLockFileMaintenance,
@@ -1 +1 @@
1
- {"version":3,"file":"pixi.js","names":[],"sources":["../../../../../lib/modules/manager/pep621/processors/pixi.ts"],"sourcesContent":["import { logger } from '../../../../logger/index.ts';\nimport {\n getSiblingFileName,\n localPathExists,\n} from '../../../../util/fs/index.ts';\nimport { updatePixiLockfile } from '../../pixi/lockfile.ts';\nimport type {\n PackageDependency,\n UpdateArtifact,\n UpdateArtifactsResult,\n} from '../../types.ts';\nimport type { PyProject } from '../schema.ts';\nimport { BasePyProjectProcessor } from './abstract.ts';\n\nexport class PixiProcessor extends BasePyProjectProcessor {\n process(_project: PyProject, deps: PackageDependency[]): PackageDependency[] {\n return deps;\n }\n\n extractLockedVersions(\n _project: PyProject,\n deps: PackageDependency[],\n _packageFile: string,\n ): Promise<PackageDependency[]> {\n return Promise.resolve(deps);\n }\n\n override async getLockfiles(\n _project: PyProject,\n packageFile: string,\n ): Promise<string[]> {\n const lockfileName = getSiblingFileName(packageFile, 'pixi.lock');\n if (await localPathExists(lockfileName)) {\n return [lockfileName];\n }\n logger.debug({ packageFile }, 'No pixi.lock found');\n return [];\n }\n\n updateArtifacts(\n { config, updatedDeps, packageFileName }: UpdateArtifact,\n project: PyProject,\n ): Promise<UpdateArtifactsResult[] | null> {\n const constraint =\n config.constraints?.pixi ?? project.tool?.pixi?.['requires-pixi'];\n\n // The `pep621` manager has already written the updated package file, so\n // `newPackageFileContent` is intentionally left unset here.\n return updatePixiLockfile({\n packageFileName,\n updatedDeps,\n isLockFileMaintenance: config.isLockFileMaintenance,\n constraint,\n });\n }\n}\n"],"mappings":";;;;;AAcA,IAAa,gBAAb,cAAmC,uBAAuB;CACxD,QAAQ,UAAqB,MAAgD;EAC3E,OAAO;CACT;CAEA,sBACE,UACA,MACA,cAC8B;EAC9B,OAAO,QAAQ,QAAQ,IAAI;CAC7B;CAEA,MAAe,aACb,UACA,aACmB;EACnB,MAAM,eAAe,mBAAmB,aAAa,WAAW;EAChE,IAAI,MAAM,gBAAgB,YAAY,GACpC,OAAO,CAAC,YAAY;EAEtB,OAAO,MAAM,EAAE,YAAY,GAAG,oBAAoB;EAClD,OAAO,CAAC;CACV;CAEA,gBACE,EAAE,QAAQ,aAAa,mBACvB,SACyC;EACzC,MAAM,aACJ,OAAO,aAAa,QAAQ,QAAQ,MAAM,OAAO;EAInD,OAAO,mBAAmB;GACxB;GACA;GACA,uBAAuB,OAAO;GAC9B;EACF,CAAC;CACH;AACF"}
1
+ {"version":3,"file":"pixi.js","names":[],"sources":["../../../../../lib/modules/manager/pep621/processors/pixi.ts"],"sourcesContent":["import { logger } from '../../../../logger/index.ts';\nimport {\n getSiblingFileName,\n localPathExists,\n} from '../../../../util/fs/index.ts';\nimport { updatePixiLockfile } from '../../pixi/lockfile.ts';\nimport type {\n PackageDependency,\n UpdateArtifact,\n UpdateArtifactsResult,\n} from '../../types.ts';\nimport { resolveToolConstraint } from '../../util.ts';\nimport type { PyProject } from '../schema.ts';\nimport { BasePyProjectProcessor } from './abstract.ts';\n\nexport class PixiProcessor extends BasePyProjectProcessor {\n process(_project: PyProject, deps: PackageDependency[]): PackageDependency[] {\n return deps;\n }\n\n extractLockedVersions(\n _project: PyProject,\n deps: PackageDependency[],\n _packageFile: string,\n ): Promise<PackageDependency[]> {\n return Promise.resolve(deps);\n }\n\n override async getLockfiles(\n _project: PyProject,\n packageFile: string,\n ): Promise<string[]> {\n const lockfileName = getSiblingFileName(packageFile, 'pixi.lock');\n if (await localPathExists(lockfileName)) {\n return [lockfileName];\n }\n logger.debug({ packageFile }, 'No pixi.lock found');\n return [];\n }\n\n async updateArtifacts(\n { config, updatedDeps, packageFileName }: UpdateArtifact,\n project: PyProject,\n ): Promise<UpdateArtifactsResult[] | null> {\n const constraint = await resolveToolConstraint(\n config,\n 'pixi',\n () => project.tool?.pixi?.['requires-pixi'],\n );\n\n // The `pep621` manager has already written the updated package file, so\n // `newPackageFileContent` is intentionally left unset here.\n return await updatePixiLockfile({\n packageFileName,\n updatedDeps,\n isLockFileMaintenance: config.isLockFileMaintenance,\n constraint,\n });\n }\n}\n"],"mappings":";;;;;;AAeA,IAAa,gBAAb,cAAmC,uBAAuB;CACxD,QAAQ,UAAqB,MAAgD;EAC3E,OAAO;CACT;CAEA,sBACE,UACA,MACA,cAC8B;EAC9B,OAAO,QAAQ,QAAQ,IAAI;CAC7B;CAEA,MAAe,aACb,UACA,aACmB;EACnB,MAAM,eAAe,mBAAmB,aAAa,WAAW;EAChE,IAAI,MAAM,gBAAgB,YAAY,GACpC,OAAO,CAAC,YAAY;EAEtB,OAAO,MAAM,EAAE,YAAY,GAAG,oBAAoB;EAClD,OAAO,CAAC;CACV;CAEA,MAAM,gBACJ,EAAE,QAAQ,aAAa,mBACvB,SACyC;EACzC,MAAM,aAAa,MAAM,sBACvB,QACA,cACM,QAAQ,MAAM,OAAO,gBAC7B;EAIA,OAAO,MAAM,mBAAmB;GAC9B;GACA;GACA,uBAAuB,OAAO;GAC9B;EACF,CAAC;CACH;AACF"}
@@ -8,7 +8,7 @@ import { findLocalSiblingOrParent, readLocalFile } from "../../../../util/fs/ind
8
8
  import { Result } from "../../../../util/result.js";
9
9
  import { getGoogleAuthHostRule } from "../../../datasource/util.js";
10
10
  import { PypiDatasource } from "../../../datasource/pypi/index.js";
11
- import { applyGitSource } from "../../util.js";
11
+ import { applyGitSource, resolveToolConstraint } from "../../util.js";
12
12
  import { withGitEnvironment } from "../../../../util/git/exec.js";
13
13
  import { BasePyProjectProcessor } from "./abstract.js";
14
14
  import { depTypes } from "../utils.js";
@@ -96,11 +96,11 @@ var UvProcessor = class extends BasePyProjectProcessor {
96
96
  }
97
97
  const pythonConstraint = {
98
98
  toolName: "python",
99
- constraint: config.constraints?.python ?? project.project?.["requires-python"]
99
+ constraint: await resolveToolConstraint(config, "python", () => project.project?.["requires-python"])
100
100
  };
101
101
  const uvConstraint = {
102
102
  toolName: "uv",
103
- constraint: config.constraints?.uv ?? project.tool?.uv?.["required-version"]
103
+ constraint: await resolveToolConstraint(config, "uv", () => project.tool?.uv?.["required-version"])
104
104
  };
105
105
  const execOptions = {
106
106
  cwdFile: packageFileName,
@@ -1 +1 @@
1
- {"version":3,"file":"uv.js","names":[],"sources":["../../../../../lib/modules/manager/pep621/processors/uv.ts"],"sourcesContent":["import { isString } from '@sindresorhus/is';\nimport { quote } from 'shlex';\nimport { TEMPORARY_ERROR } from '../../../../constants/error-messages.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport type { HostRule } from '../../../../types/index.ts';\nimport { coerceArray } from '../../../../util/array.ts';\nimport type {\n ExecOptions,\n ToolConstraint,\n} from '../../../../util/exec/types.ts';\nimport {\n findLocalSiblingOrParent,\n readLocalFile,\n} from '../../../../util/fs/index.ts';\nimport { withGitEnvironment } from '../../../../util/git/exec.ts';\nimport { find } from '../../../../util/host-rules.ts';\nimport { regEx } from '../../../../util/regex.ts';\nimport { Result } from '../../../../util/result.ts';\nimport { parseUrl } from '../../../../util/url.ts';\nimport { PypiDatasource } from '../../../datasource/pypi/index.ts';\nimport { getGoogleAuthHostRule } from '../../../datasource/util.ts';\nimport type {\n PackageDependency,\n UpdateArtifact,\n UpdateArtifactsResult,\n Upgrade,\n} from '../../types.ts';\nimport { applyGitSource } from '../../util.ts';\nimport { type PyProject, UvLockfile, type UvSource } from '../schema.ts';\nimport { depTypes } from '../utils.ts';\nimport { BasePyProjectProcessor } from './abstract.ts';\n\nconst uvUpdateCMD = 'uv lock';\nconst gitExec = withGitEnvironment(['pep621']);\n\nfunction isUvIndexSource(\n source: UvSource,\n): source is Extract<UvSource, { index: string }> {\n return 'index' in source;\n}\n\nexport class UvProcessor extends BasePyProjectProcessor {\n override lockfileName = 'uv.lock';\n\n process(project: PyProject, deps: PackageDependency[]): PackageDependency[] {\n const uv = project.tool?.uv;\n if (!uv) {\n return deps;\n }\n\n const hasExplicitDefault = uv.index?.some(\n (index) => index.default && index.explicit,\n );\n const defaultIndex = uv.index?.find(\n (index) => index.default && !index.explicit,\n );\n const implicitIndexUrls = uv.index\n ?.filter((index) => !index.explicit && index.name !== defaultIndex?.name)\n ?.map(({ url }) => url);\n\n const devDependencies = uv['dev-dependencies'];\n if (devDependencies) {\n deps.push(...devDependencies);\n }\n\n // https://docs.astral.sh/uv/concepts/dependencies/#dependency-sources\n // Skip sources that do not make sense to handle (e.g. path).\n if (uv.sources || defaultIndex || implicitIndexUrls) {\n for (const dep of deps) {\n /* v8 ignore next -- needs test */\n if (!dep.packageName) {\n continue;\n }\n\n if (dep.depType === 'requires-python') {\n continue;\n }\n\n // Using `packageName` as it applies PEP 508 normalization, which is\n // also applied by uv when matching a source to a dependency.\n const depSources = uv.sources?.[dep.packageName];\n if (depSources) {\n // Dependency is pinned to one or more specific sources.\n dep.depType = depTypes.uvSources;\n if (depSources.every(isUvIndexSource)) {\n // Sources referencing an index, possibly disambiguated by\n // environment markers. Any of the indexes can serve the package,\n // so use all of them as registries.\n const registryUrls: string[] = [];\n for (const depSource of depSources) {\n const index = uv.index?.find(\n ({ name }) => name === depSource.index,\n );\n if (index) {\n registryUrls.push(index.url);\n }\n }\n if (registryUrls.length) {\n dep.registryUrls = [...new Set(registryUrls)];\n }\n } else if (depSources.length === 1) {\n const depSource = depSources[0];\n if ('git' in depSource) {\n applyGitSource(\n dep,\n depSource.git,\n depSource.rev,\n depSource.tag,\n depSource.branch,\n );\n } else if ('url' in depSource) {\n dep.skipReason = 'unsupported-url';\n } else if ('path' in depSource) {\n dep.skipReason = 'path-dependency';\n } else if ('workspace' in depSource) {\n dep.skipReason = 'inherited-dependency';\n } else {\n dep.skipReason = 'unknown-registry';\n }\n } else {\n // Multiple sources that are not all indexes (e.g. a git source\n // per platform) cannot be represented as a single update.\n dep.skipReason = 'unsupported';\n }\n } else {\n // Dependency is not pinned to a specific source, so we need to\n // determine the source based on the index configuration.\n if (hasExplicitDefault) {\n // don't fall back to pypi if there is an explicit default index\n dep.registryUrls = [];\n } else if (defaultIndex) {\n // There is a default index configured, so use it.\n dep.registryUrls = [defaultIndex.url];\n }\n\n if (implicitIndexUrls?.length) {\n // If there are implicit indexes, check them first and fall back\n // to the default.\n dep.registryUrls = implicitIndexUrls.concat(\n dep.registryUrls ?? PypiDatasource.defaultURL,\n );\n }\n }\n }\n }\n\n return deps;\n }\n\n async extractLockedVersions(\n project: PyProject,\n deps: PackageDependency[],\n packageFile: string,\n ): Promise<PackageDependency[]> {\n const lockFileName = await findLocalSiblingOrParent(\n packageFile,\n this.lockfileName,\n );\n if (lockFileName === null) {\n logger.debug({ packageFile }, `No uv lock file found`);\n } else {\n const lockFileContent = await readLocalFile(lockFileName, 'utf8');\n if (lockFileContent) {\n const { val: lockFileMapping, err } = Result.parse(\n lockFileContent,\n UvLockfile,\n ).unwrap();\n\n if (err) {\n logger.debug({ packageFile, err }, `Error parsing uv lock file`);\n } else {\n for (const dep of deps) {\n const packageName = dep.packageName;\n if (packageName && packageName in lockFileMapping) {\n dep.lockedVersion = lockFileMapping[packageName];\n }\n }\n }\n }\n }\n\n return Promise.resolve(deps);\n }\n\n async updateArtifacts(\n updateArtifact: UpdateArtifact,\n project: PyProject,\n ): Promise<UpdateArtifactsResult[] | null> {\n const { config, updatedDeps, packageFileName } = updateArtifact;\n\n const { isLockFileMaintenance } = config;\n\n // abort if no lockfile is defined\n const lockFileName = await findLocalSiblingOrParent(\n packageFileName,\n 'uv.lock',\n );\n if (lockFileName === null) {\n logger.debug({ packageFileName }, `No uv lock file found`);\n return null;\n }\n try {\n const existingLockFileContent = await readLocalFile(lockFileName, 'utf8');\n if (!existingLockFileContent) {\n logger.debug('No uv.lock found');\n return null;\n }\n\n const pythonConstraint: ToolConstraint = {\n toolName: 'python',\n constraint:\n config.constraints?.python ?? project.project?.['requires-python'],\n };\n const uvConstraint: ToolConstraint = {\n toolName: 'uv',\n constraint:\n config.constraints?.uv ?? project.tool?.uv?.['required-version'],\n };\n\n const extraEnv = {\n ...(await getUvExtraIndexUrl(project, updateArtifact.updatedDeps)),\n ...(await getUvIndexCredentials(project)),\n };\n const execOptions: ExecOptions = {\n cwdFile: packageFileName,\n extraEnv,\n docker: {},\n toolConstraints: [pythonConstraint, uvConstraint],\n };\n\n // on lockFileMaintenance do not specify any packages and update the complete lock file\n // else only update specific packages\n let cmd: string;\n if (isLockFileMaintenance) {\n cmd = `${uvUpdateCMD} --upgrade`;\n } else {\n cmd = generateCMD(updatedDeps);\n }\n await gitExec(cmd, execOptions);\n\n // check for changes\n const fileChanges: UpdateArtifactsResult[] = [];\n const newLockContent = await readLocalFile(lockFileName, 'utf8');\n const isLockFileChanged = existingLockFileContent !== newLockContent;\n if (isLockFileChanged) {\n fileChanges.push({\n file: {\n type: 'addition',\n path: lockFileName,\n contents: newLockContent,\n },\n });\n } else {\n logger.debug('uv.lock is unchanged');\n }\n\n return fileChanges.length ? fileChanges : null;\n } catch (err) {\n if (err.message === TEMPORARY_ERROR) {\n throw err;\n }\n logger.debug({ err }, 'Failed to update uv lock file');\n return [\n {\n artifactError: {\n fileName: lockFileName,\n stderr: err.message,\n },\n },\n ];\n }\n }\n}\n\nfunction generateCMD(updatedDeps: Upgrade[]): string {\n const deps: string[] = [];\n\n for (const dep of updatedDeps) {\n switch (dep.depType) {\n case depTypes.optionalDependencies: {\n deps.push(dep.depName!);\n break;\n }\n case depTypes.uvDevDependencies:\n case depTypes.uvSources: {\n deps.push(dep.depName!);\n break;\n }\n case depTypes.buildSystemRequires:\n // build requirements are not locked in the lock files, no need to update.\n break;\n default: {\n deps.push(dep.packageName!);\n }\n }\n }\n\n return `${uvUpdateCMD} ${deps.map((dep) => `--upgrade-package ${quote(dep)}`).join(' ')}`;\n}\n\nfunction getMatchingHostRule(url: string | undefined): HostRule {\n return find({ hostType: PypiDatasource.id, url });\n}\n\nasync function getUsernamePassword(\n url: URL,\n): Promise<{ username?: string; password?: string }> {\n const rule = getMatchingHostRule(url.toString());\n if (rule.username || rule.password) {\n return rule;\n }\n\n if (url.hostname.endsWith('.pkg.dev')) {\n const hostRule = await getGoogleAuthHostRule();\n if (hostRule) {\n return hostRule;\n }\n logger.once.debug({ url }, 'Could not get Google access token');\n }\n\n return {};\n}\n\nasync function getUvExtraIndexUrl(\n project: PyProject,\n deps: Upgrade[],\n): Promise<NodeJS.ProcessEnv> {\n const pyPiRegistryUrls = deps\n .filter((dep) => dep.datasource === PypiDatasource.id)\n .filter((dep) => {\n // Remove dependencies that are pinned to a specific index\n const sources = project.tool?.uv?.sources;\n const packageName = dep.packageName!;\n return !sources || !(packageName in sources);\n })\n .flatMap((dep) => dep.registryUrls)\n .filter(isString)\n .filter((registryUrl) => {\n // Check if the registry URL is not the default one and not already configured\n const configuredIndexUrls = coerceArray(\n project.tool?.uv?.index?.map(({ url }) => url),\n );\n return (\n registryUrl !== PypiDatasource.defaultURL &&\n !configuredIndexUrls.includes(registryUrl)\n );\n });\n\n const registryUrls = new Set(pyPiRegistryUrls);\n const extraIndexUrls: string[] = [];\n\n for (const registryUrl of registryUrls) {\n const parsedUrl = parseUrl(registryUrl);\n if (!parsedUrl) {\n continue;\n }\n\n const { username, password } = await getUsernamePassword(parsedUrl);\n if (username || password) {\n if (username) {\n parsedUrl.username = username;\n }\n if (password) {\n parsedUrl.password = password;\n }\n }\n\n extraIndexUrls.push(parsedUrl.toString());\n }\n\n return {\n UV_EXTRA_INDEX_URL: extraIndexUrls.join(' '),\n };\n}\n\nasync function getUvIndexCredentials(\n project: PyProject,\n): Promise<NodeJS.ProcessEnv> {\n const uv_indexes = project.tool?.uv?.index;\n\n if (!uv_indexes) {\n return {};\n }\n\n const entries = [];\n\n for (const { name, url } of uv_indexes) {\n const parsedUrl = parseUrl(url);\n /* v8 ignore next -- needs test */\n if (!parsedUrl) {\n continue;\n }\n\n // If no name is provided for the index, authentication information must be passed through alternative methods\n if (!name) {\n continue;\n }\n\n const { username, password } = await getUsernamePassword(parsedUrl);\n\n const NAME = name.toUpperCase().replace(regEx(/[^A-Z0-9]/g), '_');\n\n if (username) {\n entries.push([`UV_INDEX_${NAME}_USERNAME`, username]);\n }\n\n if (password) {\n entries.push([`UV_INDEX_${NAME}_PASSWORD`, password]);\n }\n }\n\n return Object.fromEntries(entries);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"uv.js","names":[],"sources":["../../../../../lib/modules/manager/pep621/processors/uv.ts"],"sourcesContent":["import { isString } from '@sindresorhus/is';\nimport { quote } from 'shlex';\nimport { TEMPORARY_ERROR } from '../../../../constants/error-messages.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport type { HostRule } from '../../../../types/index.ts';\nimport { coerceArray } from '../../../../util/array.ts';\nimport type {\n ExecOptions,\n ToolConstraint,\n} from '../../../../util/exec/types.ts';\nimport {\n findLocalSiblingOrParent,\n readLocalFile,\n} from '../../../../util/fs/index.ts';\nimport { withGitEnvironment } from '../../../../util/git/exec.ts';\nimport { find } from '../../../../util/host-rules.ts';\nimport { regEx } from '../../../../util/regex.ts';\nimport { Result } from '../../../../util/result.ts';\nimport { parseUrl } from '../../../../util/url.ts';\nimport { PypiDatasource } from '../../../datasource/pypi/index.ts';\nimport { getGoogleAuthHostRule } from '../../../datasource/util.ts';\nimport type {\n PackageDependency,\n UpdateArtifact,\n UpdateArtifactsResult,\n Upgrade,\n} from '../../types.ts';\nimport { applyGitSource, resolveToolConstraint } from '../../util.ts';\nimport { type PyProject, UvLockfile, type UvSource } from '../schema.ts';\nimport { depTypes } from '../utils.ts';\nimport { BasePyProjectProcessor } from './abstract.ts';\n\nconst uvUpdateCMD = 'uv lock';\nconst gitExec = withGitEnvironment(['pep621']);\n\nfunction isUvIndexSource(\n source: UvSource,\n): source is Extract<UvSource, { index: string }> {\n return 'index' in source;\n}\n\nexport class UvProcessor extends BasePyProjectProcessor {\n override lockfileName = 'uv.lock';\n\n process(project: PyProject, deps: PackageDependency[]): PackageDependency[] {\n const uv = project.tool?.uv;\n if (!uv) {\n return deps;\n }\n\n const hasExplicitDefault = uv.index?.some(\n (index) => index.default && index.explicit,\n );\n const defaultIndex = uv.index?.find(\n (index) => index.default && !index.explicit,\n );\n const implicitIndexUrls = uv.index\n ?.filter((index) => !index.explicit && index.name !== defaultIndex?.name)\n ?.map(({ url }) => url);\n\n const devDependencies = uv['dev-dependencies'];\n if (devDependencies) {\n deps.push(...devDependencies);\n }\n\n // https://docs.astral.sh/uv/concepts/dependencies/#dependency-sources\n // Skip sources that do not make sense to handle (e.g. path).\n if (uv.sources || defaultIndex || implicitIndexUrls) {\n for (const dep of deps) {\n /* v8 ignore next -- needs test */\n if (!dep.packageName) {\n continue;\n }\n\n if (dep.depType === 'requires-python') {\n continue;\n }\n\n // Using `packageName` as it applies PEP 508 normalization, which is\n // also applied by uv when matching a source to a dependency.\n const depSources = uv.sources?.[dep.packageName];\n if (depSources) {\n // Dependency is pinned to one or more specific sources.\n dep.depType = depTypes.uvSources;\n if (depSources.every(isUvIndexSource)) {\n // Sources referencing an index, possibly disambiguated by\n // environment markers. Any of the indexes can serve the package,\n // so use all of them as registries.\n const registryUrls: string[] = [];\n for (const depSource of depSources) {\n const index = uv.index?.find(\n ({ name }) => name === depSource.index,\n );\n if (index) {\n registryUrls.push(index.url);\n }\n }\n if (registryUrls.length) {\n dep.registryUrls = [...new Set(registryUrls)];\n }\n } else if (depSources.length === 1) {\n const depSource = depSources[0];\n if ('git' in depSource) {\n applyGitSource(\n dep,\n depSource.git,\n depSource.rev,\n depSource.tag,\n depSource.branch,\n );\n } else if ('url' in depSource) {\n dep.skipReason = 'unsupported-url';\n } else if ('path' in depSource) {\n dep.skipReason = 'path-dependency';\n } else if ('workspace' in depSource) {\n dep.skipReason = 'inherited-dependency';\n } else {\n dep.skipReason = 'unknown-registry';\n }\n } else {\n // Multiple sources that are not all indexes (e.g. a git source\n // per platform) cannot be represented as a single update.\n dep.skipReason = 'unsupported';\n }\n } else {\n // Dependency is not pinned to a specific source, so we need to\n // determine the source based on the index configuration.\n if (hasExplicitDefault) {\n // don't fall back to pypi if there is an explicit default index\n dep.registryUrls = [];\n } else if (defaultIndex) {\n // There is a default index configured, so use it.\n dep.registryUrls = [defaultIndex.url];\n }\n\n if (implicitIndexUrls?.length) {\n // If there are implicit indexes, check them first and fall back\n // to the default.\n dep.registryUrls = implicitIndexUrls.concat(\n dep.registryUrls ?? PypiDatasource.defaultURL,\n );\n }\n }\n }\n }\n\n return deps;\n }\n\n async extractLockedVersions(\n project: PyProject,\n deps: PackageDependency[],\n packageFile: string,\n ): Promise<PackageDependency[]> {\n const lockFileName = await findLocalSiblingOrParent(\n packageFile,\n this.lockfileName,\n );\n if (lockFileName === null) {\n logger.debug({ packageFile }, `No uv lock file found`);\n } else {\n const lockFileContent = await readLocalFile(lockFileName, 'utf8');\n if (lockFileContent) {\n const { val: lockFileMapping, err } = Result.parse(\n lockFileContent,\n UvLockfile,\n ).unwrap();\n\n if (err) {\n logger.debug({ packageFile, err }, `Error parsing uv lock file`);\n } else {\n for (const dep of deps) {\n const packageName = dep.packageName;\n if (packageName && packageName in lockFileMapping) {\n dep.lockedVersion = lockFileMapping[packageName];\n }\n }\n }\n }\n }\n\n return Promise.resolve(deps);\n }\n\n async updateArtifacts(\n updateArtifact: UpdateArtifact,\n project: PyProject,\n ): Promise<UpdateArtifactsResult[] | null> {\n const { config, updatedDeps, packageFileName } = updateArtifact;\n\n const { isLockFileMaintenance } = config;\n\n // abort if no lockfile is defined\n const lockFileName = await findLocalSiblingOrParent(\n packageFileName,\n 'uv.lock',\n );\n if (lockFileName === null) {\n logger.debug({ packageFileName }, `No uv lock file found`);\n return null;\n }\n try {\n const existingLockFileContent = await readLocalFile(lockFileName, 'utf8');\n if (!existingLockFileContent) {\n logger.debug('No uv.lock found');\n return null;\n }\n\n const pythonConstraint: ToolConstraint = {\n toolName: 'python',\n constraint: await resolveToolConstraint(\n config,\n 'python',\n () => project.project?.['requires-python'],\n ),\n };\n const uvConstraint: ToolConstraint = {\n toolName: 'uv',\n constraint: await resolveToolConstraint(\n config,\n 'uv',\n () => project.tool?.uv?.['required-version'],\n ),\n };\n\n const extraEnv = {\n ...(await getUvExtraIndexUrl(project, updateArtifact.updatedDeps)),\n ...(await getUvIndexCredentials(project)),\n };\n const execOptions: ExecOptions = {\n cwdFile: packageFileName,\n extraEnv,\n docker: {},\n toolConstraints: [pythonConstraint, uvConstraint],\n };\n\n // on lockFileMaintenance do not specify any packages and update the complete lock file\n // else only update specific packages\n let cmd: string;\n if (isLockFileMaintenance) {\n cmd = `${uvUpdateCMD} --upgrade`;\n } else {\n cmd = generateCMD(updatedDeps);\n }\n await gitExec(cmd, execOptions);\n\n // check for changes\n const fileChanges: UpdateArtifactsResult[] = [];\n const newLockContent = await readLocalFile(lockFileName, 'utf8');\n const isLockFileChanged = existingLockFileContent !== newLockContent;\n if (isLockFileChanged) {\n fileChanges.push({\n file: {\n type: 'addition',\n path: lockFileName,\n contents: newLockContent,\n },\n });\n } else {\n logger.debug('uv.lock is unchanged');\n }\n\n return fileChanges.length ? fileChanges : null;\n } catch (err) {\n if (err.message === TEMPORARY_ERROR) {\n throw err;\n }\n logger.debug({ err }, 'Failed to update uv lock file');\n return [\n {\n artifactError: {\n fileName: lockFileName,\n stderr: err.message,\n },\n },\n ];\n }\n }\n}\n\nfunction generateCMD(updatedDeps: Upgrade[]): string {\n const deps: string[] = [];\n\n for (const dep of updatedDeps) {\n switch (dep.depType) {\n case depTypes.optionalDependencies: {\n deps.push(dep.depName!);\n break;\n }\n case depTypes.uvDevDependencies:\n case depTypes.uvSources: {\n deps.push(dep.depName!);\n break;\n }\n case depTypes.buildSystemRequires:\n // build requirements are not locked in the lock files, no need to update.\n break;\n default: {\n deps.push(dep.packageName!);\n }\n }\n }\n\n return `${uvUpdateCMD} ${deps.map((dep) => `--upgrade-package ${quote(dep)}`).join(' ')}`;\n}\n\nfunction getMatchingHostRule(url: string | undefined): HostRule {\n return find({ hostType: PypiDatasource.id, url });\n}\n\nasync function getUsernamePassword(\n url: URL,\n): Promise<{ username?: string; password?: string }> {\n const rule = getMatchingHostRule(url.toString());\n if (rule.username || rule.password) {\n return rule;\n }\n\n if (url.hostname.endsWith('.pkg.dev')) {\n const hostRule = await getGoogleAuthHostRule();\n if (hostRule) {\n return hostRule;\n }\n logger.once.debug({ url }, 'Could not get Google access token');\n }\n\n return {};\n}\n\nasync function getUvExtraIndexUrl(\n project: PyProject,\n deps: Upgrade[],\n): Promise<NodeJS.ProcessEnv> {\n const pyPiRegistryUrls = deps\n .filter((dep) => dep.datasource === PypiDatasource.id)\n .filter((dep) => {\n // Remove dependencies that are pinned to a specific index\n const sources = project.tool?.uv?.sources;\n const packageName = dep.packageName!;\n return !sources || !(packageName in sources);\n })\n .flatMap((dep) => dep.registryUrls)\n .filter(isString)\n .filter((registryUrl) => {\n // Check if the registry URL is not the default one and not already configured\n const configuredIndexUrls = coerceArray(\n project.tool?.uv?.index?.map(({ url }) => url),\n );\n return (\n registryUrl !== PypiDatasource.defaultURL &&\n !configuredIndexUrls.includes(registryUrl)\n );\n });\n\n const registryUrls = new Set(pyPiRegistryUrls);\n const extraIndexUrls: string[] = [];\n\n for (const registryUrl of registryUrls) {\n const parsedUrl = parseUrl(registryUrl);\n if (!parsedUrl) {\n continue;\n }\n\n const { username, password } = await getUsernamePassword(parsedUrl);\n if (username || password) {\n if (username) {\n parsedUrl.username = username;\n }\n if (password) {\n parsedUrl.password = password;\n }\n }\n\n extraIndexUrls.push(parsedUrl.toString());\n }\n\n return {\n UV_EXTRA_INDEX_URL: extraIndexUrls.join(' '),\n };\n}\n\nasync function getUvIndexCredentials(\n project: PyProject,\n): Promise<NodeJS.ProcessEnv> {\n const uv_indexes = project.tool?.uv?.index;\n\n if (!uv_indexes) {\n return {};\n }\n\n const entries = [];\n\n for (const { name, url } of uv_indexes) {\n const parsedUrl = parseUrl(url);\n /* v8 ignore next -- needs test */\n if (!parsedUrl) {\n continue;\n }\n\n // If no name is provided for the index, authentication information must be passed through alternative methods\n if (!name) {\n continue;\n }\n\n const { username, password } = await getUsernamePassword(parsedUrl);\n\n const NAME = name.toUpperCase().replace(regEx(/[^A-Z0-9]/g), '_');\n\n if (username) {\n entries.push([`UV_INDEX_${NAME}_USERNAME`, username]);\n }\n\n if (password) {\n entries.push([`UV_INDEX_${NAME}_PASSWORD`, password]);\n }\n }\n\n return Object.fromEntries(entries);\n}\n"],"mappings":"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"}
@@ -5,59 +5,37 @@ import { parseUrl } from "../../../util/url.js";
5
5
  import { find } from "../../../util/host-rules.js";
6
6
  import { ensureLocalPath } from "../../../util/fs/util.js";
7
7
  import { ensureCacheDir } from "../../../util/fs/index.js";
8
- import { isString } from "@sindresorhus/is";
8
+ import { resolveToolConstraint } from "../util.js";
9
9
  import { split } from "shlex";
10
10
  import upath from "upath";
11
11
  //#region lib/modules/manager/pip-compile/common.ts
12
- function getPythonVersionConstraint(config, extractedPythonVersion) {
13
- const { constraints = {} } = config;
14
- const { python } = constraints;
15
- if (python) {
16
- logger.debug("Using python constraint from config");
17
- return python;
18
- }
19
- if (extractedPythonVersion) {
20
- logger.debug("Using python constraint extracted from the lock file");
21
- return `==${extractedPythonVersion}`;
22
- }
23
- }
24
- function getPipToolsVersionConstraint(config) {
25
- const { constraints = {} } = config;
26
- const { pipTools } = constraints;
27
- if (isString(pipTools)) {
28
- logger.debug("Using pipTools constraint from config");
29
- return pipTools;
30
- }
31
- return "";
32
- }
33
- function getUvVersionConstraint(config) {
34
- const { constraints = {} } = config;
35
- const { uv } = constraints;
36
- if (isString(uv)) {
37
- logger.debug("Using uv constraint from config");
38
- return uv;
39
- }
40
- return "";
12
+ async function getPythonVersionConstraint(config, extractedPythonVersion) {
13
+ return await resolveToolConstraint(config, "python", () => {
14
+ if (extractedPythonVersion) {
15
+ logger.debug("Using python constraint extracted from the lock file");
16
+ return `==${extractedPythonVersion}`;
17
+ }
18
+ });
41
19
  }
42
- function getToolVersionConstraint(config, commandType) {
20
+ async function getToolVersionConstraint(config, commandType) {
43
21
  if (commandType === "uv") return {
44
22
  toolName: "uv",
45
- constraint: getUvVersionConstraint(config)
23
+ constraint: await resolveToolConstraint(config, "uv")
46
24
  };
47
25
  return {
48
26
  toolName: "pip-tools",
49
- constraint: getPipToolsVersionConstraint(config)
27
+ constraint: await resolveToolConstraint(config, "pipTools")
50
28
  };
51
29
  }
52
30
  async function getExecOptions(config, commandType, cwd, extraEnv, extractedPythonVersion) {
53
- const constraint = getPythonVersionConstraint(config, extractedPythonVersion);
31
+ const constraint = await getPythonVersionConstraint(config, extractedPythonVersion);
54
32
  return {
55
33
  cwd: ensureLocalPath(cwd),
56
34
  docker: {},
57
35
  toolConstraints: [{
58
36
  toolName: "python",
59
37
  constraint
60
- }, getToolVersionConstraint(config, commandType)],
38
+ }, await getToolVersionConstraint(config, commandType)],
61
39
  extraEnv: {
62
40
  PIP_CACHE_DIR: await ensureCacheDir("pip"),
63
41
  PIP_NO_INPUT: "true",
@@ -266,6 +244,6 @@ function matchManager(filename) {
266
244
  return "unknown";
267
245
  }
268
246
  //#endregion
269
- export { allowedOptions, constraintLineRegex, disallowedPipOptions, extractHeaderCommand, extractPythonVersion, getExecOptions, getPipToolsVersionConstraint, getPythonVersionConstraint, getRegistryCredVarsFromPackageFiles, getToolVersionConstraint, getUvVersionConstraint, matchManager, optionsWithArguments };
247
+ export { allowedOptions, constraintLineRegex, disallowedPipOptions, extractHeaderCommand, extractPythonVersion, getExecOptions, getPythonVersionConstraint, getRegistryCredVarsFromPackageFiles, getToolVersionConstraint, matchManager, optionsWithArguments };
270
248
 
271
249
  //# sourceMappingURL=common.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"common.js","names":["hostRules.find"],"sources":["../../../../lib/modules/manager/pip-compile/common.ts"],"sourcesContent":["import { isString } from '@sindresorhus/is';\nimport { split } from 'shlex';\nimport upath from 'upath';\nimport { logger } from '../../../logger/index.ts';\nimport { coerceArray, isNotNullOrUndefined } from '../../../util/array.ts';\nimport type {\n ExecOptions,\n ExtraEnv,\n ToolConstraint,\n} from '../../../util/exec/types.ts';\nimport { ensureCacheDir } from '../../../util/fs/index.ts';\nimport { ensureLocalPath } from '../../../util/fs/util.ts';\nimport * as hostRules from '../../../util/host-rules.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { parseUrl } from '../../../util/url.ts';\nimport type { PackageFileContent, UpdateArtifactsConfig } from '../types.ts';\nimport type {\n CommandType,\n PipCompileArgs,\n SupportedManagers,\n} from './types.ts';\n\nexport function getPythonVersionConstraint(\n config: UpdateArtifactsConfig,\n extractedPythonVersion: string | undefined,\n): string | undefined | null {\n const { constraints = {} } = config;\n const { python } = constraints;\n\n if (python) {\n logger.debug('Using python constraint from config');\n return python;\n }\n\n if (extractedPythonVersion) {\n logger.debug('Using python constraint extracted from the lock file');\n return `==${extractedPythonVersion}`;\n }\n\n return undefined;\n}\n\nexport function getPipToolsVersionConstraint(\n config: UpdateArtifactsConfig,\n): string {\n const { constraints = {} } = config;\n const { pipTools } = constraints;\n\n if (isString(pipTools)) {\n logger.debug('Using pipTools constraint from config');\n return pipTools;\n }\n\n return '';\n}\n\nexport function getUvVersionConstraint(config: UpdateArtifactsConfig): string {\n const { constraints = {} } = config;\n const { uv } = constraints;\n\n if (isString(uv)) {\n logger.debug('Using uv constraint from config');\n return uv;\n }\n\n return '';\n}\n\nexport function getToolVersionConstraint(\n config: UpdateArtifactsConfig,\n commandType: CommandType,\n): ToolConstraint {\n if (commandType === 'uv') {\n return {\n toolName: 'uv',\n constraint: getUvVersionConstraint(config),\n };\n }\n\n return {\n toolName: 'pip-tools',\n constraint: getPipToolsVersionConstraint(config),\n };\n}\n\nexport async function getExecOptions(\n config: UpdateArtifactsConfig,\n commandType: CommandType,\n cwd: string,\n extraEnv: ExtraEnv<string>,\n extractedPythonVersion: string | undefined,\n): Promise<ExecOptions> {\n const constraint = getPythonVersionConstraint(config, extractedPythonVersion);\n const execOptions: ExecOptions = {\n cwd: ensureLocalPath(cwd),\n docker: {},\n toolConstraints: [\n {\n toolName: 'python',\n constraint,\n },\n getToolVersionConstraint(config, commandType),\n ],\n extraEnv: {\n PIP_CACHE_DIR: await ensureCacheDir('pip'),\n PIP_NO_INPUT: 'true', // ensure pip doesn't block forever waiting for credentials on stdin\n PIP_KEYRING_PROVIDER: 'import',\n PYTHON_KEYRING_BACKEND: 'keyrings.envvars.keyring.EnvvarsKeyring',\n ...extraEnv,\n },\n };\n return execOptions;\n}\n\nexport const constraintLineRegex = regEx(\n /^(?:#.*?\\r?\\n)+# {4}(?<command>\\S*)(?<arguments> .*?)?\\r?\\n/,\n);\n\nexport const disallowedPipOptions = [\n '--no-header', // header is required by this manager\n];\nconst commonOptionsWithArguments = [\n '--output-file',\n '--extra',\n '--extra-index-url',\n];\nconst pipOptionsWithArguments = [\n '--resolver',\n '--constraint',\n ...commonOptionsWithArguments,\n];\nconst uvOptionsWithArguments = [\n '--constraints',\n '--constraint', // singular alias accepted by uv\n '--python-version',\n '--no-emit-package',\n '--prerelease',\n '--format',\n '--resolution',\n '--fork-strategy',\n '--exclude-newer',\n '--exclude-newer-package',\n '--group',\n '--override',\n '--overrides',\n ...commonOptionsWithArguments,\n];\nexport const optionsWithArguments = [\n ...pipOptionsWithArguments,\n ...uvOptionsWithArguments,\n];\nconst allowedCommonOptions = [\n '-v',\n '--generate-hashes',\n '--emit-index-url',\n '--index-url',\n '--all-extras',\n];\nexport const allowedOptions: Record<CommandType, string[]> = {\n 'pip-compile': [\n '--allow-unsafe',\n '--generate-hashes',\n '--no-emit-index-url',\n '--strip-extras',\n ...allowedCommonOptions,\n ...pipOptionsWithArguments,\n ],\n uv: [\n '--no-strip-extras',\n '--universal',\n ...allowedCommonOptions,\n ...uvOptionsWithArguments,\n ],\n custom: [],\n};\n\n// TODO(not7cd): test on all correct headers, even with CUSTOM_COMPILE_COMMAND\nexport function extractHeaderCommand(\n content: string,\n fileName: string,\n): PipCompileArgs {\n const compileCommand = constraintLineRegex.exec(content);\n if (compileCommand?.groups === undefined) {\n throw new Error(\n `Failed to extract command from header in ${fileName} ${content}`,\n );\n }\n logger.trace(\n `pip-compile: found header in ${fileName}: \\n${compileCommand[0]}`,\n );\n const command = compileCommand.groups.command;\n const argv = [command];\n let commandType: CommandType;\n if (command === 'pip-compile') {\n commandType = 'pip-compile';\n } else if (command === 'uv') {\n commandType = 'uv';\n } else {\n commandType = 'custom';\n }\n if (compileCommand.groups.arguments) {\n argv.push(...split(compileCommand.groups.arguments));\n }\n logger.debug(\n { fileName, argv, commandType },\n `pip-compile: extracted command from header`,\n );\n\n const result: PipCompileArgs = {\n argv,\n command,\n commandType,\n outputFile: '',\n sourceFiles: [],\n };\n for (const arg of argv.slice(1)) {\n if (commandType === 'uv' && ['pip', 'compile'].includes(arg)) {\n continue;\n }\n // TODO(not7cd): check for \"--option -- argument\" case\n if (!arg.startsWith('-')) {\n result.sourceFiles.push(arg);\n continue;\n }\n throwForDisallowedOption(arg);\n throwForNoEqualSignInOptionWithArgument(arg);\n throwForUnknownOption(commandType, arg);\n\n if (arg.includes('=')) {\n const [option, value] = arg.split('=');\n if (option === '--extra') {\n result.extra = coerceArray(result.extra);\n result.extra.push(value);\n } else if (option === '--extra-index-url') {\n result.extraIndexUrl = coerceArray(result.extraIndexUrl);\n result.extraIndexUrl.push(value);\n // TODO: add to secrets? next PR\n } else if (['--constraint', '--constraints'].includes(option)) {\n result.constraintsFiles = coerceArray(result.constraintsFiles);\n result.constraintsFiles.push(value);\n } else if (['--override', '--overrides'].includes(option)) {\n result.overridesFiles = coerceArray(result.overridesFiles);\n result.overridesFiles.push(value);\n } else if (option === '--output-file') {\n if (result.outputFile) {\n throw new Error('Cannot use multiple --output-file options');\n }\n result.outputFile = upath.normalize(value);\n } else if (option === '--python-version') {\n result.pythonVersion = value;\n } else if (option === '--index-url') {\n if (result.indexUrl) {\n throw new Error('Cannot use multiple --index-url options');\n }\n result.indexUrl = value;\n // TODO: add to secrets? next PR\n } else {\n logger.debug({ option }, `pip-compile: option not handled`);\n }\n continue;\n }\n if (arg === '--no-emit-index-url') {\n result.noEmitIndexUrl = true;\n continue;\n }\n if (arg === '--emit-index-url') {\n result.emitIndexUrl = true;\n continue;\n }\n if (arg === '--all-extras') {\n result.allExtras = true;\n continue;\n }\n\n logger.debug({ option: arg }, `pip-compile: option not handled`);\n }\n logger.trace(\n {\n ...result,\n },\n 'Parsed pip-compile command from header',\n );\n if (result.noEmitIndexUrl && result.emitIndexUrl) {\n throw new Error('Cannot use both --no-emit-index-url and --emit-index-url');\n }\n if (result.sourceFiles.length === 0) {\n throw new Error(\n 'No source files detected in command, pass at least one package file explicitly',\n );\n }\n return result;\n}\n\nconst pythonVersionRegex = regEx(\n /^(?:#.*?\\r?\\n)*# This file is autogenerated by pip-compile with Python (?<pythonVersion>\\d+(?:\\.\\d+)*)\\s/,\n 'i',\n);\n\nexport function extractPythonVersion(\n content: string,\n fileName: string,\n): string | undefined {\n const match = pythonVersionRegex.exec(content);\n if (match?.groups === undefined) {\n logger.warn(\n { fileName, content },\n 'pip-compile: failed to extract Python version from header in file',\n );\n return undefined;\n }\n logger.trace(\n `pip-compile: found Python version header in ${fileName}: \\n${match[0]}`,\n );\n const { pythonVersion } = match.groups;\n logger.debug(\n { fileName, pythonVersion },\n `pip-compile: extracted Python version from header`,\n );\n return pythonVersion;\n}\n\nfunction throwForDisallowedOption(arg: string): void {\n if (disallowedPipOptions.includes(arg)) {\n throw new Error(`Option ${arg} not allowed for this manager`);\n }\n}\nfunction throwForNoEqualSignInOptionWithArgument(arg: string): void {\n if (optionsWithArguments.includes(arg)) {\n throw new Error(\n `Option ${arg} must have equal sign '=' separating it's argument`,\n );\n }\n}\nfunction throwForUnknownOption(commandType: CommandType, arg: string): void {\n if (arg.includes('=')) {\n const [option] = arg.split('=');\n if (allowedOptions[commandType].includes(option)) {\n return;\n }\n }\n if (allowedOptions[commandType].includes(arg)) {\n return;\n }\n throw new Error(`Option ${arg} not supported (yet)`);\n}\n\nfunction getRegistryCredEnvVars(\n url: URL,\n index: number,\n): Record<string, string> {\n const hostRule = hostRules.find({ url: url.href });\n logger.debug(hostRule, `Found host rule for url ${url.href}`);\n const ret: Record<string, string> = {};\n if (!!hostRule.username || !!hostRule.password) {\n ret[`KEYRING_SERVICE_NAME_${index}`] = url.hostname;\n ret[`KEYRING_SERVICE_USERNAME_${index}`] = hostRule.username ?? '';\n ret[`KEYRING_SERVICE_PASSWORD_${index}`] = hostRule.password ?? '';\n }\n return ret;\n}\n\nfunction cleanUrl(url: string): URL | null {\n // Strip everything but protocol, host, and port\n const urlObj = parseUrl(url);\n if (!urlObj) {\n return null;\n }\n // origin of a valid URL is always parseable\n return parseUrl(urlObj.origin);\n}\n\nexport function getRegistryCredVarsFromPackageFiles(\n packageFiles: PackageFileContent[],\n): ExtraEnv<string> {\n const urls: string[] = [];\n for (const packageFile of packageFiles) {\n urls.push(\n ...coerceArray(packageFile.registryUrls),\n ...coerceArray(packageFile.additionalRegistryUrls),\n );\n }\n logger.debug(urls, 'Extracted registry URLs from package files');\n\n const uniqueHosts = new Set<URL>(\n urls.map(cleanUrl).filter(isNotNullOrUndefined),\n );\n\n let allCreds: ExtraEnv<string> = {};\n for (const [index, host] of [...uniqueHosts].entries()) {\n const hostCreds = getRegistryCredEnvVars(host, index);\n allCreds = {\n ...allCreds,\n ...hostCreds,\n };\n }\n\n return allCreds;\n}\n\nexport function matchManager(filename: string): SupportedManagers | 'unknown' {\n if (filename.endsWith('setup.py')) {\n return 'pip_setup';\n }\n if (filename.endsWith('setup.cfg')) {\n return 'setup-cfg';\n }\n if (filename.endsWith('pyproject.toml')) {\n return 'pep621';\n }\n // naive, could be improved, maybe use pip_requirements.managerFilePatterns\n if (filename.endsWith('.in') || filename.endsWith('.txt')) {\n return 'pip_requirements';\n }\n return 'unknown';\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"common.js","names":["hostRules.find"],"sources":["../../../../lib/modules/manager/pip-compile/common.ts"],"sourcesContent":["import { split } from 'shlex';\nimport upath from 'upath';\nimport { logger } from '../../../logger/index.ts';\nimport { coerceArray, isNotNullOrUndefined } from '../../../util/array.ts';\nimport type {\n ExecOptions,\n ExtraEnv,\n ToolConstraint,\n} from '../../../util/exec/types.ts';\nimport { ensureCacheDir } from '../../../util/fs/index.ts';\nimport { ensureLocalPath } from '../../../util/fs/util.ts';\nimport * as hostRules from '../../../util/host-rules.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { parseUrl } from '../../../util/url.ts';\nimport type { PackageFileContent, UpdateArtifactsConfig } from '../types.ts';\nimport { resolveToolConstraint } from '../util.ts';\nimport type {\n CommandType,\n PipCompileArgs,\n SupportedManagers,\n} from './types.ts';\n\nexport async function getPythonVersionConstraint(\n config: UpdateArtifactsConfig,\n extractedPythonVersion: string | undefined,\n): Promise<string | undefined> {\n return await resolveToolConstraint(config, 'python', () => {\n if (extractedPythonVersion) {\n logger.debug('Using python constraint extracted from the lock file');\n return `==${extractedPythonVersion}`;\n }\n\n return undefined;\n });\n}\n\nexport async function getToolVersionConstraint(\n config: UpdateArtifactsConfig,\n commandType: CommandType,\n): Promise<ToolConstraint> {\n if (commandType === 'uv') {\n return {\n toolName: 'uv',\n constraint: await resolveToolConstraint(config, 'uv'),\n };\n }\n\n return {\n toolName: 'pip-tools',\n constraint: await resolveToolConstraint(config, 'pipTools'),\n };\n}\n\nexport async function getExecOptions(\n config: UpdateArtifactsConfig,\n commandType: CommandType,\n cwd: string,\n extraEnv: ExtraEnv<string>,\n extractedPythonVersion: string | undefined,\n): Promise<ExecOptions> {\n const constraint = await getPythonVersionConstraint(\n config,\n extractedPythonVersion,\n );\n const execOptions: ExecOptions = {\n cwd: ensureLocalPath(cwd),\n docker: {},\n toolConstraints: [\n {\n toolName: 'python',\n constraint,\n },\n await getToolVersionConstraint(config, commandType),\n ],\n extraEnv: {\n PIP_CACHE_DIR: await ensureCacheDir('pip'),\n PIP_NO_INPUT: 'true', // ensure pip doesn't block forever waiting for credentials on stdin\n PIP_KEYRING_PROVIDER: 'import',\n PYTHON_KEYRING_BACKEND: 'keyrings.envvars.keyring.EnvvarsKeyring',\n ...extraEnv,\n },\n };\n return execOptions;\n}\n\nexport const constraintLineRegex = regEx(\n /^(?:#.*?\\r?\\n)+# {4}(?<command>\\S*)(?<arguments> .*?)?\\r?\\n/,\n);\n\nexport const disallowedPipOptions = [\n '--no-header', // header is required by this manager\n];\nconst commonOptionsWithArguments = [\n '--output-file',\n '--extra',\n '--extra-index-url',\n];\nconst pipOptionsWithArguments = [\n '--resolver',\n '--constraint',\n ...commonOptionsWithArguments,\n];\nconst uvOptionsWithArguments = [\n '--constraints',\n '--constraint', // singular alias accepted by uv\n '--python-version',\n '--no-emit-package',\n '--prerelease',\n '--format',\n '--resolution',\n '--fork-strategy',\n '--exclude-newer',\n '--exclude-newer-package',\n '--group',\n '--override',\n '--overrides',\n ...commonOptionsWithArguments,\n];\nexport const optionsWithArguments = [\n ...pipOptionsWithArguments,\n ...uvOptionsWithArguments,\n];\nconst allowedCommonOptions = [\n '-v',\n '--generate-hashes',\n '--emit-index-url',\n '--index-url',\n '--all-extras',\n];\nexport const allowedOptions: Record<CommandType, string[]> = {\n 'pip-compile': [\n '--allow-unsafe',\n '--generate-hashes',\n '--no-emit-index-url',\n '--strip-extras',\n ...allowedCommonOptions,\n ...pipOptionsWithArguments,\n ],\n uv: [\n '--no-strip-extras',\n '--universal',\n ...allowedCommonOptions,\n ...uvOptionsWithArguments,\n ],\n custom: [],\n};\n\n// TODO(not7cd): test on all correct headers, even with CUSTOM_COMPILE_COMMAND\nexport function extractHeaderCommand(\n content: string,\n fileName: string,\n): PipCompileArgs {\n const compileCommand = constraintLineRegex.exec(content);\n if (compileCommand?.groups === undefined) {\n throw new Error(\n `Failed to extract command from header in ${fileName} ${content}`,\n );\n }\n logger.trace(\n `pip-compile: found header in ${fileName}: \\n${compileCommand[0]}`,\n );\n const command = compileCommand.groups.command;\n const argv = [command];\n let commandType: CommandType;\n if (command === 'pip-compile') {\n commandType = 'pip-compile';\n } else if (command === 'uv') {\n commandType = 'uv';\n } else {\n commandType = 'custom';\n }\n if (compileCommand.groups.arguments) {\n argv.push(...split(compileCommand.groups.arguments));\n }\n logger.debug(\n { fileName, argv, commandType },\n `pip-compile: extracted command from header`,\n );\n\n const result: PipCompileArgs = {\n argv,\n command,\n commandType,\n outputFile: '',\n sourceFiles: [],\n };\n for (const arg of argv.slice(1)) {\n if (commandType === 'uv' && ['pip', 'compile'].includes(arg)) {\n continue;\n }\n // TODO(not7cd): check for \"--option -- argument\" case\n if (!arg.startsWith('-')) {\n result.sourceFiles.push(arg);\n continue;\n }\n throwForDisallowedOption(arg);\n throwForNoEqualSignInOptionWithArgument(arg);\n throwForUnknownOption(commandType, arg);\n\n if (arg.includes('=')) {\n const [option, value] = arg.split('=');\n if (option === '--extra') {\n result.extra = coerceArray(result.extra);\n result.extra.push(value);\n } else if (option === '--extra-index-url') {\n result.extraIndexUrl = coerceArray(result.extraIndexUrl);\n result.extraIndexUrl.push(value);\n // TODO: add to secrets? next PR\n } else if (['--constraint', '--constraints'].includes(option)) {\n result.constraintsFiles = coerceArray(result.constraintsFiles);\n result.constraintsFiles.push(value);\n } else if (['--override', '--overrides'].includes(option)) {\n result.overridesFiles = coerceArray(result.overridesFiles);\n result.overridesFiles.push(value);\n } else if (option === '--output-file') {\n if (result.outputFile) {\n throw new Error('Cannot use multiple --output-file options');\n }\n result.outputFile = upath.normalize(value);\n } else if (option === '--python-version') {\n result.pythonVersion = value;\n } else if (option === '--index-url') {\n if (result.indexUrl) {\n throw new Error('Cannot use multiple --index-url options');\n }\n result.indexUrl = value;\n // TODO: add to secrets? next PR\n } else {\n logger.debug({ option }, `pip-compile: option not handled`);\n }\n continue;\n }\n if (arg === '--no-emit-index-url') {\n result.noEmitIndexUrl = true;\n continue;\n }\n if (arg === '--emit-index-url') {\n result.emitIndexUrl = true;\n continue;\n }\n if (arg === '--all-extras') {\n result.allExtras = true;\n continue;\n }\n\n logger.debug({ option: arg }, `pip-compile: option not handled`);\n }\n logger.trace(\n {\n ...result,\n },\n 'Parsed pip-compile command from header',\n );\n if (result.noEmitIndexUrl && result.emitIndexUrl) {\n throw new Error('Cannot use both --no-emit-index-url and --emit-index-url');\n }\n if (result.sourceFiles.length === 0) {\n throw new Error(\n 'No source files detected in command, pass at least one package file explicitly',\n );\n }\n return result;\n}\n\nconst pythonVersionRegex = regEx(\n /^(?:#.*?\\r?\\n)*# This file is autogenerated by pip-compile with Python (?<pythonVersion>\\d+(?:\\.\\d+)*)\\s/,\n 'i',\n);\n\nexport function extractPythonVersion(\n content: string,\n fileName: string,\n): string | undefined {\n const match = pythonVersionRegex.exec(content);\n if (match?.groups === undefined) {\n logger.warn(\n { fileName, content },\n 'pip-compile: failed to extract Python version from header in file',\n );\n return undefined;\n }\n logger.trace(\n `pip-compile: found Python version header in ${fileName}: \\n${match[0]}`,\n );\n const { pythonVersion } = match.groups;\n logger.debug(\n { fileName, pythonVersion },\n `pip-compile: extracted Python version from header`,\n );\n return pythonVersion;\n}\n\nfunction throwForDisallowedOption(arg: string): void {\n if (disallowedPipOptions.includes(arg)) {\n throw new Error(`Option ${arg} not allowed for this manager`);\n }\n}\nfunction throwForNoEqualSignInOptionWithArgument(arg: string): void {\n if (optionsWithArguments.includes(arg)) {\n throw new Error(\n `Option ${arg} must have equal sign '=' separating it's argument`,\n );\n }\n}\nfunction throwForUnknownOption(commandType: CommandType, arg: string): void {\n if (arg.includes('=')) {\n const [option] = arg.split('=');\n if (allowedOptions[commandType].includes(option)) {\n return;\n }\n }\n if (allowedOptions[commandType].includes(arg)) {\n return;\n }\n throw new Error(`Option ${arg} not supported (yet)`);\n}\n\nfunction getRegistryCredEnvVars(\n url: URL,\n index: number,\n): Record<string, string> {\n const hostRule = hostRules.find({ url: url.href });\n logger.debug(hostRule, `Found host rule for url ${url.href}`);\n const ret: Record<string, string> = {};\n if (!!hostRule.username || !!hostRule.password) {\n ret[`KEYRING_SERVICE_NAME_${index}`] = url.hostname;\n ret[`KEYRING_SERVICE_USERNAME_${index}`] = hostRule.username ?? '';\n ret[`KEYRING_SERVICE_PASSWORD_${index}`] = hostRule.password ?? '';\n }\n return ret;\n}\n\nfunction cleanUrl(url: string): URL | null {\n // Strip everything but protocol, host, and port\n const urlObj = parseUrl(url);\n if (!urlObj) {\n return null;\n }\n // origin of a valid URL is always parseable\n return parseUrl(urlObj.origin);\n}\n\nexport function getRegistryCredVarsFromPackageFiles(\n packageFiles: PackageFileContent[],\n): ExtraEnv<string> {\n const urls: string[] = [];\n for (const packageFile of packageFiles) {\n urls.push(\n ...coerceArray(packageFile.registryUrls),\n ...coerceArray(packageFile.additionalRegistryUrls),\n );\n }\n logger.debug(urls, 'Extracted registry URLs from package files');\n\n const uniqueHosts = new Set<URL>(\n urls.map(cleanUrl).filter(isNotNullOrUndefined),\n );\n\n let allCreds: ExtraEnv<string> = {};\n for (const [index, host] of [...uniqueHosts].entries()) {\n const hostCreds = getRegistryCredEnvVars(host, index);\n allCreds = {\n ...allCreds,\n ...hostCreds,\n };\n }\n\n return allCreds;\n}\n\nexport function matchManager(filename: string): SupportedManagers | 'unknown' {\n if (filename.endsWith('setup.py')) {\n return 'pip_setup';\n }\n if (filename.endsWith('setup.cfg')) {\n return 'setup-cfg';\n }\n if (filename.endsWith('pyproject.toml')) {\n return 'pep621';\n }\n // naive, could be improved, maybe use pip_requirements.managerFilePatterns\n if (filename.endsWith('.in') || filename.endsWith('.txt')) {\n return 'pip_requirements';\n }\n return 'unknown';\n}\n"],"mappings":"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"}
@@ -3,6 +3,7 @@ import { regEx } from "../../../util/regex.js";
3
3
  import { logger } from "../../../logger/index.js";
4
4
  import { ensureCacheDir, readLocalFile } from "../../../util/fs/index.js";
5
5
  import { exec } from "../../../util/exec/index.js";
6
+ import { resolveToolConstraint } from "../util.js";
6
7
  import { extrasPattern } from "./extract.js";
7
8
  import { isNonEmptyArray } from "@sindresorhus/is";
8
9
  import { quote } from "shlex";
@@ -48,10 +49,10 @@ async function updateArtifacts({ packageFileName, updatedDeps, newPackageFileCon
48
49
  docker: {},
49
50
  toolConstraints: [{
50
51
  toolName: "python",
51
- constraint: config.constraints?.python
52
+ constraint: await resolveToolConstraint(config, "python")
52
53
  }, {
53
54
  toolName: "hashin",
54
- constraint: config.constraints?.hashin
55
+ constraint: await resolveToolConstraint(config, "hashin")
55
56
  }],
56
57
  extraEnv: { PIP_CACHE_DIR: await ensureCacheDir("pip") }
57
58
  };
@@ -1 +1 @@
1
- {"version":3,"file":"artifacts.js","names":[],"sources":["../../../../lib/modules/manager/pip_requirements/artifacts.ts"],"sourcesContent":["import { isNonEmptyArray } from '@sindresorhus/is';\nimport { quote } from 'shlex';\nimport { TEMPORARY_ERROR } from '../../../constants/error-messages.ts';\nimport { logger } from '../../../logger/index.ts';\nimport { exec } from '../../../util/exec/index.ts';\nimport type { ExecOptions } from '../../../util/exec/types.ts';\nimport { ensureCacheDir, readLocalFile } from '../../../util/fs/index.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport type { UpdateArtifact, UpdateArtifactsResult } from '../types.ts';\nimport { extrasPattern } from './extract.ts';\n\n/**\n * Create a RegExp that matches the first dependency pattern for\n * the named dependency that is followed by package hashes.\n *\n * The regular expression defines a single named group `depConstraint`\n * that holds the dependency constraint without the hash specifiers.\n * The substring matched by this named group will start with the dependency\n * name and end with a non-whitespace character.\n *\n * @param depName the name of the dependency\n */\nfunction dependencyAndHashPattern(depName: string): RegExp {\n const escapedDepName = RegExp.escape(depName);\n\n // extrasPattern covers any whitespace between the dep name and the optional extras specifier,\n // but it does not cover any whitespace in front of the equal signs.\n //\n // Use a non-greedy wildcard for the range pattern; otherwise, we would\n // include all but the last hash specifier into depConstraint.\n return regEx(\n `^\\\\s*(?<depConstraint>${escapedDepName}${extrasPattern}\\\\s*==.*?\\\\S)\\\\s+--hash=`,\n 'm',\n );\n}\n\nexport async function updateArtifacts({\n packageFileName,\n updatedDeps,\n newPackageFileContent,\n config,\n}: UpdateArtifact): Promise<UpdateArtifactsResult[] | null> {\n logger.debug(`pip_requirements.updateArtifacts(${packageFileName})`);\n if (!isNonEmptyArray(updatedDeps)) {\n logger.debug('No updated pip_requirements deps - returning null');\n return null;\n }\n try {\n const cmd: string[] = [];\n const rewrittenContent = newPackageFileContent.replace(regEx(/\\\\\\n/g), '');\n for (const dep of updatedDeps) {\n if (!dep.depName) {\n continue;\n }\n const depAndHashMatch = dependencyAndHashPattern(dep.depName).exec(\n rewrittenContent,\n );\n if (depAndHashMatch) {\n // If there's a match, then the regular expression guarantees\n // that the named subgroup deepConstraint did match as well.\n const depConstraint = depAndHashMatch.groups!.depConstraint;\n cmd.push(`hashin ${quote(depConstraint)} -r ${quote(packageFileName)}`);\n }\n }\n if (!cmd.length) {\n logger.debug('No hashin commands to run - returning');\n return null;\n }\n const execOptions: ExecOptions = {\n cwdFile: '.',\n docker: {},\n toolConstraints: [\n { toolName: 'python', constraint: config.constraints?.python },\n { toolName: 'hashin', constraint: config.constraints?.hashin },\n ],\n extraEnv: {\n PIP_CACHE_DIR: await ensureCacheDir('pip'),\n },\n };\n await exec(cmd, execOptions);\n const newContent = await readLocalFile(packageFileName, 'utf8');\n if (newContent === newPackageFileContent) {\n logger.debug(`${packageFileName} is unchanged`);\n return null;\n }\n logger.debug(`Returning updated ${packageFileName}`);\n return [\n {\n file: {\n type: 'addition',\n path: packageFileName,\n contents: newContent,\n },\n },\n ];\n } catch (err) {\n // istanbul ignore if\n if (err.message === TEMPORARY_ERROR) {\n throw err;\n }\n logger.debug({ err }, `Failed to update ${packageFileName} file`);\n return [\n {\n artifactError: {\n fileName: packageFileName,\n stderr: `${String(err.stdout)}\\n${String(err.stderr)}`,\n },\n },\n ];\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAsBA,SAAS,yBAAyB,SAAyB;CACzD,MAAM,iBAAiB,OAAO,OAAO,OAAO;CAO5C,OAAO,MACL,yBAAyB,iBAAiB,cAAc,2BACxD,GACF;AACF;AAEA,eAAsB,gBAAgB,EACpC,iBACA,aACA,uBACA,UAC0D;CAC1D,OAAO,MAAM,oCAAoC,gBAAgB,EAAE;CACnE,IAAI,CAAC,gBAAgB,WAAW,GAAG;EACjC,OAAO,MAAM,mDAAmD;EAChE,OAAO;CACT;CACA,IAAI;EACF,MAAM,MAAgB,CAAC;EACvB,MAAM,mBAAmB,sBAAsB,QAAQ,MAAM,OAAO,GAAG,EAAE;EACzE,KAAK,MAAM,OAAO,aAAa;GAC7B,IAAI,CAAC,IAAI,SACP;GAEF,MAAM,kBAAkB,yBAAyB,IAAI,OAAO,CAAC,CAAC,KAC5D,gBACF;GACA,IAAI,iBAAiB;IAGnB,MAAM,gBAAgB,gBAAgB,OAAQ;IAC9C,IAAI,KAAK,UAAU,MAAM,aAAa,EAAE,MAAM,MAAM,eAAe,GAAG;GACxE;EACF;EACA,IAAI,CAAC,IAAI,QAAQ;GACf,OAAO,MAAM,uCAAuC;GACpD,OAAO;EACT;EACA,MAAM,cAA2B;GAC/B,SAAS;GACT,QAAQ,CAAC;GACT,iBAAiB,CACf;IAAE,UAAU;IAAU,YAAY,OAAO,aAAa;GAAO,GAC7D;IAAE,UAAU;IAAU,YAAY,OAAO,aAAa;GAAO,CAC/D;GACA,UAAU,EACR,eAAe,MAAM,eAAe,KAAK,EAC3C;EACF;EACA,MAAM,KAAK,KAAK,WAAW;EAC3B,MAAM,aAAa,MAAM,cAAc,iBAAiB,MAAM;EAC9D,IAAI,eAAe,uBAAuB;GACxC,OAAO,MAAM,GAAG,gBAAgB,cAAc;GAC9C,OAAO;EACT;EACA,OAAO,MAAM,qBAAqB,iBAAiB;EACnD,OAAO,CACL,EACE,MAAM;GACJ,MAAM;GACN,MAAM;GACN,UAAU;EACZ,EACF,CACF;CACF,SAAS,KAAK;;EAEZ,IAAI,IAAI,YAAA,mBACN,MAAM;EAER,OAAO,MAAM,EAAE,IAAI,GAAG,oBAAoB,gBAAgB,MAAM;EAChE,OAAO,CACL,EACE,eAAe;GACb,UAAU;GACV,QAAQ,GAAG,OAAO,IAAI,MAAM,EAAE,IAAI,OAAO,IAAI,MAAM;EACrD,EACF,CACF;CACF;AACF"}
1
+ {"version":3,"file":"artifacts.js","names":[],"sources":["../../../../lib/modules/manager/pip_requirements/artifacts.ts"],"sourcesContent":["import { isNonEmptyArray } from '@sindresorhus/is';\nimport { quote } from 'shlex';\nimport { TEMPORARY_ERROR } from '../../../constants/error-messages.ts';\nimport { logger } from '../../../logger/index.ts';\nimport { exec } from '../../../util/exec/index.ts';\nimport type { ExecOptions } from '../../../util/exec/types.ts';\nimport { ensureCacheDir, readLocalFile } from '../../../util/fs/index.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport type { UpdateArtifact, UpdateArtifactsResult } from '../types.ts';\nimport { resolveToolConstraint } from '../util.ts';\nimport { extrasPattern } from './extract.ts';\n\n/**\n * Create a RegExp that matches the first dependency pattern for\n * the named dependency that is followed by package hashes.\n *\n * The regular expression defines a single named group `depConstraint`\n * that holds the dependency constraint without the hash specifiers.\n * The substring matched by this named group will start with the dependency\n * name and end with a non-whitespace character.\n *\n * @param depName the name of the dependency\n */\nfunction dependencyAndHashPattern(depName: string): RegExp {\n const escapedDepName = RegExp.escape(depName);\n\n // extrasPattern covers any whitespace between the dep name and the optional extras specifier,\n // but it does not cover any whitespace in front of the equal signs.\n //\n // Use a non-greedy wildcard for the range pattern; otherwise, we would\n // include all but the last hash specifier into depConstraint.\n return regEx(\n `^\\\\s*(?<depConstraint>${escapedDepName}${extrasPattern}\\\\s*==.*?\\\\S)\\\\s+--hash=`,\n 'm',\n );\n}\n\nexport async function updateArtifacts({\n packageFileName,\n updatedDeps,\n newPackageFileContent,\n config,\n}: UpdateArtifact): Promise<UpdateArtifactsResult[] | null> {\n logger.debug(`pip_requirements.updateArtifacts(${packageFileName})`);\n if (!isNonEmptyArray(updatedDeps)) {\n logger.debug('No updated pip_requirements deps - returning null');\n return null;\n }\n try {\n const cmd: string[] = [];\n const rewrittenContent = newPackageFileContent.replace(regEx(/\\\\\\n/g), '');\n for (const dep of updatedDeps) {\n if (!dep.depName) {\n continue;\n }\n const depAndHashMatch = dependencyAndHashPattern(dep.depName).exec(\n rewrittenContent,\n );\n if (depAndHashMatch) {\n // If there's a match, then the regular expression guarantees\n // that the named subgroup deepConstraint did match as well.\n const depConstraint = depAndHashMatch.groups!.depConstraint;\n cmd.push(`hashin ${quote(depConstraint)} -r ${quote(packageFileName)}`);\n }\n }\n if (!cmd.length) {\n logger.debug('No hashin commands to run - returning');\n return null;\n }\n const execOptions: ExecOptions = {\n cwdFile: '.',\n docker: {},\n toolConstraints: [\n {\n toolName: 'python',\n constraint: await resolveToolConstraint(config, 'python'),\n },\n {\n toolName: 'hashin',\n constraint: await resolveToolConstraint(config, 'hashin'),\n },\n ],\n extraEnv: {\n PIP_CACHE_DIR: await ensureCacheDir('pip'),\n },\n };\n await exec(cmd, execOptions);\n const newContent = await readLocalFile(packageFileName, 'utf8');\n if (newContent === newPackageFileContent) {\n logger.debug(`${packageFileName} is unchanged`);\n return null;\n }\n logger.debug(`Returning updated ${packageFileName}`);\n return [\n {\n file: {\n type: 'addition',\n path: packageFileName,\n contents: newContent,\n },\n },\n ];\n } catch (err) {\n // istanbul ignore if\n if (err.message === TEMPORARY_ERROR) {\n throw err;\n }\n logger.debug({ err }, `Failed to update ${packageFileName} file`);\n return [\n {\n artifactError: {\n fileName: packageFileName,\n stderr: `${String(err.stdout)}\\n${String(err.stderr)}`,\n },\n },\n ];\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAuBA,SAAS,yBAAyB,SAAyB;CACzD,MAAM,iBAAiB,OAAO,OAAO,OAAO;CAO5C,OAAO,MACL,yBAAyB,iBAAiB,cAAc,2BACxD,GACF;AACF;AAEA,eAAsB,gBAAgB,EACpC,iBACA,aACA,uBACA,UAC0D;CAC1D,OAAO,MAAM,oCAAoC,gBAAgB,EAAE;CACnE,IAAI,CAAC,gBAAgB,WAAW,GAAG;EACjC,OAAO,MAAM,mDAAmD;EAChE,OAAO;CACT;CACA,IAAI;EACF,MAAM,MAAgB,CAAC;EACvB,MAAM,mBAAmB,sBAAsB,QAAQ,MAAM,OAAO,GAAG,EAAE;EACzE,KAAK,MAAM,OAAO,aAAa;GAC7B,IAAI,CAAC,IAAI,SACP;GAEF,MAAM,kBAAkB,yBAAyB,IAAI,OAAO,CAAC,CAAC,KAC5D,gBACF;GACA,IAAI,iBAAiB;IAGnB,MAAM,gBAAgB,gBAAgB,OAAQ;IAC9C,IAAI,KAAK,UAAU,MAAM,aAAa,EAAE,MAAM,MAAM,eAAe,GAAG;GACxE;EACF;EACA,IAAI,CAAC,IAAI,QAAQ;GACf,OAAO,MAAM,uCAAuC;GACpD,OAAO;EACT;EACA,MAAM,cAA2B;GAC/B,SAAS;GACT,QAAQ,CAAC;GACT,iBAAiB,CACf;IACE,UAAU;IACV,YAAY,MAAM,sBAAsB,QAAQ,QAAQ;GAC1D,GACA;IACE,UAAU;IACV,YAAY,MAAM,sBAAsB,QAAQ,QAAQ;GAC1D,CACF;GACA,UAAU,EACR,eAAe,MAAM,eAAe,KAAK,EAC3C;EACF;EACA,MAAM,KAAK,KAAK,WAAW;EAC3B,MAAM,aAAa,MAAM,cAAc,iBAAiB,MAAM;EAC9D,IAAI,eAAe,uBAAuB;GACxC,OAAO,MAAM,GAAG,gBAAgB,cAAc;GAC9C,OAAO;EACT;EACA,OAAO,MAAM,qBAAqB,iBAAiB;EACnD,OAAO,CACL,EACE,MAAM;GACJ,MAAM;GACN,MAAM;GACN,UAAU;EACZ,EACF,CACF;CACF,SAAS,KAAK;;EAEZ,IAAI,IAAI,YAAA,mBACN,MAAM;EAER,OAAO,MAAM,EAAE,IAAI,GAAG,oBAAoB,gBAAgB,MAAM;EAChE,OAAO,CACL,EACE,eAAe;GACb,UAAU;GACV,QAAQ,GAAG,OAAO,IAAI,MAAM,EAAE,IAAI,OAAO,IAAI,MAAM;EACrD,EACF,CACF;CACF;AACF"}
@@ -9,6 +9,7 @@ import { deleteLocalFile, ensureCacheDir, getParentDir, localPathExists, readLoc
9
9
  import { exec } from "../../../util/exec/index.js";
10
10
  import { getRepoStatus } from "../../../util/git/index.js";
11
11
  import { PypiDatasource } from "../../datasource/pypi/index.js";
12
+ import { resolveToolConstraint } from "../util.js";
12
13
  import { extractPackageFile } from "./extract.js";
13
14
  import { isNonEmptyStringAndNotWhitespace, isUrlInstance } from "@sindresorhus/is";
14
15
  import { pipenv } from "@renovatebot/detect-tools";
@@ -74,8 +75,8 @@ async function updateArtifacts({ packageFileName: pipfileName, newPackageFileCon
74
75
  if (config.isLockFileMaintenance) await deleteLocalFile(lockFileName);
75
76
  const cmd = "pipenv lock";
76
77
  const pipfileDir = getParentDir(ensureLocalPath(pipfileName));
77
- const tagConstraint = config.constraints?.python ?? await pipenv.getPythonConstraint(pipfileDir);
78
- const pipenvConstraint = config.constraints?.pipenv ?? await pipenv.getPipenvConstraint(pipfileDir);
78
+ const tagConstraint = await resolveToolConstraint(config, "python", () => pipenv.getPythonConstraint(pipfileDir));
79
+ const pipenvConstraint = await resolveToolConstraint(config, "pipenv", () => pipenv.getPipenvConstraint(pipfileDir));
79
80
  const extraEnv = {
80
81
  PIPENV_CACHE_DIR: await ensureCacheDir("pipenv"),
81
82
  PIP_CACHE_DIR: await ensureCacheDir("pip"),
@@ -1 +1 @@
1
- {"version":3,"file":"artifacts.js","names":["pipenvDetect"],"sources":["../../../../lib/modules/manager/pipenv/artifacts.ts"],"sourcesContent":["import { pipenv as pipenvDetect } from '@renovatebot/detect-tools';\nimport {\n isNonEmptyStringAndNotWhitespace,\n isUrlInstance,\n} from '@sindresorhus/is';\nimport { TEMPORARY_ERROR } from '../../../constants/error-messages.ts';\nimport { logger } from '../../../logger/index.ts';\nimport type { HostRule } from '../../../types/index.ts';\nimport { coerceArray } from '../../../util/array.ts';\nimport { exec } from '../../../util/exec/index.ts';\nimport type { ExecOptions, ExtraEnv, Opt } from '../../../util/exec/types.ts';\nimport {\n deleteLocalFile,\n ensureCacheDir,\n getParentDir,\n localPathExists,\n readLocalFile,\n writeLocalFile,\n} from '../../../util/fs/index.ts';\nimport { ensureLocalPath } from '../../../util/fs/util.ts';\nimport { getRepoStatus } from '../../../util/git/index.ts';\nimport { find } from '../../../util/host-rules.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { parseUrl } from '../../../util/url.ts';\nimport { PypiDatasource } from '../../datasource/pypi/index.ts';\nimport type { UpdateArtifact, UpdateArtifactsResult } from '../types.ts';\nimport { extractPackageFile } from './extract.ts';\n\nexport function getMatchingHostRule(url: string): HostRule | null {\n const parsedUrl = parseUrl(url);\n if (parsedUrl) {\n parsedUrl.username = '';\n parsedUrl.password = '';\n const urlWithoutCredentials = parsedUrl.toString();\n\n return find({ hostType: PypiDatasource.id, url: urlWithoutCredentials });\n }\n return null;\n}\n\nasync function findPipfileSourceUrlsWithCredentials(\n pipfileContent: string,\n pipfileName: string,\n): Promise<URL[]> {\n const pipfile = await extractPackageFile(pipfileContent, pipfileName);\n\n return coerceArray(\n pipfile?.registryUrls\n ?.map(parseUrl)\n .filter(isUrlInstance)\n .filter((url) => isNonEmptyStringAndNotWhitespace(url.username)),\n );\n}\n\n/**\n * This will extract the actual variable name from an environment-placeholder:\n * ${USERNAME:-defaultvalue} will yield 'USERNAME'\n */\nexport function extractEnvironmentVariableName(\n credential: string,\n): string | null {\n const match = regEx('([a-z0-9_]+)', 'i').exec(decodeURI(credential));\n return match?.length ? match[0] : null;\n}\n\nexport function addExtraEnvVariable(\n extraEnv: ExtraEnv,\n environmentVariableName: string,\n environmentValue: string,\n): void {\n logger.trace(\n `Adding ${environmentVariableName} environment variable for pipenv`,\n );\n if (\n extraEnv[environmentVariableName] &&\n extraEnv[environmentVariableName] !== environmentValue\n ) {\n logger.warn(\n { envVar: environmentVariableName },\n 'Possible misconfiguration, environment variable already set to a different value',\n );\n }\n extraEnv[environmentVariableName] = environmentValue;\n}\n\n/**\n * Pipenv allows configuring source-urls for remote repositories with placeholders for credentials, i.e. http://$USER:$PASS@myprivate.repo\n * if a matching host rule exists for that repository, we need to set the corresponding variables.\n * Simply substituting them in the URL is not an option as it would impact the hash for the resulting Pipfile.lock\n *\n */\nasync function addCredentialsForSourceUrls(\n newPipfileContent: string,\n pipfileName: string,\n extraEnv: ExtraEnv,\n): Promise<void> {\n const sourceUrls = await findPipfileSourceUrlsWithCredentials(\n newPipfileContent,\n pipfileName,\n );\n for (const parsedSourceUrl of sourceUrls) {\n logger.trace(`Trying to add credentials for ${parsedSourceUrl.toString()}`);\n const matchingHostRule = getMatchingHostRule(parsedSourceUrl.toString());\n if (matchingHostRule) {\n const usernameVariableName = extractEnvironmentVariableName(\n parsedSourceUrl.username,\n );\n if (matchingHostRule.username && usernameVariableName) {\n addExtraEnvVariable(\n extraEnv,\n usernameVariableName,\n matchingHostRule.username,\n );\n }\n const passwordVariableName = extractEnvironmentVariableName(\n parsedSourceUrl.password,\n );\n if (matchingHostRule.password && passwordVariableName) {\n addExtraEnvVariable(\n extraEnv,\n passwordVariableName,\n matchingHostRule.password,\n );\n }\n }\n }\n}\n\nexport async function updateArtifacts({\n packageFileName: pipfileName,\n newPackageFileContent: newPipfileContent,\n config,\n}: UpdateArtifact): Promise<UpdateArtifactsResult[] | null> {\n logger.debug(`pipenv.updateArtifacts(${pipfileName})`);\n\n const lockFileName = `${pipfileName}.lock`;\n if (!(await localPathExists(lockFileName))) {\n logger.debug('No Pipfile.lock found');\n return null;\n }\n try {\n await writeLocalFile(pipfileName, newPipfileContent);\n if (config.isLockFileMaintenance) {\n await deleteLocalFile(lockFileName);\n }\n const cmd = 'pipenv lock';\n const pipfileDir = getParentDir(ensureLocalPath(pipfileName));\n const tagConstraint =\n config.constraints?.python ??\n (await pipenvDetect.getPythonConstraint(pipfileDir));\n const pipenvConstraint =\n config.constraints?.pipenv ??\n (await pipenvDetect.getPipenvConstraint(pipfileDir));\n const extraEnv: Opt<ExtraEnv> = {\n PIPENV_CACHE_DIR: await ensureCacheDir('pipenv'),\n PIP_CACHE_DIR: await ensureCacheDir('pip'),\n WORKON_HOME: await ensureCacheDir('virtualenvs'),\n };\n const execOptions: ExecOptions = {\n cwdFile: pipfileName,\n docker: {},\n toolConstraints: [\n {\n toolName: 'python',\n constraint: tagConstraint,\n },\n {\n toolName: 'pipenv',\n constraint: pipenvConstraint,\n },\n ],\n };\n await addCredentialsForSourceUrls(newPipfileContent, pipfileName, extraEnv);\n execOptions.extraEnv = extraEnv;\n\n logger.trace({ cmd }, 'pipenv lock command');\n await exec(cmd, execOptions);\n const status = await getRepoStatus();\n if (!status?.modified.includes(lockFileName)) {\n return null;\n }\n logger.debug('Returning updated Pipfile.lock');\n return [\n {\n file: {\n type: 'addition',\n path: lockFileName,\n contents: await readLocalFile(lockFileName, 'utf8'),\n },\n },\n ];\n } catch (err) {\n // istanbul ignore if\n if (err.message === TEMPORARY_ERROR) {\n throw err;\n }\n logger.debug({ err }, 'Failed to update Pipfile.lock');\n return [\n {\n artifactError: {\n fileName: lockFileName,\n stderr: err.message,\n },\n },\n ];\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"artifacts.js","names":["pipenvDetect"],"sources":["../../../../lib/modules/manager/pipenv/artifacts.ts"],"sourcesContent":["import { pipenv as pipenvDetect } from '@renovatebot/detect-tools';\nimport {\n isNonEmptyStringAndNotWhitespace,\n isUrlInstance,\n} from '@sindresorhus/is';\nimport { TEMPORARY_ERROR } from '../../../constants/error-messages.ts';\nimport { logger } from '../../../logger/index.ts';\nimport type { HostRule } from '../../../types/index.ts';\nimport { coerceArray } from '../../../util/array.ts';\nimport { exec } from '../../../util/exec/index.ts';\nimport type { ExecOptions, ExtraEnv, Opt } from '../../../util/exec/types.ts';\nimport {\n deleteLocalFile,\n ensureCacheDir,\n getParentDir,\n localPathExists,\n readLocalFile,\n writeLocalFile,\n} from '../../../util/fs/index.ts';\nimport { ensureLocalPath } from '../../../util/fs/util.ts';\nimport { getRepoStatus } from '../../../util/git/index.ts';\nimport { find } from '../../../util/host-rules.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { parseUrl } from '../../../util/url.ts';\nimport { PypiDatasource } from '../../datasource/pypi/index.ts';\nimport type { UpdateArtifact, UpdateArtifactsResult } from '../types.ts';\nimport { resolveToolConstraint } from '../util.ts';\nimport { extractPackageFile } from './extract.ts';\n\nexport function getMatchingHostRule(url: string): HostRule | null {\n const parsedUrl = parseUrl(url);\n if (parsedUrl) {\n parsedUrl.username = '';\n parsedUrl.password = '';\n const urlWithoutCredentials = parsedUrl.toString();\n\n return find({ hostType: PypiDatasource.id, url: urlWithoutCredentials });\n }\n return null;\n}\n\nasync function findPipfileSourceUrlsWithCredentials(\n pipfileContent: string,\n pipfileName: string,\n): Promise<URL[]> {\n const pipfile = await extractPackageFile(pipfileContent, pipfileName);\n\n return coerceArray(\n pipfile?.registryUrls\n ?.map(parseUrl)\n .filter(isUrlInstance)\n .filter((url) => isNonEmptyStringAndNotWhitespace(url.username)),\n );\n}\n\n/**\n * This will extract the actual variable name from an environment-placeholder:\n * ${USERNAME:-defaultvalue} will yield 'USERNAME'\n */\nexport function extractEnvironmentVariableName(\n credential: string,\n): string | null {\n const match = regEx('([a-z0-9_]+)', 'i').exec(decodeURI(credential));\n return match?.length ? match[0] : null;\n}\n\nexport function addExtraEnvVariable(\n extraEnv: ExtraEnv,\n environmentVariableName: string,\n environmentValue: string,\n): void {\n logger.trace(\n `Adding ${environmentVariableName} environment variable for pipenv`,\n );\n if (\n extraEnv[environmentVariableName] &&\n extraEnv[environmentVariableName] !== environmentValue\n ) {\n logger.warn(\n { envVar: environmentVariableName },\n 'Possible misconfiguration, environment variable already set to a different value',\n );\n }\n extraEnv[environmentVariableName] = environmentValue;\n}\n\n/**\n * Pipenv allows configuring source-urls for remote repositories with placeholders for credentials, i.e. http://$USER:$PASS@myprivate.repo\n * if a matching host rule exists for that repository, we need to set the corresponding variables.\n * Simply substituting them in the URL is not an option as it would impact the hash for the resulting Pipfile.lock\n *\n */\nasync function addCredentialsForSourceUrls(\n newPipfileContent: string,\n pipfileName: string,\n extraEnv: ExtraEnv,\n): Promise<void> {\n const sourceUrls = await findPipfileSourceUrlsWithCredentials(\n newPipfileContent,\n pipfileName,\n );\n for (const parsedSourceUrl of sourceUrls) {\n logger.trace(`Trying to add credentials for ${parsedSourceUrl.toString()}`);\n const matchingHostRule = getMatchingHostRule(parsedSourceUrl.toString());\n if (matchingHostRule) {\n const usernameVariableName = extractEnvironmentVariableName(\n parsedSourceUrl.username,\n );\n if (matchingHostRule.username && usernameVariableName) {\n addExtraEnvVariable(\n extraEnv,\n usernameVariableName,\n matchingHostRule.username,\n );\n }\n const passwordVariableName = extractEnvironmentVariableName(\n parsedSourceUrl.password,\n );\n if (matchingHostRule.password && passwordVariableName) {\n addExtraEnvVariable(\n extraEnv,\n passwordVariableName,\n matchingHostRule.password,\n );\n }\n }\n }\n}\n\nexport async function updateArtifacts({\n packageFileName: pipfileName,\n newPackageFileContent: newPipfileContent,\n config,\n}: UpdateArtifact): Promise<UpdateArtifactsResult[] | null> {\n logger.debug(`pipenv.updateArtifacts(${pipfileName})`);\n\n const lockFileName = `${pipfileName}.lock`;\n if (!(await localPathExists(lockFileName))) {\n logger.debug('No Pipfile.lock found');\n return null;\n }\n try {\n await writeLocalFile(pipfileName, newPipfileContent);\n if (config.isLockFileMaintenance) {\n await deleteLocalFile(lockFileName);\n }\n const cmd = 'pipenv lock';\n const pipfileDir = getParentDir(ensureLocalPath(pipfileName));\n const tagConstraint = await resolveToolConstraint(config, 'python', () =>\n pipenvDetect.getPythonConstraint(pipfileDir),\n );\n const pipenvConstraint = await resolveToolConstraint(config, 'pipenv', () =>\n pipenvDetect.getPipenvConstraint(pipfileDir),\n );\n const extraEnv: Opt<ExtraEnv> = {\n PIPENV_CACHE_DIR: await ensureCacheDir('pipenv'),\n PIP_CACHE_DIR: await ensureCacheDir('pip'),\n WORKON_HOME: await ensureCacheDir('virtualenvs'),\n };\n const execOptions: ExecOptions = {\n cwdFile: pipfileName,\n docker: {},\n toolConstraints: [\n {\n toolName: 'python',\n constraint: tagConstraint,\n },\n {\n toolName: 'pipenv',\n constraint: pipenvConstraint,\n },\n ],\n };\n await addCredentialsForSourceUrls(newPipfileContent, pipfileName, extraEnv);\n execOptions.extraEnv = extraEnv;\n\n logger.trace({ cmd }, 'pipenv lock command');\n await exec(cmd, execOptions);\n const status = await getRepoStatus();\n if (!status?.modified.includes(lockFileName)) {\n return null;\n }\n logger.debug('Returning updated Pipfile.lock');\n return [\n {\n file: {\n type: 'addition',\n path: lockFileName,\n contents: await readLocalFile(lockFileName, 'utf8'),\n },\n },\n ];\n } catch (err) {\n // istanbul ignore if\n if (err.message === TEMPORARY_ERROR) {\n throw err;\n }\n logger.debug({ err }, 'Failed to update Pipfile.lock');\n return [\n {\n artifactError: {\n fileName: lockFileName,\n stderr: err.message,\n },\n },\n ];\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AA6BA,SAAgB,oBAAoB,KAA8B;CAChE,MAAM,YAAY,SAAS,GAAG;CAC9B,IAAI,WAAW;EACb,UAAU,WAAW;EACrB,UAAU,WAAW;EACrB,MAAM,wBAAwB,UAAU,SAAS;EAEjD,OAAO,KAAK;GAAE,UAAU,eAAe;GAAI,KAAK;EAAsB,CAAC;CACzE;CACA,OAAO;AACT;AAEA,eAAe,qCACb,gBACA,aACgB;CAChB,MAAM,UAAU,MAAM,mBAAmB,gBAAgB,WAAW;CAEpE,OAAO,YACL,SAAS,cACL,IAAI,QAAQ,CAAC,CACd,OAAO,aAAa,CAAC,CACrB,QAAQ,QAAQ,iCAAiC,IAAI,QAAQ,CAAC,CACnE;AACF;;;;;AAMA,SAAgB,+BACd,YACe;CACf,MAAM,QAAQ,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,UAAU,UAAU,CAAC;CACnE,OAAO,OAAO,SAAS,MAAM,KAAK;AACpC;AAEA,SAAgB,oBACd,UACA,yBACA,kBACM;CACN,OAAO,MACL,UAAU,wBAAwB,iCACpC;CACA,IACE,SAAS,4BACT,SAAS,6BAA6B,kBAEtC,OAAO,KACL,EAAE,QAAQ,wBAAwB,GAClC,kFACF;CAEF,SAAS,2BAA2B;AACtC;;;;;;;AAQA,eAAe,4BACb,mBACA,aACA,UACe;CACf,MAAM,aAAa,MAAM,qCACvB,mBACA,WACF;CACA,KAAK,MAAM,mBAAmB,YAAY;EACxC,OAAO,MAAM,iCAAiC,gBAAgB,SAAS,GAAG;EAC1E,MAAM,mBAAmB,oBAAoB,gBAAgB,SAAS,CAAC;EACvE,IAAI,kBAAkB;GACpB,MAAM,uBAAuB,+BAC3B,gBAAgB,QAClB;GACA,IAAI,iBAAiB,YAAY,sBAC/B,oBACE,UACA,sBACA,iBAAiB,QACnB;GAEF,MAAM,uBAAuB,+BAC3B,gBAAgB,QAClB;GACA,IAAI,iBAAiB,YAAY,sBAC/B,oBACE,UACA,sBACA,iBAAiB,QACnB;EAEJ;CACF;AACF;AAEA,eAAsB,gBAAgB,EACpC,iBAAiB,aACjB,uBAAuB,mBACvB,UAC0D;CAC1D,OAAO,MAAM,0BAA0B,YAAY,EAAE;CAErD,MAAM,eAAe,GAAG,YAAY;CACpC,IAAI,CAAE,MAAM,gBAAgB,YAAY,GAAI;EAC1C,OAAO,MAAM,uBAAuB;EACpC,OAAO;CACT;CACA,IAAI;EACF,MAAM,eAAe,aAAa,iBAAiB;EACnD,IAAI,OAAO,uBACT,MAAM,gBAAgB,YAAY;EAEpC,MAAM,MAAM;EACZ,MAAM,aAAa,aAAa,gBAAgB,WAAW,CAAC;EAC5D,MAAM,gBAAgB,MAAM,sBAAsB,QAAQ,gBACxDA,OAAa,oBAAoB,UAAU,CAC7C;EACA,MAAM,mBAAmB,MAAM,sBAAsB,QAAQ,gBAC3DA,OAAa,oBAAoB,UAAU,CAC7C;EACA,MAAM,WAA0B;GAC9B,kBAAkB,MAAM,eAAe,QAAQ;GAC/C,eAAe,MAAM,eAAe,KAAK;GACzC,aAAa,MAAM,eAAe,aAAa;EACjD;EACA,MAAM,cAA2B;GAC/B,SAAS;GACT,QAAQ,CAAC;GACT,iBAAiB,CACf;IACE,UAAU;IACV,YAAY;GACd,GACA;IACE,UAAU;IACV,YAAY;GACd,CACF;EACF;EACA,MAAM,4BAA4B,mBAAmB,aAAa,QAAQ;EAC1E,YAAY,WAAW;EAEvB,OAAO,MAAM,EAAE,IAAI,GAAG,qBAAqB;EAC3C,MAAM,KAAK,KAAK,WAAW;EAE3B,IAAI,EAAC,MADgB,cAAc,EAAA,EACtB,SAAS,SAAS,YAAY,GACzC,OAAO;EAET,OAAO,MAAM,gCAAgC;EAC7C,OAAO,CACL,EACE,MAAM;GACJ,MAAM;GACN,MAAM;GACN,UAAU,MAAM,cAAc,cAAc,MAAM;EACpD,EACF,CACF;CACF,SAAS,KAAK;;EAEZ,IAAI,IAAI,YAAA,mBACN,MAAM;EAER,OAAO,MAAM,EAAE,IAAI,GAAG,+BAA+B;EACrD,OAAO,CACL,EACE,eAAe;GACb,UAAU;GACV,QAAQ,IAAI;EACd,EACF,CACF;CACF;AACF"}
@@ -1,11 +1,12 @@
1
1
  import { logger } from "../../../logger/index.js";
2
+ import { resolveToolConstraint } from "../util.js";
2
3
  import { updatePixiLockfile } from "./lockfile.js";
3
4
  import { getUserPixiConfig } from "./extract.js";
4
5
  //#region lib/modules/manager/pixi/artifacts.ts
5
6
  async function updateArtifacts({ packageFileName, updatedDeps, newPackageFileContent, config }) {
6
7
  logger.debug(`pixi.updateArtifacts(${packageFileName})`);
7
8
  const pixiConfig = getUserPixiConfig(newPackageFileContent, packageFileName);
8
- const constraint = config.constraints?.pixi ?? pixiConfig?.project["requires-pixi"];
9
+ const constraint = await resolveToolConstraint(config, "pixi", () => pixiConfig?.project["requires-pixi"]);
9
10
  return await updatePixiLockfile({
10
11
  packageFileName,
11
12
  updatedDeps,
@@ -1 +1 @@
1
- {"version":3,"file":"artifacts.js","names":[],"sources":["../../../../lib/modules/manager/pixi/artifacts.ts"],"sourcesContent":["import { logger } from '../../../logger/index.ts';\nimport type { UpdateArtifact, UpdateArtifactsResult } from '../types.ts';\nimport { getUserPixiConfig } from './extract.ts';\nimport { updatePixiLockfile } from './lockfile.ts';\n\nexport async function updateArtifacts({\n packageFileName,\n updatedDeps,\n newPackageFileContent,\n config,\n}: UpdateArtifact): Promise<UpdateArtifactsResult[] | null> {\n logger.debug(`pixi.updateArtifacts(${packageFileName})`);\n\n const pixiConfig = getUserPixiConfig(newPackageFileContent, packageFileName);\n const constraint =\n config.constraints?.pixi ?? pixiConfig?.project['requires-pixi'];\n\n return await updatePixiLockfile({\n packageFileName,\n updatedDeps,\n isLockFileMaintenance: config.isLockFileMaintenance,\n constraint,\n newPackageFileContent,\n });\n}\n"],"mappings":";;;;AAKA,eAAsB,gBAAgB,EACpC,iBACA,aACA,uBACA,UAC0D;CAC1D,OAAO,MAAM,wBAAwB,gBAAgB,EAAE;CAEvD,MAAM,aAAa,kBAAkB,uBAAuB,eAAe;CAC3E,MAAM,aACJ,OAAO,aAAa,QAAQ,YAAY,QAAQ;CAElD,OAAO,MAAM,mBAAmB;EAC9B;EACA;EACA,uBAAuB,OAAO;EAC9B;EACA;CACF,CAAC;AACH"}
1
+ {"version":3,"file":"artifacts.js","names":[],"sources":["../../../../lib/modules/manager/pixi/artifacts.ts"],"sourcesContent":["import { logger } from '../../../logger/index.ts';\nimport type { UpdateArtifact, UpdateArtifactsResult } from '../types.ts';\nimport { resolveToolConstraint } from '../util.ts';\nimport { getUserPixiConfig } from './extract.ts';\nimport { updatePixiLockfile } from './lockfile.ts';\n\nexport async function updateArtifacts({\n packageFileName,\n updatedDeps,\n newPackageFileContent,\n config,\n}: UpdateArtifact): Promise<UpdateArtifactsResult[] | null> {\n logger.debug(`pixi.updateArtifacts(${packageFileName})`);\n\n const pixiConfig = getUserPixiConfig(newPackageFileContent, packageFileName);\n const constraint = await resolveToolConstraint(\n config,\n 'pixi',\n () => pixiConfig?.project['requires-pixi'],\n );\n\n return await updatePixiLockfile({\n packageFileName,\n updatedDeps,\n isLockFileMaintenance: config.isLockFileMaintenance,\n constraint,\n newPackageFileContent,\n });\n}\n"],"mappings":";;;;;AAMA,eAAsB,gBAAgB,EACpC,iBACA,aACA,uBACA,UAC0D;CAC1D,OAAO,MAAM,wBAAwB,gBAAgB,EAAE;CAEvD,MAAM,aAAa,kBAAkB,uBAAuB,eAAe;CAC3E,MAAM,aAAa,MAAM,sBACvB,QACA,cACM,YAAY,QAAQ,gBAC5B;CAEA,OAAO,MAAM,mBAAmB;EAC9B;EACA;EACA,uBAAuB,OAAO;EAC9B;EACA;CACF,CAAC;AACH"}
@@ -10,6 +10,7 @@ import { deleteLocalFile, ensureCacheDir, getSiblingFileName, readLocalFile, wri
10
10
  import { Result } from "../../../util/result.js";
11
11
  import { getGoogleAuthHostRule } from "../../datasource/util.js";
12
12
  import { PypiDatasource } from "../../datasource/pypi/index.js";
13
+ import { resolveToolConstraint } from "../util.js";
13
14
  import { withGitEnvironment } from "../../../util/git/exec.js";
14
15
  import { Lockfile, PoetryPyProject } from "./schema.js";
15
16
  import { isNonEmptyArray, isNonEmptyObject, isNumber, isString } from "@sindresorhus/is";
@@ -125,8 +126,8 @@ async function updateArtifacts({ packageFileName, updatedDeps, newPackageFileCon
125
126
  await deleteLocalFile(lockFileName);
126
127
  cmd.push("poetry update --lock --no-interaction");
127
128
  } else cmd.push(`poetry update --lock --no-interaction ${updatedDeps.map((dep) => dep.depName).filter(isString).map((dep) => quote(dep)).join(" ")}`);
128
- const pythonConstraint = config?.constraints?.python ?? getPythonConstraint(newPackageFileContent, existingLockFileContent);
129
- const poetryConstraint = config.constraints?.poetry ?? getPoetryRequirement(newPackageFileContent, existingLockFileContent);
129
+ const pythonConstraint = await resolveToolConstraint(config, "python", () => getPythonConstraint(newPackageFileContent, existingLockFileContent));
130
+ const poetryConstraint = await resolveToolConstraint(config, "poetry", () => getPoetryRequirement(newPackageFileContent, existingLockFileContent));
130
131
  const extraEnv = {
131
132
  ...await getSourceCredentialVars(newPackageFileContent, packageFileName),
132
133
  PIP_CACHE_DIR: await ensureCacheDir("pip")