Skip to content

Commit

Permalink
extract add command
Browse files Browse the repository at this point in the history
  • Loading branch information
ComradeVanti committed Sep 17, 2024
1 parent ed877f8 commit 83adcfa
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 149 deletions.
211 changes: 109 additions & 102 deletions src/cli/cmd-add.ts
Original file line number Diff line number Diff line change
@@ -1,54 +1,31 @@
import { Command } from "@commander-js/extra-typings";
import { Logger } from "npmlog";
import { addDependenciesUsing } from "../app/add-dependencies";
import { determineEditorVersionUsing } from "../app/determine-editor-version";
import { loadRegistryAuthUsing } from "../app/get-registry-auth";
import { DebugLog } from "../domain/logging";
import {
makePackageReference,
PackageReference,
} from "../domain/package-reference";
import { makePackageReference } from "../domain/package-reference";
import { recordEntries } from "../domain/record-utils";
import { getHomePathFromEnv } from "../domain/special-paths";
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 { CmdOptions } from "./options";
import { eachValue } from "./cli-parsing";
import { withErrorLogger } from "./error-logging";
import type { GlobalOptions } from "./options";
import { parseEnvUsing } from "./parse-env";
import { ResultCodes } from "./result-codes";
import { mustBePackageReference } from "./validators";

/**
* 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;
}>;

/**
* The different command result codes for the add command.
*/
export type AddResultCode = ResultCodes.Ok | ResultCodes.Error;

/**
* Cmd-handler for adding packages.
* @param pkgs One or multiple references to packages to add.
* @param options Options specifying how to add the packages.
*/
type AddCmd = (
pkgs: PackageReference | PackageReference[],
options: AddOptions
) => Promise<AddResultCode>;

