renovate 44.30.0 → 44.30.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/migration.js +3 -3
- package/dist/config/migration.js.map +1 -1
- package/dist/config/migrations/custom/azure-gitlab-automerge-migration.js.map +1 -1
- package/dist/config/migrations/custom/dep-types-migration.js.map +1 -1
- package/dist/config/options/env.js +2 -1
- package/dist/config/options/env.js.map +1 -1
- package/dist/logger/utils.js +3 -3
- package/dist/logger/utils.js.map +1 -1
- package/dist/modules/datasource/crate/index.js +3 -3
- package/dist/modules/datasource/crate/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/goproxy-parser.js +1 -1
- package/dist/modules/datasource/go/goproxy-parser.js.map +1 -1
- package/dist/modules/datasource/hexpm-bob/index.js +3 -3
- package/dist/modules/datasource/hexpm-bob/index.js.map +1 -1
- package/dist/modules/datasource/maven/util.js +1 -1
- package/dist/modules/datasource/maven/util.js.map +1 -1
- package/dist/modules/datasource/packagist/schema.js +2 -1
- package/dist/modules/datasource/packagist/schema.js.map +1 -1
- package/dist/modules/datasource/pypi/common.js +1 -1
- package/dist/modules/datasource/pypi/common.js.map +1 -1
- package/dist/modules/datasource/rpm/repomd.js +2 -1
- package/dist/modules/datasource/rpm/repomd.js.map +1 -1
- package/dist/modules/datasource/sbt-package/util.js +3 -3
- package/dist/modules/datasource/sbt-package/util.js.map +1 -1
- package/dist/modules/datasource/terraform-provider/index.js +1 -1
- package/dist/modules/datasource/terraform-provider/index.js.map +1 -1
- package/dist/modules/manager/ansible-galaxy/util.js +4 -4
- package/dist/modules/manager/ansible-galaxy/util.js.map +1 -1
- package/dist/modules/manager/asdf/upgradeable-tooling.js +5 -5
- package/dist/modules/manager/asdf/upgradeable-tooling.js.map +1 -1
- package/dist/modules/manager/bazel-module/extract.js +2 -1
- package/dist/modules/manager/bazel-module/extract.js.map +1 -1
- package/dist/modules/manager/bazel-module/parser/repo-rules.js +1 -1
- package/dist/modules/manager/bazel-module/parser/repo-rules.js.map +1 -1
- package/dist/modules/manager/bitbucket-pipelines/extract.js +2 -2
- package/dist/modules/manager/bitbucket-pipelines/extract.js.map +1 -1
- package/dist/modules/manager/bun/utils.js +2 -1
- package/dist/modules/manager/bun/utils.js.map +1 -1
- package/dist/modules/manager/bundler/extract.js +1 -1
- package/dist/modules/manager/bundler/extract.js.map +1 -1
- package/dist/modules/manager/cake/index.js.map +1 -1
- package/dist/modules/manager/composer/schema.js +2 -2
- package/dist/modules/manager/composer/schema.js.map +1 -1
- package/dist/modules/manager/cpanfile/language.js.map +1 -1
- package/dist/modules/manager/cpanfile/parser.js +4 -4
- package/dist/modules/manager/cpanfile/parser.js.map +1 -1
- package/dist/modules/manager/crossplane/extract.js +2 -1
- package/dist/modules/manager/crossplane/extract.js.map +1 -1
- package/dist/modules/manager/deps-edn/extract.js +1 -1
- package/dist/modules/manager/deps-edn/extract.js.map +1 -1
- package/dist/modules/manager/deps-edn/parser.js.map +1 -1
- package/dist/modules/manager/dockerfile/extract.js +2 -2
- package/dist/modules/manager/dockerfile/extract.js.map +1 -1
- package/dist/modules/manager/flux/extract.js +2 -2
- package/dist/modules/manager/flux/extract.js.map +1 -1
- package/dist/modules/manager/git-submodules/extract.js +1 -1
- package/dist/modules/manager/git-submodules/extract.js.map +1 -1
- package/dist/modules/manager/gomod/artifacts.js +1 -1
- package/dist/modules/manager/gomod/artifacts.js.map +1 -1
- package/dist/modules/manager/gradle/extract/consistent-versions-plugin.js +2 -2
- package/dist/modules/manager/gradle/extract/consistent-versions-plugin.js.map +1 -1
- package/dist/modules/manager/gradle-wrapper/artifacts.js +2 -2
- package/dist/modules/manager/gradle-wrapper/artifacts.js.map +1 -1
- package/dist/modules/manager/helmv3/utils.js +2 -1
- package/dist/modules/manager/helmv3/utils.js.map +1 -1
- package/dist/modules/manager/hermit/extract.js +1 -1
- package/dist/modules/manager/hermit/extract.js.map +1 -1
- package/dist/modules/manager/homebrew/utils.js +3 -3
- package/dist/modules/manager/homebrew/utils.js.map +1 -1
- package/dist/modules/manager/jsonnet-bundler/extract.js +2 -1
- package/dist/modules/manager/jsonnet-bundler/extract.js.map +1 -1
- package/dist/modules/manager/leiningen/extract.js +2 -2
- package/dist/modules/manager/leiningen/extract.js.map +1 -1
- package/dist/modules/manager/maven-wrapper/artifacts.js +6 -6
- package/dist/modules/manager/maven-wrapper/artifacts.js.map +1 -1
- package/dist/modules/manager/mise/backends.js +3 -3
- package/dist/modules/manager/mise/backends.js.map +1 -1
- package/dist/modules/manager/mise/upgradeable-tooling.js +1 -1
- package/dist/modules/manager/mise/upgradeable-tooling.js.map +1 -1
- package/dist/modules/manager/npm/extract/common/dependency.js +2 -2
- package/dist/modules/manager/npm/extract/common/dependency.js.map +1 -1
- package/dist/modules/manager/npm/extract/post/locked-versions.js +2 -1
- package/dist/modules/manager/npm/extract/post/locked-versions.js.map +1 -1
- package/dist/modules/manager/npm/post-update/index.js +1 -1
- package/dist/modules/manager/npm/post-update/index.js.map +1 -1
- package/dist/modules/manager/npm/post-update/npm.js +2 -1
- package/dist/modules/manager/npm/post-update/npm.js.map +1 -1
- package/dist/modules/manager/npm/post-update/yarn.js +2 -2
- package/dist/modules/manager/npm/post-update/yarn.js.map +1 -1
- package/dist/modules/manager/npm/schema.js +2 -1
- package/dist/modules/manager/npm/schema.js.map +1 -1
- package/dist/modules/manager/npm/update/locked-dependency/yarn-lock/get-locked.js +2 -1
- package/dist/modules/manager/npm/update/locked-dependency/yarn-lock/get-locked.js.map +1 -1
- package/dist/modules/manager/npm/update/locked-dependency/yarn-lock/replace.js +1 -1
- package/dist/modules/manager/npm/update/locked-dependency/yarn-lock/replace.js.map +1 -1
- package/dist/modules/manager/nuget/extract.js +1 -1
- package/dist/modules/manager/nuget/extract.js.map +1 -1
- package/dist/modules/manager/nvm/extract.js +2 -1
- package/dist/modules/manager/nvm/extract.js.map +1 -1
- package/dist/modules/manager/osgi/extract.js +2 -1
- package/dist/modules/manager/osgi/extract.js.map +1 -1
- package/dist/modules/manager/pep621/processors/uv.js +2 -1
- package/dist/modules/manager/pep621/processors/uv.js.map +1 -1
- package/dist/modules/manager/pip_requirements/extract.js +1 -1
- package/dist/modules/manager/pip_requirements/extract.js.map +1 -1
- package/dist/modules/manager/pip_setup/extract.js +3 -3
- package/dist/modules/manager/pip_setup/extract.js.map +1 -1
- package/dist/modules/manager/pixi/schema.js +2 -1
- package/dist/modules/manager/pixi/schema.js.map +1 -1
- package/dist/modules/manager/setup-cfg/extract.js +1 -1
- package/dist/modules/manager/setup-cfg/extract.js.map +1 -1
- package/dist/modules/manager/sveltos/util.js +1 -1
- package/dist/modules/manager/sveltos/util.js.map +1 -1
- package/dist/modules/manager/typst/extract.js +2 -2
- package/dist/modules/manager/typst/extract.js.map +1 -1
- package/dist/modules/platform/azure/issue.js +2 -1
- package/dist/modules/platform/azure/issue.js.map +1 -1
- package/dist/modules/platform/bitbucket/index.js +1 -1
- package/dist/modules/platform/bitbucket/index.js.map +1 -1
- package/dist/modules/platform/bitbucket/schema.js +2 -1
- package/dist/modules/platform/bitbucket/schema.js.map +1 -1
- package/dist/modules/platform/codecommit/codecommit-client.js +2 -1
- package/dist/modules/platform/codecommit/codecommit-client.js.map +1 -1
- package/dist/modules/platform/gerrit/utils.js +1 -1
- package/dist/modules/platform/gerrit/utils.js.map +1 -1
- package/dist/modules/platform/github/index.js +8 -8
- package/dist/modules/platform/github/index.js.map +1 -1
- package/dist/modules/platform/github/massage-markdown-links.js +6 -3
- package/dist/modules/platform/github/massage-markdown-links.js.map +1 -1
- package/dist/modules/versioning/apk/index.js +15 -15
- package/dist/modules/versioning/apk/index.js.map +1 -1
- package/dist/modules/versioning/bazel-module/bzlmod-version.js +3 -2
- package/dist/modules/versioning/bazel-module/bzlmod-version.js.map +1 -1
- package/dist/modules/versioning/bazel-module/index.js +2 -1
- package/dist/modules/versioning/bazel-module/index.js.map +1 -1
- package/dist/modules/versioning/composer/index.js +2 -2
- package/dist/modules/versioning/composer/index.js.map +1 -1
- package/dist/modules/versioning/conan/range.js +4 -3
- package/dist/modules/versioning/conan/range.js.map +1 -1
- package/dist/modules/versioning/conda/index.js +4 -3
- package/dist/modules/versioning/conda/index.js.map +1 -1
- package/dist/modules/versioning/distro.js +2 -1
- package/dist/modules/versioning/distro.js.map +1 -1
- package/dist/modules/versioning/generic.js +2 -1
- package/dist/modules/versioning/generic.js.map +1 -1
- package/dist/modules/versioning/hashicorp/convertor.js +1 -1
- package/dist/modules/versioning/hashicorp/convertor.js.map +1 -1
- package/dist/modules/versioning/npm/range.js +1 -1
- package/dist/modules/versioning/npm/range.js.map +1 -1
- package/dist/modules/versioning/nuget/range.js +2 -1
- package/dist/modules/versioning/nuget/range.js.map +1 -1
- package/dist/modules/versioning/perl/index.js +1 -1
- package/dist/modules/versioning/perl/index.js.map +1 -1
- package/dist/modules/versioning/poetry/transform.js +2 -2
- package/dist/modules/versioning/poetry/transform.js.map +1 -1
- package/dist/modules/versioning/rez/pattern.js.map +1 -1
- package/dist/modules/versioning/ruby/index.js +1 -1
- package/dist/modules/versioning/ruby/index.js.map +1 -1
- package/dist/modules/versioning/semver/index.js +2 -1
- package/dist/modules/versioning/semver/index.js.map +1 -1
- package/dist/modules/versioning/semver-coerced/index.js +1 -1
- package/dist/modules/versioning/semver-coerced/index.js.map +1 -1
- package/dist/util/emoji.js.map +1 -1
- package/dist/util/exec/containerbase.js +2 -1
- package/dist/util/exec/containerbase.js.map +1 -1
- package/dist/util/exec/env.js +2 -1
- package/dist/util/exec/env.js.map +1 -1
- package/dist/util/git/private-key.js +1 -1
- package/dist/util/git/private-key.js.map +1 -1
- package/dist/util/github/graphql/datasource-fetcher.js +2 -1
- package/dist/util/github/graphql/datasource-fetcher.js.map +1 -1
- package/dist/util/http/forgejo.js +2 -1
- package/dist/util/http/forgejo.js.map +1 -1
- package/dist/util/http/gitea.js +2 -1
- package/dist/util/http/gitea.js.map +1 -1
- package/dist/util/number.js +2 -1
- package/dist/util/number.js.map +1 -1
- package/dist/util/string-match.js +1 -1
- package/dist/util/string-match.js.map +1 -1
- package/dist/util/url.js +2 -2
- package/dist/util/url.js.map +1 -1
- package/dist/workers/global/config/parse/cli.js +1 -1
- package/dist/workers/global/config/parse/cli.js.map +1 -1
- package/dist/workers/global/config/parse/coersions.js +2 -1
- package/dist/workers/global/config/parse/coersions.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/model/commit-message.js +2 -1
- package/dist/workers/repository/model/commit-message.js.map +1 -1
- package/dist/workers/repository/model/semantic-commit-message.js +2 -1
- package/dist/workers/repository/model/semantic-commit-message.js.map +1 -1
- package/dist/workers/repository/update/pr/changelog/common.js +1 -1
- package/dist/workers/repository/update/pr/changelog/common.js.map +1 -1
- package/dist/workers/repository/updates/generate.js +1 -1
- package/dist/workers/repository/updates/generate.js.map +1 -1
- package/package.json +1 -1
- package/renovate-schema.json +2 -2
package/dist/config/migration.js
CHANGED
|
@@ -92,9 +92,9 @@ function migrateConfig(config, parentKey) {
|
|
|
92
92
|
}
|
|
93
93
|
if (isNonEmptyObject(migratedConfig["pip-compile"]) && isNonEmptyArray(migratedConfig["pip-compile"].managerFilePatterns)) migratedConfig["pip-compile"].managerFilePatterns = migratedConfig["pip-compile"].managerFilePatterns.map((filePattern) => {
|
|
94
94
|
const pattern = filePattern;
|
|
95
|
-
if (pattern.endsWith(".in")) return pattern.replace(/\.in
|
|
96
|
-
if (pattern.endsWith(".in/")) return pattern.replace(/\.in
|
|
97
|
-
return pattern.replace(/\.in
|
|
95
|
+
if (pattern.endsWith(".in")) return pattern.replace(regEx(/\.in$/), ".txt");
|
|
96
|
+
if (pattern.endsWith(".in/")) return pattern.replace(regEx(/\.in\/$/), ".txt/");
|
|
97
|
+
return pattern.replace(regEx(/\.in\$\/$/), ".txt$/");
|
|
98
98
|
});
|
|
99
99
|
if (isNonEmptyArray(migratedConfig.matchManagers) && migratedConfig.matchManagers.includes("gradle-lite")) {
|
|
100
100
|
// v8 ignore else -- TODO: add test #40625
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration.js","names":[],"sources":["../../lib/config/migration.ts"],"sourcesContent":["import {\n isArray,\n isBoolean,\n isNonEmptyArray,\n isNonEmptyObject,\n isObject,\n isString,\n} from '@sindresorhus/is';\nimport { dequal } from 'dequal';\nimport { logger } from '../logger/index.ts';\nimport { clone } from '../util/clone.ts';\nimport { regEx } from '../util/regex.ts';\nimport { MigrationsService } from './migrations/index.ts';\nimport { getOptions } from './options/index.ts';\nimport type {\n MigratedConfig,\n MigratedRenovateConfig,\n PackageRule,\n RenovateConfig,\n RenovateOptions,\n} from './types.ts';\nimport { mergeChildConfig } from './utils.ts';\n\nconst options = getOptions();\nexport function fixShortHours(input: string): string {\n return input.replace(regEx(/( \\d?\\d)((a|p)m)/g), '$1:00$2');\n}\n\nlet optionTypes: Record<string, RenovateOptions['type']>;\n// Returns a migrated config\nexport function migrateConfig(\n config: RenovateConfig,\n parentKey?: string,\n): MigratedConfig {\n try {\n if (!optionTypes) {\n optionTypes = {};\n options.forEach((option) => {\n optionTypes[option.name] = option.type;\n });\n }\n const newConfig = MigrationsService.run(config, parentKey);\n const migratedConfig = clone(newConfig) as MigratedRenovateConfig;\n\n for (const [key, val] of Object.entries(newConfig)) {\n if (isString(val) && val.includes('{{baseDir}}')) {\n // @ts-expect-error -- TODO: fix me\n migratedConfig[key] = val.replace(\n regEx(/{{baseDir}}/g),\n '{{packageFileDir}}',\n );\n } else if (isString(val) && val.includes('{{lookupName}}')) {\n // @ts-expect-error -- TODO: fix me\n migratedConfig[key] = val.replace(\n regEx(/{{lookupName}}/g),\n '{{packageName}}',\n );\n } else if (isString(val) && val.includes('{{depNameShort}}')) {\n // @ts-expect-error -- TODO: fix me\n migratedConfig[key] = val.replace(\n regEx(/{{depNameShort}}/g),\n '{{depName}}',\n );\n } else if (isString(val) && val.startsWith('{{semanticPrefix}}')) {\n // @ts-expect-error -- TODO: fix me\n migratedConfig[key] = val.replace(\n '{{semanticPrefix}}',\n '{{#if semanticCommitType}}{{semanticCommitType}}{{#if semanticCommitScope}}({{semanticCommitScope}}){{/if}}: {{/if}}',\n );\n } else if (optionTypes[key] === 'object' && isBoolean(val)) {\n // @ts-expect-error -- TODO: fix me\n migratedConfig[key] = { enabled: val };\n } else if (optionTypes[key] === 'boolean') {\n if (val === 'true') {\n // @ts-expect-error -- TODO: fix me\n migratedConfig[key] = true;\n } else if (val === 'false') {\n // @ts-expect-error -- TODO: fix me\n migratedConfig[key] = false;\n }\n } else if (\n optionTypes[key] === 'string' &&\n isArray(val) &&\n val.length === 1\n ) {\n // @ts-expect-error -- TODO: fix me\n migratedConfig[key] = String(val[0]);\n } else if (isArray(val)) {\n // @ts-expect-error -- TODO: fix me\n // v8 ignore else -- TODO: add test #40625\n if (isArray(migratedConfig?.[key])) {\n const newArray = [];\n // @ts-expect-error -- TODO: fix me\n for (const item of migratedConfig[key]) {\n if (isObject(item) && !isArray(item)) {\n const arrMigrate = migrateConfig(item);\n newArray.push(arrMigrate.migratedConfig);\n } else {\n newArray.push(item);\n }\n }\n // @ts-expect-error -- TODO: fix me\n migratedConfig[key] = newArray;\n }\n } else if (isObject(val)) {\n const subMigrate = migrateConfig(\n // @ts-expect-error -- TODO: fix me\n migratedConfig[key] as RenovateConfig,\n key,\n );\n if (subMigrate.isMigrated) {\n // @ts-expect-error -- TODO: fix me\n migratedConfig[key] = subMigrate.migratedConfig;\n }\n }\n\n const migratedTemplates = {\n fromVersion: 'currentVersion',\n newValueMajor: 'newMajor',\n newValueMinor: 'newMinor',\n newVersionMajor: 'newMajor',\n newVersionMinor: 'newMinor',\n toVersion: 'newVersion',\n };\n // @ts-expect-error -- TODO: fix me\n if (isString(migratedConfig[key])) {\n for (const [from, to] of Object.entries(migratedTemplates)) {\n // @ts-expect-error -- TODO: fix me\n migratedConfig[key] = (migratedConfig[key] as string).replace(\n regEx(from, 'g'),\n to,\n );\n }\n }\n }\n const languages = [\n 'docker',\n 'dotnet',\n 'golang',\n 'java',\n 'js',\n 'node',\n 'php',\n 'python',\n 'ruby',\n 'rust',\n ];\n for (const language of languages) {\n // @ts-expect-error -- TODO: fix me\n if (isNonEmptyObject(migratedConfig[language])) {\n migratedConfig.packageRules ??= [];\n // @ts-expect-error -- TODO: fix me\n const currentContent = migratedConfig[language] as any;\n const packageRule = {\n matchCategories: [language],\n ...currentContent,\n };\n migratedConfig.packageRules.unshift(packageRule);\n // @ts-expect-error -- TODO: fix me\n delete migratedConfig[language];\n }\n }\n // Migrate nested packageRules\n if (isNonEmptyArray(migratedConfig.packageRules)) {\n const existingRules = migratedConfig.packageRules;\n migratedConfig.packageRules = [];\n for (const packageRule of existingRules) {\n // @ts-expect-error -- TODO: fix me\n if (isArray(packageRule.packageRules)) {\n logger.debug('Flattening nested packageRules');\n // merge each subrule and add to the parent list\n // @ts-expect-error -- TODO: fix me\n for (const subrule of packageRule.packageRules) {\n // TODO: fix types #22198\n const combinedRule = mergeChildConfig(\n packageRule,\n subrule as PackageRule,\n );\n // @ts-expect-error -- TODO: fix me\n delete combinedRule.packageRules;\n migratedConfig.packageRules.push(combinedRule);\n }\n } else {\n migratedConfig.packageRules.push(packageRule);\n }\n }\n }\n if (\n // @ts-expect-error -- TODO: fix me\n isNonEmptyObject(migratedConfig['pip-compile']) &&\n // @ts-expect-error -- TODO: fix me\n isNonEmptyArray(migratedConfig['pip-compile'].managerFilePatterns)\n ) {\n // @ts-expect-error -- TODO: fix me\n migratedConfig['pip-compile'].managerFilePatterns = migratedConfig[\n 'pip-compile'\n ].managerFilePatterns.map((filePattern) => {\n const pattern = filePattern as string;\n if (pattern.endsWith('.in')) {\n return pattern.replace(/\\.in$/, '.txt');\n }\n if (pattern.endsWith('.in/')) {\n return pattern.replace(/\\.in\\/$/, '.txt/');\n }\n return pattern.replace(/\\.in\\$\\/$/, '.txt$/');\n });\n }\n if (\n // @ts-expect-error -- TODO: fix me\n isNonEmptyArray(migratedConfig.matchManagers) &&\n // @ts-expect-error -- TODO: fix me\n migratedConfig.matchManagers.includes('gradle-lite')\n ) {\n // @ts-expect-error -- TODO: fix me\n // v8 ignore else -- TODO: add test #40625\n if (!migratedConfig.matchManagers.includes('gradle')) {\n // @ts-expect-error -- TODO: fix me\n migratedConfig.matchManagers.push('gradle');\n }\n // @ts-expect-error -- TODO: fix me\n migratedConfig.matchManagers = migratedConfig.matchManagers.filter(\n // @ts-expect-error -- TODO: fix me\n (manager) => manager !== 'gradle-lite',\n );\n }\n // @ts-expect-error -- TODO: fix me\n if (isNonEmptyObject(migratedConfig['gradle-lite'])) {\n migratedConfig.gradle = mergeChildConfig(\n migratedConfig.gradle ?? {},\n // @ts-expect-error -- TODO: fix me\n migratedConfig['gradle-lite'],\n );\n }\n // @ts-expect-error -- TODO: fix me\n delete migratedConfig['gradle-lite'];\n const isMigrated = !dequal(config, migratedConfig);\n if (isMigrated) {\n // recursive call in case any migrated configs need further migrating\n return {\n isMigrated,\n migratedConfig: migrateConfig(migratedConfig).migratedConfig,\n };\n }\n return { isMigrated, migratedConfig };\n } catch (err) {\n logger.debug({ config, err }, 'migrateConfig() error');\n throw err;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"migration.js","names":[],"sources":["../../lib/config/migration.ts"],"sourcesContent":["import {\n isArray,\n isBoolean,\n isNonEmptyArray,\n isNonEmptyObject,\n isObject,\n isString,\n} from '@sindresorhus/is';\nimport { dequal } from 'dequal';\nimport { logger } from '../logger/index.ts';\nimport { clone } from '../util/clone.ts';\nimport { regEx } from '../util/regex.ts';\nimport { MigrationsService } from './migrations/index.ts';\nimport { getOptions } from './options/index.ts';\nimport type {\n MigratedConfig,\n MigratedRenovateConfig,\n PackageRule,\n RenovateConfig,\n RenovateOptions,\n} from './types.ts';\nimport { mergeChildConfig } from './utils.ts';\n\nconst options = getOptions();\nexport function fixShortHours(input: string): string {\n return input.replace(regEx(/( \\d?\\d)((a|p)m)/g), '$1:00$2');\n}\n\nlet optionTypes: Record<string, RenovateOptions['type']>;\n// Returns a migrated config\nexport function migrateConfig(\n config: RenovateConfig,\n parentKey?: string,\n): MigratedConfig {\n try {\n if (!optionTypes) {\n optionTypes = {};\n options.forEach((option) => {\n optionTypes[option.name] = option.type;\n });\n }\n const newConfig = MigrationsService.run(config, parentKey);\n const migratedConfig = clone(newConfig) as MigratedRenovateConfig;\n\n for (const [key, val] of Object.entries(newConfig)) {\n if (isString(val) && val.includes('{{baseDir}}')) {\n // @ts-expect-error -- TODO: fix me\n migratedConfig[key] = val.replace(\n regEx(/{{baseDir}}/g),\n '{{packageFileDir}}',\n );\n } else if (isString(val) && val.includes('{{lookupName}}')) {\n // @ts-expect-error -- TODO: fix me\n migratedConfig[key] = val.replace(\n regEx(/{{lookupName}}/g),\n '{{packageName}}',\n );\n } else if (isString(val) && val.includes('{{depNameShort}}')) {\n // @ts-expect-error -- TODO: fix me\n migratedConfig[key] = val.replace(\n regEx(/{{depNameShort}}/g),\n '{{depName}}',\n );\n } else if (isString(val) && val.startsWith('{{semanticPrefix}}')) {\n // @ts-expect-error -- TODO: fix me\n migratedConfig[key] = val.replace(\n '{{semanticPrefix}}',\n '{{#if semanticCommitType}}{{semanticCommitType}}{{#if semanticCommitScope}}({{semanticCommitScope}}){{/if}}: {{/if}}',\n );\n } else if (optionTypes[key] === 'object' && isBoolean(val)) {\n // @ts-expect-error -- TODO: fix me\n migratedConfig[key] = { enabled: val };\n } else if (optionTypes[key] === 'boolean') {\n if (val === 'true') {\n // @ts-expect-error -- TODO: fix me\n migratedConfig[key] = true;\n } else if (val === 'false') {\n // @ts-expect-error -- TODO: fix me\n migratedConfig[key] = false;\n }\n } else if (\n optionTypes[key] === 'string' &&\n isArray(val) &&\n val.length === 1\n ) {\n // @ts-expect-error -- TODO: fix me\n migratedConfig[key] = String(val[0]);\n } else if (isArray(val)) {\n // @ts-expect-error -- TODO: fix me\n // v8 ignore else -- TODO: add test #40625\n if (isArray(migratedConfig?.[key])) {\n const newArray = [];\n // @ts-expect-error -- TODO: fix me\n for (const item of migratedConfig[key]) {\n if (isObject(item) && !isArray(item)) {\n const arrMigrate = migrateConfig(item);\n newArray.push(arrMigrate.migratedConfig);\n } else {\n newArray.push(item);\n }\n }\n // @ts-expect-error -- TODO: fix me\n migratedConfig[key] = newArray;\n }\n } else if (isObject(val)) {\n const subMigrate = migrateConfig(\n // @ts-expect-error -- TODO: fix me\n migratedConfig[key] as RenovateConfig,\n key,\n );\n if (subMigrate.isMigrated) {\n // @ts-expect-error -- TODO: fix me\n migratedConfig[key] = subMigrate.migratedConfig;\n }\n }\n\n const migratedTemplates = {\n fromVersion: 'currentVersion',\n newValueMajor: 'newMajor',\n newValueMinor: 'newMinor',\n newVersionMajor: 'newMajor',\n newVersionMinor: 'newMinor',\n toVersion: 'newVersion',\n };\n // @ts-expect-error -- TODO: fix me\n if (isString(migratedConfig[key])) {\n for (const [from, to] of Object.entries(migratedTemplates)) {\n // @ts-expect-error -- TODO: fix me\n migratedConfig[key] = (migratedConfig[key] as string).replace(\n regEx(from, 'g'),\n to,\n );\n }\n }\n }\n const languages = [\n 'docker',\n 'dotnet',\n 'golang',\n 'java',\n 'js',\n 'node',\n 'php',\n 'python',\n 'ruby',\n 'rust',\n ];\n for (const language of languages) {\n // @ts-expect-error -- TODO: fix me\n if (isNonEmptyObject(migratedConfig[language])) {\n migratedConfig.packageRules ??= [];\n // @ts-expect-error -- TODO: fix me\n const currentContent = migratedConfig[language] as any;\n const packageRule = {\n matchCategories: [language],\n ...currentContent,\n };\n migratedConfig.packageRules.unshift(packageRule);\n // @ts-expect-error -- TODO: fix me\n delete migratedConfig[language];\n }\n }\n // Migrate nested packageRules\n if (isNonEmptyArray(migratedConfig.packageRules)) {\n const existingRules = migratedConfig.packageRules;\n migratedConfig.packageRules = [];\n for (const packageRule of existingRules) {\n // @ts-expect-error -- TODO: fix me\n if (isArray(packageRule.packageRules)) {\n logger.debug('Flattening nested packageRules');\n // merge each subrule and add to the parent list\n // @ts-expect-error -- TODO: fix me\n for (const subrule of packageRule.packageRules) {\n // TODO: fix types #22198\n const combinedRule = mergeChildConfig(\n packageRule,\n subrule as PackageRule,\n );\n // @ts-expect-error -- TODO: fix me\n delete combinedRule.packageRules;\n migratedConfig.packageRules.push(combinedRule);\n }\n } else {\n migratedConfig.packageRules.push(packageRule);\n }\n }\n }\n if (\n // @ts-expect-error -- TODO: fix me\n isNonEmptyObject(migratedConfig['pip-compile']) &&\n // @ts-expect-error -- TODO: fix me\n isNonEmptyArray(migratedConfig['pip-compile'].managerFilePatterns)\n ) {\n // @ts-expect-error -- TODO: fix me\n migratedConfig['pip-compile'].managerFilePatterns = migratedConfig[\n 'pip-compile'\n ].managerFilePatterns.map((filePattern) => {\n const pattern = filePattern as string;\n if (pattern.endsWith('.in')) {\n return pattern.replace(regEx(/\\.in$/), '.txt');\n }\n if (pattern.endsWith('.in/')) {\n return pattern.replace(regEx(/\\.in\\/$/), '.txt/');\n }\n return pattern.replace(regEx(/\\.in\\$\\/$/), '.txt$/');\n });\n }\n if (\n // @ts-expect-error -- TODO: fix me\n isNonEmptyArray(migratedConfig.matchManagers) &&\n // @ts-expect-error -- TODO: fix me\n migratedConfig.matchManagers.includes('gradle-lite')\n ) {\n // @ts-expect-error -- TODO: fix me\n // v8 ignore else -- TODO: add test #40625\n if (!migratedConfig.matchManagers.includes('gradle')) {\n // @ts-expect-error -- TODO: fix me\n migratedConfig.matchManagers.push('gradle');\n }\n // @ts-expect-error -- TODO: fix me\n migratedConfig.matchManagers = migratedConfig.matchManagers.filter(\n // @ts-expect-error -- TODO: fix me\n (manager) => manager !== 'gradle-lite',\n );\n }\n // @ts-expect-error -- TODO: fix me\n if (isNonEmptyObject(migratedConfig['gradle-lite'])) {\n migratedConfig.gradle = mergeChildConfig(\n migratedConfig.gradle ?? {},\n // @ts-expect-error -- TODO: fix me\n migratedConfig['gradle-lite'],\n );\n }\n // @ts-expect-error -- TODO: fix me\n delete migratedConfig['gradle-lite'];\n const isMigrated = !dequal(config, migratedConfig);\n if (isMigrated) {\n // recursive call in case any migrated configs need further migrating\n return {\n isMigrated,\n migratedConfig: migrateConfig(migratedConfig).migratedConfig,\n };\n }\n return { isMigrated, migratedConfig };\n } catch (err) {\n logger.debug({ config, err }, 'migrateConfig() error');\n throw err;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"azure-gitlab-automerge-migration.js","names":[],"sources":["../../../../lib/config/migrations/custom/azure-gitlab-automerge-migration.ts"],"sourcesContent":["import { AbstractMigration } from '../base/abstract-migration.ts';\n\nexport class AzureGitLabAutomergeMigration extends AbstractMigration {\n override readonly deprecated = true;\n override readonly propertyName = /^azureAutoComplete$|^gitLabAutomerge$/;\n\n override run(value: boolean | undefined): void {\n if (value !== undefined) {\n this.setHard('platformAutomerge', value);\n }\n }\n}\n"],"mappings":";;AAEA,IAAa,gCAAb,cAAmD,kBAAkB;CACnE,aAA+B;
|
|
1
|
+
{"version":3,"file":"azure-gitlab-automerge-migration.js","names":[],"sources":["../../../../lib/config/migrations/custom/azure-gitlab-automerge-migration.ts"],"sourcesContent":["import { AbstractMigration } from '../base/abstract-migration.ts';\n\nexport class AzureGitLabAutomergeMigration extends AbstractMigration {\n override readonly deprecated = true;\n // oxlint-disable-next-line renovate/require-regex-util -- must stay a native RegExp: MigrationsService matches propertyName via isRegExp(), which RE2 instances fail\n override readonly propertyName = /^azureAutoComplete$|^gitLabAutomerge$/;\n\n override run(value: boolean | undefined): void {\n if (value !== undefined) {\n this.setHard('platformAutomerge', value);\n }\n }\n}\n"],"mappings":";;AAEA,IAAa,gCAAb,cAAmD,kBAAkB;CACnE,aAA+B;CAE/B,eAAiC;CAEjC,IAAa,OAAkC;EAC7C,IAAI,UAAU,KAAA,GACZ,KAAK,QAAQ,qBAAqB,KAAK;CAE3C;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dep-types-migration.js","names":[],"sources":["../../../../lib/config/migrations/custom/dep-types-migration.ts"],"sourcesContent":["import { isArray, isNonEmptyObject, isObject } from '@sindresorhus/is';\nimport type { PackageRule } from '../../types.ts';\nimport { AbstractMigration } from '../base/abstract-migration.ts';\n\ninterface DepTypesRule extends PackageRule {\n depType?: string;\n}\n\nexport class DepTypesMigration extends AbstractMigration {\n override readonly deprecated = true;\n override readonly propertyName =\n /^(?:(?:d|devD|optionalD|peerD)ependencies|engines|depTypes)$/;\n\n override run(value: unknown, key: string): void {\n const packageRules: PackageRule[] = this.get('packageRules') ?? [];\n if (isNonEmptyObject(value) && !isArray(value)) {\n packageRules.push({\n matchDepTypes: [key],\n ...value,\n });\n }\n\n if (isArray(value)) {\n for (const depType of value as DepTypesRule[]) {\n if (isObject(depType) && !isArray(depType)) {\n const depTypeName = depType.depType;\n if (depTypeName) {\n delete depType.depType;\n depType.matchDepTypes = [depTypeName];\n packageRules.push({ ...(depType as PackageRule) });\n }\n }\n }\n }\n\n if (packageRules.length) {\n this.setHard('packageRules', packageRules);\n }\n }\n}\n"],"mappings":";;;AAQA,IAAa,oBAAb,cAAuC,kBAAkB;CACvD,aAA+B;CAC/B,
|
|
1
|
+
{"version":3,"file":"dep-types-migration.js","names":[],"sources":["../../../../lib/config/migrations/custom/dep-types-migration.ts"],"sourcesContent":["import { isArray, isNonEmptyObject, isObject } from '@sindresorhus/is';\nimport type { PackageRule } from '../../types.ts';\nimport { AbstractMigration } from '../base/abstract-migration.ts';\n\ninterface DepTypesRule extends PackageRule {\n depType?: string;\n}\n\nexport class DepTypesMigration extends AbstractMigration {\n override readonly deprecated = true;\n override readonly propertyName =\n // oxlint-disable-next-line renovate/require-regex-util -- must stay a native RegExp: MigrationsService matches propertyName via isRegExp(), which RE2 instances fail\n /^(?:(?:d|devD|optionalD|peerD)ependencies|engines|depTypes)$/;\n\n override run(value: unknown, key: string): void {\n const packageRules: PackageRule[] = this.get('packageRules') ?? [];\n if (isNonEmptyObject(value) && !isArray(value)) {\n packageRules.push({\n matchDepTypes: [key],\n ...value,\n });\n }\n\n if (isArray(value)) {\n for (const depType of value as DepTypesRule[]) {\n if (isObject(depType) && !isArray(depType)) {\n const depTypeName = depType.depType;\n if (depTypeName) {\n delete depType.depType;\n depType.matchDepTypes = [depTypeName];\n packageRules.push({ ...(depType as PackageRule) });\n }\n }\n }\n }\n\n if (packageRules.length) {\n this.setHard('packageRules', packageRules);\n }\n }\n}\n"],"mappings":";;;AAQA,IAAa,oBAAb,cAAuC,kBAAkB;CACvD,aAA+B;CAC/B,eAEE;CAEF,IAAa,OAAgB,KAAmB;EAC9C,MAAM,eAA8B,KAAK,IAAI,cAAc,KAAK,CAAC;EACjE,IAAI,iBAAiB,KAAK,KAAK,CAAC,QAAQ,KAAK,GAC3C,aAAa,KAAK;GAChB,eAAe,CAAC,GAAG;GACnB,GAAG;EACL,CAAC;EAGH,IAAI,QAAQ,KAAK,GACV;QAAA,MAAM,WAAW,OACpB,IAAI,SAAS,OAAO,KAAK,CAAC,QAAQ,OAAO,GAAG;IAC1C,MAAM,cAAc,QAAQ;IAC5B,IAAI,aAAa;KACf,OAAO,QAAQ;KACf,QAAQ,gBAAgB,CAAC,WAAW;KACpC,aAAa,KAAK,EAAE,GAAI,QAAwB,CAAC;IACnD;GACF;;EAIJ,IAAI,aAAa,QACf,KAAK,QAAQ,gBAAgB,YAAY;CAE7C;AACF"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { regEx } from "../../util/regex.js";
|
|
1
2
|
//#region lib/config/options/env.ts
|
|
2
3
|
function getEnvName(option) {
|
|
3
4
|
if (option.env === false) return "";
|
|
4
5
|
if (option.env) return option.env;
|
|
5
|
-
return `RENOVATE_${option.name.replace(/([A-Z])/g, "_$1").toUpperCase()}`;
|
|
6
|
+
return `RENOVATE_${option.name.replace(regEx(/([A-Z])/g), "_$1").toUpperCase()}`;
|
|
6
7
|
}
|
|
7
8
|
//#endregion
|
|
8
9
|
export { getEnvName };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"env.js","names":[],"sources":["../../../lib/config/options/env.ts"],"sourcesContent":["import type { RenovateOptions } from '../types.ts';\n\ntype EnvNameOption = Partial<RenovateOptions> & Pick<RenovateOptions, 'name'>;\n\nexport function getEnvName(option: EnvNameOption): string {\n if (option.env === false) {\n return '';\n }\n if (option.env) {\n return option.env;\n }\n const nameWithUnderscores = option.name.replace(/([A-Z])/g, '_$1');\n return `RENOVATE_${nameWithUnderscores.toUpperCase()}`;\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"env.js","names":[],"sources":["../../../lib/config/options/env.ts"],"sourcesContent":["import { regEx } from '../../util/regex.ts';\nimport type { RenovateOptions } from '../types.ts';\n\ntype EnvNameOption = Partial<RenovateOptions> & Pick<RenovateOptions, 'name'>;\n\nexport function getEnvName(option: EnvNameOption): string {\n if (option.env === false) {\n return '';\n }\n if (option.env) {\n return option.env;\n }\n const nameWithUnderscores = option.name.replace(regEx(/([A-Z])/g), '_$1');\n return `RENOVATE_${nameWithUnderscores.toUpperCase()}`;\n}\n"],"mappings":";;AAKA,SAAgB,WAAW,QAA+B;CACxD,IAAI,OAAO,QAAQ,OACjB,OAAO;CAET,IAAI,OAAO,KACT,OAAO,OAAO;CAGhB,OAAO,YADqB,OAAO,KAAK,QAAQ,MAAM,UAAU,GAAG,KAC9B,CAAC,CAAC,YAAY;AACrD"}
|
package/dist/logger/utils.js
CHANGED
|
@@ -122,9 +122,9 @@ function sanitizeValue(value, seen = /* @__PURE__ */ new WeakMap()) {
|
|
|
122
122
|
}
|
|
123
123
|
return value;
|
|
124
124
|
}
|
|
125
|
-
const urlRe = /[a-z]{3,9}:\/\/[^@/]+@[a-z0-9.-]+/gi;
|
|
126
|
-
const urlCredRe = /\/\/[^@]+@/g;
|
|
127
|
-
const dataUriCredRe = /^(data:[0-9a-z-]+\/[0-9a-z-]+;).+/i;
|
|
125
|
+
const urlRe = regEx(/[a-z]{3,9}:\/\/[^@/]+@[a-z0-9.-]+/gi);
|
|
126
|
+
const urlCredRe = regEx(/\/\/[^@]+@/g);
|
|
127
|
+
const dataUriCredRe = regEx(/^(data:[0-9a-z-]+\/[0-9a-z-]+;).+/i);
|
|
128
128
|
function sanitizeUrls(text) {
|
|
129
129
|
return text.replace(urlRe, (url) => {
|
|
130
130
|
return url.replace(urlCredRe, "//**redacted**@");
|
package/dist/logger/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","names":["HttpError"],"sources":["../../lib/logger/utils.ts"],"sourcesContent":["import {\n isArray,\n isBuffer,\n isDate,\n isEmptyObject,\n isError,\n isFunction,\n isNonEmptyObject,\n isNonEmptyStringAndNotWhitespace,\n isObject,\n isPlainObject,\n isString,\n} from '@sindresorhus/is';\nimport { RequestError as HttpError } from 'got';\nimport { DateTime } from 'luxon';\nimport { ZodError } from 'zod/v4';\nimport { ExecError } from '../util/exec/exec-error.ts';\nimport { regEx } from '../util/regex.ts';\nimport { redactedFields, sanitize } from '../util/sanitize.ts';\n\nconst contentFields = [\n 'content',\n 'contents',\n 'packageLockParsed',\n 'yarnLockParsed',\n];\n\ntype ZodShortenedIssue =\n | null\n | string\n | string[]\n | {\n [key: string]: ZodShortenedIssue;\n };\n\nexport function prepareZodIssues(input: unknown): ZodShortenedIssue {\n if (!isPlainObject(input)) {\n return null;\n }\n\n let err: null | string | string[] = null;\n // v8 ignore else -- TODO: add test #40625\n if (isArray(input._errors, isString)) {\n if (input._errors.length === 1) {\n err = input._errors[0];\n } else if (input._errors.length > 1) {\n err = input._errors;\n } else {\n err = null;\n }\n }\n delete input._errors;\n\n if (isEmptyObject(input)) {\n return err;\n }\n\n const output: Record<string, ZodShortenedIssue> = {};\n const entries = Object.entries(input);\n for (const [key, value] of entries.slice(0, 3)) {\n const child = prepareZodIssues(value);\n // v8 ignore else -- TODO: add test #40625\n if (child !== null) {\n output[key] = child;\n }\n }\n\n if (entries.length > 3) {\n output.___ = `... ${entries.length - 3} more`;\n }\n\n return output;\n}\n\nexport function prepareZodError(err: ZodError): Record<string, unknown> {\n Object.defineProperty(err, 'message', {\n get: () => 'Schema error',\n /* v8 ignore start -- TODO: drop set? */\n set: () => {\n /* intentionally empty */\n },\n // v8 ignore stop -- TODO: drop set? */\n });\n\n return {\n message: err.message,\n stack: err.stack,\n issues: prepareZodIssues(err.format()),\n };\n}\n\nexport default function prepareError(err: Error): Record<string, unknown> {\n if (err instanceof ZodError) {\n return prepareZodError(err);\n }\n\n const response: Record<string, unknown> = {\n // We want to loose class information, but keep enumerable properties of the error\n // oxlint-disable-next-line typescript/no-misused-spread\n ...err,\n };\n\n // Required as message is non-enumerable\n if (!response.message && err.message) {\n response.message = err.message;\n }\n\n // Required as stack is non-enumerable\n if (!response.stack && err.stack) {\n response.stack = err.stack;\n }\n\n if (err instanceof AggregateError) {\n response.errors = err.errors.map((error) => prepareError(error));\n }\n\n // handle rawExec error\n if (err instanceof ExecError && isNonEmptyObject(err.options?.env)) {\n const env = Object.keys(err.options.env);\n response.options = { ...err.options, env };\n }\n\n // handle got error\n if (err instanceof HttpError) {\n const options: Record<string, unknown> = {\n headers: structuredClone(err.options.headers),\n url: err.options.url?.toString(),\n hostType: err.options.context.hostType,\n };\n response.options = options;\n\n options.username = err.options.username;\n options.password = err.options.password;\n options.method = err.options.method;\n options.http2 = err.options.http2;\n\n // v8 ignore else -- TODO: add test #40625\n if (err.response) {\n response.response = {\n statusCode: err.response.statusCode,\n statusMessage: err.response.statusMessage,\n body:\n err.name === 'TimeoutError'\n ? undefined\n : structuredClone(err.response.body),\n headers: structuredClone(err.response.headers),\n httpVersion: err.response.httpVersion,\n retryCount: err.response.retryCount,\n };\n }\n }\n\n return response;\n}\n\ntype NestedValue = unknown[] | object;\n\nfunction isNested(value: unknown): value is NestedValue {\n return isArray(value) || isObject(value);\n}\n\nexport function sanitizeValue(\n value: unknown,\n seen = new WeakMap<NestedValue, unknown>(),\n): any {\n if (isString(value)) {\n return sanitize(sanitizeUrls(value));\n }\n\n // Handle boxed String objects (e.g. from `new String()`), which `isString`\n // rejects but `isObject` would iterate character-by-character producing\n // `{\"0\":\"h\",\"1\":\"e\",...}` in log output.\n if (value instanceof String) {\n return sanitize(sanitizeUrls(value.toString()));\n }\n\n if (isDate(value)) {\n return value;\n }\n\n if (DateTime.isDateTime(value)) {\n return value.toISO();\n }\n\n if (isFunction(value)) {\n return '[function]';\n }\n\n if (isBuffer(value)) {\n return '[content]';\n }\n\n if (isError(value)) {\n const err = prepareError(value);\n return sanitizeValue(err, seen);\n }\n\n if (isArray(value)) {\n const length = value.length;\n const arrayResult = Array(length);\n seen.set(value, arrayResult);\n for (let idx = 0; idx < length; idx += 1) {\n const val = value[idx];\n arrayResult[idx] =\n isNested(val) && seen.has(val)\n ? seen.get(val)\n : sanitizeValue(val, seen);\n }\n return arrayResult;\n }\n\n if (isObject(value)) {\n const objectResult: Record<string, any> = {};\n seen.set(value, objectResult);\n for (const [key, val] of Object.entries<any>(value)) {\n let curValue: any;\n if (!val) {\n curValue = val;\n } else if (redactedFields.includes(key)) {\n // Do not mask/sanitize secrets templates\n if (isString(val) && regEx(/^{{\\s*secrets\\..*}}$/).test(val)) {\n curValue = val;\n } else {\n curValue = '***********';\n }\n } else if (contentFields.includes(key)) {\n curValue = '[content]';\n } else if (key === 'secrets') {\n curValue = {};\n Object.keys(val).forEach((secretKey) => {\n curValue[secretKey] = '***********';\n });\n } else {\n curValue = seen.has(val) ? seen.get(val) : sanitizeValue(val, seen);\n }\n\n const sanitizedKey = sanitizeValue(key, seen);\n objectResult[sanitizedKey] = curValue;\n }\n\n return objectResult;\n }\n\n return value;\n}\n\n// Can't use `util/regex` because of circular reference to logger\nconst urlRe = /[a-z]{3,9}:\\/\\/[^@/]+@[a-z0-9.-]+/gi;\nconst urlCredRe = /\\/\\/[^@]+@/g;\nconst dataUriCredRe = /^(data:[0-9a-z-]+\\/[0-9a-z-]+;).+/i;\n\nexport function sanitizeUrls(text: string): string {\n return text\n .replace(urlRe, (url) => {\n return url.replace(urlCredRe, '//**redacted**@');\n })\n .replace(dataUriCredRe, '$1**redacted**');\n}\n\nexport function getEnv(key: string): string | undefined {\n return [process.env[`RENOVATE_${key}`], process.env[key]]\n .map((v) => v?.toLowerCase().trim())\n .find(isNonEmptyStringAndNotWhitespace);\n}\n\nexport function getMessage(\n p1: string | Record<string, any>,\n p2?: string,\n): string | undefined {\n return isString(p1) ? p1 : p2;\n}\n\nexport function toMeta(\n p1: string | Record<string, any>,\n): Record<string, unknown> {\n return isObject(p1) ? p1 : {};\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"utils.js","names":["HttpError"],"sources":["../../lib/logger/utils.ts"],"sourcesContent":["import {\n isArray,\n isBuffer,\n isDate,\n isEmptyObject,\n isError,\n isFunction,\n isNonEmptyObject,\n isNonEmptyStringAndNotWhitespace,\n isObject,\n isPlainObject,\n isString,\n} from '@sindresorhus/is';\nimport { RequestError as HttpError } from 'got';\nimport { DateTime } from 'luxon';\nimport { ZodError } from 'zod/v4';\nimport { ExecError } from '../util/exec/exec-error.ts';\nimport { regEx } from '../util/regex.ts';\nimport { redactedFields, sanitize } from '../util/sanitize.ts';\n\nconst contentFields = [\n 'content',\n 'contents',\n 'packageLockParsed',\n 'yarnLockParsed',\n];\n\ntype ZodShortenedIssue =\n | null\n | string\n | string[]\n | {\n [key: string]: ZodShortenedIssue;\n };\n\nexport function prepareZodIssues(input: unknown): ZodShortenedIssue {\n if (!isPlainObject(input)) {\n return null;\n }\n\n let err: null | string | string[] = null;\n // v8 ignore else -- TODO: add test #40625\n if (isArray(input._errors, isString)) {\n if (input._errors.length === 1) {\n err = input._errors[0];\n } else if (input._errors.length > 1) {\n err = input._errors;\n } else {\n err = null;\n }\n }\n delete input._errors;\n\n if (isEmptyObject(input)) {\n return err;\n }\n\n const output: Record<string, ZodShortenedIssue> = {};\n const entries = Object.entries(input);\n for (const [key, value] of entries.slice(0, 3)) {\n const child = prepareZodIssues(value);\n // v8 ignore else -- TODO: add test #40625\n if (child !== null) {\n output[key] = child;\n }\n }\n\n if (entries.length > 3) {\n output.___ = `... ${entries.length - 3} more`;\n }\n\n return output;\n}\n\nexport function prepareZodError(err: ZodError): Record<string, unknown> {\n Object.defineProperty(err, 'message', {\n get: () => 'Schema error',\n /* v8 ignore start -- TODO: drop set? */\n set: () => {\n /* intentionally empty */\n },\n // v8 ignore stop -- TODO: drop set? */\n });\n\n return {\n message: err.message,\n stack: err.stack,\n issues: prepareZodIssues(err.format()),\n };\n}\n\nexport default function prepareError(err: Error): Record<string, unknown> {\n if (err instanceof ZodError) {\n return prepareZodError(err);\n }\n\n const response: Record<string, unknown> = {\n // We want to loose class information, but keep enumerable properties of the error\n // oxlint-disable-next-line typescript/no-misused-spread\n ...err,\n };\n\n // Required as message is non-enumerable\n if (!response.message && err.message) {\n response.message = err.message;\n }\n\n // Required as stack is non-enumerable\n if (!response.stack && err.stack) {\n response.stack = err.stack;\n }\n\n if (err instanceof AggregateError) {\n response.errors = err.errors.map((error) => prepareError(error));\n }\n\n // handle rawExec error\n if (err instanceof ExecError && isNonEmptyObject(err.options?.env)) {\n const env = Object.keys(err.options.env);\n response.options = { ...err.options, env };\n }\n\n // handle got error\n if (err instanceof HttpError) {\n const options: Record<string, unknown> = {\n headers: structuredClone(err.options.headers),\n url: err.options.url?.toString(),\n hostType: err.options.context.hostType,\n };\n response.options = options;\n\n options.username = err.options.username;\n options.password = err.options.password;\n options.method = err.options.method;\n options.http2 = err.options.http2;\n\n // v8 ignore else -- TODO: add test #40625\n if (err.response) {\n response.response = {\n statusCode: err.response.statusCode,\n statusMessage: err.response.statusMessage,\n body:\n err.name === 'TimeoutError'\n ? undefined\n : structuredClone(err.response.body),\n headers: structuredClone(err.response.headers),\n httpVersion: err.response.httpVersion,\n retryCount: err.response.retryCount,\n };\n }\n }\n\n return response;\n}\n\ntype NestedValue = unknown[] | object;\n\nfunction isNested(value: unknown): value is NestedValue {\n return isArray(value) || isObject(value);\n}\n\nexport function sanitizeValue(\n value: unknown,\n seen = new WeakMap<NestedValue, unknown>(),\n): any {\n if (isString(value)) {\n return sanitize(sanitizeUrls(value));\n }\n\n // Handle boxed String objects (e.g. from `new String()`), which `isString`\n // rejects but `isObject` would iterate character-by-character producing\n // `{\"0\":\"h\",\"1\":\"e\",...}` in log output.\n if (value instanceof String) {\n return sanitize(sanitizeUrls(value.toString()));\n }\n\n if (isDate(value)) {\n return value;\n }\n\n if (DateTime.isDateTime(value)) {\n return value.toISO();\n }\n\n if (isFunction(value)) {\n return '[function]';\n }\n\n if (isBuffer(value)) {\n return '[content]';\n }\n\n if (isError(value)) {\n const err = prepareError(value);\n return sanitizeValue(err, seen);\n }\n\n if (isArray(value)) {\n const length = value.length;\n const arrayResult = Array(length);\n seen.set(value, arrayResult);\n for (let idx = 0; idx < length; idx += 1) {\n const val = value[idx];\n arrayResult[idx] =\n isNested(val) && seen.has(val)\n ? seen.get(val)\n : sanitizeValue(val, seen);\n }\n return arrayResult;\n }\n\n if (isObject(value)) {\n const objectResult: Record<string, any> = {};\n seen.set(value, objectResult);\n for (const [key, val] of Object.entries<any>(value)) {\n let curValue: any;\n if (!val) {\n curValue = val;\n } else if (redactedFields.includes(key)) {\n // Do not mask/sanitize secrets templates\n if (isString(val) && regEx(/^{{\\s*secrets\\..*}}$/).test(val)) {\n curValue = val;\n } else {\n curValue = '***********';\n }\n } else if (contentFields.includes(key)) {\n curValue = '[content]';\n } else if (key === 'secrets') {\n curValue = {};\n Object.keys(val).forEach((secretKey) => {\n curValue[secretKey] = '***********';\n });\n } else {\n curValue = seen.has(val) ? seen.get(val) : sanitizeValue(val, seen);\n }\n\n const sanitizedKey = sanitizeValue(key, seen);\n objectResult[sanitizedKey] = curValue;\n }\n\n return objectResult;\n }\n\n return value;\n}\n\nconst urlRe = regEx(/[a-z]{3,9}:\\/\\/[^@/]+@[a-z0-9.-]+/gi);\nconst urlCredRe = regEx(/\\/\\/[^@]+@/g);\nconst dataUriCredRe = regEx(/^(data:[0-9a-z-]+\\/[0-9a-z-]+;).+/i);\n\nexport function sanitizeUrls(text: string): string {\n return text\n .replace(urlRe, (url) => {\n return url.replace(urlCredRe, '//**redacted**@');\n })\n .replace(dataUriCredRe, '$1**redacted**');\n}\n\nexport function getEnv(key: string): string | undefined {\n return [process.env[`RENOVATE_${key}`], process.env[key]]\n .map((v) => v?.toLowerCase().trim())\n .find(isNonEmptyStringAndNotWhitespace);\n}\n\nexport function getMessage(\n p1: string | Record<string, any>,\n p2?: string,\n): string | undefined {\n return isString(p1) ? p1 : p2;\n}\n\nexport function toMeta(\n p1: string | Record<string, any>,\n): Record<string, unknown> {\n return isObject(p1) ? p1 : {};\n}\n"],"mappings":"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"}
|
|
@@ -52,7 +52,7 @@ var CrateDatasource = class CrateDatasource extends Datasource {
|
|
|
52
52
|
if (metadata?.repository) result.sourceUrl = metadata.repository;
|
|
53
53
|
result.releases = lines.map((line) => {
|
|
54
54
|
const versionOrig = line.vers;
|
|
55
|
-
const version = versionOrig.replace(
|
|
55
|
+
const version = versionOrig.replace(regEx(/\+.*$/), "");
|
|
56
56
|
const release = { version };
|
|
57
57
|
if (versionOrig !== version) release.versionOrig = versionOrig;
|
|
58
58
|
if (line.yanked) release.isDeprecated = true;
|
|
@@ -182,7 +182,7 @@ var CrateDatasource = class CrateDatasource extends Datasource {
|
|
|
182
182
|
/* v8 ignore next 3 -- should never happen */
|
|
183
183
|
if (!registryUrl) return null;
|
|
184
184
|
const isSparseRegistry = CrateDatasource.isSparseRegistry(registryUrl);
|
|
185
|
-
const registryFetchUrl = isSparseRegistry ? registryUrl.replace(/^sparse
|
|
185
|
+
const registryFetchUrl = isSparseRegistry ? registryUrl.replace(regEx(/^sparse\+/), "") : registryUrl;
|
|
186
186
|
const url = parseUrl(registryFetchUrl);
|
|
187
187
|
if (!url) {
|
|
188
188
|
logger.debug(`Could not parse registry URL ${registryFetchUrl}`);
|
|
@@ -297,7 +297,7 @@ var CrateDatasource = class CrateDatasource extends Datasource {
|
|
|
297
297
|
}
|
|
298
298
|
async _postprocessRelease({ packageName, registryUrl }, release) {
|
|
299
299
|
if (release.releaseTimestamp) return release;
|
|
300
|
-
const rawUrl = registryUrl?.replace(/^sparse
|
|
300
|
+
const rawUrl = registryUrl?.replace(regEx(/^sparse\+/), "");
|
|
301
301
|
if (!rawUrl) return release;
|
|
302
302
|
const cacheKey = `crate-datasource/registry-config/${rawUrl}`;
|
|
303
303
|
const config = get(cacheKey);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["cargoVersioning.id","memCache.get"],"sources":["../../../../lib/modules/datasource/crate/index.ts"],"sourcesContent":["import upath from 'upath';\nimport { GlobalConfig } from '../../../config/global.ts';\nimport { logger } from '../../../logger/index.ts';\nimport * as memCache from '../../../util/cache/memory/index.ts';\nimport { withCache } from '../../../util/cache/package/with-cache.ts';\nimport { privateCacheDir, readCacheFile } from '../../../util/fs/index.ts';\nimport { createSimpleGit } from '../../../util/git/index.ts';\nimport { toSha256 } from '../../../util/hash.ts';\nimport { memCacheProvider } from '../../../util/http/cache/memory-http-cache-provider.ts';\nimport { acquireLock } from '../../../util/mutex.ts';\nimport { newlineRegex, regEx } from '../../../util/regex.ts';\nimport { Json } from '../../../util/schema-utils/index.ts';\nimport { asTimestamp } from '../../../util/timestamp.ts';\nimport { joinUrlParts, parseUrl } from '../../../util/url.ts';\nimport * as cargoVersioning from '../../versioning/cargo/index.ts';\nimport { Datasource } from '../datasource.ts';\nimport type {\n GetReleasesConfig,\n PostprocessReleaseConfig,\n PostprocessReleaseResult,\n Release,\n ReleaseResult,\n} from '../types.ts';\nimport type { CrateMetadata } from './schema.ts';\nimport {\n CrateMetadataResponse,\n RegistryConfig,\n ReleaseTimestamp,\n} from './schema.ts';\nimport type { CrateRecord, RegistryFlavor, RegistryInfo } from './types.ts';\n\ntype CloneResult =\n | {\n err: Error;\n clonePath?: undefined;\n }\n | {\n clonePath: string;\n err?: undefined;\n };\n\nexport class CrateDatasource extends Datasource {\n static readonly id = 'crate';\n\n constructor() {\n super(CrateDatasource.id);\n }\n\n override defaultRegistryUrls = ['sparse+https://index.crates.io/'];\n\n override defaultVersioning = cargoVersioning.id;\n\n override readonly sourceUrlSupport = 'package';\n override readonly sourceUrlNote =\n 'The source URL is determined from the `repository` field in the results.';\n\n override readonly releaseTimestampSupport = true;\n override readonly releaseTimestampNote =\n 'The release timestamp is determined from `pubtime` field from crates.io index if available, or `version.created_at` field from crates.io API otherwise.';\n\n private async _getReleases({\n packageName,\n registryUrl,\n }: GetReleasesConfig): Promise<ReleaseResult | null> {\n /* v8 ignore if -- should never happen */\n if (!registryUrl) {\n logger.warn(\n 'crate datasource: No registryUrl specified, cannot perform getReleases',\n );\n return null;\n }\n\n const registryInfo = await CrateDatasource.fetchRegistryInfo({\n packageName,\n registryUrl,\n });\n if (!registryInfo) {\n logger.debug(`Could not fetch registry info from ${registryUrl}`);\n return null;\n }\n\n const dependencyUrl = CrateDatasource.getDependencyUrl(\n registryInfo,\n packageName,\n );\n\n const payload = await this.fetchCrateRecordsPayload(\n registryInfo,\n packageName,\n );\n const lines = payload\n .split(newlineRegex) // break into lines\n .map((line) => line.trim()) // remove whitespace\n .filter((line) => line.length !== 0) // remove empty lines\n .map((line) => JSON.parse(line) as CrateRecord); // parse\n\n const metadata = await this.getCrateMetadata(registryInfo, packageName);\n\n const result: ReleaseResult = {\n dependencyUrl,\n releases: [],\n };\n\n if (metadata?.homepage) {\n result.homepage = metadata.homepage;\n }\n\n if (metadata?.repository) {\n result.sourceUrl = metadata.repository;\n }\n\n result.releases = lines\n .map((line) => {\n const versionOrig = line.vers;\n const version = versionOrig.replace(/\\+.*$/, '');\n const release: Release = { version };\n\n if (versionOrig !== version) {\n release.versionOrig = versionOrig;\n }\n\n if (line.yanked) {\n release.isDeprecated = true;\n }\n\n if (line.rust_version) {\n release.constraints = { rust: [line.rust_version] };\n }\n\n if (line.pubtime) {\n release.releaseTimestamp = asTimestamp(line.pubtime);\n }\n\n return release;\n })\n .filter((release) => release.version);\n if (!result.releases.length) {\n return null;\n }\n\n return result;\n }\n\n getReleases(config: GetReleasesConfig): Promise<ReleaseResult | null> {\n return withCache(\n {\n namespace: `datasource-${CrateDatasource.id}`,\n // TODO: types (#22198)\n key: `${config.registryUrl}/${config.packageName}`,\n cacheable: CrateDatasource.isCratesIo(config.registryUrl),\n fallback: true,\n },\n () => this._getReleases(config),\n );\n }\n\n /**\n * Fetches the registry's config.json which provides the API base URL\n * and download URL template.\n * See: https://doc.rust-lang.org/cargo/reference/registry-index.html#index-configuration\n */\n private async fetchRegistryConfig(\n info: RegistryInfo,\n ): Promise<RegistryConfig | null> {\n const cacheKey = `crate-datasource/registry-config/${info.rawUrl}`;\n const cached = memCache.get<RegistryConfig>(cacheKey);\n if (cached) {\n return cached;\n }\n\n if (info.clonePath) {\n try {\n const configPath = upath.join(info.clonePath, 'config.json');\n const content = await readCacheFile(configPath, 'utf8');\n const parsed = Json.pipe(RegistryConfig).parse(content);\n memCache.set(cacheKey, parsed);\n return parsed;\n } catch {\n logger.debug(\n { registryUrl: info.rawUrl },\n 'Could not read config.json from cloned registry',\n );\n }\n } else {\n try {\n const configUrl = joinUrlParts(info.rawUrl, 'config.json');\n const { body } = await this.http.getJson(configUrl, RegistryConfig);\n memCache.set(cacheKey, body);\n return body;\n } catch {\n logger.debug(\n { registryUrl: info.rawUrl },\n 'Could not fetch registry config.json',\n );\n }\n }\n\n return null;\n }\n\n private async _getCrateMetadata(\n info: RegistryInfo,\n packageName: string,\n ): Promise<CrateMetadata | null> {\n const registryConfig = await this.fetchRegistryConfig(info);\n if (!registryConfig?.api) {\n return null;\n }\n\n const apiBaseUrl = joinUrlParts(registryConfig.api, 'api/v1/');\n\n // The `?include=` suffix is required to avoid unnecessary database queries\n // on the crates.io server. This lets us work around the regular request\n // throttling of one request per second.\n const crateUrl = `${apiBaseUrl}crates/${packageName}?include=`;\n\n logger.trace(\n { crateUrl, packageName, registryUrl: info.rawUrl },\n 'downloading crate metadata',\n );\n\n try {\n const { body } = await this.http.getJson(crateUrl, CrateMetadataResponse);\n return body.crate;\n } catch (err) {\n logger.debug(\n { err, packageName, registryUrl: info.rawUrl },\n 'failed to download crate metadata',\n );\n }\n\n return null;\n }\n\n public getCrateMetadata(\n info: RegistryInfo,\n packageName: string,\n ): Promise<CrateMetadata | null> {\n return withCache(\n {\n namespace: `datasource-${CrateDatasource.id}-metadata`,\n key: `${info.rawUrl}/${packageName}`,\n cacheable: info.flavor === 'crates.io',\n ttlMinutes: 24 * 60, // 24 hours\n },\n () => this._getCrateMetadata(info, packageName),\n );\n }\n\n public async fetchCrateRecordsPayload(\n info: RegistryInfo,\n packageName: string,\n ): Promise<string> {\n if (info.clonePath) {\n const path = upath.join(\n info.clonePath,\n ...CrateDatasource.getIndexSuffix(packageName),\n );\n return readCacheFile(path, 'utf8');\n }\n\n // sparse index\n const packageSuffix = CrateDatasource.getIndexSuffix(\n packageName.toLowerCase(),\n );\n const crateUrl = joinUrlParts(info.rawUrl, ...packageSuffix);\n logger.trace(\n { crateUrl, packageName, registryUrl: info.rawUrl },\n 'fetching crate records from sparse index',\n );\n try {\n return (await this.http.getText(crateUrl)).body;\n } catch (err) {\n this.handleGenericErrors(err);\n }\n }\n\n /**\n * Computes the dependency URL for a crate, given\n * registry information\n */\n private static getDependencyUrl(\n info: RegistryInfo,\n packageName: string,\n ): string {\n switch (info.flavor) {\n case 'crates.io':\n return `https://crates.io/crates/${packageName}`;\n case 'cloudsmith': {\n // input: https://dl.cloudsmith.io/basic/$org/$repo/cargo/index.git\n const tokens = info.url.pathname.split('/');\n const org = tokens[2];\n const repo = tokens[3];\n return `https://cloudsmith.io/~${org}/repos/${repo}/packages/detail/cargo/${packageName}`;\n }\n default:\n return `${info.url}/${packageName}`;\n }\n }\n\n /**\n * Given a Git URL, computes a semi-human-readable name for a folder in which to\n * clone the repository.\n */\n private static cacheDirFromUrl(url: URL): string {\n const proto = url.protocol.replace(regEx(/:$/), '');\n const host = url.hostname;\n const hash = toSha256(url.pathname).substring(0, 7);\n\n return `crate-registry-${proto}-${host}-${hash}`;\n }\n\n private static isSparseRegistry(url: string): boolean {\n const parsed = parseUrl(url);\n if (!parsed) {\n return false;\n }\n return parsed.protocol.startsWith('sparse+');\n }\n\n /**\n * Fetches information about a registry, by url.\n * If no url is given, assumes crates.io.\n * If an url is given, assumes it's a valid Git repository\n * url and clones it to cache.\n */\n private static async fetchRegistryInfo({\n packageName,\n registryUrl,\n }: GetReleasesConfig): Promise<RegistryInfo | null> {\n /* v8 ignore next 3 -- should never happen */\n if (!registryUrl) {\n return null;\n }\n\n const isSparseRegistry = CrateDatasource.isSparseRegistry(registryUrl);\n const registryFetchUrl = isSparseRegistry\n ? registryUrl.replace(/^sparse\\+/, '')\n : registryUrl;\n\n const url = parseUrl(registryFetchUrl);\n if (!url) {\n logger.debug(`Could not parse registry URL ${registryFetchUrl}`);\n return null;\n }\n\n let flavor: RegistryFlavor;\n if (url.hostname === 'index.crates.io') {\n flavor = 'crates.io';\n } else if (url.hostname === 'dl.cloudsmith.io') {\n flavor = 'cloudsmith';\n } else {\n flavor = 'other';\n }\n\n const registry: RegistryInfo = {\n flavor,\n rawUrl: registryFetchUrl,\n url,\n };\n\n if (\n registry.flavor !== 'crates.io' &&\n !GlobalConfig.get('allowCustomCrateRegistries')\n ) {\n logger.warn(\n 'crate datasource: allowCustomCrateRegistries=true is required for registries other than crates.io, bailing out',\n );\n return null;\n }\n if (!isSparseRegistry) {\n const cacheKey = `crate-datasource/registry-clone-path/${registryFetchUrl}`;\n const lockKey = registryFetchUrl;\n\n const executionTimeout = GlobalConfig.get('executionTimeout') * 60 * 1000;\n const gitTimeout = GlobalConfig.get('gitTimeout') || executionTimeout;\n const releaseLock = await acquireLock(\n lockKey,\n 'crate-registry',\n gitTimeout,\n );\n try {\n const cached = memCache.get<CloneResult>(cacheKey);\n\n if (cached?.err) {\n logger.warn(\n { err: cached.err, packageName, registryFetchUrl },\n 'Previous git clone failed, bailing out.',\n );\n return null;\n }\n\n if (cached?.clonePath) {\n registry.clonePath = cached.clonePath;\n return registry;\n }\n\n const clonePath = upath.join(\n privateCacheDir(),\n CrateDatasource.cacheDirFromUrl(url),\n );\n\n const result = await CrateDatasource.clone(\n registryFetchUrl,\n clonePath,\n packageName,\n );\n\n memCache.set(cacheKey, result);\n\n if (result.err) {\n logger.warn(\n { err: result.err, packageName, registryFetchUrl },\n 'Git clone failed, bailing out.',\n );\n return null;\n }\n\n registry.clonePath = result.clonePath;\n } finally {\n releaseLock();\n }\n }\n\n return registry;\n }\n\n private static async clone(\n registryFetchUrl: string,\n clonePath: string,\n packageName: string,\n ): Promise<CloneResult> {\n logger.info(\n { clonePath, registryFetchUrl },\n `Cloning private cargo registry`,\n );\n\n const git = createSimpleGit({\n config: { maxConcurrentProcesses: 1 },\n });\n\n try {\n await git.clone(registryFetchUrl, clonePath, {\n '--depth': 1,\n });\n return { clonePath };\n } catch (err) {\n if (\n err.message.includes(\n 'fatal: dumb http transport does not support shallow capabilities',\n )\n ) {\n logger.info(\n { packageName, registryFetchUrl },\n 'failed to shallow clone git registry, doing full clone',\n );\n try {\n await git.clone(registryFetchUrl, clonePath);\n return { clonePath };\n } catch (err) {\n logger.warn(\n { err, packageName, registryFetchUrl },\n 'failed cloning git registry',\n );\n return { err };\n }\n } else {\n logger.warn(\n { err, packageName, registryFetchUrl },\n 'failed cloning git registry',\n );\n return { err };\n }\n }\n }\n\n private static isCratesIo(registryUrl: string | undefined): boolean {\n if (!registryUrl) {\n return false;\n }\n const normalized = registryUrl.replace(regEx(/^sparse\\+/), '');\n const parsed = parseUrl(normalized);\n return parsed?.hostname === 'index.crates.io';\n }\n\n public static getIndexSuffix(packageName: string): string[] {\n const len = packageName.length;\n\n if (len === 1) {\n return ['1', packageName];\n }\n if (len === 2) {\n return ['2', packageName];\n }\n if (len === 3) {\n return ['3', packageName[0], packageName];\n }\n\n return [packageName.slice(0, 2), packageName.slice(2, 4), packageName];\n }\n\n private async _postprocessRelease(\n { packageName, registryUrl }: PostprocessReleaseConfig,\n release: Release,\n ): Promise<PostprocessReleaseResult> {\n if (release.releaseTimestamp) {\n return release;\n }\n\n // Look up the registry config from cache (populated during getReleases)\n const rawUrl = registryUrl?.replace(/^sparse\\+/, '');\n if (!rawUrl) {\n return release;\n }\n const cacheKey = `crate-datasource/registry-config/${rawUrl}`;\n const config = memCache.get<{ dl: string; api?: string }>(cacheKey);\n if (!config?.api) {\n return release;\n }\n\n const apiBaseUrl = joinUrlParts(config.api, 'api/v1/');\n const url = `${apiBaseUrl}crates/${packageName}/${release.versionOrig ?? release.version}`;\n logger.trace(\n { url, packageName, version: release.version, registryUrl },\n 'fetching crate release timestamp',\n );\n // Getting release timestamp could become unnecessary if the manual backfill of `pubtime` mentioned in\n // https://github.com/rust-lang/cargo/issues/15491 is done for all packages.\n const { body: releaseTimestamp } = await this.http.getJson(\n url,\n { cacheProvider: memCacheProvider },\n ReleaseTimestamp,\n );\n release.releaseTimestamp = releaseTimestamp;\n return release;\n }\n\n override postprocessRelease(\n config: PostprocessReleaseConfig,\n release: Release,\n ): Promise<PostprocessReleaseResult> {\n return withCache(\n {\n namespace: `datasource-crate`,\n key: `postprocessRelease:${config.registryUrl}:${config.packageName}:${release.version}`,\n ttlMinutes: 7 * 24 * 60,\n cacheable: CrateDatasource.isCratesIo(config.registryUrl ?? undefined),\n },\n () => this._postprocessRelease(config, release),\n );\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["cargoVersioning.id","memCache.get"],"sources":["../../../../lib/modules/datasource/crate/index.ts"],"sourcesContent":["import upath from 'upath';\nimport { GlobalConfig } from '../../../config/global.ts';\nimport { logger } from '../../../logger/index.ts';\nimport * as memCache from '../../../util/cache/memory/index.ts';\nimport { withCache } from '../../../util/cache/package/with-cache.ts';\nimport { privateCacheDir, readCacheFile } from '../../../util/fs/index.ts';\nimport { createSimpleGit } from '../../../util/git/index.ts';\nimport { toSha256 } from '../../../util/hash.ts';\nimport { memCacheProvider } from '../../../util/http/cache/memory-http-cache-provider.ts';\nimport { acquireLock } from '../../../util/mutex.ts';\nimport { newlineRegex, regEx } from '../../../util/regex.ts';\nimport { Json } from '../../../util/schema-utils/index.ts';\nimport { asTimestamp } from '../../../util/timestamp.ts';\nimport { joinUrlParts, parseUrl } from '../../../util/url.ts';\nimport * as cargoVersioning from '../../versioning/cargo/index.ts';\nimport { Datasource } from '../datasource.ts';\nimport type {\n GetReleasesConfig,\n PostprocessReleaseConfig,\n PostprocessReleaseResult,\n Release,\n ReleaseResult,\n} from '../types.ts';\nimport type { CrateMetadata } from './schema.ts';\nimport {\n CrateMetadataResponse,\n RegistryConfig,\n ReleaseTimestamp,\n} from './schema.ts';\nimport type { CrateRecord, RegistryFlavor, RegistryInfo } from './types.ts';\n\ntype CloneResult =\n | {\n err: Error;\n clonePath?: undefined;\n }\n | {\n clonePath: string;\n err?: undefined;\n };\n\nexport class CrateDatasource extends Datasource {\n static readonly id = 'crate';\n\n constructor() {\n super(CrateDatasource.id);\n }\n\n override defaultRegistryUrls = ['sparse+https://index.crates.io/'];\n\n override defaultVersioning = cargoVersioning.id;\n\n override readonly sourceUrlSupport = 'package';\n override readonly sourceUrlNote =\n 'The source URL is determined from the `repository` field in the results.';\n\n override readonly releaseTimestampSupport = true;\n override readonly releaseTimestampNote =\n 'The release timestamp is determined from `pubtime` field from crates.io index if available, or `version.created_at` field from crates.io API otherwise.';\n\n private async _getReleases({\n packageName,\n registryUrl,\n }: GetReleasesConfig): Promise<ReleaseResult | null> {\n /* v8 ignore if -- should never happen */\n if (!registryUrl) {\n logger.warn(\n 'crate datasource: No registryUrl specified, cannot perform getReleases',\n );\n return null;\n }\n\n const registryInfo = await CrateDatasource.fetchRegistryInfo({\n packageName,\n registryUrl,\n });\n if (!registryInfo) {\n logger.debug(`Could not fetch registry info from ${registryUrl}`);\n return null;\n }\n\n const dependencyUrl = CrateDatasource.getDependencyUrl(\n registryInfo,\n packageName,\n );\n\n const payload = await this.fetchCrateRecordsPayload(\n registryInfo,\n packageName,\n );\n const lines = payload\n .split(newlineRegex) // break into lines\n .map((line) => line.trim()) // remove whitespace\n .filter((line) => line.length !== 0) // remove empty lines\n .map((line) => JSON.parse(line) as CrateRecord); // parse\n\n const metadata = await this.getCrateMetadata(registryInfo, packageName);\n\n const result: ReleaseResult = {\n dependencyUrl,\n releases: [],\n };\n\n if (metadata?.homepage) {\n result.homepage = metadata.homepage;\n }\n\n if (metadata?.repository) {\n result.sourceUrl = metadata.repository;\n }\n\n result.releases = lines\n .map((line) => {\n const versionOrig = line.vers;\n const version = versionOrig.replace(regEx(/\\+.*$/), '');\n const release: Release = { version };\n\n if (versionOrig !== version) {\n release.versionOrig = versionOrig;\n }\n\n if (line.yanked) {\n release.isDeprecated = true;\n }\n\n if (line.rust_version) {\n release.constraints = { rust: [line.rust_version] };\n }\n\n if (line.pubtime) {\n release.releaseTimestamp = asTimestamp(line.pubtime);\n }\n\n return release;\n })\n .filter((release) => release.version);\n if (!result.releases.length) {\n return null;\n }\n\n return result;\n }\n\n getReleases(config: GetReleasesConfig): Promise<ReleaseResult | null> {\n return withCache(\n {\n namespace: `datasource-${CrateDatasource.id}`,\n // TODO: types (#22198)\n key: `${config.registryUrl}/${config.packageName}`,\n cacheable: CrateDatasource.isCratesIo(config.registryUrl),\n fallback: true,\n },\n () => this._getReleases(config),\n );\n }\n\n /**\n * Fetches the registry's config.json which provides the API base URL\n * and download URL template.\n * See: https://doc.rust-lang.org/cargo/reference/registry-index.html#index-configuration\n */\n private async fetchRegistryConfig(\n info: RegistryInfo,\n ): Promise<RegistryConfig | null> {\n const cacheKey = `crate-datasource/registry-config/${info.rawUrl}`;\n const cached = memCache.get<RegistryConfig>(cacheKey);\n if (cached) {\n return cached;\n }\n\n if (info.clonePath) {\n try {\n const configPath = upath.join(info.clonePath, 'config.json');\n const content = await readCacheFile(configPath, 'utf8');\n const parsed = Json.pipe(RegistryConfig).parse(content);\n memCache.set(cacheKey, parsed);\n return parsed;\n } catch {\n logger.debug(\n { registryUrl: info.rawUrl },\n 'Could not read config.json from cloned registry',\n );\n }\n } else {\n try {\n const configUrl = joinUrlParts(info.rawUrl, 'config.json');\n const { body } = await this.http.getJson(configUrl, RegistryConfig);\n memCache.set(cacheKey, body);\n return body;\n } catch {\n logger.debug(\n { registryUrl: info.rawUrl },\n 'Could not fetch registry config.json',\n );\n }\n }\n\n return null;\n }\n\n private async _getCrateMetadata(\n info: RegistryInfo,\n packageName: string,\n ): Promise<CrateMetadata | null> {\n const registryConfig = await this.fetchRegistryConfig(info);\n if (!registryConfig?.api) {\n return null;\n }\n\n const apiBaseUrl = joinUrlParts(registryConfig.api, 'api/v1/');\n\n // The `?include=` suffix is required to avoid unnecessary database queries\n // on the crates.io server. This lets us work around the regular request\n // throttling of one request per second.\n const crateUrl = `${apiBaseUrl}crates/${packageName}?include=`;\n\n logger.trace(\n { crateUrl, packageName, registryUrl: info.rawUrl },\n 'downloading crate metadata',\n );\n\n try {\n const { body } = await this.http.getJson(crateUrl, CrateMetadataResponse);\n return body.crate;\n } catch (err) {\n logger.debug(\n { err, packageName, registryUrl: info.rawUrl },\n 'failed to download crate metadata',\n );\n }\n\n return null;\n }\n\n public getCrateMetadata(\n info: RegistryInfo,\n packageName: string,\n ): Promise<CrateMetadata | null> {\n return withCache(\n {\n namespace: `datasource-${CrateDatasource.id}-metadata`,\n key: `${info.rawUrl}/${packageName}`,\n cacheable: info.flavor === 'crates.io',\n ttlMinutes: 24 * 60, // 24 hours\n },\n () => this._getCrateMetadata(info, packageName),\n );\n }\n\n public async fetchCrateRecordsPayload(\n info: RegistryInfo,\n packageName: string,\n ): Promise<string> {\n if (info.clonePath) {\n const path = upath.join(\n info.clonePath,\n ...CrateDatasource.getIndexSuffix(packageName),\n );\n return readCacheFile(path, 'utf8');\n }\n\n // sparse index\n const packageSuffix = CrateDatasource.getIndexSuffix(\n packageName.toLowerCase(),\n );\n const crateUrl = joinUrlParts(info.rawUrl, ...packageSuffix);\n logger.trace(\n { crateUrl, packageName, registryUrl: info.rawUrl },\n 'fetching crate records from sparse index',\n );\n try {\n return (await this.http.getText(crateUrl)).body;\n } catch (err) {\n this.handleGenericErrors(err);\n }\n }\n\n /**\n * Computes the dependency URL for a crate, given\n * registry information\n */\n private static getDependencyUrl(\n info: RegistryInfo,\n packageName: string,\n ): string {\n switch (info.flavor) {\n case 'crates.io':\n return `https://crates.io/crates/${packageName}`;\n case 'cloudsmith': {\n // input: https://dl.cloudsmith.io/basic/$org/$repo/cargo/index.git\n const tokens = info.url.pathname.split('/');\n const org = tokens[2];\n const repo = tokens[3];\n return `https://cloudsmith.io/~${org}/repos/${repo}/packages/detail/cargo/${packageName}`;\n }\n default:\n return `${info.url}/${packageName}`;\n }\n }\n\n /**\n * Given a Git URL, computes a semi-human-readable name for a folder in which to\n * clone the repository.\n */\n private static cacheDirFromUrl(url: URL): string {\n const proto = url.protocol.replace(regEx(/:$/), '');\n const host = url.hostname;\n const hash = toSha256(url.pathname).substring(0, 7);\n\n return `crate-registry-${proto}-${host}-${hash}`;\n }\n\n private static isSparseRegistry(url: string): boolean {\n const parsed = parseUrl(url);\n if (!parsed) {\n return false;\n }\n return parsed.protocol.startsWith('sparse+');\n }\n\n /**\n * Fetches information about a registry, by url.\n * If no url is given, assumes crates.io.\n * If an url is given, assumes it's a valid Git repository\n * url and clones it to cache.\n */\n private static async fetchRegistryInfo({\n packageName,\n registryUrl,\n }: GetReleasesConfig): Promise<RegistryInfo | null> {\n /* v8 ignore next 3 -- should never happen */\n if (!registryUrl) {\n return null;\n }\n\n const isSparseRegistry = CrateDatasource.isSparseRegistry(registryUrl);\n const registryFetchUrl = isSparseRegistry\n ? registryUrl.replace(regEx(/^sparse\\+/), '')\n : registryUrl;\n\n const url = parseUrl(registryFetchUrl);\n if (!url) {\n logger.debug(`Could not parse registry URL ${registryFetchUrl}`);\n return null;\n }\n\n let flavor: RegistryFlavor;\n if (url.hostname === 'index.crates.io') {\n flavor = 'crates.io';\n } else if (url.hostname === 'dl.cloudsmith.io') {\n flavor = 'cloudsmith';\n } else {\n flavor = 'other';\n }\n\n const registry: RegistryInfo = {\n flavor,\n rawUrl: registryFetchUrl,\n url,\n };\n\n if (\n registry.flavor !== 'crates.io' &&\n !GlobalConfig.get('allowCustomCrateRegistries')\n ) {\n logger.warn(\n 'crate datasource: allowCustomCrateRegistries=true is required for registries other than crates.io, bailing out',\n );\n return null;\n }\n if (!isSparseRegistry) {\n const cacheKey = `crate-datasource/registry-clone-path/${registryFetchUrl}`;\n const lockKey = registryFetchUrl;\n\n const executionTimeout = GlobalConfig.get('executionTimeout') * 60 * 1000;\n const gitTimeout = GlobalConfig.get('gitTimeout') || executionTimeout;\n const releaseLock = await acquireLock(\n lockKey,\n 'crate-registry',\n gitTimeout,\n );\n try {\n const cached = memCache.get<CloneResult>(cacheKey);\n\n if (cached?.err) {\n logger.warn(\n { err: cached.err, packageName, registryFetchUrl },\n 'Previous git clone failed, bailing out.',\n );\n return null;\n }\n\n if (cached?.clonePath) {\n registry.clonePath = cached.clonePath;\n return registry;\n }\n\n const clonePath = upath.join(\n privateCacheDir(),\n CrateDatasource.cacheDirFromUrl(url),\n );\n\n const result = await CrateDatasource.clone(\n registryFetchUrl,\n clonePath,\n packageName,\n );\n\n memCache.set(cacheKey, result);\n\n if (result.err) {\n logger.warn(\n { err: result.err, packageName, registryFetchUrl },\n 'Git clone failed, bailing out.',\n );\n return null;\n }\n\n registry.clonePath = result.clonePath;\n } finally {\n releaseLock();\n }\n }\n\n return registry;\n }\n\n private static async clone(\n registryFetchUrl: string,\n clonePath: string,\n packageName: string,\n ): Promise<CloneResult> {\n logger.info(\n { clonePath, registryFetchUrl },\n `Cloning private cargo registry`,\n );\n\n const git = createSimpleGit({\n config: { maxConcurrentProcesses: 1 },\n });\n\n try {\n await git.clone(registryFetchUrl, clonePath, {\n '--depth': 1,\n });\n return { clonePath };\n } catch (err) {\n if (\n err.message.includes(\n 'fatal: dumb http transport does not support shallow capabilities',\n )\n ) {\n logger.info(\n { packageName, registryFetchUrl },\n 'failed to shallow clone git registry, doing full clone',\n );\n try {\n await git.clone(registryFetchUrl, clonePath);\n return { clonePath };\n } catch (err) {\n logger.warn(\n { err, packageName, registryFetchUrl },\n 'failed cloning git registry',\n );\n return { err };\n }\n } else {\n logger.warn(\n { err, packageName, registryFetchUrl },\n 'failed cloning git registry',\n );\n return { err };\n }\n }\n }\n\n private static isCratesIo(registryUrl: string | undefined): boolean {\n if (!registryUrl) {\n return false;\n }\n const normalized = registryUrl.replace(regEx(/^sparse\\+/), '');\n const parsed = parseUrl(normalized);\n return parsed?.hostname === 'index.crates.io';\n }\n\n public static getIndexSuffix(packageName: string): string[] {\n const len = packageName.length;\n\n if (len === 1) {\n return ['1', packageName];\n }\n if (len === 2) {\n return ['2', packageName];\n }\n if (len === 3) {\n return ['3', packageName[0], packageName];\n }\n\n return [packageName.slice(0, 2), packageName.slice(2, 4), packageName];\n }\n\n private async _postprocessRelease(\n { packageName, registryUrl }: PostprocessReleaseConfig,\n release: Release,\n ): Promise<PostprocessReleaseResult> {\n if (release.releaseTimestamp) {\n return release;\n }\n\n // Look up the registry config from cache (populated during getReleases)\n const rawUrl = registryUrl?.replace(regEx(/^sparse\\+/), '');\n if (!rawUrl) {\n return release;\n }\n const cacheKey = `crate-datasource/registry-config/${rawUrl}`;\n const config = memCache.get<{ dl: string; api?: string }>(cacheKey);\n if (!config?.api) {\n return release;\n }\n\n const apiBaseUrl = joinUrlParts(config.api, 'api/v1/');\n const url = `${apiBaseUrl}crates/${packageName}/${release.versionOrig ?? release.version}`;\n logger.trace(\n { url, packageName, version: release.version, registryUrl },\n 'fetching crate release timestamp',\n );\n // Getting release timestamp could become unnecessary if the manual backfill of `pubtime` mentioned in\n // https://github.com/rust-lang/cargo/issues/15491 is done for all packages.\n const { body: releaseTimestamp } = await this.http.getJson(\n url,\n { cacheProvider: memCacheProvider },\n ReleaseTimestamp,\n );\n release.releaseTimestamp = releaseTimestamp;\n return release;\n }\n\n override postprocessRelease(\n config: PostprocessReleaseConfig,\n release: Release,\n ): Promise<PostprocessReleaseResult> {\n return withCache(\n {\n namespace: `datasource-crate`,\n key: `postprocessRelease:${config.registryUrl}:${config.packageName}:${release.version}`,\n ttlMinutes: 7 * 24 * 60,\n cacheable: CrateDatasource.isCratesIo(config.registryUrl ?? undefined),\n },\n () => this._postprocessRelease(config, release),\n );\n }\n}\n"],"mappings":"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"}
|
|
@@ -94,7 +94,7 @@ var BaseGoDatasource = class BaseGoDatasource {
|
|
|
94
94
|
return await BaseGoDatasource.goGetDatasource(goModule);
|
|
95
95
|
}
|
|
96
96
|
static async goGetDatasource(goModule) {
|
|
97
|
-
const pkgUrl = `https://${goModule.replace(/\.git(\/[a-z0-9/]*)
|
|
97
|
+
const pkgUrl = `https://${goModule.replace(regEx(/\.git(\/[a-z0-9/]*)?$/), "")}?go-get=1`;
|
|
98
98
|
const { body: html } = await BaseGoDatasource.http.getText(pkgUrl);
|
|
99
99
|
const goSourceHeader = BaseGoDatasource.goSourceHeader(html, goModule);
|
|
100
100
|
if (goSourceHeader) return goSourceHeader;
|
|
@@ -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\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 private static async goGetDatasource(\n goModule: string,\n ): Promise<DataSource | null> {\n const goModuleUrl = goModule.replace(/\\.git(\\/[a-z0-9/]*)?$/, '');\n const pkgUrl = `https://${goModuleUrl}?go-get=1`;\n const { body: html } = await BaseGoDatasource.http.getText(pkgUrl);\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 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 /* istanbul ignore next */\n return null;\n }\n\n private static goImportHeader(\n html: string,\n goModule: string,\n ): DataSource | null {\n const importMatchGroups = regEx(\n /<meta\\s+name=\"?go-import\"?\\s+content=\"(?<prefix>[^\"\\s]+)\\s+(?<proto>[^\"\\s]+)\\s+(?<goImportURL>[^\"\\s]+)/,\n ).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\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 private static async goGetDatasource(\n goModule: string,\n ): Promise<DataSource | null> {\n const goModuleUrl = goModule.replace(regEx(/\\.git(\\/[a-z0-9/]*)?$/), '');\n const pkgUrl = `https://${goModuleUrl}?go-get=1`;\n const { body: html } = await BaseGoDatasource.http.getText(pkgUrl);\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 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 /* istanbul ignore next */\n return null;\n }\n\n private static goImportHeader(\n html: string,\n goModule: string,\n ): DataSource | null {\n const importMatchGroups = regEx(\n /<meta\\s+name=\"?go-import\"?\\s+content=\"(?<prefix>[^\"\\s]+)\\s+(?<proto>[^\"\\s]+)\\s+(?<goImportURL>[^\"\\s]+)/,\n ).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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"}
|
|
@@ -22,7 +22,7 @@ function parseGoproxy(input = getEnv().GOPROXY) {
|
|
|
22
22
|
const cacheKey = `goproxy::${input}`;
|
|
23
23
|
const cachedResult = get(cacheKey);
|
|
24
24
|
if (cachedResult) return cachedResult;
|
|
25
|
-
const result = input.split(regEx(/([^,|]*(?:,|\|))/)).filter(isTruthy).map((s) => s.split(/(
|
|
25
|
+
const result = input.split(regEx(/([^,|]*(?:,|\|))/)).filter(isTruthy).map((s) => s.split(regEx(/(,|\|)/))).filter(([url]) => isTruthy(url)).map(([url, separator]) => ({
|
|
26
26
|
url,
|
|
27
27
|
fallback: separator === "," ? "," : "|"
|
|
28
28
|
}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"goproxy-parser.js","names":["memCache.get"],"sources":["../../../../lib/modules/datasource/go/goproxy-parser.ts"],"sourcesContent":["import { isString, isTruthy } from '@sindresorhus/is';\nimport moo from 'moo';\nimport * as memCache from '../../../util/cache/memory/index.ts';\nimport { getEnv } from '../../../util/env.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport type { GoproxyItem } from './types.ts';\n\n/**\n * Parse `GOPROXY` to the sequence of url + fallback strategy tags.\n *\n * @example\n * parseGoproxy('foo.example.com|bar.example.com,baz.example.com')\n * // [\n * // { url: 'foo.example.com', fallback: '|' },\n * // { url: 'bar.example.com', fallback: ',' },\n * // { url: 'baz.example.com', fallback: '|' },\n * // ]\n *\n * @see https://golang.org/ref/mod#goproxy-protocol\n */\nexport function parseGoproxy(\n input: string | undefined = getEnv().GOPROXY,\n): GoproxyItem[] {\n if (!isString(input)) {\n return [];\n }\n\n const cacheKey = `goproxy::${input}`;\n const cachedResult = memCache.get<GoproxyItem[]>(cacheKey);\n if (cachedResult) {\n return cachedResult;\n }\n\n const result: GoproxyItem[] = input\n .split(regEx(/([^,|]*(?:,|\\|))/))\n .filter(isTruthy)\n .map((s) => s.split(/(
|
|
1
|
+
{"version":3,"file":"goproxy-parser.js","names":["memCache.get"],"sources":["../../../../lib/modules/datasource/go/goproxy-parser.ts"],"sourcesContent":["import { isString, isTruthy } from '@sindresorhus/is';\nimport moo from 'moo';\nimport * as memCache from '../../../util/cache/memory/index.ts';\nimport { getEnv } from '../../../util/env.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport type { GoproxyItem } from './types.ts';\n\n/**\n * Parse `GOPROXY` to the sequence of url + fallback strategy tags.\n *\n * @example\n * parseGoproxy('foo.example.com|bar.example.com,baz.example.com')\n * // [\n * // { url: 'foo.example.com', fallback: '|' },\n * // { url: 'bar.example.com', fallback: ',' },\n * // { url: 'baz.example.com', fallback: '|' },\n * // ]\n *\n * @see https://golang.org/ref/mod#goproxy-protocol\n */\nexport function parseGoproxy(\n input: string | undefined = getEnv().GOPROXY,\n): GoproxyItem[] {\n if (!isString(input)) {\n return [];\n }\n\n const cacheKey = `goproxy::${input}`;\n const cachedResult = memCache.get<GoproxyItem[]>(cacheKey);\n if (cachedResult) {\n return cachedResult;\n }\n\n const result: GoproxyItem[] = input\n .split(regEx(/([^,|]*(?:,|\\|))/))\n .filter(isTruthy)\n .map((s) => s.split(regEx(/(,|\\|)/)))\n // Empty segments (`a||b`, `,a`) carry no url to query, and keeping them\n // would apply their separator as the fallback strategy for a bogus request\n .filter(([url]) => isTruthy(url))\n .map(([url, separator]) => ({\n url,\n fallback: separator === ',' ? ',' : '|',\n }));\n\n memCache.set(cacheKey, result);\n return result;\n}\n\n// https://golang.org/pkg/path/#Match\n/* oxlint-disable renovate/require-regex-util -- moo lexer patterns must be native RegExp: moo recompiles their source with the native engine and rejects RE2 instances (TODO #12870) */\nconst noproxyLexer = moo.states({\n main: {\n separator: {\n match: /\\s*?,\\s*?/, // TODO #12870\n value: (_: string) => '|',\n },\n asterisk: {\n match: '*',\n value: (_: string) => '[^/]*',\n },\n qmark: {\n match: '?',\n value: (_: string) => '[^/]',\n },\n characterRangeOpen: {\n match: '[',\n push: 'characterRange',\n value: (_: string) => '[',\n },\n trailingSlash: {\n match: /\\/$/,\n value: (_: string) => '',\n },\n char: {\n match: /[^*?\\\\[\\n]/,\n value: (s: string) => s.replace(regEx('\\\\.', 'g'), '\\\\.'),\n },\n escapedChar: {\n match: /\\\\./, // TODO #12870\n value: (s: string) => s.slice(1),\n },\n },\n characterRange: {\n char: /[^\\\\\\]\\n]/, // TODO #12870\n escapedChar: {\n match: /\\\\./, // TODO #12870\n value: (s: string) => s.slice(1),\n },\n characterRangeEnd: {\n match: ']',\n pop: 1,\n },\n },\n});\n/* oxlint-enable renovate/require-regex-util */\n\nexport function parseNoproxy(\n input: unknown = (() => {\n const env = getEnv();\n return env.GONOPROXY ?? env.GOPRIVATE;\n })(),\n): RegExp | null {\n if (!isString(input)) {\n return null;\n }\n\n const cacheKey = `noproxy::${input}`;\n const cachedResult = memCache.get<RegExp | null>(cacheKey);\n if (cachedResult !== undefined) {\n return cachedResult;\n }\n\n const noproxyPattern = [...noproxyLexer.reset(input)]\n .map(({ value }) => value)\n .join('');\n\n const result = noproxyPattern\n ? regEx(`^(?:${noproxyPattern})(?:/.*)?$`)\n : null;\n\n memCache.set(cacheKey, result);\n return result;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,aACd,QAA4B,OAAO,CAAC,CAAC,SACtB;CACf,IAAI,CAAC,SAAS,KAAK,GACjB,OAAO,CAAC;CAGV,MAAM,WAAW,YAAY;CAC7B,MAAM,eAAeA,IAA4B,QAAQ;CACzD,IAAI,cACF,OAAO;CAGT,MAAM,SAAwB,MAC3B,MAAM,MAAM,kBAAkB,CAAC,CAAC,CAChC,OAAO,QAAQ,CAAC,CAChB,KAAK,MAAM,EAAE,MAAM,MAAM,QAAQ,CAAC,CAAC,CAAC,CAGpC,QAAQ,CAAC,SAAS,SAAS,GAAG,CAAC,CAAC,CAChC,KAAK,CAAC,KAAK,gBAAgB;EAC1B;EACA,UAAU,cAAc,MAAM,MAAM;CACtC,EAAE;CAEJ,IAAa,UAAU,MAAM;CAC7B,OAAO;AACT;AAIA,MAAM,eAAe,IAAI,OAAO;CAC9B,MAAM;EACJ,WAAW;GACT,OAAO;GACP,QAAQ,MAAc;EACxB;EACA,UAAU;GACR,OAAO;GACP,QAAQ,MAAc;EACxB;EACA,OAAO;GACL,OAAO;GACP,QAAQ,MAAc;EACxB;EACA,oBAAoB;GAClB,OAAO;GACP,MAAM;GACN,QAAQ,MAAc;EACxB;EACA,eAAe;GACb,OAAO;GACP,QAAQ,MAAc;EACxB;EACA,MAAM;GACJ,OAAO;GACP,QAAQ,MAAc,EAAE,QAAQ,MAAM,OAAO,GAAG,GAAG,KAAK;EAC1D;EACA,aAAa;GACX,OAAO;GACP,QAAQ,MAAc,EAAE,MAAM,CAAC;EACjC;CACF;CACA,gBAAgB;EACd,MAAM;EACN,aAAa;GACX,OAAO;GACP,QAAQ,MAAc,EAAE,MAAM,CAAC;EACjC;EACA,mBAAmB;GACjB,OAAO;GACP,KAAK;EACP;CACF;AACF,CAAC;AAGD,SAAgB,aACd,eAAwB;CACtB,MAAM,MAAM,OAAO;CACnB,OAAO,IAAI,aAAa,IAAI;AAC9B,EAAA,CAAG,GACY;CACf,IAAI,CAAC,SAAS,KAAK,GACjB,OAAO;CAGT,MAAM,WAAW,YAAY;CAC7B,MAAM,eAAeA,IAA4B,QAAQ;CACzD,IAAI,iBAAiB,KAAA,GACnB,OAAO;CAGT,MAAM,iBAAiB,CAAC,GAAG,aAAa,MAAM,KAAK,CAAC,CAAC,CAClD,KAAK,EAAE,YAAY,KAAK,CAAC,CACzB,KAAK,EAAE;CAEV,MAAM,SAAS,iBACX,MAAM,OAAO,eAAe,WAAW,IACvC;CAEJ,IAAa,UAAU,MAAM;CAC7B,OAAO;AACT"}
|
|
@@ -61,13 +61,13 @@ var HexpmBobDatasource = class HexpmBobDatasource extends Datasource {
|
|
|
61
61
|
}
|
|
62
62
|
static getPackageType(packageName) {
|
|
63
63
|
if (packageName === "elixir") return "elixir";
|
|
64
|
-
if (/^otp\/\w+-\d+\.\d
|
|
64
|
+
if (regEx(/^otp\/\w+-\d+\.\d+$/).test(packageName)) return "erlang";
|
|
65
65
|
return null;
|
|
66
66
|
}
|
|
67
67
|
static cleanVersion(version, packageType) {
|
|
68
68
|
switch (packageType) {
|
|
69
|
-
case "elixir": return version.replace(/^v
|
|
70
|
-
case "erlang": return version.replace(/^OTP
|
|
69
|
+
case "elixir": return version.replace(regEx(/^v/), "");
|
|
70
|
+
case "erlang": return version.replace(regEx(/^OTP-/), "");
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
static isStable(version, packageType) {
|
|
@@ -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 { withCache } from '../../../util/cache/package/with-cache.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 readonly customRegistrySupport = true;\n\n override readonly defaultRegistryUrls = [defaultRegistryUrl];\n\n override readonly caching = true;\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 _getReleases({\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.response?.statusCode !== 404) {\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 withCache(\n {\n namespace: `datasource-${datasource}`,\n key: `${config.registryUrl}:${config.packageName}`,\n fallback: true,\n },\n () => this._getReleases(config),\n );\n }\n\n private static getPackageType(packageName: string): PackageType | null {\n if (packageName === 'elixir') {\n return 'elixir';\n }\n if (/^otp\\/\\w+-\\d+\\.\\d
|
|
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 { withCache } from '../../../util/cache/package/with-cache.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 readonly customRegistrySupport = true;\n\n override readonly defaultRegistryUrls = [defaultRegistryUrl];\n\n override readonly caching = true;\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 _getReleases({\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.response?.statusCode !== 404) {\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 withCache(\n {\n namespace: `datasource-${datasource}`,\n key: `${config.registryUrl}:${config.packageName}`,\n fallback: true,\n },\n () => this._getReleases(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":";;;;;;;;;;;;AAaA,IAAa,qBAAb,MAAa,2BAA2B,WAAW;CACjD,OAAgB,KAAK;CAErB,cAAc;EACZ,MAAM,UAAU;CAClB;CAEA,wBAA0C;CAE1C,sBAAwC,CAAC,kBAAkB;CAE3D,UAA4B;CAE5B,oBAAsCA;CAEtC,0BAA4C;CAC5C,uBACE;CACF,mBAAqC;CACrC,gBACE;CAEF,MAAc,aAAa,EACzB,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,IAAI,UAAU,eAAe,KAC3D,MAAM,IAAI,kBAAkB,GAAG;GAEjC,KAAK,oBAAoB,GAAG;EAC9B;EAEA,OAAO,OAAO,SAAS,SAAS,IAAI,SAAS;CAC/C;CAEA,YAAY,QAA0D;EACpE,OAAO,UACL;GACE,WAAW,cAAc;GACzB,KAAK,GAAG,OAAO,YAAY,GAAG,OAAO;GACrC,UAAU;EACZ,SACM,KAAK,aAAa,MAAM,CAChC;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,yBAAyB,CAAC,CAAC,KAAK,OAAO;GACtD,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"}
|
|
@@ -304,7 +304,7 @@ async function getDependencyInfo(http, dependency, repoUrl, version, recursionLi
|
|
|
304
304
|
"groupId",
|
|
305
305
|
"artifactId",
|
|
306
306
|
"version"
|
|
307
|
-
].map((k) => parent.valueWithPath(k)?.replace(/\s+/g, ""));
|
|
307
|
+
].map((k) => parent.valueWithPath(k)?.replace(regEx(/\s+/g), ""));
|
|
308
308
|
if (parentGroupId && parentArtifactId && parentVersion) {
|
|
309
309
|
const parentInformation = await getDependencyInfo(http, getDependencyParts(`${parentGroupId}:${parentArtifactId}`), repoUrl, parentVersion, recursionLimit - 1);
|
|
310
310
|
if (!result.sourceUrl && parentInformation.sourceUrl) result.sourceUrl = parentInformation.sourceUrl;
|