wip: general approach for cli

pull/385/head
Webber 2022-04-23 23:17:35 +02:00
parent c0e0e84a07
commit b1a7be5e41
11 changed files with 104 additions and 25 deletions

View File

@ -16,6 +16,9 @@
"es6": true,
"jest/globals": true
},
"globals": {
"Deno": true
},
"rules": {
// Error out for code formatting errors
"prettier/prettier": "error",

View File

@ -0,0 +1,12 @@
import { parseArgv } from '../core/parse-argv.ts';
export class ArgumentsParser {
static parse(cliArguments: string[]) {
const [commandName, ...arguments] = cliArguments;
return {
commandName,
options: parseArgv(arguments),
};
}
}

View File

@ -0,0 +1,28 @@
import { CommandFactory } from './commands/command-factory.ts';
import { ArgumentsParser } from './arguments-parser/arguments-parser.ts';
import { Options } from './config/options.ts';
import { CommandInterface } from './commands/command/CommandInterface.ts';
export class Bootstrapper {
private readonly commandFactory: CommandFactory;
private readonly argumentsParser: ArgumentsParser;
private options?: Options;
private command?: CommandInterface;
constructor() {
this.commandFactory = new CommandFactory();
this.argumentsParser = ArgumentsParser;
}
public async run(cliArguments: string[]) {
const { commandName, options } = this.argumentsParser.parse(cliArguments);
this.options = new Options(options);
this.command = this.commandFactory.createCommand(commandName);
// Command agnostic stuff here
await this.command.execute(this.options);
}
}

View File

@ -0,0 +1,15 @@
import { NonExistentCommand } from './command/non-existent-command.ts';
import { BuildCommand } from './command/build-command.ts';
export class CommandFactory {
constructor() {}
public createCommand(commandName) {
switch (commandName) {
case 'build':
return new BuildCommand();
default:
return new NonExistentCommand(commandName);
}
}
}

View File

@ -0,0 +1,6 @@
import { Options } from '../../config/options.ts';
export interface CommandInterface {
name: string;
execute: (options: Options) => Promise<void>;
}

View File

@ -1,17 +1,15 @@
/* eslint-disable no-console */
import { CommandInterface } from './CommandInterface.ts';
import { exec, OutputMode } from 'https://deno.land/x/exec@0.0.5/mod.ts';
import { CliOptions } from '../core/cli-options.ts';
import { Options } from '../../config/options.ts';
export class Bootstrapper {
private readonly options: CliOptions;
export class BuildCommand implements CommandInterface {
public readonly name: string;
constructor(cliOptions: CliOptions) {
this.options = cliOptions;
constructor(name: string) {
this.name = name;
}
public async run() {
console.log('using options', this.options);
public async execute(options: Options) {
const result = await exec('docker run -it unityci/editor:2020.3.15f2-base-1 /bin/bash -c "echo test"', {
output: OutputMode.Capture,
continueOnError: true,
@ -19,6 +17,7 @@ export class Bootstrapper {
// verbose: true,
});
console.log(options);
console.log(result.output);
}
}

View File

@ -0,0 +1,14 @@
import { CommandInterface } from './CommandInterface.ts';
import { Options } from '../../config/options.ts';
export class NonExistentCommand implements CommandInterface {
public name: string;
constructor(name: string) {
this.name = name;
}
public async execute(options: Options) {
throw new Error(`Command ${this.name} does not exist`);
}
}

View File

@ -0,0 +1,9 @@
import { CliOptions } from '../core/cli-options.ts';
export class Options {
public options: CliOptions;
constructor(optionsFromCli) {
this.options = optionsFromCli;
}
}

View File

@ -1,11 +0,0 @@
import { parseArgv } from './parse-argv.ts';
import { Bootstrapper } from '../controller/bootstrapper.ts';
export class Kernel {
public async run() {
const cliOptions = parseArgv(Deno.args);
const bootstrapper = new Bootstrapper(cliOptions);
bootstrapper.run();
}
}

View File

@ -1,7 +1,11 @@
import { Kernel } from './core/kernel.ts';
/* eslint-disable no-console */
import { Bootstrapper } from './bootstrapper.ts';
(async () => {
const kernel = new Kernel();
await kernel.run();
try {
await new Bootstrapper().run(Deno.args);
} catch (error) {
console.error(error);
Deno.exit(1);
}
})();

View File

@ -4,7 +4,7 @@
"target": "es6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */,
"module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */,
"outDir": "./lib" /* Redirect output structure to the directory. */,
"rootDir": "./" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */,
"rootDir": "./cli" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */,
"strict": true /* Enable all strict type-checking options. */,
"noImplicitAny": false /* Re-enable after fixing compatibility */ /* Raise error on expressions and declarations with an implied 'any' type. */,
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */