├── .editorconfig
├── .github
├── ISSUE_TEMPLATE
│ ├── ---docs.md
│ ├── ---feature-request.md
│ └── --bug-report.md
└── workflows
│ └── nodejs.yml
├── .gitignore
├── .npmignore
├── .prettierignore
├── .prettierrc
├── .vscode
└── settings.json
├── CHANGELOG.md
├── DEVELOPMENT.md
├── LICENSE
├── README.md
├── assets
├── commitizen-vscode.png
├── commitizen.svg
└── commitlint.svg
├── commitlint.config.js
├── package-lock.json
├── package.json
├── src
├── collection.json
├── migration.json
├── ng-add
│ ├── defaults.ts
│ ├── index.ts
│ ├── index_spec.ts
│ ├── schema.json
│ └── schema.ts
├── ng-update
│ ├── migration-01
│ │ ├── index.ts
│ │ └── index_spec.ts
│ ├── migration-02
│ │ ├── index.ts
│ │ └── index_spec.ts
│ ├── migration-03
│ │ ├── index.ts
│ │ └── index_spec.ts
│ └── migration-04
│ │ ├── index.ts
│ │ └── index_spec.ts
├── test-utils.ts
└── utils.ts
└── tsconfig.json
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 2
6 | charset = utf-8
7 | trim_trailing_whitespace = false
8 | insert_final_newline = false
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/---docs.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: "\U0001F4D7 Docs"
3 | about: Shortly describe how the docs will be improved
4 | title: "[docs]"
5 | labels: documentation
6 | assignees: ''
7 |
8 | ---
9 |
10 | # 📗 Docs
11 |
12 | ## Description
13 |
14 | A short description of the docs improvement
15 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/---feature-request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: "\U0001F9E9 Feature request"
3 | about: Suggest an idea for this project
4 | title: "[feature]"
5 | labels: enhancement
6 | assignees: ''
7 |
8 | ---
9 |
10 | # 🧩 Feature
11 |
12 | ## What feature / part will be affected
13 |
14 |
15 |
16 |
17 | ```text
18 | - [ ] commitlint
19 | - [ ] husky
20 | - [ ] commitizen
21 | - [ ] standard-version
22 | ```
23 |
24 | ## Description
25 |
26 | A clear and concise description of the feature
27 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/--bug-report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: "\U0001F41EBug Report"
3 | about: Report a bug
4 | title: "[bug]"
5 | labels: bug
6 | assignees: ''
7 |
8 | ---
9 |
10 | # 🐞 Bug report
11 |
12 | ## What feature is affected
13 |
14 |
15 |
16 | ```text
17 | - [ ] commitlint
18 | - [ ] husky
19 | - [ ] commitizen
20 | - [ ] standard-version
21 | ```
22 |
23 | ## Description
24 |
25 | A clear and concise description of the problem...
26 |
27 | ## Reproduction
28 |
29 | Simply describe how to reproduce the bug situation
30 |
31 | ## Error message
32 |
33 |
34 |
35 |
36 |
37 | ## 🌍 Your Environment
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/.github/workflows/nodejs.yml:
--------------------------------------------------------------------------------
1 | name: Node.js CI
2 |
3 | on: [push]
4 |
5 | jobs:
6 | build:
7 |
8 | runs-on: ubuntu-latest
9 |
10 | strategy:
11 | matrix:
12 | node-version: [12.x]
13 |
14 | steps:
15 | - uses: actions/checkout@v2
16 | - name: Use Node.js ${{ matrix.node-version }}
17 | uses: actions/setup-node@v1
18 | with:
19 | node-version: ${{ matrix.node-version }}
20 | - run: npm install
21 | - run: npm test
22 | env:
23 | CI: true
24 |
25 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Outputs
2 | src/**/*.js
3 | src/**/*.js.map
4 | src/**/*.d.ts
5 |
6 | # IDEs
7 | .idea/
8 | jsconfig.json
9 |
10 | # Misc
11 | node_modules/
12 | npm-debug.log*
13 | yarn-error.log*
14 |
15 | # Mac OSX Finder files.
16 | **/.DS_Store
17 | .DS_Store
18 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | # Ignores TypeScript files, but keeps definitions.
2 | *.ts
3 | !*.d.ts
4 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | *.js
2 | *.js.map
3 | *.d.ts
4 | *.md
5 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 100,
3 | "singleQuote": true,
4 | "trailingComma": "all"
5 | }
6 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.wordWrapColumn": 100,
3 | "editor.rulers": [100],
4 | "workbench.colorCustomizations": {
5 | "activityBar.background": "#f5ac4d",
6 | "activityBar.activeBorder": "#077947",
7 | "activityBar.foreground": "#15202b",
8 | "activityBar.inactiveForeground": "#15202b99",
9 | "activityBarBadge.background": "#077947",
10 | "activityBarBadge.foreground": "#e7e7e7",
11 | "titleBar.activeBackground": "#f2961d",
12 | "titleBar.inactiveBackground": "#f2961d99",
13 | "titleBar.activeForeground": "#15202b",
14 | "titleBar.inactiveForeground": "#15202b99",
15 | "statusBar.background": "#f2961d",
16 | "statusBarItem.hoverBackground": "#d07b0c",
17 | "statusBar.foreground": "#15202b",
18 | "activityBar.activeBackground": "#f5ac4d"
19 | },
20 | "peacock.color": "#f2961d"
21 | }
22 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4 |
5 | ## [2.3.0](https://github.com/d-koppenhagen/ngx-semantic-version/compare/v2.2.0...v2.3.0) (2020-11-12)
6 |
7 |
8 | ### Features
9 |
10 | * update workspace and packages ([494a229](https://github.com/d-koppenhagen/ngx-semantic-version/commit/494a229da7ee79b2b51bae7b76c5c81eb20d7e6b))
11 |
12 | ## [2.2.0](https://github.com/d-koppenhagen/ngx-semantic-version/compare/v2.1.0...v2.2.0) (2020-08-20)
13 |
14 |
15 | ### Features
16 |
17 | * add mirgation for new package versions ([7fe59ae](https://github.com/d-koppenhagen/ngx-semantic-version/commit/7fe59ae83f01de646be3996ca25205b7ead93347))
18 | * use latest tooling versions ([74d7d85](https://github.com/d-koppenhagen/ngx-semantic-version/commit/74d7d85b32f0a1b64548ada21b8fa46b12e4a1e0))
19 |
20 | ## [2.1.0](https://github.com/d-koppenhagen/ngx-semantic-version/compare/v2.0.0...v2.1.0) (2020-06-25)
21 |
22 |
23 | ### Features
24 |
25 | * add latest package versions ([659cedc](https://github.com/d-koppenhagen/ngx-semantic-version/commit/659cedc003ea07313353206bb95c87e6d341230c))
26 |
27 | ## [2.0.0](https://github.com/d-koppenhagen/ngx-semantic-version/compare/v2.0.0-beta.5...v2.0.0) (2020-06-25)
28 |
29 | ## [2.0.0-beta.5](https://github.com/d-koppenhagen/ngx-semantic-version/compare/v2.0.0-beta.4...v2.0.0-beta.5) (2020-02-11)
30 |
31 |
32 | ### Features
33 |
34 | * update default versions ([27c77c5](https://github.com/d-koppenhagen/ngx-semantic-version/commit/27c77c5d0b76ac86cdf8a3c77b1334f522ccf50c))
35 |
36 | ## [2.0.0-beta.4](https://github.com/d-koppenhagen/ngx-semantic-version/compare/v2.0.0-beta.3...v2.0.0-beta.4) (2020-01-06)
37 |
38 | ## [2.0.0-beta.3](https://github.com/d-koppenhagen/ngx-semantic-version/compare/v2.0.0-beta.2...v2.0.0-beta.3) (2019-12-11)
39 |
40 |
41 | ### Features
42 |
43 | * warning when missing 'repository' or 'bugs' fields ([25815db](https://github.com/d-koppenhagen/ngx-semantic-version/commit/25815dbfe94834fe9eb754905b8edf6e5fd8e88e)), closes [#20](https://github.com/d-koppenhagen/ngx-semantic-version/issues/20)
44 |
45 | ## [2.0.0-beta.2](https://github.com/d-koppenhagen/ngx-semantic-version/compare/v2.0.0-beta.1...v2.0.0-beta.2) (2019-12-09)
46 |
47 |
48 | ### Bug Fixes
49 |
50 | * handle `standardVersionConfig` flag correctly ([6bb17ee](https://github.com/d-koppenhagen/ngx-semantic-version/commit/6bb17eef02313d922f3ad0201bf9c63d0141a2cd))
51 |
52 | ## [2.0.0-beta.1](https://github.com/d-koppenhagen/ngx-semantic-version/compare/v2.0.0-beta.0...v2.0.0-beta.1) (2019-12-06)
53 |
54 |
55 | ### Features
56 |
57 | * add package to devDependencies ([f129bb2](https://github.com/d-koppenhagen/ngx-semantic-version/commit/f129bb2712d7a6a41138b32c3440a81c13a6e15b)), closes [#18](https://github.com/d-koppenhagen/ngx-semantic-version/issues/18)
58 |
59 | ## [2.0.0-beta.0](https://github.com/d-koppenhagen/ngx-semantic-version/compare/v2.0.0-alpha.1...v2.0.0-beta.0) (2019-11-21)
60 |
61 | ## [2.0.0-alpha.1](https://github.com/d-koppenhagen/ngx-semantic-version/compare/v2.0.0-alpha.0...v2.0.0-alpha.1) (2019-11-18)
62 |
63 |
64 | ### ⚠ BREAKING CHANGES
65 |
66 | * `--force` will override existing files if there is a conflict. `--overrideConfigurations` can be used now to override conflicts within existing configuration parameters
67 |
68 | ### Features
69 |
70 | * introduce `--standardVersionConfig` param ([94e84c5](https://github.com/d-koppenhagen/ngx-semantic-version/commit/94e84c5b44cac887af6021508fb9ea2f8b4cb75e))
71 | * introduce `overrideConfigurations` param ([f91f92e](https://github.com/d-koppenhagen/ngx-semantic-version/commit/f91f92eebffdfe2683c5ac6378f93810261b6d53))
72 |
73 | ## [2.0.0-alpha.0](https://github.com/d-koppenhagen/ngx-semantic-version/compare/v1.2.1...v2.0.0-alpha.0) (2019-11-15)
74 |
75 |
76 | ### ⚠ BREAKING CHANGES
77 |
78 | * `--husky=`, `--commitizen=`, `--standardVersion=` are not supported anymore| use `--packages=commitizen,husky,commitlint,standard-version` instead.
79 | By default all packaged will be added.
80 |
81 | ### Features
82 |
83 | * provide packages from x-promt ([3390ff0](https://github.com/d-koppenhagen/ngx-semantic-version/commit/3390ff04d803fd8829c530c0a86c2cb0f528dcb3)), closes [#11](https://github.com/d-koppenhagen/ngx-semantic-version/issues/11)
84 |
85 | ### [1.2.1](https://github.com/d-koppenhagen/ngx-semantic-version/compare/v1.2.0...v1.2.1) (2019-11-06)
86 |
87 |
88 | ### Bug Fixes
89 |
90 | * add missing schema validation ([6554157](https://github.com/d-koppenhagen/ngx-semantic-version/commit/65541576ff55e1c857a074811fe2cefd84bd5de9))
91 |
92 | ## [1.2.0](https://github.com/d-koppenhagen/ngx-semantic-version/compare/v1.1.1...v1.2.0) (2019-11-02)
93 |
94 |
95 | ### Features
96 |
97 | * adds `--force` param ([60f4910](https://github.com/d-koppenhagen/ngx-semantic-version/commit/60f4910d3579453c3cb581fe6362f3f57184e8d3)), closes [#12](https://github.com/d-koppenhagen/ngx-semantic-version/issues/12)
98 |
99 | ### [1.1.1](https://github.com/d-koppenhagen/ngx-semantic-version/compare/v1.1.0...v1.1.1) (2019-10-28)
100 |
101 | ## [1.1.0](https://github.com/d-koppenhagen/ngx-semantic-version/compare/v1.0.0...v1.1.0) (2019-10-28)
102 |
103 |
104 | ### Features
105 |
106 | * **noisafno:** sfdafda ([093347a](https://github.com/d-koppenhagen/ngx-semantic-version/commit/093347a96141f03c8638a42d62e2fa42bd34c273))
107 | * allow to specify an issue prefix ([fa1625f](https://github.com/d-koppenhagen/ngx-semantic-version/commit/fa1625fb8245edec79bf1c4eb7ffe861cf19a7b1)), closes [#10](https://github.com/d-koppenhagen/ngx-semantic-version/issues/10)
108 |
109 |
110 | ### Bug Fixes
111 |
112 | * **saf:** asf ([1ae998d](https://github.com/d-koppenhagen/ngx-semantic-version/commit/1ae998daffba0a20c8503bfc3fb4c3056db45d41))
113 |
114 | ## [1.0.0](https://github.com/d-koppenhagen/ngx-semantic-version/compare/v0.1.4...v1.0.0) (2019-10-21)
115 |
116 | ### [0.1.4](https://github.com/d-koppenhagen/ngx-semantic-version/compare/v0.1.3...v0.1.4) (2019-10-21)
117 |
118 | ### [0.1.3](https://github.com/d-koppenhagen/ngx-semantic-version/compare/v0.1.2...v0.1.3) (2019-10-21)
119 |
120 |
121 | ### Features
122 |
123 | * adds options to skip adding packages ([fc01543](https://github.com/d-koppenhagen/ngx-semantic-version/commit/fc01543f38548c79b2e99c8395f52446d9379004)), closes [#9](https://github.com/d-koppenhagen/ngx-semantic-version/issues/9)
124 |
125 | ### [0.1.2](https://github.com/d-koppenhagen/ngx-semantic-version/compare/v0.1.1...v0.1.2) (2019-10-15)
126 |
127 |
128 | ### Bug Fixes
129 |
130 | * fixes migration ([9c18b44](https://github.com/d-koppenhagen/ngx-semantic-version/commit/9c18b441c653bd31593fbce5af7e39806e825698))
131 |
132 | ### [0.1.1](https://github.com/d-koppenhagen/ngx-semantic-version/compare/v0.1.0...v0.1.1) (2019-10-15)
133 |
134 |
135 | ### Bug Fixes
136 |
137 | * **ng-update:** use migration-02 within correct version ([4f971b7](https://github.com/d-koppenhagen/ngx-semantic-version/commit/4f971b78da89b67ef37fdc76aef604891b19c248))
138 |
139 | ## [0.1.0](https://github.com/d-koppenhagen/ngx-semantic-version/compare/v0.0.4...v0.1.0) (2019-10-15)
140 |
141 |
142 | ### ⚠ BREAKING CHANGES
143 |
144 | * **commitlint:** The default commitlint configuration was changed to `@commitlint/config-conventional` (before: `@commitlint/config-angular`
145 |
146 | ### Features
147 |
148 | * **commitlint:** use @commitlint/config-conventional ([6de7705](https://github.com/d-koppenhagen/ngx-semantic-version/commit/6de7705c4709cc80ed7e469aded1600af432ba58)), closes [#8](https://github.com/d-koppenhagen/ngx-semantic-version/issues/8)
149 |
150 | ### [0.0.4](https://github.com/d-koppenhagen/ngx-semantic-version/compare/v0.0.3...v0.0.4) (2019-10-15)
151 |
152 |
153 | ### Bug Fixes
154 |
155 | * **ng-update:** proceed update within correct version ([5b72d45](https://github.com/d-koppenhagen/ngx-semantic-version/commit/5b72d456109ff898ae09387d48b207ea305ca017))
156 |
157 | ### [0.0.3](https://github.com/d-koppenhagen/ngx-semantic-version/compare/v0.0.1...v0.0.3) (2019-10-15)
158 |
159 |
160 | ### Features
161 |
162 | * **commitizen:** adds commitizen as dependncy and husky hook ([87f316e](https://github.com/d-koppenhagen/ngx-semantic-version/commit/87f316e68358ba101adfd7b22b4ebd12f456e5fa))
163 | * adds ng-update support ([04ea589](https://github.com/d-koppenhagen/ngx-semantic-version/commit/04ea589cea711759ce5b90f4f461871c7f5f513c)), closes [#1](https://github.com/d-koppenhagen/ngx-semantic-version/issues/1)
164 | * removes `prepare-commit-msg` husky hook ([38d4a58](https://github.com/d-koppenhagen/ngx-semantic-version/commit/38d4a58eb32ce6e29b7c3ce27be192973fd19c38))
165 |
166 | ### [0.0.2](https://github.com/d-koppenhagen/ngx-semantic-version/compare/v0.0.1...v0.0.2) (2019-10-13)
167 |
168 |
169 | ### Features
170 |
171 | * **commitizen:** adds commitizen as dependncy and husky hook ([87f316e](https://github.com/d-koppenhagen/ngx-semantic-version/commit/87f316e68358ba101adfd7b22b4ebd12f456e5fa))
172 |
173 | ### 0.0.1 (2019-10-12)
174 |
175 |
176 | ### Features
177 |
178 | * adds initial version for ng add af00610
179 |
--------------------------------------------------------------------------------
/DEVELOPMENT.md:
--------------------------------------------------------------------------------
1 | # ngx-semantic-version
2 |
3 | ## Development
4 |
5 | ### Testing
6 |
7 | To test locally, install `@angular-devkit/schematics-cli` globally and use the `schematics` command line tool. That tool acts the same as the `generate` command of the Angular CLI, but also has a debug mode.
8 |
9 | Check the documentation with
10 |
11 | ```bash
12 | schematics --help
13 | ```
14 |
15 | ### Unit Testing
16 |
17 | `npm run test` will run the unit tests, using Jasmine as a runner and test framework.
18 |
19 | ### Publishing
20 |
21 | To publish, simply do:
22 |
23 | ```bash
24 | npm publish
25 | ```
26 |
27 | That's it!
28 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2019 Danny Koppenhagen
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ngx-semantic-version
2 |
3 | [](https://www.npmjs.com/package/ngx-semantic-version)
4 | [](https://david-dm.org/d-koppenhagen/ngx-semantic-version)
5 | [](https://david-dm.org/d-koppenhagen/ngx-semantic-version?type=dev)
6 | [](https://www.npmjs.com/package/ngx-semantic-version)
7 | [](http://makeapullrequest.com)
8 | [](https://github.com/ellerbrock/open-source-badge/)
9 |
10 | [](https://www.npmjs.com/package/ngx-semantic-version)
11 | [](https://github.com/semantic-release/semantic-release)
12 | [](http://commitizen.github.io/cz-cli/)
13 | [](https://conventionalcommits.org)
14 |
15 | [](https://www.npmjs.com/package/ngx-semantic-version)
16 | [](https://www.npmjs.com/package/ngx-semantic-version)
17 | [](https://www.npmjs.com/package/ngx-semantic-version)
18 | [](https://www.npmjs.com/package/ngx-semantic-version)
19 |
20 | [](https://github.com/d-koppenhagen/ngx-semantic-version/fork) [](https://github.com/d-koppenhagen/ngx-semantic-version)
21 |
22 |
23 |
24 | _ngx-semantic-version_ is an Angular Schematic that will add and configure _commitlint_, _commitizen_, _husky_ and _standard-version_ for creating commit messages in the _conventional commit_ format and automate your release and Changelog generation respecting _semver_.
25 |
26 | The schematic will configure the following packages / services:
27 |
28 | - [commitlint](https://commitlint.js.org)
29 | - [husky](https://www.npmjs.com/package/husky)
30 | - [commitizen](https://www.npmjs.com/package/commitizen)
31 | - [standard-version](https://www.npmjs.com/package/standard-version)
32 |
33 | ## How to use
34 |
35 | ### Add the schematics to your project
36 |
37 | - Angular CLI >= 9.x.x
38 | ```bash
39 | ng add ngx-semantic-version
40 | ```
41 |
42 | - Angular CLI 8.x.x | [docs](https://github.com/d-koppenhagen/ngx-semantic-version/tree/v1.2.1)
43 |
44 | ```bash
45 | ng add ngx-semantic-version@1
46 | ```
47 |
48 | > if you have already configured one of the modules and you want to use the configuration provided
49 | by ngx-semantic-version, you can use `--overrideConfigurations` to override an existing configuration.
50 | Please check the changes carefully using git after running with `--overrideConfigurations`.
51 |
52 | #### available options
53 |
54 | | Flag | Description |
55 | | ------------------------- | ------------------------------------------------------------------ |
56 | | `--skipInstall` | Skips installing new `node_modules` after modifying `package.json` |
57 | | `--packages="commitlint, husky, commitizen, standard-version"` | Define the packages to add. |
58 | | `--issuePrefix=""`| Configure an issue prefix that should be checked by each commit |
59 | | `--overrideConfigurations`| Do override existing configuration parameters if necesary |
60 | | `--force` | Ignore errors and override already existing files |
61 | | `--standardVersionConfig` | Add the base configuration for _standard-version_ to `package.json` for adjusting it later|
62 |
63 | #### force including references by configuring an issue prefix
64 |
65 | When adding the schematic using e.g. `--issuePrefix="PREFIX-"`, commitlint will be configured to use
66 | the defined issue prefix in commit messages. Therefore the following configuration will be added
67 | to the `commitlint.config.js` configuration file:
68 |
69 | ```js
70 | module.exports = {
71 | // ...
72 | rules: {
73 | 'references-empty': [2, 'never'],
74 | },
75 | parserPreset: {
76 | parserOpts: {
77 | issuePrefixes: ['PREFIX-'],
78 | },
79 | },
80 | };
81 | ```
82 |
83 | This is very helpful if you want to force the users to include always an reference to your issue
84 | tracking system (in the example above the issue racking system will use this style: `PREFIX-1242`).
85 |
86 | > The line `'references-empty': [2, 'never'],` will tell commitlint that an issue reference has
87 | to be included always. You can change the value of `2` to `1` to just warn the user instead of
88 | rejecting the commit messages. All configuration option are described in the official
89 | [docs of commitlint](https://commitlint.js.org/#/reference-rules).
90 |
91 | The prefix will be also configured for usage within _standard-version_ in your `package.json`:
92 |
93 | ```json
94 | // ...
95 | "standard-version": {
96 | "issuePrefixes": ["PREFIX-"],
97 | }
98 | ```
99 |
100 | > [You can specify further options for _standard-version_](https://github.com/conventional-changelog/conventional-changelog-config-spec/blob/master/versions/2.1.0/README.md
101 | ) that will be uses for the generated links
102 | in `CHANGELOG.md` generation. You can adjust the configuration block `standard-version` in your
103 | `package.json` and adjusts the options to satisfy your needs.
104 |
105 | ### Update the schematics
106 |
107 | Run `ng update` to see if an update is available.
108 | To proceed running an update of _ngx-semantic-version_, run the following command:
109 |
110 | ```bash
111 | ng update ngx-semantic-version
112 | ```
113 |
114 | > Updates will may touch your existing configuration. Please check the changes using git to verify the changes.
115 |
116 | ## What's included
117 |
118 | ### [commitlint](https://commitlint.js.org)
119 |
120 | Commitlint will lint your commit message and check it against some common rules.
121 | It will throw an error if the messages doesn't match with the rules.
122 | This schematic will install the ruleset [`@commitlint/config-conventional`](https://npmjs.com/package/@commitlint/config-conventional) by default.
123 |
124 | After adding the schematics you will be able to adjust the rules for your
125 | personal needs by adjusting the added file `commitlint.config.js`.
126 |
127 | You can find a description of supported adjustments in the
128 | [official documentation](https://commitlint.js.org/#/reference-rules).
129 |
130 | 
131 |
132 | ### [husky](https://www.npmjs.com/package/husky)
133 |
134 | Husky allows us to hook into the git lifecycle using nodejs. It is used by _ngx-semantic-version_ to check a commit message right before storing it by using _commitlint_.
135 | Therefore it will add this part to your `package.json`:
136 |
137 | ```json
138 | ...
139 | "husky": {
140 | "hooks": {
141 | "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
142 | }
143 | },
144 | ```
145 |
146 | Husky uses the environment variable `HUSKY_GIT_PARAMS` containing the current git message you entered and it will pass this through _commitlint_ so it can be evaluated.
147 |
148 | ### [commitizen](https://www.npmjs.com/package/commitizen)
149 |
150 | When having restrictions within the commit message text it can be difficult
151 | to always satisfy the appropriate format. Commitizen will help you to build a
152 | commit message always in the appropriate format by letting you configure the
153 | final message via an interactive cli.
154 |
155 | When _commitizen_ is installed globally (`npm i -g commitizen`) you can run it by
156 | executing `git cz`.
157 |
158 | 
159 |
160 | Alternatively, if you are using NPM 5.2+ you can use npx instead of installing globally: `npx git-cz`.
161 |
162 | _ngx-semantic-version_ will configure _commitizen_ in your `package.json`, so that is will use the _conventional changelog_ as well:
163 |
164 | ```json
165 | ...
166 | "config": {
167 | "commitizen": {
168 | "path": "./node_modules/cz-conventional-changelog"
169 | }
170 | }
171 | ```
172 |
173 | > Tip: if you are using vscode, you can add the plugin [Visual Studio Code Commitizen Support](https://marketplace.visualstudio.com/items?itemName=KnisterPeter.vscode-commitizen) which will let you build the commit message directly via vscode.
174 | > 
175 |
176 | ### [standard-version](https://www.npmjs.com/package/standard-version)
177 |
178 | Standard-version will create and update your app/package version and automatically
179 | generate a `CHANGELOG.md` file and keep it up-to-date by using the git history.
180 | It will check the messages for keywords (thanks to commitlint) and determine which part
181 | of the semantic version will be increased. Furthermore it will add a tag for the version.
182 |
183 | After adding this schematic, you can simply release a new version by running `npm run release`.
184 | This will keep your `CHNAGELOG.md` up to date and releases a new version of your project.
185 |
186 | _ngx-semantic-version_ will configure a new script in your `package.json` that can be used for releasing a new version:
187 |
188 | ```json
189 | ...
190 | "scripts": {
191 | "release": "standard-version",
192 | },
193 | ```
194 |
195 | If you typically use `npm version` to cut a new release, do this instead:
196 |
197 | ```bash
198 | npm run release
199 | ```
200 |
201 | You should also consider use one of the following commands:
202 |
203 | ```bash
204 | npm run release -- --first-release # create the initial release and create the `CHANGELOG.md`
205 | npm run release -- --prerelease # create a pre-release instead of a regular one
206 | npm run release -- --prerelease alpha # cut a new alpha release version
207 | ```
208 |
209 | To adjust the temnplate of the generated `CHANGELOG.md` or the types of commits included in it you need to modify the _standard-version_ configuration.
210 | You can use `--standardVersionConfig` within _ngx-semantic-version_ to add the default configuration to your `package.json`.
211 | After that you can simply adjust the configuration to your needs:
212 |
213 | ```bash
214 | ng add ngx-semantic-version --standardVersionConfig
215 | ```
216 |
217 | > Please note that your projects [`repository` field](https://docs.npmjs.com/files/package.json#repository) should be filled in your `package.json`, as _standard-version_ will use this information for creating the links in the `CHANGELOG.md` to your issues and releases. Check out also the [official documentation](https://www.npmjs.com/package/standard-version#release-as-a-pre-release) for further information.
218 |
219 | ## Default configurations
220 |
221 | Check out the file [src/ng-add/defaults.ts](./src/ng-add/defaults.ts) if you want to see what part will be added to your `package.json` and see the default values.
222 |
223 | ## Development
224 |
225 | For development hints, have a look at [DEVELOPMENT.md](./DEVELOPMENT.md)
226 |
--------------------------------------------------------------------------------
/assets/commitizen-vscode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/d-koppenhagen/ngx-semantic-version/ea70c29ceeb5eb330d103cb7a83fe70f47653eec/assets/commitizen-vscode.png
--------------------------------------------------------------------------------
/assets/commitizen.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/commitlint.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
56 |
77 |
78 |
79 |
80 |
81 |
82 |
83 | ~/dev/ngx-semantic-version (master ✘)✹✭ ᐅ ~/dev/ngx-semantic-version (master ✘)✹✭ ᐅ e ~/dev/ngx-semantic-version (master ✘)✹✭ ᐅ ech ~/dev/ngx-semantic-version (master ✘)✹✭ ᐅ echo ~/dev/ngx-semantic-version (master ✘)✹✭ ᐅ echo 'foo ~/dev/ngx-semantic-version (master ✘)✹✭ ᐅ echo 'foo' ~/dev/ngx-semantic-version (master ✘)✹✭ ᐅ echo 'foo' | ~/dev/ngx-semantic-version (master ✘)✹✭ ᐅ echo 'foo' | npx ~/dev/ngx-semantic-version (master ✘)✹✭ ᐅ echo 'foo' | npx commi ~/dev/ngx-semantic-version (master ✘)✹✭ ᐅ echo 'foo' | npx commitli ~/dev/ngx-semantic-version (master ✘)✹✭ ᐅ echo 'foo' | npx commitlint ~/dev/ngx-semantic-version (master ✘)✹✭ ᐅ echo 'foo' | npx commitlint ~/dev/ngx-semantic-version (master ✘)✹✭ ᐅ echo 'foo' | npx commitlint ⧗ input: foo✖ subject may not be empty [subject-empty]✖ type may not be empty [type-empty]✖ found 2 problems, 0 warningsⓘ Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint~/dev/ngx-semantic-version (master ✘)✹✭ ᐅ
84 |
--------------------------------------------------------------------------------
/commitlint.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * To check all configuration options, please visit
3 | * https://commitlint.js.org/#/reference-rules
4 | */
5 | module.exports = {
6 | extends: ['@commitlint/config-conventional'],
7 | };
8 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ngx-semantic-version",
3 | "version": "2.3.0",
4 | "description": "This schematic will add commitlint, husky, commitizen and standard-version configurations",
5 | "scripts": {
6 | "release": "standard-version",
7 | "build": "tsc -p tsconfig.json",
8 | "build:watch": "tsc -p tsconfig.json --watch",
9 | "test": "npm run build && jasmine **/*_spec.js",
10 | "prepublish": "npm run build"
11 | },
12 | "keywords": [
13 | "schematics",
14 | "commitlint",
15 | "commitizen",
16 | "husky",
17 | "standard-version",
18 | "changelog",
19 | "semver",
20 | "angular",
21 | "angular-cli"
22 | ],
23 | "author": "Danny Koppenhagen (https://d-koppenhagen.de)",
24 | "homepage": "https://github.com/d-koppenhagen/ngx-semantic-version",
25 | "repository": {
26 | "type": "git",
27 | "url": "git+https://github.com/d-koppenhagen/ngx-semantic-version.git"
28 | },
29 | "bugs": {
30 | "url": "https://github.com/d-koppenhagen/ngx-semantic-version/issues",
31 | "email": "mail@d-koppenhagen.de"
32 | },
33 | "license": "MIT",
34 | "schematics": "./src/collection.json",
35 | "ng-add": {
36 | "save": "devDependencies"
37 | },
38 | "ng-update": {
39 | "migrations": "./src/migration.json"
40 | },
41 | "dependencies": {
42 | "@angular-devkit/core": "^11.0.0",
43 | "@angular-devkit/schematics": "^11.0.0",
44 | "typescript": "~4.0.5"
45 | },
46 | "peerDependencies": {
47 | "@angular/cli": "^9.0.0 || ^10.0.0 || ^11.0.0 || ^12.0.0-0"
48 | },
49 | "devDependencies": {
50 | "@commitlint/cli": "^11.0.0",
51 | "@commitlint/config-conventional": "^11.0.0",
52 | "@schematics/angular": "^11.0.0",
53 | "@types/jasmine": "~3.6.1",
54 | "@types/node": "^14.0.14",
55 | "commitizen": "^4.2.2",
56 | "cz-conventional-changelog": "^3.3.0",
57 | "husky": "^4.3.0",
58 | "jasmine": "^3.6.1",
59 | "standard-version": "^9.0.0"
60 | },
61 | "husky": {
62 | "hooks": {
63 | "pre-push": "npm test",
64 | "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
65 | }
66 | },
67 | "config": {
68 | "commitizen": {
69 | "path": "./node_modules/cz-conventional-changelog"
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/collection.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json",
3 | "schematics": {
4 | "ng-add": {
5 | "description": "This scematic will add and configure commitlint, husky, commitizen and standard-version configuration",
6 | "factory": "./ng-add/index",
7 | "schema": "./ng-add/schema.json"
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/migration.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json",
3 | "schematics": {
4 | "migration-01": {
5 | "description": "Updates to Version 0.0.4",
6 | "version": "0.0.4",
7 | "factory": "./ng-update/migration-01/index"
8 | },
9 | "migration-02": {
10 | "description": "Updates to Version 0.1.0",
11 | "version": "0.1.0",
12 | "factory": "./ng-update/migration-02/index"
13 | },
14 | "migration-03": {
15 | "description": "Updates to Version 2",
16 | "version": "2",
17 | "factory": "./ng-update/migration-03/index"
18 | },
19 | "migration-04": {
20 | "description": "Updates to latest tooling versions",
21 | "version": "2.2",
22 | "factory": "./ng-update/migration-04/index"
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/ng-add/defaults.ts:
--------------------------------------------------------------------------------
1 | export const DEV_DEPS_TO_ADD = {
2 | commitlint: {
3 | '@commitlint/cli': '^11.0.0',
4 | '@commitlint/config-conventional': '^11.0.0',
5 | },
6 | commitizen: {
7 | commitizen: '^4.2.2',
8 | 'cz-conventional-changelog': '^3.3.0',
9 | },
10 | husky: {
11 | husky: '^4.3.0',
12 | },
13 | 'standard-version': {
14 | 'standard-version': '^9.0.0',
15 | },
16 | };
17 |
18 | export const HUSKY_DEFAULTS = {
19 | hooks: {
20 | 'commit-msg': 'commitlint -E HUSKY_GIT_PARAMS',
21 | },
22 | };
23 |
24 | export const COMMITIZEN_DEFAULTS = {
25 | commitizen: {
26 | path: './node_modules/cz-conventional-changelog',
27 | },
28 | };
29 |
30 | export const STANDARD_VERSION_DEFAULTS = {
31 | types: [
32 | {
33 | type: 'feat',
34 | section: 'Features',
35 | },
36 | {
37 | type: 'fix',
38 | section: 'Bug Fixes',
39 | },
40 | {
41 | type: 'chore',
42 | hidden: true,
43 | },
44 | {
45 | type: 'ci',
46 | hidden: true,
47 | },
48 | {
49 | type: 'build',
50 | hidden: true,
51 | },
52 | {
53 | type: 'docs',
54 | hidden: true,
55 | },
56 | {
57 | type: 'style',
58 | hidden: true,
59 | },
60 | {
61 | type: 'refactor',
62 | hidden: true,
63 | },
64 | {
65 | type: 'perf',
66 | hidden: true,
67 | },
68 | {
69 | type: 'test',
70 | hidden: true,
71 | },
72 | ],
73 | header: 'Changelog',
74 | commitUrlFormat: '{{host}}/{{owner}}/{{repository}}/commit/{{hash}}',
75 | compareUrlFormat: '{{host}}/{{owner}}/{{repository}}/compare/{{previousTag}}...{{currentTag}}',
76 | issueUrlFormat: '{{host}}/{{owner}}/{{repository}}/issues/{{id}}',
77 | userUrlFormat: '{{host}}/{{user}}',
78 | releaseCommitMessageFormat: 'chore(release): {{currentTag}}',
79 | issuePrefixes: ['#'],
80 | };
81 |
--------------------------------------------------------------------------------
/src/ng-add/index.ts:
--------------------------------------------------------------------------------
1 | import {
2 | Rule,
3 | SchematicContext,
4 | Tree,
5 | apply,
6 | chain,
7 | mergeWith,
8 | template,
9 | url,
10 | noop,
11 | FileEntry,
12 | forEach,
13 | } from '@angular-devkit/schematics';
14 | import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks';
15 |
16 | import { NgxSemanticVersion as Schema, PackageName } from './schema';
17 | import {
18 | getPackageJson,
19 | overwritePackageJson,
20 | getMergedPackageJsonConfig,
21 | PackageJsonConfigPart,
22 | } from '../utils';
23 | import {
24 | DEV_DEPS_TO_ADD,
25 | HUSKY_DEFAULTS,
26 | COMMITIZEN_DEFAULTS,
27 | STANDARD_VERSION_DEFAULTS,
28 | } from './defaults';
29 |
30 | export default (options: Schema): Rule => {
31 | const addStandardVersionConfigToPackageJson =
32 | (options.issuePrefix && options.issuePrefix !== '') || options.standardVersionConfig;
33 | return chain([
34 | addDependencies(options),
35 | options.packages.includes('commitlint') ? addCommitlintConfigFile(options) : noop(),
36 | options.packages.includes('husky') ? addHuskyConfig(options) : noop(),
37 | options.packages.includes('commitizen') ? addCommitizenConfig(options) : noop(),
38 | options.packages.includes('standard-version') ? addNpmRunScript(options) : noop(),
39 | options.packages.includes('standard-version') && addStandardVersionConfigToPackageJson
40 | ? standardVersionConfig(options)
41 | : noop(),
42 | options.skipInstall ? noop() : installDependencies,
43 | ]);
44 | };
45 |
46 | const addDependencies = (options: Schema) => (tree: Tree, context: SchematicContext) => {
47 | context.logger.info('Added npm packages as dev dependencies');
48 | const packageJson = getPackageJson(tree);
49 |
50 | let devDepsToAdd: PackageJsonConfigPart = {};
51 |
52 | const map = new Map([
53 | ['commitlint', DEV_DEPS_TO_ADD],
54 | ['commitizen', DEV_DEPS_TO_ADD],
55 | ['husky', DEV_DEPS_TO_ADD],
56 | ['standard-version', DEV_DEPS_TO_ADD],
57 | ]);
58 |
59 | for (const [key, value] of map.entries()) {
60 | const searchKey = key as PackageName;
61 | if (options.packages.includes(searchKey)) {
62 | devDepsToAdd = {
63 | ...devDepsToAdd,
64 | ...value[searchKey],
65 | };
66 | } else {
67 | context.logger.info(`- Skips adding ${searchKey}`);
68 | }
69 | }
70 |
71 | packageJson.devDependencies = {
72 | ...packageJson.devDependencies,
73 | ...devDepsToAdd,
74 | };
75 |
76 | overwritePackageJson(tree, packageJson);
77 | };
78 |
79 | const addNpmRunScript = (options: Schema) => (tree: Tree, context: SchematicContext) => {
80 | context.logger.info('Added npm script for release');
81 | const packageJson = getPackageJson(tree);
82 |
83 | if (!packageJson.repository && !packageJson.bugs) {
84 | context.logger.warn(
85 | `Neither 'repository' or 'bugs' field found in your 'package.json'. To referencs your releases and issues correctly, you should add the fiels.
86 | Check out: https://github.com/d-koppenhagen/ngx-semantic-version/wiki/FAQ for further information`,
87 | );
88 | }
89 |
90 | const configBefore = { ...packageJson.scripts };
91 | const configNew = { release: 'standard-version' };
92 |
93 | packageJson.scripts = getMergedPackageJsonConfig(
94 | configBefore,
95 | configNew,
96 | options.overrideConfigurations,
97 | );
98 | overwritePackageJson(tree, packageJson);
99 | };
100 |
101 | const addHuskyConfig = (options: Schema) => (tree: Tree, context: SchematicContext) => {
102 | addConfig(tree, context, options, 'husky', 'husky', HUSKY_DEFAULTS);
103 | };
104 |
105 | const addCommitizenConfig = (options: Schema) => (tree: Tree, context: SchematicContext) => {
106 | addConfig(tree, context, options, 'commitizen', 'config', COMMITIZEN_DEFAULTS);
107 | };
108 |
109 | const standardVersionConfig = (options: Schema) => (tree: Tree, context: SchematicContext) => {
110 | let defaults = {};
111 | if (options.standardVersionConfig) defaults = { ...STANDARD_VERSION_DEFAULTS };
112 | defaults = { ...defaults, issuePrefixes: [options.issuePrefix || '#'] };
113 | addConfig(tree, context, options, 'standard-version', 'standard-version', defaults);
114 | };
115 |
116 | function addConfig(
117 | tree: Tree,
118 | context: SchematicContext,
119 | options: Schema,
120 | what: string,
121 | getPackageJsonPart: 'husky' | 'config' | 'standard-version',
122 | defaults: object,
123 | ) {
124 | context.logger.info('Added ' + what + ' configuration');
125 | const packageJson = getPackageJson(tree);
126 | const configBefore = { ...packageJson[getPackageJsonPart] };
127 | packageJson[getPackageJsonPart] = getMergedPackageJsonConfig(
128 | configBefore,
129 | defaults,
130 | options.overrideConfigurations,
131 | );
132 | overwritePackageJson(tree, packageJson);
133 | }
134 |
135 | const addCommitlintConfigFile = (options: Schema) => (tree: Tree, context: SchematicContext) => {
136 | context.logger.info('Added commitlint configuration file');
137 | const sourceTemplates = url('./files');
138 | const sourceParameterizedTemplates = apply(sourceTemplates, [
139 | template({
140 | issuePrefix: options.issuePrefix || '',
141 | }),
142 | forEach((fileEntry: FileEntry) => {
143 | // override existing files if force flag has been set
144 | if (options.overrideConfigurations && tree.exists(fileEntry.path)) {
145 | tree.overwrite(fileEntry.path, fileEntry.content);
146 | return null;
147 | }
148 | return fileEntry;
149 | }),
150 | ]);
151 | return mergeWith(sourceParameterizedTemplates)(tree, context);
152 | };
153 |
154 | const installDependencies = () => (_tree: Tree, context: SchematicContext) => {
155 | context.logger.info('Installs npm dependencies');
156 | context.addTask(new NodePackageInstallTask());
157 | };
158 |
--------------------------------------------------------------------------------
/src/ng-add/index_spec.ts:
--------------------------------------------------------------------------------
1 | import { resolve } from 'path';
2 | import { HostTree } from '@angular-devkit/schematics';
3 | import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
4 | import { getFileContent } from '@schematics/angular/utility/test';
5 | import { NgxSemanticVersion as Schema } from './schema';
6 | import { setupProject } from '../test-utils';
7 | import { STANDARD_VERSION_DEFAULTS } from './defaults';
8 |
9 | const PACKAGE_JSON_PATH = '/package.json';
10 | const COMMITLINT_PATH = '/commitlint.config.js';
11 |
12 | describe('ngx-semantic-version schematic', () => {
13 | const schematicRunner = new SchematicTestRunner(
14 | 'ngx-semantic-version',
15 | resolve(__dirname, '../collection.json'),
16 | );
17 | const project = 'foo';
18 | const defaultOptions: Schema = {
19 | skipInstall: false,
20 | packages: ['commitlint', 'commitizen', 'husky', 'standard-version'],
21 | };
22 |
23 | let appTree: UnitTestTree;
24 |
25 | beforeEach(async () => {
26 | appTree = new UnitTestTree(new HostTree());
27 | appTree = await setupProject(appTree, schematicRunner, project);
28 | });
29 |
30 | describe('when using the default options', () => {
31 | beforeEach(async () => {
32 | appTree = await schematicRunner
33 | .runSchematicAsync('ng-add', defaultOptions, appTree)
34 | .toPromise();
35 | });
36 |
37 | it(`should add the 'commitlint' configuration file`, () => {
38 | expect(appTree.files).toContain(COMMITLINT_PATH);
39 | const fileContent = getFileContent(appTree, COMMITLINT_PATH);
40 | expect(fileContent).not.toMatch(/rules: {\s+\'references-empty\': \[2, \'never\'\].\s+\},/g);
41 | expect(fileContent).not.toMatch(
42 | /parserPreset: {\s+parserOpts: \{\s+issuePrefixes: \[\'\PREFIX-\'\],\s+},\s+},/g,
43 | );
44 | });
45 |
46 | it(`should add all required dependencies to the 'package.json'`, () => {
47 | const packageJson = JSON.parse(getFileContent(appTree, PACKAGE_JSON_PATH));
48 | const { devDependencies } = packageJson;
49 | expect(appTree.files).toContain(PACKAGE_JSON_PATH);
50 | expect(devDependencies['@commitlint/cli']).toBeDefined();
51 | expect(devDependencies['@commitlint/config-conventional']).toBeDefined();
52 | expect(devDependencies.commitizen).toBeDefined();
53 | expect(devDependencies['cz-conventional-changelog']).toBeDefined();
54 | expect(devDependencies.husky).toBeDefined();
55 | expect(devDependencies['standard-version']).toBeDefined();
56 | });
57 |
58 | it('should add a npm run script', () => {
59 | const packageJson = JSON.parse(getFileContent(appTree, PACKAGE_JSON_PATH));
60 | const { scripts } = packageJson;
61 | expect(appTree.files).toContain(PACKAGE_JSON_PATH);
62 | expect(scripts.release).toEqual('standard-version');
63 | });
64 |
65 | it(`should add the 'husky' configuration`, () => {
66 | const packageJson = JSON.parse(getFileContent(appTree, PACKAGE_JSON_PATH));
67 | const { husky } = packageJson;
68 | expect(appTree.files).toContain(PACKAGE_JSON_PATH);
69 | expect(husky.hooks['commit-msg']).toEqual('commitlint -E HUSKY_GIT_PARAMS');
70 | });
71 |
72 | it(`should add the 'commitizen' configuration`, () => {
73 | const packageJson = JSON.parse(getFileContent(appTree, PACKAGE_JSON_PATH));
74 | const { config } = packageJson;
75 | expect(appTree.files).toContain(PACKAGE_JSON_PATH);
76 | expect(config.commitizen.path).toEqual('./node_modules/cz-conventional-changelog');
77 | });
78 | });
79 |
80 | describe(`when not using 'husky'`, () => {
81 | beforeEach(async () => {
82 | appTree = await schematicRunner
83 | .runSchematicAsync(
84 | 'ng-add',
85 | {
86 | ...defaultOptions,
87 | packages: ['commitlint', 'commitizen', 'standard-version'],
88 | },
89 | appTree,
90 | )
91 | .toPromise();
92 | });
93 |
94 | it(`should not add 'husky' to the project`, () => {
95 | const packageJson = JSON.parse(getFileContent(appTree, PACKAGE_JSON_PATH));
96 | const { devDependencies } = packageJson;
97 | expect(appTree.files).toContain(PACKAGE_JSON_PATH);
98 | expect(devDependencies.husky).not.toBeDefined();
99 | });
100 |
101 | it(`should skip adding the 'husky' configuration`, () => {
102 | const packageJson = JSON.parse(getFileContent(appTree, PACKAGE_JSON_PATH));
103 | const { husky } = packageJson;
104 | expect(appTree.files).toContain(PACKAGE_JSON_PATH);
105 | expect(husky).not.toBeDefined();
106 | });
107 | });
108 |
109 | describe(`when disabling 'commitlint'`, () => {
110 | beforeEach(async () => {
111 | appTree = await schematicRunner
112 | .runSchematicAsync(
113 | 'ng-add',
114 | {
115 | ...defaultOptions,
116 | packages: ['commitizen', 'husky', 'standard-version'],
117 | },
118 | appTree,
119 | )
120 | .toPromise();
121 | });
122 |
123 | it(`should not add 'commitlint' to the project`, () => {
124 | const packageJson = JSON.parse(getFileContent(appTree, PACKAGE_JSON_PATH));
125 | const { devDependencies } = packageJson;
126 | expect(appTree.files).toContain(PACKAGE_JSON_PATH);
127 | expect(devDependencies['@commitlint/cli']).not.toBeDefined();
128 | expect(devDependencies['@commitlint/config-conventional']).not.toBeDefined();
129 | });
130 | });
131 |
132 | describe(`when disabling 'commitizen'`, () => {
133 | beforeEach(async () => {
134 | appTree = await schematicRunner
135 | .runSchematicAsync(
136 | 'ng-add',
137 | {
138 | ...defaultOptions,
139 | packages: ['commitlint', 'husky', 'standard-version'],
140 | },
141 | appTree,
142 | )
143 | .toPromise();
144 | });
145 |
146 | it(`should not add 'commitizen' to the project`, () => {
147 | const packageJson = JSON.parse(getFileContent(appTree, PACKAGE_JSON_PATH));
148 | const { devDependencies } = packageJson;
149 | expect(appTree.files).toContain(PACKAGE_JSON_PATH);
150 | expect(devDependencies.commitizen).not.toBeDefined();
151 | });
152 |
153 | it(`should skip adding the 'commitizen' configuration`, () => {
154 | const packageJson = JSON.parse(getFileContent(appTree, PACKAGE_JSON_PATH));
155 | const { config } = packageJson;
156 | expect(appTree.files).toContain(PACKAGE_JSON_PATH);
157 | expect(config).not.toBeDefined();
158 | });
159 | });
160 |
161 | describe(`when disabling 'standard-version'`, () => {
162 | beforeEach(async () => {
163 | appTree = await schematicRunner
164 | .runSchematicAsync(
165 | 'ng-add',
166 | {
167 | ...defaultOptions,
168 | packages: ['commitlint', 'commitizen', 'husky'],
169 | },
170 | appTree,
171 | )
172 | .toPromise();
173 | });
174 |
175 | it(`should not add 'standard-version' to the project`, () => {
176 | const packageJson = JSON.parse(getFileContent(appTree, PACKAGE_JSON_PATH));
177 | const { devDependencies } = packageJson;
178 | expect(appTree.files).toContain(PACKAGE_JSON_PATH);
179 | expect(devDependencies['standard-version']).not.toBeDefined();
180 | });
181 |
182 | it('should skip adding a npm run script', () => {
183 | const packageJson = JSON.parse(getFileContent(appTree, PACKAGE_JSON_PATH));
184 | const { scripts } = packageJson;
185 | expect(appTree.files).toContain(PACKAGE_JSON_PATH);
186 | expect(scripts.release).not.toBeDefined();
187 | });
188 | });
189 |
190 | describe(`when using an issue prefix`, () => {
191 | beforeEach(async () => {
192 | appTree = await schematicRunner
193 | .runSchematicAsync('ng-add', { ...defaultOptions, issuePrefix: 'PREFIX-' }, appTree)
194 | .toPromise();
195 | });
196 |
197 | it(`should configure 'issuePrefixes' in '/commitlint.config.js'`, () => {
198 | expect(appTree.files).toContain(COMMITLINT_PATH);
199 | const fileContent = getFileContent(appTree, COMMITLINT_PATH);
200 | expect(fileContent).toMatch(/rules: {\s+\'references-empty\': \[2, \'never\'\].\s+\},/g);
201 | expect(fileContent).toMatch(
202 | /parserPreset: {\s+parserOpts: \{\s+issuePrefixes: \[\'\PREFIX-\'\],\s+},\s+},/g,
203 | );
204 | });
205 |
206 | it(`should add 'standard-version' config`, () => {
207 | const packageJson = JSON.parse(getFileContent(appTree, PACKAGE_JSON_PATH));
208 | expect(packageJson['standard-version'].issuePrefixes).toContain('PREFIX-');
209 | });
210 | });
211 |
212 | describe(`when using '--standardVersionConfig'`, () => {
213 | it(`should add the basic configuration to '/package.json'`, async () => {
214 | appTree = await schematicRunner
215 | .runSchematicAsync('ng-add', { ...defaultOptions, standardVersionConfig: true }, appTree)
216 | .toPromise();
217 | const packageJson = JSON.parse(getFileContent(appTree, PACKAGE_JSON_PATH));
218 | expect(packageJson['standard-version']).toEqual(STANDARD_VERSION_DEFAULTS);
219 | });
220 |
221 | it(`should add the basic configuration with 'issuePrefix' to '/package.json'`, async () => {
222 | appTree = await schematicRunner
223 | .runSchematicAsync(
224 | 'ng-add',
225 | { ...defaultOptions, standardVersionConfig: true, issuePrefix: 'PREFIX-' },
226 | appTree,
227 | )
228 | .toPromise();
229 | const packageJson = JSON.parse(getFileContent(appTree, PACKAGE_JSON_PATH));
230 | const expectedConfig = {
231 | ...STANDARD_VERSION_DEFAULTS,
232 | issuePrefixes: ['PREFIX-'],
233 | };
234 | expect(packageJson['standard-version']).toEqual(expectedConfig);
235 | });
236 | });
237 |
238 | describe(`when running in an existing project`, () => {
239 | let appTreeOnExistingProject: UnitTestTree;
240 | let packageJson: { [key: string]: any };
241 | let packageJsonModified: { [key: string]: any };
242 |
243 | beforeEach(async () => {
244 | appTree = await schematicRunner
245 | .runSchematicAsync('ng-add', defaultOptions, appTree)
246 | .toPromise();
247 | const packageJson = JSON.parse(getFileContent(appTree, PACKAGE_JSON_PATH));
248 | packageJsonModified = {
249 | ...packageJson,
250 | scripts: {
251 | release: 'foo ./bar',
252 | foo: 'bar',
253 | },
254 | husky: {
255 | hooks: {
256 | 'commit-msg': 'foo-bar',
257 | },
258 | },
259 | config: {
260 | commitizen: {
261 | path: '~/foo-bar',
262 | },
263 | other: {
264 | foo: 'bar',
265 | },
266 | },
267 | 'standard-version': {
268 | issuePrefixes: 'foo',
269 | skip: {
270 | changelog: true,
271 | },
272 | },
273 | };
274 | });
275 |
276 | describe(`and not using '--overrideConfigurations'`, () => {
277 | beforeEach(async () => {
278 | appTree.overwrite(PACKAGE_JSON_PATH, JSON.stringify(packageJsonModified));
279 | appTree.delete(COMMITLINT_PATH);
280 | appTreeOnExistingProject = new UnitTestTree(appTree);
281 | appTreeOnExistingProject = await schematicRunner
282 | .runSchematicAsync(
283 | 'ng-add',
284 | { ...defaultOptions, issuePrefix: 'bar' },
285 | appTreeOnExistingProject,
286 | )
287 | .toPromise();
288 | packageJson = JSON.parse(getFileContent(appTreeOnExistingProject, PACKAGE_JSON_PATH));
289 | });
290 |
291 | it(`should not override 'standard-version' config`, () => {
292 | expect(packageJson['standard-version'].issuePrefixes).toContain('foo');
293 | });
294 |
295 | it(`should not override 'scripts' config`, () => {
296 | expect(packageJson.scripts.release).toContain('foo ./bar');
297 | });
298 |
299 | it(`should not override 'commitizen' config`, () => {
300 | expect(packageJson.config.commitizen.path).toContain('~/foo-bar');
301 | });
302 |
303 | it(`should not override 'husky' config`, () => {
304 | expect(packageJson.husky.hooks['commit-msg']).toContain('foo-bar');
305 | });
306 | });
307 |
308 | describe(`and using '--overrideConfigurations'`, () => {
309 | beforeEach(async () => {
310 | appTree.overwrite(PACKAGE_JSON_PATH, JSON.stringify(packageJsonModified));
311 | appTree.overwrite(COMMITLINT_PATH, '// fooBar');
312 | appTreeOnExistingProject = new UnitTestTree(appTree);
313 | appTreeOnExistingProject = await schematicRunner
314 | .runSchematicAsync(
315 | 'ng-add',
316 | { ...defaultOptions, overrideConfigurations: true, issuePrefix: 'bar' },
317 | appTreeOnExistingProject,
318 | )
319 | .toPromise();
320 | packageJson = JSON.parse(getFileContent(appTreeOnExistingProject, PACKAGE_JSON_PATH));
321 | });
322 |
323 | it(`should override 'standard-version' config`, () => {
324 | expect(packageJson['standard-version'].issuePrefixes).toContain('bar');
325 | expect(packageJson['standard-version'].skip.changelog).toBeTruthy;
326 | });
327 |
328 | it(`should override 'scripts' config`, () => {
329 | expect(packageJson.scripts.release).toContain('standard-version');
330 | expect(packageJson.scripts.foo).toContain('bar');
331 | });
332 |
333 | it(`should override 'commitizen' config`, () => {
334 | expect(packageJson.config.commitizen.path).toContain(
335 | './node_modules/cz-conventional-changelog',
336 | );
337 | expect(packageJson.config.other.foo).toContain('bar');
338 | });
339 |
340 | it(`should override 'husky' config`, () => {
341 | expect(packageJson.husky.hooks['commit-msg']).toContain('commitlint -E HUSKY_GIT_PARAMS');
342 | });
343 |
344 | it(`should override an existing 'commitlint' configuration file`, () => {
345 | expect(appTree.files).toContain(COMMITLINT_PATH);
346 | const fileContent = getFileContent(appTree, COMMITLINT_PATH);
347 | expect(fileContent).toMatch(/module.exports = \{(.*)\};/gs);
348 | });
349 | });
350 | });
351 | });
352 |
--------------------------------------------------------------------------------
/src/ng-add/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json-schema.org/schema",
3 | "id": "ngx-semantic-version",
4 | "title": "ngx-semantic-version Schema",
5 | "description": "configure commitlint, husky, commitizen and standard-version configuration",
6 | "type": "object",
7 | "properties": {
8 | "packages": {
9 | "type": "array",
10 | "description": "select the packages that should to be installed and configured",
11 | "uniqueItems": true,
12 | "minItems": 1,
13 | "items": {
14 | "enum": ["commitlint", "commitizen", "husky", "standard-version"],
15 | "type": "string"
16 | },
17 | "default": ["commitlint", "commitizen", "husky", "standard-version"],
18 | "x-prompt": "What packages do you want to be installed and configured?"
19 | },
20 | "skipInstall": {
21 | "type": "boolean",
22 | "description": "Skip installing the npm packages",
23 | "default": false
24 | },
25 | "standardVersionConfig": {
26 | "type": "boolean",
27 | "description": "add the standard-version default configuration to the `packages.json` file",
28 | "default": false
29 | },
30 | "issuePrefix": {
31 | "type": "string",
32 | "description": "configure an issue prefix that should be checked by each commit",
33 | "default": ""
34 | },
35 | "overrideConfigurations": {
36 | "type": "boolean",
37 | "description": "Override existing configuration parameters",
38 | "default": false
39 | }
40 | },
41 | "required": ["packages"]
42 | }
43 |
--------------------------------------------------------------------------------
/src/ng-add/schema.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * ngx-semantic-version Schema
3 | * configure commitlint, husky, commitizen and standard-version configuration
4 | */
5 | export interface NgxSemanticVersion {
6 | /**
7 | * select the packages that should to be installed and configured
8 | */
9 | packages: PackageName[];
10 | /**
11 | * Skip installing the npm packages
12 | */
13 | skipInstall?: boolean;
14 | /**
15 | * add the standard-version default configuration to the `packages.json` file
16 | */
17 | standardVersionConfig?: boolean;
18 | /**
19 | * configure an issue prefix that should be checked by each commit
20 | */
21 | issuePrefix?: string;
22 | /**
23 | * Override existing configuration parameters
24 | */
25 | overrideConfigurations?: boolean;
26 | }
27 |
28 | export type PackageName = 'commitlint' | 'commitizen' | 'husky' | 'standard-version';
29 |
--------------------------------------------------------------------------------
/src/ng-update/migration-01/index.ts:
--------------------------------------------------------------------------------
1 | import { Rule, SchematicContext, Tree, chain } from '@angular-devkit/schematics';
2 | import { getPackageJson, overwritePackageJson } from '../../utils';
3 |
4 | export default (_options: any): Rule => {
5 | return chain([addHuskyConfig, updateDependencies]);
6 | };
7 |
8 | const addHuskyConfig = () => (tree: Tree, context: SchematicContext) => {
9 | context.logger.info('Removes old husky prepare-commit-msg configuration');
10 |
11 | const packageJson = getPackageJson(tree);
12 | if (
13 | packageJson.husky &&
14 | packageJson.husky.hooks &&
15 | packageJson.husky.hooks['prepare-commit-msg'] === 'exec < /dev/tty && git cz --hook'
16 | ) {
17 | delete packageJson.husky.hooks['prepare-commit-msg'];
18 | }
19 |
20 | overwritePackageJson(tree, packageJson);
21 | };
22 |
23 | const updateDependencies = () => (tree: Tree, context: SchematicContext) => {
24 | context.logger.info('Updates npm packages as dev dependencies');
25 | const packageJson = getPackageJson(tree);
26 |
27 | const devDepsToAdd = {
28 | husky: '^3.0.9',
29 | };
30 | packageJson.devDependencies = {
31 | ...packageJson.devDependencies,
32 | ...devDepsToAdd,
33 | };
34 |
35 | overwritePackageJson(tree, packageJson);
36 | };
37 |
--------------------------------------------------------------------------------
/src/ng-update/migration-01/index_spec.ts:
--------------------------------------------------------------------------------
1 | import { Tree } from '@angular-devkit/schematics';
2 | import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
3 | import { map } from 'rxjs/operators';
4 | import { Observable } from 'rxjs';
5 | import * as path from 'path';
6 |
7 | const packagePath = '/package.json';
8 | const collectionPath = path.join(__dirname, '../../migration.json');
9 |
10 | const huskykHookForTest = (hook: string, command: string) => {
11 | return `{
12 | "husky": {
13 | "hooks": {
14 | "${hook}": "${command}"
15 | }
16 | }
17 | }`;
18 | };
19 | const packageJsonAfterMigration = (packgeJsonRawContent: string): Observable => {
20 | const emptyTree = Tree.empty() as UnitTestTree;
21 | const runner = new SchematicTestRunner('schematics', collectionPath);
22 | emptyTree.create(packagePath, packgeJsonRawContent);
23 | return runner.runSchematicAsync('migration-01', {}, emptyTree)
24 | .pipe(
25 | map(updatedTree => JSON.parse(updatedTree.readContent(packagePath)))
26 | );
27 | };
28 |
29 | describe('update from version 0.0.4', () => {
30 | const prepareCommitMsgHookToBeRemoved = 'exec < /dev/tty && git cz --hook';
31 |
32 | it(`should remove a previous configuration`, () => {
33 | const beforeMigration = huskykHookForTest(
34 | 'prepare-commit-msg',
35 | prepareCommitMsgHookToBeRemoved,
36 | );
37 | packageJsonAfterMigration(beforeMigration).subscribe((pkg) => {
38 | expect(pkg.husky.hooks['prepare-commit-msg']).not.toBeDefined();
39 | });
40 | });
41 | it(`should not touch if the husky hook has been modified`, () => {
42 | const beforeMigration = huskykHookForTest('prepare-commit-msg', 'some other user defined hook');
43 | packageJsonAfterMigration(beforeMigration).subscribe((pkg) => {
44 | expect(pkg.husky.hooks['prepare-commit-msg']).toBeDefined();
45 | expect(pkg.husky.hooks['prepare-commit-msg']).not.toEqual(prepareCommitMsgHookToBeRemoved);
46 | });
47 | });
48 | it('should update dependencies in package.json', () => {
49 | const beforeMigration = `{
50 | "devDependencies": {
51 | "husky": "^3.0.8"
52 | }
53 | }`;
54 | packageJsonAfterMigration(beforeMigration).subscribe((pkg) => {
55 | const { devDependencies } = pkg;
56 | expect(devDependencies.husky).toEqual('^3.0.9');
57 | });
58 | });
59 | });
60 |
--------------------------------------------------------------------------------
/src/ng-update/migration-02/index.ts:
--------------------------------------------------------------------------------
1 | import {
2 | Rule,
3 | SchematicContext,
4 | Tree,
5 | chain,
6 | apply,
7 | url,
8 | mergeWith,
9 | template,
10 | MergeStrategy,
11 | } from '@angular-devkit/schematics';
12 | import { getPackageJson, overwritePackageJson } from '../../utils';
13 |
14 | export default (_options: any): Rule => {
15 | return chain([removeCommitlintAngularConfig, overrideCommitlintConfigFile]);
16 | };
17 |
18 | const removeCommitlintAngularConfig = () => (tree: Tree, context: SchematicContext) => {
19 | context.logger.info('Updates npm packages as dev dependencies');
20 | const packageJson = getPackageJson(tree);
21 |
22 | if (packageJson.devDependencies['@commitlint/config-angular'] === '^8.2.0') {
23 | delete packageJson.devDependencies['@commitlint/config-angular'];
24 | }
25 | packageJson.devDependencies['@commitlint/config-conventional'] = '^8.2.0';
26 |
27 | overwritePackageJson(tree, packageJson);
28 | };
29 |
30 | const overrideCommitlintConfigFile = () => (tree: Tree, context: SchematicContext) => {
31 | context.logger.info('Added commitlint configuration file');
32 | const sourceTemplates = url('./files/commitlint.config.js');
33 | const sourceParameterizedTemplates = apply(sourceTemplates, [template({})]);
34 | return mergeWith(sourceParameterizedTemplates, MergeStrategy.Overwrite)(tree, context);
35 | };
36 |
--------------------------------------------------------------------------------
/src/ng-update/migration-02/index_spec.ts:
--------------------------------------------------------------------------------
1 | import { Tree } from '@angular-devkit/schematics';
2 | import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
3 | import { map } from 'rxjs/operators';
4 | import { Observable } from 'rxjs';
5 | import * as path from 'path';
6 |
7 | const packagePath = '/package.json';
8 | const collectionPath = path.join(__dirname, '../../migration.json');
9 |
10 | const packageJsonAfterMigration = (packgeJsonRawContent: string): Observable => {
11 | const emptyTree = Tree.empty() as UnitTestTree;
12 | const runner = new SchematicTestRunner('schematics', collectionPath);
13 | emptyTree.create(packagePath, packgeJsonRawContent);
14 | return runner.runSchematicAsync('migration-02', {}, emptyTree)
15 | .pipe(
16 | map(updatedTree => JSON.parse(updatedTree.readContent(packagePath)))
17 | );
18 | };
19 |
20 | describe('update to version 0.0.5', () => {
21 | it('should remove @commitlint/config-angular@^8.2.0 from package.json', () => {
22 | const beforeMigration = `{
23 | "devDependencies": {
24 | "@commitlint/config-angular": "^8.2.0"
25 | }
26 | }`;
27 | packageJsonAfterMigration(beforeMigration).subscribe((pkg) => {
28 | const { devDependencies } = pkg;
29 | expect(devDependencies['@commitlint/config-angular']).not.toBeDefined();
30 | expect(devDependencies['@commitlint/config-conventional']).toEqual('^8.2.0');
31 | });
32 | });
33 |
34 | it('should not remove modified @commitlint/config-angular version from package.json', () => {
35 | const beforeMigration = `{
36 | "devDependencies": {
37 | "@commitlint/config-angular": "^8.0.0"
38 | }
39 | }`;
40 | packageJsonAfterMigration(beforeMigration).subscribe((pkg) => {;
41 | const { devDependencies } = pkg;
42 | expect(devDependencies['@commitlint/config-angular']).toEqual('^8.0.0');
43 | });
44 | });
45 | });
46 |
--------------------------------------------------------------------------------
/src/ng-update/migration-03/index.ts:
--------------------------------------------------------------------------------
1 | import { Rule, SchematicContext, Tree, chain } from '@angular-devkit/schematics';
2 | import { getPackageJson, overwritePackageJson } from '../../utils';
3 |
4 | export default (_options: any): Rule => {
5 | return chain([updateDependencies]);
6 | };
7 |
8 | const updateDependencies = () => (tree: Tree, context: SchematicContext) => {
9 | context.logger.info('Updates npm packages as dev dependencies');
10 | const packageJson = getPackageJson(tree);
11 |
12 | // be sure that ngx-semantic-version will be removed from the `dependencies` section
13 | delete packageJson.dependencies['ngx-semantic-version'];
14 |
15 | overwritePackageJson(tree, packageJson);
16 | };
17 |
--------------------------------------------------------------------------------
/src/ng-update/migration-03/index_spec.ts:
--------------------------------------------------------------------------------
1 | import { Tree } from '@angular-devkit/schematics';
2 | import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
3 | import { map } from 'rxjs/operators';
4 | import { Observable } from 'rxjs';
5 | import * as path from 'path';
6 |
7 | const packagePath = '/package.json';
8 | const collectionPath = path.join(__dirname, '../../migration.json');
9 |
10 | const packageJsonAfterMigration = (packgeJsonRawContent: string): Observable => {
11 | const emptyTree = Tree.empty() as UnitTestTree;
12 | const runner = new SchematicTestRunner('schematics', collectionPath);
13 | emptyTree.create(packagePath, packgeJsonRawContent);
14 | return runner.runSchematicAsync('migration-03', {}, emptyTree)
15 | .pipe(
16 | map(updatedTree => JSON.parse(updatedTree.readContent(packagePath)))
17 | );
18 | };
19 |
20 | describe('update to version >= 2', () => {
21 | it('should update dependencies in package.json', () => {
22 | const beforeMigration = `{
23 | "dependencies": {
24 | "ngx-semantic-version": "1.2.1"
25 | }
26 | }`;
27 | packageJsonAfterMigration(beforeMigration).subscribe((pkg) => {
28 | const { dependencies } = pkg;
29 | expect(dependencies['ngx-semantic-version']).toBeUndefined;
30 | });
31 | });
32 | });
33 |
--------------------------------------------------------------------------------
/src/ng-update/migration-04/index.ts:
--------------------------------------------------------------------------------
1 | import { Rule, SchematicContext, Tree, chain } from '@angular-devkit/schematics';
2 | import { getPackageJson, overwritePackageJson } from '../../utils';
3 | import { NgxSemanticVersion as Schema, PackageName } from '../../ng-add/schema';
4 | import { PackageJsonConfigPart } from '../../utils';
5 | import { DEV_DEPS_TO_ADD } from '../../ng-add/defaults';
6 |
7 | export default (_options: Schema): Rule => {
8 | return chain([updateDependencies]);
9 | };
10 |
11 | const updateDependencies = () => (tree: Tree, context: SchematicContext) => {
12 | context.logger.info('Updating npm packages dev dependencies for tooling');
13 | const packageJson = getPackageJson(tree);
14 |
15 | let devDepsToAdd: PackageJsonConfigPart = {};
16 |
17 | const map = new Map([
18 | ['commitlint', DEV_DEPS_TO_ADD],
19 | ['commitizen', DEV_DEPS_TO_ADD],
20 | ['husky', DEV_DEPS_TO_ADD],
21 | ['standard-version', DEV_DEPS_TO_ADD],
22 | ]);
23 |
24 | for (const [key, value] of map.entries()) {
25 | const searchKey = key as PackageName;
26 | devDepsToAdd = {
27 | ...devDepsToAdd,
28 | ...value[searchKey],
29 | };
30 | }
31 |
32 | packageJson.devDependencies = {
33 | ...packageJson.devDependencies,
34 | ...devDepsToAdd,
35 | };
36 |
37 | overwritePackageJson(tree, packageJson);
38 | };
39 |
--------------------------------------------------------------------------------
/src/ng-update/migration-04/index_spec.ts:
--------------------------------------------------------------------------------
1 | import { Tree } from '@angular-devkit/schematics';
2 | import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
3 | import { map } from 'rxjs/operators';
4 | import { Observable } from 'rxjs';
5 | import * as path from 'path';
6 |
7 | const packagePath = '/package.json';
8 | const collectionPath = path.join(__dirname, '../../migration.json');
9 |
10 | const packageJsonAfterMigration = (packgeJsonRawContent: string): Observable => {
11 | const emptyTree = Tree.empty() as UnitTestTree;
12 | const runner = new SchematicTestRunner('schematics', collectionPath);
13 | emptyTree.create(packagePath, packgeJsonRawContent);
14 | return runner.runSchematicAsync('migration-04', {}, emptyTree)
15 | .pipe(
16 | map(updatedTree => JSON.parse(updatedTree.readContent(packagePath)))
17 | );
18 | };
19 |
20 | describe('update to version >= 2', () => {
21 | it('should not remove modified @commitlint/config-angular version from package.json', () => {
22 | const beforeMigration = `{
23 | "devDependencies": {
24 | "@commitlint/cli": "0.0.0",
25 | "@commitlint/config-conventional": "0.0.0",
26 | "commitizen": "0.0.0",
27 | "cz-conventional-changelog": "0.0.0",
28 | "husky": "0.0.0",
29 | "standard-version": "0.0.0"
30 | }
31 | }`;
32 | packageJsonAfterMigration(beforeMigration).subscribe((pkg) => {;
33 | const { devDependencies } = pkg;
34 | expect(devDependencies['@commitlint/cli']).toEqual('^11.0.0');
35 | expect(devDependencies['@commitlint/config-conventional']).toEqual('^11.0.0');
36 | expect(devDependencies['commitizen']).toEqual('^4.2.2');
37 | expect(devDependencies['cz-conventional-changelog']).toEqual('^3.3.0');
38 | expect(devDependencies['husky']).toEqual('^4.3.0');
39 | expect(devDependencies['standard-version']).toEqual('^9.0.0');
40 | });
41 | });
42 | });
43 |
--------------------------------------------------------------------------------
/src/test-utils.ts:
--------------------------------------------------------------------------------
1 | import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
2 |
3 | export async function setupProject(
4 | tree: UnitTestTree,
5 | schematicRunner: SchematicTestRunner,
6 | name: string,
7 | ) {
8 | tree = await schematicRunner
9 | .runExternalSchematicAsync('@schematics/angular', 'workspace', {
10 | name: 'workspace',
11 | version: '8.0.0',
12 | newProjectRoot: '',
13 | })
14 | .toPromise();
15 |
16 | tree = await schematicRunner
17 | .runExternalSchematicAsync(
18 | '@schematics/angular',
19 | 'application',
20 | {
21 | name,
22 | projectRoot: '',
23 | },
24 | tree,
25 | )
26 | .toPromise();
27 |
28 | return tree;
29 | }
30 |
--------------------------------------------------------------------------------
/src/utils.ts:
--------------------------------------------------------------------------------
1 | import { join } from 'path';
2 | import { SchematicsException, Tree } from '@angular-devkit/schematics';
3 |
4 | const PACKAGE_JSON = 'package.json';
5 |
6 | export interface PackageJson {
7 | dependencies: PackageJsonConfigPart;
8 | devDependencies: PackageJsonConfigPart;
9 | name?: string;
10 | version?: string;
11 | license?: string;
12 | scripts?: PackageJsonConfigPart;
13 | repository?: PackageJsonConfigPart;
14 | bugs?: PackageJsonConfigPart;
15 | config?: {
16 | commitizen?: {
17 | path?: string;
18 | };
19 | };
20 | husky?: {
21 | hooks?: {
22 | 'prepare-commit-msg'?: string;
23 | 'commit-msg'?: string;
24 | };
25 | };
26 | 'standard-version': {
27 | issuePrefixes?: string[];
28 | };
29 | }
30 |
31 | export interface PackageJsonConfigPart {
32 | [key: string]: T;
33 | }
34 |
35 | class FileNotFoundException extends Error {
36 | constructor(fileName: string) {
37 | const message = `File ${fileName} not found!`;
38 | super(message);
39 | }
40 | }
41 |
42 | export const getJsonFile = (tree: Tree, path: string): T => {
43 | const file = tree.get(path);
44 | if (!file) {
45 | throw new FileNotFoundException(path);
46 | }
47 |
48 | try {
49 | const content = JSON.parse(file.content.toString());
50 |
51 | return content as T;
52 | } catch (e) {
53 | throw new SchematicsException(`File ${path} could not be parsed!`);
54 | }
55 | };
56 |
57 | export const getFileContents = (tree: Tree, filePath: string): string => {
58 | const buffer = tree.read(filePath) || '';
59 |
60 | return buffer.toString();
61 | };
62 |
63 | export const getPackageJson = (tree: Tree, workingDirectory: string = ''): PackageJson => {
64 | const url = join(workingDirectory, PACKAGE_JSON);
65 |
66 | return getJsonFile(tree, url);
67 | };
68 |
69 | export const overwritePackageJson = (
70 | tree: Tree,
71 | content: PackageJson,
72 | workingDirectory: string = '',
73 | ) => {
74 | const url = join(workingDirectory, PACKAGE_JSON);
75 |
76 | tree.overwrite(url, JSON.stringify(content, null, 2));
77 | };
78 |
79 | export const getMergedPackageJsonConfig = (
80 | existingConfig: PackageJsonConfigPart,
81 | newConfig: PackageJsonConfigPart,
82 | overrideExisting = true,
83 | ) => {
84 | let mergedConfig: PackageJsonConfigPart = {};
85 | if (overrideExisting) {
86 | mergedConfig = { ...existingConfig, ...newConfig };
87 | } else {
88 | mergedConfig = { ...newConfig, ...existingConfig };
89 | }
90 | return mergedConfig;
91 | };
92 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": "tsconfig",
4 | "lib": ["es2018", "dom"],
5 | "declaration": true,
6 | "module": "commonjs",
7 | "moduleResolution": "node",
8 | "noEmitOnError": true,
9 | "noFallthroughCasesInSwitch": true,
10 | "noImplicitAny": true,
11 | "noImplicitThis": true,
12 | "noUnusedParameters": true,
13 | "noUnusedLocals": true,
14 | "rootDir": "src/",
15 | "skipDefaultLibCheck": true,
16 | "skipLibCheck": true,
17 | "sourceMap": true,
18 | "strictNullChecks": true,
19 | "target": "es6",
20 | "types": ["jasmine", "node"]
21 | },
22 | "include": ["src/**/*"],
23 | "exclude": ["src/*/files/**/*"]
24 | }
25 |
--------------------------------------------------------------------------------