Skip to content

Commit

Permalink
feat(install): Allow creating installs using only command line options (
Browse files Browse the repository at this point in the history
#51)

When no interactive session is available `inquirer` doesn't work, e.g.
in Dockerfiles or automated scripts.
In theses cases you can use the command line options that are added with
this PR.

E.g. install a dev install:
```shell
nodecg-io install --nodecg-io-version development --samples
```

Or create a production install using a specific list of servies:
```shell
nodecg-io install --nodecg-io-version 0.1 --service twitch-chat
--service discord
```

Create a production install with all available services installed:
```shell
nodecg-io install --nodecg-io-version 0.2 --all-services
```
  • Loading branch information
hlxid committed Dec 17, 2021
1 parent aafa2e6 commit 20014e7
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 8 deletions.
8 changes: 6 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,15 @@ const args = yargs(process.argv.slice(2))
.command(generateModule)
.option("disable-updates", { type: "boolean", description: "Disables check for nodecg-io-cli updates" })
.strict()
.demandCommand();
.demandCommand()
.parserConfiguration({
"dot-notation": false,
})
.parse();

ensureNode12();
(async () => {
const opts = await args.argv;
const opts = await args;
if (!opts["disable-updates"]) {
checkForCliUpdate();
}
Expand Down
48 changes: 43 additions & 5 deletions src/install/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,58 @@ import { logger } from "../utils/log";
import { requireNpmV7 } from "../utils/npm";
import { findNodeCGDirectory, getNodeCGIODirectory } from "../utils/nodecgInstallation";

export const installModule: CommandModule<unknown, { concurrency: number }> = {
export interface InstallCommandOptions {
"nodecg-io-version"?: string;
service: Array<string | number>;
"all-services": boolean;
docs: boolean;
samples: boolean;
}

export const installModule: CommandModule<unknown, InstallCommandOptions> = {
command: "install",
describe: "installs nodecg-io to your local nodecg installation",
handler: async () => {
handler: async (opts) => {
try {
await install();
await install(opts);
} catch (err) {
logger.error(`Error while installing nodecg-io: ${err}`);
process.exit(1);
}
},
builder: (yargs) =>
yargs
.option("nodecg-io-version", {
type: "string",
description:
'The version of nodecg-io to install. Either "major.minor" for production or "development"',
})
.option("service", {
type: "array",
description:
"The modecg-io services to install alongside the needed components. Only affects production installs.",
default: [],
})
.option("all-services", {
type: "boolean",
description: "Whether to install all available services. Only affects production installs.",
default: false,
})
.option("docs", {
type: "boolean",
description:
"Whether to clone the docs repo into the /docs sub directory. Only available for development installs.",
default: true,
})
.option("samples", {
type: "boolean",
description:
"Whether to add the samples to your NodeCG configuration. Only available for development installs.",
default: false,
}),
};

async function install(): Promise<void> {
async function install(opts: InstallCommandOptions): Promise<void> {
await requireNpmV7();

logger.info("Installing nodecg-io...");
Expand All @@ -33,7 +71,7 @@ async function install(): Promise<void> {
const nodecgIODir = getNodeCGIODirectory(nodecgDir);

let currentInstall = await readInstallInfo(nodecgIODir);
const requestedInstall = await promptForInstallInfo(currentInstall);
const requestedInstall = await promptForInstallInfo(currentInstall, opts);

// If the minor version changed and we already have another one installed, we need to delete it, so it can be properly installed.
if (currentInstall && currentInstall.version !== requestedInstall.version && (await directoryExists(nodecgIODir))) {
Expand Down
21 changes: 20 additions & 1 deletion src/install/prompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
getServicesForVersion,
supportedNodeCGIORange,
} from "../nodecgIOVersions";
import { InstallCommandOptions } from ".";

interface PromptInput {
version: string;
Expand All @@ -27,8 +28,26 @@ interface PromptInput {
* @param currentInstall the current install that will be used for default values
* @returns the requested installation
*/
export async function promptForInstallInfo(currentInstall: Installation | undefined): Promise<Installation> {
export async function promptForInstallInfo(
currentInstall: Installation | undefined,
opts: InstallCommandOptions,
): Promise<Installation> {
const versions = await getCompatibleVersions();
const optsVersion = opts["nodecg-io-version"];
if (optsVersion) {
if (optsVersion !== developmentVersion && !versions.includes(optsVersion)) {
throw new Error(`The specified nodecg-io "${optsVersion}" version could not be found.`);
}

return await processPromptInput({
version: optsVersion,
useSamples: opts.samples,
cloneDocs: opts.docs,
services: opts["all-services"]
? getServicesForVersion(optsVersion)
: opts.service?.map((s) => s.toString()),
});
}

const currentProd = currentInstall !== undefined && !currentInstall.dev ? currentInstall : undefined;
const currentDev = currentInstall !== undefined && currentInstall.dev ? currentInstall : undefined;
Expand Down

0 comments on commit 20014e7

Please sign in to comment.