mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
feat: Allow multiple configurations to be used during startup
This commit is contained in:
parent
7884348c2f
commit
e050f8be93
@ -123,11 +123,11 @@ These parameters give you direct access
|
||||
to some commonly used settings:
|
||||
|
||||
| parameter name | default value | description |
|
||||
|------------------------|----------------------------|--------------------------------------------------------------------------------------------------------------------------------------|
|
||||
|------------------------|----------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `--port, -p` | `3000` | The TCP port on which the server should listen. |
|
||||
| `--baseUrl, -b` | `http://localhost:$PORT/` | The base URL used internally to generate URLs. Change this if your server does not run on `http://localhost:$PORT/`. |
|
||||
| `--loggingLevel, -l` | `info` | The detail level of logging; useful for debugging problems. Use `debug` for full information. |
|
||||
| `--config, -c` | `@css:config/default.json` | The configuration for the server. The default only stores data in memory; to persist to your filesystem, use `@css:config/file.json` |
|
||||
| `--config, -c` | `@css:config/default.json` | The configuration(s) for the server. The default only stores data in memory; to persist to your filesystem, use `@css:config/file.json` |
|
||||
| `--rootFilePath, -f` | `./` | Root folder where the server stores data, when using a file-based configuration. |
|
||||
| `--sparqlEndpoint, -s` | | URL of the SPARQL endpoint, when using a quadstore-based configuration. |
|
||||
| `--showStackTrace, -t` | false | Enables detailed logging on error output. |
|
||||
|
@ -12,8 +12,8 @@
|
||||
"options": {
|
||||
"alias": "c",
|
||||
"requiresArg": true,
|
||||
"type": "string",
|
||||
"describe": "The configuration for the server. The default only stores data in memory; to persist to your filesystem, use @css:config/file.json."
|
||||
"type": "array",
|
||||
"describe": "The configuration(s) for the server. The default only stores data in memory; to persist to your filesystem, use @css:config/file.json."
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -21,7 +21,7 @@ const DEFAULT_CLI_RESOLVER = 'urn:solid-server-app-setup:default:CliResolver';
|
||||
const DEFAULT_APP = 'urn:solid-server:default:App';
|
||||
|
||||
const CORE_CLI_PARAMETERS = {
|
||||
config: { type: 'string', alias: 'c', default: DEFAULT_CONFIG, requiresArg: true },
|
||||
config: { type: 'array', alias: 'c', default: [ DEFAULT_CONFIG ], requiresArg: true },
|
||||
loggingLevel: { type: 'string', alias: 'l', default: 'info', requiresArg: true, choices: LOG_LEVELS },
|
||||
mainModulePath: { type: 'string', alias: 'm', requiresArg: true },
|
||||
} as const;
|
||||
@ -48,13 +48,13 @@ export class AppRunner {
|
||||
* The values in `variableBindings` take priority over those in `shorthand`.
|
||||
*
|
||||
* @param loaderProperties - Components.js loader properties.
|
||||
* @param configFile - Path to the server config file.
|
||||
* @param configFile - Path to the server config file(s).
|
||||
* @param variableBindings - Bindings of Components.js variables.
|
||||
* @param shorthand - Shorthand values that need to be resolved.
|
||||
*/
|
||||
public async run(
|
||||
loaderProperties: IComponentsManagerBuilderOptions<App>,
|
||||
configFile: string,
|
||||
configFile: string | string[],
|
||||
variableBindings?: VariableBindings,
|
||||
shorthand?: Shorthand,
|
||||
): Promise<void> {
|
||||
@ -75,13 +75,13 @@ export class AppRunner {
|
||||
* The values in `variableBindings` take priority over those in `shorthand`.
|
||||
*
|
||||
* @param loaderProperties - Components.js loader properties.
|
||||
* @param configFile - Path to the server config file.
|
||||
* @param configFile - Path to the server config file(s).
|
||||
* @param variableBindings - Bindings of Components.js variables.
|
||||
* @param shorthand - Shorthand values that need to be resolved.
|
||||
*/
|
||||
public async create(
|
||||
loaderProperties: IComponentsManagerBuilderOptions<App>,
|
||||
configFile: string,
|
||||
configFile: string | string[],
|
||||
variableBindings?: VariableBindings,
|
||||
shorthand?: Shorthand,
|
||||
): Promise<App> {
|
||||
@ -152,16 +152,16 @@ export class AppRunner {
|
||||
typeChecking: false,
|
||||
};
|
||||
|
||||
const config = resolveAssetPath(params.config);
|
||||
const configs = params.config.map(resolveAssetPath);
|
||||
|
||||
// Create the Components.js manager used to build components from the provided config
|
||||
let componentsManager: ComponentsManager<any>;
|
||||
try {
|
||||
componentsManager = await this.createComponentsManager(loaderProperties, config);
|
||||
componentsManager = await this.createComponentsManager(loaderProperties, configs);
|
||||
} catch (error: unknown) {
|
||||
// Print help of the expected core CLI parameters
|
||||
const help = await yargv.getHelp();
|
||||
this.resolveError(`${help}\n\nCould not build the config files from ${config}`, error);
|
||||
this.resolveError(`${help}\n\nCould not build the config files from ${configs}`, error);
|
||||
}
|
||||
|
||||
// Build the CLI components and use them to generate values for the Components.js variables
|
||||
@ -176,10 +176,12 @@ export class AppRunner {
|
||||
*/
|
||||
public async createComponentsManager<T>(
|
||||
loaderProperties: IComponentsManagerBuilderOptions<T>,
|
||||
configFile: string,
|
||||
configFile: string | string[],
|
||||
): Promise<ComponentsManager<T>> {
|
||||
const componentsManager = await ComponentsManager.build(loaderProperties);
|
||||
await componentsManager.configRegistry.register(configFile);
|
||||
for (const config of Array.isArray(configFile) ? configFile : [ configFile ]) {
|
||||
await componentsManager.configRegistry.register(config);
|
||||
}
|
||||
return componentsManager;
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ describe('An instantiated CliResolver', (): void => {
|
||||
'-s', 's',
|
||||
'-w', '2',
|
||||
]);
|
||||
expect(shorthand.config).toBe('c');
|
||||
expect(shorthand.config).toEqual([ 'c' ]);
|
||||
expect(shorthand.mainModulePath).toBe('m');
|
||||
expect(shorthand.loggingLevel).toBe('l');
|
||||
expect(shorthand.baseUrl).toBe('b');
|
||||
|
@ -281,6 +281,37 @@ describe('AppRunner', (): void => {
|
||||
expect(app.start).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
it('can apply multiple configurations.', async(): Promise<void> => {
|
||||
const params = [
|
||||
'node', 'script',
|
||||
'-c', 'config1.json', 'config2.json',
|
||||
];
|
||||
await expect(new AppRunner().createCli(params)).resolves.toBe(app);
|
||||
|
||||
expect(ComponentsManager.build).toHaveBeenCalledTimes(1);
|
||||
expect(ComponentsManager.build).toHaveBeenCalledWith({
|
||||
dumpErrorState: true,
|
||||
logLevel: 'info',
|
||||
mainModulePath: joinFilePath(__dirname, '../../../'),
|
||||
typeChecking: false,
|
||||
});
|
||||
expect(manager.configRegistry.register).toHaveBeenCalledTimes(2);
|
||||
expect(manager.configRegistry.register).toHaveBeenNthCalledWith(1, '/var/cwd/config1.json');
|
||||
expect(manager.configRegistry.register).toHaveBeenNthCalledWith(2, '/var/cwd/config2.json');
|
||||
expect(manager.instantiate).toHaveBeenCalledTimes(2);
|
||||
expect(manager.instantiate).toHaveBeenNthCalledWith(1, 'urn:solid-server-app-setup:default:CliResolver', {});
|
||||
expect(cliExtractor.handleSafe).toHaveBeenCalledTimes(1);
|
||||
expect(cliExtractor.handleSafe).toHaveBeenCalledWith(params);
|
||||
expect(shorthandResolver.handleSafe).toHaveBeenCalledTimes(1);
|
||||
expect(shorthandResolver.handleSafe).toHaveBeenCalledWith(defaultParameters);
|
||||
expect(manager.instantiate).toHaveBeenNthCalledWith(1, 'urn:solid-server-app-setup:default:CliResolver', {});
|
||||
expect(manager.instantiate).toHaveBeenNthCalledWith(2,
|
||||
'urn:solid-server:default:App',
|
||||
{ variables: defaultVariables });
|
||||
expect(app.clusterManager.isSingleThreaded()).toBeFalsy();
|
||||
expect(app.start).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
it('uses the default process.argv in case none are provided.', async(): Promise<void> => {
|
||||
const { argv } = process;
|
||||
const argvParameters = [
|
||||
|
Loading…
x
Reference in New Issue
Block a user