From ba4f7ff26c77636f7b367de316409001cd173692 Mon Sep 17 00:00:00 2001 From: Ruben Verborgh Date: Fri, 1 Jan 2021 18:25:35 +0100 Subject: [PATCH] feat: Add mainModulePath and globalModules CLI flags. --- src/init/CliRunner.ts | 29 +++++++++++++------- test/unit/init/CliRunner.test.ts | 47 +++++++++++++++++++++----------- 2 files changed, 50 insertions(+), 26 deletions(-) diff --git a/src/init/CliRunner.ts b/src/init/CliRunner.ts index 50a416fb3..86f129b77 100644 --- a/src/init/CliRunner.ts +++ b/src/init/CliRunner.ts @@ -16,20 +16,15 @@ export class CliRunner { * Generic run function for starting the server from a given config * @param args - Command line arguments. * @param stderr - Standard error stream. - * @param loaderProperties - Components loader properties. */ public run({ argv = process.argv, stderr = process.stderr, - loaderProperties = { - mainModulePath: path.join(__dirname, '../../'), - }, }: { argv?: string[]; stdin?: ReadStream; stdout?: WriteStream; stderr?: WriteStream; - loaderProperties?: LoaderProperties; } = {}): void { // Parse the command-line arguments const { argv: params } = yargs(argv.slice(2)) @@ -37,18 +32,22 @@ export class CliRunner { .options({ baseUrl: { type: 'string', alias: 'b' }, config: { type: 'string', alias: 'c' }, + globalModules: { type: 'boolean', alias: 'g' }, loggingLevel: { type: 'string', alias: 'l', default: 'info' }, + mainModulePath: { type: 'string', alias: 'm' }, + podTemplateFolder: { type: 'string', alias: 't' }, port: { type: 'number', alias: 'p', default: 3000 }, rootFilePath: { type: 'string', alias: 'f' }, sparqlEndpoint: { type: 'string', alias: 's' }, - podTemplateFolder: { type: 'string', alias: 't' }, }) .help(); // Gather settings for instantiating the server - const configFile = params.config ? - path.join(process.cwd(), params.config) : - path.join(__dirname, '/../../config/config-default.json'); + const loaderProperties: LoaderProperties = { + mainModulePath: this.resolvePath(params.mainModulePath), + scanGlobal: params.globalModules, + }; + const configFile = this.resolvePath(params.config, 'config/config-default.json'); const variables = this.createVariables(params); // Create and execute the server initializer @@ -67,6 +66,16 @@ export class CliRunner { }); } + /** + * Resolves a path relative to the current working directory, + * falling back to a path relative to this module. + */ + protected resolvePath(cwdPath?: string | null, modulePath = ''): string { + return typeof cwdPath === 'string' ? + path.join(process.cwd(), cwdPath) : + path.join(__dirname, '../../', modulePath); + } + /** * Translates command-line parameters into configuration variables */ @@ -79,7 +88,7 @@ export class CliRunner { 'urn:solid-server:default:variable:rootFilePath': params.rootFilePath ?? process.cwd(), 'urn:solid-server:default:variable:sparqlEndpoint': params.sparqlEndpoint, 'urn:solid-server:default:variable:podTemplateFolder': - params.podTemplateFolder ?? path.join(__dirname, '../../templates'), + params.podTemplateFolder ?? this.resolvePath(null, 'templates'), }; } diff --git a/test/unit/init/CliRunner.test.ts b/test/unit/init/CliRunner.test.ts index 80dafb4d5..10fb3544b 100644 --- a/test/unit/init/CliRunner.test.ts +++ b/test/unit/init/CliRunner.test.ts @@ -3,8 +3,6 @@ import { Loader } from 'componentsjs'; import { CliRunner } from '../../../src/init/CliRunner'; import type { Initializer } from '../../../src/init/Initializer'; -const mainModulePath = path.join(__dirname, '../../../'); - const initializer: jest.Mocked = { handleSafe: jest.fn(), } as any; @@ -19,6 +17,7 @@ jest.mock('componentsjs', (): any => ({ Loader: jest.fn((): Loader => loader), })); +jest.spyOn(process, 'cwd').mockReturnValue('/var/cwd'); const write = jest.spyOn(process.stderr, 'write').mockImplementation(jest.fn()); const exit = jest.spyOn(process, 'exit').mockImplementation(jest.fn() as any); @@ -34,7 +33,9 @@ describe('CliRunner', (): void => { await initializer.handleSafe(); expect(Loader).toHaveBeenCalledTimes(1); - expect(Loader).toHaveBeenCalledWith({ mainModulePath }); + expect(Loader).toHaveBeenCalledWith({ + mainModulePath: path.join(__dirname, '../../../'), + }); expect(loader.instantiateFromUrl).toHaveBeenCalledTimes(1); expect(loader.instantiateFromUrl).toHaveBeenCalledWith( 'urn:solid-server:default:Initializer', @@ -61,29 +62,36 @@ describe('CliRunner', (): void => { new CliRunner().run({ argv: [ 'node', 'script', - '-p', '4000', '-b', 'http://pod.example/', '-c', 'myconfig.json', '-f', '/root', - '-s', 'http://localhost:5000/sparql', + '-g', '-l', 'debug', + '-m', 'module/path', + '-p', '4000', + '-s', 'http://localhost:5000/sparql', '-t', 'templates', ], }); await initializer.handleSafe(); + expect(Loader).toHaveBeenCalledTimes(1); + expect(Loader).toHaveBeenCalledWith({ + mainModulePath: '/var/cwd/module/path', + scanGlobal: true, + }); expect(loader.instantiateFromUrl).toHaveBeenCalledWith( 'urn:solid-server:default:Initializer', - path.join(process.cwd(), 'myconfig.json'), + '/var/cwd/myconfig.json', undefined, { variables: { - 'urn:solid-server:default:variable:port': 4000, 'urn:solid-server:default:variable:baseUrl': 'http://pod.example/', - 'urn:solid-server:default:variable:rootFilePath': '/root', - 'urn:solid-server:default:variable:sparqlEndpoint': 'http://localhost:5000/sparql', 'urn:solid-server:default:variable:loggingLevel': 'debug', 'urn:solid-server:default:variable:podTemplateFolder': 'templates', + 'urn:solid-server:default:variable:port': 4000, + 'urn:solid-server:default:variable:rootFilePath': '/root', + 'urn:solid-server:default:variable:sparqlEndpoint': 'http://localhost:5000/sparql', }, }, ); @@ -93,29 +101,36 @@ describe('CliRunner', (): void => { new CliRunner().run({ argv: [ 'node', 'script', - '--port', '4000', '--baseUrl', 'http://pod.example/', '--config', 'myconfig.json', + '--globalModules', + '--loggingLevel', 'debug', + '--mainModulePath', 'module/path', + '--podTemplateFolder', 'templates', + '--port', '4000', '--rootFilePath', '/root', '--sparqlEndpoint', 'http://localhost:5000/sparql', - '--loggingLevel', 'debug', - '--podTemplateFolder', 'templates', ], }); await initializer.handleSafe(); + expect(Loader).toHaveBeenCalledTimes(1); + expect(Loader).toHaveBeenCalledWith({ + mainModulePath: '/var/cwd/module/path', + scanGlobal: true, + }); expect(loader.instantiateFromUrl).toHaveBeenCalledWith( 'urn:solid-server:default:Initializer', - path.join(process.cwd(), 'myconfig.json'), + '/var/cwd/myconfig.json', undefined, { variables: { - 'urn:solid-server:default:variable:port': 4000, 'urn:solid-server:default:variable:baseUrl': 'http://pod.example/', - 'urn:solid-server:default:variable:rootFilePath': '/root', - 'urn:solid-server:default:variable:sparqlEndpoint': 'http://localhost:5000/sparql', 'urn:solid-server:default:variable:loggingLevel': 'debug', 'urn:solid-server:default:variable:podTemplateFolder': 'templates', + 'urn:solid-server:default:variable:port': 4000, + 'urn:solid-server:default:variable:rootFilePath': '/root', + 'urn:solid-server:default:variable:sparqlEndpoint': 'http://localhost:5000/sparql', }, }, );