Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(workspace): the tsconfig links to generate libraries #2648

Merged
merged 1 commit into from
Jan 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion packages/@o3r/workspace/schematics/index.it.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ describe('new otter workspace', () => {
expect(() => packageManagerRunOnProject('@my-sdk/sdk', isInWorkspace, { script: 'spec:upgrade' }, execAppOptions)).not.toThrow();
});

test('should add a library to an existing workspace', () => {
test('should add a library to an existing workspace', async () => {
const { workspacePath } = o3rEnvironment.testEnvironment;
const execAppOptions = { ...getDefaultExecSyncOptions(), cwd: workspacePath };
const libName = 'test-library';
Expand All @@ -115,6 +115,10 @@ describe('new otter workspace', () => {
expect(existsSync(path.join(workspacePath, 'project'))).toBe(false);
generatedLibFiles.forEach((file) => expect(existsSync(path.join(inLibraryPath, file))).toBe(true));
expect(() => packageManagerRunOnProject(libName, true, { script: 'build' }, execAppOptions)).not.toThrow();

// check tsconfig.lib.prod.json override
const tsconfigLibProd = JSON.parse(await fs.readFile(path.join(inLibraryPath, 'tsconfig.lib.prod.json'), { encoding: 'utf8' }));
kpanot marked this conversation as resolved.
Show resolved Hide resolved
expect(!!tsconfigLibProd.extends && existsSync(path.resolve(inLibraryPath, tsconfigLibProd.extends))).toBe(true);
});

test('should generate a monorepo setup', async () => {
Expand Down
40 changes: 26 additions & 14 deletions packages/@o3r/workspace/schematics/library/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,14 @@ const collectionPath = path.join(__dirname, '..', '..', 'collection.json');

describe('New module generator', () => {
let initialTree: Tree;

beforeEach(() => {
initialTree = Tree.empty();
initialTree.create('/tsconfig.base.json', JSON.stringify({
compilerOptions: {
paths: {}
}
}));
initialTree.create('/tsconfig.build.json', JSON.stringify({
compilerOptions: {
paths: {}
}
}));
initialTree.create('angular.json', '{"version": 1, "projects": {} }');
initialTree.create('package.json', '{ "version": "0.0.0-test" }');
});

it('should generate the minimum mandatory files', async () => {
initialTree.create('angular.json', '{"version": 1, "projects": {} }');
initialTree.create('package.json', '{ "version": "0.0.0-test" }');
initialTree.create('/tsconfig.base.json', JSON.stringify({}));
initialTree.create('/packages-test/my-new-module/package.json', '{ "version": "0.0.0-test" }');
initialTree.create('/packages-test/my-new-module/ng-package.json', '{ }');
const runner = new SchematicTestRunner('schematics', collectionPath);
Expand All @@ -55,12 +45,34 @@ describe('New module generator', () => {

expect(spy).toHaveBeenNthCalledWith(1, '@schematics/angular', 'library', expect.anything());
expect(tree.exists('/packages-test/my-new-module/tsconfig.json')).toBe(true);
expect(tree.readJson('/packages-test/my-new-module/tsconfig.lib.prod.json')).toStrictEqual({ extends: '../../tsconfig.base.json' });
expect(tree.exists('/packages-test/my-new-module/project.json')).toBe(false);
expect(JSON.parse(tree.readContent('/tsconfig.base.json')).compilerOptions.paths['@my/new-module']).toContain('packages-test/my-new-module/src/public-api');
expect(JSON.parse(tree.readContent('/tsconfig.build.json')).compilerOptions.paths['@my/new-module'][0]).toBe('packages-test/my-new-module/dist');
expect(JSON.parse(tree.readContent('/tsconfig.base.json')).compilerOptions.paths['@my/new-module']).not.toContain('packages-test/my-new-module/dist');
expect(tree.exists('/tsconfig.build.json')).toBe(true);
expect(JSON.parse(tree.readContent('/tsconfig.build.json')).compilerOptions.paths['@my/new-module']).toContain('packages-test/my-new-module/dist');
expect(tree.files.length).toBeGreaterThanOrEqual(9);
});

it('should handle the missing tsconfig.base.json', async () => {
initialTree.create('/packages-test/my-new-module/package.json', '{ "version": "0.0.0-test" }');
initialTree.create('/packages-test/my-new-module/ng-package.json', '{ }');
const runner = new SchematicTestRunner('schematics', collectionPath);
const angularPackageJson = require.resolve('@schematics/angular/package.json');
const o3rCorePackageJson = require.resolve('@o3r/core/package.json');
runner.registerCollection('@o3r/core', path.resolve(path.dirname(o3rCorePackageJson), require(o3rCorePackageJson).schematics));
runner.registerCollection('@schematics/angular', path.resolve(path.dirname(angularPackageJson), require(angularPackageJson).schematics));
const spy = jest.spyOn(require('@angular-devkit/schematics'), 'externalSchematic');
const tree = await runner.runSchematic('library', {
path: 'packages-test',
name: '@my/new-module',
skipLinter: true,
skipInstall: true
}, initialTree);
expect(spy).toHaveBeenNthCalledWith(1, '@schematics/angular', 'library', expect.anything());
expect(tree.exists('/tsconfig.base.json')).toBe(false);
});

// eslint-disable-next-line jest/no-disabled-tests -- TODO: Should be re-enable when the following issue #2066 is fixed
describe.skip('in NX monorepo', () => {
it('should generate Nx project.json with given name', async () => {
Expand Down
56 changes: 38 additions & 18 deletions packages/@o3r/workspace/schematics/library/rules/rules.ng.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,26 +85,46 @@
*/
const updateTsConfigFiles: Rule = (tree, context) => {
const tsconfigBase = findConfigFileRelativePath(tree, ['tsconfig.base.json', 'tsconfig.json'], '/');
const tsconfigBuild = findConfigFileRelativePath(tree, ['tsconfig.build.json'], '/');
[tsconfigBase, tsconfigBuild].forEach((tsconfigPath) => {
if (tsconfigPath) {
const configFile = tree.readJson(tsconfigPath) as TsConfigJson;
if (configFile?.compilerOptions?.paths) {
configFile.compilerOptions.baseUrl = '.';
configFile.compilerOptions.paths = Object.fromEntries(
Object.entries(configFile.compilerOptions.paths).filter(([pathName, _]) => pathName !== options.name));
configFile.compilerOptions.paths[options.packageJsonName] = [
path.posix.join(relativeTargetPath, 'dist'),
path.posix.join(relativeTargetPath, 'src', 'public-api')
];
tree.overwrite(tsconfigPath, JSON.stringify(configFile, null, 2));
} else {
context.logger.warn(`${tsconfigPath} does not contain path mapping, the edition will be skipped`);
let tsconfigBuild = findConfigFileRelativePath(tree, ['tsconfig.build.json'], '/');

if (!tsconfigBase) {
context.logger.error('No TSConfig found in the workspace to register the library.');
return;
}

// create tsconfig.build.json if it does not exist
if (!tsconfigBuild || !tree.exists(tsconfigBuild)) {
const content = {
extends: tsconfigBase.replace(/^\/?/, './'),
compilerOptions: {
declarationMap: false
},
angularCompilerOptions: {
compilationMode: 'partial'
}
} else {
context.logger.warn(`No TsConfig file found at ${tsconfigPath}`);
}
};
tsconfigBuild ||= 'tsconfig.build.json';
tree.create(tsconfigBuild, JSON.stringify(content, null, 2));
}

[tsconfigBase, tsconfigBuild].forEach((tsconfigPath) => {
const configFile = tree.readJson(tsconfigPath) as TsConfigJson;
configFile.compilerOptions ||= {};
configFile.compilerOptions.paths ||= {};
configFile.compilerOptions.baseUrl ||= '.';
configFile.compilerOptions.paths = Object.fromEntries(
Object.entries(configFile.compilerOptions.paths).filter(([pathName, _]) => pathName !== options.name));

Check warning on line 116 in packages/@o3r/workspace/schematics/library/rules/rules.ng.ts

View check run for this annotation

Codecov / codecov/patch

packages/@o3r/workspace/schematics/library/rules/rules.ng.ts#L116

Added line #L116 was not covered by tests
configFile.compilerOptions.paths[options.packageJsonName] = [
path.posix.join(relativeTargetPath, 'src', 'public-api')
];
tree.overwrite(tsconfigPath, JSON.stringify(configFile, null, 2));
});

if (tsconfigBuild && tree.exists(tsconfigBuild)) {
const configFile = tree.readJson(tsconfigBuild) as TsConfigJson;
configFile.compilerOptions!.paths![options.packageJsonName].unshift(path.posix.join(relativeTargetPath, 'dist'));
tree.overwrite(tsconfigBuild, JSON.stringify(configFile, null, 2));
}
};

const ngCliUpdate: Rule = (tree, context) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "<%= tsconfigBuildPath %>"
}
Loading