Skip to content
This repository was archived by the owner on Apr 13, 2025. It is now read-only.

Commit 6ee2c74

Browse files
authored
Allow creating installs using only command line options (#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 ```
1 parent aafa2e6 commit 6ee2c74

File tree

3 files changed

+69
-8
lines changed

3 files changed

+69
-8
lines changed

src/index.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,15 @@ const args = yargs(process.argv.slice(2))
1616
.command(generateModule)
1717
.option("disable-updates", { type: "boolean", description: "Disables check for nodecg-io-cli updates" })
1818
.strict()
19-
.demandCommand();
19+
.demandCommand()
20+
.parserConfiguration({
21+
"dot-notation": false,
22+
})
23+
.parse();
2024

2125
ensureNode12();
2226
(async () => {
23-
const opts = await args.argv;
27+
const opts = await args;
2428
if (!opts["disable-updates"]) {
2529
checkForCliUpdate();
2630
}

src/install/index.ts

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,58 @@ import { logger } from "../utils/log";
1010
import { requireNpmV7 } from "../utils/npm";
1111
import { findNodeCGDirectory, getNodeCGIODirectory } from "../utils/nodecgInstallation";
1212

13-
export const installModule: CommandModule<unknown, { concurrency: number }> = {
13+
export interface InstallCommandOptions {
14+
"nodecg-io-version"?: string;
15+
service: Array<string | number>;
16+
"all-services": boolean;
17+
docs: boolean;
18+
samples: boolean;
19+
}
20+
21+
export const installModule: CommandModule<unknown, InstallCommandOptions> = {
1422
command: "install",
1523
describe: "installs nodecg-io to your local nodecg installation",
16-
handler: async () => {
24+
handler: async (opts) => {
1725
try {
18-
await install();
26+
await install(opts);
1927
} catch (err) {
2028
logger.error(`Error while installing nodecg-io: ${err}`);
2129
process.exit(1);
2230
}
2331
},
32+
builder: (yargs) =>
33+
yargs
34+
.option("nodecg-io-version", {
35+
type: "string",
36+
description:
37+
'The version of nodecg-io to install. Either "major.minor" for production or "development"',
38+
})
39+
.option("service", {
40+
type: "array",
41+
description:
42+
"The modecg-io services to install alongside the needed components. Only affects production installs.",
43+
default: [],
44+
})
45+
.option("all-services", {
46+
type: "boolean",
47+
description: "Whether to install all available services. Only affects production installs.",
48+
default: false,
49+
})
50+
.option("docs", {
51+
type: "boolean",
52+
description:
53+
"Whether to clone the docs repo into the /docs sub directory. Only available for development installs.",
54+
default: true,
55+
})
56+
.option("samples", {
57+
type: "boolean",
58+
description:
59+
"Whether to add the samples to your NodeCG configuration. Only available for development installs.",
60+
default: false,
61+
}),
2462
};
2563

26-
async function install(): Promise<void> {
64+
async function install(opts: InstallCommandOptions): Promise<void> {
2765
await requireNpmV7();
2866

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

3573
let currentInstall = await readInstallInfo(nodecgIODir);
36-
const requestedInstall = await promptForInstallInfo(currentInstall);
74+
const requestedInstall = await promptForInstallInfo(currentInstall, opts);
3775

3876
// If the minor version changed and we already have another one installed, we need to delete it, so it can be properly installed.
3977
if (currentInstall && currentInstall.version !== requestedInstall.version && (await directoryExists(nodecgIODir))) {

src/install/prompt.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
getServicesForVersion,
1313
supportedNodeCGIORange,
1414
} from "../nodecgIOVersions";
15+
import { InstallCommandOptions } from ".";
1516

1617
interface PromptInput {
1718
version: string;
@@ -27,8 +28,26 @@ interface PromptInput {
2728
* @param currentInstall the current install that will be used for default values
2829
* @returns the requested installation
2930
*/
30-
export async function promptForInstallInfo(currentInstall: Installation | undefined): Promise<Installation> {
31+
export async function promptForInstallInfo(
32+
currentInstall: Installation | undefined,
33+
opts: InstallCommandOptions,
34+
): Promise<Installation> {
3135
const versions = await getCompatibleVersions();
36+
const optsVersion = opts["nodecg-io-version"];
37+
if (optsVersion) {
38+
if (optsVersion !== developmentVersion && !versions.includes(optsVersion)) {
39+
throw new Error(`The specified nodecg-io "${optsVersion}" version could not be found.`);
40+
}
41+
42+
return await processPromptInput({
43+
version: optsVersion,
44+
useSamples: opts.samples,
45+
cloneDocs: opts.docs,
46+
services: opts["all-services"]
47+
? getServicesForVersion(optsVersion)
48+
: opts.service?.map((s) => s.toString()),
49+
});
50+
}
3251

3352
const currentProd = currentInstall !== undefined && !currentInstall.dev ? currentInstall : undefined;
3453
const currentDev = currentInstall !== undefined && currentInstall.dev ? currentInstall : undefined;

0 commit comments

Comments
 (0)