Skip to content

Commit

Permalink
fix(workspace): add tsconfig.json dedicated to the application
Browse files Browse the repository at this point in the history
  • Loading branch information
kpanot committed Dec 27, 2024
1 parent c8834dc commit adf2777
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 10 deletions.
3 changes: 3 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ ignore:
- 'packages/@o3r-training/showcase-sdk/src/spec/**/*'
- 'tools/github-actions/*/packaged-action/**/*'

# Templates
- '**/*.template'

comment:
layout: "condensed_header, condensed_files, condensed_footer"
behavior: default
Expand Down
25 changes: 17 additions & 8 deletions packages/@o3r/workspace/schematics/application/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,19 @@ const collectionPath = path.join(__dirname, '../../collection.json');
let runner: SchematicTestRunner;

describe('generateApplication', () => {
let initalTree: UnitTestTree;
let initialTree: UnitTestTree;

beforeEach(() => {
initalTree = new UnitTestTree(Tree.empty());
initalTree.create('angular.json', fs.readFileSync(path.resolve(__dirname, '..', '..', 'testing', 'mocks', 'angular.mocks.json')));
initalTree.create('package.json', fs.readFileSync(path.resolve(__dirname, '..', '..', 'testing', 'mocks', 'package.mocks.json')));
initialTree = new UnitTestTree(Tree.empty());
initialTree.create('angular.json', fs.readFileSync(path.resolve(__dirname, '..', '..', 'testing', 'mocks', 'angular.mocks.json')));
initialTree.create('package.json', fs.readFileSync(path.resolve(__dirname, '..', '..', 'testing', 'mocks', 'package.mocks.json')));
runner = new SchematicTestRunner('schematics', collectionPath);
const angularPackageJson = require.resolve('@schematics/angular/package.json');
runner.registerCollection('@schematics/angular', path.resolve(path.dirname(angularPackageJson), require(angularPackageJson).schematics));
});

it('should generate an application', async () => {
const tree = await runner.runSchematic('application', { name: 'test', routing: true }, initalTree);
const tree = await runner.runSchematic('application', { name: 'test', routing: true }, initialTree);
const mockExternalSchematic = require('@angular-devkit/schematics').externalSchematic as jest.Mock;
expect(mockExternalSchematic).toHaveBeenCalledWith('@schematics/angular', 'application', expect.objectContaining({
name: 'test',
Expand All @@ -55,7 +55,7 @@ describe('generateApplication', () => {
});

it('should generate an application with provided path', async () => {
const tree = await runner.runSchematic('application', { name: 'test', path: '/apps' }, initalTree);
const tree = await runner.runSchematic('application', { name: 'test', path: '/apps' }, initialTree);
const mockExternalSchematic = require('@angular-devkit/schematics').externalSchematic as jest.Mock;
expect(mockExternalSchematic).toHaveBeenCalledWith('@schematics/angular', 'application', expect.objectContaining({
name: 'test',
Expand All @@ -67,15 +67,24 @@ describe('generateApplication', () => {
});
});

it('should register the application in tsconfig', async () => {
initialTree.create('/tsconfig.base.json', JSON.stringify({}));
const tree = await runner.runSchematic('application', { name: 'test', path: '/apps' }, initialTree);
const mockExternalSchematic = require('@angular-devkit/schematics').externalSchematic as jest.Mock;
expect(mockExternalSchematic).toHaveBeenCalled();
expect(tree.exists('/apps/test/tsconfig.json')).toBe(true);
expect(tree.readJson('/apps/test/tsconfig.json')).toMatchObject({ extends: '../../tsconfig.base.json' });
});

it('should throw error if NX context is detected', async () => {
require('@o3r/schematics').isNxContext.mockReturnValueOnce(true);
await expect(runner.runSchematic('application', { name: 'test' }, initalTree)).rejects.toThrow(
await expect(runner.runSchematic('application', { name: 'test' }, initialTree)).rejects.toThrow(
'NX is not currently supported. Feature tracked via https://github.com/AmadeusITGroup/otter/issues/720');
});

it('should throw error if no workspace configuration is found', async () => {
require('@o3r/schematics').getWorkspaceConfig.mockReturnValueOnce(null);
await expect(runner.runSchematic('application', { name: 'test' }, initalTree)).rejects.toThrow(
await expect(runner.runSchematic('application', { name: 'test' }, initialTree)).rejects.toThrow(
'The `path` option is not provided and no workspace configuration file found to define it.');
});
});
23 changes: 21 additions & 2 deletions packages/@o3r/workspace/schematics/application/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
Schematic,
strings,
template,
type Tree,
url,
} from '@angular-devkit/schematics';
import {
Expand Down Expand Up @@ -42,6 +43,21 @@ import type {
NgGenerateApplicationSchema,
} from './schema';

/**
* Find the relative path to a configuration file at the monorepo root
* @param tree
* @param files List of files to look for, the first of the list will be used
* @param originPath Path from where to calculate the relative path
*/
function findConfigFileRelativePath(tree: Tree, files: string[], originPath: string) {
const foundFile = files.find((file) => tree.exists(`/${file}`));
if (foundFile === undefined) {
return '';
}

return path.posix.relative(originPath, `/${foundFile}`);
}

/**
* Add an Otter application to a monorepo
* @param options Schematic options
Expand All @@ -51,10 +67,11 @@ function generateApplicationFn(options: NgGenerateApplicationSchema): Rule {
const packageJsonName = strings.dasherize(options.name);
const cleanName = packageJsonName.replace(/^@/, '').replaceAll(/\//g, '-');

const addProjectSpecificFiles = (targetPath: string, rootDependencies: Record<string, string | undefined>) => {
const addProjectSpecificFiles = (targetPath: string, rootDependencies: Record<string, string | undefined>, tsconfigBasePath: string) => {
return mergeWith(apply(url('./templates'), [
template({
...options,
tsconfigBasePath,
enforceTildeRange,
name: packageJsonName,
rootDependencies
Expand Down Expand Up @@ -109,13 +126,15 @@ function generateApplicationFn(options: NgGenerateApplicationSchema): Rule {
}
} as const satisfies Record<string, DependencyToAdd>;

const tsconfigBasePath = findConfigFileRelativePath(tree, ['tsconfig.base.json', 'tsconfig.json'], targetPath);

return chain([
externalSchematic<Partial<ApplicationOptions>>('@schematics/angular', 'application', {
...Object.entries(extendedOptions).reduce((acc, [key, value]) => (angularOptions.includes(key) ? { ...acc, [key]: value } : acc), {}),
name: cleanName,
projectRoot,
style: Style.Scss }),
addProjectSpecificFiles(targetPath, rootDependencies),
addProjectSpecificFiles(targetPath, rootDependencies, tsconfigBasePath),
updateProjectTsConfig(targetPath, 'tsconfig.app.json', { updateInputFiles: true }),
setupDependencies({
dependencies,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/* For IDE usage only */
{
"extends": "<%= tsconfigBasePath %>",
"references": [
{"path": "./tsconfig.app.json"},
{"path": "./tsconfig.spec.json"}
]
}

0 comments on commit adf2777

Please sign in to comment.