Skip to content

Commit e0ce9da

Browse files
jamietannaClaude Sonnet 4.6
andauthored
docs: prefix child options with their parent (renovatebot#41828)
This also makes sure that our URL fragments should be more consistent over the years, as duplicate names (across parent and child options) cannot clash. This also corrects links from the code to include the new fragment. Co-authored-by: Claude Sonnet 4.6 <jamie.tanna+claude-code@mend.io>
1 parent 6432d21 commit e0ce9da

File tree

10 files changed

+201
-161
lines changed

10 files changed

+201
-161
lines changed

docs/usage/configuration-options.md

Lines changed: 130 additions & 124 deletions
Large diffs are not rendered by default.

docs/usage/key-concepts/changelogs.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Set to `off` if changelog fetching is causing a problem.
3434

3535
Set to `branch` if you have an advanced use case where you're embedding changelogs in the Git commit itself, we don't recommend this due to its potential size.
3636

37-
### [`changelogUrl`](../configuration-options.md#changelogurl)
37+
### [`changelogUrl`](../configuration-options.md#packageruleschangelogurl)
3838

3939
This doesn't help with _fetching_ the changelogs, but if you configure it then Renovate will include a link to this URL in the PR body, so users can click through to read the changelog.
4040

docs/usage/self-hosted-configuration.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1041,7 +1041,7 @@ If you use the Mend Renovate Enterprise Edition (Renovate EE) and:
10411041

10421042
Then you must set this variable at the _server_ and the _workers_.
10431043

1044-
But if you have specified the token as a [`matchConfidence`](configuration-options.md#matchconfidence) `packageRule`, you only need to set this variable at the _workers_.
1044+
But if you have specified the token as a [`matchConfidence`](configuration-options.md#packagerulesmatchconfidence) `packageRule`, you only need to set this variable at the _workers_.
10451045

10461046
This feature is in private beta.
10471047

lib/data/readme.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ If this does not happen, for whatever reason, Renovate can not show the changelo
7777

7878
You can use these config options to let Renovate find the correct changelog:
7979

80-
- [`changelogUrl`](https://docs.renovatebot.com/configuration-options/#changelogurl)
80+
- [`changelogUrl`](https://docs.renovatebot.com/configuration-options/#packageruleschangelogurl)
8181

8282
Read the [Renovate docs, key concepts page for changelogs](https://docs.renovatebot.com/key-concepts/changelogs/) to learn more about how Renovate fetches and displays changelogs.
8383

@@ -105,7 +105,7 @@ To check if Renovate can find the source URLs for your package:
105105
1. Read the Renovate docs for the datasource.
106106
1. Look for a table in the docs that shows if the datasource returns source URLs.
107107

108-
If Renovate does not find the right source URls automatically: use the [`sourceUrl` config option](https://docs.renovatebot.com/configuration-options/#sourceurl).
108+
If Renovate does not find the right source URls automatically: use the [`sourceUrl` config option](https://docs.renovatebot.com/configuration-options/#packagerulessourceurl).
109109

110110
To locate the source repository, Renovate requires:
111111

lib/modules/manager/custom/jsonata/readme.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@ The first two required fields are `managerFilePatterns` and `matchStrings`:
2323

2424
Before Renovate can look up a dependency and decide about updates, it must have this info about each dependency:
2525

26-
| Info type | Required | Notes | Docs |
27-
| :--------------------------------------------------- | :------- | :-------------------------------------------------------- | :----------------------------------------------------------------------------- |
28-
| Name of the dependency | Yes | | |
29-
| `datasource` | Yes | Example datasources: npm, Docker, GitHub tags, and so on. | [Supported datasources](../../datasource/index.md#supported-datasources) |
30-
| Version scheme to use. Defaults to `semver-coerced`. | Yes | You may set another version scheme, like `pep440`. | [Supported versioning schemes](../../versioning/index.md#supported-versioning) |
31-
| `fileFormat` | Yes | Must be either `json`, `yaml` or `toml`. | [`Configuration Options`](../../../configuration-options.md#fileformat) |
26+
| Info type | Required | Notes | Docs |
27+
| :--------------------------------------------------- | :------- | :-------------------------------------------------------- | :------------------------------------------------------------------------------------ |
28+
| Name of the dependency | Yes | | |
29+
| `datasource` | Yes | Example datasources: npm, Docker, GitHub tags, and so on. | [Supported datasources](../../datasource/index.md#supported-datasources) |
30+
| Version scheme to use. Defaults to `semver-coerced`. | Yes | You may set another version scheme, like `pep440`. | [Supported versioning schemes](../../versioning/index.md#supported-versioning) |
31+
| `fileFormat` | Yes | Must be either `json`, `yaml` or `toml`. | [`Configuration Options`](../../../configuration-options.md#custommanagersfileformat) |
3232

3333
#### Required fields to be present in the resulting structure returned by the jsonata query
3434

lib/util/package-rules/index.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -764,7 +764,7 @@ describe('util/package-rules/index', () => {
764764
expect(error).toMatchObject(new Error(MISSING_API_CREDENTIALS));
765765
expect(error.validationError).toBe('Missing credentials');
766766
expect(error.validationMessage).toBe(
767-
'The `matchConfidence` matcher in `packageRules` requires authentication. Please refer to the [documentation](https://docs.renovatebot.com/configuration-options/#matchconfidence) and add the required host rule.',
767+
'The `matchConfidence` matcher in `packageRules` requires authentication. Please refer to the [documentation](https://docs.renovatebot.com/configuration-options/#packagerulesmatchconfidence) and add the required host rule.',
768768
);
769769
});
770770
});

lib/util/package-rules/merge-confidence.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export class MergeConfidenceMatcher extends Matcher {
2929
error.validationSource = 'MatchConfidence Authenticator';
3030
error.validationError = 'Missing credentials';
3131
error.validationMessage =
32-
'The `matchConfidence` matcher in `packageRules` requires authentication. Please refer to the [documentation](https://docs.renovatebot.com/configuration-options/#matchconfidence) and add the required host rule.';
32+
'The `matchConfidence` matcher in `packageRules` requires authentication. Please refer to the [documentation](https://docs.renovatebot.com/configuration-options/#packagerulesmatchconfidence) and add the required host rule.';
3333
throw error;
3434
}
3535

test/docs/documentation.spec.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ describe('docs/documentation', () => {
2929
const content = await fs.readFile(`docs/usage/${file}`, 'utf8');
3030
const reg = regEx(`##\\s${configOption}[\\s\\S]+?\n##\\s`);
3131
const match = reg.exec(content);
32-
const subHeadersMatch = match?.[0]?.matchAll(/\n###\s(?<child>\w+)\n/g);
32+
const subHeadersMatch = match?.[0]?.matchAll(
33+
/\n###\s(?<child>[\w.]+)\n/g,
34+
);
3335
if (subHeadersMatch) {
3436
for (const subHeaderStr of subHeadersMatch) {
3537
if (subHeaderStr?.groups?.child) {
@@ -86,10 +88,15 @@ describe('docs/documentation', () => {
8688
.filter((option) => option.stage !== 'global')
8789
.filter((option) => !option.globalOnly)
8890
.filter((option) => option.parents)
89-
.map((option) => option.name)
9091
.filter(
91-
(header) =>
92-
header !== 'managerFilePatterns' && header !== 'enabled',
92+
(option) =>
93+
option.name !== 'managerFilePatterns' &&
94+
option.name !== 'enabled',
95+
)
96+
.flatMap((option) =>
97+
(option.parents ?? [])
98+
.filter((parent) => parent !== '.')
99+
.map((parent) => `${parent}.${option.name}`),
93100
)
94101
.sort();
95102
}

tools/docs/config.ts

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -294,32 +294,48 @@ export async function generateConfig(dist: string, bot = false): Promise<void> {
294294
// TODO: fix types (#22198,#9610)
295295
const el: Record<string, any> = { ...option };
296296

297-
if (!indexed[option.name]) {
298-
throw new Error(
299-
`Config option "${option.name}" is missing an entry in ${configFile}`,
300-
);
297+
// Child options are indexed as "parent.optionName"; collect all matching keys
298+
let lookupKeys: string[] = [];
299+
for (const parent of option.parents ?? []) {
300+
if (parent !== '.') {
301+
const key = `${parent}.${option.name}`;
302+
if (indexed[key]) {
303+
lookupKeys.push(key);
304+
}
305+
}
306+
}
307+
// Fall back to plain name for top-level ## options (e.g. enabled, managerFilePatterns)
308+
if (lookupKeys.length === 0) {
309+
if (!indexed[option.name]) {
310+
throw new Error(
311+
`Config option "${option.name}" is missing an entry in ${configFile}`,
312+
);
313+
}
314+
lookupKeys = [option.name];
301315
}
302-
303-
const [headerIndex, footerIndex] = indexed[option.name];
304316

305317
el.cli = getCliName(option);
306318
el.env = getEnvName(option);
307319
stringifyArrays(el);
308320

309-
configOptionsRaw[headerIndex] +=
310-
`\n${option.description}\n\n` +
311-
genTable(Object.entries(el), option.type, option.default);
321+
for (const key of lookupKeys) {
322+
const [headerIndex, footerIndex] = indexed[key];
312323

313-
if (el.advancedUse) {
314-
configOptionsRaw[headerIndex] += generateAdvancedUse();
315-
}
324+
configOptionsRaw[headerIndex] +=
325+
`\n${option.description}\n\n` +
326+
genTable(Object.entries(el), option.type, option.default);
316327

317-
if (el.experimental) {
318-
configOptionsRaw[footerIndex] += genExperimentalMsg(el);
319-
}
328+
if (el.advancedUse) {
329+
configOptionsRaw[headerIndex] += generateAdvancedUse();
330+
}
320331

321-
if (is.nonEmptyString(el.deprecationMsg)) {
322-
configOptionsRaw[footerIndex] += genDeprecationMsg(el);
332+
if (el.experimental) {
333+
configOptionsRaw[footerIndex] += genExperimentalMsg(el);
334+
}
335+
336+
if (is.nonEmptyString(el.deprecationMsg)) {
337+
configOptionsRaw[footerIndex] += genDeprecationMsg(el);
338+
}
323339
}
324340
});
325341

tools/docs/templates.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { getOptions } from '../../lib/config/options/index.ts';
12
import {
23
allowedFields,
34
exposedConfigOptions,
@@ -6,13 +7,23 @@ import { readFile, updateFile } from '../utils/index.ts';
67
import { replaceContent } from './utils.ts';
78

89
export async function generateTemplates(dist: string): Promise<void> {
10+
const options = getOptions();
11+
const optionParentMap = new Map(
12+
options
13+
.filter((o) => o.parents?.length)
14+
.map((o) => [o.name, o.parents![0]]),
15+
);
16+
917
let exposedConfigOptionsText =
1018
'The following configuration options are passed through for templating: \n';
1119
exposedConfigOptionsText += exposedConfigOptions
12-
.map(
13-
(field) =>
14-
` - [${field}](configuration-options.md#${field.toLowerCase()})`,
15-
)
20+
.map((field) => {
21+
const parent = optionParentMap.get(field);
22+
const anchor = parent
23+
? `${parent}${field}`.toLowerCase()
24+
: field.toLowerCase();
25+
return ` - [${field}](configuration-options.md#${anchor})`;
26+
})
1627
.join('\n');
1728

1829
let runtimeText =

0 commit comments

Comments
 (0)