/**
* Makes a {@link AddCmd} function.
* Makes the `openupm add` cli command with the given dependencies.
* @param checkUrlExists IO function to check whether a url exists.
* @param fetchPackument IO function for fetching a packument.
* @param readTextFile IO function for reading a text file.
* @param writeTextFile IO function for writing a text file.
* @param log Logger for cli output.
* @param debugLog IO function for debug-logs.
* @returns The command.
*/
export function makeAddCmd(
checkUrlExists: CheckUrlExists,
Expand All @@ -57,78 +34,108 @@ export function makeAddCmd(
writeTextFile: WriteTextFile,
log: Logger,
debugLog: DebugLog
): AddCmd {
return async (pkgs, options) => {
if (!Array.isArray(pkgs)) pkgs = [pkgs];
) {
return new Command("add")
.argument(
"<pkg>",
"Reference to the package that should be added",
mustBePackageReference
)
.argument(
"[otherPkgs...]",
"References to additional packages that should be added",
eachValue(mustBePackageReference)
)
.aliases(["install", "i"])
.option("-t, --test", "add package as testable")
.option(
"-f, --force",
"force add package if missing deps or editor version is not qualified"
)
.description(
`add package to manifest json
openupm add <pkg> [otherPkgs...]
openupm add <pkg>@<version> [otherPkgs...]`
)
.action(
withErrorLogger(log, async function (pkg, otherPkgs, addOptions, cmd) {
const globalOptions = cmd.optsWithGlobals<GlobalOptions>();

// parse env
const env = await parseEnvUsing(log, process.env, process.cwd(), options);
const pkgs = [pkg].concat(otherPkgs);

const editorVersion = await determineEditorVersionUsing(
readTextFile,
debugLog,
env.cwd
);
// parse env
const env = await parseEnvUsing(
log,
process.env,
process.cwd(),
globalOptions
);

if (typeof editorVersion === "string")
log.warn(
"editor.version",
`${editorVersion} is unknown, the editor version check is disabled`
);
const editorVersion = await determineEditorVersionUsing(
readTextFile,
debugLog,
env.cwd
);

const projectDirectory = env.cwd;
if (typeof editorVersion === "string")
log.warn(
"editor.version",
`${editorVersion} is unknown, the editor version check is disabled`
);

const homePath = getHomePathFromEnv(process.env);
const upmConfigPath = getUserUpmConfigPathFor(
process.env,
homePath,
env.systemUser
);
const projectDirectory = env.cwd;

const primaryRegistry = await loadRegistryAuthUsing(
readTextFile,
debugLog,
upmConfigPath,
env.primaryRegistryUrl
);
const homePath = getHomePathFromEnv(process.env);
const upmConfigPath = getUserUpmConfigPathFor(
process.env,
homePath,
env.systemUser
);

const addResults = await addDependenciesUsing(
readTextFile,
writeTextFile,
fetchPackument,
checkUrlExists,
debugLog,
projectDirectory,
typeof editorVersion === "string" ? null : editorVersion,
primaryRegistry,
env.upstream,
options.force === true,
options.test === true,
pkgs
);
const primaryRegistry = await loadRegistryAuthUsing(
readTextFile,
debugLog,
upmConfigPath,
env.primaryRegistryUrl
);

recordEntries(addResults)
.map(([packageName, addResult]) => {
switch (addResult.type) {
case "added":
return `added ${makePackageReference(
packageName,
addResult.version
)}`;
case "upgraded":
return `modified ${packageName} ${addResult.fromVersion} => ${addResult.toVersion}`;
case "noChange":
return `existed ${makePackageReference(
packageName,
addResult.version
)}`;
}
})
.forEach((message) => {
log.notice("", message);
});
const addResults = await addDependenciesUsing(
readTextFile,
writeTextFile,
fetchPackument,
checkUrlExists,
debugLog,
projectDirectory,
typeof editorVersion === "string" ? null : editorVersion,
primaryRegistry,
env.upstream,
addOptions.force === true,
addOptions.test === true,
pkgs
);

recordEntries(addResults)
.map(([packageName, addResult]) => {
switch (addResult.type) {
case "added":
return `added ${makePackageReference(
packageName,
addResult.version
)}`;
case "upgraded":
return `modified ${packageName} ${addResult.fromVersion} => ${addResult.toVersion}`;
case "noChange":
return `existed ${makePackageReference(
packageName,
addResult.version
)}`;
}
})
.forEach((message) => {
log.notice("", message);
});

log.notice("", "please open Unity project to apply changes.");
return ResultCodes.Ok;
};
log.notice("", "please open Unity project to apply changes.");
})
);
}
18 changes: 9 additions & 9 deletions src/cli/error-logging.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ import {
type ResolvePackumentVersionError,
} from "../domain/packument";
import { recordEntries } from "../domain/record-utils";
import { NoSystemUserProfilePath } from "../domain/upm-config";
import { RegistryAuthenticationError } from "../io/common-errors";
import {
NoHomePathError,
OSNotSupportedError,
VersionNotSupportedOnOsError,
} from "../domain/special-paths";
import { NoSystemUserProfilePath } from "../domain/upm-config";
import { RegistryAuthenticationError } from "../io/common-errors";
import { RegistryAuthLoadError } from "./parse-env";
import { ResultCodes } from "./result-codes";

Expand Down Expand Up @@ -166,16 +166,16 @@ export function logError(log: Logger, error: unknown) {
* @returns A new function that has the same behaviour as the original but with
* error logging.
*/
export function withErrorLogger<
TArgs extends unknown[],
TOut extends ResultCodes
>(
export function withErrorLogger<TArgs extends unknown[], TOut>(
log: Logger,
cmd: (...args: TArgs) => Promise<TOut>
): (...args: TArgs) => Promise<TOut> {
return (...args) =>
cmd(...args).catch((error) => {
return async (...args) => {
try {
return await cmd(...args);
} catch (error) {
logError(log, error);
process.exit(ResultCodes.Error);
});
}
};
}
46 changes: 9 additions & 37 deletions src/cli/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,6 @@ const fetchPackument = getRegistryPackumentUsing(
const searchRegistry = searchRegistryUsing(debugLogToConsole);
const fetchAllPackuments = getAllRegistryPackumentsUsing(debugLogToConsole);

const addCmd = makeAddCmd(
fetchCheckUrlExists,
fetchPackument,
readTextFile,
writeTextFile,
log,
debugLogToConsole
);
const loginCmd = makeLoginCmd(
homePath,
getAuthTokenUsing(registryClient, debugLogToConsole),
Expand Down Expand Up @@ -127,36 +119,16 @@ function makeCmdOptions<T extends Record<string, unknown>>(
return { ...specificOptions, ...program.opts() };
}

program
.command("add")
.argument(
"<pkg>",
"Reference to the package that should be added",
mustBePackageReference
program.addCommand(
makeAddCmd(
fetchCheckUrlExists,
fetchPackument,
readTextFile,
writeTextFile,
log,
debugLogToConsole
)
.argument(
"[otherPkgs...]",
"References to additional packages that should be added",
eachValue(mustBePackageReference)
)
.aliases(["install", "i"])
.option("-t, --test", "add package as testable")
.option(
"-f, --force",
"force add package if missing deps or editor version is not qualified"
)
.description(
`add package to manifest json
openupm add <pkg> [otherPkgs...]
openupm add <pkg>@<version> [otherPkgs...]`
)
.action(
withErrorLogger(log, async function (pkg, otherPkgs, options) {
const pkgs = [pkg].concat(otherPkgs);
const resultCode = await addCmd(pkgs, makeCmdOptions(options));
process.exit(resultCode);
})
);
);

program
.command("remove")
Expand Down
2 changes: 1 addition & 1 deletion src/cli/options.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* Options which are shared between commands.
*/
type GlobalOptions = Readonly<{
export type GlobalOptions = Readonly<{
/**
* Override package registry to use.
*/
Expand Down

0 comments on commit 83adcfa

Please sign in to comment.