Skip to content

Commit

Permalink
refactor(manager): final strict null checks (#15185)
Browse files Browse the repository at this point in the history
* refactor(manager): final strict null checks

* refactor: fix type issues

* test: fix mocking
  • Loading branch information
viceice authored Apr 20, 2022
1 parent 1c0073d commit 868ebbe
Show file tree
Hide file tree
Showing 34 changed files with 337 additions and 254 deletions.
4 changes: 4 additions & 0 deletions lib/modules/manager/bundler/update-locked.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ const lockFileContent = loadFixture('Gemfile.rubyci.lock');
describe('modules/manager/bundler/update-locked', () => {
it('detects already updated', () => {
const config: UpdateLockedConfig = {
packageFile: 'Gemfile',
lockFile: 'Gemfile.lock',
lockFileContent,
depName: 'activejob',
newVersion: '5.2.3',
Expand All @@ -16,6 +18,8 @@ describe('modules/manager/bundler/update-locked', () => {

it('returns unsupported', () => {
const config: UpdateLockedConfig = {
packageFile: 'Gemfile',
lockFile: 'Gemfile.lock',
lockFileContent,
depName: 'activejob',
newVersion: '5.2.0',
Expand Down
6 changes: 6 additions & 0 deletions lib/modules/manager/composer/update-locked.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@ import { loadFixture } from '../../../../test/util';
import type { UpdateLockedConfig } from '../types';
import { updateLockedDependency } from '.';

const lockFile = 'compose.lock';

const lockFileContent = loadFixture('composer5.lock');

describe('modules/manager/composer/update-locked', () => {
it('detects already updated', () => {
const config: UpdateLockedConfig = {
packageFile: 'composer.json',
lockFile,
lockFileContent,
depName: 'awesome/git',
newVersion: '1.2.0',
Expand All @@ -16,6 +20,8 @@ describe('modules/manager/composer/update-locked', () => {

it('returns unsupported', () => {
const config: UpdateLockedConfig = {
packageFile: 'composer.json',
lockFile,
lockFileContent,
depName: 'awesome/git',
newVersion: '1.0.0',
Expand Down
14 changes: 7 additions & 7 deletions lib/modules/manager/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const languageList = Object.values(ProgrammingLanguage);
export function get<T extends keyof ManagerApi>(
manager: string,
name: T
): ManagerApi[T] | null {
): ManagerApi[T] | undefined {
return managers.get(manager)?.[name];
}
export const getLanguageList = (): string[] => languageList;
Expand All @@ -27,7 +27,7 @@ export const getManagers = (): Map<string, ManagerApi> => managers;
export async function detectAllGlobalConfig(): Promise<GlobalManagerConfig> {
let config: GlobalManagerConfig = {};
for (const managerName of managerList) {
const manager = managers.get(managerName);
const manager = managers.get(managerName)!;
if (manager.detectGlobalConfig) {
// This should use mergeChildConfig once more than one manager is supported, but introduces a cyclic dependency
config = { ...config, ...(await manager.detectGlobalConfig()) };
Expand All @@ -44,7 +44,7 @@ export async function extractAllPackageFiles(
if (!managers.has(manager)) {
return null;
}
const m = managers.get(manager);
const m = managers.get(manager)!;
if (m.extractAllPackageFiles) {
const res = await m.extractAllPackageFiles(config, files);
// istanbul ignore if
Expand All @@ -65,18 +65,18 @@ export function extractPackageFile(
if (!managers.has(manager)) {
return null;
}
const m = managers.get(manager);
const m = managers.get(manager)!;
return m.extractPackageFile
? m.extractPackageFile(content, fileName, config)
: null;
}

export function getRangeStrategy(config: RangeConfig): RangeStrategy {
export function getRangeStrategy(config: RangeConfig): RangeStrategy | null {
const { manager, rangeStrategy } = config;
if (!managers.has(manager)) {
if (!manager || !managers.has(manager)) {
return null;
}
const m = managers.get(manager);
const m = managers.get(manager)!;
if (m.getRangeStrategy) {
// Use manager's own function if it exists
const managerRangeStrategy = m.getRangeStrategy(config);
Expand Down
37 changes: 22 additions & 15 deletions lib/modules/manager/npm/extract/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export async function extractPackageFile(
`npm file ${fileName} has name ${JSON.stringify(packageJsonName)}`
);
const packageFileVersion = packageJson.version;
let yarnWorkspacesPackages: string[];
let yarnWorkspacesPackages: string[] | undefined;
if (is.array(packageJson.workspaces)) {
yarnWorkspacesPackages = packageJson.workspaces;
} else {
Expand All @@ -83,7 +83,10 @@ export async function extractPackageFile(
pnpmShrinkwrap: 'pnpm-lock.yaml',
};

for (const [key, val] of Object.entries(lockFiles)) {
for (const [key, val] of Object.entries(lockFiles) as [
'yarnLock' | 'packageLock' | 'shrinkwrapJson' | 'pnpmShrinkwrap',
string
][]) {
const filePath = getSiblingFileName(fileName, val);
if (await readLocalFile(filePath, 'utf8')) {
lockFiles[key] = filePath;
Expand All @@ -95,7 +98,7 @@ export async function extractPackageFile(
delete lockFiles.packageLock;
delete lockFiles.shrinkwrapJson;

let npmrc: string;
let npmrc: string | undefined;
const npmrcFileName = getSiblingFileName(fileName, '.npmrc');
let repoNpmrc = await readLocalFile(npmrcFileName, 'utf8');
if (is.string(repoNpmrc)) {
Expand Down Expand Up @@ -135,15 +138,17 @@ export async function extractPackageFile(
const yarnrcYmlFileName = getSiblingFileName(fileName, '.yarnrc.yml');
const yarnZeroInstall = await isZeroInstall(yarnrcYmlFileName);

let lernaJsonFile: string;
let lernaPackages: string[];
let lernaClient: 'yarn' | 'npm';
let lernaJsonFile: string | undefined;
let lernaPackages: string[] | undefined;
let lernaClient: 'yarn' | 'npm' | undefined;
let hasFancyRefs = false;
let lernaJson: {
packages: string[];
npmClient: string;
useWorkspaces?: boolean;
};
let lernaJson:
| {
packages: string[];
npmClient: string;
useWorkspaces?: boolean;
}
| undefined;
try {
lernaJsonFile = getSiblingFileName(fileName, 'lerna.json');
lernaJson = JSON.parse(await readLocalFile(lernaJsonFile, 'utf8'));
Expand Down Expand Up @@ -332,14 +337,16 @@ export async function extractPackageFile(
return dep;
}

for (const depType of Object.keys(depTypes)) {
for (const depType of Object.keys(depTypes) as (keyof typeof depTypes)[]) {
let dependencies = packageJson[depType];
if (dependencies) {
try {
if (depType === 'packageManager') {
const match = regEx('^(?<name>.+)@(?<range>.+)$').exec(dependencies);
const match = regEx('^(?<name>.+)@(?<range>.+)$').exec(
dependencies as string
);
// istanbul ignore next
if (!match) {
if (!match?.groups) {
break;
}
dependencies = { [match.groups.name]: match.groups.range };
Expand Down Expand Up @@ -446,6 +453,6 @@ export async function extractAllPackageFiles(
logger.debug({ packageFile }, 'packageFile has no content');
}
}
await postExtract(npmFiles, config.updateInternalDeps);
await postExtract(npmFiles, !!config.updateInternalDeps);
return npmFiles;
}
23 changes: 14 additions & 9 deletions lib/modules/manager/npm/extract/locked-versions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export async function getLockedVersions(
logger.debug('Finding locked versions');
for (const packageFile of packageFiles) {
const { yarnLock, npmLock, pnpmShrinkwrap } = packageFile;
const lockFiles = [];
const lockFiles: string[] = [];
if (yarnLock) {
logger.trace('Found yarnLock');
lockFiles.push(yarnLock);
Expand All @@ -22,14 +22,17 @@ export async function getLockedVersions(
}
const { lockfileVersion, isYarn1 } = lockFileCache[yarnLock];
if (!isYarn1) {
if (lockfileVersion >= 8) {
if (lockfileVersion && lockfileVersion >= 8) {
// https://github.com/yarnpkg/berry/commit/9bcd27ae34aee77a567dd104947407532fa179b3
packageFile.constraints.yarn = '^3.0.0';
} else if (lockfileVersion >= 6) {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
packageFile.constraints!.yarn = '^3.0.0';
} else if (lockfileVersion && lockfileVersion >= 6) {
// https://github.com/yarnpkg/berry/commit/f753790380cbda5b55d028ea84b199445129f9ba
packageFile.constraints.yarn = '^2.2.0';
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
packageFile.constraints!.yarn = '^2.2.0';
} else {
packageFile.constraints.yarn = '^2.0.0';
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
packageFile.constraints!.yarn = '^2.0.0';
}
}
for (const dep of packageFile.deps) {
Expand All @@ -54,18 +57,20 @@ export async function getLockedVersions(
}
const { lockfileVersion } = lockFileCache[npmLock];
if (lockfileVersion === 1) {
if (packageFile.constraints.npm) {
if (packageFile.constraints?.npm) {
// Add a <7 constraint if it's not already a fixed version
if (!semver.valid(packageFile.constraints.npm)) {
packageFile.constraints.npm += ' <7';
}
} else {
packageFile.constraints.npm = '<7';
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
packageFile.constraints!.npm = '<7';
}
}
for (const dep of packageFile.deps) {
dep.lockedVersion = semver.valid(
lockFileCache[npmLock].lockedVersions[dep.depName]
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
lockFileCache[npmLock].lockedVersions[dep.depName!]
);
}
} else if (pnpmShrinkwrap) {
Expand Down
7 changes: 5 additions & 2 deletions lib/modules/manager/npm/extract/monorepo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,13 @@ export async function detectMonorepos(
if (packages?.length) {
const internalPackagePatterns = (
is.array(packages) ? packages : [packages]
).map((pattern) => getSiblingFileName(packageFile, pattern));
)
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
.map((pattern) => getSiblingFileName(packageFile!, pattern));
const internalPackageFiles = packageFiles.filter((sp) =>
matchesAnyPattern(
getSubDirectory(sp.packageFile),
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
getSubDirectory(sp.packageFile!),
internalPackagePatterns
)
);
Expand Down
4 changes: 2 additions & 2 deletions lib/modules/manager/npm/extract/pnpm.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ describe('modules/manager/npm/extract/pnpm', () => {
'..'
);
const res = await extractPnpmFilters(workSpaceFilePath);
expect(res).toBeNull();
expect(res).toBeUndefined();
expect(logger.logger.trace).toHaveBeenCalledWith(
{
fileName: expect.any(String),
Expand All @@ -39,7 +39,7 @@ describe('modules/manager/npm/extract/pnpm', () => {
});

const res = await extractPnpmFilters('pnpm-workspace.yml');
expect(res).toBeNull();
expect(res).toBeUndefined();
expect(logger.logger.trace).toHaveBeenCalledWith(
expect.objectContaining({
fileName: expect.any(String),
Expand Down
12 changes: 7 additions & 5 deletions lib/modules/manager/npm/extract/pnpm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import type { PnpmWorkspaceFile } from './types';

export async function extractPnpmFilters(
fileName: string
): Promise<string[] | null> {
): Promise<string[] | undefined> {
try {
const contents = load(await readLocalFile(fileName, 'utf8'), {
json: true,
Expand All @@ -28,12 +28,12 @@ export async function extractPnpmFilters(
{ fileName },
'Failed to find required "packages" array in pnpm-workspace.yaml'
);
return null;
return undefined;
}
return contents.packages;
} catch (err) {
logger.trace({ fileName, err }, 'Failed to parse pnpm-workspace.yaml');
return null;
return undefined;
}
}

Expand Down Expand Up @@ -91,7 +91,8 @@ export async function detectPnpmWorkspaces(
}

// search for corresponding pnpm workspace
const pnpmWorkspace = await findPnpmWorkspace(packageFile);
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
const pnpmWorkspace = await findPnpmWorkspace(packageFile!);
if (pnpmWorkspace === null) {
continue;
}
Expand All @@ -113,7 +114,8 @@ export async function detectPnpmWorkspaces(
const packagePaths = packagePathCache.get(workspaceYamlPath);

const isPackageInWorkspace = packagePaths?.some((p) =>
p.endsWith(packageFile)
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
p.endsWith(packageFile!)
);

if (isPackageInWorkspace) {
Expand Down
2 changes: 2 additions & 0 deletions lib/modules/manager/npm/extract/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ export interface NpmPackage extends PackageJson {
_id?: any;
dependenciesMeta?: DependenciesMeta;
packageManager?: string;

volta?: PackageJson.Dependency;
}

export type LockFileEntry = Record<
Expand Down
2 changes: 1 addition & 1 deletion lib/modules/manager/npm/extract/yarn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export async function getYarnLock(filePath: string): Promise<LockFile> {
try {
const parsed = parseSyml(yarnLockRaw);
const lockedVersions: Record<string, string> = {};
let lockfileVersion: number;
let lockfileVersion: number | undefined;

for (const [key, val] of Object.entries(parsed)) {
if (key === '__metadata') {
Expand Down
Loading

0 comments on commit 868ebbe

Please sign in to comment.