feat: add "config open" command
parent
0ac9b8034b
commit
f188ecfd62
35
README.md
35
README.md
|
|
@ -1,39 +1,16 @@
|
||||||
# Unity - Builder
|
# GameCI CLI
|
||||||
|
|
||||||
(Not affiliated with Unity Technologies)
|
The CLI is currently a work in progress.
|
||||||
|
|
||||||
GitHub Action to
|
We expect it to be working by the end of 2022.
|
||||||
[build Unity projects](https://github.com/marketplace/actions/unity-builder)
|
|
||||||
for different platforms.
|
|
||||||
|
|
||||||
Part of the <a href="https://game.ci">GameCI</a> open source project.
|
See [our roadmap](https://github.com/orgs/game-ci/projects/4/views/1) to follow our progress.
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
|
|
||||||
[](https://github.com/game-ci/unity-builder/actions?query=branch%3Amain+event%3Apush+workflow%3A%22Builds)
|
|
||||||
[](https://lgtm.com/projects/g/webbertakken/unity-builder/context:javascript)
|
|
||||||
[](https://codecov.io/gh/game-ci/unity-builder)
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
|
|
||||||
## How to use
|
|
||||||
|
|
||||||
Find the
|
|
||||||
[docs](https://game.ci/docs/github/builder)
|
|
||||||
on the GameCI
|
|
||||||
[documentation website](https://game.ci/docs).
|
|
||||||
|
|
||||||
## Related actions
|
|
||||||
|
|
||||||
Visit the
|
|
||||||
GameCI <a href="https://github.com/game-ci/unity-actions">Unity Actions</a>
|
|
||||||
status repository for related Actions.
|
|
||||||
|
|
||||||
## Community
|
## Community
|
||||||
|
|
||||||
Feel free to join us on
|
Feel free to join us on
|
||||||
<a href="http://game.ci/discord"><img height="30" src="media/Discord-Logo.svg" alt="Discord" /></a>
|
<a href="http://game.ci/discord"><img height="30" src="media/Discord-Logo.svg" alt="Discord" /></a> and engage with the
|
||||||
and engage with the community.
|
community.
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
|
|
|
||||||
25
deno.json
25
deno.json
|
|
@ -1,27 +1,40 @@
|
||||||
{
|
{
|
||||||
"tasks": {
|
"tasks": {
|
||||||
|
"config": "deno run -A .tools/open-config-folder.ts",
|
||||||
"test": "deno test -A ./src/integrity.test.ts",
|
"test": "deno test -A ./src/integrity.test.ts",
|
||||||
"coverage": "rm -rf .coverage ; deno test -A ./src/integrity.test.ts --coverage=.coverage/raw ; deno coverage .coverage/raw --lcov --output=.coverage/raw/.lcov ; perl .tools/lcov/genhtml.perl -q -o .coverage/report .coverage/raw/.lcov && deno run -A .tools/open-coverage-report.ts"
|
"coverage": "rm -rf .coverage ; deno test -A ./src/integrity.test.ts --coverage=.coverage/raw ; deno coverage .coverage/raw --lcov --output=.coverage/raw/.lcov ; perl .tools/lcov/genhtml.perl -q -o .coverage/report .coverage/raw/.lcov && deno run -A .tools/open-coverage-report.ts"
|
||||||
},
|
},
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"lib": ["deno.window"],
|
"lib": [
|
||||||
|
"deno.window"
|
||||||
|
],
|
||||||
"strict": true
|
"strict": true
|
||||||
},
|
},
|
||||||
"lint": {
|
"lint": {
|
||||||
"files": {
|
"files": {
|
||||||
"include": ["src/"],
|
"include": [
|
||||||
|
"src/"
|
||||||
|
],
|
||||||
"exclude": []
|
"exclude": []
|
||||||
},
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
"tags": ["recommended"],
|
"tags": [
|
||||||
"include": ["ban-untagged-todo"],
|
"recommended"
|
||||||
"exclude": ["no-unused-vars"]
|
],
|
||||||
|
"include": [
|
||||||
|
"ban-untagged-todo"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"no-unused-vars"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fmt": {
|
"fmt": {
|
||||||
"files": {
|
"files": {
|
||||||
"include": ["src/"],
|
"include": [
|
||||||
|
"src/"
|
||||||
|
],
|
||||||
"exclude": []
|
"exclude": []
|
||||||
},
|
},
|
||||||
"options": {
|
"options": {
|
||||||
|
|
|
||||||
11
src/cli.ts
11
src/cli.ts
|
|
@ -25,6 +25,7 @@ export class Cli {
|
||||||
this.configureLogger();
|
this.configureLogger();
|
||||||
this.globalOptions();
|
this.globalOptions();
|
||||||
|
|
||||||
|
await this.registerConfigCommand();
|
||||||
await this.registerBuildCommand();
|
await this.registerBuildCommand();
|
||||||
|
|
||||||
await this.parse();
|
await this.parse();
|
||||||
|
|
@ -45,7 +46,7 @@ export class Cli {
|
||||||
const defaultAbsolutePath = `${this.cliStorageAbsolutePath}/${this.configFileName}`;
|
const defaultAbsolutePath = `${this.cliStorageAbsolutePath}/${this.configFileName}`;
|
||||||
|
|
||||||
this.yargs
|
this.yargs
|
||||||
.config('config', `default: ${defaultCanonicalPath}`, async (override) => {
|
.config('config', `default: ${defaultCanonicalPath}`, async (override: string) => {
|
||||||
const configPath = override || defaultAbsolutePath;
|
const configPath = override || defaultAbsolutePath;
|
||||||
|
|
||||||
return JSON.parse(await Deno.readTextFile(configPath));
|
return JSON.parse(await Deno.readTextFile(configPath));
|
||||||
|
|
@ -150,6 +151,14 @@ export class Cli {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async registerConfigCommand() {
|
||||||
|
this.yargs.command('config', 'GameCI CLI configuration', async (yargs) => {
|
||||||
|
yargs
|
||||||
|
.command('open', 'Opens the CLI configuration folder', async (yargs) => {})
|
||||||
|
.middleware([async (args) => this.registerCommand(args, yargs)]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private async registerCommand(args: YargsArguments, yargs: YargsInstance) {
|
private async registerCommand(args: YargsArguments, yargs: YargsInstance) {
|
||||||
const { engine, engineVersion, _: command } = args;
|
const { engine, engineVersion, _: command } = args;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,36 +4,33 @@ import PlatformSetup from '../../model/platform-setup.ts';
|
||||||
import MacBuilder from '../../model/mac-builder.ts';
|
import MacBuilder from '../../model/mac-builder.ts';
|
||||||
import { CommandBase } from '../command-base.ts';
|
import { CommandBase } from '../command-base.ts';
|
||||||
import { UnityOptions } from '../../command-options/unity-options.ts';
|
import { UnityOptions } from '../../command-options/unity-options.ts';
|
||||||
import { YargsInstance } from '../../dependencies.ts';
|
import { YargsInstance, YargsArguments } from '../../dependencies.ts';
|
||||||
import { VersioningOptions } from '../../command-options/versioning-options.ts';
|
import { VersioningOptions } from '../../command-options/versioning-options.ts';
|
||||||
import { BuildOptions } from '../../command-options/build-options.ts';
|
import { BuildOptions } from '../../command-options/build-options.ts';
|
||||||
|
|
||||||
export class UnityBuildCommand extends CommandBase implements CommandInterface {
|
export class UnityBuildCommand extends CommandBase implements CommandInterface {
|
||||||
public async execute(options): Promise<boolean> {
|
public async execute(options: YargsArguments): Promise<boolean> {
|
||||||
try {
|
// Todo - rework this without needing this.options, use parameters from cli instead.
|
||||||
// Todo - rework this without needing this.options, use parameters from cli instead.
|
// const { workspace, actionFolder } = Action;
|
||||||
// const { workspace, actionFolder } = Action;
|
// const { parameters, env } = this.options;
|
||||||
// const { parameters, env } = this.options;
|
//
|
||||||
//
|
// Action.checkCompatibility();
|
||||||
// Action.checkCompatibility();
|
// Cache.verify();
|
||||||
// Cache.verify();
|
//
|
||||||
//
|
// const baseImage = new ImageTag(options);
|
||||||
// const baseImage = new ImageTag(options);
|
// log.debug('baseImage', baseImage);
|
||||||
// log.debug('baseImage', baseImage);
|
//
|
||||||
//
|
// await PlatformSetup.setup(parameters, actionFolder);
|
||||||
// await PlatformSetup.setup(parameters, actionFolder);
|
// if (env.getOS() === 'darwin') {
|
||||||
// if (env.getOS() === 'darwin') {
|
// MacBuilder.run(actionFolder, workspace, parameters);
|
||||||
// MacBuilder.run(actionFolder, workspace, parameters);
|
// } else {
|
||||||
// } else {
|
// await Docker.run(baseImage, { workspace, actionFolder, ...parameters });
|
||||||
// await Docker.run(baseImage, { workspace, actionFolder, ...parameters });
|
// }
|
||||||
// }
|
//
|
||||||
//
|
// // Set output
|
||||||
// // Set output
|
// await Output.setBuildVersion(parameters.buildVersion);
|
||||||
// await Output.setBuildVersion(parameters.buildVersion);
|
|
||||||
} catch (error) {
|
return true;
|
||||||
log.error(error);
|
|
||||||
Deno.exit(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async configureOptions(yargs: YargsInstance): Promise<void> {
|
public async configureOptions(yargs: YargsInstance): Promise<void> {
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,18 @@
|
||||||
import { Options } from '../config/options.ts';
|
|
||||||
import { Input } from '../model/index.ts';
|
|
||||||
import Parameters from '../model/parameters.ts';
|
|
||||||
import { CommandInterface } from './command-interface.ts';
|
import { CommandInterface } from './command-interface.ts';
|
||||||
|
import { YargsArguments, YargsInstance } from '../dependencies.ts';
|
||||||
|
|
||||||
export class CommandBase implements CommandInterface {
|
export class CommandBase implements CommandInterface {
|
||||||
public readonly name: string;
|
public readonly name: string;
|
||||||
private options: Options;
|
|
||||||
|
|
||||||
constructor(name: string) {
|
constructor(name: string) {
|
||||||
this.name = name;
|
this.name = name.charAt(0).toUpperCase() + name.slice(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async execute(): Promise<boolean> {
|
public execute(options: YargsArguments): Promise<boolean> {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
|
||||||
|
public configureOptions(yargs: YargsInstance): Promise<void> {
|
||||||
throw new Error('Method not implemented.');
|
throw new Error('Method not implemented.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import { NonExistentCommand } from './null/non-existent-command.ts';
|
import { NonExistentCommand } from './null/non-existent-command.ts';
|
||||||
import { UnityBuildCommand } from './build/unity-build-command.ts';
|
import { UnityBuildCommand } from './build/unity-build-command.ts';
|
||||||
import { CommandInterface } from './command-interface.ts';
|
import { CommandInterface } from './command-interface.ts';
|
||||||
import { UnityRemoteBuildCommand } from './remote/unity-remote-build-command.ts';
|
|
||||||
import { Engine } from '../model/engine/engine.ts';
|
import { Engine } from '../model/engine/engine.ts';
|
||||||
|
import { OpenConfigFolderCommand } from './config/open-config-folder-command.ts';
|
||||||
|
|
||||||
export class CommandFactory {
|
export class CommandFactory {
|
||||||
constructor() {}
|
constructor() {}
|
||||||
|
|
@ -14,27 +14,40 @@ export class CommandFactory {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public createCommand(command: string[]): CommandInterface {
|
public createCommand(commandArray: string[]): CommandInterface {
|
||||||
// Structure looks like: _: [ "build" ],
|
// Structure looks like: _: [ "build" ], or _: [ "config", "open" ]
|
||||||
const commandName = command[0];
|
const [command, ...subCommands] = commandArray;
|
||||||
|
|
||||||
|
if (command === 'config') {
|
||||||
|
return this.createConfigCommand(command, subCommands);
|
||||||
|
}
|
||||||
|
|
||||||
switch (this.engine) {
|
switch (this.engine) {
|
||||||
case Engine.unity:
|
case Engine.unity:
|
||||||
return this.createUnityCommand(commandName);
|
return this.createUnityCommand(command, subCommands);
|
||||||
default:
|
default:
|
||||||
throw new Error(`Engine ${this.engine} is not yet supported.`);
|
throw new Error(`Engine ${this.engine} is not yet supported.`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private createUnityCommand(commandName: string) {
|
private createConfigCommand(command: string, subCommands: string[]) {
|
||||||
switch (commandName) {
|
switch (subCommands[0]) {
|
||||||
|
case 'open':
|
||||||
|
return new OpenConfigFolderCommand(command);
|
||||||
|
default:
|
||||||
|
return new NonExistentCommand([command, ...subCommands].join(' '));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private createUnityCommand(command: string, subCommands: string[]) {
|
||||||
|
switch (command) {
|
||||||
case 'build':
|
case 'build':
|
||||||
return new UnityBuildCommand(commandName);
|
return new UnityBuildCommand(command);
|
||||||
|
|
||||||
// case 'remote-build':
|
// case 'remote-build':
|
||||||
// return new UnityRemoteBuildCommand(commandName);
|
// return new UnityRemoteBuildCommand(commandName);
|
||||||
// default:
|
default:
|
||||||
// return new NonExistentCommand(commandName);
|
return new NonExistentCommand([command, ...subCommands].join(' '));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
import { Options } from '../config/options.ts';
|
import { YargsInstance, YargsArguments } from '../dependencies.ts';
|
||||||
import { yargs } from '../dependencies.ts';
|
|
||||||
|
|
||||||
export interface CommandInterface {
|
export interface CommandInterface {
|
||||||
name: string;
|
name: string;
|
||||||
execute: (options: Options) => Promise<boolean>;
|
execute: (options: YargsArguments) => Promise<boolean>;
|
||||||
configureOptions: (instance: yargs.Argv) => Promise<void>;
|
configureOptions: (instance: YargsInstance) => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
import { CommandInterface } from '../command-interface.ts';
|
||||||
|
import { CommandBase } from '../command-base.ts';
|
||||||
|
import { YargsInstance, YargsArguments } from '../../dependencies.ts';
|
||||||
|
|
||||||
|
import { default as getHomeDir } from 'https://deno.land/x/dir@1.5.1/home_dir/mod.ts';
|
||||||
|
import { open } from 'https://deno.land/x/opener@v1.0.1/mod.ts';
|
||||||
|
|
||||||
|
export class OpenConfigFolderCommand extends CommandBase implements CommandInterface {
|
||||||
|
public async execute(options: YargsArguments): Promise<boolean> {
|
||||||
|
const cliStorageAbsolutePath = `${getHomeDir()}/.game-ci`;
|
||||||
|
await open(`file://${cliStorageAbsolutePath}/`);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async configureOptions(yargs: YargsInstance): Promise<void> {}
|
||||||
|
}
|
||||||
|
|
@ -1,16 +1,11 @@
|
||||||
import { CommandInterface } from '../command-interface.ts';
|
import { CommandInterface } from '../command-interface.ts';
|
||||||
import { Options } from '../../config/options.ts';
|
import { YargsInstance, YargsArguments } from '../../dependencies.ts';
|
||||||
|
import { CommandBase } from '../command-base.ts';
|
||||||
|
|
||||||
export class NonExistentCommand implements CommandInterface {
|
export class NonExistentCommand extends CommandBase implements CommandInterface {
|
||||||
public name: string;
|
public execute(options: YargsArguments): Promise<boolean> {
|
||||||
|
throw new Error(`Command "${this.name}" does not exist`);
|
||||||
constructor(name: string) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async execute(options: Options): Promise<boolean> {
|
public async configureOptions(yargs: YargsInstance): Promise<void> {}
|
||||||
throw new Error(`Command ${this.name} does not exist`);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async parseParameters() {}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,13 @@ class GameCI {
|
||||||
|
|
||||||
const success = await command.execute(options);
|
const success = await command.execute(options);
|
||||||
|
|
||||||
if (!success) log.warning(`${command.constructor.name} failed.`);
|
if (success) {
|
||||||
|
log.info(`${command.name} done.`);
|
||||||
|
} else {
|
||||||
|
log.warning(`${command.constructor.name} failed.`);
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// eslint-disable-next-line no-console
|
log.error(error);
|
||||||
console.error(error);
|
|
||||||
Deno.exit(1);
|
Deno.exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue