Skip to content

Commit

Permalink
feat: clean package install in ngAdd schematics
Browse files Browse the repository at this point in the history
feat: clean package install in ngAdd schematics

feat: migrate packageManager helpers
  • Loading branch information
kpanot committed Feb 20, 2024
1 parent 59ea4c5 commit 571938b
Show file tree
Hide file tree
Showing 111 changed files with 2,501 additions and 1,688 deletions.
5 changes: 2 additions & 3 deletions .github/workflows/it-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,12 @@ jobs:
matrix:
os: [ubuntu-latest, windows-latest]
packageManager: [yarn, npm]
exclude:
- os: windows-latest
packageManager: yarn
testEnvironment: [o3r-project-with-app]
runs-on: ${{ matrix.os }}
env:
NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
ENFORCED_PACKAGE_MANAGER: ${{ matrix.packageManager }}
PREPARE_TEST_ENV_TYPE: ${{ matrix.testEnvironment }}
steps:
- uses: actions/checkout@v4
- uses: ./tools/github-actions/download-build-output
Expand Down
12 changes: 4 additions & 8 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,19 @@
"typescript.enablePromptUseWorkspaceTsdk": true,
"typescript.preferences.preferTypeOnlyAutoImports": true,
"jest.jestCommandLine": "yarn jest",
"jest.debugMode": true,
"jest.runMode": "on-save",
"jest.outputConfig": {
"revealOn": "demand",
"revealWithFocus": "test-results",
"clearOnRun": "none"
},
"testing.openTesting": "neverOpen",
"explorer.fileNesting.enabled": true,
"explorer.fileNesting.patterns": {
"*.js": "${capture}.js.map, ${capture}.d.ts, ${capture}.d.ts.map",
"tsconfig.json": "tsconfig.*.json",
"tsconfig.base.json": "tsconfig.*.json",
"package.json": "ng-package.json, project.json, yarn.lock",
"package.json": "ng-package.json, project.json, yarn.lock, .yarnrc.yml, .npmrc, .npmrc.*, .pnp.*",
"nx.json": ".nxignore",
".yarnrc.yml": ".npmrc, .npmrc.*",
".eslintrc.*": ".eslintignore, .eslintrc-*",
"jest.config.js": "jest.config.*"
"jest.config.js": "jest.config.*",
"Dockerfile*": ".dockerignore"
},
"stylelint.validate": [
"css",
Expand Down
2 changes: 2 additions & 0 deletions apps/showcase/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@
]
},
"generate-dark-theme": {
"cache": true,
"executor": "@o3r/design:generate-css",
"outputs": [
"{options.defaultStyleFile}",
Expand Down Expand Up @@ -236,6 +237,7 @@
]
},
"generate-horizon-theme": {
"cache": true,
"executor": "@o3r/design:generate-css",
"outputs": [
"{options.defaultStyleFile}",
Expand Down
20 changes: 18 additions & 2 deletions nx.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,21 @@
],
"specs": [
"default",
"{projectRoot}/**/*.spec.ts",
"{projectRoot}/jest.config.*",
"{projectRoot}/testing/**/*",
"{projectRoot}/mocks/**/*",
"{workspaceRoot}/jest.config.js"
],
"integration-test": [
"default",
"{workspaceRoot}/jest.config.it.js",
"{workspaceRoot}/packages/*/create/src/*.ts",
"{workspaceRoot}/packages/@o3r/create/src/*.ts",
"!{workspaceRoot}/packages/@o3r/create/src/*.spec.ts",
"{workspaceRoot}/packages/@o3r/test-helpers/src/**/*.ts",
"!{workspaceRoot}/packages/@o3r/test-helpers/src/**/*.spec.ts"
],
"source": [
"default",
"!{projectRoot}/**/*.spec.ts",
Expand Down Expand Up @@ -132,15 +142,21 @@
{
"env": "ENFORCED_PACKAGE_MANAGER"
},
{
"env": "PREPARE_TEST_ENV_TYPE"
},
"default",
"schematics",
"^schematics",
"^source",
"specs",
"{workspaceRoot}/jest.config.it.js"
"integration-test"
],
"outputs": [
"{projectRoot}/dist-test/it-report.xml"
],
"outputs": ["{projectRoot}/dist-test/it-report.xml"],
"options": {
"quiet": false,
"passWithNoTests": false
},
"configurations": {
Expand Down
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"build:tools": "yarn nx run-many --target=build --projects=eslint-plugin,workspace --parallel $(yarn get:cpus-number)",
"build:lint": "yarn nx run-many --target=build --projects=eslint-plugin --parallel $(yarn get:cpus-number)",
"build:swagger-gen": "yarn nx run-many --target=build-swagger --parallel $(yarn get:cpus-number)",
"prepare:publish": "prepare-publish $(yarn workspaces:list | shx sed \"s/^(.+)\\$/\\$1\\/dist/\")",
"prepare:publish": "prepare-publish $(yarn workspaces:list | yarn node -e 'let data=\"\"; process.openStdin().on(\"data\", (c) => data+=c).on(\"end\", () => process.stdout.write(data.split(/[\\n\\r]+/).slice(0, -1).map((l) => l + \"/dist\").join(require(\"os\").EOL)));')",
"publish": "yarn run prepare:publish && yarn nx run-many --target=publish --parallel $(yarn get:cpus-number) --nx-bail",
"publish:extensions": "yarn nx run-many --target=publish-extension --parallel $(yarn get:cpus-number)",
"publish:extensions:affected": "yarn nx affected --target=publish-extension --parallel $(yarn get:cpus-number)",
Expand All @@ -23,7 +23,7 @@
"test": "yarn nx run-many --target=test --parallel $(yarn get:cpus-number) --cacheDirectory=$(yarn get:current-dir)/.cache/jest",
"test:affected": "yarn nx affected --target=test --parallel $(yarn get:cpus-number) --cacheDirectory=$(yarn get:current-dir)/.cache/jest",
"test-e2e": "yarn nx run-many --target=test-e2e --parallel $(yarn get:cpus-number)",
"test-int": "yarn nx run-many --target=test-int --parallel 2",
"test-int": "yarn nx run-many --target=test-int --parallel $(yarn get:cpus-number)",
"postinstall": "husky install && yarn build:lint && yarn harmonize:version && yarn update-yarn-sdks",
"update-yarn-sdks": "node -e \"'pnp' !== '$(yarn config get nodeLinker)' || process.exit(1)\" || yarn dlx @yarnpkg/sdks",
"build:storybook": "yarn doc:generate:json && yarn ng run storybook:extract-style && build-storybook",
Expand All @@ -36,15 +36,16 @@
"doc:generate:json": "yarn update-doc-summary ./docs && yarn compodoc -e json -d .",
"start:modules": "yarn run build:dev:modules && yarn run watch:modules",
"storybook": "yarn doc:generate:json && yarn ng run storybook:extract-style && start-storybook -p 6006",
"verdaccio:start": "docker run -d -it --rm --name verdaccio -p 4873:4873 -v \"$(shx pwd)/.verdaccio/conf\":/verdaccio/conf verdaccio/verdaccio",
"verdaccio:start-persistent": "docker run -d -it --rm --name verdaccio -p 4873:4873 -v \"$(shx pwd)/.verdaccio/conf\":/verdaccio/conf -v \"$(shx pwd)/.verdaccio/storage\":/verdaccio/storage:z verdaccio/verdaccio",
"verdaccio:start": "docker run -d -it --rm --name verdaccio -p 4873:4873 -v \"$(yarn get:current-dir)/.verdaccio/conf\":/verdaccio/conf verdaccio/verdaccio",
"verdaccio:start-local": "npx --yes verdaccio --config \"$(yarn get:current-dir)/.verdaccio/conf/config-without-docker.yaml\" --listen http://127.0.0.1:4873",
"verdaccio:start-persistent": "docker run -d -it --rm --name verdaccio -p 4873:4873 -v \"$(yarn get:current-dir)/.verdaccio/conf\":/verdaccio/conf -v \"$(yarn get:current-dir)/.verdaccio/storage\":/verdaccio/storage:z verdaccio/verdaccio",
"verdaccio:clean": "rimraf -g \".verdaccio/storage/@{o3r,ama-sdk,ama-terasu}\"",
"verdaccio:login": "yarn cpy --cwd=./.verdaccio/conf .npmrc . --rename=.npmrc-logged && npx --yes npm-cli-login -u verdaccio -p verdaccio -e [email protected] -r http://127.0.0.1:4873 --config-path \".verdaccio/conf/.npmrc-logged\"",
"verdaccio:publish": "yarn verdaccio:clean && yarn set:version 999.0.0 --include \"!**/!(dist)/package.json\" --include !package.json && yarn verdaccio:login && yarn run publish --userconfig \".verdaccio/conf/.npmrc-logged\" --tag=latest --@o3r:registry=http://127.0.0.1:4873 --@ama-sdk:registry=http://127.0.0.1:4873 --@ama-terasu:registry=http://127.0.0.1:4873",
"verdaccio:stop": "docker container stop $(docker ps -a -q --filter=\"name=verdaccio\")",
"verdaccio:all": "yarn verdaccio:stop && yarn verdaccio:start && yarn verdaccio:publish",
"watch:vscode-extension": "yarn nx run vscode-extension:compile:watch",
"workspaces:list": "yarn workspaces list --no-private --json | shx sed \"s/.*\\\"location\\\":\\\"(.*?)\\\".*/\\$1/\""
"workspaces:list": "yarn workspaces list --no-private --json | yarn node -e 'let data=\"\"; process.openStdin().on(\"data\", (c) => data+=c).on(\"end\", () => process.stdout.write(data.split(/[\\n\\r]+/).slice(0, -1).map((l) => JSON.parse(l).location).join(require(\"os\").EOL)));'"
},
"lint-staged": {
"*.ts": [
Expand Down Expand Up @@ -240,7 +241,6 @@
"sass": "~1.71.0",
"sass-loader": "^14.0.0",
"semver": "^7.5.2",
"shx": "^0.3.4",
"standard-version": "^9.0.0",
"stylelint": "^16.0.2",
"stylelint-scss": "^6.0.0",
Expand Down
3 changes: 1 addition & 2 deletions packages/@ama-sdk/create/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@
"test-int": {
"executor": "@nx/jest:jest",
"options": {
"jestConfig": "packages/@ama-sdk/create/testing/jest.config.it.js",
"silent": false
"jestConfig": "packages/@ama-sdk/create/testing/jest.config.it.js"
}
},
"publish": {
Expand Down
23 changes: 12 additions & 11 deletions packages/@ama-sdk/create/src/index.it.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import * as fs from 'node:fs';
import { cpSync, mkdirSync } from 'node:fs';
import * as path from 'node:path';

const appName = 'test-sdk';
const projectName = 'test-sdk';
const sdkPackageName = '@my-test/sdk';
let sdkFolderPath: string;
let sdkPackagePath: string;
Expand All @@ -25,7 +25,7 @@ describe('Create new sdk command', () => {
beforeEach(async () => {
const isYarnTest = packageManager.startsWith('yarn');
const yarnVersion = isYarnTest ? getYarnVersionFromRoot(process.cwd()) || 'latest' : undefined;
sdkFolderPath = await prepareTestEnv(appName, 'blank', yarnVersion);
sdkFolderPath = (await prepareTestEnv(projectName, {type: 'blank', yarnVersion })).workspacePath;
sdkPackagePath = path.join(sdkFolderPath, sdkPackageName.replace(/^@/, ''));
execAppOptions.cwd = sdkFolderPath;

Expand All @@ -51,19 +51,20 @@ describe('Create new sdk command', () => {

test('should generate a full SDK when the specification is provided', () => {
expect(() =>
packageManagerCreate(`@ama-sdk typescript ${sdkPackageName} --package-manager ${packageManager} --spec-path ./swagger-spec.yml`, execAppOptions)).not.toThrow();
expect(() => packageManagerRun('build', { ...execAppOptions, cwd: sdkPackagePath })).not.toThrow();
packageManagerCreate({script: '@ama-sdk', args: ['typescript', sdkPackageName, '--package-manager', packageManager, '--spec-path', './swagger-spec.yml']}, execAppOptions)).not.toThrow();
expect(() => packageManagerRun({script: 'build'}, { ...execAppOptions, cwd: sdkPackagePath })).not.toThrow();
});

test('should generate an empty SDK ready to be used', () => {
expect(() => packageManagerCreate(`@ama-sdk typescript ${sdkPackageName}`, execAppOptions)).not.toThrow();
expect(() => packageManagerRun('build', { ...execAppOptions, cwd: sdkPackagePath })).not.toThrow();
expect(() => packageManagerCreate({script: '@ama-sdk', args: ['typescript', sdkPackageName]}, execAppOptions)).not.toThrow();
expect(() => packageManagerRun({script: 'build'}, { ...execAppOptions, cwd: sdkPackagePath })).not.toThrow();
expect(() =>
packageManagerExec(
`schematics @ama-sdk/schematics:typescript-core --spec-path ${path.join(path.relative(sdkPackagePath, sdkFolderPath), 'swagger-spec.yml')}`,
{ ...execAppOptions, cwd: sdkPackagePath }
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('build', { ...execAppOptions, cwd: sdkPackagePath })).not.toThrow();
expect(() => packageManagerRun('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();
});
});
3 changes: 2 additions & 1 deletion packages/@ama-sdk/create/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,12 @@ const getSchematicStepInfo = (schematic: string) => ({

const run = () => {

const runner = process.platform === 'win32' ? `${packageManager}.cmd` : packageManager;
const steps: { args: string[]; cwd?: string; runner?: string }[] = [
getSchematicStepInfo(schematicsToRun[0]),
...(
packageManager === 'yarn'
? [{ runner: 'yarn', args: ['set', 'version', getYarnVersion()], cwd: resolve(process.cwd(), targetDirectory)}]
? [{ runner, args: ['set', 'version', getYarnVersion()], cwd: resolve(process.cwd(), targetDirectory)}]
: []
),
...schematicsToRun.slice(1).map(getSchematicStepInfo)
Expand Down
1 change: 0 additions & 1 deletion packages/@ama-sdk/schematics/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@
"executor": "@nx/jest:jest",
"options": {
"jestConfig": "packages/@ama-sdk/schematics/testing/jest.config.it.js",
"silent": false,
"passWithNoTests": true
}
},
Expand Down
3 changes: 1 addition & 2 deletions packages/@o3r/analytics/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,7 @@
"test-int": {
"executor": "@nx/jest:jest",
"options": {
"jestConfig": "packages/@o3r/analytics/testing/jest.config.it.js",
"silent": false
"jestConfig": "packages/@o3r/analytics/testing/jest.config.it.js"
}
},
"prepare-publish": {
Expand Down
90 changes: 36 additions & 54 deletions packages/@o3r/analytics/schematics/index.it.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,70 +2,52 @@ import {
addImportToAppModule,
getDefaultExecSyncOptions,
getGitDiff,
packageManagerAdd,
packageManagerExec,
packageManagerInstall,
packageManagerRun,
packageManagerRunOnProject,
prepareTestEnv,
setupLocalRegistry
} from '@o3r/test-helpers';
import { join } from 'node:path';
import { rm } from 'node:fs/promises';
import * as path from 'node:path';

const appName = 'test-app-analytics';
const appFolder = 'test-app-analytics';
const o3rVersion = '999.0.0';
const execAppOptions = getDefaultExecSyncOptions();
let appFolderPath: string;

let projectPath: string;
let isInWorkspace: boolean;
let workspacePath: string;
let projectName: string;
let untouchedProjectPath: undefined | string;
describe('new otter application with analytics', () => {
setupLocalRegistry();
describe('standalone', () => {
beforeAll(async () => {
appFolderPath = await prepareTestEnv(appName, 'angular-with-o3r-core');
execAppOptions.cwd = appFolderPath;
});
test('should add analytics to existing application', async () => {
packageManagerExec(`ng add --skip-confirmation @o3r/analytics@${o3rVersion}`, execAppOptions);

packageManagerExec('ng g @o3r/core:component test-component --use-otter-analytics=false', execAppOptions);
packageManagerExec('ng g @o3r/analytics:add-analytics --path="src/components/test-component/test-component.component.ts"', execAppOptions);
await addImportToAppModule(appFolderPath, 'TestComponentModule', 'src/components/test-component');

const diff = getGitDiff(appFolderPath);
expect(diff.modified).toContain('package.json');
expect(diff.added).toContain('src/components/test-component/test-component.analytics.ts');

expect(() => packageManagerInstall(execAppOptions)).not.toThrow();
expect(() => packageManagerRun('build', execAppOptions)).not.toThrow();
});
beforeAll(async () => {
({ projectPath, workspacePath, projectName, isInWorkspace, untouchedProjectPath } = await prepareTestEnv(appFolder));
execAppOptions.cwd = workspacePath;
});

describe('monorepo', () => {
beforeAll(async () => {
const workspacePath = await prepareTestEnv(`${appName}-monorepo`, 'angular-monorepo-with-o3r-core');
appFolderPath = join(workspacePath, 'projects', 'test-app');
execAppOptions.cwd = workspacePath;
});
test('should add analytics to existing application', () => {
// FIXME workaround for pnp
packageManagerAdd(`@o3r/analytics@${o3rVersion}`, {...execAppOptions, cwd: appFolderPath});

const projectName = '--project-name=test-app';
packageManagerExec(`ng add --skip-confirmation @o3r/analytics@${o3rVersion} ${projectName}`, execAppOptions);

packageManagerExec(`ng g @o3r/core:component test-component --use-otter-analytics=false ${projectName}`, execAppOptions);
packageManagerExec(
'ng g @o3r/analytics:add-analytics --path="projects/test-app/src/components/test-component/test-component.component.ts"',
execAppOptions
);
addImportToAppModule(appFolderPath, 'TestComponentModule', 'src/components/test-component');

const diff = getGitDiff(execAppOptions.cwd as string);
expect(diff.all.some((file) => /projects[\\/]dont-modify-me/.test(file))).toBe(false);
expect(diff.modified).toContain('projects/test-app/package.json');
expect(diff.added).toContain('projects/test-app/src/components/test-component/test-component.analytics.ts');

expect(() => packageManagerInstall(execAppOptions)).not.toThrow();
expect(() => packageManagerRun('build', execAppOptions)).not.toThrow();
});
afterAll(async () => {
try { await rm(workspacePath, { recursive: true }); } catch { /* ignore error */ }
});
test('should add analytics to existing application', () => {
const relativeProjectPath = path.relative(workspacePath, projectPath);
packageManagerExec({script: 'ng', args: ['add', `@o3r/analytics@${o3rVersion}`, '--project-name', projectName, '--skip-confirmation']}, execAppOptions);

packageManagerExec({script: 'ng', args: ['g', '@o3r/core:component', 'test-component', '--use-otter-analytics', 'false', '--project-name', projectName]}, execAppOptions);
const componentPath = path.normalize(path.join(relativeProjectPath, 'src/components/test-component/test-component.component.ts'));
packageManagerExec({script: 'ng', args: ['g', '@o3r/analytics:add-analytics', '--path', componentPath]}, execAppOptions);
addImportToAppModule(projectPath, 'TestComponentModule', 'src/components/test-component');

const diff = getGitDiff(workspacePath);
expect(diff.all.some((file) => /projects[\\/]dont-modify-me/.test(file))).toBe(false);
expect(diff.modified).toContain(path.join(relativeProjectPath, 'package.json').replace(/[\\/]+/g, '/'));
expect(diff.added).toContain(path.join(relativeProjectPath, 'src/components/test-component/test-component.analytics.ts').replace(/[\\/]+/g, '/'));

if (untouchedProjectPath) {
const relativeUntouchedProjectPath = path.relative(workspacePath, untouchedProjectPath);
expect(diff.all.filter((file) => new RegExp(relativeUntouchedProjectPath.replace(/[\\/]+/g, '[\\\\/]')).test(file)).length).toBe(0);
}

expect(() => packageManagerInstall(execAppOptions)).not.toThrow();
expect(() => packageManagerRunOnProject(projectName, isInWorkspace, {script: 'build'}, execAppOptions)).not.toThrow();
});
});
16 changes: 13 additions & 3 deletions packages/@o3r/analytics/schematics/ng-add/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
import type { Rule } from '@angular-devkit/schematics';
import { createSchematicWithMetricsIfInstalled } from '@o3r/schematics';
import { createSchematicWithMetricsIfInstalled, getPackageInstallConfig, setupDependencies } from '@o3r/schematics';
import type { NgAddSchematicsSchema } from './schema';
import * as path from 'node:path';

const packageJsonPath = path.resolve(__dirname, '..', '..', 'package.json');

/**
* Add Otter analytics to an Angular Project
* @param options
*/
function ngAddFn(): Rule {
function ngAddFn(options: NgAddSchematicsSchema): Rule {
/* ng add rules */
return () => {};
return (tree) => {
return setupDependencies({
projectName: options.projectName,
dependencies: getPackageInstallConfig(packageJsonPath, tree, options.projectName)
});
};
}

/**
Expand Down
3 changes: 1 addition & 2 deletions packages/@o3r/apis-manager/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@
"test-int": {
"executor": "@nx/jest:jest",
"options": {
"jestConfig": "packages/@o3r/apis-manager/testing/jest.config.it.js",
"silent": false
"jestConfig": "packages/@o3r/apis-manager/testing/jest.config.it.js"
}
},
"prepare-publish": {
Expand Down
Loading

0 comments on commit 571938b

Please sign in to comment.