Skip to content

Commit

Permalink
feat(it-tests): test schematics with yarn 1
Browse files Browse the repository at this point in the history
  • Loading branch information
vscaiceanu-1a committed Mar 12, 2024
1 parent 4bcd0f1 commit 7914831
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 41 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/it-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
packageManager: [yarn, npm]
packageManager: [yarn, npm, yarn1]
testEnvironment: [o3r-project-with-app]
runs-on: ${{ matrix.os }}
env:
Expand Down
34 changes: 18 additions & 16 deletions packages/@ama-sdk/create/src/index.it.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {
getDefaultExecSyncOptions,
getPackageManager,
getYarnVersionFromRoot,
isYarn1Enforced,
packageManagerCreate,
packageManagerExec,
packageManagerInstall,
Expand All @@ -25,8 +25,9 @@ describe('Create new sdk command', () => {
setupLocalRegistry();
beforeEach(async () => {
const isYarnTest = packageManager.startsWith('yarn');
const yarnVersion = isYarnTest ? getYarnVersionFromRoot(process.cwd()) || 'latest' : undefined;
sdkFolderPath = (await prepareTestEnv(projectName, {type: 'blank', yarnVersion })).workspacePath;
const testEnv = await prepareTestEnv(projectName, { type: 'blank' });
sdkFolderPath = testEnv.workspacePath;
const yarnVersion = testEnv.packageManagerConfig.yarnVersion;
sdkPackagePath = path.join(sdkFolderPath, sdkPackageName.replace(/^@/, ''));
execAppOptions.cwd = sdkFolderPath;

Expand All @@ -35,9 +36,10 @@ describe('Create new sdk command', () => {
packageManagerInstall(execAppOptions);

// copy yarnrc config to generated SDK
mkdirSync(sdkPackagePath, {recursive: true});
cpSync(path.join(sdkFolderPath, '.yarnrc.yml'), path.join(sdkPackagePath, '.yarnrc.yml'));
cpSync(path.join(sdkFolderPath, '.yarn'), path.join(sdkPackagePath, '.yarn'), {recursive: true});
mkdirSync(sdkPackagePath, { recursive: true });
const yarnConfigFile = isYarn1Enforced() ? '.yarnrc' : '.yarnrc.yml';
cpSync(path.join(sdkFolderPath, yarnConfigFile), path.join(sdkPackagePath, yarnConfigFile));
cpSync(path.join(sdkFolderPath, '.yarn'), path.join(sdkPackagePath, '.yarn'), { recursive: true });
fs.writeFileSync(path.join(sdkPackagePath, 'yarn.lock'), '');
} else {
// copy npmrc config to generated SDK
Expand All @@ -55,39 +57,39 @@ describe('Create new sdk command', () => {
packageManagerCreate({
script: '@ama-sdk',
args: ['typescript', sdkPackageName, '--package-manager', packageManager, '--spec-path', path.join(sdkFolderPath, 'swagger-spec.yml')]
}, execAppOptions)
}, execAppOptions, !isYarn1Enforced() ? 'npm' : undefined)
).not.toThrow();
expect(() => packageManagerRun({script: 'build'}, { ...execAppOptions, cwd: sdkPackagePath })).not.toThrow();
expect(() => packageManagerRun({ script: 'build' }, { ...execAppOptions, cwd: sdkPackagePath })).not.toThrow();
});

test('should generate an empty SDK ready to be used', () => {
expect(() => packageManagerCreate({script: '@ama-sdk', args: ['typescript', sdkPackageName]}, execAppOptions)).not.toThrow();
expect(() => packageManagerRun({script: 'build'}, { ...execAppOptions, cwd: sdkPackagePath })).not.toThrow();
expect(() => packageManagerCreate({ script: '@ama-sdk', args: ['typescript', sdkPackageName] }, execAppOptions, !isYarn1Enforced() ? 'npm' : undefined)).not.toThrow();
expect(() => packageManagerRun({ script: 'build' }, { ...execAppOptions, cwd: sdkPackagePath })).not.toThrow();
expect(() =>
packageManagerExec({
script: 'schematics',
args: ['@ama-sdk/schematics:typescript-core', '--spec-path', path.join(path.relative(sdkPackagePath, sdkFolderPath), 'swagger-spec.yml')]
}, { ...execAppOptions, cwd: sdkPackagePath })
).not.toThrow();
expect(() => packageManagerRun({script: 'build'}, { ...execAppOptions, cwd: sdkPackagePath })).not.toThrow();
expect(() => packageManagerRun({script: 'doc:generate'}, { ...execAppOptions, cwd: sdkPackagePath })).not.toThrow();
expect(() => packageManagerRun({ script: 'build' }, { ...execAppOptions, cwd: sdkPackagePath })).not.toThrow();
expect(() => packageManagerRun({ script: 'doc:generate' }, { ...execAppOptions, cwd: sdkPackagePath })).not.toThrow();
});

test('should fail when there is an error', () => {
expect(() =>
packageManagerCreate({
script: '@ama-sdk',
args: ['typescript', sdkPackageName, '--package-manager', packageManager, '--spec-path','./missing-file.yml']
}, execAppOptions)
args: ['typescript', sdkPackageName, '--package-manager', packageManager, '--spec-path', './missing-file.yml']
}, execAppOptions, !isYarn1Enforced() ? 'npm' : undefined)
).toThrow();
});

test('should use pinned versions when --exact-o3r-version is used', () => {
expect(() =>
packageManagerCreate({
script: `@ama-sdk@${o3rVersion}`,
script: `@ama-sdk`,
args: ['typescript', sdkPackageName, '--exact-o3r-version', '--package-manager', packageManager, '--spec-path', path.join(sdkFolderPath, 'swagger-spec.yml')]
}, execAppOptions)
}, execAppOptions, !isYarn1Enforced() ? 'npm' : undefined)
).not.toThrow();
expect(() => packageManagerRun({script: 'build'}, { ...execAppOptions, cwd: sdkPackagePath })).not.toThrow();
const packageJson = JSON.parse(fs.readFileSync(path.join(sdkPackagePath, 'package.json'), 'utf-8'));
Expand Down
5 changes: 3 additions & 2 deletions packages/@o3r/create/src/index.it.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
getDefaultExecSyncOptions,
getPackageManager,
isYarn1Enforced,
type PackageManagerConfig,
packageManagerCreate,
packageManagerExec,
Expand Down Expand Up @@ -40,7 +41,7 @@ describe('Create new otter project command', () => {
await fs.mkdir(inAppPath, { recursive: true });
setPackagerManagerConfig(packageManagerConfig, execInAppOptions);

expect(() => packageManagerCreate({ script: `@o3r@${o3rVersion}`, args: [workspaceProjectName, ...createOptions] }, execWorkspaceOptions, 'npm')).not.toThrow();
expect(() => packageManagerCreate({ script: `@o3r`, args: [workspaceProjectName, ...createOptions] }, execWorkspaceOptions, !isYarn1Enforced() ? 'npm' : undefined)).not.toThrow();
expect(existsSync(path.join(inAppPath, 'angular.json'))).toBe(true);
expect(existsSync(path.join(inAppPath, 'package.json'))).toBe(true);
expect(() => packageManagerInstall(execInAppOptions)).not.toThrow();
Expand All @@ -62,7 +63,7 @@ describe('Create new otter project command', () => {
await fs.mkdir(inAppPath, { recursive: true });
setPackagerManagerConfig(packageManagerConfig, execInAppOptions);

expect(() => packageManagerCreate({ script: `@o3r@${o3rVersion}`, args: [workspaceProjectName, ...createOptions] }, execWorkspaceOptions, 'npm')).not.toThrow();
expect(() => packageManagerCreate({ script: `@o3r`, args: [workspaceProjectName, ...createOptions] }, execWorkspaceOptions, !isYarn1Enforced() ? 'npm' : undefined)).not.toThrow();
expect(existsSync(path.join(inAppPath, 'angular.json'))).toBe(true);
expect(existsSync(path.join(inAppPath, 'package.json'))).toBe(true);
expect(() => packageManagerInstall(execInAppOptions)).not.toThrow();
Expand Down
6 changes: 3 additions & 3 deletions packages/@o3r/create/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,14 +201,14 @@ const prepareWorkspace = (relativeDirectory = '.', projectPackageManager = 'npm'
cwd
}));
};

const isYarn1 = packageManager === 'yarn' && argv['yarn-version']?.split('.')[0] === '1';
const addOtterFramework = (relativeDirectory = '.', projectPackageManager = 'npm') => {
const cwd = resolve(process.cwd(), relativeDirectory);
const runner = process.platform === 'win32' ? `${projectPackageManager}.cmd` : projectPackageManager;
const options = schematicsCliOptions
.flat();

exitProcessIfErrorInSpawnSync(3, spawnSync(runner, ['exec', 'ng', 'add', `@o3r/core@${exactO3rVersion ? '' : '~'}${version}`, ...(projectPackageManager === 'npm' ? ['--'] : []), ...options], {
exitProcessIfErrorInSpawnSync(3, spawnSync(runner, [isYarn1 ? 'run' : 'exec', 'ng', 'add', `@o3r/core@${exactO3rVersion ? '' : '~'}${version}`,
...((projectPackageManager === 'npm' || isYarn1) ? ['--'] : []), ...options], {
stdio: 'inherit',
cwd,
env: exactO3rVersion && projectPackageManager === 'npm' ? {
Expand Down
6 changes: 3 additions & 3 deletions packages/@o3r/telemetry/src/environment/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,22 @@ import { execSync } from 'node:child_process';
import * as path from 'node:path';

/** Support NPM package managers */
type SupportedPackageManagers = 'npm' | 'yarn';
type SupportedPackageManagers = 'npm' | 'yarn' | 'yarn1';

/**
* Determine if the given packager manager is supported
* @param name Name of the package manager
*/
function isSupportedPackageManager(name?: any): name is SupportedPackageManagers {
return name === 'yarn' || name === 'npm';
return ['yarn', 'yarn1', 'npm'].includes(name);
}

/**
* Get package manager used
*/
function getPackageManager() {
if (isSupportedPackageManager(process.env?.ENFORCED_PACKAGE_MANAGER)) {
return process.env.ENFORCED_PACKAGE_MANAGER;
return (process.env.ENFORCED_PACKAGE_MANAGE === 'npm') ? 'npm' : 'yarn';
}
return (process.env?.npm_execpath?.includes('yarn') && 'yarn') || 'npm';
}
Expand Down
10 changes: 5 additions & 5 deletions packages/@o3r/test-helpers/src/prepare-test-env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statS
import * as path from 'node:path';
import type { PackageJson } from 'type-fest';
import { createTestEnvironmentBlank } from './test-environments/create-test-environment-blank';
import { createWithLock, getPackageManager, type Logger, packageManagerInstall, setPackagerManagerConfig, setupGit } from './utilities/index';
import { createWithLock, getVersionedPackageManager, isYarn1Enforced, type Logger, packageManagerInstall, setPackagerManagerConfig, setupGit } from './utilities/index';
import { createTestEnvironmentOtterProjectWithApp } from './test-environments/create-test-environment-otter-project';
import { O3rCliError } from '@o3r/schematics';

Expand All @@ -15,8 +15,7 @@ export type PrepareTestEnvType = 'blank' | 'o3r-project-with-app';

/**
* Retrieve the version used by yarn and setup at root level
* @param rootFolderPath: path to the folder where to take the configuration from
* @param rootFolderPath
* @param rootFolderPath path to the folder where to take the configuration from
*/
export function getYarnVersionFromRoot(rootFolderPath: string) {
const o3rPackageJson: PackageJson & { generatorDependencies?: Record<string, string> } =
Expand Down Expand Up @@ -49,7 +48,8 @@ export async function prepareTestEnv(folderName: string, options?: PrepareTestEn
const cacheFolderPath = path.resolve(globalFolderPath, 'cache');

JSON.parse(readFileSync(path.join(rootFolderPath, 'packages', '@o3r', 'core', 'package.json')).toString());
const yarnVersion: string = yarnVersionParam || getYarnVersionFromRoot(rootFolderPath);
const yarn1Version = execSync('npm view yarn version', { encoding: 'utf8' }).trim();
const yarnVersion: string = yarnVersionParam || (isYarn1Enforced() && yarn1Version) || getYarnVersionFromRoot(rootFolderPath);
const execAppOptions: ExecSyncOptions = {
cwd: workspacePath,
stdio: 'inherit',
Expand Down Expand Up @@ -108,7 +108,7 @@ export async function prepareTestEnv(folderName: string, options?: PrepareTestEn
let isInWorkspace = false;
let untouchedProject: undefined | string;
let untouchedProjectPath: undefined | string;
const appDirectory = `${type}-${getPackageManager()}`;
const appDirectory = `${type}-${getVersionedPackageManager()}`;
switch (type) {
case 'blank': {
await createTestEnvironmentBlank({
Expand Down
68 changes: 57 additions & 11 deletions packages/@o3r/test-helpers/src/utilities/package-manager.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { execFileSync, ExecSyncOptions } from 'node:child_process';
import { existsSync, rmSync } from 'node:fs';
import { appendFileSync, existsSync, readFileSync, rmSync } from 'node:fs';
import { join } from 'node:path';
import { performance } from 'node:perf_hooks';

Expand Down Expand Up @@ -30,6 +30,15 @@ const PACKAGE_MANAGERS_CMD = {
run: ['yarn', 'run'],
workspaceExec: ['yarn', 'workspace'],
workspaceRun: ['yarn', 'workspace']
},
yarn1: {
add: ['yarn', 'add'],
create: ['yarn', 'create'],
exec: ['yarn', 'run'],
install: ['yarn', 'install'],
run: ['yarn', 'run'],
workspaceExec: ['yarn', 'workspace'],
workspaceRun: ['yarn', 'workspace']
}
};

Expand All @@ -41,14 +50,30 @@ type CommandArguments = {
};

/**
* Get the package manager to be used for the tests by reading environment variable ENFORCED_PACKAGE_MANAGER
* Get the package manager with its version to be used for the tests by reading environment variable ENFORCED_PACKAGE_MANAGER
* 'yarn', 'yarn1', 'npm'
*/
export function getPackageManager() {
export function getVersionedPackageManager() {
return (process.env.ENFORCED_PACKAGE_MANAGER && process.env.ENFORCED_PACKAGE_MANAGER in PACKAGE_MANAGERS_CMD) ?
process.env.ENFORCED_PACKAGE_MANAGER as keyof typeof PACKAGE_MANAGERS_CMD :
'yarn';
}

/**
* Get the package manager to be used for the tests based on env ENFORCED_PACKAGE_MANAGER
* 'yarn', 'npm'
*/
export function getPackageManager() {
return getVersionedPackageManager() === 'npm' ? 'npm' : 'yarn';
}

/**
* is Yarn 1 enforced
*/
export function isYarn1Enforced() {
return process.env.ENFORCED_PACKAGE_MANAGER === 'yarn1';
}

/**
* Need to add additional dashes when running command like exec on npm
* Convert `npm exec test --param` to `npm exec test -- --param`
Expand Down Expand Up @@ -90,7 +115,7 @@ function execCmd(args: string[], execOptions: ExecSyncOptions) {
* @param options
*/
export function packageManagerAdd(packages: string, options: ExecSyncOptions) {
return execCmd([...PACKAGE_MANAGERS_CMD[getPackageManager()].add, packages], options);
return execCmd([...PACKAGE_MANAGERS_CMD[getVersionedPackageManager()].add, packages], options);
}

/**
Expand All @@ -101,7 +126,7 @@ export function packageManagerAdd(packages: string, options: ExecSyncOptions) {
*/
export function packageManagerCreate(command: CommandArguments, options: ExecSyncOptions, packageManagerOverride?: keyof typeof PACKAGE_MANAGERS_CMD) {
const { script, args } = command;
const packageManager = packageManagerOverride || getPackageManager();
const packageManager = packageManagerOverride || getVersionedPackageManager();
return execCmd([...PACKAGE_MANAGERS_CMD[packageManager].create, script, ...addDashesForNpmCommand(args, packageManager)], options);
}

Expand All @@ -112,7 +137,7 @@ export function packageManagerCreate(command: CommandArguments, options: ExecSyn
*/
export function packageManagerExec(command: CommandArguments, options: ExecSyncOptions) {
const { script, args } = command;
return execCmd([...PACKAGE_MANAGERS_CMD[getPackageManager()].exec, script, ...addDashesForNpmCommand(args)], options);
return execCmd([...PACKAGE_MANAGERS_CMD[getVersionedPackageManager()].exec, script, ...addDashesForNpmCommand(args)], options);
}

/**
Expand All @@ -123,7 +148,7 @@ export function packageManagerExec(command: CommandArguments, options: ExecSyncO
*/
export function packageManagerWorkspaceExec(workspaceProjectName: string, command: CommandArguments, options: ExecSyncOptions) {
const { script, args } = command;
return execCmd([...PACKAGE_MANAGERS_CMD[getPackageManager()].workspaceExec, workspaceProjectName, script, ...addDashesForNpmCommand(args)], options);
return execCmd([...PACKAGE_MANAGERS_CMD[getVersionedPackageManager()].workspaceExec, workspaceProjectName, script, ...addDashesForNpmCommand(args)], options);
}

/**
Expand All @@ -142,7 +167,7 @@ export function packageManagerExecOnProject(projectName: string, isInWorkspace:
* @param options
*/
export function packageManagerInstall(options: ExecSyncOptions) {
return execCmd(PACKAGE_MANAGERS_CMD[getPackageManager()].install, options);
return execCmd(PACKAGE_MANAGERS_CMD[getVersionedPackageManager()].install, options);
}

/**
Expand All @@ -152,7 +177,7 @@ export function packageManagerInstall(options: ExecSyncOptions) {
*/
export function packageManagerRun(command: CommandArguments, options: ExecSyncOptions) {
const { script, args } = command;
return execCmd([...PACKAGE_MANAGERS_CMD[getPackageManager()].run, script, ...addDashesForNpmCommand(args)], options);
return execCmd([...PACKAGE_MANAGERS_CMD[getVersionedPackageManager()].run, script, ...addDashesForNpmCommand(args)], options);
}

/**
Expand All @@ -163,7 +188,7 @@ export function packageManagerRun(command: CommandArguments, options: ExecSyncOp
*/
export function packageManagerWorkspaceRun(workspaceProjectName: string, command: CommandArguments, options: ExecSyncOptions) {
const { script, args } = command;
return execCmd([...PACKAGE_MANAGERS_CMD[getPackageManager()].workspaceRun, workspaceProjectName, script, ...addDashesForNpmCommand(args)], options);
return execCmd([...PACKAGE_MANAGERS_CMD[getVersionedPackageManager()].workspaceRun, workspaceProjectName, script, ...addDashesForNpmCommand(args)], options);
}

/**
Expand Down Expand Up @@ -209,7 +234,7 @@ export function setPackagerManagerConfig(options: PackageManagerConfig, execAppO

const packageJsonPath = join(execOptions.cwd as string, 'package.json');
const shouldCleanPackageJson = !existsSync(packageJsonPath);
switch (getPackageManager()) {
switch (getVersionedPackageManager()) {
case 'yarn': {
// Set yarn version
if (options.yarnVersion) {
Expand All @@ -231,6 +256,27 @@ export function setPackagerManagerConfig(options: PackageManagerConfig, execAppO
execFileSync('yarn', ['config', 'set', 'unsafeHttpWhitelist', '127.0.0.1'], execOptions);
break;
}
case 'yarn1': {
if (options.yarnVersion) {
execFileSync('yarn', ['set', 'version', options.yarnVersion], execOptions);
execFileSync('yarn', ['config', 'set', '@ama-sdk:registry', options.registry], execOptions);
execFileSync('yarn', ['config', 'set', '@ama-terasu:registry', options.registry], execOptions);
execFileSync('yarn', ['config', 'set', '@o3r:registry', options.registry], execOptions);
execFileSync('yarn', ['config', 'set', 'unsafeHttpWhitelist', '127.0.0.1'], execOptions);
}
const ignoreRootCheckConfig = '--add.ignore-workspace-root-check';
const yarnRcPath = join(execOptions.cwd as string, '.yarnrc');

if (existsSync(yarnRcPath)) {
const content = readFileSync(yarnRcPath, { encoding: 'utf8' });
if (!content.includes(ignoreRootCheckConfig)) {
appendFileSync(yarnRcPath, `\n${ignoreRootCheckConfig} true`);
}
} else {
console.warn(`File not found at '${yarnRcPath}'.`);
}
break;
}
}

execFileSync('npm', ['config', 'set', 'audit=false', '-L=project'], execOptions);
Expand Down

0 comments on commit 7914831

Please sign in to comment.