Files
Sebastian Poxhofer 9717259ffc refactor(oxlint): enable no-else-return and unicorn/no-lonely-if (#44553)
Enable no-else-return (with allowElseIf: false) and unicorn/no-lonely-if
as errors in .oxlintrc.json and fix all 131 pre-existing violations
(91 no-else-return, 40 unicorn/no-lonely-if) across 98 files.

The no-else-return violations were fixed with the oxlint autofix
(iterated to a fixpoint, plus two else-if chains that required
--fix-dangerously) followed by Prettier formatting. One comment dropped
by the autofix in lib/modules/manager/pub/artifacts.ts was restored
manually. The unicorn/no-lonely-if violations were merged by hand,
preserving comments and coverage-ignore hints.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 12:11:21 +00:00

145 lines
4.2 KiB
TypeScript

import { isObject, isString } from '@sindresorhus/is';
import type { Document } from 'yaml';
import { CST, isCollection, isPair, isScalar, parseDocument } from 'yaml';
import { logger } from '../../../../../logger/index.ts';
import type { UpdateDependencyConfig } from '../../../types.ts';
import { YarnConfig } from '../../schema.ts';
import { getNewGitValue, getNewNpmAliasValue } from './common.ts';
export function updateYarnrcCatalogDependency({
fileContent,
upgrade,
}: UpdateDependencyConfig): string | null {
const { depType, depName } = upgrade;
const catalogName = depType?.split('.').at(-1);
if (!isString(catalogName)) {
logger.error(
'No catalogName was found; this is likely an extraction error.',
);
return null;
}
let { newValue } = upgrade;
newValue = getNewGitValue(upgrade) ?? newValue;
newValue = getNewNpmAliasValue(newValue, upgrade) ?? newValue;
logger.trace(
`npm.updateYarnrcCatalogDependency(): ${depType}::${catalogName}.${depName} = ${newValue}`,
);
let document: ReturnType<typeof parseDocument>;
let parsedContents: YarnConfig;
try {
// In order to preserve the original formatting as much as possible, we want
// manipulate the CST directly. Using the AST (the result of parseDocument)
// does not guarantee that formatting would be the same after
// stringification. However, the CST is more annoying to query for certain
// values. Thus, we use both an annotated AST and a JS representation; the
// former for manipulation, and the latter for querying/validation.
document = parseDocument(fileContent, { keepSourceTokens: true });
parsedContents = YarnConfig.parse(document.toString());
} catch (err) {
logger.debug({ err }, 'Could not parse yarnrc YAML file.');
return null;
}
let oldVersion: string | undefined;
if (catalogName === 'default') {
oldVersion = parsedContents.catalog?.[depName!];
} else if (
isObject(parsedContents.catalogs?.[catalogName]) &&
isString(depName)
) {
oldVersion = parsedContents.catalogs?.[catalogName][depName];
}
if (oldVersion === newValue) {
logger.trace('Version is already updated');
return fileContent;
}
// Update the value
const path = getDepPath({
depName: depName!,
catalogName,
});
const modifiedDocument = changeDependencyIn(document, path, {
newValue,
newName: upgrade.newName,
});
if (!modifiedDocument) {
// Case where we are explicitly unable to substitute the key/value, for
// example if the value was an alias.
return null;
}
return CST.stringify(modifiedDocument.contents!.srcToken!);
}
/**
* Change the scalar name and/or value of a collection item in a YAML document,
* while keeping formatting consistent. Mutates the given document.
*/
function changeDependencyIn(
document: Document,
path: string[],
{ newName, newValue }: { newName?: string; newValue?: string },
): Document | null {
const parentPath = path.slice(0, -1);
const relevantItemKey = path.at(-1);
const parentNode = document.getIn(parentPath);
if (!parentNode || !isCollection(parentNode)) {
return null;
}
const relevantNode = parentNode.items.find(
(item) =>
isPair(item) && isScalar(item.key) && item.key.value === relevantItemKey,
);
if (!relevantNode || !isPair(relevantNode)) {
return null;
}
if (newName) {
/* the try..catch block above already throws if a key is an alias */
CST.setScalarValue(relevantNode.srcToken!.key!, newName);
}
// v8 ignore else -- TODO: add test #40625
if (newValue) {
// We only support scalar values when substituting. This explicitly avoids
// substituting aliases, since those can be resolved from a shared location,
// and replacing either the referrent anchor or the alias would be wrong in
// the general case. We leave this up to the user, e.g. via a Regex custom
// manager.
if (!CST.isScalar(relevantNode.srcToken?.value)) {
return null;
}
CST.setScalarValue(relevantNode.srcToken.value, newValue);
}
return document;
}
function getDepPath({
catalogName,
depName,
}: {
catalogName: string;
depName: string;
}): string[] {
if (catalogName === 'default') {
return ['catalog', depName];
}
return ['catalogs', catalogName, depName];
}