Skip to content

Commit

Permalink
extract chdir option
Browse files Browse the repository at this point in the history
  • Loading branch information
ComradeVanti committed Sep 17, 2024
1 parent ed877f8 commit e19c0ce
Show file tree
Hide file tree
Showing 12 changed files with 96 additions and 73 deletions.
33 changes: 18 additions & 15 deletions src/cli/cmd-add.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,27 @@ import { getUserUpmConfigPathFor } from "../domain/upm-config";
import type { ReadTextFile, WriteTextFile } from "../io/fs";
import type { GetRegistryPackument } from "../io/registry";
import type { CheckUrlExists } from "../io/www";
import { determineCwd, type ChdirOptions } from "./opt-chdir";
import { CmdOptions } from "./options";
import { parseEnvUsing } from "./parse-env";
import { ResultCodes } from "./result-codes";

/**
* Options passed to the add command.
*/
export type AddOptions = CmdOptions<{
/**
* Whether to also add the packages to testables.
*/
test?: boolean;
/**
* Whether to run with force. This will add packages even if validation
* was not possible.
*/
force?: boolean;
}>;
export type AddOptions = CmdOptions<
ChdirOptions & {
/**
* Whether to also add the packages to testables.
*/
test?: boolean;
/**
* Whether to run with force. This will add packages even if validation
* was not possible.
*/
force?: boolean;
}
>;

/**
* The different command result codes for the add command.
Expand Down Expand Up @@ -59,15 +62,17 @@ export function makeAddCmd(
debugLog: DebugLog
): AddCmd {
return async (pkgs, options) => {
const projectDirectory = determineCwd(process.cwd(), options);

if (!Array.isArray(pkgs)) pkgs = [pkgs];

// parse env
const env = await parseEnvUsing(log, process.env, process.cwd(), options);
const env = await parseEnvUsing(log, process.env, options);

const editorVersion = await determineEditorVersionUsing(
readTextFile,
debugLog,
env.cwd
projectDirectory
);

if (typeof editorVersion === "string")
Expand All @@ -76,8 +81,6 @@ export function makeAddCmd(
`${editorVersion} is unknown, the editor version check is disabled`
);

const projectDirectory = env.cwd;

const homePath = getHomePathFromEnv(process.env);
const upmConfigPath = getUserUpmConfigPathFor(
process.env,
Expand Down
2 changes: 1 addition & 1 deletion src/cli/cmd-deps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export function makeDepsCmd(
): DepsCmd {
return async (pkg, options) => {
// parse env
const env = await parseEnvUsing(log, process.env, process.cwd(), options);
const env = await parseEnvUsing(log, process.env, options);

const homePath = getHomePathFromEnv(process.env);
const upmConfigPath = getUserUpmConfigPathFor(
Expand Down
2 changes: 1 addition & 1 deletion src/cli/cmd-login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export function makeLoginCmd(

return async (options) => {
// parse env
const env = await parseEnvUsing(log, process.env, process.cwd(), options);
const env = await parseEnvUsing(log, process.env, options);

const homePath = getHomePathFromEnv(process.env);
const upmConfigPath = getUserUpmConfigPathFor(
Expand Down
14 changes: 9 additions & 5 deletions src/cli/cmd-remove.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Logger } from "npmlog";
import { removeDependenciesUsing } from "../app/remove-dependencies";
import { DomainName } from "../domain/domain-name";
import { partialApply } from "../domain/fp-utils";
import type { DebugLog } from "../domain/logging";
import { makePackageReference } from "../domain/package-reference";
import type { ReadTextFile, WriteTextFile } from "../io/fs";
import type { DebugLog } from "../domain/logging";
import { partialApply } from "../domain/fp-utils";
import { logError } from "./error-logging";
import { determineCwd, type ChdirOptions } from "./opt-chdir";
import { CmdOptions } from "./options";
import { parseEnvUsing } from "./parse-env";
import { ResultCodes } from "./result-codes";
Expand All @@ -18,7 +19,7 @@ export type RemoveResultCode = ResultCodes.Ok | ResultCodes.Error;
/**
* Options passed to the remove command.
*/
export type RemoveOptions = CmdOptions;
export type RemoveOptions = CmdOptions<ChdirOptions>;

