mirror of
https://github.com/renovatebot/renovate.git
synced 2026-10-31 17:51:49 +00:00
8a926e8cc7
* fix(deno): only collect workspace members when workspaces are declared A package.json with no workspaces field has no members to find, but the member scan ran anyway, and find-packages with no patterns returns every package.json in the tree. Standalone subprojects were picked up as members of the root lock, which is what breaks lockFileMaintenance. The scan now runs only when workspaces are declared. * test(deno): use await expect().resolves Required by the `vitest(prefer-expect-resolves)` oxlint rule enabled on main since this branch was created. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Michael Kriese <michael.kriese@mend.io> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
119 lines
3.7 KiB
TypeScript
119 lines
3.7 KiB
TypeScript
import { isNonEmptyArray } from '@sindresorhus/is';
|
|
import { findPackages } from 'find-packages';
|
|
import upath from 'upath';
|
|
import { GlobalConfig } from '../../../config/global.ts';
|
|
import { logger } from '../../../logger/index.ts';
|
|
import { parseJson } from '../../../util/common.ts';
|
|
import { getSiblingFileName, readLocalFile } from '../../../util/fs/index.ts';
|
|
import { ensureLocalPath } from '../../../util/fs/util.ts';
|
|
import { extractPackageJson } from '../npm/extract/common/package-file.ts';
|
|
import type { NpmPackage } from '../npm/extract/types.ts';
|
|
import type { PackageFile } from '../types.ts';
|
|
import type { DenoManagerData } from './types.ts';
|
|
|
|
export async function extractDenoCompatiblePackageJson(
|
|
packageFile: string,
|
|
): Promise<PackageFile<DenoManagerData> | null> {
|
|
const packageFileContent = await readLocalFile(packageFile, 'utf8');
|
|
if (!packageFileContent) {
|
|
logger.debug({ packageFile }, 'Deno: No package.json found');
|
|
return null;
|
|
}
|
|
|
|
let packageJson: NpmPackage;
|
|
try {
|
|
packageJson = parseJson(packageFileContent, packageFile) as NpmPackage;
|
|
} catch (err) {
|
|
logger.error({ err, packageFile }, 'Error parsing package.json');
|
|
return null;
|
|
}
|
|
|
|
const extracted = extractPackageJson(packageJson, packageFile);
|
|
if (!extracted) {
|
|
return null;
|
|
}
|
|
|
|
const result = extracted as PackageFile<DenoManagerData>;
|
|
result.managerData = {
|
|
packageName: extracted.managerData?.packageJsonName,
|
|
workspaces: extracted.managerData?.workspaces,
|
|
};
|
|
result.packageFile = packageFile;
|
|
return result;
|
|
}
|
|
|
|
// referring to lib/modules/manager/npm/extract/pnpm.ts detectPnpmWorkspaces()
|
|
export async function detectNodeCompatWorkspaces({
|
|
managerData,
|
|
packageFile,
|
|
}: Pick<PackageFile<DenoManagerData>, 'managerData' | 'packageFile'>): Promise<{
|
|
workspaces?: string[];
|
|
packagePaths: string[];
|
|
}> {
|
|
logger.debug(`Detecting deno's node compat Workspaces`);
|
|
|
|
let filters: string[] | undefined;
|
|
|
|
// npm workspace
|
|
if (isNonEmptyArray(managerData?.workspaces)) {
|
|
filters = managerData?.workspaces;
|
|
}
|
|
|
|
// findPackages() matches every package.json below the directory when it is given no patterns
|
|
if (!filters) {
|
|
return { packagePaths: [] };
|
|
}
|
|
|
|
const localDir = GlobalConfig.get('localDir');
|
|
const packages = await findPackages(
|
|
upath.dirname(ensureLocalPath(packageFile)),
|
|
{
|
|
patterns: filters,
|
|
// Match the ignores used in @pnpm/find-workspace-packages
|
|
ignore: ['**/node_modules/**', '**/bower_components/**'],
|
|
},
|
|
);
|
|
const packagePaths = packages.map((pkg) => {
|
|
const pkgPath = upath.join(pkg.dir, 'package.json');
|
|
return upath.relative(localDir, pkgPath);
|
|
});
|
|
|
|
return {
|
|
workspaces: filters,
|
|
packagePaths,
|
|
};
|
|
}
|
|
|
|
export async function collectPackageJson(
|
|
lockFile: string,
|
|
): Promise<PackageFile<DenoManagerData>[] | null> {
|
|
const lockFiles = [lockFile];
|
|
const packageFiles: PackageFile<DenoManagerData>[] = [];
|
|
const rootPackageJson = getSiblingFileName(lockFile, 'package.json');
|
|
const rootPackageFile =
|
|
await extractDenoCompatiblePackageJson(rootPackageJson);
|
|
if (rootPackageFile) {
|
|
rootPackageFile.lockFiles = lockFiles;
|
|
|
|
// detect node compat workspaces
|
|
const result = await detectNodeCompatWorkspaces(rootPackageFile);
|
|
const { workspaces, packagePaths } = result;
|
|
rootPackageFile.managerData = {
|
|
packageName: rootPackageFile.managerData?.packageName,
|
|
// override workspace
|
|
workspaces,
|
|
};
|
|
packageFiles.push(rootPackageFile);
|
|
|
|
for (const packagePath of packagePaths) {
|
|
const packageFile = await extractDenoCompatiblePackageJson(packagePath);
|
|
if (packageFile) {
|
|
packageFile.lockFiles = lockFiles;
|
|
packageFiles.push(packageFile);
|
|
}
|
|
}
|
|
}
|
|
|
|
return packageFiles;
|
|
}
|