chore(command): set command handle by ipc server or not (#2660)

* chore: tmp commit

* feat: app command

* chore: return error when not handle by ipc server

* chore: command handle by ipc server

* chore: api name

* Update pm.ts

---------

Co-authored-by: chenos <chenlinxh@gmail.com>
This commit is contained in:
ChengLei Shao 2023-09-19 14:39:54 +08:00 committed by GitHub
parent 4fffa07998
commit 630c6f2d79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 131 additions and 21 deletions

View File

@ -0,0 +1,43 @@
import { DataTypes, mockDatabase } from '@nocobase/database';
import Application, { ApplicationOptions } from '../application';
const mockServer = (options?: ApplicationOptions) => {
return new Application({
database: mockDatabase(),
acl: false,
...options,
});
};
describe('app command', () => {
let app: Application;
afterEach(async () => {
if (app) {
await app.destroy();
}
});
beforeEach(async () => {
app = mockServer();
await app.load();
await app.install();
});
it('should test command should handle by IPC Server or not', () => {
app.command('testaa').ipc();
app.command('testbb');
expect(app.cli.parseHandleByIPCServer(['node', 'cli', 'nocobase', 'testaa'])).toBeTruthy();
expect(app.cli.parseHandleByIPCServer(['node', 'cli', 'nocobase', 'testbb'])).toBeFalsy();
});
it('should test sub command should handle by IPC Server or not', () => {
const subParent = app.command('subparent');
subParent.command('testaa').ipc();
subParent.command('testbb');
expect(app.cli.parseHandleByIPCServer(['node', 'cli', 'nocobase', 'subparent', 'testaa'])).toBeTruthy();
expect(app.cli.parseHandleByIPCServer(['node', 'cli', 'nocobase', 'subparent', 'testbb'])).toBeFalsy();
});
});

View File

@ -0,0 +1,41 @@
import { Command } from 'commander';
export class AppCommand extends Command {
private _handleByIPCServer = false;
ipc() {
this._handleByIPCServer = true;
return this;
}
isHandleByIPCServer() {
return this._handleByIPCServer;
}
createCommand(name?: string): AppCommand {
return new AppCommand(name);
}
parseHandleByIPCServer(argv, parseOptions?): Boolean {
//@ts-ignore
const userArgs = this._prepareUserArgs(argv, parseOptions);
if (userArgs[0] === 'nocobase') {
userArgs.shift();
}
let lastCommand = this;
for (const arg of userArgs) {
// @ts-ignore
const subCommand = lastCommand._findCommand(arg);
if (subCommand) {
lastCommand = subCommand;
} else {
break;
}
}
return lastCommand && lastCommand.isHandleByIPCServer();
}
}

View File

@ -22,6 +22,7 @@ import { ApplicationVersion } from './helpers/application-version';
import { Locale } from './locale';
import { Plugin } from './plugin';
import { InstallOptions, PluginManager } from './plugin-manager';
import { AppCommand } from './app-command';
const packageJson = require('../package.json');
@ -163,7 +164,7 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
return this._cache;
}
protected _cli: Command;
protected _cli: AppCommand;
get cli() {
return this._cli;
@ -286,7 +287,7 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
return this.resourcer.registerActions(handlers);
}
command(name: string, desc?: string, opts?: CommandOptions): Command {
command(name: string, desc?: string, opts?: CommandOptions): AppCommand {
return this.cli.command(name, desc, opts).allowUnknownOption();
}
@ -363,7 +364,7 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
}
createCli() {
const command = new Command('nocobase')
const command = new AppCommand('nocobase')
.usage('[command] [options]')
.hook('preAction', async (_, actionCommand) => {
this._actionCommand = actionCommand;

View File

@ -3,6 +3,7 @@ import Application from '../application';
export default (app: Application) => {
app
.command('install')
.ipc()
.option('-f, --force')
.option('-c, --clean')
.action(async (...cliArgs) => {

View File

@ -6,18 +6,19 @@ export default (app: Application) => {
const pm = app.command('pm');
pm.command('create')
.ipc()
.arguments('plugin')
.action(async (plugin) => {
await app.pm.create(plugin);
});
pm.command('add')
.ipc()
.argument('<pkg>')
.option('--registry [registry]')
.option('--auth-token [authToken]')
.option('--version [version]')
.action(async (name, options, cli) => {
console.log('pm.add', name, options);
try {
await app.pm.addViaCLI(name, _.cloneDeep(options));
} catch (error) {
@ -26,6 +27,7 @@ export default (app: Application) => {
});
pm.command('update')
.ipc()
.argument('<packageName>')
.option('--path [path]')
.option('--url [url]')
@ -44,6 +46,7 @@ export default (app: Application) => {
});
pm.command('enable')
.ipc()
.arguments('<plugins...>')
.action(async (plugins) => {
try {
@ -54,6 +57,7 @@ export default (app: Application) => {
});
pm.command('disable')
.ipc()
.arguments('<plugins...>')
.action(async (plugins) => {
try {
@ -64,6 +68,7 @@ export default (app: Application) => {
});
pm.command('remove')
.ipc()
.arguments('<plugins...>')
.action(async (plugins) => {
await app.pm.remove(plugins);

View File

@ -1,9 +1,12 @@
import Application from '../application';
export default (app: Application) => {
app.command('restart').action(async (...cliArgs) => {
await app.restart({
cliArgs,
app
.command('restart')
.ipc()
.action(async (...cliArgs) => {
await app.restart({
cliArgs,
});
});
});
};

View File

@ -1,9 +1,12 @@
import Application from '../application';
export default (app: Application) => {
app.command('stop').action(async (...cliArgs) => {
await app.stop({
cliArgs,
app
.command('stop')
.ipc()
.action(async (...cliArgs) => {
await app.stop({
cliArgs,
});
});
});
};

View File

@ -5,10 +5,13 @@ import Application from '../application';
* TODO
*/
export default (app: Application) => {
app.command('upgrade').action(async (...cliArgs) => {
const [opts] = cliArgs;
console.log('upgrading...');
await app.upgrade();
console.log(chalk.green(`✨ NocoBase has been upgraded to v${app.getVersion()}`));
});
app
.command('upgrade')
.ipc()
.action(async (...cliArgs) => {
const [opts] = cliArgs;
console.log('upgrading...');
await app.upgrade();
console.log(chalk.green(`✨ NocoBase has been upgraded to v${app.getVersion()}`));
});
};

View File

@ -228,10 +228,12 @@ export class Gateway extends EventEmitter {
ipcClient = await this.tryConnectToIPCServer();
if (ipcClient) {
await ipcClient.write({ type: 'passCliArgv', payload: { argv: process.argv } });
// should wait for server response
const response: any = await ipcClient.write({ type: 'passCliArgv', payload: { argv: process.argv } });
ipcClient.close();
return;
if (response.type !== 'error' || response.payload.message !== 'Not handle by ipc server') {
return;
}
}
}

View File

@ -66,6 +66,14 @@ export class IPCSocketServer {
const argv = payload.argv;
const mainApp = await AppSupervisor.getInstance().getApp('main');
const cli = mainApp.cli;
if (
!cli.parseHandleByIPCServer(argv, {
from: 'node',
})
) {
throw new Error('Not handle by ipc server');
}
return mainApp.runAsCLI(argv, {
from: 'node',