Skip to content
This repository has been archived by the owner on Jan 26, 2024. It is now read-only.

feat: add support for Angular v13 by @fmalcher #30

Merged
merged 4 commits into from
Nov 21, 2021
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
3 changes: 1 addition & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ version: 2

jobs:
build:

docker:
- image: circleci/node:12-browsers
- image: circleci/node:14-browsers

steps:
- checkout
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ jobs:
- name: Checkout
uses: actions/checkout@v2

- name: Use Node.js 10.x
- name: Use Node.js 14.x
uses: actions/setup-node@v1
with:
node-version: 10.x
node-version: 14.x

- name: Prepare
run: |
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2019-2020 Johannes Hoppe
Copyright (c) 2019-2021 Johannes Hoppe
Copyright (c) 2019 Minko Gechev

Permission is hereby granted, free of charge, to any person obtaining a copy of
Expand Down
72 changes: 72 additions & 0 deletions src/__snapshots__/ng-add.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`ng-add generating files generates new files if starting from scratch 1`] = `
"{
\\"version\\": 1,
\\"defaultProject\\": \\"THEPROJECT\\",
\\"projects\\": {
\\"THEPROJECT\\": {
\\"projectType\\": \\"application\\",
\\"root\\": \\"PROJECTROOT\\",
\\"architect\\": {
\\"build\\": {
\\"options\\": {
\\"outputPath\\": \\"dist/THEPROJECT\\"
}
},
\\"deploy\\": {
\\"builder\\": \\"@angular-schule/ngx-deploy-starter:deploy\\"
}
}
},
\\"OTHERPROJECT\\": {
\\"projectType\\": \\"application\\",
\\"root\\": \\"PROJECTROOT\\",
\\"architect\\": {
\\"build\\": {
\\"options\\": {
\\"outputPath\\": \\"dist/OTHERPROJECT\\"
}
}
}
}
}
}"
`;

exports[`ng-add generating files overrides existing files 1`] = `
"{
\\"version\\": 1,
\\"defaultProject\\": \\"THEPROJECT\\",
\\"projects\\": {
\\"THEPROJECT\\": {
\\"projectType\\": \\"application\\",
\\"root\\": \\"PROJECTROOT\\",
\\"architect\\": {
\\"build\\": {
\\"options\\": {
\\"outputPath\\": \\"dist/THEPROJECT\\"
}
},
\\"deploy\\": {
\\"builder\\": \\"@angular-schule/ngx-deploy-starter:deploy\\"
}
}
},
\\"OTHERPROJECT\\": {
\\"projectType\\": \\"application\\",
\\"root\\": \\"PROJECTROOT\\",
\\"architect\\": {
\\"build\\": {
\\"options\\": {
\\"outputPath\\": \\"dist/OTHERPROJECT\\"
}
},
\\"deploy\\": {
\\"builder\\": \\"@angular-schule/ngx-deploy-starter:deploy\\"
}
}
}
}
}"
`;
6 changes: 3 additions & 3 deletions src/deploy/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {
BuilderContext,
targetFromTargetString
} from '@angular-devkit/architect';
import { json, logging } from '@angular-devkit/core';
import { logging } from '@angular-devkit/core';

import { Schema } from './schema';
import { BuildTarget } from '../interfaces';
Expand Down Expand Up @@ -31,8 +31,8 @@ export default async function deploy(
...(options.baseHref && { baseHref: options.baseHref })
};

context.logger.info(` Building "${context.target.project}"`);
context.logger.info(` Build target "${buildTarget.name}"`);
context.logger.info(`📦 Building "${context.target.project}"`);
context.logger.info(`📦 Build target "${buildTarget.name}"`);

