Skip to content

Commit

Permalink
feat(cli): log config file loading status (#95)
Browse files Browse the repository at this point in the history
* docs: explain tests process

* feat(e2e): add tests structure

* feat(cli): add logging on config file loading

* chore(e2e): adapt tests

* fix(cli): use generic type
  • Loading branch information
EdouardDem committed Sep 12, 2024
1 parent 26ae8fd commit 97f4b15
Show file tree
Hide file tree
Showing 10 changed files with 120 additions and 24 deletions.
16 changes: 8 additions & 8 deletions packages/cli/src/lib/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,18 @@ export async function initContext(
programOptions: object,
commandOptions: object,
) {
// Set temporary logger, in case of error when loading the config
Container.set(
LOGGER,
Logger({
transport: getPinoTransport(),
level: 'error',
}),
);
// Set temporary logger. This allows the config process to log infos and errors
const tempLogger = Logger({
transport: getPinoTransport(),
level: 'info',
});
Container.set(LOGGER, tempLogger);
// Get the config service
const config = Container.get(ConfigService);
// Set the options
config.setOptions(programOptions, commandOptions);
// Flush previous logs
tempLogger.flush();
// Define the logger
Container.set(
LOGGER,
Expand Down
29 changes: 22 additions & 7 deletions packages/cli/src/lib/services/config/config.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
import { Service } from 'typedi';
import { Container, Service } from 'typedi';
import {
CollectionHooks,
CollectionName,
CollectionPreservableIdName,
ConfigFileOptions,
DirectusConfigWithCredentials,
DirectusConfigWithToken,
CollectionName,
CollectionHooks,
SnapshotHooks,
OptionName,
Options,
CollectionPreservableIdName,
SnapshotHooks,
} from './interfaces';
import Path from 'path';
import { Cacheable } from 'typescript-cacheable';
import { ConfigFileLoader } from './config-file-loader';
import { zodParse } from '../../helpers';
import { getChildLogger, zodParse } from '../../helpers';
import deepmerge from 'deepmerge';
import { DefaultConfig, DefaultConfigPaths } from './default-config';
import { CollectionsList, OptionsSchema } from './schema';
import { LOGGER } from '../../constants';
import pino from 'pino';

@Service()
export class ConfigService {
Expand Down Expand Up @@ -185,6 +187,7 @@ export class ConfigService {

@Cacheable()
protected getFileOptions(): ConfigFileOptions | undefined {
const logger = this.getLogger();
const customConfigPath = this.programOptions?.configPath;
const possiblePaths = [
...(customConfigPath ? [Path.resolve(customConfigPath)] : []),
Expand All @@ -195,10 +198,22 @@ export class ConfigService {
for (const configPath of possiblePaths) {
const config = new ConfigFileLoader(configPath).get();
if (config) {
logger.info(`Loaded config file from ${configPath}`);
return config;
}
}

logger.info(
`No config file found. Tried path: \n- ${possiblePaths.join('\n- ')}`,
);
return undefined;
}

/**
* Returns a temporary logger as it may be changed by another one with specific options
* See loader.ts file for more information
*/
protected getLogger() {
const baseLogger = Container.get<pino.Logger>(LOGGER);
return getChildLogger(baseLogger, 'config');
}
}
22 changes: 22 additions & 0 deletions packages/e2e/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,25 @@ Therefore, you need to have a the dependencies installed in the host machine.
You must install the following libraries:

- `libvips`: `sudo apt install libvips` (https://libvips.github.io/libvips/install.html)

## Running the tests

First, you need to build the CLI and the extension. Go to the root of the repository and run:

```bash
npm run build
```

Then, you can run the tests:

```bash
npm run test
```

If you have edited the extension or the CLI, you need to rebuild them.

### Running a single test

By design, the tests are ran sequentially. This is done to avoid conflicts between Directus servers.

To run a single test, you need to edit the test file and change the `it` function to `fit`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module.exports = {
};
3 changes: 1 addition & 2 deletions packages/e2e/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@
"directus": "directus",
"directus-sync": "directus-sync",
"bootstrap": "./bootstrap.sh",
"test": "rm -f ./logs/*.log && jasmine",
"build-test": "npm run build && npm run test",
"test": "npm run build && rm -f ./logs/*.log && jasmine",
"upgrade": "zx upgrade-directus-version.mjs && zx update-dumps-from-current-version.mjs"
},
"keywords": [],
Expand Down
44 changes: 44 additions & 0 deletions packages/e2e/spec/config/config-path-info.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { Context } from '../helpers/index.js';

export const configPathInfo = (context: Context) => {
it('ensure logs show info about missing config file when wrong path is provided', async () => {
// Init sync client
const sync = await context.getSync(
'sources/empty-collections',
'wrong-path/directus-sync.config.cjs',
);

const output = await sync.diff();
const first = output.shift();

expect(first?.msg).toContain('No config file found');
expect(first?.msg).toContain('wrong-path/directus-sync.config.cjs');
});

it('ensure log shows info about missing config file for default files', async () => {
// Init sync client
const sync = await context.getSync('sources/empty-collections');

const output = await sync.diff();
const first = output.shift();

expect(first?.msg).toContain('No config file found');
expect(first?.msg).toContain('e2e/directus-sync.config.cjs');
expect(first?.msg).toContain('e2e/directus-sync.config.js');
expect(first?.msg).toContain('e2e/directus-sync.config.json');
});

it('ensure logs show info when config path exists', async () => {
// Init sync client
const sync = await context.getSync(
'sources/empty-collections',
'config-path-info/directus-sync.config.cjs',
);

const output = await sync.diff();
const first = output.shift();

expect(first?.msg).toContain('Loaded config file from');
expect(first?.msg).toContain('config-path-info/directus-sync.config.cjs');
});
};
1 change: 1 addition & 0 deletions packages/e2e/spec/config/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './config-path-info.js';
3 changes: 3 additions & 0 deletions packages/e2e/spec/entrypoint.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {
updateOperationsWithConflicts,
} from './operations/index.js';
import { updateDefaultData } from './default-data/index.js';
import { configPathInfo } from './config/index.js';

jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;

Expand Down Expand Up @@ -92,6 +93,8 @@ describe('Tests entrypoint ->', () => {
includeSomeCollections(context);
noSnapshot(context);

configPathInfo(context);

insertDuplicatedPermissions(context);
removePermissionDuplicates(context);
pullAndPushPublicPermissions(context);
Expand Down
12 changes: 9 additions & 3 deletions packages/e2e/spec/helpers/sdk/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import fs from 'fs-extra';
import { DirectusSync } from './directus-sync.js';
import { SqliteClient } from './sqlite-client.js';
import { sleep } from './async/index.js';
import { DirectusSyncArgs } from './interfaces';

const dumpBaseDirectory = Path.resolve('dumps');
const configBaseDirectory = Path.resolve('configs');
Expand Down Expand Up @@ -45,21 +46,26 @@ export class Context {
return this.instance;
}

async getSync(dumpFolder: string, configPath?: string) {
async getSync(
dumpFolder: string,
configPath?: string,
factory: new (options: DirectusSyncArgs) => DirectusSync = DirectusSync,
): Promise<DirectusSync> {
const dumpPath = Path.resolve(dumpBaseDirectory, dumpFolder);
const clearDumpPath = dumpFolder.startsWith('temp');
if (clearDumpPath) {
fs.rmSync(dumpPath, { recursive: true, force: true });
}
const directus = this.getDirectus();
const instance = this.getInstance();
return new DirectusSync({
const options = {
token: await directus.requireToken(),
url: instance.getUrl(),
dumpPath,
configPath: configPath
? Path.resolve(configBaseDirectory, configPath)
: undefined,
});
};
return new factory(options);
}
}
12 changes: 8 additions & 4 deletions packages/e2e/spec/helpers/sdk/directus-sync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,16 +123,20 @@ export class DirectusSync {
}

protected getOptionsArgs(): string[] {
const requiredArgs = [
const requiredArgs = this.getRequiredArgs();
return this.options.configPath
? [...requiredArgs, `--config-path`, this.options.configPath]
: requiredArgs;
}

protected getRequiredArgs(): string[] {
return [
`--directus-token`,
this.options.token,
`--directus-url`,
this.options.url,
'--debug',
];
return this.options.configPath
? [...requiredArgs, `--config-path`, this.options.configPath]
: requiredArgs;
}

protected getLogTransport(logFilePath: string): LoggerOptions['transport'] {
Expand Down

0 comments on commit 97f4b15

Please sign in to comment.