[6a3a178] | 1 | "use strict";
|
---|
| 2 | /**
|
---|
| 3 | * @license
|
---|
| 4 | * Copyright Google LLC All Rights Reserved.
|
---|
| 5 | *
|
---|
| 6 | * Use of this source code is governed by an MIT-style license that can be
|
---|
| 7 | * found in the LICENSE file at https://angular.io/license
|
---|
| 8 | */
|
---|
| 9 | Object.defineProperty(exports, "__esModule", { value: true });
|
---|
| 10 | exports.SchematicEngine = exports.TaskScheduler = exports.CollectionImpl = exports.UnknownTaskDependencyException = exports.UnregisteredTaskException = exports.SchematicEngineConflictingException = exports.PrivateSchematicException = exports.UnknownSchematicException = exports.CircularCollectionException = exports.UnknownCollectionException = exports.UnknownUrlSourceProtocol = void 0;
|
---|
| 11 | const core_1 = require("@angular-devkit/core");
|
---|
| 12 | const rxjs_1 = require("rxjs");
|
---|
| 13 | const operators_1 = require("rxjs/operators");
|
---|
| 14 | const interface_1 = require("../tree/interface");
|
---|
| 15 | const null_1 = require("../tree/null");
|
---|
| 16 | const static_1 = require("../tree/static");
|
---|
| 17 | const schematic_1 = require("./schematic");
|
---|
| 18 | class UnknownUrlSourceProtocol extends core_1.BaseException {
|
---|
| 19 | constructor(url) {
|
---|
| 20 | super(`Unknown Protocol on url "${url}".`);
|
---|
| 21 | }
|
---|
| 22 | }
|
---|
| 23 | exports.UnknownUrlSourceProtocol = UnknownUrlSourceProtocol;
|
---|
| 24 | class UnknownCollectionException extends core_1.BaseException {
|
---|
| 25 | constructor(name) {
|
---|
| 26 | super(`Unknown collection "${name}".`);
|
---|
| 27 | }
|
---|
| 28 | }
|
---|
| 29 | exports.UnknownCollectionException = UnknownCollectionException;
|
---|
| 30 | class CircularCollectionException extends core_1.BaseException {
|
---|
| 31 | constructor(name) {
|
---|
| 32 | super(`Circular collection reference "${name}".`);
|
---|
| 33 | }
|
---|
| 34 | }
|
---|
| 35 | exports.CircularCollectionException = CircularCollectionException;
|
---|
| 36 | class UnknownSchematicException extends core_1.BaseException {
|
---|
| 37 | constructor(name, collection) {
|
---|
| 38 | super(`Schematic "${name}" not found in collection "${collection.name}".`);
|
---|
| 39 | }
|
---|
| 40 | }
|
---|
| 41 | exports.UnknownSchematicException = UnknownSchematicException;
|
---|
| 42 | class PrivateSchematicException extends core_1.BaseException {
|
---|
| 43 | constructor(name, collection) {
|
---|
| 44 | super(`Schematic "${name}" not found in collection "${collection.name}".`);
|
---|
| 45 | }
|
---|
| 46 | }
|
---|
| 47 | exports.PrivateSchematicException = PrivateSchematicException;
|
---|
| 48 | class SchematicEngineConflictingException extends core_1.BaseException {
|
---|
| 49 | constructor() {
|
---|
| 50 | super(`A schematic was called from a different engine as its parent.`);
|
---|
| 51 | }
|
---|
| 52 | }
|
---|
| 53 | exports.SchematicEngineConflictingException = SchematicEngineConflictingException;
|
---|
| 54 | class UnregisteredTaskException extends core_1.BaseException {
|
---|
| 55 | constructor(name, schematic) {
|
---|
| 56 | const addendum = schematic ? ` in schematic "${schematic.name}"` : '';
|
---|
| 57 | super(`Unregistered task "${name}"${addendum}.`);
|
---|
| 58 | }
|
---|
| 59 | }
|
---|
| 60 | exports.UnregisteredTaskException = UnregisteredTaskException;
|
---|
| 61 | class UnknownTaskDependencyException extends core_1.BaseException {
|
---|
| 62 | constructor(id) {
|
---|
| 63 | super(`Unknown task dependency [ID: ${id.id}].`);
|
---|
| 64 | }
|
---|
| 65 | }
|
---|
| 66 | exports.UnknownTaskDependencyException = UnknownTaskDependencyException;
|
---|
| 67 | class CollectionImpl {
|
---|
| 68 | constructor(_description, _engine, baseDescriptions) {
|
---|
| 69 | this._description = _description;
|
---|
| 70 | this._engine = _engine;
|
---|
| 71 | this.baseDescriptions = baseDescriptions;
|
---|
| 72 | }
|
---|
| 73 | get description() {
|
---|
| 74 | return this._description;
|
---|
| 75 | }
|
---|
| 76 | get name() {
|
---|
| 77 | return this.description.name || '<unknown>';
|
---|
| 78 | }
|
---|
| 79 | createSchematic(name, allowPrivate = false) {
|
---|
| 80 | return this._engine.createSchematic(name, this, allowPrivate);
|
---|
| 81 | }
|
---|
| 82 | listSchematicNames() {
|
---|
| 83 | return this._engine.listSchematicNames(this);
|
---|
| 84 | }
|
---|
| 85 | }
|
---|
| 86 | exports.CollectionImpl = CollectionImpl;
|
---|
| 87 | class TaskScheduler {
|
---|
| 88 | constructor(_context) {
|
---|
| 89 | this._context = _context;
|
---|
| 90 | this._queue = new core_1.PriorityQueue((x, y) => x.priority - y.priority);
|
---|
| 91 | this._taskIds = new Map();
|
---|
| 92 | }
|
---|
| 93 | _calculatePriority(dependencies) {
|
---|
| 94 | if (dependencies.size === 0) {
|
---|
| 95 | return 0;
|
---|
| 96 | }
|
---|
| 97 | const prio = [...dependencies].reduce((prio, task) => prio + task.priority, 1);
|
---|
| 98 | return prio;
|
---|
| 99 | }
|
---|
| 100 | _mapDependencies(dependencies) {
|
---|
| 101 | if (!dependencies) {
|
---|
| 102 | return new Set();
|
---|
| 103 | }
|
---|
| 104 | const tasks = dependencies.map((dep) => {
|
---|
| 105 | const task = this._taskIds.get(dep);
|
---|
| 106 | if (!task) {
|
---|
| 107 | throw new UnknownTaskDependencyException(dep);
|
---|
| 108 | }
|
---|
| 109 | return task;
|
---|
| 110 | });
|
---|
| 111 | return new Set(tasks);
|
---|
| 112 | }
|
---|
| 113 | schedule(taskConfiguration) {
|
---|
| 114 | const dependencies = this._mapDependencies(taskConfiguration.dependencies);
|
---|
| 115 | const priority = this._calculatePriority(dependencies);
|
---|
| 116 | const task = {
|
---|
| 117 | id: TaskScheduler._taskIdCounter++,
|
---|
| 118 | priority,
|
---|
| 119 | configuration: taskConfiguration,
|
---|
| 120 | context: this._context,
|
---|
| 121 | };
|
---|
| 122 | this._queue.push(task);
|
---|
| 123 | const id = { id: task.id };
|
---|
| 124 | this._taskIds.set(id, task);
|
---|
| 125 | return id;
|
---|
| 126 | }
|
---|
| 127 | finalize() {
|
---|
| 128 | const tasks = this._queue.toArray();
|
---|
| 129 | this._queue.clear();
|
---|
| 130 | this._taskIds.clear();
|
---|
| 131 | return tasks;
|
---|
| 132 | }
|
---|
| 133 | }
|
---|
| 134 | exports.TaskScheduler = TaskScheduler;
|
---|
| 135 | TaskScheduler._taskIdCounter = 1;
|
---|
| 136 | class SchematicEngine {
|
---|
| 137 | constructor(_host, _workflow) {
|
---|
| 138 | this._host = _host;
|
---|
| 139 | this._workflow = _workflow;
|
---|
| 140 | this._collectionCache = new Map();
|
---|
| 141 | this._schematicCache = new WeakMap();
|
---|
| 142 | this._taskSchedulers = new Array();
|
---|
| 143 | }
|
---|
| 144 | get workflow() {
|
---|
| 145 | return this._workflow || null;
|
---|
| 146 | }
|
---|
| 147 | get defaultMergeStrategy() {
|
---|
| 148 | return this._host.defaultMergeStrategy || interface_1.MergeStrategy.Default;
|
---|
| 149 | }
|
---|
| 150 | createCollection(name, requester) {
|
---|
| 151 | let collection = this._collectionCache.get(name);
|
---|
| 152 | if (collection) {
|
---|
| 153 | return collection;
|
---|
| 154 | }
|
---|
| 155 | const [description, bases] = this._createCollectionDescription(name, requester === null || requester === void 0 ? void 0 : requester.description);
|
---|
| 156 | collection = new CollectionImpl(description, this, bases);
|
---|
| 157 | this._collectionCache.set(name, collection);
|
---|
| 158 | this._schematicCache.set(collection, new Map());
|
---|
| 159 | return collection;
|
---|
| 160 | }
|
---|
| 161 | _createCollectionDescription(name, requester, parentNames) {
|
---|
| 162 | const description = this._host.createCollectionDescription(name, requester);
|
---|
| 163 | if (!description) {
|
---|
| 164 | throw new UnknownCollectionException(name);
|
---|
| 165 | }
|
---|
| 166 | if (parentNames && parentNames.has(description.name)) {
|
---|
| 167 | throw new CircularCollectionException(name);
|
---|
| 168 | }
|
---|
| 169 | const bases = new Array();
|
---|
| 170 | if (description.extends) {
|
---|
| 171 | parentNames = (parentNames || new Set()).add(description.name);
|
---|
| 172 | for (const baseName of description.extends) {
|
---|
| 173 | const [base, baseBases] = this._createCollectionDescription(baseName, description, new Set(parentNames));
|
---|
| 174 | bases.unshift(base, ...baseBases);
|
---|
| 175 | }
|
---|
| 176 | }
|
---|
| 177 | return [description, bases];
|
---|
| 178 | }
|
---|
| 179 | createContext(schematic, parent, executionOptions) {
|
---|
| 180 | // Check for inconsistencies.
|
---|
| 181 | if (parent && parent.engine && parent.engine !== this) {
|
---|
| 182 | throw new SchematicEngineConflictingException();
|
---|
| 183 | }
|
---|
| 184 | let interactive = true;
|
---|
| 185 | if (executionOptions && executionOptions.interactive != undefined) {
|
---|
| 186 | interactive = executionOptions.interactive;
|
---|
| 187 | }
|
---|
| 188 | else if (parent && parent.interactive != undefined) {
|
---|
| 189 | interactive = parent.interactive;
|
---|
| 190 | }
|
---|
| 191 | let context = {
|
---|
| 192 | debug: (parent && parent.debug) || false,
|
---|
| 193 | engine: this,
|
---|
| 194 | logger: (parent && parent.logger && parent.logger.createChild(schematic.description.name)) ||
|
---|
| 195 | new core_1.logging.NullLogger(),
|
---|
| 196 | schematic,
|
---|
| 197 | strategy: parent && parent.strategy !== undefined ? parent.strategy : this.defaultMergeStrategy,
|
---|
| 198 | interactive,
|
---|
| 199 | addTask,
|
---|
| 200 | };
|
---|
| 201 | const maybeNewContext = this._host.transformContext(context);
|
---|
| 202 | if (maybeNewContext) {
|
---|
| 203 | context = maybeNewContext;
|
---|
| 204 | }
|
---|
| 205 | const taskScheduler = new TaskScheduler(context);
|
---|
| 206 | const host = this._host;
|
---|
| 207 | this._taskSchedulers.push(taskScheduler);
|
---|
| 208 | function addTask(task, dependencies) {
|
---|
| 209 | const config = task.toConfiguration();
|
---|
| 210 | if (!host.hasTaskExecutor(config.name)) {
|
---|
| 211 | throw new UnregisteredTaskException(config.name, schematic.description);
|
---|
| 212 | }
|
---|
| 213 | config.dependencies = config.dependencies || [];
|
---|
| 214 | if (dependencies) {
|
---|
| 215 | config.dependencies.unshift(...dependencies);
|
---|
| 216 | }
|
---|
| 217 | return taskScheduler.schedule(config);
|
---|
| 218 | }
|
---|
| 219 | return context;
|
---|
| 220 | }
|
---|
| 221 | createSchematic(name, collection, allowPrivate = false) {
|
---|
| 222 | const schematicMap = this._schematicCache.get(collection);
|
---|
| 223 | let schematic = schematicMap === null || schematicMap === void 0 ? void 0 : schematicMap.get(name);
|
---|
| 224 | if (schematic) {
|
---|
| 225 | return schematic;
|
---|
| 226 | }
|
---|
| 227 | let collectionDescription = collection.description;
|
---|
| 228 | let description = this._host.createSchematicDescription(name, collection.description);
|
---|
| 229 | if (!description) {
|
---|
| 230 | if (collection.baseDescriptions) {
|
---|
| 231 | for (const base of collection.baseDescriptions) {
|
---|
| 232 | description = this._host.createSchematicDescription(name, base);
|
---|
| 233 | if (description) {
|
---|
| 234 | collectionDescription = base;
|
---|
| 235 | break;
|
---|
| 236 | }
|
---|
| 237 | }
|
---|
| 238 | }
|
---|
| 239 | if (!description) {
|
---|
| 240 | // Report the error for the top level schematic collection
|
---|
| 241 | throw new UnknownSchematicException(name, collection.description);
|
---|
| 242 | }
|
---|
| 243 | }
|
---|
| 244 | if (description.private && !allowPrivate) {
|
---|
| 245 | throw new PrivateSchematicException(name, collection.description);
|
---|
| 246 | }
|
---|
| 247 | const factory = this._host.getSchematicRuleFactory(description, collectionDescription);
|
---|
| 248 | schematic = new schematic_1.SchematicImpl(description, factory, collection, this);
|
---|
| 249 | schematicMap === null || schematicMap === void 0 ? void 0 : schematicMap.set(name, schematic);
|
---|
| 250 | return schematic;
|
---|
| 251 | }
|
---|
| 252 | listSchematicNames(collection) {
|
---|
| 253 | const names = this._host.listSchematicNames(collection.description);
|
---|
| 254 | if (collection.baseDescriptions) {
|
---|
| 255 | for (const base of collection.baseDescriptions) {
|
---|
| 256 | names.push(...this._host.listSchematicNames(base));
|
---|
| 257 | }
|
---|
| 258 | }
|
---|
| 259 | // remove duplicates
|
---|
| 260 | return [...new Set(names)].sort();
|
---|
| 261 | }
|
---|
| 262 | transformOptions(schematic, options, context) {
|
---|
| 263 | return this._host.transformOptions(schematic.description, options, context);
|
---|
| 264 | }
|
---|
| 265 | createSourceFromUrl(url, context) {
|
---|
| 266 | switch (url.protocol) {
|
---|
| 267 | case 'null:':
|
---|
| 268 | return () => new null_1.NullTree();
|
---|
| 269 | case 'empty:':
|
---|
| 270 | return () => static_1.empty();
|
---|
| 271 | default:
|
---|
| 272 | const hostSource = this._host.createSourceFromUrl(url, context);
|
---|
| 273 | if (!hostSource) {
|
---|
| 274 | throw new UnknownUrlSourceProtocol(url.toString());
|
---|
| 275 | }
|
---|
| 276 | return hostSource;
|
---|
| 277 | }
|
---|
| 278 | }
|
---|
| 279 | executePostTasks() {
|
---|
| 280 | const executors = new Map();
|
---|
| 281 | const taskObservable = rxjs_1.from(this._taskSchedulers).pipe(operators_1.concatMap((scheduler) => scheduler.finalize()), operators_1.concatMap((task) => {
|
---|
| 282 | const { name, options } = task.configuration;
|
---|
| 283 | const executor = executors.get(name);
|
---|
| 284 | if (executor) {
|
---|
| 285 | return executor(options, task.context);
|
---|
| 286 | }
|
---|
| 287 | return this._host.createTaskExecutor(name).pipe(operators_1.concatMap((executor) => {
|
---|
| 288 | executors.set(name, executor);
|
---|
| 289 | return executor(options, task.context);
|
---|
| 290 | }));
|
---|
| 291 | }));
|
---|
| 292 | return taskObservable;
|
---|
| 293 | }
|
---|
| 294 | }
|
---|
| 295 | exports.SchematicEngine = SchematicEngine;
|
---|