const build = await context.scheduleTarget(
targetFromTargetString(buildTarget.name),
Expand Down
2 changes: 1 addition & 1 deletion src/deploy/schema.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"id": "Schema",
"$id": "Schema",
"title": "schema",
"description": "Deployment of Angular CLI applications to the file system",
"properties": {
Expand Down
2 changes: 1 addition & 1 deletion src/ng-add-schema.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"$schema": "http://json-schema.org/schema",
"id": "ngx-deploy-starter-ng-add-schematic",
"$id": "ngx-deploy-starter-ng-add-schematic",
"title": "ngx-deploy-starter ng-add schematic",
"type": "object",
"properties": {},
Expand Down
141 changes: 39 additions & 102 deletions src/ng-add.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ import { SchematicContext, Tree } from '@angular-devkit/schematics';

import { ngAdd } from './ng-add';

const PROJECT_NAME = 'pie-ka-chu';
const PROJECT_ROOT = 'pirojok';

const OTHER_PROJECT_NAME = 'pi-catch-you';
const PROJECT_NAME = 'THEPROJECT';
const PROJECT_ROOT = 'PROJECTROOT';
const OTHER_PROJECT_NAME = 'OTHERPROJECT';

describe('ng-add', () => {
describe('generating files', () => {
Expand All @@ -17,118 +16,124 @@ describe('ng-add', () => {
});

it('generates new files if starting from scratch', async () => {
const result = ngAdd({
const result = await ngAdd({
project: PROJECT_NAME
})(tree, {} as SchematicContext);

expect(result.read('angular.json')!.toString()).toEqual(
initialAngularJson
);
const actual = result.read('angular.json')!.toString();
expect(prettifyJSON(actual)).toMatchSnapshot();
});

it('overrides existing files', async () => {
const tempTree = ngAdd({
const tempTree = await ngAdd({
project: PROJECT_NAME
})(tree, {} as SchematicContext);

const result = ngAdd({
const result = await ngAdd({
project: OTHER_PROJECT_NAME
})(tempTree, {} as SchematicContext);

const actual = result.read('angular.json')!.toString();

expect(actual).toEqual(overwriteAngularJson);
expect(prettifyJSON(actual)).toMatchSnapshot();
});
});

describe('error handling', () => {
it('fails if project not defined', () => {
it('should fail if project not defined', async () => {
const tree = Tree.empty();
const angularJSON = generateAngularJson();
delete angularJSON.defaultProject;
tree.create('angular.json', JSON.stringify(angularJSON));

expect(() =>
await expect(
ngAdd({
project: ''
})(tree, {} as SchematicContext)
).toThrowError(
).rejects.toThrowError(
'No Angular project selected and no default project in the workspace'
);
});

it('Should throw if angular.json not found', async () => {
expect(() =>
it('should throw if angular.json not found', async () => {
await expect(
ngAdd({
project: PROJECT_NAME
})(Tree.empty(), {} as SchematicContext)
).toThrowError('Could not find angular.json');
).rejects.toThrowError('Unable to determine format for workspace path.');
});

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(() =>
await expect(
ngAdd({
project: PROJECT_NAME
})(tree, {} as SchematicContext)
).toThrowError('Could not parse angular.json');
).rejects.toThrowError('Invalid JSON character: "h" at 0:0.');
});

it('Should throw if specified project does not exist ', async () => {
it('should throw if specified project does not exist', async () => {
const tree = Tree.empty();
tree.create('angular.json', JSON.stringify({ projects: {} }));
tree.create('angular.json', JSON.stringify({ version: 1, projects: {} }));

expect(() =>
await expect(
ngAdd({
project: PROJECT_NAME
})(tree, {} as SchematicContext)
).toThrowError(
).rejects.toThrowError(
'The specified Angular project is not defined in this workspace'
);
});

it('Should throw if specified project is not application', async () => {
it('should throw if specified project is not application', async () => {
const tree = Tree.empty();
tree.create(
'angular.json',
JSON.stringify({
projects: { [PROJECT_NAME]: { projectType: 'pokemon' } }
version: 1,
projects: { [PROJECT_NAME]: { projectType: 'invalid' } }
})
);

expect(() =>
await expect(
ngAdd({
project: PROJECT_NAME
})(tree, {} as SchematicContext)
).toThrowError(
).rejects.toThrowError(
'Deploy requires an Angular project type of "application" in angular.json'
);
});

it('Should throw if app does not have architect configured', async () => {
it('should throw if app does not have architect configured', async () => {
const tree = Tree.empty();
tree.create(
'angular.json',
JSON.stringify({
version: 1,
projects: { [PROJECT_NAME]: { projectType: 'application' } }
})
);

expect(() =>
await expect(
ngAdd({
project: PROJECT_NAME
})(tree, {} as SchematicContext)
).toThrowError(
'Cannot read the output path (architect.build.options.outputPath) of the Angular project "pie-ka-chu" in angular.json'
).rejects.toThrowError(
'Cannot read the output path (architect.build.options.outputPath) of the Angular project "THEPROJECT" in angular.json'
);
});
});
});

function prettifyJSON(json: string) {
return JSON.stringify(JSON.parse(json), null, 2);
}

function generateAngularJson() {
return {
version: 1,
defaultProject: PROJECT_NAME as string | undefined,
projects: {
[PROJECT_NAME]: {
Expand All @@ -137,7 +142,7 @@ function generateAngularJson() {
architect: {
build: {
options: {
outputPath: 'dist/ikachu'
outputPath: 'dist/' + PROJECT_NAME
}
}
}
Expand All @@ -148,79 +153,11 @@ function generateAngularJson() {
architect: {
build: {
options: {
outputPath: 'dist/ikachu'
outputPath: 'dist/' + OTHER_PROJECT_NAME
}
}
}
}
}
};
}

const initialAngularJson = `{
"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": {}
}
}
},
"pi-catch-you": {
"projectType": "application",
"root": "pirojok",
"architect": {
"build": {
"options": {
"outputPath": "dist/ikachu"
}
}
}
}
}
}`;

const overwriteAngularJson = `{
"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": {}
}
}
},
"pi-catch-you": {
"projectType": "application",
"root": "pirojok",
"architect": {
"build": {
"options": {
"outputPath": "dist/ikachu"
}
},
"deploy": {
"builder": "@angular-schule/ngx-deploy-starter:deploy",
"options": {}
}
}
}
}
}`;
Loading