Skip to content

Commit

Permalink
feat(align-deps): add flag to make unmanaged capabilities errors (#3024)
Browse files Browse the repository at this point in the history
  • Loading branch information
tido64 authored Mar 19, 2024
1 parent 3b99c63 commit 26e34b7
Show file tree
Hide file tree
Showing 12 changed files with 151 additions and 8 deletions.
5 changes: 5 additions & 0 deletions .changeset/friendly-peas-sneeze.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rnx-kit/align-deps": minor
---

Added a flag, `--no-unmanaged`, to make unmanaged capabilities errors
5 changes: 5 additions & 0 deletions .changeset/tidy-windows-relate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rnx-kit/cli": patch
---

align-deps: Added a flag, `--no-unmanaged`, to make unmanaged capabilities errors
22 changes: 22 additions & 0 deletions packages/align-deps/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,20 @@ cumbersome to manually add all capabilities yourself. You can run this tool with
`--init`, and it will try to add a sensible configuration based on what is
currently defined in the specified `package.json`.

### `--loose`

Determines how strict the React Native version requirement should be. Useful for
apps that depend on a newer React Native version than their dependencies declare
support for.

Default: `false`

### `--no-unmanaged`

Whether unmanaged capabilities should be treated as errors.

Default: `false`

### `--presets`

Comma-separated list of presets. This can be names to built-in presets, or paths
Expand Down Expand Up @@ -170,10 +184,18 @@ If the version numbers are omitted, an _interactive prompt_ will appear.
> made. As such, this flag will fail if changes are needed before making any
> modifications.
### `--verbose`

Specify to increase logging verbosity.

Default: `false`

### `--write`

Writes all proposed changes to the specified `package.json`.

Default: `false`

## Configure

While `@rnx-kit/align-deps` can ensure your dependencies are aligned without a
Expand Down
8 changes: 8 additions & 0 deletions packages/align-deps/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ export const cliOptions = {
"Determines whether align-deps should try to update the config in 'package.json'.",
type: "boolean",
},
"no-unmanaged": {
default: false,
description:
"Determines whether align-deps should treat unmanaged capabilities as errors.",
type: "boolean",
},
presets: {
description:
"Comma-separated list of presets. This can be names to built-in presets, or paths to external presets.",
Expand Down Expand Up @@ -157,6 +163,7 @@ async function makeCommand(args: Args): Promise<Command | undefined> {
init,
loose,
"migrate-config": migrateConfig,
"no-unmanaged": noUnmanaged,
presets,
requirements,
"set-version": setVersion,
Expand All @@ -168,6 +175,7 @@ async function makeCommand(args: Args): Promise<Command | undefined> {
presets: presets?.toString()?.split(",") ?? defaultConfig.presets,
loose,
migrateConfig,
noUnmanaged,
verbose,
write,
excludePackages: excludePackages?.toString()?.split(","),
Expand Down
17 changes: 11 additions & 6 deletions packages/align-deps/src/commands/vigilant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ export function inspect(
*/
export function checkPackageManifestUnconfigured(
manifestPath: string,
{ excludePackages, write }: Options,
{ excludePackages, noUnmanaged, write }: Options,
config: AlignDepsConfig,
logError = error
): ErrorCode {
Expand All @@ -281,17 +281,18 @@ export function checkPackageManifestUnconfigured(
manifestProfile,
write
);

if (
const hasUnmanagedDeps =
config.alignDeps.capabilities.length > 0 &&
unmanagedDependencies.length > 0
) {
unmanagedDependencies.length > 0;

if (hasUnmanagedDeps) {
const log = noUnmanaged ? logError : warn;
const dependencies = unmanagedDependencies
.map(([name, capability]) => {
return `\t - ${name} can be managed by '${capability}'`;
})
.join("\n");
warn(
log(
`${manifestPath}: Found dependencies that are currently missing from capabilities:\n${dependencies}`
);
info(
Expand All @@ -311,5 +312,9 @@ export function checkPackageManifestUnconfigured(
}
}

if (noUnmanaged && hasUnmanagedDeps) {
return "unmanaged-capabilities";
}

return "success";
}
3 changes: 3 additions & 0 deletions packages/align-deps/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export type Options = {
presets: string[];
loose: boolean;
migrateConfig: boolean;
noUnmanaged: boolean;
verbose: boolean;
write: boolean;
excludePackages?: string[];
Expand All @@ -31,6 +32,7 @@ export type Options = {
export type Args = Pick<Options, "loose" | "verbose" | "write"> & {
"exclude-packages"?: string | number;
"migrate-config": boolean;
"no-unmanaged": boolean;
"set-version"?: string | number;
init?: string;
packages?: (string | number)[];
Expand All @@ -48,6 +50,7 @@ export type ErrorCode =
| "invalid-manifest"
| "missing-react-native"
| "not-configured"
| "unmanaged-capabilities"
| "unsatisfied";

export type Command = (manifest: string) => ErrorCode;
Expand Down
1 change: 1 addition & 0 deletions packages/align-deps/test/check.app.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const defaultOptions = {
presets: defaultConfig.presets,
loose: false,
migrateConfig: false,
noUnmanaged: false,
verbose: false,
write: true,
};
Expand Down
18 changes: 18 additions & 0 deletions packages/align-deps/test/check.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const defaultOptions = {
presets: defaultConfig.presets,
loose: false,
migrateConfig: false,
noUnmanaged: false,
verbose: false,
write: false,
};
Expand All @@ -26,6 +27,7 @@ describe("checkPackageManifest({ kitType: 'library' })", () => {

const consoleLogSpy = jest.spyOn(global.console, "log");
const consoleWarnSpy = jest.spyOn(global.console, "warn");
const consoleErrorSpy = jest.spyOn(global.console, "error");

const mockManifest = {
name: "@rnx-kit/align-deps",
Expand All @@ -49,6 +51,7 @@ describe("checkPackageManifest({ kitType: 'library' })", () => {
rnxKitConfig.__setMockConfig();
consoleLogSpy.mockReset();
consoleWarnSpy.mockReset();
consoleErrorSpy.mockReset();
});

afterAll(() => {
Expand All @@ -60,6 +63,7 @@ describe("checkPackageManifest({ kitType: 'library' })", () => {
expect(result).toBe("invalid-manifest");
expect(consoleLogSpy).not.toHaveBeenCalled();
expect(consoleWarnSpy).not.toHaveBeenCalled();
expect(consoleErrorSpy).not.toHaveBeenCalled();
});

test("returns early if 'rnx-kit' is missing from the manifest", () => {
Expand All @@ -73,6 +77,7 @@ describe("checkPackageManifest({ kitType: 'library' })", () => {
expect(result).toBe("not-configured");
expect(consoleLogSpy).not.toHaveBeenCalled();
expect(consoleWarnSpy).toHaveBeenCalled();
expect(consoleErrorSpy).not.toHaveBeenCalled();
});

test("prints warnings when detecting bad packages", () => {
Expand All @@ -95,6 +100,7 @@ describe("checkPackageManifest({ kitType: 'library' })", () => {
expect(result).toBe("success");
expect(consoleLogSpy).not.toHaveBeenCalled();
expect(consoleWarnSpy).toHaveBeenCalled();
expect(consoleErrorSpy).not.toHaveBeenCalled();
});

test("prints warnings when detecting bad packages (with version range)", () => {
Expand All @@ -111,6 +117,7 @@ describe("checkPackageManifest({ kitType: 'library' })", () => {
expect(result).toBe("success");
expect(consoleLogSpy).not.toHaveBeenCalled();
expect(consoleWarnSpy).toHaveBeenCalled();
expect(consoleErrorSpy).not.toHaveBeenCalled();
});

test("returns early if no capabilities are defined", () => {
Expand All @@ -124,6 +131,7 @@ describe("checkPackageManifest({ kitType: 'library' })", () => {
expect(result).toBe("success");
expect(consoleLogSpy).not.toHaveBeenCalled();
expect(consoleWarnSpy).not.toHaveBeenCalled();
expect(consoleErrorSpy).not.toHaveBeenCalled();
});

test("returns if no changes are needed", () => {
Expand All @@ -150,6 +158,7 @@ describe("checkPackageManifest({ kitType: 'library' })", () => {
expect(result).toBe("success");
expect(consoleLogSpy).not.toHaveBeenCalled();
expect(consoleWarnSpy).not.toHaveBeenCalled();
expect(consoleErrorSpy).not.toHaveBeenCalled();
});

test("prints additional information with `--verbose`", () => {
Expand Down Expand Up @@ -179,6 +188,7 @@ describe("checkPackageManifest({ kitType: 'library' })", () => {
expect(result).toBe("success");
expect(consoleLogSpy).toHaveBeenCalled();
expect(consoleWarnSpy).not.toHaveBeenCalled();
expect(consoleErrorSpy).not.toHaveBeenCalled();
});

test("returns if no changes are needed (write: true)", () => {
Expand Down Expand Up @@ -209,6 +219,7 @@ describe("checkPackageManifest({ kitType: 'library' })", () => {
expect(didWriteToPath).toBe(false);
expect(consoleLogSpy).not.toHaveBeenCalled();
expect(consoleWarnSpy).not.toHaveBeenCalled();
expect(consoleErrorSpy).not.toHaveBeenCalled();
});

test("returns error code if changes are needed", () => {
Expand Down Expand Up @@ -239,6 +250,7 @@ describe("checkPackageManifest({ kitType: 'library' })", () => {
expect(result).not.toBe("success");
expect(consoleLogSpy).not.toHaveBeenCalled();
expect(consoleWarnSpy).not.toHaveBeenCalled();
expect(consoleErrorSpy).not.toHaveBeenCalled();
});

test("writes changes back to 'package.json'", () => {
Expand All @@ -259,6 +271,7 @@ describe("checkPackageManifest({ kitType: 'library' })", () => {
expect(didWriteToPath).toBe("package.json");
expect(consoleLogSpy).not.toHaveBeenCalled();
expect(consoleWarnSpy).not.toHaveBeenCalled();
expect(consoleErrorSpy).not.toHaveBeenCalled();
});

test("preserves indentation in 'package.json'", () => {
Expand All @@ -279,6 +292,7 @@ describe("checkPackageManifest({ kitType: 'library' })", () => {
expect(output).toMatchSnapshot();
expect(consoleLogSpy).not.toHaveBeenCalled();
expect(consoleWarnSpy).not.toHaveBeenCalled();
expect(consoleErrorSpy).not.toHaveBeenCalled();
});

test("returns appropriate error code if package is excluded", () => {
Expand All @@ -298,6 +312,7 @@ describe("checkPackageManifest({ kitType: 'library' })", () => {
expect(result).toBe("excluded");
expect(consoleLogSpy).not.toHaveBeenCalled();
expect(consoleWarnSpy).not.toHaveBeenCalled();
expect(consoleErrorSpy).not.toHaveBeenCalled();
});

test("uses minimum supported version as development version", () => {
Expand All @@ -324,6 +339,7 @@ describe("checkPackageManifest({ kitType: 'library' })", () => {
expect(result).toBe("success");
expect(consoleLogSpy).not.toHaveBeenCalled();
expect(consoleWarnSpy).not.toHaveBeenCalled();
expect(consoleErrorSpy).not.toHaveBeenCalled();
});

test("uses declared development version", () => {
Expand Down Expand Up @@ -353,6 +369,7 @@ describe("checkPackageManifest({ kitType: 'library' })", () => {
expect(result).toBe("success");
expect(consoleLogSpy).not.toHaveBeenCalled();
expect(consoleWarnSpy).not.toHaveBeenCalled();
expect(consoleErrorSpy).not.toHaveBeenCalled();
});

test("handles development version ranges", () => {
Expand Down Expand Up @@ -382,6 +399,7 @@ describe("checkPackageManifest({ kitType: 'library' })", () => {
expect(result).toBe("success");
expect(consoleLogSpy).not.toHaveBeenCalled();
expect(consoleWarnSpy).not.toHaveBeenCalled();
expect(consoleErrorSpy).not.toHaveBeenCalled();
});
});

Expand Down
13 changes: 13 additions & 0 deletions packages/align-deps/test/initialize.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const defaultOptions = {
presets: defaultConfig.presets,
loose: false,
migrateConfig: false,
noUnmanaged: false,
verbose: false,
write: false,
};
Expand Down Expand Up @@ -190,13 +191,25 @@ describe("initializeConfig()", () => {
describe("makeInitializeCommand()", () => {
const options = { ...defaultOptions, presets: [] };

const consoleErrorSpy = jest.spyOn(global.console, "error");

beforeEach(() => {
consoleErrorSpy.mockReset();
});

afterAll(() => {
jest.clearAllMocks();
});

test("returns undefined for invalid kit types", () => {
const command = makeInitializeCommand("random", options);
expect(command).toBeUndefined();
expect(consoleErrorSpy).toHaveBeenCalledTimes(1);
});

test("returns command for kit types", () => {
expect(makeInitializeCommand("app", options)).toBeDefined();
expect(makeInitializeCommand("library", options)).toBeDefined();
expect(consoleErrorSpy).not.toHaveBeenCalled();
});
});
1 change: 1 addition & 0 deletions packages/align-deps/test/setVersion.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ describe("makeSetVersionCommand()", () => {
presets: defaultConfig.presets,
loose: false,
migrateConfig: false,
noUnmanaged: false,
verbose: false,
write: false,
};
Expand Down
Loading

0 comments on commit 26e34b7

Please sign in to comment.