1 | import {
|
2 | Rule,
|
3 | SchematicContext,
|
4 | Tree,
|
5 | apply,
|
6 | chain,
|
7 | mergeWith,
|
8 | schematic,
|
9 | template,
|
10 | url,
|
11 | } from '@angular-devkit/schematics';
|
12 |
|
13 |
|
14 | // Instead of `any`, it would make sense here to get a schema-to-dts package and output the
|
15 | // interfaces so you get type-safe options.
|
16 | export default function (options: any): Rule {
|
17 | // The chain rule allows us to chain multiple rules and apply them one after the other.
|
18 | return chain([
|
19 | (_tree: Tree, context: SchematicContext) => {
|
20 | // Show the options for this Schematics.
|
21 | context.logger.info('My Full Schematic: ' + JSON.stringify(options));
|
22 | },
|
23 |
|
24 | // The schematic Rule calls the schematic from the same collection, with the options
|
25 | // passed in. Please note that if the schematic has a schema, the options will be
|
26 | // validated and could throw, e.g. if a required option is missing.
|
27 | schematic('my-other-schematic', { option: true }),
|
28 |
|
29 | // The mergeWith() rule merge two trees; one that's coming from a Source (a Tree with no
|
30 | // base), and the one as input to the rule. You can think of it like rebasing a Source on
|
31 | // top of your current set of changes. In this case, the Source is that apply function.
|
32 | // The apply() source takes a Source, and apply rules to it. In our case, the Source is
|
33 | // url(), which takes an URL and returns a Tree that contains all the files from that URL
|
34 | // in it. In this case, we use the relative path `./files`, and so two files are going to
|
35 | // be created (test1, and test2).
|
36 | // We then apply the template() rule, which takes a tree and apply two templates to it:
|
37 | // path templates: this template replaces instances of __X__ in paths with the value of
|
38 | // X from the options passed to template(). If the value of X is a
|
39 | // function, the function will be called. If the X is undefined or it
|
40 | // returns null (not empty string), the file or path will be removed.
|
41 | // content template: this is similar to EJS, but does so in place (there's no special
|
42 | // extension), does not support additional functions if you don't pass
|
43 | // them in, and only work on text files (we use an algorithm to detect
|
44 | // if a file is binary or not).
|
45 | mergeWith(apply(url('./files'), [
|
46 | template({
|
47 | INDEX: options.index,
|
48 | name: options.name,
|
49 | }),
|
50 | ])),
|
51 | ]);
|
52 | }
|