renovate 44.101.0 → 44.101.1
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.
- package/dist/modules/datasource/pypi/common.js +2 -1
- package/dist/modules/datasource/pypi/common.js.map +1 -1
- package/dist/modules/datasource/pypi/host-rules.js +43 -0
- package/dist/modules/datasource/pypi/host-rules.js.map +1 -0
- package/dist/modules/datasource/pypi/index.js +18 -19
- package/dist/modules/datasource/pypi/index.js.map +1 -1
- package/dist/modules/datasource/util.js +7 -1
- package/dist/modules/datasource/util.js.map +1 -1
- package/dist/modules/manager/fingerprint.generated.js +5 -5
- package/dist/modules/manager/fingerprint.generated.js.map +1 -1
- package/dist/modules/manager/helmv3/common.js +1 -1
- package/dist/modules/manager/helmv3/common.js.map +1 -1
- package/dist/modules/manager/pep621/processors/uv.js +3 -20
- package/dist/modules/manager/pep621/processors/uv.js.map +1 -1
- package/dist/modules/manager/pip-compile/artifacts.js +4 -3
- package/dist/modules/manager/pip-compile/artifacts.js.map +1 -1
- package/dist/modules/manager/pip-compile/common.js +10 -17
- package/dist/modules/manager/pip-compile/common.js.map +1 -1
- package/dist/modules/manager/pipenv/artifacts.js +9 -26
- package/dist/modules/manager/pipenv/artifacts.js.map +1 -1
- package/dist/modules/manager/poetry/artifacts.js +3 -26
- package/dist/modules/manager/poetry/artifacts.js.map +1 -1
- package/dist/modules/manager/swift/artifacts.js +12 -0
- package/dist/modules/manager/swift/artifacts.js.map +1 -1
- package/dist/util/git/index.d.ts +7 -1
- package/dist/util/git/index.js +9 -1
- package/dist/util/git/index.js.map +1 -1
- package/dist/util/host-rules.js +2 -2
- package/dist/util/host-rules.js.map +1 -1
- package/dist/util/url.d.ts +10 -1
- package/dist/util/url.js +10 -1
- package/dist/util/url.js.map +1 -1
- package/dist/workers/repository/process/lookup/bucket.js +23 -4
- package/dist/workers/repository/process/lookup/bucket.js.map +1 -1
- package/dist/workers/repository/process/lookup/current.js +28 -1
- package/dist/workers/repository/process/lookup/current.js.map +1 -1
- package/dist/workers/repository/process/lookup/digest.js +99 -0
- package/dist/workers/repository/process/lookup/digest.js.map +1 -0
- package/dist/workers/repository/process/lookup/filter-checks.js +28 -7
- package/dist/workers/repository/process/lookup/filter-checks.js.map +1 -1
- package/dist/workers/repository/process/lookup/generate.js +2 -2
- package/dist/workers/repository/process/lookup/generate.js.map +1 -1
- package/dist/workers/repository/process/lookup/index.js +24 -161
- package/dist/workers/repository/process/lookup/index.js.map +1 -1
- package/dist/workers/repository/process/lookup/range-strategy.js +18 -0
- package/dist/workers/repository/process/lookup/range-strategy.js.map +1 -0
- package/dist/workers/repository/process/lookup/update-type.js +14 -5
- package/dist/workers/repository/process/lookup/update-type.js.map +1 -1
- package/dist/workers/repository/process/lookup/utils.js +13 -2
- package/dist/workers/repository/process/lookup/utils.js.map +1 -1
- package/dist/workers/repository/process/lookup/version-compatibility.js +51 -0
- package/dist/workers/repository/process/lookup/version-compatibility.js.map +1 -0
- package/dist/workers/repository/process/lookup/vulnerability.js +53 -0
- package/dist/workers/repository/process/lookup/vulnerability.js.map +1 -0
- package/package.json +2 -2
- package/renovate-schema.json +2 -2
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { regEx } from "../../../util/regex.js";
|
|
2
2
|
//#region lib/modules/datasource/pypi/common.ts
|
|
3
|
+
const pypiDatasourceId = "pypi";
|
|
3
4
|
const githubRepoPattern = regEx(/^https?:\/\/github\.com\/(?<owner>[^/]+)\/[^/]+$/);
|
|
4
5
|
function isGitHubRepo(url) {
|
|
5
6
|
const m = url.match(githubRepoPattern);
|
|
@@ -9,6 +10,6 @@ function normalizePythonDepName(name) {
|
|
|
9
10
|
return name.replace(regEx(/[-_.]+/g), "-").toLowerCase();
|
|
10
11
|
}
|
|
11
12
|
//#endregion
|
|
12
|
-
export { isGitHubRepo, normalizePythonDepName };
|
|
13
|
+
export { isGitHubRepo, normalizePythonDepName, pypiDatasourceId };
|
|
13
14
|
|
|
14
15
|
//# sourceMappingURL=common.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.js","names":[],"sources":["../../../../lib/modules/datasource/pypi/common.ts"],"sourcesContent":["import { regEx } from '../../../util/regex.ts';\n\nconst githubRepoPattern = regEx(\n /^https?:\\/\\/github\\.com\\/(?<owner>[^/]+)\\/[^/]+$/,\n);\n\nexport function isGitHubRepo(url: string): boolean {\n const m = url.match(githubRepoPattern);\n return !!m && m.groups!.owner !== 'sponsors';\n}\n\n// https://packaging.python.org/en/latest/specifications/name-normalization/\nexport function normalizePythonDepName(name: string): string {\n return name.replace(regEx(/[-_.]+/g), '-').toLowerCase();\n}\n"],"mappings":";;AAEA,MAAM,oBAAoB,MACxB,kDACF;AAEA,SAAgB,aAAa,KAAsB;CACjD,MAAM,IAAI,IAAI,MAAM,iBAAiB;CACrC,OAAO,CAAC,CAAC,KAAK,EAAE,OAAQ,UAAU;AACpC;AAGA,SAAgB,uBAAuB,MAAsB;CAC3D,OAAO,KAAK,QAAQ,MAAM,SAAS,GAAG,GAAG,CAAC,CAAC,YAAY;AACzD"}
|
|
1
|
+
{"version":3,"file":"common.js","names":[],"sources":["../../../../lib/modules/datasource/pypi/common.ts"],"sourcesContent":["import { regEx } from '../../../util/regex.ts';\n\nexport const pypiDatasourceId = 'pypi';\n\nconst githubRepoPattern = regEx(\n /^https?:\\/\\/github\\.com\\/(?<owner>[^/]+)\\/[^/]+$/,\n);\n\nexport function isGitHubRepo(url: string): boolean {\n const m = url.match(githubRepoPattern);\n return !!m && m.groups!.owner !== 'sponsors';\n}\n\n// https://packaging.python.org/en/latest/specifications/name-normalization/\nexport function normalizePythonDepName(name: string): string {\n return name.replace(regEx(/[-_.]+/g), '-').toLowerCase();\n}\n"],"mappings":";;AAEA,MAAa,mBAAmB;AAEhC,MAAM,oBAAoB,MACxB,kDACF;AAEA,SAAgB,aAAa,KAAsB;CACjD,MAAM,IAAI,IAAI,MAAM,iBAAiB;CACrC,OAAO,CAAC,CAAC,KAAK,EAAE,OAAQ,UAAU;AACpC;AAGA,SAAgB,uBAAuB,MAAsB;CAC3D,OAAO,KAAK,QAAQ,MAAM,SAAS,GAAG,GAAG,CAAC,CAAC,YAAY;AACzD"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { logger } from "../../../logger/index.js";
|
|
2
|
+
import { parseUrl } from "../../../util/url.js";
|
|
3
|
+
import { find } from "../../../util/host-rules.js";
|
|
4
|
+
import { getGoogleAuthHostRule, isGoogleArtifactRegistry } from "../util.js";
|
|
5
|
+
import { pypiDatasourceId } from "./common.js";
|
|
6
|
+
//#region lib/modules/datasource/pypi/host-rules.ts
|
|
7
|
+
/**
|
|
8
|
+
* Resolves the credentials for a Python package index URL.
|
|
9
|
+
*
|
|
10
|
+
* The URL's own `user:password@` part - which is often a placeholder such as
|
|
11
|
+
* `${USER}:${PASS}@` - does not stop it matching a `matchHost` without
|
|
12
|
+
* credentials, as `find()` ignores userinfo when matching. Google Artifact
|
|
13
|
+
* Registry is only asked for a token when no host rule supplies credentials,
|
|
14
|
+
* so an explicitly configured username/password always wins.
|
|
15
|
+
*/
|
|
16
|
+
async function findPypiIndexCredentials(indexUrl) {
|
|
17
|
+
const parsedUrl = parseUrl(indexUrl);
|
|
18
|
+
if (!parsedUrl) {
|
|
19
|
+
logger.once.debug(`Failed to parse index URL ${indexUrl}`);
|
|
20
|
+
return {};
|
|
21
|
+
}
|
|
22
|
+
const { username, password } = find({
|
|
23
|
+
hostType: pypiDatasourceId,
|
|
24
|
+
url: parsedUrl.toString()
|
|
25
|
+
});
|
|
26
|
+
if (username ?? password) return {
|
|
27
|
+
username,
|
|
28
|
+
password
|
|
29
|
+
};
|
|
30
|
+
if (isGoogleArtifactRegistry(parsedUrl.hostname)) {
|
|
31
|
+
const googleHostRule = await getGoogleAuthHostRule();
|
|
32
|
+
if (googleHostRule) return {
|
|
33
|
+
username: googleHostRule.username,
|
|
34
|
+
password: googleHostRule.password
|
|
35
|
+
};
|
|
36
|
+
logger.once.debug(`Could not get Google access token (url=${parsedUrl.toString()})`);
|
|
37
|
+
}
|
|
38
|
+
return {};
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
export { findPypiIndexCredentials };
|
|
42
|
+
|
|
43
|
+
//# sourceMappingURL=host-rules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host-rules.js","names":[],"sources":["../../../../lib/modules/datasource/pypi/host-rules.ts"],"sourcesContent":["import { logger } from '../../../logger/index.ts';\nimport { find } from '../../../util/host-rules.ts';\nimport { parseUrl } from '../../../util/url.ts';\nimport { getGoogleAuthHostRule, isGoogleArtifactRegistry } from '../util.ts';\nimport { pypiDatasourceId } from './common.ts';\nimport type { PypiIndexCredentials } from './types.ts';\n\n/**\n * Resolves the credentials for a Python package index URL.\n *\n * The URL's own `user:password@` part - which is often a placeholder such as\n * `${USER}:${PASS}@` - does not stop it matching a `matchHost` without\n * credentials, as `find()` ignores userinfo when matching. Google Artifact\n * Registry is only asked for a token when no host rule supplies credentials,\n * so an explicitly configured username/password always wins.\n */\nexport async function findPypiIndexCredentials(\n indexUrl: string | undefined,\n): Promise<PypiIndexCredentials> {\n const parsedUrl = parseUrl(indexUrl);\n if (!parsedUrl) {\n logger.once.debug(`Failed to parse index URL ${indexUrl}`);\n return {};\n }\n\n const { username, password } = find({\n hostType: pypiDatasourceId,\n url: parsedUrl.toString(),\n });\n if (username ?? password) {\n return { username, password };\n }\n\n if (isGoogleArtifactRegistry(parsedUrl.hostname)) {\n const googleHostRule = await getGoogleAuthHostRule();\n if (googleHostRule) {\n return {\n username: googleHostRule.username,\n password: googleHostRule.password,\n };\n }\n logger.once.debug(\n `Could not get Google access token (url=${parsedUrl.toString()})`,\n );\n }\n\n return {};\n}\n"],"mappings":";;;;;;;;;;;;;;;AAgBA,eAAsB,yBACpB,UAC+B;CAC/B,MAAM,YAAY,SAAS,QAAQ;CACnC,IAAI,CAAC,WAAW;EACd,OAAO,KAAK,MAAM,6BAA6B,UAAU;EACzD,OAAO,CAAC;CACV;CAEA,MAAM,EAAE,UAAU,aAAa,KAAK;EAClC,UAAU;EACV,KAAK,UAAU,SAAS;CAC1B,CAAC;CACD,IAAI,YAAY,UACd,OAAO;EAAE;EAAU;CAAS;CAG9B,IAAI,yBAAyB,UAAU,QAAQ,GAAG;EAChD,MAAM,iBAAiB,MAAM,sBAAsB;EACnD,IAAI,gBACF,OAAO;GACL,UAAU,eAAe;GACzB,UAAU,eAAe;EAC3B;EAEF,OAAO,KAAK,MACV,0CAA0C,UAAU,SAAS,EAAE,EACjE;CACF;CAEA,OAAO,CAAC;AACV"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { getEnv } from "../../../util/env.js";
|
|
2
2
|
import { regEx } from "../../../util/regex.js";
|
|
3
3
|
import { coerceArray, deduplicateArray } from "../../../util/array.js";
|
|
4
|
+
import { toBase64 } from "../../../util/string.js";
|
|
5
|
+
import { addSecretForSanitizing } from "../../../util/sanitize.js";
|
|
4
6
|
import { logger } from "../../../logger/index.js";
|
|
5
7
|
import { ensureTrailingSlash, parseUrl } from "../../../util/url.js";
|
|
6
8
|
import { ExternalHostError } from "../../../types/errors/external-host-error.js";
|
|
@@ -11,14 +13,15 @@ import "../../../util/http/index.js";
|
|
|
11
13
|
import { asTimestamp } from "../../../util/timestamp.js";
|
|
12
14
|
import { Datasource } from "../datasource.js";
|
|
13
15
|
import { parse } from "../../../util/html.js";
|
|
14
|
-
import {
|
|
15
|
-
import { isGitHubRepo, normalizePythonDepName } from "./common.js";
|
|
16
|
+
import { isGoogleArtifactRegistry } from "../util.js";
|
|
17
|
+
import { isGitHubRepo, normalizePythonDepName, pypiDatasourceId } from "./common.js";
|
|
18
|
+
import { findPypiIndexCredentials } from "./host-rules.js";
|
|
16
19
|
import { PypiResponse, PypiSimpleResponse } from "./schema.js";
|
|
17
20
|
import { isNonEmptyString } from "@sindresorhus/is";
|
|
18
21
|
import changelogFilenameRegex from "changelog-filename-regex";
|
|
19
22
|
//#region lib/modules/datasource/pypi/index.ts
|
|
20
23
|
var PypiDatasource = class PypiDatasource extends Datasource {
|
|
21
|
-
static id =
|
|
24
|
+
static id = pypiDatasourceId;
|
|
22
25
|
constructor() {
|
|
23
26
|
super(PypiDatasource.id);
|
|
24
27
|
}
|
|
@@ -76,25 +79,21 @@ var PypiDatasource = class PypiDatasource extends Datasource {
|
|
|
76
79
|
lookupUrl
|
|
77
80
|
};
|
|
78
81
|
}
|
|
79
|
-
if (parsedUrl.hostname
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
lookupUrl: sanitizedLookupUrl
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
logger.once.debug({ lookupUrl }, "Could not get Google access token");
|
|
89
|
-
return {
|
|
90
|
-
headers: {},
|
|
91
|
-
lookupUrl
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
return {
|
|
82
|
+
if (!isGoogleArtifactRegistry(parsedUrl.hostname)) return {
|
|
83
|
+
headers: {},
|
|
84
|
+
lookupUrl
|
|
85
|
+
};
|
|
86
|
+
const { username, password } = await findPypiIndexCredentials(lookupUrl);
|
|
87
|
+
if (!username && !password) return {
|
|
95
88
|
headers: {},
|
|
96
89
|
lookupUrl
|
|
97
90
|
};
|
|
91
|
+
const auth = toBase64(`${username ?? ""}:${password ?? ""}`);
|
|
92
|
+
addSecretForSanitizing(auth);
|
|
93
|
+
return {
|
|
94
|
+
headers: { authorization: `Basic ${auth}` },
|
|
95
|
+
lookupUrl: this.sanitizeLookupUrl(lookupUrl, parsedUrl)
|
|
96
|
+
};
|
|
98
97
|
}
|
|
99
98
|
async getDependency(packageName, hostUrl) {
|
|
100
99
|
const lookupUrl = new URL(`${normalizePythonDepName(packageName)}/json`, hostUrl).href;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["pep440.id","HttpError"],"sources":["../../../../lib/modules/datasource/pypi/index.ts"],"sourcesContent":["import { isNonEmptyString } from '@sindresorhus/is';\nimport changelogFilenameRegex from 'changelog-filename-regex';\nimport { logger } from '../../../logger/index.ts';\nimport { ExternalHostError } from '../../../types/errors/external-host-error.ts';\nimport { coerceArray, deduplicateArray } from '../../../util/array.ts';\nimport { getEnv } from '../../../util/env.ts';\nimport { parse } from '../../../util/html.ts';\nimport { HttpError } from '../../../util/http/index.ts';\nimport type {\n HttpResponse,\n OutgoingHttpHeaders,\n} from '../../../util/http/types.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { Json } from '../../../util/schema-utils/index.ts';\nimport type { Timestamp } from '../../../util/timestamp.ts';\nimport { asTimestamp } from '../../../util/timestamp.ts';\nimport { ensureTrailingSlash, parseUrl } from '../../../util/url.ts';\nimport * as pep440 from '../../versioning/pep440/index.ts';\nimport { Datasource } from '../datasource.ts';\nimport type { GetReleasesConfig, Release, ReleaseResult } from '../types.ts';\nimport { getGoogleAuthToken } from '../util.ts';\nimport { isGitHubRepo, normalizePythonDepName } from './common.ts';\nimport type { PypiRelease } from './schema.ts';\nimport { PypiResponse, PypiSimpleResponse } from './schema.ts';\nimport type { Releases } from './types.ts';\n\nexport class PypiDatasource extends Datasource {\n static readonly id = 'pypi';\n\n constructor() {\n super(PypiDatasource.id);\n }\n\n override readonly caching = true;\n\n override readonly customRegistrySupport = true;\n\n static readonly defaultURL =\n getEnv().PIP_INDEX_URL ?? 'https://pypi.org/pypi/';\n override readonly defaultRegistryUrls = [PypiDatasource.defaultURL];\n\n override readonly defaultVersioning = pep440.id;\n\n override readonly registryStrategy = 'merge';\n\n override readonly releaseTimestampSupport = true;\n override readonly releaseTimestampNote =\n 'The release timestamp is determined from the earliest `upload_time` field of the files of a version. When using the Simple API, timestamps are available if the server supports the JSON-based Simple API (PEP 691).';\n override readonly sourceUrlSupport = 'release';\n override readonly sourceUrlNote =\n 'The source URL is determined from the `homepage` field if it is a github repository, else we use the `project_urls` field.';\n\n async getReleases({\n packageName,\n registryUrl,\n }: GetReleasesConfig): Promise<ReleaseResult | null> {\n let dependency: ReleaseResult | null = null;\n // TODO: null check (#22198)\n const hostUrl = ensureTrailingSlash(\n registryUrl!.replace('https://pypi.org/simple', 'https://pypi.org/pypi'),\n );\n const normalizedLookupName = normalizePythonDepName(packageName);\n\n // not all simple indexes use this identifier, but most do\n if (hostUrl.endsWith('/simple/') || hostUrl.endsWith('/+simple/')) {\n logger.trace(\n { packageName, hostUrl },\n 'Looking up pypi simple dependency',\n );\n dependency = await this.getSimpleDependency(\n normalizedLookupName,\n hostUrl,\n );\n } else {\n logger.trace({ packageName, hostUrl }, 'Looking up pypi api dependency');\n try {\n // we need to resolve early here so we can catch any 404s and fallback to a simple lookup\n dependency = await this.getDependency(normalizedLookupName, hostUrl);\n } catch (err) {\n // error contacting json-style api -- attempt to fallback to a simple-style api\n logger.trace(\n { packageName, hostUrl, err },\n 'Looking up pypi simple dependency via fallback',\n );\n dependency = await this.getSimpleDependency(\n normalizedLookupName,\n hostUrl,\n );\n }\n }\n return dependency;\n }\n\n private sanitizeLookupUrl(lookupUrl: string, parsedUrl: URL): string {\n if (!parsedUrl.username && !parsedUrl.password) {\n return lookupUrl;\n }\n\n parsedUrl.username = '';\n parsedUrl.password = '';\n return parsedUrl.toString();\n }\n\n private async getAuthHeaders(\n lookupUrl: string,\n ): Promise<{ headers: OutgoingHttpHeaders; lookupUrl: string }> {\n const parsedUrl = parseUrl(lookupUrl);\n // v8 ignore if -- TODO: refactor to cover this branch through public behavior again\n if (!parsedUrl) {\n logger.once.debug({ lookupUrl }, 'Failed to parse URL');\n return { headers: {}, lookupUrl };\n }\n if (parsedUrl.hostname.endsWith('.pkg.dev')) {\n const auth = await getGoogleAuthToken();\n if (auth) {\n const sanitizedLookupUrl = this.sanitizeLookupUrl(lookupUrl, parsedUrl);\n return {\n headers: { authorization: `Basic ${auth}` },\n lookupUrl: sanitizedLookupUrl,\n };\n }\n logger.once.debug({ lookupUrl }, 'Could not get Google access token');\n return { headers: {}, lookupUrl };\n }\n return { headers: {}, lookupUrl };\n }\n\n private async getDependency(\n packageName: string,\n hostUrl: string,\n ): Promise<ReleaseResult | null> {\n const lookupUrl = new URL(\n `${normalizePythonDepName(packageName)}/json`,\n hostUrl,\n ).href;\n const dependency: ReleaseResult = { releases: [] };\n logger.trace({ lookupUrl }, 'Pypi api got lookup');\n const { headers, lookupUrl: sanitizedUrl } =\n await this.getAuthHeaders(lookupUrl);\n const rep = await this.http.getJson(\n sanitizedUrl,\n { headers },\n PypiResponse,\n );\n const dep = rep?.body;\n if (rep.authorization) {\n dependency.isPrivate = true;\n }\n logger.trace({ lookupUrl }, 'Got pypi api result');\n\n if (dep.info?.home_page) {\n dependency.homepage = dep.info.home_page;\n if (isGitHubRepo(dep.info.home_page)) {\n dependency.sourceUrl = dep.info.home_page.replace(\n 'http://',\n 'https://',\n );\n }\n }\n\n if (dep.info?.project_urls) {\n for (const [name, projectUrl] of Object.entries(dep.info.project_urls)) {\n const lower = name.toLowerCase();\n\n if (\n projectUrl &&\n !dependency.sourceUrl &&\n (lower.startsWith('repo') ||\n lower === 'code' ||\n lower === 'source' ||\n isGitHubRepo(projectUrl))\n ) {\n dependency.sourceUrl = projectUrl;\n }\n\n if (\n !dependency.changelogUrl &&\n ([\n 'changelog',\n 'change log',\n 'changes',\n 'release notes',\n 'news',\n \"what's new\",\n ].includes(lower) ||\n changelogFilenameRegex.exec(lower))\n ) {\n // from https://github.com/pypa/warehouse/blob/418c7511dc367fb410c71be139545d0134ccb0df/warehouse/templates/packaging/detail.html#L24\n dependency.changelogUrl = projectUrl;\n }\n }\n }\n\n if (dep.releases) {\n dependency.releases = PypiDatasource.toReleases(dep.releases);\n }\n return dependency;\n }\n\n private static getEarliestTimestamp(\n releases: PypiRelease[],\n ): Timestamp | null {\n let earliest: Timestamp | null = null;\n for (const { upload_time } of releases) {\n const timestamp = asTimestamp(upload_time);\n // `asTimestamp` normalizes to UTC ISO 8601, so comparing the strings compares the instants\n if (timestamp && (!earliest || timestamp < earliest)) {\n earliest = timestamp;\n }\n }\n return earliest;\n }\n\n private static extractVersionFromLinkText(\n text: string,\n packageName: string,\n ): string | null {\n // source packages\n const lcText = text.toLowerCase();\n const normalizedSrcText = normalizePythonDepName(text);\n const srcPrefix = `${packageName}-`;\n\n // source distribution format: `{name}-{version}.tar.gz` (https://packaging.python.org/en/latest/specifications/source-distribution-format/#source-distribution-file-name)\n // binary distribution: `{distribution}-{version}(-{build tag})?-{python tag}-{abi tag}-{platform tag}.whl` (https://packaging.python.org/en/latest/specifications/binary-distribution-format/#file-name-convention)\n // officially both `name` and `distribution` should be normalized and then the - replaced with _, but in reality this is not the case\n // We therefore normalize the name we have (replacing `_-.` with -) and then check if the text starts with the normalized name\n\n if (!normalizedSrcText.startsWith(srcPrefix)) {\n return null;\n }\n\n // strip off the prefix using the prefix length as we may have normalized the srcPrefix/packageName\n // We assume that neither the version nor the suffix contains multiple `-` like `0.1.2---rc1.tar.gz`\n // and use the difference in length to strip off the prefix in case the name contains double `--` characters\n const normalizedLengthDiff = lcText.length - normalizedSrcText.length;\n const res = lcText.slice(srcPrefix.length + normalizedLengthDiff);\n\n // source distribution\n const srcSuffixes = ['.tar.gz', '.tar.bz2', '.tar.xz', '.zip', '.tgz'];\n const srcSuffix = srcSuffixes.find((suffix) => lcText.endsWith(suffix));\n if (srcSuffix) {\n // strip off the suffix using character length\n return res.slice(0, -srcSuffix.length);\n }\n\n // binary distribution\n // for binary distributions the version is the first part after the removed distribution name\n const wheelSuffix = '.whl';\n if (lcText.endsWith(wheelSuffix) && lcText.split('-').length > 2) {\n return res.split('-')[0];\n }\n return null;\n }\n\n private static cleanSimpleHtml(html: string): string {\n return (\n html\n .replace(regEx(/<\\/?pre>/), '')\n // Certain simple repositories like artifactory don't escape > and <\n .replace(\n regEx(/data-requires-python=\"(?<before>[^\"]*?)>(?<after>[^\"]*?)\"/g),\n 'data-requires-python=\"$<before>>$<after>\"',\n )\n .replace(\n regEx(/data-requires-python=\"(?<before>[^\"]*?)<(?<after>[^\"]*?)\"/g),\n 'data-requires-python=\"$<before><$<after>\"',\n )\n );\n }\n\n private static getSimpleReleasesFromHtml(\n html: string,\n packageName: string,\n ): Releases {\n const root = parse(PypiDatasource.cleanSimpleHtml(html));\n const links = root.querySelectorAll('a');\n const releases: Releases = {};\n for (const link of Array.from(links)) {\n const version = PypiDatasource.extractVersionFromLinkText(\n link.text?.trim(),\n packageName,\n );\n if (version) {\n const release: PypiRelease = {\n yanked: link.hasAttribute('data-yanked'),\n };\n const requiresPython = link.getAttribute('data-requires-python');\n if (requiresPython) {\n release.requires_python = requiresPython;\n }\n (releases[version] ??= []).push(release);\n }\n }\n return releases;\n }\n\n private static getSimpleReleasesFromJson(\n json: string,\n packageName: string,\n ): Releases | null {\n const releases: Releases = {};\n const parsed = Json.pipe(PypiSimpleResponse).safeParse(json);\n if (!parsed.success) {\n logger.once.warn(\n { packageName, err: parsed.error },\n 'Failed to parse JSON-based Simple API response',\n );\n // Distinguish a malformed response from a package with genuinely no files, so the caller doesn't mistake an error for an empty result.\n return null;\n }\n for (const file of parsed.data.files) {\n const version = PypiDatasource.extractVersionFromLinkText(\n file.filename,\n packageName,\n );\n if (version) {\n (releases[version] ??= []).push(file);\n }\n }\n return releases;\n }\n\n private async getSimpleDependency(\n packageName: string,\n hostUrl: string,\n ): Promise<ReleaseResult | null> {\n const lookupUrl = new URL(\n ensureTrailingSlash(normalizePythonDepName(packageName)),\n hostUrl,\n ).href;\n const dependency: ReleaseResult = { releases: [] };\n const { headers: authHeaders, lookupUrl: sanitizedUrl } =\n await this.getAuthHeaders(lookupUrl);\n const headers: OutgoingHttpHeaders = {\n ...authHeaders,\n // Request the JSON serialization (PEP 691), falling back to the legacy HTML serialization (PEP 503) via content negotiation.\n // https://github.com/pypa/pip/blob/6b0011b49a068c62f65389bf4cea7af5d28cb002/src/pip/_internal/index/collector.py#L128-L134\n accept:\n 'application/vnd.pypi.simple.v1+json, application/vnd.pypi.simple.v1+html; q=0.1, text/html; q=0.01',\n };\n let response: HttpResponse;\n try {\n response = await this.http.getText(sanitizedUrl, { headers });\n } catch (err) {\n // An `abortOnError` host rule makes `Http` wrap the original error, so unwrap it before looking at the status code.\n const httpErr = err instanceof ExternalHostError ? err.err : err;\n const statusCode =\n httpErr instanceof HttpError ? httpErr.response?.statusCode : undefined;\n // A registry which cannot serve any of the negotiated types may pick a content type of its own, answer `406`, or answer `300`; the spec mandates none of them, but `406` is the common choice.\n // https://packaging.python.org/en/latest/specifications/simple-repository-api/#version-format-selection\n // Retry once without the negotiated `accept` header to preserve the pre-PEP-691 behaviour of a plain request.\n if (statusCode !== 406) {\n throw err;\n }\n\n logger.trace(\n { packageName, hostUrl, statusCode },\n 'Registry rejected negotiated Accept header, retrying without it',\n );\n response = await this.http.getText(sanitizedUrl, {\n headers: authHeaders,\n });\n }\n const dep = response?.body;\n if (!dep) {\n logger.trace({ dependency: packageName }, 'pip package not found');\n return null;\n }\n if (response.authorization) {\n dependency.isPrivate = true;\n }\n\n // Dispatch on the response content-type: JSON serialization (PEP 691) or the legacy HTML serialization (PEP 503). Matched loosely (any `json` media type) rather than the exact vendor type, as some registries/proxies relabel or strip the vendor-specific media type while still returning JSON.\n const contentType = response.headers['content-type'];\n const isJson = !!contentType && contentType.includes('json');\n const looksLikeJson = dep.trimStart().startsWith('{');\n\n if (isJson) {\n if (looksLikeJson) {\n const releases = PypiDatasource.getSimpleReleasesFromJson(\n dep,\n packageName,\n );\n // A parse failure is distinct from a package with genuinely no files, so don't report an empty release list as if it were a real (if empty) result, which would be cached as such.\n if (!releases) {\n return null;\n }\n dependency.releases = PypiDatasource.toReleases(releases);\n return dependency;\n }\n\n // The registry mislabeled a non-JSON body as JSON, so fall through to the HTML parser instead of reporting the package as not found.\n logger.debug(\n { packageName, hostUrl, contentType },\n 'Parsing Simple API response as HTML, as it is labeled as JSON but does not look like it',\n );\n }\n\n const htmlReleases = PypiDatasource.getSimpleReleasesFromHtml(\n dep,\n packageName,\n );\n dependency.releases = PypiDatasource.toReleases(htmlReleases);\n if (dependency.releases.length > 0 || !looksLikeJson) {\n return dependency;\n }\n\n // The registry honored the `Accept` header but omitted or mislabeled the `content-type`, so a JSON body went through the HTML parser and found nothing. Parse it as JSON instead of silently reporting no releases.\n logger.debug(\n { packageName, hostUrl, contentType },\n 'Retrying Simple API response as JSON, as it is not labeled as JSON but looks like it',\n );\n const jsonReleases = PypiDatasource.getSimpleReleasesFromJson(\n dep,\n packageName,\n );\n if (!jsonReleases) {\n return null;\n }\n dependency.releases = PypiDatasource.toReleases(jsonReleases);\n return dependency;\n }\n\n /**\n * The files of a version are not ordered by upload time, so use the earliest one: that is when the version was first published, which is what `minimumReleaseAge` needs.\n */\n private static toReleases(releases: Releases): Release[] {\n const versions = Object.keys(releases);\n return versions.map((version) => {\n const versionReleases = coerceArray(releases[version]);\n const isDeprecated = versionReleases.some(({ yanked }) => yanked);\n const result: Release = { version };\n const releaseTimestamp =\n PypiDatasource.getEarliestTimestamp(versionReleases);\n if (releaseTimestamp) {\n result.releaseTimestamp = releaseTimestamp;\n }\n if (isDeprecated) {\n result.isDeprecated = isDeprecated;\n }\n const pythonConstraints = versionReleases.map(\n ({ requires_python }) => requires_python,\n );\n // A file without `requires_python` can be installed on any Python version, so the version as a whole is unconstrained\n const isUnconstrained = pythonConstraints.some(\n (constraint) => !isNonEmptyString(constraint),\n );\n // There may be multiple releases with different requires_python, so we return all in an array.\n // Report no constraints at all for an unconstrained version, instead of only those of its other files, which would drop the version under `constraintsFiltering=strict`.\n result.constraints = {\n python: isUnconstrained\n ? []\n : deduplicateArray(pythonConstraints.filter(isNonEmptyString)),\n };\n return result;\n });\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["pep440.id","HttpError"],"sources":["../../../../lib/modules/datasource/pypi/index.ts"],"sourcesContent":["import { isNonEmptyString } from '@sindresorhus/is';\nimport changelogFilenameRegex from 'changelog-filename-regex';\nimport { logger } from '../../../logger/index.ts';\nimport { ExternalHostError } from '../../../types/errors/external-host-error.ts';\nimport { coerceArray, deduplicateArray } from '../../../util/array.ts';\nimport { getEnv } from '../../../util/env.ts';\nimport { parse } from '../../../util/html.ts';\nimport { HttpError } from '../../../util/http/index.ts';\nimport type {\n HttpResponse,\n OutgoingHttpHeaders,\n} from '../../../util/http/types.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { addSecretForSanitizing } from '../../../util/sanitize.ts';\nimport { Json } from '../../../util/schema-utils/index.ts';\nimport { toBase64 } from '../../../util/string.ts';\nimport type { Timestamp } from '../../../util/timestamp.ts';\nimport { asTimestamp } from '../../../util/timestamp.ts';\nimport { ensureTrailingSlash, parseUrl } from '../../../util/url.ts';\nimport * as pep440 from '../../versioning/pep440/index.ts';\nimport { Datasource } from '../datasource.ts';\nimport type { GetReleasesConfig, Release, ReleaseResult } from '../types.ts';\nimport { isGoogleArtifactRegistry } from '../util.ts';\nimport {\n isGitHubRepo,\n normalizePythonDepName,\n pypiDatasourceId,\n} from './common.ts';\nimport { findPypiIndexCredentials } from './host-rules.ts';\nimport type { PypiRelease } from './schema.ts';\nimport { PypiResponse, PypiSimpleResponse } from './schema.ts';\nimport type { Releases } from './types.ts';\n\nexport class PypiDatasource extends Datasource {\n static readonly id = pypiDatasourceId;\n\n constructor() {\n super(PypiDatasource.id);\n }\n\n override readonly caching = true;\n\n override readonly customRegistrySupport = true;\n\n static readonly defaultURL =\n getEnv().PIP_INDEX_URL ?? 'https://pypi.org/pypi/';\n override readonly defaultRegistryUrls = [PypiDatasource.defaultURL];\n\n override readonly defaultVersioning = pep440.id;\n\n override readonly registryStrategy = 'merge';\n\n override readonly releaseTimestampSupport = true;\n override readonly releaseTimestampNote =\n 'The release timestamp is determined from the earliest `upload_time` field of the files of a version. When using the Simple API, timestamps are available if the server supports the JSON-based Simple API (PEP 691).';\n override readonly sourceUrlSupport = 'release';\n override readonly sourceUrlNote =\n 'The source URL is determined from the `homepage` field if it is a github repository, else we use the `project_urls` field.';\n\n async getReleases({\n packageName,\n registryUrl,\n }: GetReleasesConfig): Promise<ReleaseResult | null> {\n let dependency: ReleaseResult | null = null;\n // TODO: null check (#22198)\n const hostUrl = ensureTrailingSlash(\n registryUrl!.replace('https://pypi.org/simple', 'https://pypi.org/pypi'),\n );\n const normalizedLookupName = normalizePythonDepName(packageName);\n\n // not all simple indexes use this identifier, but most do\n if (hostUrl.endsWith('/simple/') || hostUrl.endsWith('/+simple/')) {\n logger.trace(\n { packageName, hostUrl },\n 'Looking up pypi simple dependency',\n );\n dependency = await this.getSimpleDependency(\n normalizedLookupName,\n hostUrl,\n );\n } else {\n logger.trace({ packageName, hostUrl }, 'Looking up pypi api dependency');\n try {\n // we need to resolve early here so we can catch any 404s and fallback to a simple lookup\n dependency = await this.getDependency(normalizedLookupName, hostUrl);\n } catch (err) {\n // error contacting json-style api -- attempt to fallback to a simple-style api\n logger.trace(\n { packageName, hostUrl, err },\n 'Looking up pypi simple dependency via fallback',\n );\n dependency = await this.getSimpleDependency(\n normalizedLookupName,\n hostUrl,\n );\n }\n }\n return dependency;\n }\n\n private sanitizeLookupUrl(lookupUrl: string, parsedUrl: URL): string {\n if (!parsedUrl.username && !parsedUrl.password) {\n return lookupUrl;\n }\n\n parsedUrl.username = '';\n parsedUrl.password = '';\n return parsedUrl.toString();\n }\n\n private async getAuthHeaders(\n lookupUrl: string,\n ): Promise<{ headers: OutgoingHttpHeaders; lookupUrl: string }> {\n const parsedUrl = parseUrl(lookupUrl);\n // v8 ignore if -- TODO: refactor to cover this branch through public behavior again\n if (!parsedUrl) {\n logger.once.debug({ lookupUrl }, 'Failed to parse URL');\n return { headers: {}, lookupUrl };\n }\n // Only Google Artifact Registry needs a header of our own: for every other host `applyHostRule` already turns the matching host rule into request auth\n if (!isGoogleArtifactRegistry(parsedUrl.hostname)) {\n return { headers: {}, lookupUrl };\n }\n\n const { username, password } = await findPypiIndexCredentials(lookupUrl);\n if (!username && !password) {\n return { headers: {}, lookupUrl };\n }\n\n const auth = toBase64(`${username ?? ''}:${password ?? ''}`);\n addSecretForSanitizing(auth);\n return {\n headers: { authorization: `Basic ${auth}` },\n lookupUrl: this.sanitizeLookupUrl(lookupUrl, parsedUrl),\n };\n }\n\n private async getDependency(\n packageName: string,\n hostUrl: string,\n ): Promise<ReleaseResult | null> {\n const lookupUrl = new URL(\n `${normalizePythonDepName(packageName)}/json`,\n hostUrl,\n ).href;\n const dependency: ReleaseResult = { releases: [] };\n logger.trace({ lookupUrl }, 'Pypi api got lookup');\n const { headers, lookupUrl: sanitizedUrl } =\n await this.getAuthHeaders(lookupUrl);\n const rep = await this.http.getJson(\n sanitizedUrl,\n { headers },\n PypiResponse,\n );\n const dep = rep?.body;\n if (rep.authorization) {\n dependency.isPrivate = true;\n }\n logger.trace({ lookupUrl }, 'Got pypi api result');\n\n if (dep.info?.home_page) {\n dependency.homepage = dep.info.home_page;\n if (isGitHubRepo(dep.info.home_page)) {\n dependency.sourceUrl = dep.info.home_page.replace(\n 'http://',\n 'https://',\n );\n }\n }\n\n if (dep.info?.project_urls) {\n for (const [name, projectUrl] of Object.entries(dep.info.project_urls)) {\n const lower = name.toLowerCase();\n\n if (\n projectUrl &&\n !dependency.sourceUrl &&\n (lower.startsWith('repo') ||\n lower === 'code' ||\n lower === 'source' ||\n isGitHubRepo(projectUrl))\n ) {\n dependency.sourceUrl = projectUrl;\n }\n\n if (\n !dependency.changelogUrl &&\n ([\n 'changelog',\n 'change log',\n 'changes',\n 'release notes',\n 'news',\n \"what's new\",\n ].includes(lower) ||\n changelogFilenameRegex.exec(lower))\n ) {\n // from https://github.com/pypa/warehouse/blob/418c7511dc367fb410c71be139545d0134ccb0df/warehouse/templates/packaging/detail.html#L24\n dependency.changelogUrl = projectUrl;\n }\n }\n }\n\n if (dep.releases) {\n dependency.releases = PypiDatasource.toReleases(dep.releases);\n }\n return dependency;\n }\n\n private static getEarliestTimestamp(\n releases: PypiRelease[],\n ): Timestamp | null {\n let earliest: Timestamp | null = null;\n for (const { upload_time } of releases) {\n const timestamp = asTimestamp(upload_time);\n // `asTimestamp` normalizes to UTC ISO 8601, so comparing the strings compares the instants\n if (timestamp && (!earliest || timestamp < earliest)) {\n earliest = timestamp;\n }\n }\n return earliest;\n }\n\n private static extractVersionFromLinkText(\n text: string,\n packageName: string,\n ): string | null {\n // source packages\n const lcText = text.toLowerCase();\n const normalizedSrcText = normalizePythonDepName(text);\n const srcPrefix = `${packageName}-`;\n\n // source distribution format: `{name}-{version}.tar.gz` (https://packaging.python.org/en/latest/specifications/source-distribution-format/#source-distribution-file-name)\n // binary distribution: `{distribution}-{version}(-{build tag})?-{python tag}-{abi tag}-{platform tag}.whl` (https://packaging.python.org/en/latest/specifications/binary-distribution-format/#file-name-convention)\n // officially both `name` and `distribution` should be normalized and then the - replaced with _, but in reality this is not the case\n // We therefore normalize the name we have (replacing `_-.` with -) and then check if the text starts with the normalized name\n\n if (!normalizedSrcText.startsWith(srcPrefix)) {\n return null;\n }\n\n // strip off the prefix using the prefix length as we may have normalized the srcPrefix/packageName\n // We assume that neither the version nor the suffix contains multiple `-` like `0.1.2---rc1.tar.gz`\n // and use the difference in length to strip off the prefix in case the name contains double `--` characters\n const normalizedLengthDiff = lcText.length - normalizedSrcText.length;\n const res = lcText.slice(srcPrefix.length + normalizedLengthDiff);\n\n // source distribution\n const srcSuffixes = ['.tar.gz', '.tar.bz2', '.tar.xz', '.zip', '.tgz'];\n const srcSuffix = srcSuffixes.find((suffix) => lcText.endsWith(suffix));\n if (srcSuffix) {\n // strip off the suffix using character length\n return res.slice(0, -srcSuffix.length);\n }\n\n // binary distribution\n // for binary distributions the version is the first part after the removed distribution name\n const wheelSuffix = '.whl';\n if (lcText.endsWith(wheelSuffix) && lcText.split('-').length > 2) {\n return res.split('-')[0];\n }\n return null;\n }\n\n private static cleanSimpleHtml(html: string): string {\n return (\n html\n .replace(regEx(/<\\/?pre>/), '')\n // Certain simple repositories like artifactory don't escape > and <\n .replace(\n regEx(/data-requires-python=\"(?<before>[^\"]*?)>(?<after>[^\"]*?)\"/g),\n 'data-requires-python=\"$<before>>$<after>\"',\n )\n .replace(\n regEx(/data-requires-python=\"(?<before>[^\"]*?)<(?<after>[^\"]*?)\"/g),\n 'data-requires-python=\"$<before><$<after>\"',\n )\n );\n }\n\n private static getSimpleReleasesFromHtml(\n html: string,\n packageName: string,\n ): Releases {\n const root = parse(PypiDatasource.cleanSimpleHtml(html));\n const links = root.querySelectorAll('a');\n const releases: Releases = {};\n for (const link of Array.from(links)) {\n const version = PypiDatasource.extractVersionFromLinkText(\n link.text?.trim(),\n packageName,\n );\n if (version) {\n const release: PypiRelease = {\n yanked: link.hasAttribute('data-yanked'),\n };\n const requiresPython = link.getAttribute('data-requires-python');\n if (requiresPython) {\n release.requires_python = requiresPython;\n }\n (releases[version] ??= []).push(release);\n }\n }\n return releases;\n }\n\n private static getSimpleReleasesFromJson(\n json: string,\n packageName: string,\n ): Releases | null {\n const releases: Releases = {};\n const parsed = Json.pipe(PypiSimpleResponse).safeParse(json);\n if (!parsed.success) {\n logger.once.warn(\n { packageName, err: parsed.error },\n 'Failed to parse JSON-based Simple API response',\n );\n // Distinguish a malformed response from a package with genuinely no files, so the caller doesn't mistake an error for an empty result.\n return null;\n }\n for (const file of parsed.data.files) {\n const version = PypiDatasource.extractVersionFromLinkText(\n file.filename,\n packageName,\n );\n if (version) {\n (releases[version] ??= []).push(file);\n }\n }\n return releases;\n }\n\n private async getSimpleDependency(\n packageName: string,\n hostUrl: string,\n ): Promise<ReleaseResult | null> {\n const lookupUrl = new URL(\n ensureTrailingSlash(normalizePythonDepName(packageName)),\n hostUrl,\n ).href;\n const dependency: ReleaseResult = { releases: [] };\n const { headers: authHeaders, lookupUrl: sanitizedUrl } =\n await this.getAuthHeaders(lookupUrl);\n const headers: OutgoingHttpHeaders = {\n ...authHeaders,\n // Request the JSON serialization (PEP 691), falling back to the legacy HTML serialization (PEP 503) via content negotiation.\n // https://github.com/pypa/pip/blob/6b0011b49a068c62f65389bf4cea7af5d28cb002/src/pip/_internal/index/collector.py#L128-L134\n accept:\n 'application/vnd.pypi.simple.v1+json, application/vnd.pypi.simple.v1+html; q=0.1, text/html; q=0.01',\n };\n let response: HttpResponse;\n try {\n response = await this.http.getText(sanitizedUrl, { headers });\n } catch (err) {\n // An `abortOnError` host rule makes `Http` wrap the original error, so unwrap it before looking at the status code.\n const httpErr = err instanceof ExternalHostError ? err.err : err;\n const statusCode =\n httpErr instanceof HttpError ? httpErr.response?.statusCode : undefined;\n // A registry which cannot serve any of the negotiated types may pick a content type of its own, answer `406`, or answer `300`; the spec mandates none of them, but `406` is the common choice.\n // https://packaging.python.org/en/latest/specifications/simple-repository-api/#version-format-selection\n // Retry once without the negotiated `accept` header to preserve the pre-PEP-691 behaviour of a plain request.\n if (statusCode !== 406) {\n throw err;\n }\n\n logger.trace(\n { packageName, hostUrl, statusCode },\n 'Registry rejected negotiated Accept header, retrying without it',\n );\n response = await this.http.getText(sanitizedUrl, {\n headers: authHeaders,\n });\n }\n const dep = response?.body;\n if (!dep) {\n logger.trace({ dependency: packageName }, 'pip package not found');\n return null;\n }\n if (response.authorization) {\n dependency.isPrivate = true;\n }\n\n // Dispatch on the response content-type: JSON serialization (PEP 691) or the legacy HTML serialization (PEP 503). Matched loosely (any `json` media type) rather than the exact vendor type, as some registries/proxies relabel or strip the vendor-specific media type while still returning JSON.\n const contentType = response.headers['content-type'];\n const isJson = !!contentType && contentType.includes('json');\n const looksLikeJson = dep.trimStart().startsWith('{');\n\n if (isJson) {\n if (looksLikeJson) {\n const releases = PypiDatasource.getSimpleReleasesFromJson(\n dep,\n packageName,\n );\n // A parse failure is distinct from a package with genuinely no files, so don't report an empty release list as if it were a real (if empty) result, which would be cached as such.\n if (!releases) {\n return null;\n }\n dependency.releases = PypiDatasource.toReleases(releases);\n return dependency;\n }\n\n // The registry mislabeled a non-JSON body as JSON, so fall through to the HTML parser instead of reporting the package as not found.\n logger.debug(\n { packageName, hostUrl, contentType },\n 'Parsing Simple API response as HTML, as it is labeled as JSON but does not look like it',\n );\n }\n\n const htmlReleases = PypiDatasource.getSimpleReleasesFromHtml(\n dep,\n packageName,\n );\n dependency.releases = PypiDatasource.toReleases(htmlReleases);\n if (dependency.releases.length > 0 || !looksLikeJson) {\n return dependency;\n }\n\n // The registry honored the `Accept` header but omitted or mislabeled the `content-type`, so a JSON body went through the HTML parser and found nothing. Parse it as JSON instead of silently reporting no releases.\n logger.debug(\n { packageName, hostUrl, contentType },\n 'Retrying Simple API response as JSON, as it is not labeled as JSON but looks like it',\n );\n const jsonReleases = PypiDatasource.getSimpleReleasesFromJson(\n dep,\n packageName,\n );\n if (!jsonReleases) {\n return null;\n }\n dependency.releases = PypiDatasource.toReleases(jsonReleases);\n return dependency;\n }\n\n /**\n * The files of a version are not ordered by upload time, so use the earliest one: that is when the version was first published, which is what `minimumReleaseAge` needs.\n */\n private static toReleases(releases: Releases): Release[] {\n const versions = Object.keys(releases);\n return versions.map((version) => {\n const versionReleases = coerceArray(releases[version]);\n const isDeprecated = versionReleases.some(({ yanked }) => yanked);\n const result: Release = { version };\n const releaseTimestamp =\n PypiDatasource.getEarliestTimestamp(versionReleases);\n if (releaseTimestamp) {\n result.releaseTimestamp = releaseTimestamp;\n }\n if (isDeprecated) {\n result.isDeprecated = isDeprecated;\n }\n const pythonConstraints = versionReleases.map(\n ({ requires_python }) => requires_python,\n );\n // A file without `requires_python` can be installed on any Python version, so the version as a whole is unconstrained\n const isUnconstrained = pythonConstraints.some(\n (constraint) => !isNonEmptyString(constraint),\n );\n // There may be multiple releases with different requires_python, so we return all in an array.\n // Report no constraints at all for an unconstrained version, instead of only those of its other files, which would drop the version under `constraintsFiltering=strict`.\n result.constraints = {\n python: isUnconstrained\n ? []\n : deduplicateArray(pythonConstraints.filter(isNonEmptyString)),\n };\n return result;\n });\n }\n}\n"],"mappings":"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"}
|
|
@@ -51,6 +51,12 @@ function resolvePaginationUrl(baseUrl, nextUrl, allowCrossOrigin) {
|
|
|
51
51
|
function isArtifactoryServer(res) {
|
|
52
52
|
return isString(res?.headers[JFROG_ARTIFACTORY_RES_HEADER]);
|
|
53
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* Whether the host is a Google Artifact Registry endpoint, which authenticates with a short-lived Google access token instead of static credentials.
|
|
56
|
+
*/
|
|
57
|
+
function isGoogleArtifactRegistry(hostname) {
|
|
58
|
+
return hostname.endsWith(".pkg.dev");
|
|
59
|
+
}
|
|
54
60
|
async function getGoogleAuthHostRule() {
|
|
55
61
|
try {
|
|
56
62
|
const accessToken = await new GoogleAuth({ scopes: "https://www.googleapis.com/auth/cloud-platform" }).getAccessToken();
|
|
@@ -78,6 +84,6 @@ async function getGoogleAuthToken() {
|
|
|
78
84
|
return null;
|
|
79
85
|
}
|
|
80
86
|
//#endregion
|
|
81
|
-
export { getGoogleAuthHostRule, getGoogleAuthToken, isArtifactoryServer, isCrossOriginPaginationAllowed, resolvePaginationUrl };
|
|
87
|
+
export { getGoogleAuthHostRule, getGoogleAuthToken, isArtifactoryServer, isCrossOriginPaginationAllowed, isGoogleArtifactRegistry, resolvePaginationUrl };
|
|
82
88
|
|
|
83
89
|
//# sourceMappingURL=util.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.js","names":[],"sources":["../../../lib/modules/datasource/util.ts"],"sourcesContent":["import { isString } from '@sindresorhus/is';\nimport { GoogleAuth } from 'google-auth-library';\nimport { logger } from '../../logger/index.ts';\nimport type { HostRule } from '../../types/index.ts';\nimport { getEnv } from '../../util/env.ts';\nimport type { HttpResponse } from '../../util/http/types.ts';\nimport { addSecretForSanitizing } from '../../util/sanitize.ts';\nimport { parseUrl, resolveSameOriginUrl } from '../../util/url.ts';\n\nconst JFROG_ARTIFACTORY_RES_HEADER = 'x-jfrog-version';\n\n/**\n * Experimental, per-datasource env var that opts a datasource into following\n * server-provided pagination links across origins. Each datasource has its own\n * flag so relaxing the restriction for one registry cannot weaken the others.\n */\nconst crossOriginPaginationEnv: Record<string, string> = {\n docker: 'RENOVATE_X_DOCKER_PAGINATION_ALLOW_CROSS_ORIGIN',\n nuget: 'RENOVATE_X_NUGET_PAGINATION_ALLOW_CROSS_ORIGIN',\n};\n\n/**\n * Whether a datasource is opted in to following server-provided pagination\n * links across origins, via its experimental `RENOVATE_X_<DATASOURCE>_PAGINATION_ALLOW_CROSS_ORIGIN`\n * env var.\n *\n * By default such links are restricted to the same origin as the request so a\n * malicious or compromised registry cannot attempt to redirect our requests in an attempt for Server Side Request Forgery.\n */\nexport function isCrossOriginPaginationAllowed(datasource: string): boolean {\n const envVar = crossOriginPaginationEnv[datasource];\n return envVar ? !!getEnv()[envVar] : false;\n}\n\n/**\n * Resolves a server-provided pagination `next` URL against `baseUrl`, returning\n * the URL to follow or `null` if it must not be followed.\n *\n * When `allowCrossOrigin` is false (the default; see\n * {@link isCrossOriginPaginationAllowed}) the link is dropped unless it stays on\n * the same origin. When true, the link is followed regardless of origin.\n */\nexport function resolvePaginationUrl(\n baseUrl: string,\n nextUrl: string,\n allowCrossOrigin: boolean,\n): string | null {\n if (!allowCrossOrigin) {\n return resolveSameOriginUrl(baseUrl, nextUrl);\n }\n try {\n const resolved = new URL(nextUrl, baseUrl).href;\n if (parseUrl(baseUrl)?.origin !== parseUrl(resolved)?.origin) {\n logger.once.warn(\n { baseUrl, nextUrl },\n 'Following cross-origin pagination link',\n );\n }\n return resolved;\n } catch {\n return null;\n }\n}\n\nexport function isArtifactoryServer<T = unknown>(\n res: HttpResponse<T> | undefined,\n): boolean {\n return isString(res?.headers[JFROG_ARTIFACTORY_RES_HEADER]);\n}\n\nexport async function getGoogleAuthHostRule(): Promise<HostRule | null> {\n try {\n const googleAuth: GoogleAuth = new GoogleAuth({\n scopes: 'https://www.googleapis.com/auth/cloud-platform',\n });\n const accessToken = await googleAuth.getAccessToken();\n if (accessToken) {\n // sanitize token\n addSecretForSanitizing(accessToken);\n return {\n username: 'oauth2accesstoken',\n password: accessToken,\n };\n }\n logger.warn(\n 'Could not retrieve access token using google-auth-library getAccessToken',\n );\n } catch (err) {\n if (err.message?.includes('Could not load the default credentials')) {\n return null;\n }\n throw err;\n }\n return null;\n}\n\nexport async function getGoogleAuthToken(): Promise<string | null> {\n const rule = await getGoogleAuthHostRule();\n if (rule) {\n const token = Buffer.from(`${rule.username}:${rule.password}`).toString(\n 'base64',\n );\n addSecretForSanitizing(token);\n return token;\n }\n return null;\n}\n"],"mappings":";;;;;;;AASA,MAAM,+BAA+B;;;;;;AAOrC,MAAM,2BAAmD;CACvD,QAAQ;CACR,OAAO;AACT;;;;;;;;;AAUA,SAAgB,+BAA+B,YAA6B;CAC1E,MAAM,SAAS,yBAAyB;CACxC,OAAO,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU;AACvC;;;;;;;;;AAUA,SAAgB,qBACd,SACA,SACA,kBACe;CACf,IAAI,CAAC,kBACH,OAAO,qBAAqB,SAAS,OAAO;CAE9C,IAAI;EACF,MAAM,WAAW,IAAI,IAAI,SAAS,OAAO,CAAC,CAAC;EAC3C,IAAI,SAAS,OAAO,CAAC,EAAE,WAAW,SAAS,QAAQ,CAAC,EAAE,QACpD,OAAO,KAAK,KACV;GAAE;GAAS;EAAQ,GACnB,wCACF;EAEF,OAAO;CACT,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAgB,oBACd,KACS;CACT,OAAO,SAAS,KAAK,QAAQ,6BAA6B;AAC5D;AAEA,eAAsB,wBAAkD;CACtE,IAAI;EAIF,MAAM,cAAc,MAAM,IAHS,WAAW,EAC5C,QAAQ,iDACV,CACmC,CAAC,CAAC,eAAe;EACpD,IAAI,aAAa;GAEf,uBAAuB,WAAW;GAClC,OAAO;IACL,UAAU;IACV,UAAU;GACZ;EACF;EACA,OAAO,KACL,0EACF;CACF,SAAS,KAAK;EACZ,IAAI,IAAI,SAAS,SAAS,wCAAwC,GAChE,OAAO;EAET,MAAM;CACR;CACA,OAAO;AACT;AAEA,eAAsB,qBAA6C;CACjE,MAAM,OAAO,MAAM,sBAAsB;CACzC,IAAI,MAAM;EACR,MAAM,QAAQ,OAAO,KAAK,GAAG,KAAK,SAAS,GAAG,KAAK,UAAU,CAAC,CAAC,SAC7D,QACF;EACA,uBAAuB,KAAK;EAC5B,OAAO;CACT;CACA,OAAO;AACT"}
|
|
1
|
+
{"version":3,"file":"util.js","names":[],"sources":["../../../lib/modules/datasource/util.ts"],"sourcesContent":["import { isString } from '@sindresorhus/is';\nimport { GoogleAuth } from 'google-auth-library';\nimport { logger } from '../../logger/index.ts';\nimport type { HostRule } from '../../types/index.ts';\nimport { getEnv } from '../../util/env.ts';\nimport type { HttpResponse } from '../../util/http/types.ts';\nimport { addSecretForSanitizing } from '../../util/sanitize.ts';\nimport { parseUrl, resolveSameOriginUrl } from '../../util/url.ts';\n\nconst JFROG_ARTIFACTORY_RES_HEADER = 'x-jfrog-version';\n\n/**\n * Experimental, per-datasource env var that opts a datasource into following\n * server-provided pagination links across origins. Each datasource has its own\n * flag so relaxing the restriction for one registry cannot weaken the others.\n */\nconst crossOriginPaginationEnv: Record<string, string> = {\n docker: 'RENOVATE_X_DOCKER_PAGINATION_ALLOW_CROSS_ORIGIN',\n nuget: 'RENOVATE_X_NUGET_PAGINATION_ALLOW_CROSS_ORIGIN',\n};\n\n/**\n * Whether a datasource is opted in to following server-provided pagination\n * links across origins, via its experimental `RENOVATE_X_<DATASOURCE>_PAGINATION_ALLOW_CROSS_ORIGIN`\n * env var.\n *\n * By default such links are restricted to the same origin as the request so a\n * malicious or compromised registry cannot attempt to redirect our requests in an attempt for Server Side Request Forgery.\n */\nexport function isCrossOriginPaginationAllowed(datasource: string): boolean {\n const envVar = crossOriginPaginationEnv[datasource];\n return envVar ? !!getEnv()[envVar] : false;\n}\n\n/**\n * Resolves a server-provided pagination `next` URL against `baseUrl`, returning\n * the URL to follow or `null` if it must not be followed.\n *\n * When `allowCrossOrigin` is false (the default; see\n * {@link isCrossOriginPaginationAllowed}) the link is dropped unless it stays on\n * the same origin. When true, the link is followed regardless of origin.\n */\nexport function resolvePaginationUrl(\n baseUrl: string,\n nextUrl: string,\n allowCrossOrigin: boolean,\n): string | null {\n if (!allowCrossOrigin) {\n return resolveSameOriginUrl(baseUrl, nextUrl);\n }\n try {\n const resolved = new URL(nextUrl, baseUrl).href;\n if (parseUrl(baseUrl)?.origin !== parseUrl(resolved)?.origin) {\n logger.once.warn(\n { baseUrl, nextUrl },\n 'Following cross-origin pagination link',\n );\n }\n return resolved;\n } catch {\n return null;\n }\n}\n\nexport function isArtifactoryServer<T = unknown>(\n res: HttpResponse<T> | undefined,\n): boolean {\n return isString(res?.headers[JFROG_ARTIFACTORY_RES_HEADER]);\n}\n\n/**\n * Whether the host is a Google Artifact Registry endpoint, which authenticates with a short-lived Google access token instead of static credentials.\n */\nexport function isGoogleArtifactRegistry(hostname: string): boolean {\n return hostname.endsWith('.pkg.dev');\n}\n\nexport async function getGoogleAuthHostRule(): Promise<HostRule | null> {\n try {\n const googleAuth: GoogleAuth = new GoogleAuth({\n scopes: 'https://www.googleapis.com/auth/cloud-platform',\n });\n const accessToken = await googleAuth.getAccessToken();\n if (accessToken) {\n // sanitize token\n addSecretForSanitizing(accessToken);\n return {\n username: 'oauth2accesstoken',\n password: accessToken,\n };\n }\n logger.warn(\n 'Could not retrieve access token using google-auth-library getAccessToken',\n );\n } catch (err) {\n if (err.message?.includes('Could not load the default credentials')) {\n return null;\n }\n throw err;\n }\n return null;\n}\n\nexport async function getGoogleAuthToken(): Promise<string | null> {\n const rule = await getGoogleAuthHostRule();\n if (rule) {\n const token = Buffer.from(`${rule.username}:${rule.password}`).toString(\n 'base64',\n );\n addSecretForSanitizing(token);\n return token;\n }\n return null;\n}\n"],"mappings":";;;;;;;AASA,MAAM,+BAA+B;;;;;;AAOrC,MAAM,2BAAmD;CACvD,QAAQ;CACR,OAAO;AACT;;;;;;;;;AAUA,SAAgB,+BAA+B,YAA6B;CAC1E,MAAM,SAAS,yBAAyB;CACxC,OAAO,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU;AACvC;;;;;;;;;AAUA,SAAgB,qBACd,SACA,SACA,kBACe;CACf,IAAI,CAAC,kBACH,OAAO,qBAAqB,SAAS,OAAO;CAE9C,IAAI;EACF,MAAM,WAAW,IAAI,IAAI,SAAS,OAAO,CAAC,CAAC;EAC3C,IAAI,SAAS,OAAO,CAAC,EAAE,WAAW,SAAS,QAAQ,CAAC,EAAE,QACpD,OAAO,KAAK,KACV;GAAE;GAAS;EAAQ,GACnB,wCACF;EAEF,OAAO;CACT,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAgB,oBACd,KACS;CACT,OAAO,SAAS,KAAK,QAAQ,6BAA6B;AAC5D;;;;AAKA,SAAgB,yBAAyB,UAA2B;CAClE,OAAO,SAAS,SAAS,UAAU;AACrC;AAEA,eAAsB,wBAAkD;CACtE,IAAI;EAIF,MAAM,cAAc,MAAM,IAHS,WAAW,EAC5C,QAAQ,iDACV,CACmC,CAAC,CAAC,eAAe;EACpD,IAAI,aAAa;GAEf,uBAAuB,WAAW;GAClC,OAAO;IACL,UAAU;IACV,UAAU;GACZ;EACF;EACA,OAAO,KACL,0EACF;CACF,SAAS,KAAK;EACZ,IAAI,IAAI,SAAS,SAAS,wCAAwC,GAChE,OAAO;EAET,MAAM;CACR;CACA,OAAO;AACT;AAEA,eAAsB,qBAA6C;CACjE,MAAM,OAAO,MAAM,sBAAsB;CACzC,IAAI,MAAM;EACR,MAAM,QAAQ,OAAO,KAAK,GAAG,KAAK,SAAS,GAAG,KAAK,UAAU,CAAC,CAAC,SAC7D,QACF;EACA,uBAAuB,KAAK;EAC5B,OAAO;CACT;CACA,OAAO;AACT"}
|
|
@@ -56,7 +56,7 @@ hashMap.set("helm-requirements", "7ee9dace4c036dfe113c0c0e46369d8b83a739caa83166
|
|
|
56
56
|
hashMap.set("helm-values", "0aa79bb0257d0d72e54dfd2653e59bfef63b97e46c035b7443593bdf6e6382aa");
|
|
57
57
|
hashMap.set("helmfile", "28572dd24b6746ca7065ee467aa13bbc8c3e8c0f88ae48e33bce88468c600100");
|
|
58
58
|
hashMap.set("helmsman", "951deeb3355da751ef39c9e932b26ea749450e32e75759e4b5fc29359e100b37");
|
|
59
|
-
hashMap.set("helmv3", "
|
|
59
|
+
hashMap.set("helmv3", "e2d464055503d3702d3cf7323ce593747fe482def8ee59aea2dcaadb0bb0f72c");
|
|
60
60
|
hashMap.set("hermit", "0fb25b7766c3a264fbb765ff75b1542b24136c4c9f933696d4a5aecfed637071");
|
|
61
61
|
hashMap.set("homeassistant-manifest", "05043c6db870cffbb6f8f3e351c025e3de227eaae0b24134b796aec46f84b65f");
|
|
62
62
|
hashMap.set("homebrew", "dffe954a4e18c2dc4bfdaa12222fe8ddc3395869afd5afa603fc2b6264747984");
|
|
@@ -82,12 +82,12 @@ hashMap.set("ocb", "032b216684c14b0954e0bb019513a2aca3faaee5748587acb668d377d7c8
|
|
|
82
82
|
hashMap.set("osgi", "d6567a733ef3983112b46fdccd7ceebfcd48411104e0c6b6e714d4310db48024");
|
|
83
83
|
hashMap.set("pep621", "52450676f8b0e05134b3e8947b832195ef40bcaec1ce43d71351a2f797b80d75");
|
|
84
84
|
hashMap.set("pep723", "77022a0eae6a3cbb74a1e6d596db1276e379768e40448192b3fa81edd14ca73f");
|
|
85
|
-
hashMap.set("pip-compile", "
|
|
85
|
+
hashMap.set("pip-compile", "a98dc76a002e1dc21662237f009ff8fea36236bb4e24cb82ee30c6a78f57271f");
|
|
86
86
|
hashMap.set("pip_requirements", "bf3a407f72abf711230247bef94ba5dc84c08a35107b0f017912fad66afa716a");
|
|
87
87
|
hashMap.set("pip_setup", "df18fba2bdcf48f3ca12a8f7e5cd28df31e2368d5528127277038ef4206eca79");
|
|
88
|
-
hashMap.set("pipenv", "
|
|
88
|
+
hashMap.set("pipenv", "baf237cd77173c1a7a9c7fa2a8bfb214f3c488ba0cc27f0e8f334df192e3a398");
|
|
89
89
|
hashMap.set("pixi", "e31c397982ffa34222b061f23f3b3683f42523dd5dca45ecce2448b0ebc55ea2");
|
|
90
|
-
hashMap.set("poetry", "
|
|
90
|
+
hashMap.set("poetry", "e9dea5d591c87956b9f018414cb3dab8f2e13580a13be00550fdce198fdf08e6");
|
|
91
91
|
hashMap.set("pre-commit", "760f2c291ae084db889f722390798a0e2d431ccdc3bc676e73b14901ebea19ac");
|
|
92
92
|
hashMap.set("proto", "412053d4550026b4ace490b46e970915b87ec1abf0b0a0c6c8c58ccf1fc16843");
|
|
93
93
|
hashMap.set("pub", "8e7c65dfd1999de4f7c44392e949a4d8f4701eb86df59d550e4657feb06b1872");
|
|
@@ -103,7 +103,7 @@ hashMap.set("scalafmt", "9d36159b56835e96498af026a1fb0543200db0581681ef95ec54988
|
|
|
103
103
|
hashMap.set("setup-cfg", "4a3a7c812d34739c07685691e7e64c7d3127f9d7d4aff99dc45a25df97ed9745");
|
|
104
104
|
hashMap.set("smithy", "9641b91d065ffb63be0dd888139a0402dba41e550f8b44c592db9daf52109100");
|
|
105
105
|
hashMap.set("sveltos", "60dd75bb53ace31217211100d622fdb65068c6162758b6ae7103a6ce8bdc9f90");
|
|
106
|
-
hashMap.set("swift", "
|
|
106
|
+
hashMap.set("swift", "cdf063debdbf36888523ff8cec6d2d1b0ec6f49b37b2fbcd80b0d4f6a31114e1");
|
|
107
107
|
hashMap.set("tekton", "33948f5bdf7553909fa63744adb26da97ddf366e9499bccab1250879570267c9");
|
|
108
108
|
hashMap.set("terraform", "5b0037e4a88e06efe6f006eff15c24d9e1fefdda40d282aa99f54c2637d21c4d");
|
|
109
109
|
hashMap.set("terraform-version", "ec8f786b9731d47f2c2fe0307caf64d7ddd83046fe7ff1f7d8423239f8b0f2aa");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fingerprint.generated.js","names":[],"sources":["../../../lib/modules/manager/fingerprint.generated.ts"],"sourcesContent":["export const hashMap = new Map<string, string>();\n\nhashMap.set('ansible','a52394a36ac5517f7330473c31d93aa05b2ce607c5e951b48f25a4693cd20a81');\nhashMap.set('ansible-galaxy','0a264d6be73953d801510fdeff271e4071c274339569c6dab4e2a128eaf4869f');\nhashMap.set('ant','2df5943cf0ed19a21b94df13729dbb925655548130caf37e3e22bebaed518e17');\nhashMap.set('apm','bdb6931cc03f4ac02ebfdb56c4b3483bb6c5250fa952545f1a25584d502bbffd');\nhashMap.set('argocd','cff9cd22257bc460ae4b9936570bf0ed5585f280a55d26629deaeeb0bfee8eb5');\nhashMap.set('asdf','430eb99b58171700c8a59c78b9e648575e9b176b781d90dd10a710f7b69015bb');\nhashMap.set('azure-pipelines','a051fe5e7e4fef8208b5864131a2b52b4ae319936f1dd8ee5a4e1ef11359ec09');\nhashMap.set('batect','375d39b432013bedb1330cf40a2199dd822751b28578214f219e7bab98594b8d');\nhashMap.set('batect-wrapper','d999355511ea7f4053325a18b8cfc8d2b586c61e6760c35e557d383a673e3939');\nhashMap.set('bazel','c31bc0a0e23d32726bcc09aa67533ebc5058124bf89c88e09c837419f550801a');\nhashMap.set('bazel-module','9fbba0339f9f7785d52ab85c5f0f6385003093c063483c13feccba13ae438bef');\nhashMap.set('bazelisk','770f75a746dc6ba90c518788d5987d7df4243ef9eee122d1bb0556a93d6e1b11');\nhashMap.set('bicep','7246e0bfc06e0e28cbb03ac088c5591f648956b086e106aeb251fe5d628329db');\nhashMap.set('bitbucket-pipelines','59c0503494ab1442b127914503c01b97ac17b6742b19c632292d5aa24de115cd');\nhashMap.set('bitrise','478dfd316221fad7c29e177c70d1018d832fb2626b53308a5d0f1f0380e69f42');\nhashMap.set('buildkite','b8b404f53cd5d61c39153fddf93945e621471c4ac6aa9960c881cd868922bb4c');\nhashMap.set('buildpacks','6bef3cb04d66b5cfbb195adb4829bcbccae6408518706744d291bacf0610421f');\nhashMap.set('bun','5820cfb6ebe018b8c336d481ea9ae319daaee6a2e368c45196fc8bc67cb3e755');\nhashMap.set('bun-version','df3ae8e4a5de1fa1b4544f3d7fc8117e80adb1e151c46d1ede54a4dbea6521e4');\nhashMap.set('bundler','6e4784dd98c1f86ef64cc8cbf3128df48aebf920032d7792b54fdedd3dd9d4d5');\nhashMap.set('cake','9ebd8b481220b30a8860121d26184540a1a2fcc05ef780df9295dea39b386fad');\nhashMap.set('cargo','fe8136135c895dd08819f91a60cf105f8b951251b057092700101ace991ae1d7');\nhashMap.set('cdnurl','9a81c8e3c6ad6c788498c99fc1067ffdfcd92a427c3afaf8c0130975d83131f2');\nhashMap.set('circleci','91cbeb33ea20f9838e2c81a1195eb806f0b38fa282bc3679f62552f20575ca85');\nhashMap.set('cloudbuild','f4e40388944652c8a19f8518771ac8d3f3c4ccf81ddef0e68b463aca833cb73c');\nhashMap.set('cocoapods','f832e2beef885bb3fd697ed9bb3e8cd742926bfec37ff41212edd2dbb4edb3ba');\nhashMap.set('composer','f1294fb3866ff65a75d98fdef80b1df3d3a8856535b8c690d1799e1205e4b639');\nhashMap.set('conan','8d46e9a30ae628e26118aea10a98d1b846f7c5d96d51ce24693437d555f6d125');\nhashMap.set('copier','10ae4d7f8ff35faf3a3f9f25bf4c969ea960e19aaf8c012aee11f93f4d10533e');\nhashMap.set('cpanfile','07813fec3f3c2197056500e9266a0553b9774c02f2c74d5ca2e213188c7c12d3');\nhashMap.set('crossplane','5c26b1201a1a51454ffb94d829e223a76a781569bf79cdb1e47087c30233ec40');\nhashMap.set('crow','eb9a5f9f95041855dded67bcce3dd54724f690995ed6268d272e8a666ff28fd0');\nhashMap.set('deno','05e7ab60494a20a5e7477f06a9e723e443d37643b6e1d9ba8d3d87126a051175');\nhashMap.set('deps-edn','06783dbc8b9c7bb84e162d1f75b7db56dfa021cc6f809dfd2314cee8b64af08d');\nhashMap.set('devbox','a40050cc61bd9b5d500ec111abb17bb15d5f82ab5b7699f66f628307ba8382c9');\nhashMap.set('devcontainer','24320ed1cb6191d04cb8b2707214d82c08c682597aed1d84f250aa00ad1632ec');\nhashMap.set('docker-compose','fba87b82cb0f2bfd66526631fbe928b8153e7ca701a5790d02b944df17417bb9');\nhashMap.set('dockerfile','78cb1e8b58653289dd4b73425c45495a4c4b41badd3614b8345aaf8ab73de09c');\nhashMap.set('droneci','661d2a2d7295af8dd7a1234c7090c42a89306bd574c3adf1fc67782efaad3998');\nhashMap.set('fleet','4942d52e82f35c41e2d46cf76f426e2d91b350338cfc0bbcb97e8aaae2a1ac0b');\nhashMap.set('flux','aad8c786c4a2b5820663027452eeb8fe84c3af8c8399261e85f0eade2e484fe8');\nhashMap.set('fvm','9b161df0f14bc6e536368952adf373e343630097121a913cea60ee284027fb90');\nhashMap.set('git-submodules','df8bb92b2906d8cddda2d4b302ee503f8002e3554d32d74cef2f584fe891f38f');\nhashMap.set('github-actions','7adddc8e590786084855ffe53292bff3098ac672f91c21cc39d45bcf0af2271f');\nhashMap.set('gitlabci','a5e1e66ef461e1c1e71062f85f35a212417e23627f4b002810f9a98295d6e672');\nhashMap.set('gitlabci-include','8860a15ab516fde00694f9bd9bf56fce4addafe5a55b5ddb9a4ec477d301d351');\nhashMap.set('glasskube','93e7b9000a17efa15a1abaaf320b5af9169b1ecd828fc0c881d98570ef9d9e30');\nhashMap.set('gleam','5e9b9f5f914afe5ed7b526c06c65111e3716d2dea9b0cbe7907bbc96db1064a3');\nhashMap.set('gomod','de042f3b5a900346c5f2df41f793f1716dc12145c38705c3064c6a7150b49495');\nhashMap.set('gradle','9e3ff52ce4ad2555929acdd4d32c417c4ef8714c23a92f2893ecc580fa4d6064');\nhashMap.set('gradle-wrapper','73ba30c34955fab7737454b5cff9aca6d1b5607d53c17c9e13d8ad96f6eaae87');\nhashMap.set('haskell-cabal','f158b7725e3143dfd2950e3de0bbccc2a61cd7eba87f7a54c5057e01252348e2');\nhashMap.set('helm-requirements','7ee9dace4c036dfe113c0c0e46369d8b83a739caa831660142ca98d3236a180a');\nhashMap.set('helm-values','0aa79bb0257d0d72e54dfd2653e59bfef63b97e46c035b7443593bdf6e6382aa');\nhashMap.set('helmfile','28572dd24b6746ca7065ee467aa13bbc8c3e8c0f88ae48e33bce88468c600100');\nhashMap.set('helmsman','951deeb3355da751ef39c9e932b26ea749450e32e75759e4b5fc29359e100b37');\nhashMap.set('helmv3','4a3cf47072978eb131d70cd13f3d0bbd4408b0290be2a798a4cbf6103189269b');\nhashMap.set('hermit','0fb25b7766c3a264fbb765ff75b1542b24136c4c9f933696d4a5aecfed637071');\nhashMap.set('homeassistant-manifest','05043c6db870cffbb6f8f3e351c025e3de227eaae0b24134b796aec46f84b65f');\nhashMap.set('homebrew','dffe954a4e18c2dc4bfdaa12222fe8ddc3395869afd5afa603fc2b6264747984');\nhashMap.set('html','81fa6c2bf2b868596584a48b949645207a2aa3081951ed99183ee50b70b77d5f');\nhashMap.set('jenkins','7fda0e7e0f3d5e18088ccb3594f727f4cfc48b064706bdaaf1a0a075b6a2cff5');\nhashMap.set('jsonnet-bundler','4cedeb0394e5c38361d1868ff45b4f34747ab8c492378b6e63dcaf1f4f3c024d');\nhashMap.set('kotlin-script','95ebc844c040ca047321b207d525220e29774a2a1fe06f9639e8353c66908564');\nhashMap.set('kubernetes','321e7d77fb3600dd4c00a86eaa1294927e7f92300b74fa2977d813dcaa3bb4de');\nhashMap.set('kustomize','aa830c27302555e12d7f04e342c96125d68c231028a2d3c459c4431516382584');\nhashMap.set('leiningen','c8397e376f1717c2f771ae9ea3ba6b720d2422b133cf937e762c44e42be146a2');\nhashMap.set('maven','c110b99291c2a5bc82cf7a69330275e9bbd7dc8ba3e9e987611dfcffbe002d8d');\nhashMap.set('maven-wrapper','6e53b6e4abf1d20b75094c7a70d66b4a5ac39954f009aa401f5e55dada8be4d0');\nhashMap.set('meteor','4636a47ba4dcfff19fe662572ef7a40d17146be3c966e00ef437e1fc8de92776');\nhashMap.set('mint','248fe4f1ea5c985921c286785792c97e06fc41f402b2d45df82f6aecd17f710e');\nhashMap.set('mise','279da4690751c3abee10badd12eb4ac6ef31d824c6bd3ada824859eca3109ebe');\nhashMap.set('mix','0f79163dc2a1c896599d152be635c23beaf16812ae3d8fbfffec98c7bd0de872');\nhashMap.set('nix','0f80f0b81f2197a7e588be5c115a32a826fc184593f4e879f7b60fafd97a977e');\nhashMap.set('nodenv','ac652c28481b001f7471f4183eac07b45d98ecbe83efc275830b0a1b2e0459b8');\nhashMap.set('npm','30c78bc1c29eeecbdedb4eacc52bd93eedfb07279fd385f893193dcac6196466');\nhashMap.set('nuget','b81fb0ca6cfeb86b004592b38ce176673e056d6a2ed41a9807afb0eb7ad405d2');\nhashMap.set('nvm','3eb77c7b0acf6d64753de78fad2499b352719853aa6872878c40675d14152322');\nhashMap.set('ocb','032b216684c14b0954e0bb019513a2aca3faaee5748587acb668d377d7c891ca');\nhashMap.set('osgi','d6567a733ef3983112b46fdccd7ceebfcd48411104e0c6b6e714d4310db48024');\nhashMap.set('pep621','52450676f8b0e05134b3e8947b832195ef40bcaec1ce43d71351a2f797b80d75');\nhashMap.set('pep723','77022a0eae6a3cbb74a1e6d596db1276e379768e40448192b3fa81edd14ca73f');\nhashMap.set('pip-compile','7e418b8bdaeed38c1372eb19e0ae1c64999000e128d8754e37368638037b4c5c');\nhashMap.set('pip_requirements','bf3a407f72abf711230247bef94ba5dc84c08a35107b0f017912fad66afa716a');\nhashMap.set('pip_setup','df18fba2bdcf48f3ca12a8f7e5cd28df31e2368d5528127277038ef4206eca79');\nhashMap.set('pipenv','cd974eadd649ba8c9c2e3c7b564a49c8bb2ce95d6df043a7e942364f574c7613');\nhashMap.set('pixi','e31c397982ffa34222b061f23f3b3683f42523dd5dca45ecce2448b0ebc55ea2');\nhashMap.set('poetry','b2b917c200d25e01a3a198deb3bf33353535f27430142111cfab816c03bb966d');\nhashMap.set('pre-commit','760f2c291ae084db889f722390798a0e2d431ccdc3bc676e73b14901ebea19ac');\nhashMap.set('proto','412053d4550026b4ace490b46e970915b87ec1abf0b0a0c6c8c58ccf1fc16843');\nhashMap.set('pub','8e7c65dfd1999de4f7c44392e949a4d8f4701eb86df59d550e4657feb06b1872');\nhashMap.set('puppet','ba58ab689e44acc8f61c3569ab8b40fde01b8a9d3aad712708e2a419e57d8b45');\nhashMap.set('pyenv','9ede8becc97774f9040b40f4472d3e933534b596e04c360bfe0f3c6f95f25182');\nhashMap.set('quadlet','e1fc88a4e14cd595e89bb3d79b4adf2add3ce5eb80f75276e712c32598cca53d');\nhashMap.set('renovate-config','dfaf3f03ddaf70c332f7916106648f36dbfa6a36dd76d15dd27fa116ab3c174c');\nhashMap.set('ruby-version','2db2140d9eee8c555e729a4de0396fa2d78846d3149890ee12fa515bd654be97');\nhashMap.set('runtime-version','b582b168c0cc595e39010feb10f4b97a82683eb269e9598216fbb11cc186e160');\nhashMap.set('rust-toolchain','6ace53db02874d73620d2d872291839820a512a9529c42d174358c692e5db720');\nhashMap.set('sbt','e1eb5c7f0171a9bb1b6bd4a36a91039a31b6c84e0983d91d930be31a69506d9e');\nhashMap.set('scalafmt','9d36159b56835e96498af026a1fb0543200db0581681ef95ec54988f411e180f');\nhashMap.set('setup-cfg','4a3a7c812d34739c07685691e7e64c7d3127f9d7d4aff99dc45a25df97ed9745');\nhashMap.set('smithy','9641b91d065ffb63be0dd888139a0402dba41e550f8b44c592db9daf52109100');\nhashMap.set('sveltos','60dd75bb53ace31217211100d622fdb65068c6162758b6ae7103a6ce8bdc9f90');\nhashMap.set('swift','6932c904b0d18ad4845c46ce3f7d4c54dd8e411e16c31a782b399fe0b7dc550b');\nhashMap.set('tekton','33948f5bdf7553909fa63744adb26da97ddf366e9499bccab1250879570267c9');\nhashMap.set('terraform','5b0037e4a88e06efe6f006eff15c24d9e1fefdda40d282aa99f54c2637d21c4d');\nhashMap.set('terraform-version','ec8f786b9731d47f2c2fe0307caf64d7ddd83046fe7ff1f7d8423239f8b0f2aa');\nhashMap.set('terragrunt','300f8fb3c09667654412d2f5dd8ab4882e0f5d1d7a8bc39794993d2e7e58d1b7');\nhashMap.set('terragrunt-version','eea6087b33717d22ede2fc68c2f64df8390b75abe82110ed831a180648feb51d');\nhashMap.set('tflint-plugin','f423bfa2b42a2bfc0e38a33ebd4f9d452473e7ed4e7ad6384a99eb9a35d97479');\nhashMap.set('travis','f3e2f38e699c390b00ff481be5e91dceaa81609e93caf9a4214933de759c84fc');\nhashMap.set('typst','d080a79fbd961c6e21fcc505d544b7e0ff2126142acb1dcabdf6abbcd9339248');\nhashMap.set('unity3d','f13e25e115e3443f4e16cf31578acffa78fb1a5e23339680a92d8d6de6052920');\nhashMap.set('velaci','fda00ddb7cc23e9a37e0a8a253151df0a6930b4276d3e4f78cc54b9ac09af7de');\nhashMap.set('vendir','7db907b3b77ef5f3465f3c4339fbab56bbcdfd1bf34b3d33e4c178d2e07e23e7');\nhashMap.set('woodpecker','6110d3bec33aaeb3511d4bbfa896cec3c8e02fb04a6cff50c9ba81061c851045');\nhashMap.set('xcodegen','dad511d88a9ce1dbdde8b9731f3da7f2bdaa4ca8a083294ee58d56da62ab1683');\nhashMap.set('jsonata','416bcf61144b276b3112814c6e6d261aa29608f46fbb0516c471d35c16f8f0d7');\nhashMap.set('regex','20be5247fdc164173871a051acb0527da017d0c155c653d7563601f55e7b3ff5');"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"fingerprint.generated.js","names":[],"sources":["../../../lib/modules/manager/fingerprint.generated.ts"],"sourcesContent":["export const hashMap = new Map<string, string>();\n\nhashMap.set('ansible','a52394a36ac5517f7330473c31d93aa05b2ce607c5e951b48f25a4693cd20a81');\nhashMap.set('ansible-galaxy','0a264d6be73953d801510fdeff271e4071c274339569c6dab4e2a128eaf4869f');\nhashMap.set('ant','2df5943cf0ed19a21b94df13729dbb925655548130caf37e3e22bebaed518e17');\nhashMap.set('apm','bdb6931cc03f4ac02ebfdb56c4b3483bb6c5250fa952545f1a25584d502bbffd');\nhashMap.set('argocd','cff9cd22257bc460ae4b9936570bf0ed5585f280a55d26629deaeeb0bfee8eb5');\nhashMap.set('asdf','430eb99b58171700c8a59c78b9e648575e9b176b781d90dd10a710f7b69015bb');\nhashMap.set('azure-pipelines','a051fe5e7e4fef8208b5864131a2b52b4ae319936f1dd8ee5a4e1ef11359ec09');\nhashMap.set('batect','375d39b432013bedb1330cf40a2199dd822751b28578214f219e7bab98594b8d');\nhashMap.set('batect-wrapper','d999355511ea7f4053325a18b8cfc8d2b586c61e6760c35e557d383a673e3939');\nhashMap.set('bazel','c31bc0a0e23d32726bcc09aa67533ebc5058124bf89c88e09c837419f550801a');\nhashMap.set('bazel-module','9fbba0339f9f7785d52ab85c5f0f6385003093c063483c13feccba13ae438bef');\nhashMap.set('bazelisk','770f75a746dc6ba90c518788d5987d7df4243ef9eee122d1bb0556a93d6e1b11');\nhashMap.set('bicep','7246e0bfc06e0e28cbb03ac088c5591f648956b086e106aeb251fe5d628329db');\nhashMap.set('bitbucket-pipelines','59c0503494ab1442b127914503c01b97ac17b6742b19c632292d5aa24de115cd');\nhashMap.set('bitrise','478dfd316221fad7c29e177c70d1018d832fb2626b53308a5d0f1f0380e69f42');\nhashMap.set('buildkite','b8b404f53cd5d61c39153fddf93945e621471c4ac6aa9960c881cd868922bb4c');\nhashMap.set('buildpacks','6bef3cb04d66b5cfbb195adb4829bcbccae6408518706744d291bacf0610421f');\nhashMap.set('bun','5820cfb6ebe018b8c336d481ea9ae319daaee6a2e368c45196fc8bc67cb3e755');\nhashMap.set('bun-version','df3ae8e4a5de1fa1b4544f3d7fc8117e80adb1e151c46d1ede54a4dbea6521e4');\nhashMap.set('bundler','6e4784dd98c1f86ef64cc8cbf3128df48aebf920032d7792b54fdedd3dd9d4d5');\nhashMap.set('cake','9ebd8b481220b30a8860121d26184540a1a2fcc05ef780df9295dea39b386fad');\nhashMap.set('cargo','fe8136135c895dd08819f91a60cf105f8b951251b057092700101ace991ae1d7');\nhashMap.set('cdnurl','9a81c8e3c6ad6c788498c99fc1067ffdfcd92a427c3afaf8c0130975d83131f2');\nhashMap.set('circleci','91cbeb33ea20f9838e2c81a1195eb806f0b38fa282bc3679f62552f20575ca85');\nhashMap.set('cloudbuild','f4e40388944652c8a19f8518771ac8d3f3c4ccf81ddef0e68b463aca833cb73c');\nhashMap.set('cocoapods','f832e2beef885bb3fd697ed9bb3e8cd742926bfec37ff41212edd2dbb4edb3ba');\nhashMap.set('composer','f1294fb3866ff65a75d98fdef80b1df3d3a8856535b8c690d1799e1205e4b639');\nhashMap.set('conan','8d46e9a30ae628e26118aea10a98d1b846f7c5d96d51ce24693437d555f6d125');\nhashMap.set('copier','10ae4d7f8ff35faf3a3f9f25bf4c969ea960e19aaf8c012aee11f93f4d10533e');\nhashMap.set('cpanfile','07813fec3f3c2197056500e9266a0553b9774c02f2c74d5ca2e213188c7c12d3');\nhashMap.set('crossplane','5c26b1201a1a51454ffb94d829e223a76a781569bf79cdb1e47087c30233ec40');\nhashMap.set('crow','eb9a5f9f95041855dded67bcce3dd54724f690995ed6268d272e8a666ff28fd0');\nhashMap.set('deno','05e7ab60494a20a5e7477f06a9e723e443d37643b6e1d9ba8d3d87126a051175');\nhashMap.set('deps-edn','06783dbc8b9c7bb84e162d1f75b7db56dfa021cc6f809dfd2314cee8b64af08d');\nhashMap.set('devbox','a40050cc61bd9b5d500ec111abb17bb15d5f82ab5b7699f66f628307ba8382c9');\nhashMap.set('devcontainer','24320ed1cb6191d04cb8b2707214d82c08c682597aed1d84f250aa00ad1632ec');\nhashMap.set('docker-compose','fba87b82cb0f2bfd66526631fbe928b8153e7ca701a5790d02b944df17417bb9');\nhashMap.set('dockerfile','78cb1e8b58653289dd4b73425c45495a4c4b41badd3614b8345aaf8ab73de09c');\nhashMap.set('droneci','661d2a2d7295af8dd7a1234c7090c42a89306bd574c3adf1fc67782efaad3998');\nhashMap.set('fleet','4942d52e82f35c41e2d46cf76f426e2d91b350338cfc0bbcb97e8aaae2a1ac0b');\nhashMap.set('flux','aad8c786c4a2b5820663027452eeb8fe84c3af8c8399261e85f0eade2e484fe8');\nhashMap.set('fvm','9b161df0f14bc6e536368952adf373e343630097121a913cea60ee284027fb90');\nhashMap.set('git-submodules','df8bb92b2906d8cddda2d4b302ee503f8002e3554d32d74cef2f584fe891f38f');\nhashMap.set('github-actions','7adddc8e590786084855ffe53292bff3098ac672f91c21cc39d45bcf0af2271f');\nhashMap.set('gitlabci','a5e1e66ef461e1c1e71062f85f35a212417e23627f4b002810f9a98295d6e672');\nhashMap.set('gitlabci-include','8860a15ab516fde00694f9bd9bf56fce4addafe5a55b5ddb9a4ec477d301d351');\nhashMap.set('glasskube','93e7b9000a17efa15a1abaaf320b5af9169b1ecd828fc0c881d98570ef9d9e30');\nhashMap.set('gleam','5e9b9f5f914afe5ed7b526c06c65111e3716d2dea9b0cbe7907bbc96db1064a3');\nhashMap.set('gomod','de042f3b5a900346c5f2df41f793f1716dc12145c38705c3064c6a7150b49495');\nhashMap.set('gradle','9e3ff52ce4ad2555929acdd4d32c417c4ef8714c23a92f2893ecc580fa4d6064');\nhashMap.set('gradle-wrapper','73ba30c34955fab7737454b5cff9aca6d1b5607d53c17c9e13d8ad96f6eaae87');\nhashMap.set('haskell-cabal','f158b7725e3143dfd2950e3de0bbccc2a61cd7eba87f7a54c5057e01252348e2');\nhashMap.set('helm-requirements','7ee9dace4c036dfe113c0c0e46369d8b83a739caa831660142ca98d3236a180a');\nhashMap.set('helm-values','0aa79bb0257d0d72e54dfd2653e59bfef63b97e46c035b7443593bdf6e6382aa');\nhashMap.set('helmfile','28572dd24b6746ca7065ee467aa13bbc8c3e8c0f88ae48e33bce88468c600100');\nhashMap.set('helmsman','951deeb3355da751ef39c9e932b26ea749450e32e75759e4b5fc29359e100b37');\nhashMap.set('helmv3','e2d464055503d3702d3cf7323ce593747fe482def8ee59aea2dcaadb0bb0f72c');\nhashMap.set('hermit','0fb25b7766c3a264fbb765ff75b1542b24136c4c9f933696d4a5aecfed637071');\nhashMap.set('homeassistant-manifest','05043c6db870cffbb6f8f3e351c025e3de227eaae0b24134b796aec46f84b65f');\nhashMap.set('homebrew','dffe954a4e18c2dc4bfdaa12222fe8ddc3395869afd5afa603fc2b6264747984');\nhashMap.set('html','81fa6c2bf2b868596584a48b949645207a2aa3081951ed99183ee50b70b77d5f');\nhashMap.set('jenkins','7fda0e7e0f3d5e18088ccb3594f727f4cfc48b064706bdaaf1a0a075b6a2cff5');\nhashMap.set('jsonnet-bundler','4cedeb0394e5c38361d1868ff45b4f34747ab8c492378b6e63dcaf1f4f3c024d');\nhashMap.set('kotlin-script','95ebc844c040ca047321b207d525220e29774a2a1fe06f9639e8353c66908564');\nhashMap.set('kubernetes','321e7d77fb3600dd4c00a86eaa1294927e7f92300b74fa2977d813dcaa3bb4de');\nhashMap.set('kustomize','aa830c27302555e12d7f04e342c96125d68c231028a2d3c459c4431516382584');\nhashMap.set('leiningen','c8397e376f1717c2f771ae9ea3ba6b720d2422b133cf937e762c44e42be146a2');\nhashMap.set('maven','c110b99291c2a5bc82cf7a69330275e9bbd7dc8ba3e9e987611dfcffbe002d8d');\nhashMap.set('maven-wrapper','6e53b6e4abf1d20b75094c7a70d66b4a5ac39954f009aa401f5e55dada8be4d0');\nhashMap.set('meteor','4636a47ba4dcfff19fe662572ef7a40d17146be3c966e00ef437e1fc8de92776');\nhashMap.set('mint','248fe4f1ea5c985921c286785792c97e06fc41f402b2d45df82f6aecd17f710e');\nhashMap.set('mise','279da4690751c3abee10badd12eb4ac6ef31d824c6bd3ada824859eca3109ebe');\nhashMap.set('mix','0f79163dc2a1c896599d152be635c23beaf16812ae3d8fbfffec98c7bd0de872');\nhashMap.set('nix','0f80f0b81f2197a7e588be5c115a32a826fc184593f4e879f7b60fafd97a977e');\nhashMap.set('nodenv','ac652c28481b001f7471f4183eac07b45d98ecbe83efc275830b0a1b2e0459b8');\nhashMap.set('npm','30c78bc1c29eeecbdedb4eacc52bd93eedfb07279fd385f893193dcac6196466');\nhashMap.set('nuget','b81fb0ca6cfeb86b004592b38ce176673e056d6a2ed41a9807afb0eb7ad405d2');\nhashMap.set('nvm','3eb77c7b0acf6d64753de78fad2499b352719853aa6872878c40675d14152322');\nhashMap.set('ocb','032b216684c14b0954e0bb019513a2aca3faaee5748587acb668d377d7c891ca');\nhashMap.set('osgi','d6567a733ef3983112b46fdccd7ceebfcd48411104e0c6b6e714d4310db48024');\nhashMap.set('pep621','52450676f8b0e05134b3e8947b832195ef40bcaec1ce43d71351a2f797b80d75');\nhashMap.set('pep723','77022a0eae6a3cbb74a1e6d596db1276e379768e40448192b3fa81edd14ca73f');\nhashMap.set('pip-compile','a98dc76a002e1dc21662237f009ff8fea36236bb4e24cb82ee30c6a78f57271f');\nhashMap.set('pip_requirements','bf3a407f72abf711230247bef94ba5dc84c08a35107b0f017912fad66afa716a');\nhashMap.set('pip_setup','df18fba2bdcf48f3ca12a8f7e5cd28df31e2368d5528127277038ef4206eca79');\nhashMap.set('pipenv','baf237cd77173c1a7a9c7fa2a8bfb214f3c488ba0cc27f0e8f334df192e3a398');\nhashMap.set('pixi','e31c397982ffa34222b061f23f3b3683f42523dd5dca45ecce2448b0ebc55ea2');\nhashMap.set('poetry','e9dea5d591c87956b9f018414cb3dab8f2e13580a13be00550fdce198fdf08e6');\nhashMap.set('pre-commit','760f2c291ae084db889f722390798a0e2d431ccdc3bc676e73b14901ebea19ac');\nhashMap.set('proto','412053d4550026b4ace490b46e970915b87ec1abf0b0a0c6c8c58ccf1fc16843');\nhashMap.set('pub','8e7c65dfd1999de4f7c44392e949a4d8f4701eb86df59d550e4657feb06b1872');\nhashMap.set('puppet','ba58ab689e44acc8f61c3569ab8b40fde01b8a9d3aad712708e2a419e57d8b45');\nhashMap.set('pyenv','9ede8becc97774f9040b40f4472d3e933534b596e04c360bfe0f3c6f95f25182');\nhashMap.set('quadlet','e1fc88a4e14cd595e89bb3d79b4adf2add3ce5eb80f75276e712c32598cca53d');\nhashMap.set('renovate-config','dfaf3f03ddaf70c332f7916106648f36dbfa6a36dd76d15dd27fa116ab3c174c');\nhashMap.set('ruby-version','2db2140d9eee8c555e729a4de0396fa2d78846d3149890ee12fa515bd654be97');\nhashMap.set('runtime-version','b582b168c0cc595e39010feb10f4b97a82683eb269e9598216fbb11cc186e160');\nhashMap.set('rust-toolchain','6ace53db02874d73620d2d872291839820a512a9529c42d174358c692e5db720');\nhashMap.set('sbt','e1eb5c7f0171a9bb1b6bd4a36a91039a31b6c84e0983d91d930be31a69506d9e');\nhashMap.set('scalafmt','9d36159b56835e96498af026a1fb0543200db0581681ef95ec54988f411e180f');\nhashMap.set('setup-cfg','4a3a7c812d34739c07685691e7e64c7d3127f9d7d4aff99dc45a25df97ed9745');\nhashMap.set('smithy','9641b91d065ffb63be0dd888139a0402dba41e550f8b44c592db9daf52109100');\nhashMap.set('sveltos','60dd75bb53ace31217211100d622fdb65068c6162758b6ae7103a6ce8bdc9f90');\nhashMap.set('swift','cdf063debdbf36888523ff8cec6d2d1b0ec6f49b37b2fbcd80b0d4f6a31114e1');\nhashMap.set('tekton','33948f5bdf7553909fa63744adb26da97ddf366e9499bccab1250879570267c9');\nhashMap.set('terraform','5b0037e4a88e06efe6f006eff15c24d9e1fefdda40d282aa99f54c2637d21c4d');\nhashMap.set('terraform-version','ec8f786b9731d47f2c2fe0307caf64d7ddd83046fe7ff1f7d8423239f8b0f2aa');\nhashMap.set('terragrunt','300f8fb3c09667654412d2f5dd8ab4882e0f5d1d7a8bc39794993d2e7e58d1b7');\nhashMap.set('terragrunt-version','eea6087b33717d22ede2fc68c2f64df8390b75abe82110ed831a180648feb51d');\nhashMap.set('tflint-plugin','f423bfa2b42a2bfc0e38a33ebd4f9d452473e7ed4e7ad6384a99eb9a35d97479');\nhashMap.set('travis','f3e2f38e699c390b00ff481be5e91dceaa81609e93caf9a4214933de759c84fc');\nhashMap.set('typst','d080a79fbd961c6e21fcc505d544b7e0ff2126142acb1dcabdf6abbcd9339248');\nhashMap.set('unity3d','f13e25e115e3443f4e16cf31578acffa78fb1a5e23339680a92d8d6de6052920');\nhashMap.set('velaci','fda00ddb7cc23e9a37e0a8a253151df0a6930b4276d3e4f78cc54b9ac09af7de');\nhashMap.set('vendir','7db907b3b77ef5f3465f3c4339fbab56bbcdfd1bf34b3d33e4c178d2e07e23e7');\nhashMap.set('woodpecker','6110d3bec33aaeb3511d4bbfa896cec3c8e02fb04a6cff50c9ba81061c851045');\nhashMap.set('xcodegen','dad511d88a9ce1dbdde8b9731f3da7f2bdaa4ca8a083294ee58d56da62ab1683');\nhashMap.set('jsonata','416bcf61144b276b3112814c6e6d261aa29608f46fbb0516c471d35c16f8f0d7');\nhashMap.set('regex','20be5247fdc164173871a051acb0527da017d0c155c653d7563601f55e7b3ff5');"],"mappings":"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"}
|
|
@@ -27,7 +27,7 @@ async function generateLoginCmd(repositoryRule) {
|
|
|
27
27
|
logger.trace({ repository }, `Using basic auth for Helm registry`);
|
|
28
28
|
const hostPart = repository.split("/")[0];
|
|
29
29
|
const cmd = `${loginCMD} --username ${quote(username)} --password ${quote(password)} ${quote(hostPart)}`;
|
|
30
|
-
logger.trace({
|
|
30
|
+
logger.trace({ host: hostPart }, "Generated Helm registry login command");
|
|
31
31
|
return cmd;
|
|
32
32
|
}
|
|
33
33
|
return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.js","names":[],"sources":["../../../../lib/modules/manager/helmv3/common.ts"],"sourcesContent":["import { quote } from 'shlex';\nimport upath from 'upath';\n\nimport { logger } from '../../../logger/index.ts';\nimport { coerceArray } from '../../../util/array.ts';\nimport type { ExtraEnv } from '../../../util/exec/types.ts';\nimport { privateCacheDir } from '../../../util/fs/index.ts';\nimport { addSecretForSanitizing } from '../../../util/sanitize.ts';\nimport { fromBase64 } from '../../../util/string.ts';\nimport { ecrRegex, getECRAuthToken } from '../../datasource/docker/ecr.ts';\nimport type { RepositoryRule } from './types.ts';\n\nexport async function generateLoginCmd(\n repositoryRule: RepositoryRule,\n): Promise<string | null> {\n logger.trace({ repositoryRule }, 'Generating Helm registry login command');\n const { hostRule, repository } = repositoryRule;\n const { username, password } = hostRule;\n const loginCMD = 'helm registry login';\n if (username !== 'AWS' && ecrRegex.test(repository)) {\n logger.trace({ repository }, `Using ecr auth for Helm registry`);\n const [, region] = coerceArray(ecrRegex.exec(repository));\n const auth = await getECRAuthToken(region, hostRule);\n if (!auth) {\n return null;\n }\n const [username, password] = fromBase64(auth).split(':');\n if (!username || !password) {\n return null;\n }\n addSecretForSanitizing(username);\n addSecretForSanitizing(password);\n return `${loginCMD} --username ${quote(username)} --password ${quote(\n password,\n )} ${quote(repository)}`;\n }\n if (username && password) {\n logger.trace({ repository }, `Using basic auth for Helm registry`);\n // Split off any path as it's not valid for the helm registry login command\n const hostPart = repository.split('/')[0];\n const cmd = `${loginCMD} --username ${quote(username)} --password ${quote(\n password,\n )} ${quote(hostPart)}`;\n logger.trace({
|
|
1
|
+
{"version":3,"file":"common.js","names":[],"sources":["../../../../lib/modules/manager/helmv3/common.ts"],"sourcesContent":["import { quote } from 'shlex';\nimport upath from 'upath';\n\nimport { logger } from '../../../logger/index.ts';\nimport { coerceArray } from '../../../util/array.ts';\nimport type { ExtraEnv } from '../../../util/exec/types.ts';\nimport { privateCacheDir } from '../../../util/fs/index.ts';\nimport { addSecretForSanitizing } from '../../../util/sanitize.ts';\nimport { fromBase64 } from '../../../util/string.ts';\nimport { ecrRegex, getECRAuthToken } from '../../datasource/docker/ecr.ts';\nimport type { RepositoryRule } from './types.ts';\n\nexport async function generateLoginCmd(\n repositoryRule: RepositoryRule,\n): Promise<string | null> {\n logger.trace({ repositoryRule }, 'Generating Helm registry login command');\n const { hostRule, repository } = repositoryRule;\n const { username, password } = hostRule;\n const loginCMD = 'helm registry login';\n if (username !== 'AWS' && ecrRegex.test(repository)) {\n logger.trace({ repository }, `Using ecr auth for Helm registry`);\n const [, region] = coerceArray(ecrRegex.exec(repository));\n const auth = await getECRAuthToken(region, hostRule);\n if (!auth) {\n return null;\n }\n const [username, password] = fromBase64(auth).split(':');\n if (!username || !password) {\n return null;\n }\n addSecretForSanitizing(username);\n addSecretForSanitizing(password);\n return `${loginCMD} --username ${quote(username)} --password ${quote(\n password,\n )} ${quote(repository)}`;\n }\n if (username && password) {\n logger.trace({ repository }, `Using basic auth for Helm registry`);\n // Split off any path as it's not valid for the helm registry login command\n const hostPart = repository.split('/')[0];\n const cmd = `${loginCMD} --username ${quote(username)} --password ${quote(\n password,\n )} ${quote(hostPart)}`;\n // the command carries the password, so log the target host only\n logger.trace({ host: hostPart }, 'Generated Helm registry login command');\n return cmd;\n }\n return null;\n}\n\nexport function generateHelmEnvs(): ExtraEnv {\n return {\n HELM_EXPERIMENTAL_OCI: '1',\n // set cache and config files to a path in privateCacheDir to prevent file and credential leakage\n HELM_REGISTRY_CONFIG: `${upath.join(privateCacheDir(), 'registry.json')}`,\n HELM_REPOSITORY_CONFIG: `${upath.join(\n privateCacheDir(),\n 'repositories.yaml',\n )}`,\n HELM_REPOSITORY_CACHE: `${upath.join(privateCacheDir(), 'repositories')}`,\n };\n}\n"],"mappings":";;;;;;;;;AAYA,eAAsB,iBACpB,gBACwB;CACxB,OAAO,MAAM,EAAE,eAAe,GAAG,wCAAwC;CACzE,MAAM,EAAE,UAAU,eAAe;CACjC,MAAM,EAAE,UAAU,aAAa;CAC/B,MAAM,WAAW;CACjB,IAAI,aAAa,SAAS,SAAS,KAAK,UAAU,GAAG;EACnD,OAAO,MAAM,EAAE,WAAW,GAAG,kCAAkC;EAC/D,MAAM,GAAG,UAAU,YAAY,SAAS,KAAK,UAAU,CAAC;EACxD,MAAM,OAAO,MAAM,gBAAgB,QAAQ,QAAQ;EACnD,IAAI,CAAC,MACH,OAAO;EAET,MAAM,CAAC,UAAU,YAAY,WAAW,IAAI,CAAC,CAAC,MAAM,GAAG;EACvD,IAAI,CAAC,YAAY,CAAC,UAChB,OAAO;EAET,uBAAuB,QAAQ;EAC/B,uBAAuB,QAAQ;EAC/B,OAAO,GAAG,SAAS,cAAc,MAAM,QAAQ,EAAE,cAAc,MAC7D,QACF,EAAE,GAAG,MAAM,UAAU;CACvB;CACA,IAAI,YAAY,UAAU;EACxB,OAAO,MAAM,EAAE,WAAW,GAAG,oCAAoC;EAEjE,MAAM,WAAW,WAAW,MAAM,GAAG,CAAC,CAAC;EACvC,MAAM,MAAM,GAAG,SAAS,cAAc,MAAM,QAAQ,EAAE,cAAc,MAClE,QACF,EAAE,GAAG,MAAM,QAAQ;EAEnB,OAAO,MAAM,EAAE,MAAM,SAAS,GAAG,uCAAuC;EACxE,OAAO;CACT;CACA,OAAO;AACT;AAEA,SAAgB,mBAA6B;CAC3C,OAAO;EACL,uBAAuB;EAEvB,sBAAsB,GAAG,MAAM,KAAK,gBAAgB,GAAG,eAAe;EACtE,wBAAwB,GAAG,MAAM,KAC/B,gBAAgB,GAChB,mBACF;EACA,uBAAuB,GAAG,MAAM,KAAK,gBAAgB,GAAG,cAAc;CACxE;AACF"}
|
|
@@ -3,10 +3,9 @@ import { regEx } from "../../../../util/regex.js";
|
|
|
3
3
|
import { coerceArray } from "../../../../util/array.js";
|
|
4
4
|
import { logger } from "../../../../logger/index.js";
|
|
5
5
|
import { parseUrl } from "../../../../util/url.js";
|
|
6
|
-
import { find } from "../../../../util/host-rules.js";
|
|
7
6
|
import { findLocalSiblingOrParent, readLocalFile } from "../../../../util/fs/index.js";
|
|
8
7
|
import { Result } from "../../../../util/result.js";
|
|
9
|
-
import {
|
|
8
|
+
import { findPypiIndexCredentials } from "../../../datasource/pypi/host-rules.js";
|
|
10
9
|
import { PypiDatasource } from "../../../datasource/pypi/index.js";
|
|
11
10
|
import { applyGitSource, artifactErrorResult, resolveToolConstraint, updateLockFile } from "../../util.js";
|
|
12
11
|
import { withGitEnvironment } from "../../../../util/git/exec.js";
|
|
@@ -141,22 +140,6 @@ function generateCMD(updatedDeps) {
|
|
|
141
140
|
}
|
|
142
141
|
return `${uvUpdateCMD} ${deps.map((dep) => `--upgrade-package ${quote(dep)}`).join(" ")}`;
|
|
143
142
|
}
|
|
144
|
-
function getMatchingHostRule(url) {
|
|
145
|
-
return find({
|
|
146
|
-
hostType: PypiDatasource.id,
|
|
147
|
-
url
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
async function getUsernamePassword(url) {
|
|
151
|
-
const rule = getMatchingHostRule(url.toString());
|
|
152
|
-
if (rule.username || rule.password) return rule;
|
|
153
|
-
if (url.hostname.endsWith(".pkg.dev")) {
|
|
154
|
-
const hostRule = await getGoogleAuthHostRule();
|
|
155
|
-
if (hostRule) return hostRule;
|
|
156
|
-
logger.once.debug({ url }, "Could not get Google access token");
|
|
157
|
-
}
|
|
158
|
-
return {};
|
|
159
|
-
}
|
|
160
143
|
async function getUvExtraIndexUrl(project, deps) {
|
|
161
144
|
const pyPiRegistryUrls = deps.filter((dep) => dep.datasource === PypiDatasource.id).filter((dep) => {
|
|
162
145
|
const sources = project.tool?.uv?.sources;
|
|
@@ -171,7 +154,7 @@ async function getUvExtraIndexUrl(project, deps) {
|
|
|
171
154
|
for (const registryUrl of registryUrls) {
|
|
172
155
|
const parsedUrl = parseUrl(registryUrl);
|
|
173
156
|
if (!parsedUrl) continue;
|
|
174
|
-
const { username, password } = await
|
|
157
|
+
const { username, password } = await findPypiIndexCredentials(parsedUrl.toString());
|
|
175
158
|
if (username || password) {
|
|
176
159
|
// v8 ignore else -- needs a host rule carrying only one of the two
|
|
177
160
|
if (username) parsedUrl.username = username;
|
|
@@ -191,7 +174,7 @@ async function getUvIndexCredentials(project) {
|
|
|
191
174
|
/* v8 ignore next -- needs test */
|
|
192
175
|
if (!parsedUrl) continue;
|
|
193
176
|
if (!name) continue;
|
|
194
|
-
const { username, password } = await
|
|
177
|
+
const { username, password } = await findPypiIndexCredentials(parsedUrl.toString());
|
|
195
178
|
const NAME = name.toUpperCase().replace(regEx(/[^A-Z0-9]/g), "_");
|
|
196
179
|
// v8 ignore else -- needs a host rule carrying only one of the two
|
|
197
180
|
if (username) entries.push([`UV_INDEX_${NAME}_USERNAME`, username]);
|
|
@@ -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 {\n applyGitSource,\n artifactErrorResult,\n resolveToolConstraint,\n updateLockFile,\n} 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 return await updateLockFile({\n lockFileName,\n existingLockFileContent,\n run: () => gitExec(cmd, execOptions),\n });\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 artifactErrorResult(lockFileName, err);\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 // v8 ignore else -- needs a host rule carrying only one of the two\n if (username) {\n parsedUrl.username = username;\n }\n // v8 ignore else -- needs a host rule carrying only one of the two\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 // v8 ignore else -- needs a host rule carrying only one of the two\n if (username) {\n entries.push([`UV_INDEX_${NAME}_USERNAME`, username]);\n }\n\n // v8 ignore else -- needs a host rule carrying only one of the two\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 { 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 { regEx } from '../../../../util/regex.ts';\nimport { Result } from '../../../../util/result.ts';\nimport { parseUrl } from '../../../../util/url.ts';\nimport { findPypiIndexCredentials } from '../../../datasource/pypi/host-rules.ts';\nimport { PypiDatasource } from '../../../datasource/pypi/index.ts';\nimport type {\n PackageDependency,\n UpdateArtifact,\n UpdateArtifactsResult,\n Upgrade,\n} from '../../types.ts';\nimport {\n applyGitSource,\n artifactErrorResult,\n resolveToolConstraint,\n updateLockFile,\n} 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 return await updateLockFile({\n lockFileName,\n existingLockFileContent,\n run: () => gitExec(cmd, execOptions),\n });\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 artifactErrorResult(lockFileName, err);\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\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 findPypiIndexCredentials(\n parsedUrl.toString(),\n );\n if (username || password) {\n // v8 ignore else -- needs a host rule carrying only one of the two\n if (username) {\n parsedUrl.username = username;\n }\n // v8 ignore else -- needs a host rule carrying only one of the two\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 findPypiIndexCredentials(\n parsedUrl.toString(),\n );\n\n const NAME = name.toUpperCase().replace(regEx(/[^A-Z0-9]/g), '_');\n\n // v8 ignore else -- needs a host rule carrying only one of the two\n if (username) {\n entries.push([`UV_INDEX_${NAME}_USERNAME`, username]);\n }\n\n // v8 ignore else -- needs a host rule carrying only one of the two\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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"}
|