/**
* Cmd-handler for removing packages.
Expand Down Expand Up @@ -47,10 +48,13 @@ export function makeRemoveCmd(
);

return async (pkgs, options) => {
const projectDirectory = determineCwd(process.cwd(), options);

// parse env
const env = await parseEnvUsing(log, process.env, process.cwd(), options);
await parseEnvUsing(log, process.env, options);

const removeResult = await removeDependencies(env.cwd, pkgs).promise;
const removeResult = await removeDependencies(projectDirectory, pkgs)
.promise;
if (removeResult.isErr()) {
logError(log, removeResult.error);
return ResultCodes.Error;
Expand Down
2 changes: 1 addition & 1 deletion src/cli/cmd-search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export function makeSearchCmd(

return async (keyword, options) => {
// parse env
const env = await parseEnvUsing(log, process.env, process.cwd(), options);
const env = await parseEnvUsing(log, process.env, options);
const homePath = getHomePathFromEnv(process.env);
const upmConfigPath = getUserUpmConfigPathFor(
process.env,
Expand Down
2 changes: 1 addition & 1 deletion src/cli/cmd-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export function makeViewCmd(
): ViewCmd {
return async (pkg, options) => {
// parse env
const env = await parseEnvUsing(log, process.env, process.cwd(), options);
const env = await parseEnvUsing(log, process.env, options);
const homePath = getHomePathFromEnv(process.env);
const upmConfigPath = getUserUpmConfigPathFor(
process.env,
Expand Down
4 changes: 3 additions & 1 deletion src/cli/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { makeRemoveCmd } from "./cmd-remove";
import { makeSearchCmd } from "./cmd-search";
import { makeViewCmd } from "./cmd-view";
import { withErrorLogger } from "./error-logging";
import { chdirOption } from "./opt-chdir";
import { CmdOptions } from "./options";
import {
mustBeDomainName,
Expand Down Expand Up @@ -109,7 +110,6 @@ notifier.notify();

const program = createCommand()
.version(module.exports.version)
.option("-c, --chdir <path>", "change the working directory")
.option("-r, --registry <url>", "specify registry url", mustBeRegistryUrl)
.option("-v, --verbose", "output extra debugging")
.option("--system-user", "auth for Windows system user")
Expand Down Expand Up @@ -140,6 +140,7 @@ program
eachValue(mustBePackageReference)
)
.aliases(["install", "i"])
.addOption(chdirOption)
.option("-t, --test", "add package as testable")
.option(
"-f, --force",
Expand Down Expand Up @@ -168,6 +169,7 @@ program
)
.aliases(["rm", "uninstall"])
.description("remove package from manifest json")
.addOption(chdirOption)
.action(
withErrorLogger(
log,
Expand Down
35 changes: 35 additions & 0 deletions src/cli/opt-chdir.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Option } from "@commander-js/extra-typings";
import path from "path";

/**
* The `chdir` cli-option for allowing users to switch their working
* directory.
*/
export const chdirOption = new Option(
"-c, --chdir <path>",
"change the working directory"
)
.default(null)
.makeOptionMandatory(true);

/**
* Parsed cli options which include a changed working directory.
*/
export type ChdirOptions = {
/**
* Overriden working-directory.
*/
chdir: string | null;
};

/**
* Determines the directory in which to execute commands.
* @param processCwd The process cwd.
* @param options Cmd options.
*/
export function determineCwd(
processCwd: string,
options: ChdirOptions
): string {
return options.chdir !== null ? path.resolve(options.chdir) : processCwd;
}
12 changes: 5 additions & 7 deletions src/cli/options.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { OptionValues } from "@commander-js/extra-typings";

/**
* Options which are shared between commands.
*/
Expand Down Expand Up @@ -26,15 +28,11 @@ type GlobalOptions = Readonly<{
* Whether to authenticate as a Windows system-user.
*/
systemUser?: boolean;
/**
* Override working directory.
*/
chdir?: string;
}>;

