diff --git a/packages/angular_devkit/architect/src/architect.ts b/packages/angular_devkit/architect/src/architect.ts index 5143204494..da620d2ec5 100644 --- a/packages/angular_devkit/architect/src/architect.ts +++ b/packages/angular_devkit/architect/src/architect.ts @@ -78,6 +78,7 @@ export interface BuilderConfiguration { export interface TargetSpecifier { project: string; + projectFilter?: experimental.workspace.projectFilter; target: string; configuration?: string; overrides?: Partial; diff --git a/packages/angular_devkit/core/src/workspace/workspace.ts b/packages/angular_devkit/core/src/workspace/workspace.ts index 703dd263a4..bcabb9a569 100644 --- a/packages/angular_devkit/core/src/workspace/workspace.ts +++ b/packages/angular_devkit/core/src/workspace/workspace.ts @@ -48,6 +48,8 @@ export class WorkspaceNotYetLoadedException extends BaseException { } +export type projectFilter = (project: WorkspaceProject, name: string) => boolean; + export class Workspace { private readonly _workspaceSchemaPath = join(normalize(__dirname), 'workspace-schema.json'); private _workspaceSchema: JsonObject; @@ -109,8 +111,12 @@ export class Workspace { return this._workspace.newProjectRoot; } - listProjectNames(): string[] { - return Object.keys(this._workspace.projects); + listProjectNames(filter?: projectFilter): string[] { + const projectNames = Object.keys(this._workspace.projects); + + return filter ? projectNames.filter((name) => + filter(this._workspace.projects[name], name), + ) : projectNames; } getProject(projectName: string): WorkspaceProject { diff --git a/packages/angular_devkit/core/src/workspace/workspace_spec.ts b/packages/angular_devkit/core/src/workspace/workspace_spec.ts index a27661a42a..547e03b499 100644 --- a/packages/angular_devkit/core/src/workspace/workspace_spec.ts +++ b/packages/angular_devkit/core/src/workspace/workspace_spec.ts @@ -14,15 +14,15 @@ import { ProjectNotFoundException, Workspace, WorkspaceNotYetLoadedException, + projectFilter, } from './workspace'; import { WorkspaceProject, WorkspaceSchema, WorkspaceTool } from './workspace-schema'; - describe('Workspace', () => { const host = new NodeJsSyncHost(); const root = normalize(__dirname); // The content of this JSON object should be kept in sync with the path below: - // tests/@angular_devkit/workspace/angular-workspace.json + // tests/@angular_devkit/core/workspace/angular-workspace.json const workspaceJson: WorkspaceSchema = { version: 1, newProjectRoot: './projects', @@ -98,8 +98,47 @@ describe('Workspace', () => { }, }, }, + lib: { + root: 'projects/lib', + projectType: 'library', + prefix: 'lib', + architect: { + 'build': { + 'builder': '@angular-devkit/build-ng-packagr:build', + 'options': { + 'project': 'projects/lib/ng-package.json', + }, + 'configurations': { + 'production': { + 'project': 'projects/lib/ng-package.prod.json', + }, + }, + }, + test: { + 'builder': '@angular-devkit/build-angular:karma', + 'options': { + 'main': 'projects/lib/src/test.ts', + 'tsConfig': 'projects/lib/tsconfig.spec.json', + 'karmaConfig': 'projects/lib/karma.conf.js', + }, + }, + lint: { + 'builder': '@angular-devkit/build-angular:tslint', + 'options': { + 'tsConfig': [ + 'projects/lib/tsconfig.lint.json', + 'projects/lib/tsconfig.spec.json', + ], + 'exclude': [ + '**/node_modules/**', + ], + }, + }, + }, + }, }, }; + const appProject = { ...workspaceJson.projects['app'], // Tools should not be returned when getting a project. @@ -167,10 +206,26 @@ describe('Workspace', () => { ).subscribe(undefined, done.fail, done); }); - it('lists project names', (done) => { + it('lists all project names', (done) => { + const workspace = new Workspace(root, host); + workspace.loadWorkspaceFromJson(workspaceJson).pipe( + tap((ws) => expect(ws.listProjectNames()).toEqual(['app', 'lib'])), + ).subscribe(undefined, done.fail, done); + }); + + it('lists project names filtered by project property value', (done) => { + const workspace = new Workspace(root, host); + const librariesFilter: projectFilter = (project, name) => project.projectType === 'library'; + workspace.loadWorkspaceFromJson(workspaceJson).pipe( + tap((ws) => expect(ws.listProjectNames(librariesFilter)).toEqual(['lib'])), + ).subscribe(undefined, done.fail, done); + }); + + it('lists filtered project names', (done) => { const workspace = new Workspace(root, host); + const nameFilter: projectFilter = (project, name) => name.startsWith('a'); workspace.loadWorkspaceFromJson(workspaceJson).pipe( - tap((ws) => expect(ws.listProjectNames()).toEqual(['app'])), + tap((ws) => expect(ws.listProjectNames(nameFilter)).toEqual(['app'])), ).subscribe(undefined, done.fail, done); }); @@ -196,7 +251,11 @@ describe('Workspace', () => { }); it('gets default project when there is a single one', (done) => { - const customWorkspaceJson = { ...workspaceJson, defaultProject: undefined }; + const customWorkspaceJson: WorkspaceSchema = { + ...workspaceJson, + defaultProject: undefined, + projects: { app: {...workspaceJson.projects.app}}, + }; const workspace = new Workspace(root, host); workspace.loadWorkspaceFromJson(customWorkspaceJson).pipe( tap((ws) => expect(ws.getDefaultProjectName()).toEqual('app')), @@ -213,8 +272,9 @@ describe('Workspace', () => { it('gets project by path', (done) => { const workspace = new Workspace(root, host); + const appRoot = normalize(workspaceJson.projects.app.root); workspace.loadWorkspaceFromJson(workspaceJson).pipe( - tap((ws) => expect(ws.getProjectByPath(ws.root)).toEqual('app')), + tap((ws) => expect(ws.getProjectByPath(appRoot)).toEqual('app')), ).subscribe(undefined, done.fail, done); }); @@ -222,7 +282,7 @@ describe('Workspace', () => { const app = workspaceJson.projects['app']; const anotherAppRoot = join(normalize(app.root), 'folder'); const customWorkspaceJson = { ...workspaceJson, projects: { - 'app': app, + ...workspaceJson.projects, 'another-app': { ...app, root: anotherAppRoot}, } }; const workspace = new Workspace(root, host); diff --git a/tests/@angular_devkit/core/workspace/angular-workspace.json b/tests/@angular_devkit/core/workspace/angular-workspace.json index 46c20948ac..eb16f82138 100644 --- a/tests/@angular_devkit/core/workspace/angular-workspace.json +++ b/tests/@angular_devkit/core/workspace/angular-workspace.json @@ -69,6 +69,44 @@ } } } + }, + "lib": { + "root": "projects/lib", + "projectType": "library", + "prefix": "lib", + "architect": { + "build": { + "builder": "@angular-devkit/build-ng-packagr:build", + "options": { + "project": "projects/lib/ng-package.json" + }, + "configurations": { + "production": { + "project": "projects/lib/ng-package.prod.json" + } + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "main": "projects/lib/src/test.ts", + "tsConfig": "projects/lib/tsconfig.spec.json", + "karmaConfig": "projects/lib/karma.conf.js" + } + }, + "lint": { + "builder": "@angular-devkit/build-angular:tslint", + "options": { + "tsConfig": [ + "projects/lib/tsconfig.lint.json", + "projects/lib/tsconfig.spec.json" + ], + "exclude": [ + "**/node_modules/**" + ] + } + } + } } } } \ No newline at end of file