* test(versioning/aws-machine-image): cover the empty version guard
`_parse()` returns null for a falsy version before it tries the AMI id
regex, and no test passed one. Checking that an empty string is not
valid closes the only branch the module was missing.
Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io>
* test(datasource/buildpacks-registry): cover a response without a homepage
`latest.homepage` is optional in the registry response, but every test
supplied one, so the release result was never built without it. A
buildpack whose latest entry carries no homepage now checks that the
releases still come back and no source url is derived.
Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io>
* test(datasource): cover optional-field branches in four datasources
Each of these datasources builds its release result by attaching fields
only when the registry supplies them, and the "not supplied" path was
never exercised:
- cdnjs: a library with neither homepage nor repository
- cpan: a search result where no release is marked latest, so no tag
- dart: a latest release carrying no pubspec
- ruby-version: a release table row whose first column is not a version
Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io>
* test(datasource): cover missing-metadata branches in hex and pypi
Two more datasources only attached fields when the registry supplied
them, and the absent case was untested: a hex package with neither an
html_url nor a github link in its meta, and a pypi response carrying no
releases at all.
Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io>
* test(datasource): cover galaxy and repology fallbacks, mark unreachable guards
Adds a galaxy role with empty github fields, so no source url is
derived, and a repology lookup where the api fallback after a 403 finds
no matching package.
Marks four guards that are not worth a test: cpan and dart both check a
variable that is only null when the request threw, and
`handleGenericErrors()` always rethrows; conan's registry url is always
supplied by the datasource layer; and repology's resolver either returns
a body or throws.
Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io>
* test(datasource): cover pod CDN branches, mark the sbt listing guards
Adds two pod lookups: an empty CDN body, and a CDN index that lists no
matching pod.
Marks the guards whose tests would need multi-level directory listing
fixtures: both sbt datasources walk nested index pages, and pod's github
helper checks a body that an empty json response never produces because
parsing throws first.
Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io>
* test(datasource): cover maven metadata without a latest tag
Adds maven metadata carrying a release but no latest, so respectLatest
is left alone. Marks the three deb guards, which would each need a
crafted package index: a block missing a required key, a repeated
package in the final block, and two component indexes whose meta agrees.
Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io>
* test(datasource): cover npmrc registry fallback, mark cache-bound guards
Adds a resolveRegistryUrl lookup for a package no npmrc rule matches.
Marks the guards whose tests would need a primed cache or a specific
blob shape: nuget's services index, deno's release cache, the docker hub
cache window, docker's manifest and config handling, go's pseudo-version
fallback, and both rubygems cache layers.
Three implicit elses are left counted: a coverage-ignore hint does not
attach to an `else if`, so the registry strategy chain, the npmrc reset
and docker's digest-header branch carry a plain note instead.
Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io>
* fix(datasource/repology): pass the mock body as a string
`ResponseMock.body` is typed as a string, and every other call in the
spec passes `'[]'`. The new api fallback test passed an array literal,
which tsc rejected.
Co-Authored-By: Claude Opus 5 <michael.kriese+claude-code@mend.io>
---------
Co-authored-by: Claude Opus 5 <michael.kriese+claude-code@mend.io>
* test: reduce oversized expectation literals to representative examples
* test: shrink oversized fixtures instead of trimming assertions
Cut the real-world fixtures down to a representative set of entries that still covers every parser shape, and assert the complete output again with a single toEqual.
Adds a custom oxlint rule renovate/v8-ignore-no-count that flags the
count form '/* v8 ignore next <N> */'. The count is not honored by
vitest's ast-v8-to-istanbul hint parser, which captures only the
keyword (if/else/next/file); 'next' always exempts exactly the next
AST node. Trailing counts therefore suggest a line range that is never
applied and mislead readers.
The rule is autofixable (drops the count, preserving actual behavior)
and has been applied to all existing occurrences.
* refactor(oxlint): enable func-style
Enable the built-in func-style rule as ["warn", "declaration"] so that
named functions are written as function declarations instead of arrow or
function expressions assigned to variables, matching the convention in
docs/development/best-practices.md (Functions section). Inline arrow
callbacks are unaffected; prefer-arrow-callback continues to cover the
callback direction.
Severity is "warn" instead of "error" as a fallback: a repo-wide run
found 196 pre-existing violations (70 in spec files, 126 in production
code), exceeding the 80-violation fix threshold for this change, so no
violations were fixed here. Follow-up work can convert the offenders
(largest clusters: lib/modules/versioning/ruby, lib/util/cache/package,
lib/modules/versioning/maven, lib/modules/versioning/gradle) and then
raise the rule to "error". Note oxlint 1.72 also supports an
allowTypeAnnotation option if typed consts should remain arrows.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* ci(linter): enforce func-style at error
* refactor(func-style): convert const-arrow functions to declarations in with-cache spec and ruby versioning
* refactor(func-style): convert const-arrow functions to declarations in maven/gradle modules
* refactor(func-style): convert const-arrow functions to declarations in remaining versioning modules
* refactor(func-style): convert const-arrow functions to declarations in platform modules
Discriminated-union closures (ensureCommentRemoval byTopic/byContent
helpers in github, gitlab, bitbucket, bitbucket-server) needed the
narrowed field passed explicitly as a parameter, since function
declarations are hoisted and lose the outer if-narrowing that inline
arrow-function closures previously relied on.
* refactor(func-style): convert const-arrow functions to declarations across util/manager/datasource modules
One case (logger/renovate-logger.ts logOnceFn) is kept as an arrow
function with a documented oxlint-disable: it is stored on
this.logger.once[level] and relies on lexically-bound this, which a
hoisted function declaration would not preserve.
* refactor(func-style): convert remaining const-arrow test helpers to declarations
get-updated.spec.ts: hoisted expectPipCompilePackageAndLockFile to
module scope (it only closes over the module-level pipCompile mock)
and added a documented oxlint-disable for vitest/expect-expect on its
caller test, since oxlint's expect-expect check does not trace
assertions through an externally-defined helper function.
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* docs: skip validation on JSON files that aren't Renovate config
As part of future changes, we'll enable validation on all JSON code
snippets to run Config Validation.
Before we do that, we should opt-out JSON snippets that aren't anything
related to Renovate config.
* docs: don't validate invalid Renovate config
As it's intentionally referencing a manager that doesn't exist.
* docs: don't validate partial Renovate config
As part of future changes, we'll enable validation on all JSON code
snippets to run Config Validation.
There are several code snippets we have that are part of a Renovate JSON,
but it doesn't make sense to convert these to a fully passing config, as
it'd reduce clarity on what we're trying to explain.
* docs: convert `baseBranchPatterns` snippets to code blocks
So we can validate them.
* docs: make sure that `datasourceTemplate` is set
So this passes validation.
* docs: clarify that `force` is global config
As it may not be clear, so we can make it extra clear with a `.js` file,
and note that it's global self-hosted config.
* docs: make sure `packageRules` is an array
* docs: `matchBaseBranches` needs `baseBranchPatterns` to be set
* docs: correct typo for `prBodyColumns`
* docs: mark global config snippets as such
As part of future changes, we'll use this to detect whether it's global
self-hosted configuration.
* docs: make sure `packageRules` wraps its children
* docs: add `allowedHeaders`
* docs: ignore deprecation warnings
As part of future changes, we'll use this to note that we don't care
about the validation warnings.
* docs: make sure `customManagers` wraps its children
* docs: make sure `fleet` wraps its children
* docs: validate JSON snippets are valid Renovate config
To make sure that we're always presenting valid JSON configuration to
our users, we can validate them as part of `check-fenced-code`.
As well as configuration errors we can warn for warnings, but allow code
blocks to opt-out, for instance when there's a known deprecation
affecting the code block.
We need to make sure to set `allowedEnv` for various code snippets that
reference environment variables.
* docs(development): document fenced code block checks
* docs: wrap `configType` and `ignoreConfigWarnings` in `{ ... }`
As otherwise we see build failures i.e.
WARNING - Doc file 'modules/platform/gitlab/index.md' contains a link
'../../../self-hosted-configuration.md#autodiscoverrepoorder', but the doc
'self-hosted-configuration.md' does not contain an anchor '#autodiscoverrepoorder'.
This needs to be wrapped alongside all other options like `title`.
* fixup! docs: wrap `configType` and `ignoreConfigWarnings` in `{ ... }`
* fix(sbt): consider html hrefs in absolute and root-relative format
* Use .at(-1) instead of .reverse()[0]
Co-authored-by: Michael Kriese <michael.kriese@gmx.de>
* Use non-null assertion
---------
Co-authored-by: Michael Kriese <michael.kriese@gmx.de>
Renames `lookupName` to be `packageName`.
BREAKING CHANGE: Use `packageName` instead of `lookupName` if interacting with Renovate datasources directly.
Moves datasource, manager, platform and versioning code from lib/ into new lib/modules/
BREAKING CHANGE: External tools must update paths to datasource, manager, platform and versioning