├── .conventional-changelog-lintrc ├── .cz-config.js ├── .editorconfig ├── .github ├── stale.yml └── workflows │ ├── build.yml │ ├── shipjs-prepare.yml │ └── shipjs-trigger.yml ├── .gitignore ├── .vscode ├── launch.json ├── settings.json └── tasks.json ├── .vscodeignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── images ├── commitizen-logo.png └── commitizen-logo.svg ├── package.json ├── ship.config.js ├── src ├── extension.ts └── test │ ├── runTest.ts │ └── workspace │ ├── extension.test.ts │ ├── index.ts │ └── workspace │ ├── .gitignore │ ├── package.json │ ├── src │ └── index.js │ └── yarn.lock ├── tsconfig.json ├── tslint.json ├── typings └── sander.d.ts └── yarn.lock /.conventional-changelog-lintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["angular"] 3 | } 4 | -------------------------------------------------------------------------------- /.cz-config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | 5 | types: [ 6 | {value: 'feat', name: 'feat: A new feature'}, 7 | {value: 'fix', name: 'fix: A bug fix'}, 8 | {value: 'docs', name: 'docs: Documentation only changes'}, 9 | {value: 'style', name: 'style: Changes that do not affect the meaning of the code\n (white-space, formatting, missing semi-colons, etc)'}, 10 | {value: 'refactor', name: 'refactor: A code change that neither fixes a bug nor adds a feature'}, 11 | {value: 'perf', name: 'perf: A code change that improves performance'}, 12 | {value: 'test', name: 'test: Adding missing tests'}, 13 | {value: 'chore', name: 'chore: Changes to the build process or auxiliary tools\n and libraries such as documentation generation'}, 14 | {value: 'revert', name: 'revert: Revert to a commit'}, 15 | {value: 'WIP', name: 'WIP: Work in progress'} 16 | ], 17 | 18 | scopes: [ 19 | {} 20 | ], 21 | 22 | allowCustomScopes: false, 23 | allowBreakingChanges: ['feat'] 24 | 25 | }; 26 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_size = 2 7 | indent_style = space 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | charset = utf-8 13 | end_of_line = lf 14 | indent_size = 2 15 | indent_style = space 16 | insert_final_newline = true 17 | trim_trailing_whitespace = false 18 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 30 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 7 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - pinned 8 | - security 9 | # Comment to post when marking an issue as stale. Set to `false` to disable 10 | markComment: > 11 | This issue has been automatically marked as stale because it has not had 12 | recent activity. It will be closed if no further activity occurs. Thank you 13 | for your contributions. 14 | # Comment to post when closing a stale issue. Set to `false` to disable 15 | closeComment: false 16 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | branches: 9 | - master 10 | 11 | jobs: 12 | build: 13 | strategy: 14 | matrix: 15 | os: 16 | - macos-latest 17 | - ubuntu-latest 18 | - windows-latest 19 | 20 | runs-on: ${{ matrix.os }} 21 | 22 | steps: 23 | - uses: actions/checkout@v3 24 | - uses: actions/setup-node@v3 25 | with: 26 | node-version: 12.8.1 27 | - id: yarn-cache-dir-path 28 | run: echo "::set-output name=dir::$(yarn cache dir)" 29 | - uses: actions/cache@v3 30 | id: yarn-cache 31 | with: 32 | path: ${{ steps.yarn-cache-dir-path.outputs.dir }} 33 | key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} 34 | restore-keys: | 35 | ${{ runner.os }}-yarn- 36 | - run: | 37 | yarn install 38 | - run: | 39 | yarn vscode:prepublish 40 | yarn linter 41 | - uses: GabrielBB/xvfb-action@v1.6 42 | with: 43 | run: | 44 | yarn test 45 | -------------------------------------------------------------------------------- /.github/workflows/shipjs-prepare.yml: -------------------------------------------------------------------------------- 1 | name: Ship js prepare release 2 | 3 | on: 4 | issue_comment: 5 | types: [created] 6 | 7 | jobs: 8 | prepare_release: 9 | if: | 10 | github.event_name == 'issue_comment' && 11 | (github.event.comment.author_association == 'member' || github.event.comment.author_association == 'owner') && 12 | startsWith(github.event.comment.body, '@shipjs prepare') 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v3 17 | - run: | 18 | git fetch --prune --unshallow 19 | - uses: actions/setup-node@v3 20 | - run: | 21 | yarn install 22 | - run: | 23 | git config --global user.email "mail@markus-wolf.de" 24 | git config --global user.name "Markus Wolf" 25 | - run: yarn shipjs prepare --yes --no-browse 26 | env: 27 | GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} 28 | 29 | create_done_comment: 30 | if: success() 31 | needs: prepare_release 32 | runs-on: ubuntu-latest 33 | 34 | steps: 35 | - uses: actions/github-script@v6.3.3 36 | with: 37 | github-token: ${{ secrets.GITHUB_TOKEN }} 38 | script: | 39 | github.rest.issues.createComment({ 40 | issue_number: context.issue.number, 41 | owner: context.repo.owner, 42 | repo: context.repo.repo, 43 | body: '@${{ github.actor }} `shipjs prepare` done' 44 | }) 45 | 46 | create_fail_comment: 47 | if: cancelled() || failure() 48 | needs: prepare_release 49 | runs-on: ubuntu-latest 50 | 51 | steps: 52 | - uses: actions/github-script@v6.3.3 53 | with: 54 | github-token: ${{secrets.GITHUB_TOKEN}} 55 | script: | 56 | github.rest.issues.createComment({ 57 | issue_number: context.issue.number, 58 | owner: context.repo.owner, 59 | repo: context.repo.repo, 60 | body: '@${{ github.actor }} `shipjs prepare` fail' 61 | }) 62 | -------------------------------------------------------------------------------- /.github/workflows/shipjs-trigger.yml: -------------------------------------------------------------------------------- 1 | name: Ship js trigger release 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | 7 | jobs: 8 | trigger_release: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - uses: actions/checkout@v3 13 | - uses: actions/setup-node@v3 14 | - run: | 15 | yarn install 16 | - run: | 17 | yarn shipjs trigger 18 | env: 19 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 20 | VSCE_TOKEN: ${{ secrets.VSCE_TOKEN }} 21 | NPM_AUTH_TOKEN: "" 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | node_modules 3 | npm-debug.log 4 | .vscode-test/ 5 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that compiles the extension and then opens it inside a new window 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | { 6 | "version": "0.2.0", 7 | "configurations": [ 8 | { 9 | "name": "Run Extension", 10 | "type": "extensionHost", 11 | "request": "launch", 12 | "runtimeExecutable": "${execPath}", 13 | "args": [ 14 | "--disable-extensions", 15 | "--extensionDevelopmentPath=${workspaceFolder}", 16 | "${workspaceFolder}/src/test/workspace/workspace" 17 | ], 18 | "outFiles": ["${workspaceFolder}/out/**/*.js"], 19 | "preLaunchTask": "${defaultBuildTask}" 20 | }, 21 | { 22 | "name": "Extension Tests", 23 | "type": "extensionHost", 24 | "request": "launch", 25 | "runtimeExecutable": "${execPath}", 26 | "args": [ 27 | "--disable-extensions", 28 | "--extensionDevelopmentPath=${workspaceFolder}", 29 | "--extensionTestsPath=${workspaceFolder}/src/test/workspace/index", 30 | "${workspaceFolder}/src/test/workspace/workspace" 31 | ], 32 | "outFiles": ["${workspaceFolder}/out/test/**/*.js"], 33 | "preLaunchTask": "${defaultBuildTask}" 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.exclude": { 4 | "out": false // set this to true to hide the "out" folder with the compiled JS files 5 | }, 6 | "search.exclude": { 7 | "out": true // set this to false to include "out" folder in search results 8 | }, 9 | "typescript.tsdk": "./node_modules/typescript/lib" // we want to use the TS server from our node_modules folder to control its version 10 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // See https://go.microsoft.com/fwlink/?LinkId=733558 2 | // for the documentation about the tasks.json format 3 | { 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "type": "npm", 8 | "script": "compile", 9 | "problemMatcher": "$tsc-watch", 10 | "isBackground": true, 11 | "presentation": { 12 | "reveal": "never" 13 | }, 14 | "group": { 15 | "kind": "build", 16 | "isDefault": true 17 | } 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | out/test/** 4 | test/** 5 | src/** 6 | **/*.map 7 | .gitignore 8 | tsconfig.json 9 | vsc-extension-quickstart.md 10 | **/tsconfig.json 11 | **/.eslintrc.json 12 | **/*.map 13 | **/*.ts 14 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # [1.1.0](https://github.com/KnisterPeter/vscode-commitizen/compare/v1.0.3...v1.1.0) (2022-02-15) 2 | 3 | 4 | ### Features 5 | 6 | * icon from commitizen/cz-cli as command icon ([be78942](https://github.com/KnisterPeter/vscode-commitizen/commit/be78942dd04eb640af0c53f2e1d3e185da36ab51)) 7 | 8 | 9 | 10 | ## [1.0.3](https://github.com/KnisterPeter/vscode-commitizen/compare/v1.0.2...v1.0.3) (2022-01-12) 11 | 12 | 13 | ### Bug Fixes 14 | 15 | * **bug:** make 'scope' skippable if found in skipQuestions ([1ee71b5](https://github.com/KnisterPeter/vscode-commitizen/commit/1ee71b522a5b604d8c47b45545d690c3245a4a1c)), closes [#672](https://github.com/KnisterPeter/vscode-commitizen/issues/672) 16 | 17 | 18 | 19 | ## [1.0.2](https://github.com/KnisterPeter/vscode-commitizen/compare/v1.0.1...v1.0.2) (2021-11-11) 20 | 21 | 22 | ### Bug Fixes 23 | 24 | * **bug:** add body in section message commit ([#616](https://github.com/KnisterPeter/vscode-commitizen/issues/616)) ([1967b88](https://github.com/KnisterPeter/vscode-commitizen/commit/1967b8855e686ab5f0a6484d2cbc0f331b383fd0)) 25 | 26 | 27 | 28 | ## [1.0.1](https://github.com/KnisterPeter/vscode-commitizen/compare/v1.0.0...v1.0.1) (2021-08-30) 29 | 30 | 31 | ### Bug Fixes 32 | 33 | * revert vscode typings ([0d7bd35](https://github.com/KnisterPeter/vscode-commitizen/commit/0d7bd35146c90a7f525de7e73ec986f948fec95b)) 34 | 35 | 36 | 37 | # [1.0.0](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.15.1...v1.0.0) (2021-08-30) 38 | 39 | 40 | ### Bug Fixes 41 | 42 | * **commit:** fix missing body and footer message ([#579](https://github.com/KnisterPeter/vscode-commitizen/issues/579)) ([8857f85](https://github.com/KnisterPeter/vscode-commitizen/commit/8857f8536ba9eaa0f3618ff6da79447da2388d18)), closes [#443](https://github.com/KnisterPeter/vscode-commitizen/issues/443) [#527](https://github.com/KnisterPeter/vscode-commitizen/issues/527) 43 | 44 | 45 | ### BREAKING CHANGES 46 | 47 | * **commit:** remove quoteMessageInGitCommit option 48 | 49 | 50 | 51 | ## [0.15.1](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.15.0...v0.15.1) (2021-07-26) 52 | 53 | 54 | 55 | # [0.15.0](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.14.1...v0.15.0) (2021-07-26) 56 | 57 | 58 | ### Features 59 | 60 | * add option to sign and verify commits ([#551](https://github.com/KnisterPeter/vscode-commitizen/issues/551)) ([5d0fc90](https://github.com/KnisterPeter/vscode-commitizen/commit/5d0fc90266eb9f1309ab68a36be53d6a20b79722)) 61 | * **icon:** add an icon beside the git scm ([#537](https://github.com/KnisterPeter/vscode-commitizen/issues/537)) ([4303d38](https://github.com/KnisterPeter/vscode-commitizen/commit/4303d385e2987799c3862f7e1d05e642bd3bf638)) 62 | 63 | 64 | 65 | ## [0.14.1](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.14.0...v0.14.1) (2021-04-16) 66 | 67 | 68 | ### Bug Fixes 69 | 70 | * gitroot only worked once ([#483](https://github.com/KnisterPeter/vscode-commitizen/issues/483)) ([858d6bc](https://github.com/KnisterPeter/vscode-commitizen/commit/858d6bc72a3e043da0b971aadb19d78ef738323f)) 71 | 72 | 73 | 74 | # [0.14.0](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.13.1...v0.14.0) (2021-04-14) 75 | 76 | 77 | ### Features 78 | 79 | * remove the error message ([#479](https://github.com/KnisterPeter/vscode-commitizen/issues/479)) ([4b141c3](https://github.com/KnisterPeter/vscode-commitizen/commit/4b141c3881c64c127b141dac7330e6a1dddd57a9)) 80 | 81 | 82 | 83 | ## [0.13.1](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.13.0...v0.13.1) (2021-04-14) 84 | 85 | 86 | 87 | # [0.13.0](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.12.1...v0.13.0) (2021-04-14) 88 | 89 | 90 | ### Bug Fixes 91 | 92 | * error cyclomatic-complexity ([d64b210](https://github.com/KnisterPeter/vscode-commitizen/commit/d64b2101d7396c48599596869260878772a5bcea)) 93 | * repeated calls to the findLookupPath function ([a8a34e1](https://github.com/KnisterPeter/vscode-commitizen/commit/a8a34e17ee5d91e63c476d4af681647bf8688b4d)) 94 | 95 | 96 | ### Features 97 | 98 | * add support multi folders ([8a2f5a3](https://github.com/KnisterPeter/vscode-commitizen/commit/8a2f5a330ca6ff2788c6a07b69ce95100b7c9a31)) 99 | 100 | 101 | 102 | ## [0.12.1](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.12.0...v0.12.1) (2021-02-17) 103 | 104 | 105 | ### Bug Fixes 106 | 107 | * add cwd for git path context ([3c3f519](https://github.com/KnisterPeter/vscode-commitizen/commit/3c3f5197e828f66a86ebff8af0129155b35bf052)), closes [#429](https://github.com/KnisterPeter/vscode-commitizen/issues/429) 108 | 109 | 110 | 111 | # [0.12.0](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.11.1...v0.12.0) (2021-02-11) 112 | 113 | 114 | ### Features 115 | 116 | * add git top level option ([#420](https://github.com/KnisterPeter/vscode-commitizen/issues/420)) ([9fb6f0c](https://github.com/KnisterPeter/vscode-commitizen/commit/9fb6f0cb921ad47bcf6d8f95341966c4e0689ea5)) 117 | 118 | 119 | 120 | ## [0.11.1](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.11.0...v0.11.1) (2021-02-11) 121 | 122 | 123 | ### Bug Fixes 124 | 125 | * rollback vscode types ([6285234](https://github.com/KnisterPeter/vscode-commitizen/commit/6285234c9da9b9bc51b465d871f45f800cda1685)) 126 | 127 | 128 | 129 | # [0.11.0](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.10.2...v0.11.0) (2021-02-11) 130 | 131 | 132 | ### Features 133 | 134 | * add shell option ([926aa74](https://github.com/KnisterPeter/vscode-commitizen/commit/926aa74d19e75299d8ee3c60f626f4c98b97502e)), closes [#325](https://github.com/KnisterPeter/vscode-commitizen/issues/325) 135 | 136 | 137 | 138 | ## [0.10.2](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.10.1...v0.10.2) (2021-02-02) 139 | 140 | 141 | ### Bug Fixes 142 | 143 | * bug allowBreakingChanges ([15bd0a0](https://github.com/KnisterPeter/vscode-commitizen/commit/15bd0a04d0f2888ce3b79f9c3a8b4749f0364d67)) 144 | 145 | 146 | 147 | ## [0.10.1](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.10.0...v0.10.1) (2021-01-25) 148 | 149 | 150 | 151 | # [0.10.0](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.9.3...v0.10.0) (2021-01-25) 152 | 153 | 154 | ### Bug Fixes 155 | 156 | * **deps:** update dependency execa to v5 ([3354396](https://github.com/KnisterPeter/vscode-commitizen/commit/3354396afed20b7a7eb4fa98e6b41b9cb09ecdab)) 157 | * Cannot read property 'czConfig' of undefined ([#222](https://github.com/KnisterPeter/vscode-commitizen/issues/222)) ([#327](https://github.com/KnisterPeter/vscode-commitizen/issues/327)) ([bf1b0ba](https://github.com/KnisterPeter/vscode-commitizen/commit/bf1b0ba29c2dfce34b5bc455ede4f9a453e2f5ef)) 158 | 159 | 160 | ### Features 161 | 162 | * consider allowBreakingChanges ([6f07e60](https://github.com/KnisterPeter/vscode-commitizen/commit/6f07e60cde41d8f9d9241013d24f68229cfdd5fa)) 163 | 164 | 165 | 166 | ## [0.9.3](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.9.2...v0.9.3) (2020-07-21) 167 | 168 | 169 | ### Bug Fixes 170 | 171 | * git shellout ([d275e4c](https://github.com/KnisterPeter/vscode-commitizen/commit/d275e4cb85a2a218d30aa29a3d8a70d4d0577482)), closes [#313](https://github.com/KnisterPeter/vscode-commitizen/issues/313) 172 | 173 | 174 | 175 | 176 | ## [0.9.2](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.8.4...v0.9.2) (2020-07-10) 177 | 178 | 179 | ### Bug Fixes 180 | 181 | * correct minimal code version ([95dc509](https://github.com/KnisterPeter/vscode-commitizen/commit/95dc509)) 182 | 183 | 184 | 185 | 186 | ## [0.9.1](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.8.4...v0.9.1) (2020-07-10) 187 | 188 | 189 | 190 | # [0.9.0](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.8.4...v0.9.0) (2020-07-09) 191 | 192 | 193 | ### Bug Fixes 194 | 195 | * **deps:** update dependency execa to v3 ([509a8dc](https://github.com/KnisterPeter/vscode-commitizen/commit/509a8dc0da22ed88882a53f406f288b8900c6311)) 196 | * **deps:** update dependency execa to v4 ([10bfe12](https://github.com/KnisterPeter/vscode-commitizen/commit/10bfe1218d1472eb8c55c9fdeffb00ffbb393487)) 197 | * **deps:** update dependency wrap-ansi to v7 ([f055902](https://github.com/KnisterPeter/vscode-commitizen/commit/f05590216ed8cb7500907b137923dfb351b56bbe)) 198 | * includeif with lowercase drive letter ([#296](https://github.com/KnisterPeter/vscode-commitizen/issues/296)) ([#297](https://github.com/KnisterPeter/vscode-commitizen/issues/297)) ([3ac91b3](https://github.com/KnisterPeter/vscode-commitizen/commit/3ac91b39dcd30603014c3b8fed54b62a11aed73a)) 199 | * wrap commit message in quotes ([4cf64c2](https://github.com/KnisterPeter/vscode-commitizen/commit/4cf64c28511250a3191eb8695aa8307f584a4068)), closes [#215](https://github.com/KnisterPeter/vscode-commitizen/issues/215) 200 | 201 | 202 | ### Features 203 | 204 | * add option to toggle quoting the git message ([faa5dae](https://github.com/KnisterPeter/vscode-commitizen/commit/faa5daef4e5b9eaef45d46937df40f7901522c4e)), closes [#215](https://github.com/KnisterPeter/vscode-commitizen/issues/215) 205 | 206 | 207 | # [0.8.4](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.8.3...v0.8.4) (2019-10-11) 208 | 209 | 210 | ### Bug Fixes 211 | 212 | * **linter:** Refactor to reduce complexity ([6ab8fd9](https://github.com/KnisterPeter/vscode-commitizen/commit/6ab8fd9)) 213 | 214 | 215 | ### Features 216 | 217 | * **questions:** Skip questions from cz-config ([1214d28](https://github.com/KnisterPeter/vscode-commitizen/commit/1214d28)) 218 | 219 | ### [0.8.3](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.8.2...v0.8.3) (2019-07-12) 220 | 221 | 222 | ### Bug Fixes 223 | 224 | * **config:** reads.cz-config.js filein root ([814ebdf](https://github.com/KnisterPeter/vscode-commitizen/commit/814ebdf)) 225 | * **deps:** update dependency execa to v2 ([e7a84f5](https://github.com/KnisterPeter/vscode-commitizen/commit/e7a84f5)) 226 | * **deps:** update dependency wrap-ansi to v5 ([dd7d588](https://github.com/KnisterPeter/vscode-commitizen/commit/dd7d588)) 227 | * **deps:** update dependency wrap-ansi to v6 ([5edbc71](https://github.com/KnisterPeter/vscode-commitizen/commit/5edbc71)) 228 | 229 | 230 | 231 | 232 | ## [0.8.2](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.8.1...v0.8.2) (2019-01-04) 233 | 234 | 235 | ### Bug Fixes 236 | 237 | * **messages:** fixes custom messages not loading ([3a423ec](https://github.com/KnisterPeter/vscode-commitizen/commit/3a423ec)) 238 | 239 | 240 | 241 | 242 | ## [0.8.1](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.8.0...v0.8.1) (2018-10-26) 243 | 244 | 245 | ### Bug Fixes 246 | 247 | * **commit:** custom scope with scopes ([0316fc5](https://github.com/KnisterPeter/vscode-commitizen/commit/0316fc5)) 248 | * fixed lint errors ([786d60b](https://github.com/KnisterPeter/vscode-commitizen/commit/786d60b)) 249 | 250 | 251 | 252 | 253 | # [0.8.0](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.7.0...v0.8.0) (2018-10-15) 254 | 255 | 256 | ### Features 257 | 258 | * **footer:** add ability for custom footer ([5d06c7a](https://github.com/KnisterPeter/vscode-commitizen/commit/5d06c7a)) 259 | 260 | 261 | 262 | 263 | # [0.7.0](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.6.0...v0.7.0) (2018-10-09) 264 | 265 | 266 | ### Features 267 | 268 | * **commit:** Auto-stage with enableSmartCommit ([1db4fd9](https://github.com/KnisterPeter/vscode-commitizen/commit/1db4fd9)), closes [#80](https://github.com/KnisterPeter/vscode-commitizen/issues/80) 269 | 270 | 271 | 272 | 273 | # [0.6.0](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.5.0...v0.6.0) (2018-09-23) 274 | 275 | 276 | ### Bug Fixes 277 | 278 | * **deps:** update dependency execa to ^0.11.0 ([061f117](https://github.com/KnisterPeter/vscode-commitizen/commit/061f117)) 279 | * **deps:** update dependency execa to v1 ([f8e0499](https://github.com/KnisterPeter/vscode-commitizen/commit/f8e0499)) 280 | * **package:** update execa to version 0.10.0 ([481ca84](https://github.com/KnisterPeter/vscode-commitizen/commit/481ca84)) 281 | * **package:** update execa to version 0.9.0 ([44721f4](https://github.com/KnisterPeter/vscode-commitizen/commit/44721f4)) 282 | 283 | 284 | ### Features 285 | 286 | * **messages:** add custom messages from cz-config ([a2dc633](https://github.com/KnisterPeter/vscode-commitizen/commit/a2dc633)) 287 | 288 | 289 | 290 | 291 | # [0.5.0](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.4.0...v0.5.0) (2017-10-05) 292 | 293 | 294 | ### Features 295 | 296 | * add output after commit ([19c7505](https://github.com/KnisterPeter/vscode-commitizen/commit/19c7505)), closes [#42](https://github.com/KnisterPeter/vscode-commitizen/issues/42) 297 | * allow to override subject length ([a8557b8](https://github.com/KnisterPeter/vscode-commitizen/commit/a8557b8)), closes [#41](https://github.com/KnisterPeter/vscode-commitizen/issues/41) 298 | 299 | 300 | 301 | 302 | # [0.4.0](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.3.10...v0.4.0) (2017-09-05) 303 | 304 | 305 | ### Bug Fixes 306 | 307 | * **package:** update execa to version 0.7.0 ([30b2170](https://github.com/KnisterPeter/vscode-commitizen/commit/30b2170)) 308 | * **package:** update execa to version 0.8.0 ([d917bea](https://github.com/KnisterPeter/vscode-commitizen/commit/d917bea)) 309 | * **package:** update wrap-ansi to version 3.0.0 ([493f227](https://github.com/KnisterPeter/vscode-commitizen/commit/493f227)) 310 | 311 | 312 | ### Features 313 | 314 | * add autoSync feature ([87d3a71](https://github.com/KnisterPeter/vscode-commitizen/commit/87d3a71)), closes [#39](https://github.com/KnisterPeter/vscode-commitizen/issues/39) 315 | 316 | 317 | 318 | 319 | ## [0.3.10](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.3.9...v0.3.10) (2017-04-12) 320 | 321 | 322 | ### Bug Fixes 323 | 324 | * do not add empty parenthesis if no scope given ([11a7e13](https://github.com/KnisterPeter/vscode-commitizen/commit/11a7e13)) 325 | 326 | 327 | 328 | 329 | ## [0.3.9](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.3.8...v0.3.9) (2017-04-05) 330 | 331 | 332 | ### Bug Fixes 333 | 334 | * allow multiple pipes to split ([0d62ef9](https://github.com/KnisterPeter/vscode-commitizen/commit/0d62ef9)), closes [#29](https://github.com/KnisterPeter/vscode-commitizen/issues/29) 335 | 336 | 337 | 338 | 339 | ## [0.3.8](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.3.7...v0.3.8) (2017-03-29) 340 | 341 | 342 | ### Bug Fixes 343 | 344 | * remove parenthesis without scope ([97aec9c](https://github.com/KnisterPeter/vscode-commitizen/commit/97aec9c)) 345 | 346 | 347 | 348 | 349 | ## [0.3.7](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.3.6...v0.3.7) (2017-03-28) 350 | 351 | 352 | ### Bug Fixes 353 | 354 | * **package:** update execa to version 0.6.1 ([fcd8049](https://github.com/KnisterPeter/vscode-commitizen/commit/fcd8049)) 355 | * **package:** update execa to version 0.6.2 ([3a3a27c](https://github.com/KnisterPeter/vscode-commitizen/commit/3a3a27c)) 356 | * **package:** update execa to version 0.6.3 ([b68fd58](https://github.com/KnisterPeter/vscode-commitizen/commit/b68fd58)) 357 | * notify user about error ([541bb8e](https://github.com/KnisterPeter/vscode-commitizen/commit/541bb8e)), closes [#25](https://github.com/KnisterPeter/vscode-commitizen/issues/25) 358 | 359 | 360 | 361 | 362 | ## [0.3.6](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.3.5...v0.3.6) (2017-03-12) 363 | 364 | 365 | ### Bug Fixes 366 | 367 | * **package:** update execa to version 0.5.1 ([e0a71a8](https://github.com/KnisterPeter/vscode-commitizen/commit/e0a71a8)) 368 | * **package:** update execa to version 0.6.0 ([6883734](https://github.com/KnisterPeter/vscode-commitizen/commit/6883734)) 369 | * support plain string scopes ([7e0ad50](https://github.com/KnisterPeter/vscode-commitizen/commit/7e0ad50)) 370 | * update dependencies ([cd7c487](https://github.com/KnisterPeter/vscode-commitizen/commit/cd7c487)) 371 | * update standard-linter config ([d678d02](https://github.com/KnisterPeter/vscode-commitizen/commit/d678d02)) 372 | 373 | 374 | 375 | 376 | ## [0.3.5](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.3.4...v0.3.5) (2016-12-05) 377 | 378 | 379 | ### Bug Fixes 380 | 381 | * invalid array access ([d059b37](https://github.com/KnisterPeter/vscode-commitizen/commit/d059b37)) 382 | 383 | 384 | 385 | 386 | ## [0.3.4](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.3.3...v0.3.4) (2016-12-02) 387 | 388 | 389 | ### Bug Fixes 390 | 391 | * test for custom scopes ([07231aa](https://github.com/KnisterPeter/vscode-commitizen/commit/07231aa)) 392 | 393 | 394 | 395 | 396 | ## [0.3.3](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.3.2...v0.3.3) (2016-12-02) 397 | 398 | 399 | ### Bug Fixes 400 | 401 | * do not close input if focus is lost ([1966396](https://github.com/KnisterPeter/vscode-commitizen/commit/1966396)) 402 | * use proper command namespace ([fa43433](https://github.com/KnisterPeter/vscode-commitizen/commit/fa43433)) 403 | 404 | 405 | 406 | 407 | ## [0.3.2](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.3.1...v0.3.2) (2016-11-30) 408 | 409 | 410 | ### Bug Fixes 411 | 412 | * wrap commit body at 72 characters ([d4089f9](https://github.com/KnisterPeter/vscode-commitizen/commit/d4089f9)) 413 | 414 | 415 | 416 | 417 | ## [0.3.1](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.3.0...v0.3.1) (2016-11-30) 418 | 419 | 420 | ### Bug Fixes 421 | 422 | * validate subject length to be at most 50 chars ([66993f6](https://github.com/KnisterPeter/vscode-commitizen/commit/66993f6)) 423 | 424 | 425 | 426 | 427 | # [0.3.0](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.2.1...v0.3.0) (2016-11-29) 428 | 429 | 430 | ### Features 431 | 432 | * start reading cz-config (types and scopes) ([24e12ad](https://github.com/KnisterPeter/vscode-commitizen/commit/24e12ad)) 433 | 434 | 435 | 436 | 437 | ## [0.2.1](https://github.com/KnisterPeter/vscode-commitizen/compare/v0.2.0...v0.2.1) (2016-11-28) 438 | 439 | 440 | ### Bug Fixes 441 | 442 | * commit should be cancelable ([b81cb30](https://github.com/KnisterPeter/vscode-commitizen/commit/b81cb30)) 443 | 444 | 445 | 446 | 447 | # 0.2.0 (2016-11-28) 448 | 449 | 450 | ### Features 451 | 452 | * implement hardcoded angular style commit conventions ([fc81416](https://github.com/KnisterPeter/vscode-commitizen/commit/fc81416)) 453 | * initial setup ([7d45724](https://github.com/KnisterPeter/vscode-commitizen/commit/7d45724)) 454 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Markus Wolf 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 | # vscode-commitizen README 2 | 3 | ![build](https://github.com/KnisterPeter/vscode-commitizen/workflows/build/badge.svg) 4 | [![Marketplace Version](https://vsmarketplacebadge.apphb.com/version/knisterpeter.vscode-commitizen.svg)](https://marketplace.visualstudio.com/items?itemName=KnisterPeter.vscode-commitizen) 5 | [![Installs](https://vsmarketplacebadge.apphb.com/installs/knisterpeter.vscode-commitizen.svg)](https://marketplace.visualstudio.com/items?itemName=KnisterPeter.vscode-commitizen) 6 | [![renovate badge](https://img.shields.io/badge/renovate-enabled-brightgreen.svg)](https://renovateapp.com/) 7 | 8 | This vscode extension adds [commitizen support](https://github.com/commitizen). 9 | 10 | ## Usage 11 | 12 | * Open the command panel (`ctrl+shift+p` or `command+shift+p`) and type 'conventional commit'. 13 | * Select the command and answer the questions afterwards (type, scope, subject, body, breaking changes, closed issues). 14 | * After the closed issues the commit is done automatically. 15 | * **Note**: During answering the questions just hit `ESC`to cancel the commit. 16 | 17 | ## Configuration 18 | 19 | To configure this extension follow [cz-customizable](https://github.com/leonardoanalista/cz-customizable) and 20 | create the required config file. This also read by this extension if configured. 21 | 22 | To determine what config to use, the extention will look for a config file in the following places: 23 | 24 | 1. a ```.cz-config.js``` in the root directory 25 | 2. in ```package.json``` to determine the path to the config file: 26 | ``` 27 | "config": { 28 | "cz-customizable": { 29 | "config": "test.js" 30 | } 31 | } 32 | ``` 33 | 3. use the default config 34 | 35 | ## Attributions 36 | 37 | [Commitizen logo](./images/commitizen-logo.svg) is a remixed version of the [logo created by authors of commitizen cz-cli repository](https://github.com/commitizen/cz-cli/blob/a3f4ffa88221013960cd9c6d8711b319016b9e2d/logo/commitizen-logo-color.svg), under MIT license. 38 | -------------------------------------------------------------------------------- /images/commitizen-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KnisterPeter/vscode-commitizen/274086dc61ae2d565c33f325504d39a890029377/images/commitizen-logo.png -------------------------------------------------------------------------------- /images/commitizen-logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vscode-commitizen", 3 | "displayName": "Visual Studio Code Commitizen Support", 4 | "description": "commitizen - git commit with conventions", 5 | "version": "1.1.0", 6 | "publisher": "KnisterPeter", 7 | "engines": { 8 | "vscode": "^1.55.0" 9 | }, 10 | "categories": [ 11 | "Other" 12 | ], 13 | "keywords": [ 14 | "git", 15 | "commit", 16 | "commitizen", 17 | "changelog", 18 | "conventional-changelog" 19 | ], 20 | "activationEvents": [ 21 | "onCommand:vscode-commitizen.commit" 22 | ], 23 | "main": "./out/extension", 24 | "contributes": { 25 | "configuration": { 26 | "title": "Commitizen configuration", 27 | "properties": { 28 | "commitizen.autoSync": { 29 | "type": "boolean", 30 | "default": false, 31 | "description": "Set to true to automatically sync commit with git (push and pull)." 32 | }, 33 | "commitizen.subjectLength": { 34 | "type": "number", 35 | "default": 50, 36 | "description": "Override the allowed commit message subject length." 37 | }, 38 | "commitizen.showOutputChannel": { 39 | "type": "string", 40 | "enum": [ 41 | "off", 42 | "always", 43 | "onError" 44 | ], 45 | "default": "onError", 46 | "description": "Open the output panel after commit." 47 | }, 48 | "commitizen.capitalizeWindowsDriveLetter": { 49 | "type": "boolean", 50 | "default": false, 51 | "description": "Set to true to capitalize the Windows drive letter in Git's working directory path. Git treats paths as case sensitive and may ignore [includeIf] attributes in your .gitconfig if drive letters are the wrong case." 52 | }, 53 | "commitizen.useGitRoot": { 54 | "type": "boolean", 55 | "default": false, 56 | "description": "Use git root to locate .cz-config.js file via `git rev-parse --show-toplevel`" 57 | }, 58 | "commitizen.shell": { 59 | "type": "boolean", 60 | "default": true, 61 | "description": "Set to true to runs file inside of a shell. Uses /bin/sh on UNIX and cmd.exe on Windows." 62 | }, 63 | "commitizen.signCommits": { 64 | "type": "boolean", 65 | "default": false, 66 | "description": "Set to true to sign commits by adding the -S flag" 67 | } 68 | } 69 | }, 70 | "commands": [ 71 | { 72 | "command": "vscode-commitizen.commit", 73 | "title": "Conventional Commits", 74 | "category": "Commitizen", 75 | "icon": "images/commitizen-logo.svg" 76 | } 77 | ], 78 | "menus": { 79 | "scm/title": [ 80 | { 81 | "when": "scmProvider == git", 82 | "command": "vscode-commitizen.commit", 83 | "group": "navigation" 84 | } 85 | ] 86 | } 87 | }, 88 | "scripts": { 89 | "linter": "tslint --project .", 90 | "pretest": "yarn vscode:prepublish && yarn linter", 91 | "test": "node ./out/test/runTest.js", 92 | "vscode:prepublish": "tsc -p ./", 93 | "compile": "tsc -watch -p ./", 94 | "publish-extension": "vsce publish --yarn --pat $VSCE_TOKEN $(node -e \"console.log(require('./package.json').version)\")" 95 | }, 96 | "devDependencies": { 97 | "@commitlint/cli": "16.3.0", 98 | "@commitlint/config-conventional": "16.2.4", 99 | "@knisterpeter/standard-tslint": "1.7.2", 100 | "@types/mocha": "9.1.1", 101 | "@types/node": "20.8.10", 102 | "@types/vscode": "1.83.1", 103 | "@types/wrap-ansi": "8.0.2", 104 | "glob": "8.1.0", 105 | "husky": "7.0.4", 106 | "mocha": "9.2.2", 107 | "prettier": "2.8.8", 108 | "shipjs": "0.26.3", 109 | "tslint": "6.1.3", 110 | "typescript": "4.9.5", 111 | "vsce": "1.103.1", 112 | "vscode-test": "1.6.1" 113 | }, 114 | "dependencies": { 115 | "execa": "^5.0.0", 116 | "sander": "^0.6.0", 117 | "wrap-ansi": "^7.0.0" 118 | }, 119 | "repository": { 120 | "type": "git", 121 | "url": "https://github.com/KnisterPeter/vscode-commitizen.git" 122 | }, 123 | "author": { 124 | "name": "Markus Wolf", 125 | "email": "knister.peter@shadowrun-clan.de" 126 | }, 127 | "license": "MIT", 128 | "icon": "images/commitizen-logo.png", 129 | "bugs": { 130 | "url": "https://github.com/KnisterPeter/vscode-commitizen/issues" 131 | }, 132 | "homepage": "https://github.com/KnisterPeter/vscode-commitizen", 133 | "commitlint": { 134 | "extends": [ 135 | "@commitlint/config-conventional" 136 | ] 137 | }, 138 | "husky": { 139 | "hooks": { 140 | "commit-msg": "commitlint -E HUSKY_GIT_PARAMS" 141 | } 142 | }, 143 | "prettier": { 144 | "singleQuote": true, 145 | "trailingComma": "none" 146 | }, 147 | "renovate": { 148 | "extends": [ 149 | "config:base" 150 | ], 151 | "lockFileMaintenance": { 152 | "enabled": true, 153 | "automerge": true 154 | }, 155 | "packageRules": [ 156 | { 157 | "depTypeList": [ 158 | "devDependencies" 159 | ], 160 | "updateTypes": [ 161 | "minor", 162 | "patch" 163 | ], 164 | "automerge": true 165 | }, 166 | { 167 | "packagePatterns": [ 168 | "^@types/" 169 | ], 170 | "excludePackagePatterns": [ 171 | "@types/vscode" 172 | ], 173 | "automerge": true 174 | } 175 | ] 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /ship.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | mergeStrategy: { toSameBranch: ["master"] }, 3 | buildCommand: ({}) => null, 4 | publishCommand: () => "yarn publish-extension", 5 | }; 6 | -------------------------------------------------------------------------------- /src/extension.ts: -------------------------------------------------------------------------------- 1 | import { exec } from 'child_process'; 2 | import execa from 'execa'; 3 | import { join } from 'path'; 4 | import * as sander from 'sander'; 5 | // tslint:disable-next-line:no-implicit-dependencies 6 | import * as vscode from 'vscode'; 7 | import wrap from 'wrap-ansi'; 8 | 9 | let channel: vscode.OutputChannel; 10 | 11 | interface Configuration { 12 | autoSync: boolean; 13 | subjectLength: number; 14 | showOutputChannel: 'off' | 'always' | 'onError'; 15 | capitalizeWindowsDriveLetter: boolean; 16 | useGitRoot: boolean; 17 | shell: boolean; 18 | signCommits: boolean; 19 | } 20 | 21 | function getConfiguration(): Configuration { 22 | const config = vscode.workspace 23 | .getConfiguration() 24 | .get('commitizen'); 25 | return config!; 26 | } 27 | 28 | export async function activate( 29 | context: vscode.ExtensionContext 30 | ): Promise { 31 | channel = vscode.window.createOutputChannel('commitizen'); 32 | channel.appendLine('Commitizen support started'); 33 | 34 | context.subscriptions.push( 35 | vscode.commands.registerCommand('vscode-commitizen.commit', async () => { 36 | const lookupPath = await findLookupPath(); 37 | if (lookupPath) { 38 | const czConfig = await readCzConfig(lookupPath); 39 | const ccm = new ConventionalCommitMessage(czConfig); 40 | await ccm.getType(); 41 | await ccm.getScope(); 42 | await ccm.getSubject(); 43 | await ccm.getBody(); 44 | await ccm.getBreaking(); 45 | await ccm.getFooter(); 46 | if (ccm.complete) { 47 | await commit(lookupPath, ccm.messages); 48 | } 49 | } else { 50 | channel.appendLine('Lookup path not found'); 51 | } 52 | }) 53 | ); 54 | } 55 | 56 | interface CzConfig { 57 | types: { 58 | value: string; 59 | name: string; 60 | }[]; 61 | scopes: { 62 | name?: string; 63 | }[]; 64 | messages: { 65 | type?: string; 66 | customScope?: string; 67 | scope?: string; 68 | subject?: string; 69 | body?: string; 70 | breaking?: string; 71 | footer?: string; 72 | }; 73 | allowCustomScopes: boolean; 74 | allowBreakingChanges: string[]; 75 | footerPrefix: string; 76 | skipQuestions?: string[]; 77 | } 78 | type Messages = { 79 | main: string; 80 | body: string; 81 | footer: string; 82 | }; 83 | 84 | let gitRoot: string | undefined = undefined; 85 | async function findLookupPath(): Promise { 86 | let ws = ''; 87 | if (!vscode.workspace.workspaceFolders) { 88 | return undefined; 89 | } else if (vscode.workspace.workspaceFolders.length > 1) { 90 | const repositories = {}; 91 | vscode.workspace.workspaceFolders.forEach( 92 | (folder: vscode.WorkspaceFolder) => { 93 | repositories[folder.name] = { 94 | label: folder.name, 95 | description: folder.uri.fsPath 96 | }; 97 | } 98 | ); 99 | 100 | const pickOptions: vscode.QuickPickOptions = { 101 | placeHolder: 'Select a folder', 102 | ignoreFocusOut: true, 103 | matchOnDescription: true, 104 | matchOnDetail: true 105 | }; 106 | const pick = await vscode.window.showQuickPick( 107 | Object.values(repositories), 108 | pickOptions 109 | ); 110 | 111 | if (pick) { 112 | ws = repositories[pick.label].description; 113 | } 114 | } else { 115 | ws = vscode.workspace.workspaceFolders[0].uri.fsPath; 116 | } 117 | 118 | if (getConfiguration().useGitRoot) { 119 | if (gitRoot === undefined) { 120 | gitRoot = await new Promise((resolve, reject) => 121 | exec( 122 | 'git rev-parse --show-toplevel', 123 | { cwd: ws }, 124 | (err, stdout, stderr) => { 125 | if (err) { 126 | reject({ err, stderr }); 127 | } else if (stdout) { 128 | channel.appendLine(`Found git root at: ${stdout}`); 129 | resolve(stdout.trim()); 130 | } else { 131 | reject({ err: 'Unable to find git root' }); 132 | } 133 | } 134 | ) 135 | ).catch((e) => { 136 | channel.appendLine(e.err.toString()); 137 | if (e.stderr) { 138 | channel.appendLine(e.stderr.toString()); 139 | } 140 | return undefined; 141 | }); 142 | } 143 | 144 | return gitRoot; 145 | } 146 | 147 | return ws; 148 | } 149 | 150 | async function readCzConfig(lookupPath: string): Promise { 151 | let configPath = join(lookupPath, '.cz-config.js'); 152 | 153 | if (await sander.exists(configPath)) { 154 | return require(configPath) as CzConfig; 155 | } 156 | const pkg = await readPackageJson(lookupPath); 157 | if (!pkg) { 158 | return undefined; 159 | } 160 | configPath = join(lookupPath, '.cz-config.js'); 161 | if (hasCzConfig(pkg)) { 162 | configPath = join(lookupPath, pkg.config['cz-customizable'].config); 163 | } 164 | if (!(await sander.exists(configPath))) { 165 | return undefined; 166 | } 167 | return require(configPath) as CzConfig; 168 | } 169 | 170 | async function readPackageJson( 171 | lookupPath: string 172 | ): Promise { 173 | const pkgPath = join(lookupPath, 'package.json'); 174 | if (!(await sander.exists(pkgPath))) { 175 | return undefined; 176 | } 177 | return JSON.parse(await sander.readFile(pkgPath)); 178 | } 179 | 180 | function hasCzConfig( 181 | pkg: any 182 | ): pkg is { config: { 'cz-customizable': { config: string } } } { 183 | return ( 184 | pkg.config && 185 | pkg.config['cz-customizable'] && 186 | pkg.config['cz-customizable'].config 187 | ); 188 | } 189 | 190 | async function askOneOf( 191 | question: string, 192 | picks: vscode.QuickPickItem[], 193 | save: (pick: vscode.QuickPickItem) => void, 194 | customLabel?: string, 195 | customQuestion?: string 196 | ): Promise { 197 | const pickOptions: vscode.QuickPickOptions = { 198 | placeHolder: question, 199 | ignoreFocusOut: true, 200 | matchOnDescription: true, 201 | matchOnDetail: true 202 | }; 203 | const pick = await vscode.window.showQuickPick(picks, pickOptions); 204 | if (pick && pick.label === customLabel && !!customQuestion) { 205 | const next = await ask(customQuestion || '', (input) => { 206 | save({ label: input, description: '' }); 207 | return true; 208 | }); 209 | return next; 210 | } 211 | if (pick === undefined) { 212 | return false; 213 | } 214 | save(pick); 215 | return true; 216 | } 217 | 218 | async function ask( 219 | question: string, 220 | save: (input: string) => void, 221 | validate?: (input: string) => string 222 | ): Promise { 223 | const options: vscode.InputBoxOptions = { 224 | placeHolder: question, 225 | ignoreFocusOut: true 226 | }; 227 | if (validate) { 228 | options.validateInput = validate; 229 | } 230 | const input = await vscode.window.showInputBox(options); 231 | if (input === undefined) { 232 | return false; 233 | } 234 | save(input); 235 | return true; 236 | } 237 | 238 | const DEFAULT_TYPES = [ 239 | { 240 | value: 'feat', 241 | name: 'A new feature' 242 | }, 243 | { 244 | value: 'fix', 245 | name: 'A bug fix' 246 | }, 247 | { 248 | value: 'docs', 249 | name: 'Documentation only changes' 250 | }, 251 | { 252 | value: 'style', 253 | name: 254 | 'Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)' 255 | }, 256 | { 257 | value: 'refactor', 258 | name: 'A code change that neither fixes a bug nor adds a feature' 259 | }, 260 | { 261 | value: 'perf', 262 | name: 'A code change that improves performance' 263 | }, 264 | { 265 | value: 'test', 266 | name: 'Adding missing tests or correcting existing tests' 267 | }, 268 | { 269 | value: 'build', 270 | name: 271 | 'Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)' 272 | }, 273 | { 274 | value: 'ci', 275 | name: 276 | 'Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)' 277 | }, 278 | { 279 | value: 'chore', 280 | name: "Other changes that don't modify src or test files" 281 | } 282 | ]; 283 | 284 | const DEFAULT_MESSAGES = { 285 | type: "Select the type of change that you're committing", 286 | customScope: 'Denote the SCOPE of this change', 287 | customScopeEntry: 'Custom scope...', 288 | scope: 'Denote the SCOPE of this change (optional)', 289 | subject: 'Write a SHORT, IMPERATIVE tense description of the change', 290 | body: 291 | 'Provide a LONGER description of the change (optional). Use "|" to break new line', 292 | breaking: 'List any BREAKING CHANGES (optional)', 293 | footer: 'List any ISSUES CLOSED by this change (optional). E.g.: #31, #34' 294 | }; 295 | 296 | const splitMessages = (message: string) => { 297 | const result: string[] = []; 298 | 299 | if (message.includes('|')) { 300 | message.split('|').forEach((msg) => { 301 | result.push('-m', `"${msg}"`); 302 | }); 303 | } else { 304 | result.push('-m', `"${message}"`); 305 | } 306 | 307 | return result; 308 | }; 309 | 310 | const buildCommitArguments = (message: Messages): string[] => { 311 | const messageArguments = ['-m', `"${message.main}"`]; 312 | 313 | if (message.body) { 314 | messageArguments.push(...splitMessages(message.body)); 315 | } 316 | 317 | if (message.footer) { 318 | messageArguments.push(...splitMessages(message.footer)); 319 | } 320 | 321 | const signArgument = getConfiguration().signCommits ? ['-S'] : []; 322 | 323 | return [...messageArguments, ...signArgument]; 324 | }; 325 | 326 | async function commit(cwd: string, message: Messages): Promise { 327 | 328 | channel.appendLine(`About to commit '${message.main}'`); 329 | 330 | try { 331 | await conditionallyStageFiles(cwd); 332 | const result = await execa('git', ['commit', ...buildCommitArguments(message)], { 333 | cwd: getGitCwd(cwd), 334 | preferLocal: false, 335 | shell: getConfiguration().shell 336 | }); 337 | if (getConfiguration().autoSync) { 338 | await execa('git', ['sync'], { cwd }); 339 | } 340 | if (hasOutput(result)) { 341 | result.stdout.split('\n').forEach((line) => channel.appendLine(line)); 342 | if (shouldShowOutput(result)) { 343 | channel.show(); 344 | } 345 | } 346 | } catch (e: any) { 347 | vscode.window.showErrorMessage(e.message); 348 | channel.appendLine(e.message); 349 | channel.appendLine(e.stack); 350 | } 351 | } 352 | 353 | function hasOutput(result?: { stdout?: string }): boolean { 354 | return Boolean(result && result.stdout); 355 | } 356 | 357 | function shouldShowOutput(result: { exitCode: number }): boolean { 358 | return ( 359 | getConfiguration().showOutputChannel === 'always' || 360 | (getConfiguration().showOutputChannel === 'onError' && result.exitCode > 0) 361 | ); 362 | } 363 | 364 | async function conditionallyStageFiles(cwd: string): Promise { 365 | const hasSmartCommitEnabled = 366 | vscode.workspace 367 | .getConfiguration('git') 368 | .get('enableSmartCommit') === true; 369 | 370 | if (hasSmartCommitEnabled && !(await hasStagedFiles(cwd))) { 371 | channel.appendLine( 372 | 'Staging all files (enableSmartCommit enabled with nothing staged)' 373 | ); 374 | await execa('git', ['add', '.'], { 375 | cwd 376 | }); 377 | } 378 | } 379 | 380 | async function hasStagedFiles(cwd: string): Promise { 381 | const result = await execa('git', ['diff', '--name-only', '--cached'], { 382 | cwd 383 | }); 384 | return hasOutput(result); 385 | } 386 | 387 | class ConventionalCommitMessage { 388 | private static shouldSkip( 389 | czConfig: CzConfig | undefined, 390 | messageType: string 391 | ): boolean { 392 | return Boolean( 393 | czConfig && 394 | czConfig.skipQuestions && 395 | czConfig.skipQuestions.includes(messageType) 396 | ); 397 | } 398 | 399 | private static hasScopes( 400 | czConfig: CzConfig | undefined 401 | ): czConfig is CzConfig { 402 | return Boolean(czConfig && czConfig.scopes && czConfig.scopes.length !== 0); 403 | } 404 | 405 | private static hasCustomMessage( 406 | czConfig: CzConfig | undefined, 407 | messageType: string 408 | ): czConfig is CzConfig { 409 | return Boolean( 410 | czConfig && 411 | czConfig.messages && 412 | czConfig.messages.hasOwnProperty(messageType) 413 | ); 414 | } 415 | 416 | private static getScopePicks( 417 | czConfig: CzConfig, 418 | allowCustomScopesLabel: string 419 | ): { label: string; description: string }[] { 420 | const scopePicks = czConfig.scopes.map((scope) => ({ 421 | label: scope.name || (scope as string), 422 | description: '' 423 | })); 424 | if (czConfig.allowCustomScopes) { 425 | scopePicks.push({ 426 | label: allowCustomScopesLabel, 427 | description: '' 428 | }); 429 | } 430 | return scopePicks; 431 | } 432 | 433 | private static allowBreakingChanges( 434 | czConfig: CzConfig | undefined, 435 | selectedType: string | undefined 436 | ): boolean { 437 | if (czConfig?.allowBreakingChanges && selectedType) { 438 | return czConfig?.allowBreakingChanges.some( 439 | (type: string) => type === selectedType 440 | ); 441 | } 442 | 443 | return true; 444 | } 445 | 446 | private readonly czConfig: CzConfig | undefined; 447 | private next = true; 448 | 449 | private type?: string; 450 | private scope: string | undefined; 451 | private subject?: string; 452 | private body: string | undefined; 453 | private breaking: string | undefined; 454 | private footer: string | undefined; 455 | 456 | constructor(czConfig: CzConfig | undefined) { 457 | this.czConfig = czConfig; 458 | } 459 | 460 | public async getType(): Promise { 461 | if (this.next) { 462 | const types = (this.czConfig && this.czConfig.types) || DEFAULT_TYPES; 463 | const typePicks = types.map((type) => ({ 464 | label: type.value, 465 | description: type.name 466 | })); 467 | this.next = await askOneOf( 468 | this.inputMessage('type'), 469 | typePicks, 470 | (pick) => (this.type = pick.label) 471 | ); 472 | } 473 | } 474 | 475 | public async getScope(): Promise { 476 | if (this.next && !ConventionalCommitMessage.shouldSkip(this.czConfig, 'scope')) { 477 | if ( 478 | ConventionalCommitMessage.hasScopes(this.czConfig) 479 | ) { 480 | if (this.czConfig.scopes && this.czConfig.scopes[0] !== undefined) { 481 | const scopePicks = ConventionalCommitMessage.getScopePicks( 482 | this.czConfig, 483 | this.inputMessage('customScopeEntry') 484 | ); 485 | this.next = await askOneOf( 486 | this.inputMessage('customScope'), 487 | scopePicks, 488 | (pick) => { 489 | this.scope = pick.label || undefined; 490 | }, 491 | this.inputMessage('customScopeEntry'), 492 | this.inputMessage('customScope') 493 | ); 494 | } 495 | } else { 496 | this.next = await ask( 497 | this.inputMessage('scope'), 498 | (input) => (this.scope = input) 499 | ); 500 | } 501 | } 502 | } 503 | 504 | public async getSubject(): Promise { 505 | if (this.next) { 506 | const maxLength = getConfiguration().subjectLength; 507 | const validator = (input: string) => { 508 | if (input.length === 0 || input.length > maxLength) { 509 | return `Subject is required and must be less than ${maxLength} characters`; 510 | } 511 | return ''; 512 | }; 513 | this.next = await ask( 514 | this.inputMessage('subject'), 515 | (input) => (this.subject = input), 516 | validator 517 | ); 518 | } 519 | } 520 | 521 | public async getBody(): Promise { 522 | if ( 523 | this.next && 524 | !ConventionalCommitMessage.shouldSkip(this.czConfig, 'body') 525 | ) { 526 | this.next = await ask( 527 | this.inputMessage('body'), 528 | (input) => 529 | (this.body = wrap(input, 72, { hard: true })) 530 | ); 531 | } 532 | } 533 | 534 | public async getBreaking(): Promise { 535 | if ( 536 | this.next && 537 | !ConventionalCommitMessage.shouldSkip(this.czConfig, 'breaking') && 538 | ConventionalCommitMessage.allowBreakingChanges(this.czConfig, this.type) 539 | ) { 540 | this.next = await ask( 541 | this.inputMessage('breaking'), 542 | (input) => (this.breaking = input) 543 | ); 544 | } 545 | } 546 | 547 | public async getFooter(): Promise { 548 | if ( 549 | this.next && 550 | !ConventionalCommitMessage.shouldSkip(this.czConfig, 'footer') 551 | ) { 552 | this.next = await ask( 553 | this.inputMessage('footer'), 554 | (input) => (this.footer = input) 555 | ); 556 | } 557 | } 558 | 559 | public get complete(): boolean { 560 | return this.next && Boolean(this.type) && Boolean(this.subject); 561 | } 562 | 563 | public get messages(): Messages { 564 | const main = `${this.type}${typeof this.scope === 'string' && this.scope ? 565 | `(${this.scope})` : '' 566 | }: ${this.subject}`; 567 | const body = `${this.body}`; 568 | const footer = `${this.breaking ? `BREAKING CHANGE: ${this.breaking}|` : ''}${this.messageFooter()}`; 569 | 570 | return { 571 | main, 572 | body, 573 | footer 574 | }; 575 | } 576 | 577 | private messageFooter(): string { 578 | return this.footer 579 | ? `${this.czConfig && this.czConfig.footerPrefix 580 | ? this.czConfig.footerPrefix 581 | : 'Closes ' 582 | }${this.footer}` 583 | : ''; 584 | } 585 | 586 | private inputMessage(messageType: string): string { 587 | return ConventionalCommitMessage.hasCustomMessage( 588 | this.czConfig, 589 | messageType 590 | ) 591 | ? this.czConfig.messages[messageType] 592 | : DEFAULT_MESSAGES[messageType]; 593 | } 594 | } 595 | 596 | function capitalizeWindowsDriveLetter(path: string): string { 597 | if (!path) { 598 | return path; 599 | } 600 | 601 | return path.replace(/(\w+?):/, (rootElement) => { 602 | return rootElement.toUpperCase(); 603 | }); 604 | } 605 | 606 | function getGitCwd(cwd: string): string { 607 | let cwdForGit = cwd; 608 | 609 | if (getConfiguration().capitalizeWindowsDriveLetter) { 610 | cwdForGit = capitalizeWindowsDriveLetter(cwd); 611 | } 612 | 613 | return cwdForGit; 614 | } 615 | -------------------------------------------------------------------------------- /src/test/runTest.ts: -------------------------------------------------------------------------------- 1 | import { execSync } from 'child_process'; 2 | import * as path from 'path'; 3 | // tslint:disable-next-line: no-implicit-dependencies 4 | import { runTests } from 'vscode-test'; 5 | 6 | async function runWorkspace(name: string): Promise { 7 | try { 8 | const extensionDevelopmentPath = path.resolve(__dirname, '../../'); 9 | const extensionTestsPath = path.resolve(__dirname, `./${name}/index`); 10 | const workspace = path.resolve( 11 | __dirname, 12 | `../../src/test/${name}/workspace` 13 | ); 14 | 15 | execSync('yarn install', { 16 | cwd: workspace 17 | }); 18 | 19 | await runTests({ 20 | extensionDevelopmentPath, 21 | extensionTestsPath, 22 | launchArgs: ['--disable-extensions', workspace] 23 | }); 24 | } catch (err) { 25 | console.error(`Failed to run tests '${name}'`); 26 | process.exit(1); 27 | } 28 | } 29 | 30 | async function main(): Promise { 31 | await runWorkspace('workspace'); 32 | } 33 | 34 | main().catch((e) => { 35 | setImmediate(() => { 36 | throw e; 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /src/test/workspace/extension.test.ts: -------------------------------------------------------------------------------- 1 | import * as assert from 'assert'; 2 | 3 | describe('Extension Test with webpack in workspace', () => { 4 | it('should be activated by default', () => { 5 | assert.strictEqual(-1, [1, 2, 3].indexOf(5)); 6 | assert.strictEqual(-1, [1, 2, 3].indexOf(0)); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /src/test/workspace/index.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable-next-line: no-implicit-dependencies 2 | import glob from 'glob'; 3 | // tslint:disable-next-line: no-implicit-dependencies 4 | import Mocha from 'mocha'; 5 | import * as path from 'path'; 6 | 7 | export async function run(): Promise { 8 | const mocha = new Mocha({ 9 | color: true, 10 | timeout: 10 * 1000 11 | }); 12 | 13 | const testsRoot = path.resolve(__dirname); 14 | 15 | return new Promise((resolve, reject) => { 16 | glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { 17 | if (err) { 18 | return reject(err); 19 | } 20 | 21 | files.forEach((f) => mocha.addFile(path.resolve(testsRoot, f))); 22 | 23 | try { 24 | mocha.run((failures) => { 25 | if (failures > 0) { 26 | reject(new Error(`${failures} tests failed.`)); 27 | } else { 28 | resolve(); 29 | } 30 | }); 31 | } catch (err) { 32 | console.error(err); 33 | reject(err); 34 | } 35 | }); 36 | }); 37 | } 38 | -------------------------------------------------------------------------------- /src/test/workspace/workspace/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | out 3 | -------------------------------------------------------------------------------- /src/test/workspace/workspace/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "simple", 4 | "version": "0.0.1" 5 | } 6 | -------------------------------------------------------------------------------- /src/test/workspace/workspace/src/index.js: -------------------------------------------------------------------------------- 1 | console.log('Hello World!'); 2 | -------------------------------------------------------------------------------- /src/test/workspace/workspace/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "outDir": "out", 6 | "lib": ["ESNext"], 7 | "sourceMap": true, 8 | "rootDir": "src", 9 | "strict": true, 10 | "noImplicitReturns": true, 11 | "noFallthroughCasesInSwitch": true, 12 | "noUnusedParameters": true, 13 | "suppressImplicitAnyIndexErrors": true, 14 | "esModuleInterop": true, 15 | "forceConsistentCasingInFileNames": true, 16 | "importsNotUsedAsValues": "error", 17 | "moduleResolution": "Node", 18 | "noImplicitAny": true, 19 | "noImplicitThis": true, 20 | "noUnusedLocals": true 21 | }, 22 | "exclude": ["node_modules", ".vscode-test"] 23 | } 24 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@knisterpeter/standard-tslint", 3 | "rules": { 4 | "await-promise": [true, "Thenable"], 5 | "space-before-function-paren": [false] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /typings/sander.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'sander' { 2 | export function readFile(path: string): Promise; 3 | export function exists(path: string): Promise; 4 | } 5 | --------------------------------------------------------------------------------