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