Skip to content

Commit 2f8bc73

Browse files
jamietannaClaude Sonnet 4.6
andauthored
fix(validation): validate installTools (#42838)
* test(validation): validate `installTools` aren't validated Co-authored-by: Claude Sonnet 4.6 <jamie.tanna+claude-code@mend.io> * fix(validation): validate `installTools` As we have a strong type for our `ToolName`s, we should make sure that we now validate the `installTools`. We'll start with a warning for now, and at some point promote it to an error in the future. Co-authored-by: Claude Sonnet 4.6 <jamie.tanna+claude-code@mend.io> --------- Co-authored-by: Claude Sonnet 4.6 <jamie.tanna+claude-code@mend.io>
1 parent 45d36dc commit 2f8bc73

2 files changed

Lines changed: 52 additions & 0 deletions

File tree

lib/config/validation.spec.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2352,6 +2352,48 @@ describe('config/validation', () => {
23522352
);
23532353
});
23542354

2355+
it('validates postUpgradeTasks.installTools tool names', async () => {
2356+
const config = {
2357+
postUpgradeTasks: {
2358+
executionMode: 'update' as const,
2359+
installTools: {
2360+
npm: {},
2361+
node: {},
2362+
},
2363+
},
2364+
};
2365+
const { warnings, errors } = await configValidation.validateConfig(
2366+
'global',
2367+
config,
2368+
);
2369+
expect(warnings).toHaveLength(0);
2370+
expect(errors).toHaveLength(0);
2371+
});
2372+
2373+
it('rejects invalid postUpgradeTasks.installTools tool names', async () => {
2374+
const config = {
2375+
postUpgradeTasks: {
2376+
installTools: {
2377+
npm: {},
2378+
unknownTool: {},
2379+
},
2380+
},
2381+
};
2382+
const { warnings, errors } = await configValidation.validateConfig(
2383+
'global',
2384+
// @ts-expect-error: installTools.unknownTool is not a valid tool
2385+
config,
2386+
);
2387+
expect(warnings).toMatchObject([
2388+
{
2389+
topic: 'Configuration Error',
2390+
message:
2391+
'Invalid `postUpgradeTasks.installTools.unknownTool` configuration: not a valid tool name.',
2392+
},
2393+
]);
2394+
expect(errors).toHaveLength(0);
2395+
});
2396+
23552397
it('catches when * or ** is combined with others patterns in a regexOrGlob option', async () => {
23562398
const config = {
23572399
packageRules: [

lib/config/validation.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { isCustomManager } from '../modules/manager/custom/index.ts';
1313
import type { CustomManager } from '../modules/manager/custom/types.ts';
1414
import { allManagersList, getManagerList } from '../modules/manager/index.ts';
1515
import type { HostRule } from '../types/index.ts';
16+
import { isToolName } from '../util/exec/types.ts';
1617
import { getExpression } from '../util/jsonata.ts';
1718
import { regEx } from '../util/regex.ts';
1819
import {
@@ -751,6 +752,15 @@ export async function validateConfig(
751752
}
752753
}
753754
}
755+
} else if (key === 'installTools') {
756+
for (const toolName of Object.keys(val)) {
757+
if (!isToolName(toolName)) {
758+
warnings.push({
759+
topic: 'Configuration Error',
760+
message: `Invalid \`${currentPath}.${toolName}\` configuration: not a valid tool name.`,
761+
});
762+
}
763+
}
754764
} else {
755765
const ignoredObjects = options
756766
.filter((option) => option.freeChoice)

0 commit comments

Comments
 (0)