diff --git a/packages/schematics/angular/migrations/use-library-builder/migration.ts b/packages/schematics/angular/migrations/use-library-builder/migration.ts index 68f9e8738e25..285cdf9f2332 100644 --- a/packages/schematics/angular/migrations/use-library-builder/migration.ts +++ b/packages/schematics/angular/migrations/use-library-builder/migration.ts @@ -251,7 +251,23 @@ function migrateTargetOptions( : []; const migratedAssets = ngPackageConfig.assets.map((asset) => { if (typeof asset === 'string') { - return join(projectDir, asset); + const assetPath = join(projectDir, asset); + if (assetPath.startsWith('..')) { + return assetPath; + } + + if (tree.exists(assetPath)) { + return assetPath; + } + + const assetDir = tree.getDir(assetPath); + if (assetDir.subfiles.length || assetDir.subdirs.length) { + return assetPath; + } + + // `ng-packagr` treats a string that is neither a file nor a directory as a glob relative + // to the package root, while the library builder only accepts files and directories. + return { glob: asset, input: projectDir }; } if (isJsonObject(asset) && typeof asset['input'] === 'string') { return { diff --git a/packages/schematics/angular/migrations/use-library-builder/migration_spec.ts b/packages/schematics/angular/migrations/use-library-builder/migration_spec.ts index 11192f8e5897..d54d5f62f61a 100644 --- a/packages/schematics/angular/migrations/use-library-builder/migration_spec.ts +++ b/packages/schematics/angular/migrations/use-library-builder/migration_spec.ts @@ -281,6 +281,7 @@ describe('Migration to use the library builder', () => { }); it('should migrate assets, styleIncludePaths, and sass options from ng-package.json', async () => { + tree.create('/projects/my-lib/CHANGELOG.md', '# Changelog'); tree.overwrite( '/projects/my-lib/ng-package.json', JSON.stringify( @@ -324,6 +325,48 @@ describe('Migration to use the library builder', () => { }); }); + it('should migrate ng-packagr glob string assets to glob objects', async () => { + tree.create('/projects/my-lib/docs/guide.md', '# Guide'); + tree.create('/projects/my-lib/CHANGELOG.md', '# Changelog'); + tree.overwrite( + '/projects/my-lib/ng-package.json', + JSON.stringify({ + assets: ['CHANGELOG.md', 'docs', 'docs/**/*.md'], + lib: { entryFile: 'src/public-api.ts' }, + }), + ); + + const newTree = await schematicRunner.runSchematic(schematicName, {}, tree); + const { + projects: { 'my-lib': lib }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } = newTree.readJson('/angular.json') as any; + + expect(lib.architect['build'].options.assets).toEqual([ + 'projects/my-lib/CHANGELOG.md', + 'projects/my-lib/docs', + { glob: 'docs/**/*.md', input: 'projects/my-lib' }, + ]); + }); + + it('should keep ng-packagr assets outside the project root as paths', async () => { + tree.overwrite( + '/projects/my-lib/ng-package.json', + JSON.stringify({ + assets: ['../../../shared-assets'], + lib: { entryFile: 'src/public-api.ts' }, + }), + ); + + const newTree = await schematicRunner.runSchematic(schematicName, {}, tree); + const { + projects: { 'my-lib': lib }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } = newTree.readJson('/angular.json') as any; + + expect(lib.architect['build'].options.assets).toEqual(['../shared-assets']); + }); + it('should preserve existing stylePreprocessorOptions.includePaths when migrating styleIncludePaths', async () => { const angularJson = JSON.parse(tree.readContent('/angular.json')); angularJson.projects['my-lib'].architect.build.options.stylePreprocessorOptions = {