Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions lib/config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import type {
SkipReason,
} from '../types/index.ts';
import type { StageName } from '../types/skip-reason.ts';
import type { ConstraintName, ToolName } from '../util/exec/types.ts';
import type { GitNoVerifyOption } from '../util/git/types.ts';
import type { MergeConfidence } from '../util/merge-confidence/types.ts';
import type { Timestamp } from '../util/timestamp.ts';
Expand Down Expand Up @@ -305,7 +306,7 @@ export interface PostUpgradeTasks {
dataFileTemplate?: string;
fileFilters?: string[];
executionMode: ExecutionMode;
installTools?: Record<string, Record<never, never>>;
installTools?: Partial<Record<ToolName, Record<never, never>>>;
}

export type UpdateConfig<
Expand Down Expand Up @@ -451,7 +452,7 @@ export interface RenovateConfig
secrets?: Record<string, string>;
variables?: Record<string, string>;

constraints?: Record<string, string>;
constraints?: Partial<Record<ConstraintName, string>>;
skipInstalls?: boolean | null;

constraintsFiltering?: ConstraintsFilter;
Expand Down
19 changes: 16 additions & 3 deletions lib/modules/datasource/common.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,20 @@ describe('modules/datasource/common', () => {
};
const releaseResult: ReleaseResult = {
releases: [
{ version: '1.0.0', constraints: { foo: ['^1.0.0'] } },
{ version: '2.0.0', constraints: { foo: ['^2.0.0'] } },
{
version: '1.0.0',
constraints: {
// @ts-expect-error -- intentionally using invalid constraint names
foo: ['^1.0.0'],
},
},
{
version: '2.0.0',
constraints: {
// @ts-expect-error -- intentionally using invalid constraint names
foo: ['^2.0.0'],
},
},
],
};
expect(applyConstraintsFiltering(releaseResult, config)).toEqual({
Expand All @@ -218,7 +230,7 @@ describe('modules/datasource/common', () => {
datasource: 'foo',
packageName: 'bar',
constraintsFiltering: 'strict' as const,
constraints: { baz: '^1.0.0', qux: 'invalid' },
constraints: { baz: '^1.0.0', qux: 'invalid' } as never,
};
const releaseResult = {
releases: [
Expand All @@ -227,6 +239,7 @@ describe('modules/datasource/common', () => {
{ version: '3.0.0', constraints: { baz: ['^0.9.0', 'invalid'] } },
],
};
// @ts-expect-error -- intentionally using invalid constraint names
expect(applyConstraintsFiltering(releaseResult, config)).toEqual({
releases: [{ version: '1.0.0' }, { version: '2.0.0' }],
});
Expand Down
5 changes: 4 additions & 1 deletion lib/modules/datasource/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
isNonEmptyStringAndNotWhitespace,
} from '@sindresorhus/is';
import { logger } from '../../logger/index.ts';
import type { ConstraintName } from '../../util/exec/types.ts';
import { filterMap } from '../../util/filter-map.ts';
import { regEx } from '../../util/regex.ts';
import * as allVersioning from '../versioning/index.ts';
Expand Down Expand Up @@ -193,7 +194,9 @@ export function applyConstraintsFiltering<
return release;
}

for (const [name, configConstraint] of Object.entries(configConstraints)) {
for (const [name, configConstraint] of Object.entries(
configConstraints,
) as [ConstraintName, string][]) {
if (!versioning.isValid(configConstraint)) {
logger.once.warn(
{
Expand Down
7 changes: 4 additions & 3 deletions lib/modules/datasource/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type {
CustomDatasourceConfig,
} from '../../config/types.ts';
import type { ModuleApi } from '../../types/index.ts';
import type { ConstraintName } from '../../util/exec/types.ts';
import type { Timestamp } from '../../util/timestamp.ts';

export interface GetDigestInputConfig {
Expand Down Expand Up @@ -32,7 +33,7 @@ export interface GetReleasesConfig {
packageName: string;
registryUrl?: string;
currentValue?: string;
constraints?: Record<string, string>;
constraints?: Partial<Record<ConstraintName, string>>;
constraintsFiltering?: ConstraintsFilter;
}

Expand All @@ -49,7 +50,7 @@ export interface GetPkgReleasesConfig {
extractVersion?: string;
versionCompatibility?: string;
currentCompatibility?: string;
constraints?: Record<string, string>;
constraints?: Partial<Record<ConstraintName, string>>;
replacementName?: string;
replacementVersion?: string;
constraintsFiltering?: ConstraintsFilter;
Expand All @@ -69,7 +70,7 @@ export interface Release {
/** The original value to which `extractVersion` was applied */
versionOrig?: string;
newDigest?: string | null;
constraints?: Record<string, string[]>;
constraints?: Partial<Record<ConstraintName, string[]>>;
dependencies?: Record<string, string>;
devDependencies?: Record<string, string>;
registryUrl?: string;
Expand Down
5 changes: 3 additions & 2 deletions lib/modules/manager/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import type {
SkipReason,
StageName,
} from '../../types/index.ts';
import type { ConstraintName } from '../../util/exec/types.ts';
import type { FileChange } from '../../util/git/types.ts';
import type { MergeConfidence } from '../../util/merge-confidence/types.ts';
import type { Timestamp } from '../../util/timestamp.ts';
Expand All @@ -35,7 +36,7 @@ export interface ExtractConfig extends CustomExtractConfig {

export interface UpdateArtifactsConfig {
isLockFileMaintenance?: boolean;
constraints?: Record<string, string>;
constraints?: Partial<Record<ConstraintName, string>>;
composerIgnorePlatformReqs?: string[];
goGetDirs?: string[];
currentValue?: string;
Expand Down Expand Up @@ -373,7 +374,7 @@ export type ManagerApi = ManagerApiBase &
export interface PostUpdateConfig<T = Record<string, any>>
extends Record<string, any>, ManagerData<T> {
// TODO: remove null
constraints?: Record<string, string> | null;
constraints?: Partial<Record<ConstraintName, string>> | null;
updatedPackageFiles?: FileChange[];
postUpdateOptions?: string[];
skipArtifactsUpdate?: boolean;
Expand Down
9 changes: 5 additions & 4 deletions lib/util/exec/containerbase.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
isDynamicInstall,
resolveConstraint,
} from './containerbase.ts';
import type { ToolConstraint } from './types.ts';
import type { ToolConstraint, ToolName } from './types.ts';

vi.mock('../../modules/datasource/index.ts');

Expand All @@ -32,6 +32,7 @@ describe('util/exec/containerbase', () => {
process.env.CONTAINERBASE = 'true';
const toolConstraints: ToolConstraint[] = [
{ toolName: 'node' },
// @ts-expect-error -- intentionally using invalid constraint names
{ toolName: 'invalid' },
];
expect(isDynamicInstall(toolConstraints)).toBeFalse();
Expand Down Expand Up @@ -107,9 +108,9 @@ describe('util/exec/containerbase', () => {
});

it('throws for unknown tools', async () => {
await expect(resolveConstraint({ toolName: 'whoops' })).rejects.toThrow(
'Invalid tool to install: whoops',
);
await expect(
resolveConstraint({ toolName: 'whoops' as ToolName }),
).rejects.toThrow('Invalid tool to install: whoops');
});

it('throws no releases', async () => {
Expand Down
6 changes: 3 additions & 3 deletions lib/util/exec/containerbase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ import { id as rubyVersioningId } from '../../modules/versioning/ruby/index.ts';
import { id as semverVersioningId } from '../../modules/versioning/semver/index.ts';
import { id as semverCoercedVersioningId } from '../../modules/versioning/semver-coerced/index.ts';
import { getEnv } from '../env.ts';
import type { Opt, ToolConfig, ToolConstraint } from './types.ts';
import type { Opt, ToolConfig, ToolConstraint, ToolName } from './types.ts';

const allToolConfig: Record<string, ToolConfig> = {
const allToolConfig: Record<ToolName, ToolConfig> = {
bazelisk: {
datasource: 'github-releases',
packageName: 'bazelbuild/bazelisk',
Expand Down Expand Up @@ -252,7 +252,7 @@ async function getPkgReleases(
return getPkgReleases(toolConfig);
}

export function supportsDynamicInstall(toolName: string): boolean {
export function supportsDynamicInstall(toolName: ToolName): boolean {
return !!allToolConfig[toolName];
}

Expand Down
122 changes: 121 additions & 1 deletion lib/util/exec/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,127 @@
import { isString } from '@sindresorhus/is';
import type { Options as ExecaOptions } from 'execa';

/**
* A `tool` that Containerbase supports.
*
* TODO #41849 replace with upstream types
*/
const toolNames = [
'bazelisk',
'bun',
'bundler',
'cocoapods',
'composer',
'conan',
'copier',
'corepack',
'devbox',
'dotnet',
'erlang',
'elixir',
'flux',
'gleam',
'golang',
'gradle',
'hashin',
'helm',
'helmfile',
'java',
'java-maven',
'jb',
'kustomize',
'maven',
'nix',
'node',
'npm',
'pdm',
'php',
'pip-tools',
'pipenv',
'pnpm',
'pixi',
'poetry',
'python',
'ruby',
'rust',
'uv',
'yarn',
'yarn-slim',
'dart',
'flutter',
'vendir',
] as const;

export type ToolName = (typeof toolNames)[number];

export function isToolName(value: unknown): value is ToolName {
return isString(value) && toolNames.includes(value as ToolName);
}

/**
* Additional constraints that can be specified for some Managers, but are **not** tools that Containerbase supports.
*/
const additionalConstraintNames = [
/**
* Used in the `gomod` manager to specify the version of the Go toolchain to use.
*
* In precedence order:
*
* 1. config: `constraints.go`
* 1. `go.mod`: `toolchain` directive
* 1. `go.mod`: `go` directive
*
* NOTE that the `constraints.golang` is not used (https://github.com/renovatebot/renovate/issues/42601)
*
* @deprecated TODO remove in #42600
*/
'go',
/**
* Used in the `gomod` manager to specify a tag for `github.com/marwan-at-work/mod`.
*
* Must be prefixed with `v`.
*
* @see https://github.com/marwan-at-work/mod
*/
'gomodMod',
/**
* Used in the `jenkins-plugins` datasource to specify a minimum version of the Jenkins that a plugin must support.
*/
'jenkins',
/**
* Used in the `pip-compile` manager datasource to specify a version of `pip-tools` to use.
*
* @deprecated TODO remove in #42599
*/
'pipTools',
] as const;

/**
* Additional constraints that can be specified for some Managers, but are **not** tools that Containerbase supports.
*/
export type AdditionalConstraintName =
(typeof additionalConstraintNames)[number];

export function isAdditionalConstraintName(
value: unknown,
): value is AdditionalConstraintName {
return (
isString(value) &&
additionalConstraintNames.includes(value as AdditionalConstraintName)
);
}

/**
* A name usable as a key in a `constraints` record, which may be tools that Containerbase supports.
*/
export type ConstraintName = ToolName | AdditionalConstraintName;

export function isConstraintName(value: unknown): value is ConstraintName {
return isToolName(value) || isAdditionalConstraintName(value);
}

export interface ToolConstraint {
toolName: string;
toolName: ToolName;
constraint?: string | null;
}

Expand Down
1 change: 1 addition & 0 deletions lib/workers/repository/process/fetch.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ describe('workers/repository/process/fetch', () => {

it('fetches updates', async () => {
config.rangeStrategy = 'auto';
// @ts-expect-error -- intentionally using invalid constraint names
config.constraints = { some: 'different' };
const packageFiles: any = {
maven: [
Expand Down
Loading
Loading