renovate 44.61.0 → 44.61.2
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/config/migration.js +1 -1
- package/dist/config/migration.js.map +1 -1
- package/dist/config/migrations/custom/schedule-migration.js +8 -8
- package/dist/config/migrations/custom/schedule-migration.js.map +1 -1
- package/dist/config/options/env.js +1 -1
- package/dist/config/options/env.js.map +1 -1
- package/dist/config/parse.js +1 -1
- package/dist/config/parse.js.map +1 -1
- package/dist/config/presets/parse.js +1 -1
- package/dist/config/presets/parse.js.map +1 -1
- package/dist/config/validation.js +1 -1
- package/dist/config/validation.js.map +1 -1
- package/dist/logger/utils.js +2 -2
- package/dist/logger/utils.js.map +1 -1
- package/dist/modules/datasource/deno/index.js +1 -1
- package/dist/modules/datasource/deno/index.js.map +1 -1
- package/dist/modules/datasource/docker/ecr.js +1 -1
- package/dist/modules/datasource/docker/ecr.js.map +1 -1
- package/dist/modules/datasource/docker/google.js +1 -1
- package/dist/modules/datasource/docker/google.js.map +1 -1
- package/dist/modules/datasource/go/base.js +1 -1
- package/dist/modules/datasource/go/base.js.map +1 -1
- package/dist/modules/datasource/go/goproxy-parser.js +1 -1
- package/dist/modules/datasource/go/goproxy-parser.js.map +1 -1
- package/dist/modules/datasource/go/releases-goproxy.js +1 -1
- package/dist/modules/datasource/go/releases-goproxy.js.map +1 -1
- package/dist/modules/datasource/gradle-version/index.js +1 -1
- package/dist/modules/datasource/gradle-version/index.js.map +1 -1
- package/dist/modules/datasource/helm/schema.js +2 -2
- package/dist/modules/datasource/helm/schema.js.map +1 -1
- package/dist/modules/datasource/hexpm-bob/index.js +1 -1
- package/dist/modules/datasource/hexpm-bob/index.js.map +1 -1
- package/dist/modules/datasource/npm/get.js +1 -1
- package/dist/modules/datasource/npm/get.js.map +1 -1
- package/dist/modules/datasource/npm/npmrc.js +1 -1
- package/dist/modules/datasource/npm/npmrc.js.map +1 -1
- package/dist/modules/datasource/pypi/common.js +2 -2
- package/dist/modules/datasource/pypi/common.js.map +1 -1
- package/dist/modules/datasource/pypi/index.js +1 -1
- package/dist/modules/datasource/pypi/index.js.map +1 -1
- package/dist/modules/manager/ansible/extract.js +2 -2
- package/dist/modules/manager/ansible/extract.js.map +1 -1
- package/dist/modules/manager/ansible-galaxy/collections.js +2 -2
- package/dist/modules/manager/ansible-galaxy/collections.js.map +1 -1
- package/dist/modules/manager/ansible-galaxy/roles.js +2 -2
- package/dist/modules/manager/ansible-galaxy/roles.js.map +1 -1
- package/dist/modules/manager/ansible-galaxy/util.js +4 -4
- package/dist/modules/manager/ansible-galaxy/util.js.map +1 -1
- package/dist/modules/manager/ant/properties.js +9 -9
- package/dist/modules/manager/ant/properties.js.map +1 -1
- package/dist/modules/manager/asdf/extract.js +1 -1
- package/dist/modules/manager/asdf/extract.js.map +1 -1
- package/dist/modules/manager/asdf/upgradeable-tooling.js +1 -1
- package/dist/modules/manager/asdf/upgradeable-tooling.js.map +1 -1
- package/dist/modules/manager/batect-wrapper/extract.js +2 -2
- package/dist/modules/manager/batect-wrapper/extract.js.map +1 -1
- package/dist/modules/manager/bazel/rules/go.js +1 -1
- package/dist/modules/manager/bazel/rules/go.js.map +1 -1
- package/dist/modules/manager/buildkite/extract.js +1 -1
- package/dist/modules/manager/buildkite/extract.js.map +1 -1
- package/dist/modules/manager/buildpacks/extract.js +1 -1
- package/dist/modules/manager/buildpacks/extract.js.map +1 -1
- package/dist/modules/manager/bundler/common.js +7 -7
- package/dist/modules/manager/bundler/common.js.map +1 -1
- package/dist/modules/manager/bundler/extract.js +4 -4
- package/dist/modules/manager/bundler/extract.js.map +1 -1
- package/dist/modules/manager/deno/utils.js +1 -1
- package/dist/modules/manager/deno/utils.js.map +1 -1
- package/dist/modules/manager/dockerfile/extract.js +11 -4
- package/dist/modules/manager/dockerfile/extract.js.map +1 -1
- package/dist/modules/manager/fingerprint.generated.js +4 -4
- package/dist/modules/manager/fingerprint.generated.js.map +1 -1
- package/dist/modules/manager/flux/extract.js +2 -1
- package/dist/modules/manager/flux/extract.js.map +1 -1
- package/dist/modules/manager/git-submodules/extract.js +1 -1
- package/dist/modules/manager/git-submodules/extract.js.map +1 -1
- package/dist/modules/manager/github-actions/common.js +3 -3
- package/dist/modules/manager/github-actions/common.js.map +1 -1
- package/dist/modules/manager/github-actions/parse.js +1 -1
- package/dist/modules/manager/github-actions/parse.js.map +1 -1
- package/dist/modules/manager/gomod/artifacts.js +4 -4
- package/dist/modules/manager/gomod/artifacts.js.map +1 -1
- package/dist/modules/manager/gomod/line-parser.js +1 -1
- package/dist/modules/manager/gomod/line-parser.js.map +1 -1
- package/dist/modules/manager/gomod/update.js +1 -1
- package/dist/modules/manager/gomod/update.js.map +1 -1
- package/dist/modules/manager/gradle/parser/handlers.js +1 -1
- package/dist/modules/manager/gradle/parser/handlers.js.map +1 -1
- package/dist/modules/manager/helmv3/utils.js +1 -1
- package/dist/modules/manager/helmv3/utils.js.map +1 -1
- package/dist/modules/manager/html/extract.js +2 -2
- package/dist/modules/manager/html/extract.js.map +1 -1
- package/dist/modules/manager/kustomize/extract.js +3 -3
- package/dist/modules/manager/kustomize/extract.js.map +1 -1
- package/dist/modules/manager/leiningen/extract.js +1 -1
- package/dist/modules/manager/leiningen/extract.js.map +1 -1
- package/dist/modules/manager/maven-wrapper/artifacts.js +6 -6
- package/dist/modules/manager/maven-wrapper/artifacts.js.map +1 -1
- package/dist/modules/manager/meteor/extract.js +2 -2
- package/dist/modules/manager/meteor/extract.js.map +1 -1
- package/dist/modules/manager/mise/upgradeable-tooling.js +2 -2
- package/dist/modules/manager/mise/upgradeable-tooling.js.map +1 -1
- package/dist/modules/manager/mix/extract.js +3 -3
- package/dist/modules/manager/mix/extract.js.map +1 -1
- package/dist/modules/manager/npm/extract/common/dependency.js +4 -4
- package/dist/modules/manager/npm/extract/common/dependency.js.map +1 -1
- package/dist/modules/manager/npm/extract/yarnrc.js +1 -1
- package/dist/modules/manager/npm/extract/yarnrc.js.map +1 -1
- package/dist/modules/manager/npm/npmrc.js +1 -1
- package/dist/modules/manager/npm/npmrc.js.map +1 -1
- package/dist/modules/manager/npm/post-update/yarn.js +1 -1
- package/dist/modules/manager/npm/post-update/yarn.js.map +1 -1
- package/dist/modules/manager/npm/update/locked-dependency/package-lock/dep-constraints.js +1 -1
- package/dist/modules/manager/npm/update/locked-dependency/package-lock/dep-constraints.js.map +1 -1
- package/dist/modules/manager/npm/update/locked-dependency/yarn-lock/replace.js +1 -1
- package/dist/modules/manager/npm/update/locked-dependency/yarn-lock/replace.js.map +1 -1
- package/dist/modules/manager/nuget/extract.js +1 -1
- package/dist/modules/manager/nuget/extract.js.map +1 -1
- package/dist/modules/manager/pep621/utils.js +1 -1
- package/dist/modules/manager/pep621/utils.js.map +1 -1
- package/dist/modules/manager/pep723/utils.js +1 -1
- package/dist/modules/manager/pep723/utils.js.map +1 -1
- package/dist/modules/manager/pip-compile/common.js +2 -2
- package/dist/modules/manager/pip-compile/common.js.map +1 -1
- package/dist/modules/manager/pip_requirements/common.js +1 -1
- package/dist/modules/manager/pip_requirements/common.js.map +1 -1
- package/dist/modules/manager/pip_requirements/extract.js +1 -1
- package/dist/modules/manager/pip_requirements/extract.js.map +1 -1
- package/dist/modules/manager/poetry/artifacts.js +4 -4
- package/dist/modules/manager/poetry/artifacts.js.map +1 -1
- package/dist/modules/manager/puppet/puppetfile-parser.js +5 -5
- package/dist/modules/manager/puppet/puppetfile-parser.js.map +1 -1
- package/dist/modules/manager/sbt/update.js +1 -1
- package/dist/modules/manager/sbt/update.js.map +1 -1
- package/dist/modules/manager/sbt/util.js +2 -2
- package/dist/modules/manager/sbt/util.js.map +1 -1
- package/dist/modules/manager/setup-cfg/extract.js +2 -2
- package/dist/modules/manager/setup-cfg/extract.js.map +1 -1
- package/dist/modules/manager/swift/artifacts.js +4 -4
- package/dist/modules/manager/swift/artifacts.js.map +1 -1
- package/dist/modules/manager/swift/extract.js +1 -1
- package/dist/modules/manager/swift/extract.js.map +1 -1
- package/dist/modules/manager/tekton/extract.js +1 -1
- package/dist/modules/manager/tekton/extract.js.map +1 -1
- package/dist/modules/manager/terraform/extractors/others/modules.js +5 -5
- package/dist/modules/manager/terraform/extractors/others/modules.js.map +1 -1
- package/dist/modules/manager/terraform/util.js +1 -1
- package/dist/modules/manager/terraform/util.js.map +1 -1
- package/dist/modules/manager/terragrunt/modules.js +3 -3
- package/dist/modules/manager/terragrunt/modules.js.map +1 -1
- package/dist/modules/platform/azure/azure-got-wrapper.js +15 -5
- package/dist/modules/platform/azure/azure-got-wrapper.js.map +1 -1
- package/dist/modules/platform/azure/index.js +28 -8
- package/dist/modules/platform/azure/index.js.map +1 -1
- package/dist/modules/platform/azure/types.js.map +1 -1
- package/dist/modules/platform/bitbucket/index.js +4 -4
- package/dist/modules/platform/bitbucket/index.js.map +1 -1
- package/dist/modules/platform/bitbucket-server/index.js +1 -1
- package/dist/modules/platform/bitbucket-server/index.js.map +1 -1
- package/dist/modules/platform/gerrit/index.js +1 -1
- package/dist/modules/platform/gerrit/index.js.map +1 -1
- package/dist/modules/platform/gerrit/utils.js +3 -3
- package/dist/modules/platform/gerrit/utils.js.map +1 -1
- package/dist/modules/versioning/apk/index.js +3 -3
- package/dist/modules/versioning/apk/index.js.map +1 -1
- package/dist/modules/versioning/composer/index.js +11 -11
- package/dist/modules/versioning/composer/index.js.map +1 -1
- package/dist/modules/versioning/conan/range.js +1 -1
- package/dist/modules/versioning/conan/range.js.map +1 -1
- package/dist/modules/versioning/conda/index.js +1 -1
- package/dist/modules/versioning/conda/index.js.map +1 -1
- package/dist/modules/versioning/devbox/index.js +2 -2
- package/dist/modules/versioning/devbox/index.js.map +1 -1
- package/dist/modules/versioning/distro.js +1 -1
- package/dist/modules/versioning/distro.js.map +1 -1
- package/dist/modules/versioning/github-actions/index.js +2 -2
- package/dist/modules/versioning/github-actions/index.js.map +1 -1
- package/dist/modules/versioning/go-mod-directive/index.js +1 -1
- package/dist/modules/versioning/go-mod-directive/index.js.map +1 -1
- package/dist/modules/versioning/hashicorp/convertor.js +5 -5
- package/dist/modules/versioning/hashicorp/convertor.js.map +1 -1
- package/dist/modules/versioning/hex/index.js +4 -4
- package/dist/modules/versioning/hex/index.js.map +1 -1
- package/dist/modules/versioning/lambda-node/schedule.js +2 -2
- package/dist/modules/versioning/lambda-node/schedule.js.map +1 -1
- package/dist/modules/versioning/loose/index.js +2 -2
- package/dist/modules/versioning/loose/index.js.map +1 -1
- package/dist/modules/versioning/pep440/range.js +1 -1
- package/dist/modules/versioning/pep440/range.js.map +1 -1
- package/dist/modules/versioning/perl/index.js +4 -4
- package/dist/modules/versioning/perl/index.js.map +1 -1
- package/dist/modules/versioning/poetry/patterns.js +1 -1
- package/dist/modules/versioning/poetry/patterns.js.map +1 -1
- package/dist/modules/versioning/poetry/transform.js +3 -3
- package/dist/modules/versioning/poetry/transform.js.map +1 -1
- package/dist/modules/versioning/redhat/index.js +1 -1
- package/dist/modules/versioning/redhat/index.js.map +1 -1
- package/dist/modules/versioning/rpm/index.js +1 -1
- package/dist/modules/versioning/rpm/index.js.map +1 -1
- package/dist/modules/versioning/ruby/index.js +2 -2
- package/dist/modules/versioning/ruby/index.js.map +1 -1
- package/dist/modules/versioning/semver/common.js +1 -1
- package/dist/modules/versioning/semver/common.js.map +1 -1
- package/dist/modules/versioning/swift/range.js +13 -13
- package/dist/modules/versioning/swift/range.js.map +1 -1
- package/dist/modules/versioning/ubuntu/index.js +1 -1
- package/dist/modules/versioning/ubuntu/index.js.map +1 -1
- package/dist/modules/versioning/unity3d-packages/index.js +2 -2
- package/dist/modules/versioning/unity3d-packages/index.js.map +1 -1
- package/dist/util/cache/package/impl/redis.js +1 -1
- package/dist/util/cache/package/impl/redis.js.map +1 -1
- package/dist/util/exec/common.js +3 -3
- package/dist/util/exec/common.js.map +1 -1
- package/dist/util/git/author.js +1 -1
- package/dist/util/git/author.js.map +1 -1
- package/dist/util/git/semantic.js +1 -1
- package/dist/util/git/semantic.js.map +1 -1
- package/dist/util/http/www-authenticate.js +4 -4
- package/dist/util/http/www-authenticate.js.map +1 -1
- package/dist/util/ignore.js +1 -1
- package/dist/util/ignore.js.map +1 -1
- package/dist/util/markdown.js +8 -8
- package/dist/util/markdown.js.map +1 -1
- package/dist/util/pretty-time.js +3 -3
- package/dist/util/pretty-time.js.map +1 -1
- package/dist/util/regex.js +1 -1
- package/dist/util/regex.js.map +1 -1
- package/dist/workers/global/config/parse/cli.js +1 -1
- package/dist/workers/global/config/parse/cli.js.map +1 -1
- package/dist/workers/repository/model/semantic-commit-message.js +1 -1
- package/dist/workers/repository/model/semantic-commit-message.js.map +1 -1
- package/dist/workers/repository/onboarding/pr/pr-list.js +2 -2
- package/dist/workers/repository/onboarding/pr/pr-list.js.map +1 -1
- package/dist/workers/repository/update/pr/changelog/release-notes.js +3 -3
- package/dist/workers/repository/update/pr/changelog/release-notes.js.map +1 -1
- package/dist/workers/repository/updates/branch-name.js +1 -1
- package/dist/workers/repository/updates/branch-name.js.map +1 -1
- package/dist/workers/repository/updates/flatten.js +1 -1
- package/dist/workers/repository/updates/flatten.js.map +1 -1
- package/dist/workers/repository/updates/generate.js +1 -1
- package/dist/workers/repository/updates/generate.js.map +1 -1
- package/package.json +2 -2
- package/renovate-schema.json +2 -2
|
@@ -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=\"([^\"]*?)>([^\"]*?)\"/g),\n 'data-requires-python=\"$1>$2\"',\n )\n .replace(\n regEx(/data-requires-python=\"([^\"]*?)<([^\"]*?)\"/g),\n 'data-requires-python=\"$1<$2\"',\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 { 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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"}
|
|
@@ -5,11 +5,11 @@ import { getDep } from "../dockerfile/extract.js";
|
|
|
5
5
|
function extractPackageFile(content, packageFile, config) {
|
|
6
6
|
logger.trace(`ansible.extractPackageFile(${packageFile})`);
|
|
7
7
|
let deps = [];
|
|
8
|
-
const re = regEx(/^\s*image:\s*'?"?([^\s'"]+)'?"?\s*$/);
|
|
8
|
+
const re = regEx(/^\s*image:\s*'?"?(?<image>[^\s'"]+)'?"?\s*$/);
|
|
9
9
|
for (const line of content.split(newlineRegex)) {
|
|
10
10
|
const match = re.exec(line);
|
|
11
11
|
if (match) {
|
|
12
|
-
const currentFrom = match
|
|
12
|
+
const currentFrom = match.groups.image;
|
|
13
13
|
const dep = getDep(currentFrom, true, config.registryAliases);
|
|
14
14
|
logger.debug({
|
|
15
15
|
depName: dep.depName,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extract.js","names":[],"sources":["../../../../lib/modules/manager/ansible/extract.ts"],"sourcesContent":["import { logger } from '../../../logger/index.ts';\nimport { newlineRegex, regEx } from '../../../util/regex.ts';\nimport { getDep } from '../dockerfile/extract.ts';\nimport type {\n ExtractConfig,\n PackageDependency,\n PackageFileContent,\n} from '../types.ts';\n\nexport function extractPackageFile(\n content: string,\n packageFile: string,\n config: ExtractConfig,\n): PackageFileContent | null {\n logger.trace(`ansible.extractPackageFile(${packageFile})`);\n let deps: PackageDependency[] = [];\n const re = regEx(/^\\s*image:\\s*'?\"?([^\\s'\"]+)'?\"?\\s*$/);\n for (const line of content.split(newlineRegex)) {\n const match = re.exec(line);\n if (match) {\n const currentFrom = match
|
|
1
|
+
{"version":3,"file":"extract.js","names":[],"sources":["../../../../lib/modules/manager/ansible/extract.ts"],"sourcesContent":["import { logger } from '../../../logger/index.ts';\nimport { newlineRegex, regEx } from '../../../util/regex.ts';\nimport { getDep } from '../dockerfile/extract.ts';\nimport type {\n ExtractConfig,\n PackageDependency,\n PackageFileContent,\n} from '../types.ts';\n\nexport function extractPackageFile(\n content: string,\n packageFile: string,\n config: ExtractConfig,\n): PackageFileContent | null {\n logger.trace(`ansible.extractPackageFile(${packageFile})`);\n let deps: PackageDependency[] = [];\n const re = regEx(/^\\s*image:\\s*'?\"?(?<image>[^\\s'\"]+)'?\"?\\s*$/);\n for (const line of content.split(newlineRegex)) {\n const match = re.exec(line);\n if (match) {\n const currentFrom = match.groups!.image;\n const dep = getDep(currentFrom, true, config.registryAliases);\n logger.debug(\n {\n depName: dep.depName,\n currentValue: dep.currentValue,\n currentDigest: dep.currentDigest,\n },\n 'Docker image inside ansible',\n );\n deps.push(dep);\n }\n }\n deps = deps.filter((dep) => !dep.currentValue?.includes('${'));\n if (!deps.length) {\n return null;\n }\n return { deps };\n}\n"],"mappings":";;;;AASA,SAAgB,mBACd,SACA,aACA,QAC2B;CAC3B,OAAO,MAAM,8BAA8B,YAAY,EAAE;CACzD,IAAI,OAA4B,CAAC;CACjC,MAAM,KAAK,MAAM,6CAA6C;CAC9D,KAAK,MAAM,QAAQ,QAAQ,MAAM,YAAY,GAAG;EAC9C,MAAM,QAAQ,GAAG,KAAK,IAAI;EAC1B,IAAI,OAAO;GACT,MAAM,cAAc,MAAM,OAAQ;GAClC,MAAM,MAAM,OAAO,aAAa,MAAM,OAAO,eAAe;GAC5D,OAAO,MACL;IACE,SAAS,IAAI;IACb,cAAc,IAAI;IAClB,eAAe,IAAI;GACrB,GACA,6BACF;GACA,KAAK,KAAK,GAAG;EACf;CACF;CACA,OAAO,KAAK,QAAQ,QAAQ,CAAC,IAAI,cAAc,SAAS,IAAI,CAAC;CAC7D,IAAI,CAAC,KAAK,QACR,OAAO;CAET,OAAO,EAAE,KAAK;AAChB"}
|
|
@@ -6,8 +6,8 @@ import { blockLineRegEx, galaxyDepRegex, nameMatchRegex, newBlockRegEx } from ".
|
|
|
6
6
|
//#region lib/modules/manager/ansible-galaxy/collections.ts
|
|
7
7
|
function interpretLine(lineMatch, dependency) {
|
|
8
8
|
const localDependency = dependency;
|
|
9
|
-
const key = lineMatch
|
|
10
|
-
const value = lineMatch
|
|
9
|
+
const key = lineMatch.groups.key;
|
|
10
|
+
const value = lineMatch.groups.value.replace(regEx(/["']/g), "");
|
|
11
11
|
switch (key) {
|
|
12
12
|
case "name":
|
|
13
13
|
localDependency.managerData.name = value;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collections.js","names":[],"sources":["../../../../lib/modules/manager/ansible-galaxy/collections.ts"],"sourcesContent":["import { regEx } from '../../../util/regex.ts';\nimport { GalaxyCollectionDatasource } from '../../datasource/galaxy-collection/index.ts';\nimport { GitTagsDatasource } from '../../datasource/git-tags/index.ts';\nimport { GithubTagsDatasource } from '../../datasource/github-tags/index.ts';\nimport type { PackageDependency } from '../types.ts';\nimport type { AnsibleGalaxyPackageDependency } from './types.ts';\nimport {\n blockLineRegEx,\n galaxyDepRegex,\n nameMatchRegex,\n newBlockRegEx,\n} from './util.ts';\n\nfunction interpretLine(\n lineMatch: RegExpMatchArray,\n dependency: AnsibleGalaxyPackageDependency,\n): void {\n const localDependency = dependency;\n const key = lineMatch
|
|
1
|
+
{"version":3,"file":"collections.js","names":[],"sources":["../../../../lib/modules/manager/ansible-galaxy/collections.ts"],"sourcesContent":["import { regEx } from '../../../util/regex.ts';\nimport { GalaxyCollectionDatasource } from '../../datasource/galaxy-collection/index.ts';\nimport { GitTagsDatasource } from '../../datasource/git-tags/index.ts';\nimport { GithubTagsDatasource } from '../../datasource/github-tags/index.ts';\nimport type { PackageDependency } from '../types.ts';\nimport type { AnsibleGalaxyPackageDependency } from './types.ts';\nimport {\n blockLineRegEx,\n galaxyDepRegex,\n nameMatchRegex,\n newBlockRegEx,\n} from './util.ts';\n\nfunction interpretLine(\n lineMatch: RegExpMatchArray,\n dependency: AnsibleGalaxyPackageDependency,\n): void {\n const localDependency = dependency;\n const key = lineMatch.groups!.key;\n const value = lineMatch.groups!.value.replace(regEx(/[\"']/g), '');\n switch (key) {\n case 'name': {\n localDependency.managerData.name = value;\n break;\n }\n case 'version': {\n localDependency.managerData.version = value;\n localDependency.currentValue = value;\n break;\n }\n case 'source': {\n localDependency.managerData.source = value;\n if (value?.startsWith('git@') || value?.endsWith('.git')) {\n localDependency.packageName = value;\n } else {\n localDependency.registryUrls = value\n ? [value]\n : /* istanbul ignore next: should have test */ [];\n }\n break;\n }\n case 'type': {\n localDependency.managerData.type = value;\n break;\n }\n default: {\n // fail if we find an unexpected key\n localDependency.skipReason = 'unsupported';\n }\n }\n}\n\nfunction handleGitDep(\n dep: AnsibleGalaxyPackageDependency,\n nameMatch: RegExpExecArray | null,\n): void {\n dep.datasource = GitTagsDatasource.id;\n\n if (nameMatch?.groups) {\n // if a github.com repository is referenced use github-tags instead of git-tags\n if (nameMatch.groups.hostname === 'github.com') {\n dep.datasource = GithubTagsDatasource.id;\n } else {\n dep.datasource = GitTagsDatasource.id;\n }\n // source definition without version appendix\n const source = nameMatch.groups.source;\n const massagedDepName = nameMatch.groups.depName.replace(\n regEx(/.git$/),\n '',\n );\n dep.depName = `${nameMatch.groups.hostname}/${massagedDepName}`;\n // remove leading `git+` from URLs like `git+https://...`\n dep.packageName = source.replace(regEx(/git\\+/), '');\n\n // if version is declared using version appendix `<source url>,v1.2.0`, use it\n if (nameMatch.groups.version) {\n dep.currentValue = nameMatch.groups.version;\n } else {\n dep.currentValue = dep.managerData.version;\n }\n }\n}\n\nfunction handleGalaxyDep(dep: AnsibleGalaxyPackageDependency): void {\n dep.datasource = GalaxyCollectionDatasource.id;\n dep.depName = dep.managerData.name;\n dep.registryUrls = dep.managerData.source\n ? /* istanbul ignore next: should have test */ [dep.managerData.source]\n : [];\n dep.currentValue = dep.managerData.version;\n}\n\nfunction finalize(dependency: AnsibleGalaxyPackageDependency): boolean {\n const dep = dependency;\n dep.depName = dep.managerData.name;\n\n const name = dep.managerData.name;\n const nameMatch = nameMatchRegex.exec(name);\n\n // use type if defined\n switch (dependency.managerData.type) {\n case 'galaxy':\n handleGalaxyDep(dep);\n break;\n case 'git':\n handleGitDep(dep, nameMatch);\n break;\n case 'file':\n dep.skipReason = 'local-dependency';\n break;\n case null:\n // try to find out type based on source\n if (nameMatch) {\n handleGitDep(dep, nameMatch);\n break;\n }\n if (galaxyDepRegex.exec(dep.managerData.name)) {\n dep.datasource = GalaxyCollectionDatasource.id;\n dep.depName = dep.managerData.name;\n break;\n }\n dep.skipReason = 'no-source-match';\n break;\n default:\n dep.skipReason = 'unsupported';\n return true;\n }\n\n if (!dependency.currentValue && !dep.skipReason) {\n dep.skipReason = 'unspecified-version';\n }\n return true;\n}\n\nexport function extractCollections(lines: string[]): PackageDependency[] {\n const deps: PackageDependency[] = [];\n\n for (let lineNumber = 0; lineNumber < lines.length; lineNumber += 1) {\n let lineMatch = newBlockRegEx.exec(lines[lineNumber]);\n if (lineMatch) {\n const dep: AnsibleGalaxyPackageDependency = {\n depType: 'galaxy-collection',\n managerData: {\n name: null,\n version: null,\n type: null,\n source: null,\n },\n };\n do {\n interpretLine(lineMatch, dep);\n const line = lines[lineNumber + 1];\n\n if (!line) {\n break;\n }\n lineMatch = blockLineRegEx.exec(line);\n if (lineMatch) {\n lineNumber += 1;\n }\n } while (lineMatch);\n if (finalize(dep)) {\n delete (dep as PackageDependency).managerData;\n deps.push(dep);\n }\n }\n }\n return deps;\n}\n"],"mappings":"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"}
|
|
@@ -5,8 +5,8 @@ import { blockLineRegEx, galaxyDepRegex, nameMatchRegex, newBlockRegEx } from ".
|
|
|
5
5
|
//#region lib/modules/manager/ansible-galaxy/roles.ts
|
|
6
6
|
function interpretLine(lineMatch, lineNumber, dependency) {
|
|
7
7
|
const localDependency = dependency;
|
|
8
|
-
const key = lineMatch
|
|
9
|
-
const value = lineMatch
|
|
8
|
+
const key = lineMatch.groups.key;
|
|
9
|
+
const value = lineMatch.groups.value.replace(regEx(/["']/g), "");
|
|
10
10
|
switch (key) {
|
|
11
11
|
case "name":
|
|
12
12
|
localDependency.managerData.name = value;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roles.js","names":[],"sources":["../../../../lib/modules/manager/ansible-galaxy/roles.ts"],"sourcesContent":["import { regEx } from '../../../util/regex.ts';\nimport { GalaxyDatasource } from '../../datasource/galaxy/index.ts';\nimport { GitTagsDatasource } from '../../datasource/git-tags/index.ts';\nimport type { PackageDependency } from '../types.ts';\nimport type { AnsibleGalaxyPackageDependency } from './types.ts';\nimport {\n blockLineRegEx,\n galaxyDepRegex,\n nameMatchRegex,\n newBlockRegEx,\n} from './util.ts';\n\nfunction interpretLine(\n lineMatch: RegExpMatchArray,\n lineNumber: number,\n dependency: AnsibleGalaxyPackageDependency,\n): AnsibleGalaxyPackageDependency | null {\n const localDependency = dependency;\n const key = lineMatch
|
|
1
|
+
{"version":3,"file":"roles.js","names":[],"sources":["../../../../lib/modules/manager/ansible-galaxy/roles.ts"],"sourcesContent":["import { regEx } from '../../../util/regex.ts';\nimport { GalaxyDatasource } from '../../datasource/galaxy/index.ts';\nimport { GitTagsDatasource } from '../../datasource/git-tags/index.ts';\nimport type { PackageDependency } from '../types.ts';\nimport type { AnsibleGalaxyPackageDependency } from './types.ts';\nimport {\n blockLineRegEx,\n galaxyDepRegex,\n nameMatchRegex,\n newBlockRegEx,\n} from './util.ts';\n\nfunction interpretLine(\n lineMatch: RegExpMatchArray,\n lineNumber: number,\n dependency: AnsibleGalaxyPackageDependency,\n): AnsibleGalaxyPackageDependency | null {\n const localDependency = dependency;\n const key = lineMatch.groups!.key;\n const value = lineMatch.groups!.value.replace(regEx(/[\"']/g), '');\n switch (key) {\n case 'name': {\n localDependency.managerData.name = value;\n break;\n }\n case 'version': {\n localDependency.managerData.version = value;\n localDependency.currentValue = value;\n localDependency.managerData.lineNumber = lineNumber;\n break;\n }\n case 'scm': {\n localDependency.managerData.scm = value;\n break;\n }\n case 'src': {\n localDependency.managerData.src = value;\n break;\n }\n default: {\n return null;\n }\n }\n return localDependency;\n}\n\nfunction finalize(dependency: AnsibleGalaxyPackageDependency): boolean {\n const dep = dependency;\n if (dependency.managerData.version === null) {\n dep.skipReason = 'unspecified-version';\n return false;\n }\n const source = dep.managerData.src ?? '';\n const sourceMatch = nameMatchRegex.exec(source);\n if (sourceMatch?.groups) {\n dep.datasource = GitTagsDatasource.id;\n dep.depName = sourceMatch.groups.depName.replace(regEx(/.git$/), '');\n // remove leading `git+` from URLs like `git+https://...`\n dep.packageName = source.replace(regEx(/git\\+/), '');\n } else if (galaxyDepRegex.exec(source)) {\n dep.datasource = GalaxyDatasource.id;\n dep.depName = source;\n dep.packageName = source;\n } else if (galaxyDepRegex.exec(dep.managerData.name ?? '')) {\n dep.datasource = GalaxyDatasource.id;\n dep.depName = dep.managerData.name!;\n dep.packageName = dep.managerData.name!;\n } else {\n dep.skipReason = 'no-source-match';\n return false;\n }\n if (dep.managerData.name !== null) {\n dep.depName = dep.managerData.name;\n }\n\n return true;\n}\n\nexport function extractRoles(lines: string[]): PackageDependency[] {\n const deps: PackageDependency[] = [];\n\n for (let lineNumber = 0; lineNumber < lines.length; lineNumber += 1) {\n let lineMatch = newBlockRegEx.exec(lines[lineNumber]);\n if (lineMatch) {\n const dep: AnsibleGalaxyPackageDependency = {\n depType: 'role',\n managerData: {\n name: null,\n version: null,\n scm: null,\n src: null,\n },\n };\n do {\n const localdep = interpretLine(lineMatch, lineNumber, dep);\n if (!localdep) {\n break;\n }\n const line = lines[lineNumber + 1];\n\n if (!line) {\n break;\n }\n lineMatch = blockLineRegEx.exec(line);\n if (lineMatch) {\n lineNumber += 1;\n }\n } while (lineMatch);\n if (finalize(dep)) {\n delete (dep as PackageDependency).managerData;\n deps.push(dep);\n }\n }\n }\n return deps;\n}\n"],"mappings":";;;;;AAYA,SAAS,cACP,WACA,YACA,YACuC;CACvC,MAAM,kBAAkB;CACxB,MAAM,MAAM,UAAU,OAAQ;CAC9B,MAAM,QAAQ,UAAU,OAAQ,MAAM,QAAQ,MAAM,OAAO,GAAG,EAAE;CAChE,QAAQ,KAAR;EACE,KAAK;GACH,gBAAgB,YAAY,OAAO;GACnC;EAEF,KAAK;GACH,gBAAgB,YAAY,UAAU;GACtC,gBAAgB,eAAe;GAC/B,gBAAgB,YAAY,aAAa;GACzC;EAEF,KAAK;GACH,gBAAgB,YAAY,MAAM;GAClC;EAEF,KAAK;GACH,gBAAgB,YAAY,MAAM;GAClC;EAEF,SACE,OAAO;CAEX;CACA,OAAO;AACT;AAEA,SAAS,SAAS,YAAqD;CACrE,MAAM,MAAM;CACZ,IAAI,WAAW,YAAY,YAAY,MAAM;EAC3C,IAAI,aAAa;EACjB,OAAO;CACT;CACA,MAAM,SAAS,IAAI,YAAY,OAAO;CACtC,MAAM,cAAc,eAAe,KAAK,MAAM;CAC9C,IAAI,aAAa,QAAQ;EACvB,IAAI,aAAa,kBAAkB;EACnC,IAAI,UAAU,YAAY,OAAO,QAAQ,QAAQ,MAAM,OAAO,GAAG,EAAE;EAEnE,IAAI,cAAc,OAAO,QAAQ,MAAM,OAAO,GAAG,EAAE;CACrD,OAAO,IAAI,eAAe,KAAK,MAAM,GAAG;EACtC,IAAI,aAAa,iBAAiB;EAClC,IAAI,UAAU;EACd,IAAI,cAAc;CACpB,OAAO,IAAI,eAAe,KAAK,IAAI,YAAY,QAAQ,EAAE,GAAG;EAC1D,IAAI,aAAa,iBAAiB;EAClC,IAAI,UAAU,IAAI,YAAY;EAC9B,IAAI,cAAc,IAAI,YAAY;CACpC,OAAO;EACL,IAAI,aAAa;EACjB,OAAO;CACT;CACA,IAAI,IAAI,YAAY,SAAS,MAC3B,IAAI,UAAU,IAAI,YAAY;CAGhC,OAAO;AACT;AAEA,SAAgB,aAAa,OAAsC;CACjE,MAAM,OAA4B,CAAC;CAEnC,KAAK,IAAI,aAAa,GAAG,aAAa,MAAM,QAAQ,cAAc,GAAG;EACnE,IAAI,YAAY,cAAc,KAAK,MAAM,WAAW;EACpD,IAAI,WAAW;GACb,MAAM,MAAsC;IAC1C,SAAS;IACT,aAAa;KACX,MAAM;KACN,SAAS;KACT,KAAK;KACL,KAAK;IACP;GACF;GACA,GAAG;IAED,IAAI,CADa,cAAc,WAAW,YAAY,GAC1C,GACV;IAEF,MAAM,OAAO,MAAM,aAAa;IAEhC,IAAI,CAAC,MACH;IAEF,YAAY,eAAe,KAAK,IAAI;IACpC,IAAI,WACF,cAAc;GAElB,SAAS;GACT,IAAI,SAAS,GAAG,GAAG;IACjB,OAAQ,IAA0B;IAClC,KAAK,KAAK,GAAG;GACf;EACF;CACF;CACA,OAAO;AACT"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { regEx } from "../../../util/regex.js";
|
|
2
2
|
//#region lib/modules/manager/ansible-galaxy/util.ts
|
|
3
|
-
const newBlockRegEx = regEx(/^\s*-\s*((
|
|
4
|
-
const blockLineRegEx = regEx(/^\s*((
|
|
3
|
+
const newBlockRegEx = regEx(/^\s*-\s*(?:(?<key>\w+):\s*(?<value>.*))$/);
|
|
4
|
+
const blockLineRegEx = regEx(/^\s*(?:(?<key>\w+):\s*(?<value>\S+))\s*$/);
|
|
5
5
|
const galaxyDepRegex = regEx(/[\w-]+\.[\w-]+/);
|
|
6
6
|
const dependencyRegex = regEx(/^dependencies:/);
|
|
7
|
-
const galaxyRegEx = regEx(/^\s+["']?(?<packageName>[\w.]+)["']?:\s*["']?(?<version>.+?)["']?\s*(
|
|
8
|
-
const nameMatchRegex = regEx(/(?<source>((git\+)?(?:(git|ssh|https?):\/\/)?(
|
|
7
|
+
const galaxyRegEx = regEx(/^\s+["']?(?<packageName>[\w.]+)["']?:\s*["']?(?<version>.+?)["']?\s*(?:\s#.*)?$/);
|
|
8
|
+
const nameMatchRegex = regEx(/(?<source>(?:(?:git\+)?(?:(?:git|ssh|https?):\/\/)?(?:.*@)?(?<hostname>[\w.-]+)(?:(?::\d+)?\/|:))(?<depName>[\w./-]+)(?:\.git)?)(?:,(?<version>[\w.]*))?/);
|
|
9
9
|
//#endregion
|
|
10
10
|
export { blockLineRegEx, dependencyRegex, galaxyDepRegex, galaxyRegEx, nameMatchRegex, newBlockRegEx };
|
|
11
11
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.js","names":[],"sources":["../../../../lib/modules/manager/ansible-galaxy/util.ts"],"sourcesContent":["import { regEx } from '../../../util/regex.ts';\n\nexport const newBlockRegEx = regEx(/^\\s*-\\s*((
|
|
1
|
+
{"version":3,"file":"util.js","names":[],"sources":["../../../../lib/modules/manager/ansible-galaxy/util.ts"],"sourcesContent":["import { regEx } from '../../../util/regex.ts';\n\nexport const newBlockRegEx = regEx(/^\\s*-\\s*(?:(?<key>\\w+):\\s*(?<value>.*))$/);\nexport const blockLineRegEx = regEx(/^\\s*(?:(?<key>\\w+):\\s*(?<value>\\S+))\\s*$/);\nexport const galaxyDepRegex = regEx(/[\\w-]+\\.[\\w-]+/);\nexport const dependencyRegex = regEx(/^dependencies:/);\nexport const galaxyRegEx = regEx(\n /^\\s+[\"']?(?<packageName>[\\w.]+)[\"']?:\\s*[\"']?(?<version>.+?)[\"']?\\s*(?:\\s#.*)?$/,\n);\nexport const nameMatchRegex = regEx(\n /(?<source>(?:(?:git\\+)?(?:(?:git|ssh|https?):\\/\\/)?(?:.*@)?(?<hostname>[\\w.-]+)(?:(?::\\d+)?\\/|:))(?<depName>[\\w./-]+)(?:\\.git)?)(?:,(?<version>[\\w.]*))?/,\n);\n"],"mappings":";;AAEA,MAAa,gBAAgB,MAAM,0CAA0C;AAC7E,MAAa,iBAAiB,MAAM,0CAA0C;AAC9E,MAAa,iBAAiB,MAAM,gBAAgB;AACpD,MAAa,kBAAkB,MAAM,gBAAgB;AACrD,MAAa,cAAc,MACzB,iFACF;AACA,MAAa,iBAAiB,MAC5B,0JACF"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { regEx } from "../../../util/regex.js";
|
|
2
2
|
//#region lib/modules/manager/ant/properties.ts
|
|
3
|
-
const fullPlaceholderRegex = regEx(/^\$\{([^}]+)}$/);
|
|
3
|
+
const fullPlaceholderRegex = regEx(/^\$\{(?<key>[^}]+)}$/);
|
|
4
4
|
const placeholderTestRegex = regEx(/\$\{[^}]+}/);
|
|
5
|
-
const propertySeparatorRegex = regEx(/^([^=:\s]+)\s*[=:\s]\s*(
|
|
5
|
+
const propertySeparatorRegex = regEx(/^(?<key>[^=:\s]+)\s*[=:\s]\s*(?<value>.*)$/);
|
|
6
6
|
function containsPlaceholder(str) {
|
|
7
7
|
return !!str && placeholderTestRegex.test(str);
|
|
8
8
|
}
|
|
@@ -14,8 +14,8 @@ function findAttrValuePosition(content, node, attrName) {
|
|
|
14
14
|
const startTag = node.startTagPosition;
|
|
15
15
|
const tagEnd = content.indexOf(">", startTag);
|
|
16
16
|
const tagContent = content.slice(startTag, tagEnd + 1);
|
|
17
|
-
const match = regEx(`${RegExp.escape(attrName)}\\s*=\\s*(?:"([^"]*)"|'([^']*)')`).exec(tagContent);
|
|
18
|
-
const valueInMatch = match
|
|
17
|
+
const match = regEx(`${RegExp.escape(attrName)}\\s*=\\s*(?:"(?<dq>[^"]*)"|'(?<sq>[^']*)')`).exec(tagContent);
|
|
18
|
+
const valueInMatch = match.groups.dq ?? match.groups.sq;
|
|
19
19
|
const valueOffset = match[0].indexOf(valueInMatch);
|
|
20
20
|
return startTag + match.index + valueOffset;
|
|
21
21
|
}
|
|
@@ -33,11 +33,11 @@ function parsePropertiesFile(content, packageFile, props) {
|
|
|
33
33
|
}
|
|
34
34
|
const separatorMatch = propertySeparatorRegex.exec(line);
|
|
35
35
|
if (separatorMatch) {
|
|
36
|
-
const key = separatorMatch
|
|
37
|
-
const val = separatorMatch
|
|
36
|
+
const key = separatorMatch.groups.key;
|
|
37
|
+
const val = separatorMatch.groups.value.trim();
|
|
38
38
|
if (!(key in props)) props[key] = {
|
|
39
39
|
val,
|
|
40
|
-
fileReplacePosition: offset + rawLine.indexOf(line) + line.indexOf(separatorMatch
|
|
40
|
+
fileReplacePosition: offset + rawLine.indexOf(line) + line.indexOf(separatorMatch.groups.value),
|
|
41
41
|
packageFile
|
|
42
42
|
};
|
|
43
43
|
}
|
|
@@ -56,7 +56,7 @@ function applyProps(dep, depPackageFile, props) {
|
|
|
56
56
|
dep.skipReason = "version-placeholder";
|
|
57
57
|
return dep;
|
|
58
58
|
}
|
|
59
|
-
const propKey = fullMatch
|
|
59
|
+
const propKey = fullMatch.groups.key;
|
|
60
60
|
const prop = props[propKey];
|
|
61
61
|
if (!prop) {
|
|
62
62
|
dep.skipReason = "version-placeholder";
|
|
@@ -91,7 +91,7 @@ function resolveKey(key, props, resolved, chain) {
|
|
|
91
91
|
}
|
|
92
92
|
chain.add(key);
|
|
93
93
|
let isCircular = false;
|
|
94
|
-
const val = prop.val.replace(regEx(/\$\{([^}]+)}/g), (match, refKey) => {
|
|
94
|
+
const val = prop.val.replace(regEx(/\$\{(?<key>[^}]+)}/g), (match, refKey) => {
|
|
95
95
|
const refResult = resolveKey(refKey, props, resolved, chain);
|
|
96
96
|
if (refResult === null) {
|
|
97
97
|
isCircular = true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"properties.js","names":[],"sources":["../../../../lib/modules/manager/ant/properties.ts"],"sourcesContent":["import type { XmlElement } from 'xmldoc';\nimport { regEx } from '../../../util/regex.ts';\nimport type { PackageDependency } from '../types.ts';\nimport type { AntProp } from './types.ts';\n\nconst fullPlaceholderRegex = regEx(/^\\$\\{([^}]+)}$/);\nconst placeholderTestRegex = regEx(/\\$\\{[^}]+}/);\nconst propertySeparatorRegex = regEx(/^([^=:\\s]+)\\s*[=:\\s]\\s*(
|
|
1
|
+
{"version":3,"file":"properties.js","names":[],"sources":["../../../../lib/modules/manager/ant/properties.ts"],"sourcesContent":["import type { XmlElement } from 'xmldoc';\nimport { regEx } from '../../../util/regex.ts';\nimport type { PackageDependency } from '../types.ts';\nimport type { AntProp } from './types.ts';\n\nconst fullPlaceholderRegex = regEx(/^\\$\\{(?<key>[^}]+)}$/);\nconst placeholderTestRegex = regEx(/\\$\\{[^}]+}/);\nconst propertySeparatorRegex = regEx(\n /^(?<key>[^=:\\s]+)\\s*[=:\\s]\\s*(?<value>.*)$/,\n);\n\nexport function containsPlaceholder(str: string | null | undefined): boolean {\n return !!str && placeholderTestRegex.test(str);\n}\n\n/**\n * Find the byte offset of an attribute's value in raw XML content.\n * Returns the offset of the first character of the value (after the opening quote).\n */\nexport function findAttrValuePosition(\n content: string,\n node: XmlElement,\n attrName: string,\n): number {\n const startTag = node.startTagPosition!;\n const tagEnd = content.indexOf('>', startTag);\n const tagContent = content.slice(startTag, tagEnd + 1);\n\n const attrPattern = regEx(\n `${RegExp.escape(attrName)}\\\\s*=\\\\s*(?:\"(?<dq>[^\"]*)\"|'(?<sq>[^']*)')`,\n );\n const match = attrPattern.exec(tagContent)!;\n\n const valueInMatch = match.groups!.dq ?? match.groups!.sq;\n const valueOffset = match[0].indexOf(valueInMatch);\n return startTag + match.index + valueOffset;\n}\n\n/**\n * Parse a .properties file into a map of property names to AntProp.\n * Implements first-definition-wins: if a key already exists in the map, it is not overwritten.\n */\nexport function parsePropertiesFile(\n content: string,\n packageFile: string,\n props: Record<string, AntProp>,\n): void {\n let offset = 0;\n for (const rawLine of content.split('\\n')) {\n const line = rawLine.trim();\n // Skip comments and blank lines\n if (line.startsWith('#') || line.startsWith('!') || line === '') {\n offset += rawLine.length + 1; // +1 for newline\n continue;\n }\n\n // Match key=value, key:value, or key value (first separator wins)\n const separatorMatch = propertySeparatorRegex.exec(line);\n if (separatorMatch) {\n const key = separatorMatch.groups!.key;\n const val = separatorMatch.groups!.value.trim();\n\n // First-definition-wins\n if (!(key in props)) {\n // fileReplacePosition points to the start of the value in the raw content\n const lineStart = offset + rawLine.indexOf(line);\n const keyEnd = line.indexOf(separatorMatch.groups!.value);\n const fileReplacePosition = lineStart + keyEnd;\n\n props[key] = { val, fileReplacePosition, packageFile };\n }\n }\n\n offset += rawLine.length + 1;\n }\n}\n\n/**\n * Apply property resolution to a dependency.\n * Handles chained references with circular detection.\n */\nexport function applyProps(\n dep: PackageDependency,\n depPackageFile: string,\n props: Record<string, AntProp>,\n): PackageDependency {\n const currentValue = dep.currentValue;\n\n if (!currentValue || !containsPlaceholder(currentValue)) {\n return dep;\n }\n\n // Check if the entire version is a single property reference\n const fullMatch = fullPlaceholderRegex.exec(currentValue);\n if (!fullMatch) {\n // Partial placeholder in version string - not supported for updates\n dep.skipReason = 'version-placeholder';\n return dep;\n }\n\n const propKey = fullMatch.groups!.key;\n const prop = props[propKey];\n if (!prop) {\n dep.skipReason = 'version-placeholder';\n return dep;\n }\n\n // After resolveChainedProps, prop.val is either fully resolved or still contains\n // placeholders (meaning circular or unresolvable)\n if (containsPlaceholder(prop.val)) {\n dep.skipReason = 'recursive-placeholder';\n return dep;\n }\n\n dep.currentValue = prop.val;\n dep.sharedVariableName = propKey;\n dep.fileReplacePosition = prop.fileReplacePosition;\n if (prop.packageFile !== depPackageFile) {\n dep.editFile = prop.packageFile;\n }\n // propSource is used to route deps to the correct PackageFile\n dep.propSource = prop.packageFile;\n return dep;\n}\n\n/**\n * Resolve a single property key, following chained references.\n * Returns the resolved value or null if circular/unresolvable.\n */\nfunction resolveKey(\n key: string,\n props: Record<string, AntProp>,\n resolved: Map<string, string | null>,\n chain: Set<string>,\n): string | null {\n if (resolved.has(key)) {\n return resolved.get(key)!;\n }\n if (chain.has(key)) {\n // Circular reference detected\n resolved.set(key, null);\n return null;\n }\n const prop = props[key];\n if (!prop) {\n return null;\n }\n if (!containsPlaceholder(prop.val)) {\n resolved.set(key, prop.val);\n return prop.val;\n }\n\n chain.add(key);\n let isCircular = false;\n const val = prop.val.replace(\n regEx(/\\$\\{(?<key>[^}]+)}/g),\n (match: string, refKey: string) => {\n const refResult = resolveKey(refKey, props, resolved, chain);\n if (refResult === null) {\n isCircular = true;\n return match;\n }\n return refResult;\n },\n );\n chain.delete(key);\n\n if (isCircular) {\n resolved.set(key, null);\n return null;\n }\n\n resolved.set(key, val);\n prop.val = val;\n return val;\n}\n\n/**\n * Resolve chained property references within the property map itself.\n * E.g., if prop A = \"${B}\" and prop B = \"1.0\", resolve A to \"1.0\".\n * Marks circular properties by setting val to a placeholder that will be caught later.\n */\nexport function resolveChainedProps(props: Record<string, AntProp>): void {\n const resolved = new Map<string, string | null>(); // null = circular\n\n for (const key of Object.keys(props)) {\n resolveKey(key, props, resolved, new Set());\n }\n}\n"],"mappings":"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"}
|
|
@@ -6,7 +6,7 @@ import { isFunction, isTruthy } from "@sindresorhus/is";
|
|
|
6
6
|
//#region lib/modules/manager/asdf/extract.ts
|
|
7
7
|
function extractPackageFile(content) {
|
|
8
8
|
logger.trace(`asdf.extractPackageFile()`);
|
|
9
|
-
const regex = regEx(/^(?<toolName>([\w_-]+)) +(?<version>[^\s#]+)(?: +[^\s#]+)* *(?: #(?<comment>.*))?$/gm);
|
|
9
|
+
const regex = regEx(/^(?<toolName>(?:[\w_-]+)) +(?<version>[^\s#]+)(?: +[^\s#]+)* *(?: #(?<comment>.*))?$/gm);
|
|
10
10
|
const deps = [];
|
|
11
11
|
for (const groups of [...content.matchAll(regex)].map((m) => m.groups).filter(isTruthy)) {
|
|
12
12
|
const depName = groups.toolName.trim();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extract.js","names":[],"sources":["../../../../lib/modules/manager/asdf/extract.ts"],"sourcesContent":["import { isFunction, isTruthy } from '@sindresorhus/is';\nimport { logger } from '../../../logger/index.ts';\nimport { isSkipComment } from '../../../util/ignore.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport type { PackageDependency, PackageFileContent } from '../types.ts';\nimport type { StaticTooling } from './types.ts';\nimport { upgradeableTooling } from './upgradeable-tooling.ts';\n\nexport function extractPackageFile(content: string): PackageFileContent | null {\n logger.trace(`asdf.extractPackageFile()`);\n\n const regex = regEx(\n /^(?<toolName>([\\w_-]+)) +(?<version>[^\\s#]+)(?: +[^\\s#]+)* *(?: #(?<comment>.*))?$/gm,\n );\n\n const deps: PackageDependency[] = [];\n\n for (const groups of [...content.matchAll(regex)]\n .map((m) => m.groups)\n .filter(isTruthy)) {\n const depName = groups.toolName.trim();\n const version = groups.version.trim();\n\n const toolConfig = upgradeableTooling[depName];\n let toolDefinition: StaticTooling | undefined;\n if (toolConfig) {\n toolDefinition = isFunction(toolConfig.config)\n ? toolConfig.config(version)\n : toolConfig.config;\n }\n\n if (toolDefinition) {\n const dep: PackageDependency = {\n currentValue: version,\n depName,\n ...toolDefinition,\n };\n if (isSkipComment((groups.comment ?? '').trim())) {\n dep.skipReason = 'ignored';\n }\n\n deps.push(dep);\n } else {\n const dep: PackageDependency = {\n depName,\n skipReason: 'unsupported-datasource',\n };\n\n deps.push(dep);\n }\n }\n\n return deps.length ? { deps } : null;\n}\n"],"mappings":";;;;;;AAQA,SAAgB,mBAAmB,SAA4C;CAC7E,OAAO,MAAM,2BAA2B;CAExC,MAAM,QAAQ,MACZ,
|
|
1
|
+
{"version":3,"file":"extract.js","names":[],"sources":["../../../../lib/modules/manager/asdf/extract.ts"],"sourcesContent":["import { isFunction, isTruthy } from '@sindresorhus/is';\nimport { logger } from '../../../logger/index.ts';\nimport { isSkipComment } from '../../../util/ignore.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport type { PackageDependency, PackageFileContent } from '../types.ts';\nimport type { StaticTooling } from './types.ts';\nimport { upgradeableTooling } from './upgradeable-tooling.ts';\n\nexport function extractPackageFile(content: string): PackageFileContent | null {\n logger.trace(`asdf.extractPackageFile()`);\n\n const regex = regEx(\n /^(?<toolName>(?:[\\w_-]+)) +(?<version>[^\\s#]+)(?: +[^\\s#]+)* *(?: #(?<comment>.*))?$/gm,\n );\n\n const deps: PackageDependency[] = [];\n\n for (const groups of [...content.matchAll(regex)]\n .map((m) => m.groups)\n .filter(isTruthy)) {\n const depName = groups.toolName.trim();\n const version = groups.version.trim();\n\n const toolConfig = upgradeableTooling[depName];\n let toolDefinition: StaticTooling | undefined;\n if (toolConfig) {\n toolDefinition = isFunction(toolConfig.config)\n ? toolConfig.config(version)\n : toolConfig.config;\n }\n\n if (toolDefinition) {\n const dep: PackageDependency = {\n currentValue: version,\n depName,\n ...toolDefinition,\n };\n if (isSkipComment((groups.comment ?? '').trim())) {\n dep.skipReason = 'ignored';\n }\n\n deps.push(dep);\n } else {\n const dep: PackageDependency = {\n depName,\n skipReason: 'unsupported-datasource',\n };\n\n deps.push(dep);\n }\n }\n\n return deps.length ? { deps } : null;\n}\n"],"mappings":";;;;;;AAQA,SAAgB,mBAAmB,SAA4C;CAC7E,OAAO,MAAM,2BAA2B;CAExC,MAAM,QAAQ,MACZ,wFACF;CAEA,MAAM,OAA4B,CAAC;CAEnC,KAAK,MAAM,UAAU,CAAC,GAAG,QAAQ,SAAS,KAAK,CAAC,CAAC,CAC9C,KAAK,MAAM,EAAE,MAAM,CAAC,CACpB,OAAO,QAAQ,GAAG;EACnB,MAAM,UAAU,OAAO,SAAS,KAAK;EACrC,MAAM,UAAU,OAAO,QAAQ,KAAK;EAEpC,MAAM,aAAa,mBAAmB;EACtC,IAAI;EACJ,IAAI,YACF,iBAAiB,WAAW,WAAW,MAAM,IACzC,WAAW,OAAO,OAAO,IACzB,WAAW;EAGjB,IAAI,gBAAgB;GAClB,MAAM,MAAyB;IAC7B,cAAc;IACd;IACA,GAAG;GACL;GACA,IAAI,eAAe,OAAO,WAAW,GAAA,CAAI,KAAK,CAAC,GAC7C,IAAI,aAAa;GAGnB,KAAK,KAAK,GAAG;EACf,OAAO;GACL,MAAM,MAAyB;IAC7B;IACA,YAAY;GACd;GAEA,KAAK,KAAK,GAAG;EACf;CACF;CAEA,OAAO,KAAK,SAAS,EAAE,KAAK,IAAI;AAClC"}
|
|
@@ -246,7 +246,7 @@ const upgradeableTooling = {
|
|
|
246
246
|
asdfPluginUrl: "https://github.com/oae/asdf-flutter",
|
|
247
247
|
config: (version) => ({
|
|
248
248
|
datasource: FlutterVersionDatasource.id,
|
|
249
|
-
currentValue: version.replace(regEx(/-(stable|beta|dev)$/), "")
|
|
249
|
+
currentValue: version.replace(regEx(/-(?:stable|beta|dev)$/), "")
|
|
250
250
|
})
|
|
251
251
|
},
|
|
252
252
|
flux2: {
|