Skip to content

Commit

Permalink
refactor(build-env): refactor logging to formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
BioPhoton committed Sep 13, 2024
1 parent 6b80130 commit 2567641
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 139 deletions.
27 changes: 9 additions & 18 deletions tooling/build-env/src/internal/utils/logging.spec.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,18 @@
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { error, info } from './logging';
import { describe, expect, it } from 'vitest';
import { bold, gray, red } from 'ansis';
import { formatError, formatInfo } from './logging';

describe('info', () => {
let consoleInfoSpy;
let consoleErrorSpy;
beforeEach(() => {
consoleInfoSpy = vi.spyOn(console, 'info').mockImplementation(vi.fn());
consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(vi.fn());
});

it('should log info', () => {
info('message', 'token');
expect(consoleInfoSpy).toHaveBeenCalledTimes(1);
expect(consoleInfoSpy).toHaveBeenCalledWith(
describe('formatInfo', () => {
it('should format info message correctly', () => {
expect(formatInfo('message', 'token')).toBe(
`${gray('>')} ${gray(bold('token'))} ${'message'}`
);
});
});

it('should log error', () => {
error('message', 'token');
expect(consoleErrorSpy).toHaveBeenCalledTimes(1);
expect(consoleErrorSpy).toHaveBeenCalledWith(
describe('formatError', () => {
it('should format error message correctly', () => {
expect(formatError('message', 'token')).toBe(
`${red('>')} ${red(bold('token'))} ${'message'}`
);
});
Expand Down
8 changes: 4 additions & 4 deletions tooling/build-env/src/internal/utils/logging.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { bold, gray, red } from 'ansis';

export function info(message: string, token: string) {
console.info(`${gray('>')} ${gray(bold(token))} ${message}`);
export function formatInfo(message: string, token: string) {
return `${gray('>')} ${gray(bold(token))} ${message}`;
}
export function error(message: string, token: string) {
console.error(`${red('>')} ${red(bold(token))} ${message}`);
export function formatError(message: string, token: string) {
return `${red('>')} ${red(bold(token))} ${message}`;
}
27 changes: 16 additions & 11 deletions tooling/build-env/src/internal/utils/npm.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
import { execFileSync } from 'node:child_process';
import { join } from 'node:path';
import { ensureDirectoryExists } from './file-system';
import { error, info } from './logging';
import * as process from 'process';
import { formatError, formatInfo } from './logging';
import { logger } from '@nx/devkit';

export function logInfo(msg: string) {
info(msg, 'Npm Env: ');
}

export function logError(msg: string) {
error(msg, 'Npm Env: ');
}
export const NPM_ENV_TOKEN = 'Npm Env: ';

/*
@TODO:
This is here to be able to better mock chdir.
We should definitely find a better solution that mocks it directly and avoids this wrapper completely.
*/
Expand All @@ -25,15 +20,25 @@ export async function setupNpmWorkspace(
verbose?: boolean
): Promise<void> {
if (verbose) {
logInfo(`Execute: npm init in directory ${environmentRoot}`);
logger.info(
formatInfo(
`Execute: npm init in directory ${environmentRoot}`,
NPM_ENV_TOKEN
)
);
}
const cwd = process.cwd();
await ensureDirectoryExists(environmentRoot);
chdir(join(cwd, environmentRoot));
try {
execFileSync('npm', ['init', '--force']).toString();
} catch (error) {
logError(`Error creating NPM workspace: ${(error as Error).message}`);
logger.error(
formatError(
`Error creating NPM workspace: ${(error as Error).message}`,
NPM_ENV_TOKEN
)
);
} finally {
chdir(cwd);
}
Expand Down
46 changes: 8 additions & 38 deletions tooling/build-env/src/internal/utils/npm.unit-test.ts
Original file line number Diff line number Diff line change
@@ -1,66 +1,36 @@
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { bold, gray, red } from 'ansis';
import { bold, red } from 'ansis';
import { MEMFS_VOLUME } from '@org/test-utils';
import { logError, logInfo, setupNpmWorkspace } from './npm';

describe('logInfo', () => {
let consoleInfoSpy;
beforeEach(() => {
consoleInfoSpy = vi.spyOn(console, 'info').mockImplementation(vi.fn());
});

it('should log info', () => {
logInfo('message');
expect(consoleInfoSpy).toHaveBeenCalledTimes(1);
expect(consoleInfoSpy).toHaveBeenCalledWith(
`${gray('>')} ${gray(bold('Npm Env: '))} ${'message'}`
);
});
});

describe('logError', () => {
let consoleErrorSpy;
beforeEach(() => {
consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(vi.fn());
});

it('should log error', () => {
logError('message');
expect(consoleErrorSpy).toHaveBeenCalledTimes(1);
expect(consoleErrorSpy).toHaveBeenCalledWith(
`${red('>')} ${red(bold('Npm Env: '))} ${'message'}`
);
});
});
import { setupNpmWorkspace } from './npm';

describe.skip('setupNpmWorkspace', () => {
let cwdSpy;
let chdirSpy;
let logInfoSpy;
let consoleInfoSpy;

beforeEach(() => {
cwdSpy = vi.spyOn(process, 'cwd').mockReturnValue(MEMFS_VOLUME);
chdirSpy = vi.spyOn(process, 'chdir').mockImplementation(vi.fn());
logInfoSpy = vi.mocked(logInfo).mockImplementation(vi.fn());
consoleInfoSpy = vi.spyOn(console, 'info').mockImplementation(vi.fn());
});

afterEach(() => {
cwdSpy.mockRestore();
chdirSpy.mockRestore();
logInfoSpy.mockRestore();
consoleInfoSpy.mockRestore();
});

it('should create npm workspace in given folder', () => {
setupNpmWorkspace('tmp');
expect(chdirSpy).toHaveBeenCalledTimes(1);
expect(chdirSpy).toHaveBeenCalledWith('tmp');
expect(logInfoSpy).not.toHaveBeenCalled();
expect(consoleInfoSpy).not.toHaveBeenCalled();
});

it('should call infoLog if verbose is given', () => {
setupNpmWorkspace('tmp', true);
expect(logInfoSpy).toHaveBeenCalledTimes(1);
expect(logInfoSpy).toHaveBeenCalledWith(
expect(consoleInfoSpy).toHaveBeenCalledTimes(1);
expect(consoleInfoSpy).toHaveBeenCalledWith(
`${red('>')} ${red(bold('Npm Env: '))} Execute: npm init in directory tmp`
);
});
Expand Down
46 changes: 26 additions & 20 deletions tooling/build-env/src/internal/verdaccio/verdaccio-npm-env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,13 @@ import {
} from './verdaccio-registry';
import { writeFile } from 'node:fs/promises';
import { setupNpmWorkspace } from '../utils/npm';
import { error, info } from '../utils/logging';
import { formatInfo } from '../utils/logging';
import { objectToCliArgs } from '../utils/terminal';
import { execSync } from 'node:child_process';
import { VERDACCIO_REGISTRY_JSON } from './constants';
import { logger } from '@nx/devkit';

function logInfo(msg: string) {
info(msg, 'Verdaccio Env: ');
}

function errorLog(msg: string) {
error(msg, 'Verdaccio Env: ');
}

export const verdaccioEnvLogger = {
info: logInfo,
error: errorLog,
};
export const VERDACCIO_ENV_TOKEN = 'Verdaccio Env: ';

export type Environment = {
root: string;
Expand Down Expand Up @@ -63,15 +53,23 @@ export async function bootstrapEnvironment({
root: environmentRoot,
};

logInfo(
`Save active verdaccio registry data to file: ${activeRegistry.root}`
logger.info(
formatInfo(
`Save active verdaccio registry data to file: ${activeRegistry.root}`,
VERDACCIO_ENV_TOKEN
)
);
await writeFile(
join(activeRegistry.root, VERDACCIO_REGISTRY_JSON),
JSON.stringify(activeRegistry.registry, null, 2)
);

logInfo(`Environment ready under: ${activeRegistry.root}`);
logger.info(
formatInfo(
`Environment ready under: ${activeRegistry.root}`,
VERDACCIO_ENV_TOKEN
)
);

return activeRegistry;
}
Expand All @@ -87,7 +85,9 @@ export function configureRegistry(
userconfig,
}).join(' ')}`;
if (verbose) {
logInfo(`Set registry:\n${setRegistry}`);
logger.info(
formatInfo(`Set registry:\n${setRegistry}`, VERDACCIO_ENV_TOKEN)
);
}
execSync(setRegistry);

Expand All @@ -103,7 +103,9 @@ export function configureRegistry(
{ userconfig }
).join(' ')}`;
if (verbose) {
logInfo(`Set authToken:\n${setAuthToken}`);
logger.info(
formatInfo(`Set authToken:\n${setAuthToken}`, VERDACCIO_ENV_TOKEN)
);
}
execSync(setAuthToken);
}
Expand All @@ -117,15 +119,19 @@ export function unconfigureRegistry(
{ userconfig }
).join(' ')}`;
if (verbose) {
logInfo(`Delete authToken:\n${setAuthToken}`);
logger.info(
formatInfo(`Delete authToken:\n${setAuthToken}`, VERDACCIO_ENV_TOKEN)
);
}
execSync(setAuthToken);

const setRegistry = `npm config delete registry ${objectToCliArgs({
userconfig,
}).join(' ')}`;
if (verbose) {
logInfo(`Delete registry:\n${setRegistry}`);
logger.info(
formatInfo(`Delete registry:\n${setRegistry}`, VERDACCIO_ENV_TOKEN)
);
}
execSync(setRegistry);
}
Original file line number Diff line number Diff line change
@@ -1,81 +1,78 @@
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { configureRegistry, verdaccioEnvLogger } from './verdaccio-npm-env';
import { bold, gray, red } from 'ansis';
import { describe, expect, it, vi } from 'vitest';
import {
configureRegistry,
ConfigureRegistryOptions,
VERDACCIO_ENV_TOKEN,
} from './verdaccio-npm-env';
import { execSync } from 'node:child_process';
import { objectToCliArgs } from '../utils/terminal';
import type { VerdaccioProcessResult } from './verdaccio-registry';
import { logger } from '@nx/devkit';
import { formatInfo } from '../utils/logging';

describe('verdaccioEnvLogger.info', () => {
let consoleInfoSpy;
beforeEach(() => {
consoleInfoSpy = vi.spyOn(console, 'info').mockImplementation(vi.fn());
});

it('should log info', () => {
verdaccioEnvLogger.info('message');
expect(consoleInfoSpy).toHaveBeenCalledTimes(1);
expect(consoleInfoSpy).toHaveBeenCalledWith(
`${gray('>')} ${gray(bold('Verdaccio Env: '))} ${'message'}`
);
});
vi.mock('child_process', async () => {
const actual = await vi.importActual<typeof import('child_process')>(
'child_process'
);
return {
...actual,
execSync: vi.fn(),
};
});

describe('logError', () => {
let consoleErrorSpy;
beforeEach(() => {
consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(vi.fn());
});

it('should log error', () => {
verdaccioEnvLogger.error('message');
expect(consoleErrorSpy).toHaveBeenCalledTimes(1);
expect(consoleErrorSpy).toHaveBeenCalledWith(
`${red('>')} ${red(bold('Verdaccio Env: '))} ${'message'}`
);
});
vi.mock('@nx/devkit', async () => {
const actual = await vi.importActual('@nx/devkit');
return {
...actual,
logger: {
info: vi.fn(),
},
};
});

describe('configureRegistry', () => {
it('should set the npm registry and authToken', () => {
const processResult: VerdaccioProcessResult & { userconfig?: string } = {
const processResult: ConfigureRegistryOptions = {
port: 4873,
host: 'localhost',
protocol: 'http',
url: 'http://localhost:4873',
userconfig: 'test-config',
};

configureRegistry(processResult, false);

expect(objectToCliArgs).toHaveBeenCalledWith({ userconfig: 'test-config' });
configureRegistry(processResult);

expect(execSync).toHaveBeenCalledTimes(2);
expect(execSync).toHaveBeenCalledWith(
'npm config set registry="http://localhost:4873" --userconfig=test-config'
'npm config set registry="http://localhost:4873" --userconfig="test-config"'
);

expect(execSync).toHaveBeenCalledWith(
'npm config set //localhost:4873/:_authToken "secretVerdaccioToken" --userconfig=test-config'
'npm config set //localhost:4873/:_authToken "secretVerdaccioToken" --userconfig="test-config"'
);
});

it('should log registry and authToken commands if verbose is true', () => {
const processResult = {
const processResult: ConfigureRegistryOptions = {
port: 4873,
host: 'localhost',
protocol: 'http',
url: 'http://localhost:4873',
userconfig: 'test-config',
};

configureRegistry(processResult, true);

expect(verdaccioEnvLogger.info).toHaveBeenCalledWith(
'Set registry:\nnpm config set registry="http://localhost:4873" --userconfig=test-config'
expect(execSync).toHaveBeenCalledTimes(2);
expect(logger.info).toHaveBeenCalledWith(
formatInfo(
'Set registry:\nnpm config set registry="http://localhost:4873" --userconfig="test-config"',
VERDACCIO_ENV_TOKEN
)
);

expect(verdaccioEnvLogger.info).toHaveBeenCalledWith(
'Set authToken:\nnpm config set //localhost:4873/:_authToken "secretVerdaccioToken" --userconfig=test-config'
expect(logger.info).toHaveBeenCalledWith(
formatInfo(
'Set authToken:\nnpm config set //localhost:4873/:_authToken "secretVerdaccioToken" --userconfig="test-config"',
VERDACCIO_ENV_TOKEN
)
);

expect(execSync).toHaveBeenCalledTimes(2);
});
});
Loading

0 comments on commit 2567641

Please sign in to comment.