diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..1e52c4eb --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,19 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Debug Jest Tests", + "type": "node", + "request": "launch", + "runtimeArgs": [ + "--inspect-brk", + "${workspaceRoot}/src/node_modules/.bin/jest", + "--runInBand" + ], + "cwd": "${workspaceFolder}/src", + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen", + "port": 9229 + } + ] +} diff --git a/src/collection.json b/src/collection.json index fb35b947..ee2f6c9c 100644 --- a/src/collection.json +++ b/src/collection.json @@ -3,7 +3,9 @@ "schematics": { "ng-add": { "description": "Add @angular-schule/ngx-deploy-starter deploy schematic", - "factory": "./ng-add#ngAdd" + "factory": "./ng-add#ngAdd", + "schema": "./ng-add-schema.json", + "aliases": ["install"] } } } diff --git a/src/ng-add-schema.json b/src/ng-add-schema.json new file mode 100644 index 00000000..e26d401f --- /dev/null +++ b/src/ng-add-schema.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/schema", + "id": "angular-cli-ghpages-ng-add-schematic", + "title": "angular-cli-ghpages ng-add schematic", + "type": "object", + "properties": { + "project": { + "type": "string", + "description": "The name of the project." + } + }, + "required": [], + "additionalProperties": false +} diff --git a/src/ng-add.spec.ts b/src/ng-add.spec.ts index bb28ebd3..0ddf2e57 100644 --- a/src/ng-add.spec.ts +++ b/src/ng-add.spec.ts @@ -1,4 +1,4 @@ -import { Tree } from '@angular-devkit/schematics'; +import { Tree, SchematicContext } from '@angular-devkit/schematics'; import { ngAdd } from './ng-add'; const PROJECT_NAME = 'pie-ka-chu'; @@ -18,77 +18,70 @@ describe('ng-add', () => { it('generates new files if starting from scratch', async () => { const result = ngAdd({ project: PROJECT_NAME - })(tree, {}); - expect(result.read('angular.json')!.toString()).toEqual( - initialAngularJson - ); - }); + })(tree, {} as SchematicContext); - it('uses default project', async () => { - const result = ngAdd({ - project: PROJECT_NAME - })(tree, {}); - expect(result.read('angular.json')!.toString()).toEqual( - overwriteAngularJson - ); + expect(result.read('angular.json')!.toString()).toEqual(initialAngularJson); }); it('overrides existing files', async () => { + const tempTree = ngAdd({ project: PROJECT_NAME - })(tree, {}); + })(tree, {} as SchematicContext); + const result = ngAdd({ project: OTHER_PROJECT_NAME - })(tempTree, {}); - expect(result.read('angular.json')!.toString()).toEqual( - projectAngularJson - ); + })(tempTree, {} as SchematicContext); + + const actual = result.read('angular.json')!.toString(); + + expect(actual).toEqual(overwriteAngularJson); }); }); describe('error handling', () => { it('fails if project not defined', () => { + const tree = Tree.empty(); const angularJSON = generateAngularJson(); delete angularJSON.defaultProject; tree.create('angular.json', JSON.stringify(angularJSON)); + expect(() => ngAdd({ project: '' - })(tree, {}) - ).toThrowError( - /No Angular project selected and no default project in the workspace/ - ); + })(tree, {} as SchematicContext) + ).toThrowError('No Angular project selected and no default project in the workspace'); }); it('Should throw if angular.json not found', async () => { expect(() => ngAdd({ project: PROJECT_NAME - })(Tree.empty(), {}) - ).toThrowError(/Could not find angular.json/); + })(Tree.empty(), {} as SchematicContext) + ).toThrowError('Could not find angular.json'); }); - it('Should throw if angular.json can not be parsed', async () => { + it('Should throw if angular.json can not be parsed', async () => { const tree = Tree.empty(); tree.create('angular.json', 'hi'); + expect(() => ngAdd({ project: PROJECT_NAME - })(tree, {}) - ).toThrowError(/Could not parse angular.json/); + })(tree, {} as SchematicContext) + ).toThrowError('Could not parse angular.json'); }); it('Should throw if specified project does not exist ', async () => { const tree = Tree.empty(); tree.create('angular.json', JSON.stringify({ projects: {} })); + expect(() => ngAdd({ project: PROJECT_NAME - })(tree, {}) - ).toThrowError( - /No Angular project selected and no default project in the workspace/ - ); + })(tree, {} as SchematicContext) + ).toThrowError('The specified Angular project is not defined in this workspace'); }); it('Should throw if specified project is not application', async () => { @@ -99,13 +92,12 @@ describe('ng-add', () => { projects: { [PROJECT_NAME]: { projectType: 'pokemon' } } }) ); + expect(() => ngAdd({ project: PROJECT_NAME - })(tree, {}) - ).toThrowError( - /No Angular project selected and no default project in the workspace/ - ); + })(tree, {} as SchematicContext) + ).toThrowError('Deploy requires an Angular project type of "application" in angular.json'); }); it('Should throw if app does not have architect configured', async () => { @@ -116,13 +108,12 @@ describe('ng-add', () => { projects: { [PROJECT_NAME]: { projectType: 'application' } } }) ); + expect(() => ngAdd({ project: PROJECT_NAME - })(tree, {}) - ).toThrowError( - /No Angular project selected and no default project in the workspace/ - ); + })(tree, {} as SchematicContext) + ).toThrowError('Cannot read the output path (architect.build.options.outputPath) of the Angular project "pie-ka-chu" in angular.json'); }); }); }); @@ -158,30 +149,30 @@ function generateAngularJson() { } const initialAngularJson = `{ - \"defaultProject\": \"pie-ka-chu\", - \"projects\": { - \"pie-ka-chu\": { - \"projectType\": \"application\", - \"root\": \"pirojok\", - \"architect\": { - \"build\": { - \"options\": { - \"outputPath\": \"dist/ikachu\" + "defaultProject": "pie-ka-chu", + "projects": { + "pie-ka-chu": { + "projectType": "application", + "root": "pirojok", + "architect": { + "build": { + "options": { + "outputPath": "dist/ikachu" } }, - \"deploy\": { - \"builder\": \"@angular-schule/ngx-deploy-starter:deploy\", - \"options\": {} + "deploy": { + "builder": "@angular-schule/ngx-deploy-starter:deploy", + "options": {} } } }, - \"pi-catch-you\": { - \"projectType\": \"application\", - \"root\": \"pirojok\", - \"architect\": { - \"build\": { - \"options\": { - \"outputPath\": \"dist/ikachu\" + "pi-catch-you": { + "projectType": "application", + "root": "pirojok", + "architect": { + "build": { + "options": { + "outputPath": "dist/ikachu" } } } @@ -190,65 +181,38 @@ const initialAngularJson = `{ }`; const overwriteAngularJson = `{ - \"defaultProject\": \"pie-ka-chu\", - \"projects\": { - \"pie-ka-chu\": { - \"projectType\": \"application\", - \"root\": \"pirojok\", - \"architect\": { - \"build\": { - \"options\": { - \"outputPath\": \"dist/ikachu\" + "defaultProject": "pie-ka-chu", + "projects": { + "pie-ka-chu": { + "projectType": "application", + "root": "pirojok", + "architect": { + "build": { + "options": { + "outputPath": "dist/ikachu" } }, - \"deploy\": { - \"builder\": \"@angular-schule/ngx-deploy-starter:deploy\", - \"options\": {} + "deploy": { + "builder": "@angular-schule/ngx-deploy-starter:deploy", + "options": {} } } }, - \"pi-catch-you\": { - \"projectType\": \"application\", - \"root\": \"pirojok\", - \"architect\": { - \"build\": { - \"options\": { - \"outputPath\": \"dist/ikachu\" - } - } - } - } - } -}`; - -const projectAngularJson = `{ - \"defaultProject\": \"pie-ka-chu\", - \"projects\": { - \"pie-ka-chu\": { - \"projectType\": \"application\", - \"root\": \"pirojok\", - \"architect\": { - \"build\": { - \"options\": { - \"outputPath\": \"dist/ikachu\" + "pi-catch-you": { + "projectType": "application", + "root": "pirojok", + "architect": { + "build": { + "options": { + "outputPath": "dist/ikachu" } }, - \"deploy\": { - \"builder\": \"@angular-schule/ngx-deploy-starter:deploy\", - \"options\": {} - } - } - }, - \"pi-catch-you\": { - \"projectType\": \"application\", - \"root\": \"pirojok\", - \"architect\": { - \"build\": { - \"options\": { - \"outputPath\": \"dist/ikachu\" - } + "deploy": { + "builder": "@angular-schule/ngx-deploy-starter:deploy", + "options": {} } } } } }`; + diff --git a/src/ng-add.ts b/src/ng-add.ts index 224eb9ed..124a956b 100644 --- a/src/ng-add.ts +++ b/src/ng-add.ts @@ -1,4 +1,4 @@ -import { SchematicsException, Tree } from '@angular-devkit/schematics'; +import { SchematicsException, Tree, SchematicContext } from '@angular-devkit/schematics'; import { experimental, JsonParseMode, parseJson } from '@angular-devkit/core'; function getWorkspace( @@ -29,16 +29,12 @@ function getWorkspace( }; } interface NgAddOptions { - project?: string; -} - -interface DeployOptions { project: string; } -export const ngAdd = ({ project: DeployOptions }) => ( +export const ngAdd = (options: NgAddOptions) => ( tree: Tree, - options: NgAddOptions + _context: SchematicContext ) => { const { path: workspacePath, workspace } = getWorkspace(tree); diff --git a/src/package.json b/src/package.json index 9432a00e..18b66d4b 100644 --- a/src/package.json +++ b/src/package.json @@ -4,7 +4,7 @@ "description": "Deployment from the Angular CLI to the file system. This is a sample project that helps you to implement your own deployment builder (`ng deploy`) for the Angular CLI.", "main": "index.js", "scripts": { - "build": "rimraf dist && json2ts deploy/schema.json > deploy/schema.d.ts && tsc && copyfiles README.md builders.json collection.json package.json ngx-deploy-starter deploy/schema.json dist", + "build": "rimraf dist && json2ts deploy/schema.json > deploy/schema.d.ts && tsc && copyfiles README.md builders.json collection.json ng-add-schema.json package.json ngx-deploy-starter deploy/schema.json dist", "test": "jest" }, "schematics": "./collection.json",