renovate 44.210.2 → 44.211.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/options/index.js +1 -1
- package/dist/config/options/index.js.map +1 -1
- package/dist/config/utils.js +2 -1
- package/dist/config/utils.js.map +1 -1
- package/dist/config/validation-helpers/regex-glob-matchers.js.map +1 -1
- package/dist/config/validation-helpers/utils.js +5 -1
- package/dist/config/validation-helpers/utils.js.map +1 -1
- package/dist/config/validation.js +8 -2
- package/dist/config/validation.js.map +1 -1
- package/dist/config-validator.js +1 -1
- package/dist/config-validator.js.map +1 -1
- package/dist/global-config-option-defaults.generated.js +1 -1
- package/dist/global-config-option-defaults.generated.js.map +1 -1
- package/dist/instrumentation/index.js +3 -2
- package/dist/instrumentation/index.js.map +1 -1
- package/dist/logger/bunyan.js +3 -2
- package/dist/logger/bunyan.js.map +1 -1
- package/dist/logger/pretty-stdout.js +2 -1
- package/dist/logger/pretty-stdout.js.map +1 -1
- package/dist/modules/datasource/apk/index.js +2 -2
- package/dist/modules/datasource/apk/index.js.map +1 -1
- package/dist/modules/datasource/artifactory/index.js +2 -3
- package/dist/modules/datasource/artifactory/index.js.map +1 -1
- package/dist/modules/datasource/bazel/index.js +2 -1
- package/dist/modules/datasource/bazel/index.js.map +1 -1
- package/dist/modules/datasource/cdnjs/index.js +2 -1
- package/dist/modules/datasource/cdnjs/index.js.map +1 -1
- package/dist/modules/datasource/conda/index.js +2 -1
- package/dist/modules/datasource/conda/index.js.map +1 -1
- package/dist/modules/datasource/crate/index.js +2 -1
- package/dist/modules/datasource/crate/index.js.map +1 -1
- package/dist/modules/datasource/dart-version/index.js +2 -1
- package/dist/modules/datasource/dart-version/index.js.map +1 -1
- package/dist/modules/datasource/datasource.js +2 -2
- package/dist/modules/datasource/datasource.js.map +1 -1
- package/dist/modules/datasource/deb/url.js +3 -1
- package/dist/modules/datasource/deb/url.js.map +1 -1
- package/dist/modules/datasource/devbox/index.js +2 -1
- package/dist/modules/datasource/devbox/index.js.map +1 -1
- package/dist/modules/datasource/docker/common.js +10 -8
- package/dist/modules/datasource/docker/common.js.map +1 -1
- package/dist/modules/datasource/docker/ecr.js +2 -1
- package/dist/modules/datasource/docker/ecr.js.map +1 -1
- package/dist/modules/datasource/docker/index.js +20 -17
- package/dist/modules/datasource/docker/index.js.map +1 -1
- package/dist/modules/datasource/gitea-tags/base.js +2 -3
- package/dist/modules/datasource/gitea-tags/base.js.map +1 -1
- package/dist/modules/datasource/github-tags/index.js +2 -1
- package/dist/modules/datasource/github-tags/index.js.map +1 -1
- package/dist/modules/datasource/gitlab-tags/index.js +2 -3
- package/dist/modules/datasource/gitlab-tags/index.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/common.js +8 -2
- package/dist/modules/datasource/go/common.js.map +1 -1
- package/dist/modules/datasource/go/env.js +2 -1
- package/dist/modules/datasource/go/env.js.map +1 -1
- package/dist/modules/datasource/go/releases-goproxy.js +7 -5
- package/dist/modules/datasource/go/releases-goproxy.js.map +1 -1
- package/dist/modules/datasource/helm/index.js +2 -1
- package/dist/modules/datasource/helm/index.js.map +1 -1
- package/dist/modules/datasource/hexpm-bob/index.js +2 -1
- package/dist/modules/datasource/hexpm-bob/index.js.map +1 -1
- package/dist/modules/datasource/index.js +4 -3
- package/dist/modules/datasource/index.js.map +1 -1
- package/dist/modules/datasource/java-version/adoptium.js +3 -2
- package/dist/modules/datasource/java-version/adoptium.js.map +1 -1
- package/dist/modules/datasource/java-version/graalvm.js +2 -1
- package/dist/modules/datasource/java-version/graalvm.js.map +1 -1
- package/dist/modules/datasource/maven/index.js.map +1 -1
- package/dist/modules/datasource/maven/util.js +7 -10
- package/dist/modules/datasource/maven/util.js.map +1 -1
- package/dist/modules/datasource/npm/npmrc.js +2 -2
- package/dist/modules/datasource/npm/npmrc.js.map +1 -1
- package/dist/modules/datasource/nuget/v3.js +3 -5
- package/dist/modules/datasource/nuget/v3.js.map +1 -1
- package/dist/modules/datasource/packagist/index.js +4 -5
- package/dist/modules/datasource/packagist/index.js.map +1 -1
- package/dist/modules/datasource/pod/index.js +4 -4
- package/dist/modules/datasource/pod/index.js.map +1 -1
- package/dist/modules/datasource/pypi/index.js +19 -11
- package/dist/modules/datasource/pypi/index.js.map +1 -1
- package/dist/modules/datasource/python-version/index.js +2 -3
- package/dist/modules/datasource/python-version/index.js.map +1 -1
- package/dist/modules/datasource/repology/index.js +4 -3
- package/dist/modules/datasource/repology/index.js.map +1 -1
- package/dist/modules/datasource/rpm/providers/common.js +3 -1
- package/dist/modules/datasource/rpm/providers/common.js.map +1 -1
- package/dist/modules/datasource/rubygems/index.js +2 -5
- package/dist/modules/datasource/rubygems/index.js.map +1 -1
- package/dist/modules/datasource/rubygems/versions-endpoint-cache.js +13 -18
- package/dist/modules/datasource/rubygems/versions-endpoint-cache.js.map +1 -1
- package/dist/modules/datasource/terraform-module/base.js +2 -1
- package/dist/modules/datasource/terraform-module/base.js.map +1 -1
- package/dist/modules/datasource/terraform-provider/index.js +2 -3
- package/dist/modules/datasource/terraform-provider/index.js.map +1 -1
- package/dist/modules/manager/bazel-module/parser/context.js +0 -1
- package/dist/modules/manager/bazel-module/parser/context.js.map +1 -1
- package/dist/modules/manager/bundler/host-rules.js +4 -1
- package/dist/modules/manager/bundler/host-rules.js.map +1 -1
- package/dist/modules/manager/composer/range.js +1 -1
- package/dist/modules/manager/composer/range.js.map +1 -1
- package/dist/modules/manager/custom/utils.js +3 -1
- package/dist/modules/manager/custom/utils.js.map +1 -1
- package/dist/modules/manager/devbox/schema.js +2 -1
- package/dist/modules/manager/devbox/schema.js.map +1 -1
- package/dist/modules/manager/dockerfile/extract.js +10 -2
- package/dist/modules/manager/dockerfile/extract.js.map +1 -1
- package/dist/modules/manager/fingerprint.generated.js +1 -1
- package/dist/modules/manager/fingerprint.generated.js.map +1 -1
- package/dist/modules/manager/github-actions/parse.js +2 -1
- package/dist/modules/manager/github-actions/parse.js.map +1 -1
- package/dist/modules/manager/gomod/artifacts.js +5 -2
- package/dist/modules/manager/gomod/artifacts.js.map +1 -1
- package/dist/modules/manager/gradle/artifacts.js +5 -2
- package/dist/modules/manager/gradle/artifacts.js.map +1 -1
- package/dist/modules/manager/gradle/utils.js +2 -1
- package/dist/modules/manager/gradle/utils.js.map +1 -1
- package/dist/modules/manager/gradle-wrapper/utils.js +9 -5
- package/dist/modules/manager/gradle-wrapper/utils.js.map +1 -1
- package/dist/modules/manager/helm-values/util.js +1 -1
- package/dist/modules/manager/helm-values/util.js.map +1 -1
- package/dist/modules/manager/helmfile/artifacts.js +1 -1
- package/dist/modules/manager/helmfile/artifacts.js.map +1 -1
- package/dist/modules/manager/helmv3/artifacts.js +1 -1
- package/dist/modules/manager/helmv3/artifacts.js.map +1 -1
- package/dist/modules/manager/maven/extract.js +5 -2
- package/dist/modules/manager/maven/extract.js.map +1 -1
- package/dist/modules/manager/maven-wrapper/artifacts.js +3 -2
- package/dist/modules/manager/maven-wrapper/artifacts.js.map +1 -1
- package/dist/modules/manager/mise/artifacts.js +2 -1
- package/dist/modules/manager/mise/artifacts.js.map +1 -1
- package/dist/modules/manager/mise/extract.js.map +1 -1
- package/dist/modules/manager/npm/artifacts.js +3 -1
- package/dist/modules/manager/npm/artifacts.js.map +1 -1
- package/dist/modules/manager/npm/extract/common/dependency.js +4 -1
- package/dist/modules/manager/npm/extract/common/dependency.js.map +1 -1
- package/dist/modules/manager/npm/extract/common/package-file.js +2 -1
- package/dist/modules/manager/npm/extract/common/package-file.js.map +1 -1
- package/dist/modules/manager/npm/extract/index.js.map +1 -1
- package/dist/modules/manager/npm/extract/post/locked-versions.js.map +1 -1
- package/dist/modules/manager/npm/npmrc.js +2 -1
- package/dist/modules/manager/npm/npmrc.js.map +1 -1
- package/dist/modules/manager/npm/post-update/index.js +2 -1
- package/dist/modules/manager/npm/post-update/index.js.map +1 -1
- package/dist/modules/manager/npm/post-update/npm.js +2 -3
- package/dist/modules/manager/npm/post-update/npm.js.map +1 -1
- package/dist/modules/manager/npm/post-update/yarn.js.map +1 -1
- package/dist/modules/manager/npm/schema.js +6 -2
- package/dist/modules/manager/npm/schema.js.map +1 -1
- package/dist/modules/manager/npm/update/dependency/index.js +3 -2
- package/dist/modules/manager/npm/update/dependency/index.js.map +1 -1
- package/dist/modules/manager/npm/update/locked-dependency/common/parent-version.js +6 -2
- package/dist/modules/manager/npm/update/locked-dependency/common/parent-version.js.map +1 -1
- package/dist/modules/manager/npm/update/locked-dependency/package-lock/get-locked.js +2 -1
- package/dist/modules/manager/npm/update/locked-dependency/package-lock/get-locked.js.map +1 -1
- package/dist/modules/manager/nuget/package-tree.js +2 -1
- package/dist/modules/manager/nuget/package-tree.js.map +1 -1
- package/dist/modules/manager/paket/update-locked.js +4 -1
- package/dist/modules/manager/paket/update-locked.js.map +1 -1
- package/dist/modules/manager/pipenv/extract.js +4 -1
- package/dist/modules/manager/pipenv/extract.js.map +1 -1
- package/dist/modules/platform/azure/azure-helper.js +2 -1
- package/dist/modules/platform/azure/azure-helper.js.map +1 -1
- package/dist/modules/platform/azure/index.js +7 -3
- package/dist/modules/platform/azure/index.js.map +1 -1
- package/dist/modules/platform/bitbucket/index.js +13 -6
- package/dist/modules/platform/bitbucket/index.js.map +1 -1
- package/dist/modules/platform/bitbucket-server/index.js +13 -9
- package/dist/modules/platform/bitbucket-server/index.js.map +1 -1
- package/dist/modules/platform/codecommit/index.js +2 -2
- package/dist/modules/platform/codecommit/index.js.map +1 -1
- package/dist/modules/platform/gerrit/client.js +4 -1
- package/dist/modules/platform/gerrit/client.js.map +1 -1
- package/dist/modules/platform/gerrit/index.js +3 -2
- package/dist/modules/platform/gerrit/index.js.map +1 -1
- package/dist/modules/platform/gitea/gitea-helper.js +5 -4
- package/dist/modules/platform/gitea/gitea-helper.js.map +1 -1
- package/dist/modules/platform/gitea/index.js +11 -4
- package/dist/modules/platform/gitea/index.js.map +1 -1
- package/dist/modules/platform/github/index.js +36 -23
- package/dist/modules/platform/github/index.js.map +1 -1
- package/dist/modules/platform/gitlab/index.js +16 -9
- package/dist/modules/platform/gitlab/index.js.map +1 -1
- package/dist/modules/platform/scm-manager/index.js +4 -1
- package/dist/modules/platform/scm-manager/index.js.map +1 -1
- package/dist/modules/platform/scm-manager/utils.js +2 -1
- package/dist/modules/platform/scm-manager/utils.js.map +1 -1
- package/dist/modules/versioning/cargo/index.js.map +1 -1
- package/dist/modules/versioning/composer/index.js +2 -1
- package/dist/modules/versioning/composer/index.js.map +1 -1
- package/dist/modules/versioning/conan/common.js +4 -1
- package/dist/modules/versioning/conan/common.js.map +1 -1
- package/dist/modules/versioning/debian/index.js +2 -1
- package/dist/modules/versioning/debian/index.js.map +1 -1
- package/dist/modules/versioning/gradle/compare.js +2 -1
- package/dist/modules/versioning/gradle/compare.js.map +1 -1
- package/dist/modules/versioning/hex/index.js +2 -1
- package/dist/modules/versioning/hex/index.js.map +1 -1
- package/dist/modules/versioning/julia/index.js.map +1 -1
- package/dist/modules/versioning/maven/compare.js +17 -7
- package/dist/modules/versioning/maven/compare.js.map +1 -1
- package/dist/modules/versioning/npm/index.js +2 -1
- package/dist/modules/versioning/npm/index.js.map +1 -1
- package/dist/modules/versioning/npm/range.js.map +1 -1
- package/dist/modules/versioning/paket/index.js +2 -1
- package/dist/modules/versioning/paket/index.js.map +1 -1
- package/dist/modules/versioning/paket/range.js +7 -3
- package/dist/modules/versioning/paket/range.js.map +1 -1
- package/dist/modules/versioning/pep440/index.js +2 -1
- package/dist/modules/versioning/pep440/index.js.map +1 -1
- package/dist/modules/versioning/poetry/index.js +2 -1
- package/dist/modules/versioning/poetry/index.js.map +1 -1
- package/dist/modules/versioning/regex/index.js +1 -1
- package/dist/modules/versioning/regex/index.js.map +1 -1
- package/dist/modules/versioning/rez/index.js +2 -1
- package/dist/modules/versioning/rez/index.js.map +1 -1
- package/dist/modules/versioning/vcpkg/index.js +2 -1
- package/dist/modules/versioning/vcpkg/index.js.map +1 -1
- package/dist/util/cache/package/impl/base.js +2 -1
- package/dist/util/cache/package/impl/base.js.map +1 -1
- package/dist/util/cache/package/with-cache.js +2 -1
- package/dist/util/cache/package/with-cache.js.map +1 -1
- package/dist/util/check-token.js +7 -4
- package/dist/util/check-token.js.map +1 -1
- package/dist/util/exec/utils.js +4 -1
- package/dist/util/exec/utils.js.map +1 -1
- package/dist/util/git/auth.js +5 -1
- package/dist/util/git/auth.js.map +1 -1
- package/dist/util/git/error.js.map +1 -1
- package/dist/util/host-rules.js +5 -3
- package/dist/util/host-rules.js.map +1 -1
- package/dist/util/http/cache/abstract-http-cache-provider.js +3 -2
- package/dist/util/http/cache/abstract-http-cache-provider.js.map +1 -1
- package/dist/util/http/cache/package-http-cache-provider.js +2 -1
- package/dist/util/http/cache/package-http-cache-provider.js.map +1 -1
- package/dist/util/http/github.js +15 -11
- package/dist/util/http/github.js.map +1 -1
- package/dist/util/http/gitlab.js +5 -4
- package/dist/util/http/gitlab.js.map +1 -1
- package/dist/util/http/http.js +2 -1
- package/dist/util/http/http.js.map +1 -1
- package/dist/util/http/jwt.js +2 -1
- package/dist/util/http/jwt.js.map +1 -1
- package/dist/util/http/retry-after.js +2 -1
- package/dist/util/http/retry-after.js.map +1 -1
- package/dist/util/http/status.js +95 -0
- package/dist/util/http/status.js.map +1 -0
- package/dist/util/merge-confidence/index.js +3 -2
- package/dist/util/merge-confidence/index.js.map +1 -1
- package/dist/util/package-rules/current-version.js +4 -1
- package/dist/util/package-rules/current-version.js.map +1 -1
- package/dist/util/package-rules/index.js +7 -3
- package/dist/util/package-rules/index.js.map +1 -1
- package/dist/util/schema-utils/index.js +5 -0
- package/dist/util/schema-utils/index.js.map +1 -1
- package/dist/workers/global/config/parse/host-rules-from-env.js +2 -1
- package/dist/workers/global/config/parse/host-rules-from-env.js.map +1 -1
- package/dist/workers/repository/common.js +4 -1
- package/dist/workers/repository/common.js.map +1 -1
- package/dist/workers/repository/config-migration/branch/index.js +2 -1
- package/dist/workers/repository/config-migration/branch/index.js.map +1 -1
- package/dist/workers/repository/dependency-dashboard.js +6 -2
- package/dist/workers/repository/dependency-dashboard.js.map +1 -1
- package/dist/workers/repository/finalize/repository-statistics.js +4 -1
- package/dist/workers/repository/finalize/repository-statistics.js.map +1 -1
- package/dist/workers/repository/init/merge.js +13 -3
- package/dist/workers/repository/init/merge.js.map +1 -1
- package/dist/workers/repository/onboarding/branch/check.js +2 -1
- package/dist/workers/repository/onboarding/branch/check.js.map +1 -1
- package/dist/workers/repository/onboarding/pr/pr-list.js +4 -2
- package/dist/workers/repository/onboarding/pr/pr-list.js.map +1 -1
- package/dist/workers/repository/process/extract-update.js +4 -1
- package/dist/workers/repository/process/extract-update.js.map +1 -1
- package/dist/workers/repository/process/lookup/digest.js +2 -1
- package/dist/workers/repository/process/lookup/digest.js.map +1 -1
- package/dist/workers/repository/process/lookup/generate.js +1 -1
- package/dist/workers/repository/process/lookup/generate.js.map +1 -1
- package/dist/workers/repository/process/lookup/index.js +4 -1
- package/dist/workers/repository/process/lookup/index.js.map +1 -1
- package/dist/workers/repository/process/lookup/utils.js +7 -1
- package/dist/workers/repository/process/lookup/utils.js.map +1 -1
- package/dist/workers/repository/process/vulnerabilities.js +10 -3
- package/dist/workers/repository/process/vulnerabilities.js.map +1 -1
- package/dist/workers/repository/reconfigure/index.js +2 -1
- package/dist/workers/repository/reconfigure/index.js.map +1 -1
- package/dist/workers/repository/update/branch/auto-replace.js +6 -2
- package/dist/workers/repository/update/branch/auto-replace.js.map +1 -1
- package/dist/workers/repository/update/branch/errors.js +2 -1
- package/dist/workers/repository/update/branch/errors.js.map +1 -1
- package/dist/workers/repository/update/branch/execute-post-upgrade-commands.js +2 -2
- package/dist/workers/repository/update/branch/execute-post-upgrade-commands.js.map +1 -1
- package/dist/workers/repository/update/branch/get-updated.js +1 -2
- package/dist/workers/repository/update/branch/get-updated.js.map +1 -1
- package/dist/workers/repository/update/branch/index.js +2 -1
- package/dist/workers/repository/update/branch/index.js.map +1 -1
- package/dist/workers/repository/update/branch/status-checks.js +2 -1
- package/dist/workers/repository/update/branch/status-checks.js.map +1 -1
- package/dist/workers/repository/update/pr/body/index.js.map +1 -1
- package/dist/workers/repository/update/pr/changelog/release-notes.js +3 -2
- package/dist/workers/repository/update/pr/changelog/release-notes.js.map +1 -1
- package/dist/workers/repository/update/pr/index.js +7 -3
- package/dist/workers/repository/update/pr/index.js.map +1 -1
- package/dist/workers/repository/updates/generate.js +6 -3
- 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":"base.js","names":["modulePath","hostRules.hostType"],"sources":["../../../../lib/modules/datasource/go/base.ts"],"sourcesContent":["// TODO: types (#22198)\nimport { GlobalConfig } from '../../../config/global.ts';\nimport { logger } from '../../../logger/index.ts';\nimport { detectPlatform } from '../../../util/common.ts';\nimport * as hostRules from '../../../util/host-rules.ts';\nimport { Http } from '../../../util/http/index.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport {\n parseUrl,\n trimLeadingSlash,\n trimTrailingSlash,\n} from '../../../util/url.ts';\nimport { BitbucketTagsDatasource } from '../bitbucket-tags/index.ts';\nimport { ForgejoTagsDatasource } from '../forgejo-tags/index.ts';\nimport { GitTagsDatasource } from '../git-tags/index.ts';\nimport { GiteaTagsDatasource } from '../gitea-tags/index.ts';\nimport { GithubTagsDatasource } from '../github-tags/index.ts';\nimport { GitlabTagsDatasource } from '../gitlab-tags/index.ts';\nimport type { DataSource } from './types.ts';\n\n// TODO: figure out class hierarchy (#10532)\nexport class BaseGoDatasource {\n private static readonly gitlabHttpsRegExp = regEx(\n /^(?<httpsRegExpUrl>https:\\/\\/[^/]*gitlab\\.[^/]*)\\/(?<httpsRegExpName>.+?)(?:\\/v\\d+)?[/]?$/,\n );\n private static readonly gitlabRegExp = regEx(\n /^(?<regExpUrl>gitlab\\.[^/]*)\\/(?<regExpPath>.+?)(?:\\/v\\d+)?[/]?$/,\n );\n private static readonly gitVcsRegexp = regEx(\n /^(?:[^/]+)\\/(?<module>.*)\\.git(?:$|\\/)/,\n );\n private static readonly goImportRegexp = regEx(\n /<meta\\s+name=\"?go-import\"?\\s+content=\"(?<prefix>[^\"\\s]+)\\s+(?<proto>[^\"\\s]+)\\s+(?<goImportURL>[^\"\\s]+)/,\n );\n private static readonly goImportAllRegexp = regEx(\n BaseGoDatasource.goImportRegexp.source,\n 'g',\n );\n\n private static readonly id = 'go';\n private static readonly http = new Http(BaseGoDatasource.id);\n\n static async getDatasource(goModule: string): Promise<DataSource | null> {\n if (goModule.startsWith('gopkg.in/')) {\n const [pkg] = goModule.replace('gopkg.in/', '').split('.');\n const packageName = pkg.includes('/') ? pkg : `go-${pkg}/${pkg}`;\n return {\n datasource: GithubTagsDatasource.id,\n packageName,\n registryUrl: 'https://github.com',\n };\n }\n\n if (goModule.startsWith('github.com/')) {\n const split = goModule.split('/');\n const packageName = `${split[1]}/${split[2]}`;\n return {\n datasource: GithubTagsDatasource.id,\n packageName,\n registryUrl: 'https://github.com',\n };\n }\n\n if (goModule.startsWith('bitbucket.org/')) {\n const split = goModule.split('/');\n const packageName = `${split[1]}/${split[2]}`;\n return {\n datasource: BitbucketTagsDatasource.id,\n packageName,\n registryUrl: 'https://bitbucket.org',\n };\n }\n\n if (goModule.startsWith('code.cloudfoundry.org/')) {\n const packageName = goModule.replace(\n 'code.cloudfoundry.org',\n 'cloudfoundry',\n );\n return {\n datasource: GithubTagsDatasource.id,\n packageName,\n registryUrl: 'https://github.com',\n };\n }\n\n if (goModule.startsWith('dev.azure.com/')) {\n const split = goModule.split('/');\n if ((split.length > 4 && split[3] === '_git') || split.length > 3) {\n const packageName = `https://dev.azure.com/${split[1]}/${split[2]}/_git/${(split[3] === '_git' ? split[4] : split[3]).replace(regEx(/\\.git$/), '')}`;\n return {\n datasource: GitTagsDatasource.id,\n packageName,\n };\n }\n }\n\n //#region known gitea compatible hosts\n if (goModule.startsWith('gitea.com/')) {\n const split = goModule.split('/');\n const packageName = `${split[1]}/${split[2]}`;\n return {\n datasource: GiteaTagsDatasource.id,\n packageName,\n registryUrl: 'https://gitea.com',\n };\n }\n\n if (goModule.startsWith('code.forgejo.org/')) {\n const split = goModule.split('/');\n const packageName = `${split[1]}/${split[2]}`;\n return {\n datasource: ForgejoTagsDatasource.id,\n packageName,\n registryUrl: 'https://code.forgejo.org',\n };\n }\n\n if (goModule.startsWith('codeberg.org/')) {\n const split = goModule.split('/');\n const packageName = `${split[1]}/${split[2]}`;\n return {\n datasource: ForgejoTagsDatasource.id,\n packageName,\n registryUrl: 'https://codeberg.org',\n };\n }\n //#endregion\n\n return await BaseGoDatasource.goGetDatasource(goModule);\n }\n\n /**\n * Returns the module proxy URL that a `go-import` meta tag with the `mod` VCS advertises for the module.\n *\n * @see https://go.dev/ref/mod#serving-from-proxy\n */\n static async getModProxyUrl(goModule: string): Promise<string | null> {\n const html = await BaseGoDatasource.goGet(goModule);\n return BaseGoDatasource.findModProxyUrl(html, goModule);\n }\n\n /**\n * Finds the first `go-import` meta tag with the `mod` VCS whose prefix is a path prefix of the module.\n *\n * The proxy URL is controlled by the host serving the page, so only a valid `https:` URL is accepted, as with `go` (unless `GOINSECURE` is set).\n */\n private static findModProxyUrl(\n html: string,\n goModule: string,\n ): string | null {\n for (const match of html.matchAll(BaseGoDatasource.goImportAllRegexp)) {\n const { prefix, proto, goImportURL } = match.groups as Record<\n string,\n string\n >;\n\n if (\n proto !== 'mod' ||\n !(goModule === prefix || goModule.startsWith(`${prefix}/`))\n ) {\n continue;\n }\n\n if (parseUrl(goImportURL)?.protocol !== 'https:') {\n logger.debug(\n { goModule, goImportURL },\n 'Ignoring go-import mod proxy URL which is not a valid https URL',\n );\n continue;\n }\n\n return goImportURL;\n }\n\n return null;\n }\n\n private static async goGet(goModule: string): Promise<string> {\n const goModuleUrl = goModule.replace(regEx(/\\.git(?:\\/[a-z0-9/]*)?$/), '');\n const pkgUrl = `https://${goModuleUrl}?go-get=1`;\n const { body } = await BaseGoDatasource.http.getText(pkgUrl);\n return body;\n }\n\n private static async goGetDatasource(\n goModule: string,\n ): Promise<DataSource | null> {\n const html = await BaseGoDatasource.goGet(goModule);\n\n // `go` prefers a `mod` proxy over a VCS for the same module, so leave it to the caller to look it up\n if (BaseGoDatasource.findModProxyUrl(html, goModule)) {\n logger.debug(\n { goModule },\n 'Preferring go-import mod proxy over other go-import and go-source entries',\n );\n return null;\n }\n\n const goSourceHeader = BaseGoDatasource.goSourceHeader(html, goModule);\n if (goSourceHeader) {\n return goSourceHeader;\n }\n\n // GitHub Enterprise only returns a go-import meta\n const goImport = BaseGoDatasource.goImportHeader(html, goModule);\n if (goImport) {\n return goImport;\n }\n\n logger.trace({ goModule }, 'No go-source or go-import header found');\n /* istanbul ignore next */\n return null;\n }\n\n private static goSourceHeader(\n html: string,\n goModule: string,\n ): DataSource | null {\n const sourceMatchGroups = regEx(\n /<meta\\s+name=\"?go-source\"?\\s+content=\"(?<prefix>[^\"\\s]+)\\s+(?<goSourceUrl>[^\"\\s]+)/,\n ).exec(html)?.groups;\n if (!sourceMatchGroups) {\n return null;\n }\n const { prefix, goSourceUrl } = sourceMatchGroups;\n\n if (!goModule.startsWith(prefix)) {\n logger.trace({ goModule }, 'go-source header prefix not match');\n return null;\n }\n\n logger.debug(`Go lookup source url ${goSourceUrl} for module ${goModule}`);\n return this.detectDatasource(goSourceUrl, goModule);\n }\n\n private static detectDatasource(\n metadataUrl: string,\n goModule: string,\n ): DataSource | null {\n if (metadataUrl.startsWith('https://github.com/')) {\n return {\n datasource: GithubTagsDatasource.id,\n packageName: metadataUrl\n .replace('https://github.com/', '')\n .replace(regEx(/\\/$/), ''),\n registryUrl: 'https://github.com',\n };\n }\n\n const gitlabModuleName =\n BaseGoDatasource.gitlabRegExp.exec(goModule)?.groups?.regExpPath;\n const vcsIndicatedModule =\n BaseGoDatasource.gitVcsRegexp.exec(goModule)?.groups?.module;\n\n const metadataUrlMatchGroups =\n BaseGoDatasource.gitlabHttpsRegExp.exec(metadataUrl)?.groups;\n if (metadataUrlMatchGroups) {\n const { httpsRegExpUrl, httpsRegExpName } = metadataUrlMatchGroups;\n\n let packageName = vcsIndicatedModule ?? gitlabModuleName;\n\n // Detect submodules in monorepos by comparing metadata path and module path\n if (!vcsIndicatedModule && httpsRegExpName && gitlabModuleName) {\n const metadataPath = httpsRegExpName;\n const modulePath = gitlabModuleName;\n\n if (modulePath.startsWith(`${metadataPath}/`)) {\n packageName = metadataPath;\n }\n }\n\n // If we still don't have a package name, fall back to the metadata URL path\n packageName = packageName ?? httpsRegExpName;\n\n return {\n datasource: GitlabTagsDatasource.id,\n registryUrl: httpsRegExpUrl,\n packageName,\n };\n }\n\n if (hostRules.hostType({ url: metadataUrl }) === 'gitlab') {\n const parsedUrl = parseUrl(metadataUrl);\n if (!parsedUrl) {\n logger.trace({ goModule }, 'Could not parse go-source URL');\n return null;\n }\n\n const endpoint = GlobalConfig.get('endpoint');\n const endpointPrefix = regEx(\n /https:\\/\\/[^/]+\\/(?<prefix>.*?\\/)(?:api\\/v4\\/?)?/,\n ).exec(endpoint)?.groups?.prefix;\n\n let packageName =\n // a .git path indicates a concrete git repository, which can be different from metadata returned by gitlab\n vcsIndicatedModule ?? trimLeadingSlash(parsedUrl.pathname);\n if (endpointPrefix && endpointPrefix !== 'api/') {\n packageName = packageName.replace(endpointPrefix, '');\n }\n\n const registryUrl = endpointPrefix\n ? endpoint.replace(regEx(/\\/api\\/v4\\/?$/), '/')\n : `${parsedUrl.protocol}//${parsedUrl.host}`;\n\n return {\n datasource: GitlabTagsDatasource.id,\n registryUrl,\n packageName,\n };\n }\n return null;\n }\n\n private static goImportHeader(\n html: string,\n goModule: string,\n ): DataSource | null {\n const importMatchGroups =\n BaseGoDatasource.goImportRegexp.exec(html)?.groups;\n if (!importMatchGroups) {\n logger.trace({ goModule }, 'No go-source or go-import header found');\n return null;\n }\n const { prefix, proto, goImportURL } = importMatchGroups;\n\n if (!goModule.startsWith(prefix)) {\n logger.trace({ goModule }, 'go-import header prefix not match');\n return null;\n }\n\n if (proto !== 'git') {\n logger.trace({ goModule }, 'go-import header proto not git');\n return null;\n }\n\n // get server base url from import url\n const parsedUrl = parseUrl(goImportURL);\n if (!parsedUrl) {\n logger.trace({ goModule }, 'Could not parse go-import URL');\n return null;\n }\n\n logger.debug(`Go module: ${goModule} lookup import url ${goImportURL}`);\n\n const datasource = this.detectDatasource(\n goImportURL.replace(regEx(/\\.git$/), ''),\n goModule,\n );\n if (datasource !== null) {\n return datasource;\n }\n // fall back to old behavior if detection did not work\n\n switch (detectPlatform(goImportURL)) {\n case 'github': {\n // split the go module from the URL: host/go/module -> go/module\n // TODO: `parsedUrl.pathname` can be undefined\n const packageName = trimTrailingSlash(`${parsedUrl.pathname}`)\n .replace(regEx(/\\.git$/), '')\n .split('/')\n .slice(-2)\n .join('/');\n\n return {\n datasource: GithubTagsDatasource.id,\n registryUrl: `${parsedUrl.protocol}//${parsedUrl.host}`,\n packageName,\n };\n }\n case 'azure': {\n return {\n datasource: GitTagsDatasource.id,\n packageName: goImportURL.replace(regEx(/\\.git$/), ''),\n };\n }\n default: {\n return {\n datasource: GitTagsDatasource.id,\n packageName: goImportURL,\n };\n }\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"base.js","names":["modulePath","hostRules.hostType"],"sources":["../../../../lib/modules/datasource/go/base.ts"],"sourcesContent":["// TODO: types (#22198)\nimport { GlobalConfig } from '../../../config/global.ts';\nimport { logger } from '../../../logger/index.ts';\nimport { detectPlatform } from '../../../util/common.ts';\nimport * as hostRules from '../../../util/host-rules.ts';\nimport { Http } from '../../../util/http/index.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport {\n parseUrl,\n trimLeadingSlash,\n trimTrailingSlash,\n} from '../../../util/url.ts';\nimport { BitbucketTagsDatasource } from '../bitbucket-tags/index.ts';\nimport { ForgejoTagsDatasource } from '../forgejo-tags/index.ts';\nimport { GitTagsDatasource } from '../git-tags/index.ts';\nimport { GiteaTagsDatasource } from '../gitea-tags/index.ts';\nimport { GithubTagsDatasource } from '../github-tags/index.ts';\nimport { GitlabTagsDatasource } from '../gitlab-tags/index.ts';\nimport type { DataSource } from './types.ts';\n\n// TODO: figure out class hierarchy (#10532)\nexport class BaseGoDatasource {\n private static readonly gitlabHttpsRegExp = regEx(\n /^(?<httpsRegExpUrl>https:\\/\\/[^/]*gitlab\\.[^/]*)\\/(?<httpsRegExpName>.+?)(?:\\/v\\d+)?[/]?$/,\n );\n private static readonly gitlabRegExp = regEx(\n /^(?<regExpUrl>gitlab\\.[^/]*)\\/(?<regExpPath>.+?)(?:\\/v\\d+)?[/]?$/,\n );\n private static readonly gitVcsRegexp = regEx(\n /^(?:[^/]+)\\/(?<module>.*)\\.git(?:$|\\/)/,\n );\n private static readonly goImportRegexp = regEx(\n /<meta\\s+name=\"?go-import\"?\\s+content=\"(?<prefix>[^\"\\s]+)\\s+(?<proto>[^\"\\s]+)\\s+(?<goImportURL>[^\"\\s]+)/,\n );\n private static readonly goImportAllRegexp = regEx(\n BaseGoDatasource.goImportRegexp.source,\n 'g',\n );\n\n private static readonly id = 'go';\n private static readonly http = new Http(BaseGoDatasource.id);\n\n static async getDatasource(goModule: string): Promise<DataSource | null> {\n if (goModule.startsWith('gopkg.in/')) {\n const [pkg] = goModule.replace('gopkg.in/', '').split('.');\n const packageName = pkg.includes('/') ? pkg : `go-${pkg}/${pkg}`;\n return {\n datasource: GithubTagsDatasource.id,\n packageName,\n registryUrl: 'https://github.com',\n };\n }\n\n if (goModule.startsWith('github.com/')) {\n const split = goModule.split('/');\n const packageName = `${split[1]}/${split[2]}`;\n return {\n datasource: GithubTagsDatasource.id,\n packageName,\n registryUrl: 'https://github.com',\n };\n }\n\n if (goModule.startsWith('bitbucket.org/')) {\n const split = goModule.split('/');\n const packageName = `${split[1]}/${split[2]}`;\n return {\n datasource: BitbucketTagsDatasource.id,\n packageName,\n registryUrl: 'https://bitbucket.org',\n };\n }\n\n if (goModule.startsWith('code.cloudfoundry.org/')) {\n const packageName = goModule.replace(\n 'code.cloudfoundry.org',\n 'cloudfoundry',\n );\n return {\n datasource: GithubTagsDatasource.id,\n packageName,\n registryUrl: 'https://github.com',\n };\n }\n\n if (goModule.startsWith('dev.azure.com/')) {\n const split = goModule.split('/');\n if (split.length > 3) {\n const packageName = `https://dev.azure.com/${split[1]}/${split[2]}/_git/${(split[3] === '_git' ? split[4] : split[3]).replace(regEx(/\\.git$/), '')}`;\n return {\n datasource: GitTagsDatasource.id,\n packageName,\n };\n }\n }\n\n //#region known gitea compatible hosts\n if (goModule.startsWith('gitea.com/')) {\n const split = goModule.split('/');\n const packageName = `${split[1]}/${split[2]}`;\n return {\n datasource: GiteaTagsDatasource.id,\n packageName,\n registryUrl: 'https://gitea.com',\n };\n }\n\n if (goModule.startsWith('code.forgejo.org/')) {\n const split = goModule.split('/');\n const packageName = `${split[1]}/${split[2]}`;\n return {\n datasource: ForgejoTagsDatasource.id,\n packageName,\n registryUrl: 'https://code.forgejo.org',\n };\n }\n\n if (goModule.startsWith('codeberg.org/')) {\n const split = goModule.split('/');\n const packageName = `${split[1]}/${split[2]}`;\n return {\n datasource: ForgejoTagsDatasource.id,\n packageName,\n registryUrl: 'https://codeberg.org',\n };\n }\n //#endregion\n\n return await BaseGoDatasource.goGetDatasource(goModule);\n }\n\n /**\n * Returns the module proxy URL that a `go-import` meta tag with the `mod` VCS advertises for the module.\n *\n * @see https://go.dev/ref/mod#serving-from-proxy\n */\n static async getModProxyUrl(goModule: string): Promise<string | null> {\n const html = await BaseGoDatasource.goGet(goModule);\n return BaseGoDatasource.findModProxyUrl(html, goModule);\n }\n\n /**\n * Finds the first `go-import` meta tag with the `mod` VCS whose prefix is a path prefix of the module.\n *\n * The proxy URL is controlled by the host serving the page, so only a valid `https:` URL is accepted, as with `go` (unless `GOINSECURE` is set).\n */\n private static findModProxyUrl(\n html: string,\n goModule: string,\n ): string | null {\n for (const match of html.matchAll(BaseGoDatasource.goImportAllRegexp)) {\n const { prefix, proto, goImportURL } = match.groups as Record<\n string,\n string\n >;\n\n if (\n proto !== 'mod' ||\n !(goModule === prefix || goModule.startsWith(`${prefix}/`))\n ) {\n continue;\n }\n\n if (parseUrl(goImportURL)?.protocol !== 'https:') {\n logger.debug(\n { goModule, goImportURL },\n 'Ignoring go-import mod proxy URL which is not a valid https URL',\n );\n continue;\n }\n\n return goImportURL;\n }\n\n return null;\n }\n\n private static async goGet(goModule: string): Promise<string> {\n const goModuleUrl = goModule.replace(regEx(/\\.git(?:\\/[a-z0-9/]*)?$/), '');\n const pkgUrl = `https://${goModuleUrl}?go-get=1`;\n const { body } = await BaseGoDatasource.http.getText(pkgUrl);\n return body;\n }\n\n private static async goGetDatasource(\n goModule: string,\n ): Promise<DataSource | null> {\n const html = await BaseGoDatasource.goGet(goModule);\n\n // `go` prefers a `mod` proxy over a VCS for the same module, so leave it to the caller to look it up\n if (BaseGoDatasource.findModProxyUrl(html, goModule)) {\n logger.debug(\n { goModule },\n 'Preferring go-import mod proxy over other go-import and go-source entries',\n );\n return null;\n }\n\n const goSourceHeader = BaseGoDatasource.goSourceHeader(html, goModule);\n if (goSourceHeader) {\n return goSourceHeader;\n }\n\n // GitHub Enterprise only returns a go-import meta\n const goImport = BaseGoDatasource.goImportHeader(html, goModule);\n if (goImport) {\n return goImport;\n }\n\n logger.trace({ goModule }, 'No go-source or go-import header found');\n /* istanbul ignore next */\n return null;\n }\n\n private static goSourceHeader(\n html: string,\n goModule: string,\n ): DataSource | null {\n const sourceMatchGroups = regEx(\n /<meta\\s+name=\"?go-source\"?\\s+content=\"(?<prefix>[^\"\\s]+)\\s+(?<goSourceUrl>[^\"\\s]+)/,\n ).exec(html)?.groups;\n if (!sourceMatchGroups) {\n return null;\n }\n const { prefix, goSourceUrl } = sourceMatchGroups;\n\n if (!goModule.startsWith(prefix)) {\n logger.trace({ goModule }, 'go-source header prefix not match');\n return null;\n }\n\n logger.debug(`Go lookup source url ${goSourceUrl} for module ${goModule}`);\n return this.detectDatasource(goSourceUrl, goModule);\n }\n\n private static detectDatasource(\n metadataUrl: string,\n goModule: string,\n ): DataSource | null {\n if (metadataUrl.startsWith('https://github.com/')) {\n return {\n datasource: GithubTagsDatasource.id,\n packageName: metadataUrl\n .replace('https://github.com/', '')\n .replace(regEx(/\\/$/), ''),\n registryUrl: 'https://github.com',\n };\n }\n\n const gitlabModuleName =\n BaseGoDatasource.gitlabRegExp.exec(goModule)?.groups?.regExpPath;\n const vcsIndicatedModule =\n BaseGoDatasource.gitVcsRegexp.exec(goModule)?.groups?.module;\n\n const metadataUrlMatchGroups =\n BaseGoDatasource.gitlabHttpsRegExp.exec(metadataUrl)?.groups;\n if (metadataUrlMatchGroups) {\n const { httpsRegExpUrl, httpsRegExpName } = metadataUrlMatchGroups;\n\n let packageName = vcsIndicatedModule ?? gitlabModuleName;\n\n // Detect submodules in monorepos by comparing metadata path and module path\n if (!vcsIndicatedModule && httpsRegExpName && gitlabModuleName) {\n const metadataPath = httpsRegExpName;\n const modulePath = gitlabModuleName;\n\n if (modulePath.startsWith(`${metadataPath}/`)) {\n packageName = metadataPath;\n }\n }\n\n // If we still don't have a package name, fall back to the metadata URL path\n packageName = packageName ?? httpsRegExpName;\n\n return {\n datasource: GitlabTagsDatasource.id,\n registryUrl: httpsRegExpUrl,\n packageName,\n };\n }\n\n if (hostRules.hostType({ url: metadataUrl }) === 'gitlab') {\n const parsedUrl = parseUrl(metadataUrl);\n if (!parsedUrl) {\n logger.trace({ goModule }, 'Could not parse go-source URL');\n return null;\n }\n\n const endpoint = GlobalConfig.get('endpoint');\n const endpointPrefix = regEx(\n /https:\\/\\/[^/]+\\/(?<prefix>.*?\\/)(?:api\\/v4\\/?)?/,\n ).exec(endpoint)?.groups?.prefix;\n\n let packageName =\n // a .git path indicates a concrete git repository, which can be different from metadata returned by gitlab\n vcsIndicatedModule ?? trimLeadingSlash(parsedUrl.pathname);\n if (endpointPrefix && endpointPrefix !== 'api/') {\n packageName = packageName.replace(endpointPrefix, '');\n }\n\n const registryUrl = endpointPrefix\n ? endpoint.replace(regEx(/\\/api\\/v4\\/?$/), '/')\n : `${parsedUrl.protocol}//${parsedUrl.host}`;\n\n return {\n datasource: GitlabTagsDatasource.id,\n registryUrl,\n packageName,\n };\n }\n return null;\n }\n\n private static goImportHeader(\n html: string,\n goModule: string,\n ): DataSource | null {\n const importMatchGroups =\n BaseGoDatasource.goImportRegexp.exec(html)?.groups;\n if (!importMatchGroups) {\n logger.trace({ goModule }, 'No go-source or go-import header found');\n return null;\n }\n const { prefix, proto, goImportURL } = importMatchGroups;\n\n if (!goModule.startsWith(prefix)) {\n logger.trace({ goModule }, 'go-import header prefix not match');\n return null;\n }\n\n if (proto !== 'git') {\n logger.trace({ goModule }, 'go-import header proto not git');\n return null;\n }\n\n // get server base url from import url\n const parsedUrl = parseUrl(goImportURL);\n if (!parsedUrl) {\n logger.trace({ goModule }, 'Could not parse go-import URL');\n return null;\n }\n\n logger.debug(`Go module: ${goModule} lookup import url ${goImportURL}`);\n\n const datasource = this.detectDatasource(\n goImportURL.replace(regEx(/\\.git$/), ''),\n goModule,\n );\n if (datasource !== null) {\n return datasource;\n }\n // fall back to old behavior if detection did not work\n\n switch (detectPlatform(goImportURL)) {\n case 'github': {\n // split the go module from the URL: host/go/module -> go/module\n // TODO: `parsedUrl.pathname` can be undefined\n const packageName = trimTrailingSlash(`${parsedUrl.pathname}`)\n .replace(regEx(/\\.git$/), '')\n .split('/')\n .slice(-2)\n .join('/');\n\n return {\n datasource: GithubTagsDatasource.id,\n registryUrl: `${parsedUrl.protocol}//${parsedUrl.host}`,\n packageName,\n };\n }\n case 'azure': {\n return {\n datasource: GitTagsDatasource.id,\n packageName: goImportURL.replace(regEx(/\\.git$/), ''),\n };\n }\n default: {\n return {\n datasource: GitTagsDatasource.id,\n packageName: goImportURL,\n };\n }\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -27,9 +27,12 @@ import { isNonEmptyString } from "@sindresorhus/is";
|
|
|
27
27
|
function isPublicProxy({ url }) {
|
|
28
28
|
return trimTrailingSlash(url) === publicGoproxyUrl;
|
|
29
29
|
}
|
|
30
|
+
function matchesRuleHost(rule, url) {
|
|
31
|
+
return !rule.matchHost || matchesHost(url, rule.matchHost);
|
|
32
|
+
}
|
|
30
33
|
function hasGoHostRuleCredentials(packageName) {
|
|
31
34
|
const url = `https://${packageName}`;
|
|
32
|
-
return [...findAll({ hostType: "go" }), ...findAll({ hostType: "go-proxy" })].some((rule) => (
|
|
35
|
+
return [...findAll({ hostType: "go" }), ...findAll({ hostType: "go-proxy" })].some((rule) => matchesRuleHost(rule, url) && [
|
|
33
36
|
rule.token,
|
|
34
37
|
rule.password,
|
|
35
38
|
rule.httpsPrivateKey
|
|
@@ -39,7 +42,10 @@ function isPublicGoPackage(packageName) {
|
|
|
39
42
|
if (parseNoproxy()?.test(packageName)) return false;
|
|
40
43
|
if (hasGoHostRuleCredentials(packageName)) return false;
|
|
41
44
|
const proxies = parseGoproxy();
|
|
42
|
-
return proxies.every((proxy) =>
|
|
45
|
+
return proxies.every((proxy) => {
|
|
46
|
+
if (proxy.url === "off" || isPublicProxy(proxy)) return true;
|
|
47
|
+
return proxy.url === "direct" && proxies.some(isPublicProxy);
|
|
48
|
+
});
|
|
43
49
|
}
|
|
44
50
|
function getSourceUrl(dataSource) {
|
|
45
51
|
if (dataSource) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.js","names":["hostRules.
|
|
1
|
+
{"version":3,"file":"common.js","names":["hostRules.matchesHost","hostRules.findAll","githubSourceUrl","gitlabSourceUrl"],"sources":["../../../../lib/modules/datasource/go/common.ts"],"sourcesContent":["import { isNonEmptyString } from '@sindresorhus/is';\nimport type { HostRule } from '../../../types/index.ts';\nimport { getSourceUrl as githubSourceUrl } from '../../../util/github/url.ts';\nimport { getSourceUrl as gitlabSourceUrl } from '../../../util/gitlab/url.ts';\nimport * as hostRules from '../../../util/host-rules.ts';\nimport { trimTrailingSlash } from '../../../util/url.ts';\nimport { BitbucketTagsDatasource } from '../bitbucket-tags/index.ts';\nimport { ForgejoTagsDatasource } from '../forgejo-tags/index.ts';\nimport { GiteaTagsDatasource } from '../gitea-tags/index.ts';\nimport { GithubTagsDatasource } from '../github-tags/index.ts';\nimport { GitlabTagsDatasource } from '../gitlab-tags/index.ts';\n\nimport { publicGoproxyUrl } from './env.ts';\nimport { parseGoproxy, parseNoproxy } from './goproxy-parser.ts';\nimport type { DataSource, GoproxyItem } from './types.ts';\n\n/**\n * Whether a module's data may be written to a package cache which is shared with others.\n *\n * `GOPRIVATE`/`GONOPROXY` is how the user declares which modules are private, and `GOPROXY` decides who serves the rest: whatever the public proxy serves is public by definition, whereas a self-hosted proxy may serve modules which are not.\n *\n * `direct` only counts as public alongside the public proxy, which is how Go's own default `GOPROXY` is written: there, it is the fallback for what the public proxy doesn't have. On its own it means every module comes from its source, which tells us nothing about who may read it.\n *\n * An unset `GOPROXY` is the default, so it is public too.\n *\n * A `hostType: go` (or `go-proxy`) host rule with credentials for the module's host is also a declaration that the module is private, as it can't be read without them.\n *\n * @see https://go.dev/ref/mod#private-modules\n */\nfunction isPublicProxy({ url }: GoproxyItem): boolean {\n return trimTrailingSlash(url) === publicGoproxyUrl;\n}\n\nfunction matchesRuleHost(rule: HostRule, url: string): boolean {\n return !rule.matchHost || hostRules.matchesHost(url, rule.matchHost);\n}\n\nfunction hasGoHostRuleCredentials(packageName: string): boolean {\n const url = `https://${packageName}`;\n return [\n ...hostRules.findAll({ hostType: 'go' }),\n ...hostRules.findAll({ hostType: 'go-proxy' }),\n ].some(\n (rule) =>\n matchesRuleHost(rule, url) &&\n [rule.token, rule.password, rule.httpsPrivateKey].some(isNonEmptyString),\n );\n}\n\nexport function isPublicGoPackage(packageName: string): boolean {\n if (parseNoproxy()?.test(packageName)) {\n return false;\n }\n\n if (hasGoHostRuleCredentials(packageName)) {\n return false;\n }\n\n const proxies = parseGoproxy();\n\n return proxies.every((proxy) => {\n if (proxy.url === 'off' || isPublicProxy(proxy)) {\n return true;\n }\n return proxy.url === 'direct' && proxies.some(isPublicProxy);\n });\n}\n\nexport function getSourceUrl(\n dataSource?: DataSource | null,\n): string | undefined {\n if (dataSource) {\n const { datasource, registryUrl, packageName } = dataSource;\n\n switch (datasource) {\n case ForgejoTagsDatasource.id:\n return ForgejoTagsDatasource.getSourceUrl(packageName, registryUrl);\n case GiteaTagsDatasource.id:\n return GiteaTagsDatasource.getSourceUrl(packageName, registryUrl);\n case GithubTagsDatasource.id:\n return githubSourceUrl(packageName, registryUrl);\n case GitlabTagsDatasource.id:\n return gitlabSourceUrl(packageName, registryUrl);\n case BitbucketTagsDatasource.id:\n return BitbucketTagsDatasource.getSourceUrl(packageName, registryUrl);\n }\n }\n\n return undefined;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,SAAS,cAAc,EAAE,OAA6B;CACpD,OAAO,kBAAkB,GAAG,MAAM;AACpC;AAEA,SAAS,gBAAgB,MAAgB,KAAsB;CAC7D,OAAO,CAAC,KAAK,aAAaA,YAAsB,KAAK,KAAK,SAAS;AACrE;AAEA,SAAS,yBAAyB,aAA8B;CAC9D,MAAM,MAAM,WAAW;CACvB,OAAO,CACL,GAAGC,QAAkB,EAAE,UAAU,KAAK,CAAC,GACvC,GAAGA,QAAkB,EAAE,UAAU,WAAW,CAAC,CAC/C,CAAC,CAAC,MACC,SACC,gBAAgB,MAAM,GAAG,KACzB;EAAC,KAAK;EAAO,KAAK;EAAU,KAAK;CAAe,CAAC,CAAC,KAAK,gBAAgB,CAC3E;AACF;AAEA,SAAgB,kBAAkB,aAA8B;CAC9D,IAAI,aAAa,CAAC,EAAE,KAAK,WAAW,GAClC,OAAO;CAGT,IAAI,yBAAyB,WAAW,GACtC,OAAO;CAGT,MAAM,UAAU,aAAa;CAE7B,OAAO,QAAQ,OAAO,UAAU;EAC9B,IAAI,MAAM,QAAQ,SAAS,cAAc,KAAK,GAC5C,OAAO;EAET,OAAO,MAAM,QAAQ,YAAY,QAAQ,KAAK,aAAa;CAC7D,CAAC;AACH;AAEA,SAAgB,aACd,YACoB;CACpB,IAAI,YAAY;EACd,MAAM,EAAE,YAAY,aAAa,gBAAgB;EAEjD,QAAQ,YAAR;GACE,KAAK,sBAAsB,IACzB,OAAO,sBAAsB,aAAa,aAAa,WAAW;GACpE,KAAK,oBAAoB,IACvB,OAAO,oBAAoB,aAAa,aAAa,WAAW;GAClE,KAAK,qBAAqB,IACxB,OAAOC,eAAgB,aAAa,WAAW;GACjD,KAAK,qBAAqB,IACxB,OAAOC,eAAgB,aAAa,WAAW;GACjD,KAAK,wBAAwB,IAC3B,OAAO,wBAAwB,aAAa,aAAa,WAAW;EACxE;CACF;AAGF"}
|
|
@@ -20,7 +20,8 @@ function toUrl(matchHost) {
|
|
|
20
20
|
* `go` only sends basic auth from a `GOPROXY` URL, and fails without falling back on a 401/403, so a token-only rule can't be used.
|
|
21
21
|
*/
|
|
22
22
|
function canAuthenticateGo(rule) {
|
|
23
|
-
|
|
23
|
+
const hasBasicAuth = isNonEmptyString(rule.username) && isNonEmptyString(rule.password);
|
|
24
|
+
if (!isNonEmptyString(rule.token) || hasBasicAuth) return true;
|
|
24
25
|
logger.once.warn({ matchHost: rule.matchHost }, "go-proxy host rule with only a token is not added to GOPROXY");
|
|
25
26
|
return false;
|
|
26
27
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"env.js","names":["hostRules\n .findAll"],"sources":["../../../../lib/modules/datasource/go/env.ts"],"sourcesContent":["import { isNonEmptyString } from '@sindresorhus/is';\nimport { GlobalConfig } from '../../../config/global.ts';\nimport { logger } from '../../../logger/index.ts';\nimport type { HostRule } from '../../../types/index.ts';\nimport { getEnv } from '../../../util/env.ts';\nimport * as hostRules from '../../../util/host-rules.ts';\nimport { addSecretForSanitizing } from '../../../util/sanitize.ts';\nimport { parseUrl, trimTrailingSlash } from '../../../util/url.ts';\nimport type { GoEnv } from './types.ts';\n\n/**\n * The Go module proxy which serves public modules only, and which the Go toolchain uses by default.\n *\n * @see https://go.dev/ref/mod#module-proxy\n */\nexport const publicGoproxyUrl = 'https://proxy.golang.org';\n\nfunction toUrl(matchHost: string | undefined): URL | null {\n // a leading dot matches any subdomain, so it can't be turned into one host\n if (!isNonEmptyString(matchHost) || matchHost.startsWith('.')) {\n return null;\n }\n return parseUrl(\n matchHost.includes('://') ? matchHost : `https://${matchHost}`,\n );\n}\n\n/**\n * `go` only sends basic auth from a `GOPROXY` URL, and fails without falling back on a 401/403, so a token-only rule can't be used.\n */\nfunction canAuthenticateGo(rule: HostRule): boolean {\n
|
|
1
|
+
{"version":3,"file":"env.js","names":["hostRules\n .findAll"],"sources":["../../../../lib/modules/datasource/go/env.ts"],"sourcesContent":["import { isNonEmptyString } from '@sindresorhus/is';\nimport { GlobalConfig } from '../../../config/global.ts';\nimport { logger } from '../../../logger/index.ts';\nimport type { HostRule } from '../../../types/index.ts';\nimport { getEnv } from '../../../util/env.ts';\nimport * as hostRules from '../../../util/host-rules.ts';\nimport { addSecretForSanitizing } from '../../../util/sanitize.ts';\nimport { parseUrl, trimTrailingSlash } from '../../../util/url.ts';\nimport type { GoEnv } from './types.ts';\n\n/**\n * The Go module proxy which serves public modules only, and which the Go toolchain uses by default.\n *\n * @see https://go.dev/ref/mod#module-proxy\n */\nexport const publicGoproxyUrl = 'https://proxy.golang.org';\n\nfunction toUrl(matchHost: string | undefined): URL | null {\n // a leading dot matches any subdomain, so it can't be turned into one host\n if (!isNonEmptyString(matchHost) || matchHost.startsWith('.')) {\n return null;\n }\n return parseUrl(\n matchHost.includes('://') ? matchHost : `https://${matchHost}`,\n );\n}\n\n/**\n * `go` only sends basic auth from a `GOPROXY` URL, and fails without falling back on a 401/403, so a token-only rule can't be used.\n */\nfunction canAuthenticateGo(rule: HostRule): boolean {\n const hasBasicAuth =\n isNonEmptyString(rule.username) && isNonEmptyString(rule.password);\n if (!isNonEmptyString(rule.token) || hasBasicAuth) {\n return true;\n }\n logger.once.warn(\n { matchHost: rule.matchHost },\n 'go-proxy host rule with only a token is not added to GOPROXY',\n );\n return false;\n}\n\nfunction toGoproxyUrl(rule: HostRule, withCredentials: boolean): string | null {\n const url = toUrl(rule.matchHost);\n if (!url) {\n return null;\n }\n\n if (\n withCredentials &&\n isNonEmptyString(rule.username) &&\n isNonEmptyString(rule.password)\n ) {\n url.username = encodeURIComponent(rule.username);\n url.password = encodeURIComponent(rule.password);\n // the encoded password differs from the one registered by the host rule\n addSecretForSanitizing(url.password);\n }\n\n return trimTrailingSlash(url.href);\n}\n\n/**\n * Returns the module path pattern of a `hostType: go` rule whose `matchHost` includes a path, e.g. `https://github.com/org` → `github.com/org`.\n */\nfunction toPrivateModulePattern(rule: HostRule): string | null {\n const url = toUrl(rule.matchHost);\n const path = trimTrailingSlash(url?.pathname ?? '');\n if (!url || !path) {\n return null;\n }\n return `${url.hostname}${path}`;\n}\n\nfunction joinNonEmpty(values: (string | null)[]): string | undefined {\n const list = new Set(values.filter(isNonEmptyString));\n return list.size ? [...list].join(',') : undefined;\n}\n\n/**\n * Returns the `GOPROXY`, `GONOPROXY`, `GOPRIVATE` and `GONOSUMDB` values to use.\n *\n * Each value set in the environment is used as-is.\n * With `goEnvFromHostRules` enabled, unset values are derived from host rules:\n * - `GOPROXY`: one URL per `hostType: go-proxy` rule, followed by the public proxy and `direct`\n * - `GONOPROXY`: `hostType: go` rules whose `matchHost` includes a path\n * - `GONOSUMDB`: the `go-proxy` hosts and the derived `GONOPROXY` patterns\n *\n * When `GOPRIVATE` is set, `GONOPROXY` isn't derived, as it would override it, and `GONOSUMDB` is `GOPRIVATE` followed by the `go-proxy` hosts.\n *\n * @param withCredentials embed `go-proxy` rule credentials in the derived `GOPROXY`, for running `go`\n */\nexport function getGoEnv(withCredentials = false): GoEnv {\n const { GOPROXY, GONOPROXY, GOPRIVATE, GONOSUMDB } = getEnv();\n const env: GoEnv = { GOPROXY, GONOPROXY, GOPRIVATE, GONOSUMDB };\n\n if (!GlobalConfig.get('goEnvFromHostRules')) {\n return env;\n }\n\n const proxyRules = hostRules\n .findAll({ hostType: 'go-proxy' })\n .filter(canAuthenticateGo);\n\n if (GOPROXY === undefined) {\n const proxies = joinNonEmpty(\n proxyRules.map((rule) => toGoproxyUrl(rule, withCredentials)),\n );\n if (proxies) {\n env.GOPROXY = `${proxies},${publicGoproxyUrl},direct`;\n }\n }\n\n const proxyHosts = proxyRules.map(\n (rule) => toUrl(rule.matchHost)?.hostname ?? null,\n );\n\n if (GOPRIVATE !== undefined) {\n // `GONOSUMDB` replaces `GOPRIVATE` for the checksum database, so it has to keep the `GOPRIVATE` patterns\n env.GONOSUMDB ??= proxyHosts.some(isNonEmptyString)\n ? joinNonEmpty([GOPRIVATE, ...proxyHosts])\n : undefined;\n return env;\n }\n\n const privatePatterns = hostRules\n .findAll({ hostType: 'go' })\n .map(toPrivateModulePattern);\n\n env.GONOPROXY ??= joinNonEmpty(privatePatterns);\n env.GONOSUMDB ??= joinNonEmpty([...proxyHosts, ...privatePatterns]);\n\n return env;\n}\n"],"mappings":";;;;;;;;;;;;;AAeA,MAAa,mBAAmB;AAEhC,SAAS,MAAM,WAA2C;CAExD,IAAI,CAAC,iBAAiB,SAAS,KAAK,UAAU,WAAW,GAAG,GAC1D,OAAO;CAET,OAAO,SACL,UAAU,SAAS,KAAK,IAAI,YAAY,WAAW,WACrD;AACF;;;;AAKA,SAAS,kBAAkB,MAAyB;CAClD,MAAM,eACJ,iBAAiB,KAAK,QAAQ,KAAK,iBAAiB,KAAK,QAAQ;CACnE,IAAI,CAAC,iBAAiB,KAAK,KAAK,KAAK,cACnC,OAAO;CAET,OAAO,KAAK,KACV,EAAE,WAAW,KAAK,UAAU,GAC5B,8DACF;CACA,OAAO;AACT;AAEA,SAAS,aAAa,MAAgB,iBAAyC;CAC7E,MAAM,MAAM,MAAM,KAAK,SAAS;CAChC,IAAI,CAAC,KACH,OAAO;CAGT,IACE,mBACA,iBAAiB,KAAK,QAAQ,KAC9B,iBAAiB,KAAK,QAAQ,GAC9B;EACA,IAAI,WAAW,mBAAmB,KAAK,QAAQ;EAC/C,IAAI,WAAW,mBAAmB,KAAK,QAAQ;EAE/C,uBAAuB,IAAI,QAAQ;CACrC;CAEA,OAAO,kBAAkB,IAAI,IAAI;AACnC;;;;AAKA,SAAS,uBAAuB,MAA+B;CAC7D,MAAM,MAAM,MAAM,KAAK,SAAS;CAChC,MAAM,OAAO,kBAAkB,KAAK,YAAY,EAAE;CAClD,IAAI,CAAC,OAAO,CAAC,MACX,OAAO;CAET,OAAO,GAAG,IAAI,WAAW;AAC3B;AAEA,SAAS,aAAa,QAA+C;CACnE,MAAM,OAAO,IAAI,IAAI,OAAO,OAAO,gBAAgB,CAAC;CACpD,OAAO,KAAK,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,KAAK,GAAG,IAAI,KAAA;AAC3C;;;;;;;;;;;;;;AAeA,SAAgB,SAAS,kBAAkB,OAAc;CACvD,MAAM,EAAE,SAAS,WAAW,WAAW,cAAc,OAAO;CAC5D,MAAM,MAAa;EAAE;EAAS;EAAW;EAAW;CAAU;CAE9D,IAAI,CAAC,aAAa,IAAI,oBAAoB,GACxC,OAAO;CAGT,MAAM,aAAaA,QACR,EAAE,UAAU,WAAW,CAAC,CAAC,CACjC,OAAO,iBAAiB;CAE3B,IAAI,YAAY,KAAA,GAAW;EACzB,MAAM,UAAU,aACd,WAAW,KAAK,SAAS,aAAa,MAAM,eAAe,CAAC,CAC9D;EACA,IAAI,SACF,IAAI,UAAU,GAAG,QAAQ,GAAG,iBAAiB;CAEjD;CAEA,MAAM,aAAa,WAAW,KAC3B,SAAS,MAAM,KAAK,SAAS,CAAC,EAAE,YAAY,IAC/C;CAEA,IAAI,cAAc,KAAA,GAAW;EAE3B,IAAI,cAAc,WAAW,KAAK,gBAAgB,IAC9C,aAAa,CAAC,WAAW,GAAG,UAAU,CAAC,IACvC,KAAA;EACJ,OAAO;CACT;CAEA,MAAM,kBAAkBA,QACb,EAAE,UAAU,KAAK,CAAC,CAAC,CAC3B,IAAI,sBAAsB;CAE7B,IAAI,cAAc,aAAa,eAAe;CAC9C,IAAI,cAAc,aAAa,CAAC,GAAG,YAAY,GAAG,eAAe,CAAC;CAElE,OAAO;AACT"}
|
|
@@ -2,6 +2,7 @@ import { newlineRegex, regEx } from "../../../util/regex.js";
|
|
|
2
2
|
import { logger } from "../../../logger/index.js";
|
|
3
3
|
import { buildCacheKey } from "../../../util/cache/package/key.js";
|
|
4
4
|
import { joinUrlParts, parseUrl, trimLeadingSlash, trimTrailingSlash } from "../../../util/url.js";
|
|
5
|
+
import { isForbidden, isGone, isNotFound } from "../../../util/http/status.js";
|
|
5
6
|
import { detectPlatform } from "../../../util/common.js";
|
|
6
7
|
import { ExternalHostError } from "../../../types/errors/external-host-error.js";
|
|
7
8
|
import { filterMap } from "../../../util/filter-map.js";
|
|
@@ -95,8 +96,8 @@ var GoProxyDatasource = class GoProxyDatasource extends Datasource {
|
|
|
95
96
|
break;
|
|
96
97
|
}
|
|
97
98
|
} catch (err) {
|
|
98
|
-
const
|
|
99
|
-
if (!(fallback === "|" ? true :
|
|
99
|
+
const potentialHttpError = err instanceof ExternalHostError ? err.err : err;
|
|
100
|
+
if (!(fallback === "|" ? true : isNotFound(potentialHttpError) || isGone(potentialHttpError))) {
|
|
100
101
|
logger.debug({ err }, "Goproxy error: not falling back to other URLs provided with GOPROXY, rethrowing");
|
|
101
102
|
this.handleGenericErrors(err);
|
|
102
103
|
}
|
|
@@ -161,7 +162,8 @@ var GoProxyDatasource = class GoProxyDatasource extends Datasource {
|
|
|
161
162
|
for (const release of releases) {
|
|
162
163
|
const version = release.version.replace(incompatibleSuffixRegex, "");
|
|
163
164
|
const releaseTimestamp = timestamps.get(`${tagPrefix}${version}`);
|
|
164
|
-
if (
|
|
165
|
+
if (!releaseTimestamp) continue;
|
|
166
|
+
if (!release.releaseTimestamp || releaseTimestamp > release.releaseTimestamp) release.releaseTimestamp = releaseTimestamp;
|
|
165
167
|
}
|
|
166
168
|
}
|
|
167
169
|
getReleases(config) {
|
|
@@ -303,8 +305,8 @@ var GoProxyDatasource = class GoProxyDatasource extends Datasource {
|
|
|
303
305
|
result.releases.push(...releases);
|
|
304
306
|
} catch (err) {
|
|
305
307
|
const potentialHttpError = err instanceof ExternalHostError ? err.err : err;
|
|
306
|
-
const
|
|
307
|
-
if (potentialHttpError instanceof RequestError &&
|
|
308
|
+
const isNotFoundOrForbidden = isNotFound(potentialHttpError) || isForbidden(potentialHttpError);
|
|
309
|
+
if (potentialHttpError instanceof RequestError && isNotFoundOrForbidden && major !== packageMajor) break;
|
|
308
310
|
throw err;
|
|
309
311
|
}
|
|
310
312
|
const latest = await this.getLatestVersion(baseUrl, pkg);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"releases-goproxy.js","names":["p.map","HttpError","goVersioning"],"sources":["../../../../lib/modules/datasource/go/releases-goproxy.ts"],"sourcesContent":["import {\n isNonEmptyString,\n isNonEmptyStringAndNotWhitespace,\n isTruthy,\n} from '@sindresorhus/is';\nimport type { ConstraintsFilter } from '../../../config/types.ts';\nimport { logger } from '../../../logger/index.ts';\nimport { ExternalHostError } from '../../../types/errors/external-host-error.ts';\nimport { buildCacheKey } from '../../../util/cache/package/key.ts';\nimport { withCache } from '../../../util/cache/package/with-cache.ts';\nimport { detectPlatform } from '../../../util/common.ts';\nimport { filterMap } from '../../../util/filter-map.ts';\nimport {\n queryReleases,\n queryTags,\n} from '../../../util/github/graphql/index.ts';\nimport { GithubHttp } from '../../../util/http/github.ts';\nimport { HttpError } from '../../../util/http/index.ts';\nimport * as p from '../../../util/promises.ts';\nimport { newlineRegex, regEx } from '../../../util/regex.ts';\nimport type { Timestamp } from '../../../util/timestamp.ts';\nimport { asTimestamp } from '../../../util/timestamp.ts';\nimport {\n joinUrlParts,\n parseUrl,\n trimLeadingSlash,\n trimTrailingSlash,\n} from '../../../util/url.ts';\nimport goVersioning from '../../versioning/go-mod-directive/index.ts';\nimport { parseVersionCommit } from '../../versioning/gomod/index.ts';\nimport { Datasource } from '../datasource.ts';\nimport { GithubReleasesDatasource } from '../github-releases/index.ts';\nimport type { GetReleasesConfig, Release, ReleaseResult } from '../types.ts';\nimport { BaseGoDatasource } from './base.ts';\nimport { getSourceUrl, isPublicGoPackage } from './common.ts';\nimport { getGoEnv, publicGoproxyUrl } from './env.ts';\nimport { parseGoproxy, parseNoproxy } from './goproxy-parser.ts';\nimport { GoDirectDatasource } from './releases-direct.ts';\nimport { VersionInfo } from './schema.ts';\nimport { GoVersionTimestampCache } from './timestamp-cache.ts';\n\n/** TODO #42566 */\nconst goVersionRegex = regEx(/^\\s*go\\s+(?<version>[^\\s]+)\\s*$/);\n\nconst modRegex = regEx(/^(?<baseMod>.*?)(?:[./]v(?<majorVersion>\\d+))?$/);\n\nconst versionTagRegex = regEx(/^v\\d/);\n\n/**\n * Modules with a major version of v2 or above which have no `go.mod` are reported by a Go proxy with a `+incompatible` suffix, which is absent from the tag they were published as.\n *\n * @see https://go.dev/ref/mod#non-module-compat\n */\nconst incompatibleSuffixRegex = regEx(/\\+incompatible$/);\n\nexport function pseudoVersionToRelease(pseudoVersion: string): Release | null {\n const commit = parseVersionCommit(pseudoVersion);\n if (!commit) {\n return null;\n }\n\n return {\n version: pseudoVersion,\n newDigest: commit.revision,\n releaseTimestamp: asTimestamp(commit.timestamp),\n };\n}\n\n/**\n * A Go module which lives in a subdirectory of its repository is tagged with that subdirectory as a prefix, so `github.com/aws/aws-sdk-go-v2/service/s3` publishes `v1.2.3` as the tag `service/s3/v1.2.3`.\n *\n * @see https://go.dev/ref/mod#vcs-version\n *\n * Because we can't tell from the module path alone where the repository ends and the subdirectory begins, we try each candidate prefix - longest first - against the tags we actually found, in the same way as `filterByPrefix` does for direct lookups.\n */\nexport function getTagPrefix(goModule: string, tags: Iterable<string>): string {\n const nameParts = goModule\n .replace(regEx(/\\/v\\d+$/), '')\n .split('/')\n .slice(1);\n const tagNames = [...tags];\n\n while (nameParts.length) {\n const prefix = `${nameParts.join('/')}/`;\n\n const isUsed = tagNames.some(\n (tag) =>\n tag.startsWith(prefix) &&\n versionTagRegex.test(tag.slice(prefix.length)),\n );\n if (isUsed) {\n return prefix;\n }\n\n nameParts.shift();\n }\n\n return '';\n}\n\nexport class GoProxyDatasource extends Datasource {\n static readonly id = 'go-proxy';\n\n constructor() {\n super(GoProxyDatasource.id);\n }\n\n readonly direct = new GoDirectDatasource();\n\n private readonly githubHttp = new GithubHttp(GithubReleasesDatasource.id);\n\n private async _getReleases(\n config: GetReleasesConfig,\n ): Promise<ReleaseResult | null> {\n const { packageName } = config;\n logger.trace(`goproxy.getReleases(${packageName})`);\n const goproxy = getGoEnv().GOPROXY ?? `${publicGoproxyUrl},direct`;\n if (goproxy === 'direct') {\n return this.getDirectReleases(config);\n }\n const proxyList = parseGoproxy(goproxy);\n const noproxy = parseNoproxy();\n\n let result: ReleaseResult | null = null;\n let servedByProxy = false;\n\n if (noproxy?.test(packageName)) {\n logger.debug(`Fetching ${packageName} via GONOPROXY match`);\n result = await this.getDirectReleases(config);\n return result;\n }\n\n for (const { url, fallback } of proxyList) {\n try {\n if (url === 'off') {\n break;\n } else if (url === 'direct') {\n result = await this.getDirectReleases(config);\n break;\n }\n\n const res = await this.getVersionsWithInfo(\n url,\n packageName,\n config.constraintsFiltering,\n );\n if (res.releases.length) {\n result = res;\n servedByProxy = true;\n break;\n }\n } catch (err) {\n const potentialHttpError =\n err instanceof ExternalHostError ? err.err : err;\n const statusCode = potentialHttpError?.response?.statusCode;\n const canFallback =\n fallback === '|' ? true : statusCode === 404 || statusCode === 410;\n if (!canFallback) {\n logger.debug(\n { err },\n 'Goproxy error: not falling back to other URLs provided with GOPROXY, rethrowing',\n );\n this.handleGenericErrors(err);\n }\n logger.debug(\n { err },\n 'Goproxy error: trying next URL provided with GOPROXY',\n );\n }\n }\n\n if (result && !result.sourceUrl) {\n try {\n const datasource = await BaseGoDatasource.getDatasource(packageName);\n const sourceUrl = getSourceUrl(datasource);\n if (sourceUrl) {\n result.sourceUrl = sourceUrl;\n }\n } catch (err) {\n logger.trace({ err }, `Can't get datasource for ${packageName}`);\n }\n }\n\n if (result?.sourceUrl && servedByProxy) {\n await this.addGithubTimestamps(\n packageName,\n result.sourceUrl,\n result.releases,\n );\n }\n\n return result;\n }\n\n /**\n * Looks up a module directly from its source, or from the module proxy its `go-import` meta tag advertises with the `mod` VCS, as with private Buf Schema Registries.\n */\n private async getDirectReleases(\n config: GetReleasesConfig,\n ): Promise<ReleaseResult | null> {\n const { packageName } = config;\n\n const source = await BaseGoDatasource.getDatasource(packageName);\n if (!source) {\n const modProxyUrl = await BaseGoDatasource.getModProxyUrl(packageName);\n if (modProxyUrl) {\n logger.debug(\n `Fetching ${packageName} via go-import mod proxy ${modProxyUrl}`,\n );\n const res = await this.getVersionsWithInfo(\n modProxyUrl,\n packageName,\n config.constraintsFiltering,\n );\n return res.releases.length ? res : null;\n }\n }\n\n return this.direct.getReleases(config);\n }\n\n /**\n * A Go proxy reports the commit time of the tagged commit as a version's `Time`, which can be much earlier than the point at which that version was released.\n *\n * When the module is hosted on GitHub, a GitHub Release's publication time, or - if there's no Release - the git tag's own creation time (distinct from the commit time for an annotated tag), is a better indicator of when the version became available. A Release is preferred over a tag when both exist for the same version.\n */\n async addGithubTimestamps(\n packageName: string,\n sourceUrl: string,\n releases: Release[],\n ): Promise<void> {\n if (detectPlatform(sourceUrl) !== 'github') {\n return;\n }\n\n const parsedUrl = parseUrl(sourceUrl);\n /* v8 ignore next -- detectPlatform only returns a platform for parseable URLs */\n if (!parsedUrl) {\n return;\n }\n\n const repository = trimTrailingSlash(\n trimLeadingSlash(parsedUrl.pathname),\n ).replace(regEx(/\\.git$/), '');\n const githubConfig = {\n packageName: repository,\n registryUrl: parsedUrl.origin,\n };\n\n const [githubTags, githubReleases] = await Promise.all([\n queryTags(githubConfig, this.githubHttp).catch((err) => {\n logger.debug(\n { err, packageName },\n 'Error fetching GitHub Tags for Go module',\n );\n return [];\n }),\n queryReleases(githubConfig, this.githubHttp).catch((err) => {\n logger.debug(\n { err, packageName },\n 'Error fetching GitHub Releases for Go module',\n );\n return [];\n }),\n ]);\n\n const timestamps = new Map<string, Timestamp>();\n for (const { version, releaseTimestamp } of githubTags) {\n timestamps.set(version, releaseTimestamp);\n }\n for (const { version, releaseTimestamp } of githubReleases) {\n timestamps.set(version, releaseTimestamp);\n }\n\n const tagPrefix = getTagPrefix(packageName, timestamps.keys());\n for (const release of releases) {\n const version = release.version.replace(incompatibleSuffixRegex, '');\n const releaseTimestamp = timestamps.get(`${tagPrefix}${version}`);\n if (\n releaseTimestamp &&\n (!release.releaseTimestamp ||\n releaseTimestamp > release.releaseTimestamp)\n ) {\n release.releaseTimestamp = releaseTimestamp;\n }\n }\n }\n\n getReleases(config: GetReleasesConfig): Promise<ReleaseResult | null> {\n return withCache(\n {\n namespace: `datasource-${GoProxyDatasource.id}`,\n key: GoProxyDatasource.getCacheKey(config),\n public: isPublicGoPackage(config.packageName),\n fallback: true,\n },\n () => this._getReleases(config),\n );\n }\n\n /**\n * Avoid ambiguity when serving from case-insensitive file systems.\n *\n * @see https://golang.org/ref/mod#goproxy-protocol\n */\n encodeCase(input: string): string {\n return input.replace(regEx(/(?:[A-Z])/g), (x) => `!${x.toLowerCase()}`);\n }\n\n async listVersions(baseUrl: string, packageName: string): Promise<Release[]> {\n const url = joinUrlParts(\n baseUrl,\n this.encodeCase(packageName),\n '@v',\n 'list',\n );\n const { body } = await this.http.getText(url);\n return filterMap(body.split(newlineRegex), (str) => {\n if (!isNonEmptyStringAndNotWhitespace(str)) {\n return null;\n }\n\n const [version, timestamp] = str.trim().split(regEx(/\\s+/));\n const release: Release = pseudoVersionToRelease(version) ?? { version };\n\n const releaseTimestamp = asTimestamp(timestamp);\n if (releaseTimestamp) {\n release.releaseTimestamp = releaseTimestamp;\n }\n\n return release;\n });\n }\n\n async versionInfo(\n baseUrl: string,\n packageName: string,\n version: string,\n ): Promise<Release> {\n const url = joinUrlParts(\n baseUrl,\n this.encodeCase(packageName),\n '@v',\n `${version}.info`,\n );\n const res = await this.http.getJson(url, VersionInfo);\n\n const result: Release = {\n version: res.body.Version,\n };\n\n const releaseTimestamp = asTimestamp(res.body.Time);\n if (releaseTimestamp) {\n result.releaseTimestamp = releaseTimestamp;\n }\n\n return result;\n }\n\n /**\n * Retrieve the `go` directive for a given Go Module.\n *\n * NOTE that this means the `go` directive, not the `toolchain` directive.\n */\n async retrieveGoDirectiveForModule(\n baseUrl: string,\n packageName: string,\n version: string,\n ): Promise<string | undefined> {\n return withCache(\n {\n namespace: `datasource-${GoProxyDatasource.id}`,\n key: GoProxyDatasource.getVersionedCacheKey(packageName, version),\n // a module's `go.mod` should /never/ change after it's published. If going via the Go Proxy and the Go Checksum Database, a change in this value will result in build failures.\n ttlMinutes: 100 * 24 * 60,\n public: isPublicGoPackage(packageName),\n },\n () => this._retrieveGoDirectiveForModule(baseUrl, packageName, version),\n );\n }\n\n async _retrieveGoDirectiveForModule(\n baseUrl: string,\n packageName: string,\n version: string,\n ): Promise<string | undefined> {\n const url = joinUrlParts(\n baseUrl,\n this.encodeCase(packageName),\n '@v',\n `${version}.mod`,\n );\n const res = await this.http.getText(url);\n\n let goDirective: string | undefined = undefined;\n\n for (const line of res.body.split('\\n')) {\n const goVersionMatches = goVersionRegex.exec(line)?.groups;\n if (goVersionMatches) {\n goDirective = goVersionMatches.version;\n break;\n }\n }\n\n if (!goDirective) {\n return goDirective;\n }\n\n // always return it in full SemVer format, which can then be matched on using `semver` or `semver-coerced`\n const parts = goDirective.split('.');\n if (parts.length === 1) {\n return `${parts[0]}.0.0`;\n }\n if (parts.length === 2) {\n return `${parts[0]}.${parts[1]}.0`;\n }\n return `${parts[0]}.${parts[1]}.${parts[2]}`;\n }\n\n async getLatestVersion(\n baseUrl: string,\n packageName: string,\n ): Promise<{ version: string; sourceUrl?: string } | null> {\n try {\n const url = joinUrlParts(\n baseUrl,\n this.encodeCase(packageName),\n '@latest',\n );\n const res = await this.http.getJson(url, VersionInfo);\n const { Version: version, Origin: origin } = res.body;\n // Extract sourceUrl from GOPROXY Origin when present, avoiding go-get to\n // vanity hosts (https://github.com/renovatebot/renovate/discussions/44898)\n const sourceUrl =\n origin?.VCS === 'git' && isNonEmptyString(origin.URL)\n ? origin.URL.replace(regEx(/\\.git$/), '')\n : undefined;\n return { version, sourceUrl };\n } catch (err) {\n logger.trace({ err }, 'Failed to get latest version');\n return null;\n }\n }\n\n async getVersionsWithInfo(\n baseUrl: string,\n packageName: string,\n constraintsFiltering: ConstraintsFilter | undefined,\n ): Promise<ReleaseResult> {\n const isGopkgin = packageName.startsWith('gopkg.in/');\n const majorSuffixSeparator = isGopkgin ? '.' : '/';\n const modParts = packageName.match(modRegex)?.groups;\n /* v8 ignore start: defensive - modRegex matches any non-empty package name, so baseMod is always set */\n const baseMod = modParts?.baseMod ?? packageName;\n /* v8 ignore stop */\n const packageMajor = parseInt(modParts?.majorVersion ?? '0', 10);\n\n const result: ReleaseResult = { releases: [] };\n for (let major = packageMajor; ; major += 1) {\n let pkg = `${baseMod}${majorSuffixSeparator}v${major}`;\n if (!isGopkgin && major < 2) {\n pkg = baseMod;\n major += 1; // v0 and v1 are the same module\n }\n\n let releases: Release[] = [];\n\n try {\n const res = await this.listVersions(baseUrl, pkg);\n\n // Artifactory returns all versions in any major (past and future),\n // so starting from v2, we filter them in order to avoid the infinite loop\n const filteredReleases = res.filter(({ version }) => {\n if (major < 2) {\n return true;\n }\n\n return (\n version.split(regEx(/[^\\d]+/)).find(isTruthy) === major.toString()\n );\n });\n\n const timestamps = await GoVersionTimestampCache.init(baseUrl, pkg);\n\n releases = await p.map(filteredReleases, async (versionInfo) => {\n const { version, newDigest, releaseTimestamp } = versionInfo;\n\n if (releaseTimestamp) {\n return { version, newDigest, releaseTimestamp };\n }\n\n const cachedTimestamp = timestamps.get(version);\n if (cachedTimestamp) {\n return { version, releaseTimestamp: cachedTimestamp };\n }\n\n try {\n const release = await this.versionInfo(baseUrl, pkg, version);\n if (release.releaseTimestamp) {\n timestamps.set(version, release.releaseTimestamp);\n }\n return release;\n } catch (err) {\n logger.trace({ err }, `Can't obtain data from ${baseUrl}`);\n return { version };\n }\n });\n\n await timestamps.save();\n\n if (constraintsFiltering === 'strict') {\n releases = await p.map(releases, async (rel) => {\n try {\n const goDirective = await this.retrieveGoDirectiveForModule(\n baseUrl,\n pkg,\n rel.version,\n );\n if (goDirective) {\n rel.constraints ??= {};\n rel.constraints['%goMod'] ??= [];\n rel.constraints['%goMod'].push(goDirective);\n }\n } catch (err) {\n logger.trace(\n { err },\n `Can't obtain \\`go\\` directive from ${baseUrl}`,\n );\n }\n\n return rel;\n });\n }\n\n result.releases.push(...releases);\n } catch (err) {\n const potentialHttpError =\n err instanceof ExternalHostError ? err.err : err;\n const status = potentialHttpError.response?.statusCode;\n if (\n potentialHttpError instanceof HttpError &&\n (status === 404 || status === 403) &&\n major !== packageMajor\n ) {\n break;\n }\n\n throw err;\n }\n\n const latest = await this.getLatestVersion(baseUrl, pkg);\n if (latest) {\n const { version: latestVersion, sourceUrl } = latest;\n result.tags ??= {};\n result.tags.latest ??= latestVersion;\n if (goVersioning.isGreaterThan(latestVersion, result.tags.latest)) {\n result.tags.latest = latestVersion;\n }\n if (sourceUrl) {\n result.sourceUrl ??= sourceUrl;\n }\n if (!result.releases.length) {\n const releaseFromLatest = pseudoVersionToRelease(latestVersion);\n // v8 ignore else -- needs an empty version list plus a non-pseudo latest\n if (releaseFromLatest) {\n result.releases.push(releaseFromLatest);\n }\n }\n }\n\n if (!releases.length) {\n break;\n }\n }\n\n return result;\n }\n\n static getCacheKey({\n packageName,\n constraintsFiltering,\n }: GetReleasesConfig): string {\n const goproxy = getGoEnv().GOPROXY;\n const noproxy = parseNoproxy();\n const constraintsFilteringKey =\n constraintsFiltering === 'none' ? '' : constraintsFiltering;\n return buildCacheKey(\n 'getReleases',\n packageName,\n goproxy,\n noproxy?.toString(),\n constraintsFilteringKey,\n );\n }\n\n static getVersionedCacheKey(packageName: string, version: string): string {\n const goproxy = getGoEnv().GOPROXY;\n const noproxy = parseNoproxy();\n return buildCacheKey(\n 'goDirective',\n packageName,\n version,\n goproxy,\n noproxy?.toString(),\n );\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"releases-goproxy.js","names":["p.map","HttpError","goVersioning"],"sources":["../../../../lib/modules/datasource/go/releases-goproxy.ts"],"sourcesContent":["import {\n isNonEmptyString,\n isNonEmptyStringAndNotWhitespace,\n isTruthy,\n} from '@sindresorhus/is';\nimport type { ConstraintsFilter } from '../../../config/types.ts';\nimport { logger } from '../../../logger/index.ts';\nimport { ExternalHostError } from '../../../types/errors/external-host-error.ts';\nimport { buildCacheKey } from '../../../util/cache/package/key.ts';\nimport { withCache } from '../../../util/cache/package/with-cache.ts';\nimport { detectPlatform } from '../../../util/common.ts';\nimport { filterMap } from '../../../util/filter-map.ts';\nimport {\n queryReleases,\n queryTags,\n} from '../../../util/github/graphql/index.ts';\nimport { GithubHttp } from '../../../util/http/github.ts';\nimport { HttpError } from '../../../util/http/index.ts';\nimport { isForbidden, isGone, isNotFound } from '../../../util/http/status.ts';\nimport * as p from '../../../util/promises.ts';\nimport { newlineRegex, regEx } from '../../../util/regex.ts';\nimport type { Timestamp } from '../../../util/timestamp.ts';\nimport { asTimestamp } from '../../../util/timestamp.ts';\nimport {\n joinUrlParts,\n parseUrl,\n trimLeadingSlash,\n trimTrailingSlash,\n} from '../../../util/url.ts';\nimport goVersioning from '../../versioning/go-mod-directive/index.ts';\nimport { parseVersionCommit } from '../../versioning/gomod/index.ts';\nimport { Datasource } from '../datasource.ts';\nimport { GithubReleasesDatasource } from '../github-releases/index.ts';\nimport type { GetReleasesConfig, Release, ReleaseResult } from '../types.ts';\nimport { BaseGoDatasource } from './base.ts';\nimport { getSourceUrl, isPublicGoPackage } from './common.ts';\nimport { getGoEnv, publicGoproxyUrl } from './env.ts';\nimport { parseGoproxy, parseNoproxy } from './goproxy-parser.ts';\nimport { GoDirectDatasource } from './releases-direct.ts';\nimport { VersionInfo } from './schema.ts';\nimport { GoVersionTimestampCache } from './timestamp-cache.ts';\n\n/** TODO #42566 */\nconst goVersionRegex = regEx(/^\\s*go\\s+(?<version>[^\\s]+)\\s*$/);\n\nconst modRegex = regEx(/^(?<baseMod>.*?)(?:[./]v(?<majorVersion>\\d+))?$/);\n\nconst versionTagRegex = regEx(/^v\\d/);\n\n/**\n * Modules with a major version of v2 or above which have no `go.mod` are reported by a Go proxy with a `+incompatible` suffix, which is absent from the tag they were published as.\n *\n * @see https://go.dev/ref/mod#non-module-compat\n */\nconst incompatibleSuffixRegex = regEx(/\\+incompatible$/);\n\nexport function pseudoVersionToRelease(pseudoVersion: string): Release | null {\n const commit = parseVersionCommit(pseudoVersion);\n if (!commit) {\n return null;\n }\n\n return {\n version: pseudoVersion,\n newDigest: commit.revision,\n releaseTimestamp: asTimestamp(commit.timestamp),\n };\n}\n\n/**\n * A Go module which lives in a subdirectory of its repository is tagged with that subdirectory as a prefix, so `github.com/aws/aws-sdk-go-v2/service/s3` publishes `v1.2.3` as the tag `service/s3/v1.2.3`.\n *\n * @see https://go.dev/ref/mod#vcs-version\n *\n * Because we can't tell from the module path alone where the repository ends and the subdirectory begins, we try each candidate prefix - longest first - against the tags we actually found, in the same way as `filterByPrefix` does for direct lookups.\n */\nexport function getTagPrefix(goModule: string, tags: Iterable<string>): string {\n const nameParts = goModule\n .replace(regEx(/\\/v\\d+$/), '')\n .split('/')\n .slice(1);\n const tagNames = [...tags];\n\n while (nameParts.length) {\n const prefix = `${nameParts.join('/')}/`;\n\n const isUsed = tagNames.some(\n (tag) =>\n tag.startsWith(prefix) &&\n versionTagRegex.test(tag.slice(prefix.length)),\n );\n if (isUsed) {\n return prefix;\n }\n\n nameParts.shift();\n }\n\n return '';\n}\n\nexport class GoProxyDatasource extends Datasource {\n static readonly id = 'go-proxy';\n\n constructor() {\n super(GoProxyDatasource.id);\n }\n\n readonly direct = new GoDirectDatasource();\n\n private readonly githubHttp = new GithubHttp(GithubReleasesDatasource.id);\n\n private async _getReleases(\n config: GetReleasesConfig,\n ): Promise<ReleaseResult | null> {\n const { packageName } = config;\n logger.trace(`goproxy.getReleases(${packageName})`);\n const goproxy = getGoEnv().GOPROXY ?? `${publicGoproxyUrl},direct`;\n if (goproxy === 'direct') {\n return this.getDirectReleases(config);\n }\n const proxyList = parseGoproxy(goproxy);\n const noproxy = parseNoproxy();\n\n let result: ReleaseResult | null = null;\n let servedByProxy = false;\n\n if (noproxy?.test(packageName)) {\n logger.debug(`Fetching ${packageName} via GONOPROXY match`);\n result = await this.getDirectReleases(config);\n return result;\n }\n\n for (const { url, fallback } of proxyList) {\n try {\n if (url === 'off') {\n break;\n } else if (url === 'direct') {\n result = await this.getDirectReleases(config);\n break;\n }\n\n const res = await this.getVersionsWithInfo(\n url,\n packageName,\n config.constraintsFiltering,\n );\n if (res.releases.length) {\n result = res;\n servedByProxy = true;\n break;\n }\n } catch (err) {\n const potentialHttpError =\n err instanceof ExternalHostError ? err.err : err;\n const canFallback =\n fallback === '|'\n ? true\n : isNotFound(potentialHttpError) || isGone(potentialHttpError);\n if (!canFallback) {\n logger.debug(\n { err },\n 'Goproxy error: not falling back to other URLs provided with GOPROXY, rethrowing',\n );\n this.handleGenericErrors(err);\n }\n logger.debug(\n { err },\n 'Goproxy error: trying next URL provided with GOPROXY',\n );\n }\n }\n\n if (result && !result.sourceUrl) {\n try {\n const datasource = await BaseGoDatasource.getDatasource(packageName);\n const sourceUrl = getSourceUrl(datasource);\n if (sourceUrl) {\n result.sourceUrl = sourceUrl;\n }\n } catch (err) {\n logger.trace({ err }, `Can't get datasource for ${packageName}`);\n }\n }\n\n if (result?.sourceUrl && servedByProxy) {\n await this.addGithubTimestamps(\n packageName,\n result.sourceUrl,\n result.releases,\n );\n }\n\n return result;\n }\n\n /**\n * Looks up a module directly from its source, or from the module proxy its `go-import` meta tag advertises with the `mod` VCS, as with private Buf Schema Registries.\n */\n private async getDirectReleases(\n config: GetReleasesConfig,\n ): Promise<ReleaseResult | null> {\n const { packageName } = config;\n\n const source = await BaseGoDatasource.getDatasource(packageName);\n if (!source) {\n const modProxyUrl = await BaseGoDatasource.getModProxyUrl(packageName);\n if (modProxyUrl) {\n logger.debug(\n `Fetching ${packageName} via go-import mod proxy ${modProxyUrl}`,\n );\n const res = await this.getVersionsWithInfo(\n modProxyUrl,\n packageName,\n config.constraintsFiltering,\n );\n return res.releases.length ? res : null;\n }\n }\n\n return this.direct.getReleases(config);\n }\n\n /**\n * A Go proxy reports the commit time of the tagged commit as a version's `Time`, which can be much earlier than the point at which that version was released.\n *\n * When the module is hosted on GitHub, a GitHub Release's publication time, or - if there's no Release - the git tag's own creation time (distinct from the commit time for an annotated tag), is a better indicator of when the version became available. A Release is preferred over a tag when both exist for the same version.\n */\n async addGithubTimestamps(\n packageName: string,\n sourceUrl: string,\n releases: Release[],\n ): Promise<void> {\n if (detectPlatform(sourceUrl) !== 'github') {\n return;\n }\n\n const parsedUrl = parseUrl(sourceUrl);\n /* v8 ignore next -- detectPlatform only returns a platform for parseable URLs */\n if (!parsedUrl) {\n return;\n }\n\n const repository = trimTrailingSlash(\n trimLeadingSlash(parsedUrl.pathname),\n ).replace(regEx(/\\.git$/), '');\n const githubConfig = {\n packageName: repository,\n registryUrl: parsedUrl.origin,\n };\n\n const [githubTags, githubReleases] = await Promise.all([\n queryTags(githubConfig, this.githubHttp).catch((err) => {\n logger.debug(\n { err, packageName },\n 'Error fetching GitHub Tags for Go module',\n );\n return [];\n }),\n queryReleases(githubConfig, this.githubHttp).catch((err) => {\n logger.debug(\n { err, packageName },\n 'Error fetching GitHub Releases for Go module',\n );\n return [];\n }),\n ]);\n\n const timestamps = new Map<string, Timestamp>();\n for (const { version, releaseTimestamp } of githubTags) {\n timestamps.set(version, releaseTimestamp);\n }\n for (const { version, releaseTimestamp } of githubReleases) {\n timestamps.set(version, releaseTimestamp);\n }\n\n const tagPrefix = getTagPrefix(packageName, timestamps.keys());\n for (const release of releases) {\n const version = release.version.replace(incompatibleSuffixRegex, '');\n const releaseTimestamp = timestamps.get(`${tagPrefix}${version}`);\n if (!releaseTimestamp) {\n continue;\n }\n\n if (\n !release.releaseTimestamp ||\n releaseTimestamp > release.releaseTimestamp\n ) {\n release.releaseTimestamp = releaseTimestamp;\n }\n }\n }\n\n getReleases(config: GetReleasesConfig): Promise<ReleaseResult | null> {\n return withCache(\n {\n namespace: `datasource-${GoProxyDatasource.id}`,\n key: GoProxyDatasource.getCacheKey(config),\n public: isPublicGoPackage(config.packageName),\n fallback: true,\n },\n () => this._getReleases(config),\n );\n }\n\n /**\n * Avoid ambiguity when serving from case-insensitive file systems.\n *\n * @see https://golang.org/ref/mod#goproxy-protocol\n */\n encodeCase(input: string): string {\n return input.replace(regEx(/(?:[A-Z])/g), (x) => `!${x.toLowerCase()}`);\n }\n\n async listVersions(baseUrl: string, packageName: string): Promise<Release[]> {\n const url = joinUrlParts(\n baseUrl,\n this.encodeCase(packageName),\n '@v',\n 'list',\n );\n const { body } = await this.http.getText(url);\n return filterMap(body.split(newlineRegex), (str) => {\n if (!isNonEmptyStringAndNotWhitespace(str)) {\n return null;\n }\n\n const [version, timestamp] = str.trim().split(regEx(/\\s+/));\n const release: Release = pseudoVersionToRelease(version) ?? { version };\n\n const releaseTimestamp = asTimestamp(timestamp);\n if (releaseTimestamp) {\n release.releaseTimestamp = releaseTimestamp;\n }\n\n return release;\n });\n }\n\n async versionInfo(\n baseUrl: string,\n packageName: string,\n version: string,\n ): Promise<Release> {\n const url = joinUrlParts(\n baseUrl,\n this.encodeCase(packageName),\n '@v',\n `${version}.info`,\n );\n const res = await this.http.getJson(url, VersionInfo);\n\n const result: Release = {\n version: res.body.Version,\n };\n\n const releaseTimestamp = asTimestamp(res.body.Time);\n if (releaseTimestamp) {\n result.releaseTimestamp = releaseTimestamp;\n }\n\n return result;\n }\n\n /**\n * Retrieve the `go` directive for a given Go Module.\n *\n * NOTE that this means the `go` directive, not the `toolchain` directive.\n */\n async retrieveGoDirectiveForModule(\n baseUrl: string,\n packageName: string,\n version: string,\n ): Promise<string | undefined> {\n return withCache(\n {\n namespace: `datasource-${GoProxyDatasource.id}`,\n key: GoProxyDatasource.getVersionedCacheKey(packageName, version),\n // a module's `go.mod` should /never/ change after it's published. If going via the Go Proxy and the Go Checksum Database, a change in this value will result in build failures.\n ttlMinutes: 100 * 24 * 60,\n public: isPublicGoPackage(packageName),\n },\n () => this._retrieveGoDirectiveForModule(baseUrl, packageName, version),\n );\n }\n\n async _retrieveGoDirectiveForModule(\n baseUrl: string,\n packageName: string,\n version: string,\n ): Promise<string | undefined> {\n const url = joinUrlParts(\n baseUrl,\n this.encodeCase(packageName),\n '@v',\n `${version}.mod`,\n );\n const res = await this.http.getText(url);\n\n let goDirective: string | undefined = undefined;\n\n for (const line of res.body.split('\\n')) {\n const goVersionMatches = goVersionRegex.exec(line)?.groups;\n if (goVersionMatches) {\n goDirective = goVersionMatches.version;\n break;\n }\n }\n\n if (!goDirective) {\n return goDirective;\n }\n\n // always return it in full SemVer format, which can then be matched on using `semver` or `semver-coerced`\n const parts = goDirective.split('.');\n if (parts.length === 1) {\n return `${parts[0]}.0.0`;\n }\n if (parts.length === 2) {\n return `${parts[0]}.${parts[1]}.0`;\n }\n return `${parts[0]}.${parts[1]}.${parts[2]}`;\n }\n\n async getLatestVersion(\n baseUrl: string,\n packageName: string,\n ): Promise<{ version: string; sourceUrl?: string } | null> {\n try {\n const url = joinUrlParts(\n baseUrl,\n this.encodeCase(packageName),\n '@latest',\n );\n const res = await this.http.getJson(url, VersionInfo);\n const { Version: version, Origin: origin } = res.body;\n // Extract sourceUrl from GOPROXY Origin when present, avoiding go-get to\n // vanity hosts (https://github.com/renovatebot/renovate/discussions/44898)\n const sourceUrl =\n origin?.VCS === 'git' && isNonEmptyString(origin.URL)\n ? origin.URL.replace(regEx(/\\.git$/), '')\n : undefined;\n return { version, sourceUrl };\n } catch (err) {\n logger.trace({ err }, 'Failed to get latest version');\n return null;\n }\n }\n\n async getVersionsWithInfo(\n baseUrl: string,\n packageName: string,\n constraintsFiltering: ConstraintsFilter | undefined,\n ): Promise<ReleaseResult> {\n const isGopkgin = packageName.startsWith('gopkg.in/');\n const majorSuffixSeparator = isGopkgin ? '.' : '/';\n const modParts = packageName.match(modRegex)?.groups;\n /* v8 ignore start: defensive - modRegex matches any non-empty package name, so baseMod is always set */\n const baseMod = modParts?.baseMod ?? packageName;\n /* v8 ignore stop */\n const packageMajor = parseInt(modParts?.majorVersion ?? '0', 10);\n\n const result: ReleaseResult = { releases: [] };\n for (let major = packageMajor; ; major += 1) {\n let pkg = `${baseMod}${majorSuffixSeparator}v${major}`;\n if (!isGopkgin && major < 2) {\n pkg = baseMod;\n major += 1; // v0 and v1 are the same module\n }\n\n let releases: Release[] = [];\n\n try {\n const res = await this.listVersions(baseUrl, pkg);\n\n // Artifactory returns all versions in any major (past and future),\n // so starting from v2, we filter them in order to avoid the infinite loop\n const filteredReleases = res.filter(({ version }) => {\n if (major < 2) {\n return true;\n }\n\n return (\n version.split(regEx(/[^\\d]+/)).find(isTruthy) === major.toString()\n );\n });\n\n const timestamps = await GoVersionTimestampCache.init(baseUrl, pkg);\n\n releases = await p.map(filteredReleases, async (versionInfo) => {\n const { version, newDigest, releaseTimestamp } = versionInfo;\n\n if (releaseTimestamp) {\n return { version, newDigest, releaseTimestamp };\n }\n\n const cachedTimestamp = timestamps.get(version);\n if (cachedTimestamp) {\n return { version, releaseTimestamp: cachedTimestamp };\n }\n\n try {\n const release = await this.versionInfo(baseUrl, pkg, version);\n if (release.releaseTimestamp) {\n timestamps.set(version, release.releaseTimestamp);\n }\n return release;\n } catch (err) {\n logger.trace({ err }, `Can't obtain data from ${baseUrl}`);\n return { version };\n }\n });\n\n await timestamps.save();\n\n if (constraintsFiltering === 'strict') {\n releases = await p.map(releases, async (rel) => {\n try {\n const goDirective = await this.retrieveGoDirectiveForModule(\n baseUrl,\n pkg,\n rel.version,\n );\n if (goDirective) {\n rel.constraints ??= {};\n rel.constraints['%goMod'] ??= [];\n rel.constraints['%goMod'].push(goDirective);\n }\n } catch (err) {\n logger.trace(\n { err },\n `Can't obtain \\`go\\` directive from ${baseUrl}`,\n );\n }\n\n return rel;\n });\n }\n\n result.releases.push(...releases);\n } catch (err) {\n const potentialHttpError =\n err instanceof ExternalHostError ? err.err : err;\n const isNotFoundOrForbidden =\n isNotFound(potentialHttpError) || isForbidden(potentialHttpError);\n if (\n potentialHttpError instanceof HttpError &&\n isNotFoundOrForbidden &&\n major !== packageMajor\n ) {\n break;\n }\n\n throw err;\n }\n\n const latest = await this.getLatestVersion(baseUrl, pkg);\n if (latest) {\n const { version: latestVersion, sourceUrl } = latest;\n result.tags ??= {};\n result.tags.latest ??= latestVersion;\n if (goVersioning.isGreaterThan(latestVersion, result.tags.latest)) {\n result.tags.latest = latestVersion;\n }\n if (sourceUrl) {\n result.sourceUrl ??= sourceUrl;\n }\n if (!result.releases.length) {\n const releaseFromLatest = pseudoVersionToRelease(latestVersion);\n // v8 ignore else -- needs an empty version list plus a non-pseudo latest\n if (releaseFromLatest) {\n result.releases.push(releaseFromLatest);\n }\n }\n }\n\n if (!releases.length) {\n break;\n }\n }\n\n return result;\n }\n\n static getCacheKey({\n packageName,\n constraintsFiltering,\n }: GetReleasesConfig): string {\n const goproxy = getGoEnv().GOPROXY;\n const noproxy = parseNoproxy();\n const constraintsFilteringKey =\n constraintsFiltering === 'none' ? '' : constraintsFiltering;\n return buildCacheKey(\n 'getReleases',\n packageName,\n goproxy,\n noproxy?.toString(),\n constraintsFilteringKey,\n );\n }\n\n static getVersionedCacheKey(packageName: string, version: string): string {\n const goproxy = getGoEnv().GOPROXY;\n const noproxy = parseNoproxy();\n return buildCacheKey(\n 'goDirective',\n packageName,\n version,\n goproxy,\n noproxy?.toString(),\n );\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { logger } from "../../../logger/index.js";
|
|
2
2
|
import { buildCacheKey } from "../../../util/cache/package/key.js";
|
|
3
3
|
import { ensureTrailingSlash } from "../../../util/url.js";
|
|
4
|
+
import { isForbidden } from "../../../util/http/status.js";
|
|
4
5
|
import { find } from "../../../util/host-rules.js";
|
|
5
6
|
import { parseSingleYaml } from "../../../util/yaml.js";
|
|
6
7
|
import { ExternalHostError } from "../../../types/errors/external-host-error.js";
|
|
@@ -82,7 +83,7 @@ function classifyS3Error(err, indexUrl) {
|
|
|
82
83
|
logger.debug({ indexUrl }, "Helm S3 lookup error: object not found");
|
|
83
84
|
return err;
|
|
84
85
|
}
|
|
85
|
-
if (err.name === "CredentialsProviderError" || err.$metadata?.httpStatusCode
|
|
86
|
+
if (err.name === "CredentialsProviderError" || isForbidden(err.$metadata?.httpStatusCode)) logger.debug({
|
|
86
87
|
indexUrl,
|
|
87
88
|
err
|
|
88
89
|
}, "Helm S3 lookup error: credentials error, check \"AWS_ACCESS_KEY_ID\" and \"AWS_SECRET_ACCESS_KEY\" variables or the matching `hostRules` entry");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["helmVersioning.id","hostRules.find"],"sources":["../../../../lib/modules/datasource/helm/index.ts"],"sourcesContent":["import { Readable } from 'node:stream';\nimport type {\n GetObjectCommandOutput,\n S3ClientConfig,\n} from '@aws-sdk/client-s3';\nimport { GetObjectCommand } from '@aws-sdk/client-s3';\nimport { logger } from '../../../logger/index.ts';\nimport { ExternalHostError } from '../../../types/errors/external-host-error.ts';\nimport { buildCacheKey } from '../../../util/cache/package/key.ts';\nimport { withCache } from '../../../util/cache/package/with-cache.ts';\nimport * as hostRules from '../../../util/host-rules.ts';\nimport type { S3UrlParts } from '../../../util/s3.ts';\nimport { getS3Client, parseS3Url } from '../../../util/s3.ts';\nimport { streamToString } from '../../../util/streams.ts';\nimport { ensureTrailingSlash } from '../../../util/url.ts';\nimport { parseSingleYaml } from '../../../util/yaml.ts';\nimport * as helmVersioning from '../../versioning/helm/index.ts';\nimport { Datasource } from '../datasource.ts';\nimport type { GetReleasesConfig, ReleaseResult } from '../types.ts';\nimport { HelmRepository } from './schema.ts';\n\nexport class HelmDatasource extends Datasource {\n static readonly id = 'helm';\n\n constructor() {\n super(HelmDatasource.id);\n }\n\n override getDefaultRegistryUrls(_packageName: string): string[] {\n return ['https://charts.helm.sh/stable'];\n }\n\n override readonly defaultConfig = {\n commitMessageTopic: 'Helm release {{depName}}',\n };\n\n override readonly defaultVersioning = helmVersioning.id;\n\n override readonly releaseTimestampSupport = true;\n override readonly releaseTimestampNote =\n 'The release timstamp is determined from the `created` field in the results.';\n override readonly sourceUrlSupport = 'package';\n override readonly sourceUrlNote =\n 'The source URL is determined from the `home` field or the `sources` field in the results.';\n\n private async _getRepositoryData(\n helmRepository: string,\n ): Promise<HelmRepository> {\n const baseUrl = ensureTrailingSlash(helmRepository);\n const indexUrl = `${baseUrl}index.yaml`;\n\n const s3Url = parseS3Url(indexUrl);\n if (s3Url) {\n return await getS3RepositoryData(s3Url, indexUrl);\n }\n\n const { val, err } = await this.http\n .getYamlSafe('index.yaml', { baseUrl }, HelmRepository)\n .unwrap();\n\n if (err) {\n this.handleGenericErrors(err);\n }\n\n return val;\n }\n\n getRepositoryData(helmRepository: string): Promise<HelmRepository> {\n return withCache(\n {\n namespace: `datasource-${HelmDatasource.id}`,\n key: buildCacheKey('repository-data', helmRepository),\n },\n () => this._getRepositoryData(helmRepository),\n );\n }\n\n async getReleases({\n packageName,\n registryUrl: helmRepository,\n }: GetReleasesConfig): Promise<ReleaseResult | null> {\n /* v8 ignore next -- should never happen */\n if (!helmRepository) {\n return null;\n }\n\n const repositoryData = await this.getRepositoryData(helmRepository);\n const releases = repositoryData[packageName];\n if (!releases) {\n logger.debug(\n { dependency: packageName },\n `Entry ${packageName} doesn't exist in index.yaml from ${helmRepository}`,\n );\n return null;\n }\n return releases;\n }\n}\n\nasync function getS3RepositoryData(\n s3Url: S3UrlParts,\n indexUrl: string,\n): Promise<HelmRepository> {\n const client = getS3Client(undefined, undefined, getS3Credentials(indexUrl));\n\n let res: GetObjectCommandOutput;\n try {\n res = await client.send(new GetObjectCommand(s3Url));\n } catch (err) {\n throw classifyS3Error(err, indexUrl);\n }\n\n if (res.DeleteMarker) {\n logger.debug(\n { indexUrl },\n 'Helm S3 lookup error: DeleteMarker encountered',\n );\n throw new Error(`No index.yaml found at ${indexUrl}`);\n }\n\n if (!(res.Body instanceof Readable)) {\n logger.debug({ indexUrl }, 'Helm S3 lookup error: unsupported Body type');\n throw new Error(`Unsupported S3 response body for ${indexUrl}`);\n }\n\n return parseSingleYaml(await streamToString(res.Body), {\n customSchema: HelmRepository,\n });\n}\n\n/**\n * Only a missing object means \"this chart repository has no releases\", so that\n * error is rethrown as-is and the lookup resolves to `null`.\n * Everything else becomes an `ExternalHostError` to abort the run, otherwise a\n * transient S3 failure looks like a deleted chart and closes open PRs.\n */\nfunction classifyS3Error(\n // `name` holds the S3 error code, `message` holds server-supplied prose\n err: Error & { $metadata?: { httpStatusCode?: number } },\n indexUrl: string,\n): Error {\n if (err.name === 'NotFound' || err.name === 'NoSuchKey') {\n logger.debug({ indexUrl }, 'Helm S3 lookup error: object not found');\n return err;\n }\n\n if (\n err.name === 'CredentialsProviderError' ||\n err.$metadata?.httpStatusCode
|
|
1
|
+
{"version":3,"file":"index.js","names":["helmVersioning.id","hostRules.find"],"sources":["../../../../lib/modules/datasource/helm/index.ts"],"sourcesContent":["import { Readable } from 'node:stream';\nimport type {\n GetObjectCommandOutput,\n S3ClientConfig,\n} from '@aws-sdk/client-s3';\nimport { GetObjectCommand } from '@aws-sdk/client-s3';\nimport { logger } from '../../../logger/index.ts';\nimport { ExternalHostError } from '../../../types/errors/external-host-error.ts';\nimport { buildCacheKey } from '../../../util/cache/package/key.ts';\nimport { withCache } from '../../../util/cache/package/with-cache.ts';\nimport * as hostRules from '../../../util/host-rules.ts';\nimport { isForbidden } from '../../../util/http/status.ts';\nimport type { S3UrlParts } from '../../../util/s3.ts';\nimport { getS3Client, parseS3Url } from '../../../util/s3.ts';\nimport { streamToString } from '../../../util/streams.ts';\nimport { ensureTrailingSlash } from '../../../util/url.ts';\nimport { parseSingleYaml } from '../../../util/yaml.ts';\nimport * as helmVersioning from '../../versioning/helm/index.ts';\nimport { Datasource } from '../datasource.ts';\nimport type { GetReleasesConfig, ReleaseResult } from '../types.ts';\nimport { HelmRepository } from './schema.ts';\n\nexport class HelmDatasource extends Datasource {\n static readonly id = 'helm';\n\n constructor() {\n super(HelmDatasource.id);\n }\n\n override getDefaultRegistryUrls(_packageName: string): string[] {\n return ['https://charts.helm.sh/stable'];\n }\n\n override readonly defaultConfig = {\n commitMessageTopic: 'Helm release {{depName}}',\n };\n\n override readonly defaultVersioning = helmVersioning.id;\n\n override readonly releaseTimestampSupport = true;\n override readonly releaseTimestampNote =\n 'The release timstamp is determined from the `created` field in the results.';\n override readonly sourceUrlSupport = 'package';\n override readonly sourceUrlNote =\n 'The source URL is determined from the `home` field or the `sources` field in the results.';\n\n private async _getRepositoryData(\n helmRepository: string,\n ): Promise<HelmRepository> {\n const baseUrl = ensureTrailingSlash(helmRepository);\n const indexUrl = `${baseUrl}index.yaml`;\n\n const s3Url = parseS3Url(indexUrl);\n if (s3Url) {\n return await getS3RepositoryData(s3Url, indexUrl);\n }\n\n const { val, err } = await this.http\n .getYamlSafe('index.yaml', { baseUrl }, HelmRepository)\n .unwrap();\n\n if (err) {\n this.handleGenericErrors(err);\n }\n\n return val;\n }\n\n getRepositoryData(helmRepository: string): Promise<HelmRepository> {\n return withCache(\n {\n namespace: `datasource-${HelmDatasource.id}`,\n key: buildCacheKey('repository-data', helmRepository),\n },\n () => this._getRepositoryData(helmRepository),\n );\n }\n\n async getReleases({\n packageName,\n registryUrl: helmRepository,\n }: GetReleasesConfig): Promise<ReleaseResult | null> {\n /* v8 ignore next -- should never happen */\n if (!helmRepository) {\n return null;\n }\n\n const repositoryData = await this.getRepositoryData(helmRepository);\n const releases = repositoryData[packageName];\n if (!releases) {\n logger.debug(\n { dependency: packageName },\n `Entry ${packageName} doesn't exist in index.yaml from ${helmRepository}`,\n );\n return null;\n }\n return releases;\n }\n}\n\nasync function getS3RepositoryData(\n s3Url: S3UrlParts,\n indexUrl: string,\n): Promise<HelmRepository> {\n const client = getS3Client(undefined, undefined, getS3Credentials(indexUrl));\n\n let res: GetObjectCommandOutput;\n try {\n res = await client.send(new GetObjectCommand(s3Url));\n } catch (err) {\n throw classifyS3Error(err, indexUrl);\n }\n\n if (res.DeleteMarker) {\n logger.debug(\n { indexUrl },\n 'Helm S3 lookup error: DeleteMarker encountered',\n );\n throw new Error(`No index.yaml found at ${indexUrl}`);\n }\n\n if (!(res.Body instanceof Readable)) {\n logger.debug({ indexUrl }, 'Helm S3 lookup error: unsupported Body type');\n throw new Error(`Unsupported S3 response body for ${indexUrl}`);\n }\n\n return parseSingleYaml(await streamToString(res.Body), {\n customSchema: HelmRepository,\n });\n}\n\n/**\n * Only a missing object means \"this chart repository has no releases\", so that\n * error is rethrown as-is and the lookup resolves to `null`.\n * Everything else becomes an `ExternalHostError` to abort the run, otherwise a\n * transient S3 failure looks like a deleted chart and closes open PRs.\n */\nfunction classifyS3Error(\n // `name` holds the S3 error code, `message` holds server-supplied prose\n err: Error & { $metadata?: { httpStatusCode?: number } },\n indexUrl: string,\n): Error {\n if (err.name === 'NotFound' || err.name === 'NoSuchKey') {\n logger.debug({ indexUrl }, 'Helm S3 lookup error: object not found');\n return err;\n }\n\n if (\n err.name === 'CredentialsProviderError' ||\n isForbidden(err.$metadata?.httpStatusCode)\n ) {\n logger.debug(\n { indexUrl, err },\n 'Helm S3 lookup error: credentials error, check \"AWS_ACCESS_KEY_ID\" and \"AWS_SECRET_ACCESS_KEY\" variables or the matching `hostRules` entry',\n );\n } else if (err.message === 'Region is missing') {\n // Thrown client-side by the SDK region resolver, so this string is stable\n logger.debug(\n { indexUrl },\n 'Helm S3 lookup error: missing region, check \"AWS_REGION\" variable',\n );\n } else {\n logger.debug({ indexUrl, err }, 'Helm S3 lookup error: unknown error');\n }\n\n return new ExternalHostError(err, HelmDatasource.id);\n}\n\nfunction getS3Credentials(\n indexUrl: string,\n): S3ClientConfig['credentials'] | undefined {\n const { username, password, token } = hostRules.find({\n hostType: HelmDatasource.id,\n url: indexUrl,\n });\n\n // Fall back to the default AWS credential provider chain\n if (!username || !password) {\n return undefined;\n }\n\n return {\n accessKeyId: username,\n secretAccessKey: password,\n sessionToken: token,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAsBA,IAAa,iBAAb,MAAa,uBAAuB,WAAW;CAC7C,OAAgB,KAAK;CAErB,cAAc;EACZ,MAAM,eAAe,EAAE;CACzB;CAEA,uBAAgC,cAAgC;EAC9D,OAAO,CAAC,+BAA+B;CACzC;CAEA,gBAAkC,EAChC,oBAAoB,2BACtB;CAEA,oBAAsCA;CAEtC,0BAA4C;CAC5C,uBACE;CACF,mBAAqC;CACrC,gBACE;CAEF,MAAc,mBACZ,gBACyB;EACzB,MAAM,UAAU,oBAAoB,cAAc;EAClD,MAAM,WAAW,GAAG,QAAQ;EAE5B,MAAM,QAAQ,WAAW,QAAQ;EACjC,IAAI,OACF,OAAO,MAAM,oBAAoB,OAAO,QAAQ;EAGlD,MAAM,EAAE,KAAK,QAAQ,MAAM,KAAK,KAC7B,YAAY,cAAc,EAAE,QAAQ,GAAG,cAAc,CAAC,CACtD,OAAO;EAEV,IAAI,KACF,KAAK,oBAAoB,GAAG;EAG9B,OAAO;CACT;CAEA,kBAAkB,gBAAiD;EACjE,OAAO,UACL;GACE,WAAW,cAAc,eAAe;GACxC,KAAK,cAAc,mBAAmB,cAAc;EACtD,SACM,KAAK,mBAAmB,cAAc,CAC9C;CACF;CAEA,MAAM,YAAY,EAChB,aACA,aAAa,kBACsC;;EAEnD,IAAI,CAAC,gBACH,OAAO;EAIT,MAAM,YAAW,MADY,KAAK,kBAAkB,cAAc,EAAA,CAClC;EAChC,IAAI,CAAC,UAAU;GACb,OAAO,MACL,EAAE,YAAY,YAAY,GAC1B,SAAS,YAAY,oCAAoC,gBAC3D;GACA,OAAO;EACT;EACA,OAAO;CACT;AACF;AAEA,eAAe,oBACb,OACA,UACyB;CACzB,MAAM,SAAS,YAAY,KAAA,GAAW,KAAA,GAAW,iBAAiB,QAAQ,CAAC;CAE3E,IAAI;CACJ,IAAI;EACF,MAAM,MAAM,OAAO,KAAK,IAAI,iBAAiB,KAAK,CAAC;CACrD,SAAS,KAAK;EACZ,MAAM,gBAAgB,KAAK,QAAQ;CACrC;CAEA,IAAI,IAAI,cAAc;EACpB,OAAO,MACL,EAAE,SAAS,GACX,gDACF;EACA,MAAM,IAAI,MAAM,0BAA0B,UAAU;CACtD;CAEA,IAAI,EAAE,IAAI,gBAAgB,WAAW;EACnC,OAAO,MAAM,EAAE,SAAS,GAAG,6CAA6C;EACxE,MAAM,IAAI,MAAM,oCAAoC,UAAU;CAChE;CAEA,OAAO,gBAAgB,MAAM,eAAe,IAAI,IAAI,GAAG,EACrD,cAAc,eAChB,CAAC;AACH;;;;;;;AAQA,SAAS,gBAEP,KACA,UACO;CACP,IAAI,IAAI,SAAS,cAAc,IAAI,SAAS,aAAa;EACvD,OAAO,MAAM,EAAE,SAAS,GAAG,wCAAwC;EACnE,OAAO;CACT;CAEA,IACE,IAAI,SAAS,8BACb,YAAY,IAAI,WAAW,cAAc,GAEzC,OAAO,MACL;EAAE;EAAU;CAAI,GAChB,gJACF;MACK,IAAI,IAAI,YAAY,qBAEzB,OAAO,MACL,EAAE,SAAS,GACX,qEACF;MAEA,OAAO,MAAM;EAAE;EAAU;CAAI,GAAG,qCAAqC;CAGvE,OAAO,IAAI,kBAAkB,KAAK,eAAe,EAAE;AACrD;AAEA,SAAS,iBACP,UAC2C;CAC3C,MAAM,EAAE,UAAU,UAAU,UAAUC,KAAe;EACnD,UAAU,eAAe;EACzB,KAAK;CACP,CAAC;CAGD,IAAI,CAAC,YAAY,CAAC,UAChB;CAGF,OAAO;EACL,aAAa;EACb,iBAAiB;EACjB,cAAc;CAChB;AACF"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { regEx } from "../../../util/regex.js";
|
|
2
2
|
import { logger } from "../../../logger/index.js";
|
|
3
3
|
import { buildCacheKey } from "../../../util/cache/package/key.js";
|
|
4
|
+
import { isNotFound } from "../../../util/http/status.js";
|
|
4
5
|
import { ExternalHostError } from "../../../types/errors/external-host-error.js";
|
|
5
6
|
import { id } from "../../versioning/semver/index.js";
|
|
6
7
|
import { RequestError } from "../../../util/http/got.js";
|
|
@@ -50,7 +51,7 @@ var HexpmBobDatasource = class HexpmBobDatasource extends Datasource {
|
|
|
50
51
|
};
|
|
51
52
|
});
|
|
52
53
|
} catch (err) {
|
|
53
|
-
if (err instanceof RequestError && err
|
|
54
|
+
if (err instanceof RequestError && !isNotFound(err)) throw new ExternalHostError(err);
|
|
54
55
|
this.handleGenericErrors(err);
|
|
55
56
|
}
|
|
56
57
|
return result.releases.length > 0 ? result : null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["semverId","HttpError"],"sources":["../../../../lib/modules/datasource/hexpm-bob/index.ts"],"sourcesContent":["import { isNonEmptyString } from '@sindresorhus/is';\nimport { logger } from '../../../logger/index.ts';\nimport { ExternalHostError } from '../../../types/errors/external-host-error.ts';\nimport { buildCacheKey } from '../../../util/cache/package/key.ts';\nimport { HttpError } from '../../../util/http/index.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { asTimestamp } from '../../../util/timestamp.ts';\nimport { id as semverId } from '../../versioning/semver/index.ts';\nimport { Datasource } from '../datasource.ts';\nimport type { GetReleasesConfig, ReleaseResult } from '../types.ts';\nimport { datasource, defaultRegistryUrl } from './common.ts';\nimport type { PackageType } from './types.ts';\n\nexport class HexpmBobDatasource extends Datasource {\n static readonly id = datasource;\n\n constructor() {\n super(datasource);\n }\n\n override supportsCustomRegistry(_packageName: string): boolean {\n return true;\n }\n\n override getDefaultRegistryUrls(_packageName: string): string[] {\n return [defaultRegistryUrl];\n }\n\n override readonly defaultVersioning = semverId;\n\n override readonly releaseTimestampSupport = true;\n override readonly releaseTimestampNote =\n 'The release timestamp is determined from the `buildDate` field in the results.';\n override readonly sourceUrlSupport = 'package';\n override readonly sourceUrlNote =\n 'We use the URL https://github.com/elixir-lang/elixir.git for the `elixir` package and the https://github.com/erlang/otp.git URL for the `erlang` package.';\n\n private async fetchReleases({\n registryUrl,\n packageName,\n }: GetReleasesConfig): Promise<ReleaseResult | null> {\n const packageType = HexpmBobDatasource.getPackageType(packageName);\n\n if (!packageType) {\n return null;\n }\n\n logger.trace(\n { registryUrl, packageName },\n `fetching hex.pm bob ${packageName} release`,\n );\n\n const url = `${registryUrl!}/builds/${packageName}/builds.txt`;\n\n const result: ReleaseResult = {\n releases: [],\n ...HexpmBobDatasource.getPackageDetails(packageType),\n };\n try {\n const { body } = await this.http.getText(url);\n result.releases = body\n .split('\\n')\n .map((line) => line.trim())\n .filter(isNonEmptyString)\n .map((line) => {\n const [version, gitRef, buildDate] = line.split(' ');\n\n return {\n gitRef,\n isStable: HexpmBobDatasource.isStable(version, packageType),\n releaseTimestamp: asTimestamp(buildDate),\n version: HexpmBobDatasource.cleanVersion(version, packageType),\n };\n });\n } catch (err) {\n if (err instanceof HttpError && err
|
|
1
|
+
{"version":3,"file":"index.js","names":["semverId","HttpError"],"sources":["../../../../lib/modules/datasource/hexpm-bob/index.ts"],"sourcesContent":["import { isNonEmptyString } from '@sindresorhus/is';\nimport { logger } from '../../../logger/index.ts';\nimport { ExternalHostError } from '../../../types/errors/external-host-error.ts';\nimport { buildCacheKey } from '../../../util/cache/package/key.ts';\nimport { HttpError } from '../../../util/http/index.ts';\nimport { isNotFound } from '../../../util/http/status.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { asTimestamp } from '../../../util/timestamp.ts';\nimport { id as semverId } from '../../versioning/semver/index.ts';\nimport { Datasource } from '../datasource.ts';\nimport type { GetReleasesConfig, ReleaseResult } from '../types.ts';\nimport { datasource, defaultRegistryUrl } from './common.ts';\nimport type { PackageType } from './types.ts';\n\nexport class HexpmBobDatasource extends Datasource {\n static readonly id = datasource;\n\n constructor() {\n super(datasource);\n }\n\n override supportsCustomRegistry(_packageName: string): boolean {\n return true;\n }\n\n override getDefaultRegistryUrls(_packageName: string): string[] {\n return [defaultRegistryUrl];\n }\n\n override readonly defaultVersioning = semverId;\n\n override readonly releaseTimestampSupport = true;\n override readonly releaseTimestampNote =\n 'The release timestamp is determined from the `buildDate` field in the results.';\n override readonly sourceUrlSupport = 'package';\n override readonly sourceUrlNote =\n 'We use the URL https://github.com/elixir-lang/elixir.git for the `elixir` package and the https://github.com/erlang/otp.git URL for the `erlang` package.';\n\n private async fetchReleases({\n registryUrl,\n packageName,\n }: GetReleasesConfig): Promise<ReleaseResult | null> {\n const packageType = HexpmBobDatasource.getPackageType(packageName);\n\n if (!packageType) {\n return null;\n }\n\n logger.trace(\n { registryUrl, packageName },\n `fetching hex.pm bob ${packageName} release`,\n );\n\n const url = `${registryUrl!}/builds/${packageName}/builds.txt`;\n\n const result: ReleaseResult = {\n releases: [],\n ...HexpmBobDatasource.getPackageDetails(packageType),\n };\n try {\n const { body } = await this.http.getText(url);\n result.releases = body\n .split('\\n')\n .map((line) => line.trim())\n .filter(isNonEmptyString)\n .map((line) => {\n const [version, gitRef, buildDate] = line.split(' ');\n\n return {\n gitRef,\n isStable: HexpmBobDatasource.isStable(version, packageType),\n releaseTimestamp: asTimestamp(buildDate),\n version: HexpmBobDatasource.cleanVersion(version, packageType),\n };\n });\n } catch (err) {\n if (err instanceof HttpError && !isNotFound(err)) {\n throw new ExternalHostError(err);\n }\n this.handleGenericErrors(err);\n }\n\n return result.releases.length > 0 ? result : null;\n }\n\n getReleases(config: GetReleasesConfig): Promise<ReleaseResult | null> {\n return this.cached(\n {\n key: buildCacheKey(config.registryUrl, config.packageName),\n fallback: true,\n },\n () => this.fetchReleases(config),\n );\n }\n\n private static getPackageType(packageName: string): PackageType | null {\n if (packageName === 'elixir') {\n return 'elixir';\n }\n if (regEx(/^otp\\/\\w+-\\d+\\.\\d+$/).test(packageName)) {\n return 'erlang';\n }\n return null;\n }\n\n private static cleanVersion(\n version: string,\n packageType: PackageType,\n ): string {\n switch (packageType) {\n case 'elixir':\n return version.replace(regEx(/^v/), '');\n case 'erlang':\n return version.replace(regEx(/^OTP-/), '');\n }\n }\n\n private static isStable(version: string, packageType: PackageType): boolean {\n switch (packageType) {\n case 'elixir':\n return regEx(/^v\\d+\\.\\d+\\.\\d+(?:$|-otp)/).test(version);\n case 'erlang':\n return version.startsWith('OTP-');\n }\n }\n\n private static getPackageDetails(\n packageType: PackageType,\n ): Omit<ReleaseResult, 'releases'> {\n switch (packageType) {\n case 'elixir':\n return {\n homepage: 'https://elixir-lang.org/',\n sourceUrl: 'https://github.com/elixir-lang/elixir.git',\n };\n case 'erlang':\n return {\n homepage: 'https://www.erlang.org/',\n sourceUrl: 'https://github.com/erlang/otp.git',\n };\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAcA,IAAa,qBAAb,MAAa,2BAA2B,WAAW;CACjD,OAAgB,KAAK;CAErB,cAAc;EACZ,MAAM,UAAU;CAClB;CAEA,uBAAgC,cAA+B;EAC7D,OAAO;CACT;CAEA,uBAAgC,cAAgC;EAC9D,OAAO,CAAC,kBAAkB;CAC5B;CAEA,oBAAsCA;CAEtC,0BAA4C;CAC5C,uBACE;CACF,mBAAqC;CACrC,gBACE;CAEF,MAAc,cAAc,EAC1B,aACA,eACmD;EACnD,MAAM,cAAc,mBAAmB,eAAe,WAAW;EAEjE,IAAI,CAAC,aACH,OAAO;EAGT,OAAO,MACL;GAAE;GAAa;EAAY,GAC3B,uBAAuB,YAAY,SACrC;EAEA,MAAM,MAAM,GAAG,YAAa,UAAU,YAAY;EAElD,MAAM,SAAwB;GAC5B,UAAU,CAAC;GACX,GAAG,mBAAmB,kBAAkB,WAAW;EACrD;EACA,IAAI;GACF,MAAM,EAAE,SAAS,MAAM,KAAK,KAAK,QAAQ,GAAG;GAC5C,OAAO,WAAW,KACf,MAAM,IAAI,CAAC,CACX,KAAK,SAAS,KAAK,KAAK,CAAC,CAAC,CAC1B,OAAO,gBAAgB,CAAC,CACxB,KAAK,SAAS;IACb,MAAM,CAAC,SAAS,QAAQ,aAAa,KAAK,MAAM,GAAG;IAEnD,OAAO;KACL;KACA,UAAU,mBAAmB,SAAS,SAAS,WAAW;KAC1D,kBAAkB,YAAY,SAAS;KACvC,SAAS,mBAAmB,aAAa,SAAS,WAAW;IAC/D;GACF,CAAC;EACL,SAAS,KAAK;GACZ,IAAI,eAAeC,gBAAa,CAAC,WAAW,GAAG,GAC7C,MAAM,IAAI,kBAAkB,GAAG;GAEjC,KAAK,oBAAoB,GAAG;EAC9B;EAEA,OAAO,OAAO,SAAS,SAAS,IAAI,SAAS;CAC/C;CAEA,YAAY,QAA0D;EACpE,OAAO,KAAK,OACV;GACE,KAAK,cAAc,OAAO,aAAa,OAAO,WAAW;GACzD,UAAU;EACZ,SACM,KAAK,cAAc,MAAM,CACjC;CACF;CAEA,OAAe,eAAe,aAAyC;EACrE,IAAI,gBAAgB,UAClB,OAAO;EAET,IAAI,MAAM,qBAAqB,CAAC,CAAC,KAAK,WAAW,GAC/C,OAAO;EAET,OAAO;CACT;CAEA,OAAe,aACb,SACA,aACQ;EACR,QAAQ,aAAR;GACE,KAAK,UACH,OAAO,QAAQ,QAAQ,MAAM,IAAI,GAAG,EAAE;GACxC,KAAK,UACH,OAAO,QAAQ,QAAQ,MAAM,OAAO,GAAG,EAAE;EAC7C;CACF;CAEA,OAAe,SAAS,SAAiB,aAAmC;EAC1E,QAAQ,aAAR;GACE,KAAK,UACH,OAAO,MAAM,2BAA2B,CAAC,CAAC,KAAK,OAAO;GACxD,KAAK,UACH,OAAO,QAAQ,WAAW,MAAM;EACpC;CACF;CAEA,OAAe,kBACb,aACiC;EACjC,QAAQ,aAAR;GACE,KAAK,UACH,OAAO;IACL,UAAU;IACV,WAAW;GACb;GACF,KAAK,UACH,OAAO;IACL,UAAU;IACV,WAAW;GACb;EACJ;CACF;AACF"}
|
|
@@ -9,6 +9,7 @@ import { buildCacheKey } from "../../util/cache/package/key.js";
|
|
|
9
9
|
import { trimTrailingSlash, withoutUrlCredentials } from "../../util/url.js";
|
|
10
10
|
import { ATTR_RENOVATE_DATASOURCE, ATTR_RENOVATE_PACKAGE_NAME, ATTR_RENOVATE_REGISTRY_URL } from "../../instrumentation/types.js";
|
|
11
11
|
import { DatasourceCacheStats } from "../../util/stats.js";
|
|
12
|
+
import { isForbidden, isNotFound, isUnauthorized } from "../../util/http/status.js";
|
|
12
13
|
import { instrument } from "../../instrumentation/index.js";
|
|
13
14
|
import { detachUrlCredentials } from "../../util/host-rules.js";
|
|
14
15
|
import { ExternalHostError } from "../../types/errors/external-host-error.js";
|
|
@@ -49,13 +50,13 @@ function toGetReleasesConfig(config, registryUrl = config.registryUrl) {
|
|
|
49
50
|
};
|
|
50
51
|
}
|
|
51
52
|
function logError(datasource, packageName, err) {
|
|
52
|
-
const {
|
|
53
|
-
if (
|
|
53
|
+
const { code: errCode, url } = err;
|
|
54
|
+
if (isNotFound(err)) logger.debug({
|
|
54
55
|
datasource,
|
|
55
56
|
packageName,
|
|
56
57
|
url
|
|
57
58
|
}, "Datasource 404");
|
|
58
|
-
else if (
|
|
59
|
+
else if (isUnauthorized(err) || isForbidden(err)) logger.debug({
|
|
59
60
|
datasource,
|
|
60
61
|
packageName,
|
|
61
62
|
url
|