/**
* Command-options. Extends the given record with {@link GlobalOptions}.
*/
export type CmdOptions<
TOptions extends Record<string, unknown> = Record<string, unknown>
> = Readonly<TOptions & GlobalOptions>;
export type CmdOptions<TOptions extends OptionValues = OptionValues> = Readonly<
TOptions & GlobalOptions
>;
20 changes: 0 additions & 20 deletions src/cli/parse-env.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import chalk from "chalk";
import { Logger } from "npmlog";
import path from "path";
import { CustomError } from "ts-custom-error";
import {
coerceRegistryUrl,
Expand All @@ -20,10 +19,6 @@ export class RegistryAuthLoadError extends CustomError {
* Contains information about the environment and context a command is run in.
*/
export type Env = Readonly<{
/**
* The working directory.
*/
cwd: string;
/**
* Whether the user is a system-user.
*/
Expand All @@ -38,15 +33,6 @@ export type Env = Readonly<{
primaryRegistryUrl: RegistryUrl;
}>;

/**
* Determines the directory in which to execute commands.
* @param processCwd The process cwd.
* @param options Cmd options.
*/
export function determineCwd(processCwd: string, options: CmdOptions): string {
return options.chdir !== undefined ? path.resolve(options.chdir) : processCwd;
}

/**
* Determines which log level to use for output.
* @param options Cmd options.
Expand Down Expand Up @@ -97,14 +83,12 @@ export function determinePrimaryRegistryUrl(options: CmdOptions): RegistryUrl {
* command-options for further usage.
* @param log The logger that is used in the application.
* @param envVars Environment variables.
* @param processCwd The process directory.
* @param options The options passed to the current command.
* @returns Environment information.
*/
export async function parseEnvUsing(
log: Logger,
envVars: Record<string, string | undefined>,
processCwd: string,
options: CmdOptions
): Promise<Env> {
// log level
Expand All @@ -126,11 +110,7 @@ export async function parseEnvUsing(
// registries
const primaryRegistryUrl = determinePrimaryRegistryUrl(options);

// cwd
const cwd = determineCwd(processCwd, options);

return {
cwd,
primaryRegistryUrl,
systemUser,
upstream,
Expand Down
22 changes: 22 additions & 0 deletions test/unit/cli/opt-chdir.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import path from "path";
import { determineCwd } from "../../../src/cli/opt-chdir";

describe("chdir option", () => {
const testRootPath = "/users/some-user/projects/MyUnityProject";

it("should be process directory by default", () => {
const actual = determineCwd(testRootPath, { chdir: null });

expect(actual).toEqual(testRootPath);
});

it("should be specified path if overridden", () => {
const expected = path.resolve("/some/other/path");

const actual = determineCwd(testRootPath, {
chdir: expected,
});

expect(actual).toEqual(expected);
});
});
21 changes: 0 additions & 21 deletions test/unit/cli/parse-env.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import path from "path";
import {
determineCwd,
determineIsSystemUser,
determineLogLevel,
determinePrimaryRegistryUrl,
Expand All @@ -10,7 +8,6 @@ import {
import { openupmRegistryUrl } from "../../../src/domain/registry-url";
import { someRegistryUrl } from "../../common/data-registry";

const testRootPath = "/users/some-user/projects/MyUnityProject";

describe("parse env", () => {
describe("log-level", () => {
Expand Down Expand Up @@ -130,22 +127,4 @@ describe("parse env", () => {
expect(actual).toEqual(someRegistryUrl);
});
});

describe("cwd", () => {
it("should be process directory by default", () => {
const actual = determineCwd(testRootPath, {});

expect(actual).toEqual(testRootPath);
});

it("should be specified path if overridden", () => {
const expected = path.resolve("/some/other/path");

const actual = determineCwd(testRootPath, {
chdir: expected,
});

expect(actual).toEqual(expected);
});
});
});

0 comments on commit e19c0ce

Please sign in to comment.