diff --git a/.github/workflows/stale.yaml b/.github/workflows/stale.yaml index 8de703ba8b26..5ee4d73e0ea9 100644 --- a/.github/workflows/stale.yaml +++ b/.github/workflows/stale.yaml @@ -10,7 +10,7 @@ jobs: issues: write pull-requests: write steps: - - uses: actions/stale@99b6c709598e2b0d0841cd037aaf1ba07a4410bd # tag=v5 + - uses: actions/stale@3de2653986ebd134983c79fe2be5d45cc3d9f4e1 # tag=v6 with: repo-token: ${{ secrets.GITHUB_TOKEN }} days-before-stale: 90 diff --git a/bots/package.json b/bots/package.json index 8ad60ca572d3..6fb5a0f18018 100644 --- a/bots/package.json +++ b/bots/package.json @@ -7,6 +7,6 @@ "main": "index.js", "license": "MIT", "devDependencies": { - "danger": "11.1.2" + "danger": "11.1.4" } } diff --git a/bots/yarn.lock b/bots/yarn.lock index 9c7374e7044c..3b84fa407da7 100644 --- a/bots/yarn.lock +++ b/bots/yarn.lock @@ -2,6 +2,36 @@ # yarn lockfile v1 +"@gitbeaker/core@^21.7.0": + version "21.7.0" + resolved "https://registry.yarnpkg.com/@gitbeaker/core/-/core-21.7.0.tgz#fcf7a12915d39f416e3f316d0a447a814179b8e5" + integrity sha512-cw72rE7tA27wc6JJe1WqeAj9v/6w0S7XJcEji+bRNjTlUfE1zgfW0Gf1mbGUi7F37SOABGCosQLfg9Qe63aIqA== + dependencies: + "@gitbeaker/requester-utils" "^21.7.0" + form-data "^3.0.0" + li "^1.3.0" + xcase "^2.0.1" + +"@gitbeaker/node@^21.3.0": + version "21.7.0" + resolved "https://registry.yarnpkg.com/@gitbeaker/node/-/node-21.7.0.tgz#2c19613f44ee497a8808c555abec614ebd2dfcad" + integrity sha512-OdM3VcTKYYqboOsnbiPcO0XimXXpYK4gTjARBZ6BWc+1LQXKmqo+OH6oUbyxOoaFu9hHECafIt3WZU3NM4sZTg== + dependencies: + "@gitbeaker/core" "^21.7.0" + "@gitbeaker/requester-utils" "^21.7.0" + form-data "^3.0.0" + got "^11.1.4" + xcase "^2.0.1" + +"@gitbeaker/requester-utils@^21.7.0": + version "21.7.0" + resolved "https://registry.yarnpkg.com/@gitbeaker/requester-utils/-/requester-utils-21.7.0.tgz#e9a9cfaf268d2a99eb7bbdc930943240a5f88878" + integrity sha512-eLTaVXlBnh8Qimj6QuMMA06mu/mLcJm3dy8nqhhn/Vm/D25sPrvpGwmbfFyvzj6QujPqtHvFfsCHtyZddL01qA== + dependencies: + form-data "^3.0.0" + query-string "^6.12.1" + xcase "^2.0.1" + "@octokit/auth-token@^2.4.4": version "2.5.0" resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-2.5.0.tgz#27c37ea26c205f28443402477ffd261311f21e36" @@ -103,19 +133,63 @@ dependencies: "@octokit/openapi-types" "^12.11.0" -abort-controller@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" - integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== +"@sindresorhus/is@^4.0.0": + version "4.6.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f" + integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw== + +"@szmarczak/http-timer@^4.0.5": + version "4.0.6" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807" + integrity sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w== dependencies: - event-target-shim "^5.0.0" + defer-to-connect "^2.0.0" -agent-base@4, agent-base@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" - integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== +"@tootallnate/once@2": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" + integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== + +"@types/cacheable-request@^6.0.1": + version "6.0.2" + resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.2.tgz#c324da0197de0a98a2312156536ae262429ff6b9" + integrity sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA== + dependencies: + "@types/http-cache-semantics" "*" + "@types/keyv" "*" + "@types/node" "*" + "@types/responselike" "*" + +"@types/http-cache-semantics@*": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz#0ea7b61496902b95890dc4c3a116b60cb8dae812" + integrity sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ== + +"@types/keyv@*": + version "3.1.4" + resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.4.tgz#3ccdb1c6751b0c7e52300bcdacd5bcbf8faa75b6" + integrity sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg== + dependencies: + "@types/node" "*" + +"@types/node@*": + version "18.7.23" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.23.tgz#75c580983846181ebe5f4abc40fe9dfb2d65665f" + integrity sha512-DWNcCHolDq0ZKGizjx2DZjR/PqsYwAcYUJmfMWqtVU2MBMG5Mo+xFZrhGId5r/O5HOuMPyQEcM6KUBp5lBZZBg== + +"@types/responselike@*", "@types/responselike@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29" + integrity sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA== + dependencies: + "@types/node" "*" + +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== dependencies: - es6-promisify "^5.0.0" + debug "4" ansi-styles@^3.2.1: version "3.2.1" @@ -153,6 +227,24 @@ buffer-equal-constant-time@1.0.1: resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA== +cacheable-lookup@^5.0.3: + version "5.0.4" + resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005" + integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA== + +cacheable-request@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.2.tgz#ea0d0b889364a25854757301ca12b2da77f91d27" + integrity sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^4.0.0" + lowercase-keys "^2.0.0" + normalize-url "^6.0.1" + responselike "^2.0.0" + chalk@^2.3.0: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -162,6 +254,13 @@ chalk@^2.3.0: escape-string-regexp "^1.0.5" supports-color "^5.3.0" +clone-response@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.3.tgz#af2032aa47816399cf5f0a1d0db902f517abb8c3" + integrity sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA== + dependencies: + mimic-response "^1.0.0" + color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" @@ -179,7 +278,7 @@ colors@1.4.0: resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== -combined-stream@^1.0.6: +combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -196,11 +295,12 @@ core-js@^3.8.2: resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.24.1.tgz#cf7724d41724154010a6576b7b57d94c5d66e64f" integrity sha512-0QTBSYSUZ6Gq21utGzkfITDylE8jWC9Ne1D2MrhvlsZBI1x39OdDIVbzSqtgMndIy6BlHxBXpMGqzZmnztg2rg== -danger@11.1.2: - version "11.1.2" - resolved "https://registry.yarnpkg.com/danger/-/danger-11.1.2.tgz#6fa7807c8721e9f8a040252ae8a22db222b8c4e0" - integrity sha512-tlAyADE7BRHbnoAA7BB7RzcO/ZLvXMpnWms7dBT/Tm4ntxdbrTT6wCPO1qFcd5Jc9LfM0Iez3hKUSINtnPLH+g== +danger@11.1.4: + version "11.1.4" + resolved "https://registry.yarnpkg.com/danger/-/danger-11.1.4.tgz#db33fe9fb864c9a8d6e9e7a6a69072b0704c3697" + integrity sha512-2X6pbtz7r1RyRhpZpYUWA0L+NancQcjZ0krnoYS5lZxRYfZfG51g1zEUork33zwoUcSpL0BnlTlQQqcGvXhj2A== dependencies: + "@gitbeaker/node" "^21.3.0" "@octokit/rest" "^18.12.0" async-retry "1.2.3" chalk "^2.3.0" @@ -209,9 +309,8 @@ danger@11.1.2: debug "^4.1.1" fast-json-patch "^3.0.0-1" get-stdin "^6.0.0" - gitlab "^10.0.1" - http-proxy-agent "^2.1.0" - https-proxy-agent "^2.2.1" + http-proxy-agent "^5.0.0" + https-proxy-agent "^5.0.1" hyperlinker "^1.0.0" json5 "^2.1.0" jsonpointer "^5.0.0" @@ -239,21 +338,7 @@ danger@11.1.2: require-from-string "^2.0.2" supports-hyperlinks "^1.0.1" -debug@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== - dependencies: - ms "2.0.0" - -debug@^3.1.0: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -debug@^4.1.1: +debug@4, debug@^4.1.1: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -265,6 +350,18 @@ decode-uri-component@^0.2.0: resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" integrity sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og== +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + +defer-to-connect@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" + integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -282,28 +379,18 @@ ecdsa-sig-formatter@1.0.11: dependencies: safe-buffer "^5.0.1" -es6-promise@^4.0.3: - version "4.2.8" - resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" - integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== - -es6-promisify@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" - integrity sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ== +end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== dependencies: - es6-promise "^4.0.3" + once "^1.4.0" escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== -event-target-shim@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" - integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== - expand-tilde@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" @@ -335,13 +422,13 @@ filter-obj@^1.1.0: resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-1.1.0.tgz#9b311112bc6c6127a16e016c6c5d7f19e0805c5b" integrity sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ== -form-data@^2.5.0: - version "2.5.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" - integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== +form-data@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" + integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== dependencies: asynckit "^0.4.0" - combined-stream "^1.0.6" + combined-stream "^1.0.8" mime-types "^2.1.12" fs-exists-sync@^0.1.0: @@ -354,6 +441,13 @@ get-stdin@^6.0.0: resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" integrity sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g== +get-stream@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + git-config-path@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/git-config-path/-/git-config-path-1.0.1.tgz#6d33f7ed63db0d0e118131503bab3aca47d54664" @@ -363,18 +457,22 @@ git-config-path@^1.0.1: fs-exists-sync "^0.1.0" homedir-polyfill "^1.0.0" -gitlab@^10.0.1: - version "10.2.1" - resolved "https://registry.yarnpkg.com/gitlab/-/gitlab-10.2.1.tgz#1f5fb2c2bad08f95b7c7d91dd41805ab5eea3960" - integrity sha512-z+DxRF1C9uayVbocs9aJkJz+kGy14TSm1noB/rAIEBbXOkOYbjKxyuqJzt+0zeFpXFdgA0yq6DVVbvM7HIfGwg== - dependencies: - form-data "^2.5.0" - humps "^2.0.1" - ky "^0.12.0" - ky-universal "^0.3.0" - li "^1.3.0" - query-string "^6.8.2" - universal-url "^2.0.0" +got@^11.1.4: + version "11.8.5" + resolved "https://registry.yarnpkg.com/got/-/got-11.8.5.tgz#ce77d045136de56e8f024bebb82ea349bc730046" + integrity sha512-o0Je4NvQObAuZPHLFoRSkdG2lTgtcynqymzg2Vupdx6PorhaT5MCbIyXG6d4D94kk8ZG57QeosgdiqfJWhEhlQ== + dependencies: + "@sindresorhus/is" "^4.0.0" + "@szmarczak/http-timer" "^4.0.5" + "@types/cacheable-request" "^6.0.1" + "@types/responselike" "^1.0.0" + cacheable-lookup "^5.0.3" + cacheable-request "^7.0.2" + decompress-response "^6.0.0" + http2-wrapper "^1.0.0-beta.5.2" + lowercase-keys "^2.0.0" + p-cancelable "^2.0.0" + responselike "^2.0.0" has-flag@^2.0.0: version "2.0.0" @@ -386,11 +484,6 @@ has-flag@^3.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== -hasurl@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/hasurl/-/hasurl-1.0.0.tgz#e4c619097ae1e8fc906bee904ce47e94f5e1ea37" - integrity sha512-43ypUd3DbwyCT01UYpA99AEZxZ4aKtRxWGBHEIbjcOsUghd9YUON0C+JF6isNjaiwC/UF5neaUudy6JS9jZPZQ== - homedir-polyfill@^1.0.0, homedir-polyfill@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" @@ -398,26 +491,35 @@ homedir-polyfill@^1.0.0, homedir-polyfill@^1.0.1: dependencies: parse-passwd "^1.0.0" -http-proxy-agent@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405" - integrity sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg== +http-cache-semantics@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" + integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== + +http-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" + integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== dependencies: - agent-base "4" - debug "3.1.0" + "@tootallnate/once" "2" + agent-base "6" + debug "4" -https-proxy-agent@^2.2.1: - version "2.2.4" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b" - integrity sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg== +http2-wrapper@^1.0.0-beta.5.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d" + integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg== dependencies: - agent-base "^4.3.0" - debug "^3.1.0" + quick-lru "^5.1.1" + resolve-alpn "^1.0.0" -humps@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/humps/-/humps-2.0.1.tgz#dd02ea6081bd0568dc5d073184463957ba9ef9aa" - integrity sha512-E0eIbrFWUhwfXJmsbdjRQFQPrl5pTEoKlz163j1mTqqUnU9PgR4AgB8AIITzuB3vLBdxZXyZ9TDIrwB2OASz4g== +https-proxy-agent@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" + integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== + dependencies: + agent-base "6" + debug "4" hyperlinker@^1.0.0: version "1.0.0" @@ -444,6 +546,11 @@ is-plain-object@^5.0.0: resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + json5@^2.1.0: version "2.2.1" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" @@ -487,18 +594,12 @@ jws@^3.2.2: jwa "^1.4.1" safe-buffer "^5.0.1" -ky-universal@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/ky-universal/-/ky-universal-0.3.0.tgz#3fcbb0dd03da39b5f05100d9362a630d5e1d402e" - integrity sha512-CM4Bgb2zZZpsprcjI6DNYTaH3oGHXL2u7BU4DK+lfCuC4snkt9/WRpMYeKbBbXscvKkeqBwzzjFX2WwmKY5K/A== +keyv@^4.0.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.0.tgz#dbce9ade79610b6e641a9a65f2f6499ba06b9bc6" + integrity sha512-2YvuMsA+jnFGtBareKqgANOEKe1mk3HKiXu2fRmAfyxG0MJAywNhi5ttWA3PMjl4NmpyjZNbFifR2vNjW1znfA== dependencies: - abort-controller "^3.0.0" - node-fetch "^2.6.0" - -ky@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/ky/-/ky-0.12.0.tgz#c05be95e6745ba422a6d2cc8ae964164962279f9" - integrity sha512-t9b7v3V2fGwAcQnnDDQwKQGF55eWrf4pwi1RN08Fy8b/9GEwV7Ea0xQiaSW6ZbeghBHIwl8kgnla4vVo9seepQ== + json-buffer "3.0.1" li@^1.3.0: version "1.3.0" @@ -565,10 +666,10 @@ lodash.once@^4.0.0: resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== -lodash.sortby@^4.7.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" - integrity sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA== +lowercase-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" + integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== memfs-or-file-map-to-github-branch@^1.2.1: version "1.2.1" @@ -597,16 +698,21 @@ mime-types@^2.1.12: dependencies: mime-db "1.52.0" +mimic-response@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + minimist@^1.2.0: version "1.2.6" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== - ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" @@ -622,14 +728,19 @@ node-cleanup@^2.1.2: resolved "https://registry.yarnpkg.com/node-cleanup/-/node-cleanup-2.1.2.tgz#7ac19abd297e09a7f72a71545d951b517e4dde2c" integrity sha512-qN8v/s2PAJwGUtr1/hYTpNKlD6Y9rc4p8KSmJXyGdYGZsDGKXrGThikLFP9OCHFeLeEpQzPwiAtdIvBLqm//Hw== -node-fetch@^2.6.0, node-fetch@^2.6.7: +node-fetch@^2.6.7: version "2.6.7" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== dependencies: whatwg-url "^5.0.0" -once@^1.4.0: +normalize-url@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" + integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== + +once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== @@ -641,6 +752,11 @@ override-require@^1.1.1: resolved "https://registry.yarnpkg.com/override-require/-/override-require-1.1.1.tgz#6ae22fadeb1f850ffb0cf4c20ff7b87e5eb650df" integrity sha512-eoJ9YWxFcXbrn2U8FKT6RV+/Kj7fiGAB1VvHzbYKt8xM5ZuKZgCGvnHzDxmreEjcBH28ejg5MiOH4iyY1mQnkg== +p-cancelable@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf" + integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg== + p-limit@^2.1.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" @@ -702,12 +818,15 @@ prettyjson@^1.2.1: colors "1.4.0" minimist "^1.2.0" -punycode@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" -query-string@^6.8.2: +query-string@^6.12.1: version "6.14.1" resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.14.1.tgz#7ac2dca46da7f309449ba0f86b1fd28255b0c86a" integrity sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw== @@ -717,6 +836,11 @@ query-string@^6.8.2: split-on-first "^1.0.0" strict-uri-encode "^2.0.0" +quick-lru@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" + integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== + readline-sync@^1.4.9: version "1.4.10" resolved "https://registry.yarnpkg.com/readline-sync/-/readline-sync-1.4.10.tgz#41df7fbb4b6312d673011594145705bf56d8873b" @@ -732,6 +856,18 @@ require-from-string@^2.0.2: resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== +resolve-alpn@^1.0.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9" + integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g== + +responselike@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.1.tgz#9a0bc8fdc252f3fb1cca68b016591059ba1422bc" + integrity sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw== + dependencies: + lowercase-keys "^2.0.0" + retry@0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" @@ -779,26 +915,11 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -tr46@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" - integrity sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA== - dependencies: - punycode "^2.1.0" - tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== -universal-url@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/universal-url/-/universal-url-2.0.0.tgz#35e7fc2c3374804905cee67ea289ed3a47669809" - integrity sha512-3DLtXdm/G1LQMCnPj+Aw7uDoleQttNHp2g5FnNQKR6cP6taNWS1b/Ehjjx4PVyvejKi3TJyu8iBraKM4q3JQPg== - dependencies: - hasurl "^1.0.0" - whatwg-url "^7.0.0" - universal-user-agent@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee" @@ -809,11 +930,6 @@ webidl-conversions@^3.0.0: resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== -webidl-conversions@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" - integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== - whatwg-url@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" @@ -822,20 +938,16 @@ whatwg-url@^5.0.0: tr46 "~0.0.3" webidl-conversions "^3.0.0" -whatwg-url@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" - integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== - dependencies: - lodash.sortby "^4.7.0" - tr46 "^1.0.1" - webidl-conversions "^4.0.2" - wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== +xcase@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/xcase/-/xcase-2.0.1.tgz#c7fa72caa0f440db78fd5673432038ac984450b9" + integrity sha512-UmFXIPU+9Eg3E9m/728Bii0lAIuoc+6nbrNUKaRPJOFp91ih44qqGlWtxMB6kXFrRD6po+86ksHM5XHCfk6iPw== + xtend@~4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" diff --git a/detekt-core/src/main/resources/default-detekt-config.yml b/detekt-core/src/main/resources/default-detekt-config.yml index 764ba811aa5e..04d72e456a8e 100644 --- a/detekt-core/src/main/resources/default-detekt-config.yml +++ b/detekt-core/src/main/resources/default-detekt-config.yml @@ -419,8 +419,6 @@ potential-bugs: - 'java.util.HashSet' - 'java.util.LinkedHashMap' - 'java.util.HashMap' - DuplicateCaseInWhenExpression: - active: true ElseCaseInsteadOfExhaustiveWhen: active: false EqualsAlwaysReturnsTrueOrFalse: @@ -466,17 +464,14 @@ potential-bugs: MissingPackageDeclaration: active: false excludes: ['**/*.kts'] - MissingWhenCase: - active: true - allowElseExpression: true NullCheckOnMutableProperty: active: false NullableToStringCall: active: false - RedundantElseInWhen: - active: true UnconditionalJumpStatementInLoop: active: false + UnnecessaryNotNullCheck: + active: false UnnecessaryNotNullOperator: active: true UnnecessarySafeCall: @@ -499,6 +494,8 @@ potential-bugs: style: active: true + AlsoCouldBeApply: + active: false CanBeNonNullable: active: false CascadingCallWrapping: diff --git a/detekt-core/src/main/resources/deprecation.properties b/detekt-core/src/main/resources/deprecation.properties index acb37d82c7df..8f69beffb59a 100644 --- a/detekt-core/src/main/resources/deprecation.properties +++ b/detekt-core/src/main/resources/deprecation.properties @@ -1,7 +1,10 @@ complexity>LongParameterList>threshold=Use `functionThreshold` and `constructorThreshold` instead empty-blocks>EmptyFunctionBlock>ignoreOverriddenFunctions=Use `ignoreOverridden` instead +potential-bugs>DuplicateCaseInWhenExpression=Rule deprecated as compiler performs this check by default potential-bugs>IgnoredReturnValue>restrictToAnnotatedMethods=Use `restrictToConfig` instead potential-bugs>LateinitUsage>excludeAnnotatedProperties=Use `ignoreAnnotated` instead +potential-bugs>MissingWhenCase=Rule deprecated as compiler performs this check by default +potential-bugs>RedundantElseInWhen=Rule deprecated as compiler performs this check by default naming>FunctionParameterNaming>ignoreOverriddenFunctions=Use `ignoreOverridden` instead naming>MemberNameEqualsClassName>ignoreOverriddenFunction=Use `ignoreOverridden` instead style>FunctionOnlyReturningConstant>excludeAnnotatedFunction=Use `ignoreAnnotated` instead diff --git a/detekt-generator/build.gradle.kts b/detekt-generator/build.gradle.kts index 747a38e48a56..9c355eb7911f 100644 --- a/detekt-generator/build.gradle.kts +++ b/detekt-generator/build.gradle.kts @@ -35,7 +35,7 @@ val ruleModules = rootProject.subprojects .map { "${rootProject.rootDir}/$it/src/main/kotlin" } val generateDocumentation by tasks.registering(JavaExec::class) { - dependsOn(tasks.assemble, ":detekt-api:dokkaHtml") + dependsOn(tasks.assemble, ":detekt-api:dokkaHtml", tasks.shadowJar, ":detekt-rules-ruleauthors:sourcesJar") description = "Generates detekt documentation and the default config.yml based on Rule KDoc" group = "documentation" diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/Rule.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/Rule.kt index 0043eb04d97c..e1f27ca5e541 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/Rule.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/Rule.kt @@ -13,5 +13,8 @@ data class Rule( val configuration: List = emptyList(), val autoCorrect: Boolean = false, var inMultiRule: String? = null, - val requiresTypeResolution: Boolean = false -) + val requiresTypeResolution: Boolean = false, + val deprecationMessage: String? = null +) { + fun isDeprecated() = deprecationMessage != null +} diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/RuleSetProviderCollector.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/RuleSetProviderCollector.kt index b3553c007eb8..95fccaf208b9 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/RuleSetProviderCollector.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/RuleSetProviderCollector.kt @@ -5,6 +5,7 @@ import io.gitlab.arturbosch.detekt.api.internal.ActiveByDefault import io.gitlab.arturbosch.detekt.api.internal.DefaultRuleSetProvider import io.gitlab.arturbosch.detekt.generator.collection.exception.InvalidDocumentationException import io.gitlab.arturbosch.detekt.rules.isOverride +import org.jetbrains.kotlin.psi.KtAnnotatedExpression import org.jetbrains.kotlin.psi.KtCallExpression import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtFile @@ -128,6 +129,7 @@ class RuleSetProviderVisitor : DetektVisitor() { val ruleArgumentNames = (ruleListExpression as? KtCallExpression) ?.valueArguments ?.mapNotNull { it.getArgumentExpression() } + ?.map { if (it is KtAnnotatedExpression) it.lastChild as KtCallExpression else it } ?.mapNotNull { it.referenceExpression()?.text } .orEmpty() diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/RuleVisitor.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/RuleVisitor.kt index 862eb94c0d46..fc9c46831066 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/RuleVisitor.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/collection/RuleVisitor.kt @@ -35,6 +35,7 @@ internal class RuleVisitor : DetektVisitor() { private var parent = "" private val configurationCollector = ConfigurationCollector() private val classesMap = mutableMapOf() + private var deprecationMessage: String? = null fun getRule(): Rule { if (documentationCollector.description.isEmpty()) { @@ -55,6 +56,7 @@ internal class RuleVisitor : DetektVisitor() { parent = parent, configuration = configurationByAnnotation, autoCorrect = autoCorrect, + deprecationMessage = deprecationMessage, requiresTypeResolution = requiresTypeResolution ) } @@ -105,6 +107,7 @@ internal class RuleVisitor : DetektVisitor() { autoCorrect = classOrObject.isAnnotatedWith(AutoCorrectable::class) requiresTypeResolution = classOrObject.isAnnotatedWith(RequiresTypeResolution::class) + deprecationMessage = classOrObject.firstAnnotationParameterOrNull(Deprecated::class) documentationCollector.setClass(classOrObject) } diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/DeprecatedPrinter.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/DeprecatedPrinter.kt index 141e9a38b9d1..0d0a0e024013 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/DeprecatedPrinter.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/DeprecatedPrinter.kt @@ -10,6 +10,9 @@ object DeprecatedPrinter : DocumentationPrinter> { val builder = StringBuilder() item.forEach { ruleSet -> ruleSet.rules.forEach { rule -> + if (rule.isDeprecated()) { + builder.appendLine(writeRuleProperty(ruleSet, rule)) + } rule.configuration.forEach { configuration -> if (configuration.isDeprecated()) { builder.appendLine(writeProperty(ruleSet, rule, configuration)) @@ -25,3 +28,8 @@ private fun writeProperty(ruleSet: RuleSetPage, rule: Rule, configuration: Confi @Suppress("UnsafeCallOnNullableType") return "${ruleSet.ruleSet.name}>${rule.name}>${configuration.name}=${configuration.deprecated!!}" } + +private fun writeRuleProperty(ruleSet: RuleSetPage, rule: Rule): String { + @Suppress("UnsafeCallOnNullableType") + return "${ruleSet.ruleSet.name}>${rule.name}=${rule.deprecationMessage!!}" +} diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/RulePrinter.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/RulePrinter.kt index 9c171d7f8e03..48ebd0fad12f 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/RulePrinter.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/RulePrinter.kt @@ -3,6 +3,7 @@ package io.gitlab.arturbosch.detekt.generator.printer import io.github.detekt.utils.MarkdownContent import io.github.detekt.utils.bold import io.github.detekt.utils.codeBlock +import io.github.detekt.utils.crossOut import io.github.detekt.utils.h3 import io.github.detekt.utils.h4 import io.github.detekt.utils.markdown @@ -14,7 +15,12 @@ internal object RulePrinter : DocumentationPrinter { override fun print(item: Rule): String { return markdown { - h3 { item.name } + if (item.isDeprecated()) { + h3 { crossOut { item.name } } + paragraph { escapeHtml(item.deprecationMessage.orEmpty()) } + } else { + h3 { item.name } + } if (item.description.isNotEmpty()) { paragraph { escapeHtml(item.description) } diff --git a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/defaultconfig/RuleSetConfigPrinter.kt b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/defaultconfig/RuleSetConfigPrinter.kt index e412afc64d91..638507b5caff 100644 --- a/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/defaultconfig/RuleSetConfigPrinter.kt +++ b/detekt-generator/src/main/kotlin/io/gitlab/arturbosch/detekt/generator/printer/defaultconfig/RuleSetConfigPrinter.kt @@ -30,6 +30,8 @@ internal fun YamlNode.printRuleSet(ruleSet: RuleSetProvider, rules: List) } internal fun YamlNode.printRule(rule: Rule) { + if (rule.isDeprecated()) return + node(rule.name) { keyValue { Config.ACTIVE_KEY to "${rule.defaultActivationStatus.active}" } if (rule.autoCorrect) { diff --git a/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/config/ConfigAssert.kt b/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/config/ConfigAssert.kt index 483ca09d259a..0b7bdbbfadea 100644 --- a/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/config/ConfigAssert.kt +++ b/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/config/ConfigAssert.kt @@ -77,6 +77,9 @@ class ConfigAssert( private fun getRuleClassesInPackage(): List> { return Reflections(packageName) .getSubTypesOf(Rule::class.java) - .filter { !Modifier.isAbstract(it.modifiers) } + .filter { rule -> + !Modifier.isAbstract(rule.modifiers) && + rule.annotations.none { it.annotationClass == Deprecated::class } + } } } diff --git a/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/printer/DeprecatedPrinterSpec.kt b/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/printer/DeprecatedPrinterSpec.kt index 0e2690929c08..ec694b070b90 100644 --- a/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/printer/DeprecatedPrinterSpec.kt +++ b/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/printer/DeprecatedPrinterSpec.kt @@ -12,7 +12,8 @@ class DeprecatedPrinterSpec { val expectedMarkdownString = """ style>MagicNumber>conf2=use conf1 instead style>MagicNumber>conf4=use conf3 instead - + style>DuplicateCaseInWhenExpression=is deprecated + """.trimIndent() assertThat(markdownString).isEqualTo(expectedMarkdownString) } diff --git a/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/util/RuleSetPageCreator.kt b/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/util/RuleSetPageCreator.kt index c217da2e9ec4..124d90040420 100644 --- a/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/util/RuleSetPageCreator.kt +++ b/detekt-generator/src/test/kotlin/io/gitlab/arturbosch/detekt/generator/util/RuleSetPageCreator.kt @@ -102,5 +102,17 @@ internal fun createRules(): List { autoCorrect = true, requiresTypeResolution = true ) - return listOf(rule1, rule2, rule3) + val rule4 = Rule( + name = "DuplicateCaseInWhenExpression", + description = "Duplicated `case` statements in a `when` expression detected.", + nonCompliantCodeExample = "fun stuff(): Unit {}", + compliantCodeExample = "fun stuff() {}", + defaultActivationStatus = Active(since = "1.16.0"), + severity = "", + debt = "5m", + aliases = null, + parent = "", + deprecationMessage = "is deprecated" + ) + return listOf(rule1, rule2, rule3, rule4) } diff --git a/detekt-generator/src/test/resources/RuleSet.md b/detekt-generator/src/test/resources/RuleSet.md index 9943ce20efc9..60b39b40556d 100644 --- a/detekt-generator/src/test/resources/RuleSet.md +++ b/detekt-generator/src/test/resources/RuleSet.md @@ -75,3 +75,25 @@ fun stuff(): Unit {} ```kotlin fun stuff() {} ``` + +### ~~DuplicateCaseInWhenExpression~~ + +is deprecated + +Duplicated `case` statements in a `when` expression detected. + +**Active by default**: Yes - Since v1.16.0 + +**Debt**: 5m + +#### Noncompliant Code: + +```kotlin +fun stuff(): Unit {} +``` + +#### Compliant Code: + +```kotlin +fun stuff() {} +``` diff --git a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/internal/DetektJvm.kt b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/internal/DetektJvm.kt index 15ba228b0500..3b2623bbcd23 100644 --- a/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/internal/DetektJvm.kt +++ b/detekt-gradle-plugin/src/main/kotlin/io/gitlab/arturbosch/detekt/internal/DetektJvm.kt @@ -1,52 +1,53 @@ -@file:Suppress("DEPRECATION") - package io.gitlab.arturbosch.detekt.internal import io.gitlab.arturbosch.detekt.DetektPlugin import io.gitlab.arturbosch.detekt.extensions.DetektExtension -import org.gradle.api.GradleException import org.gradle.api.Project import org.gradle.api.file.FileCollection -import org.gradle.api.internal.HasConvention -import org.gradle.api.plugins.JavaPluginConvention -import org.gradle.api.tasks.SourceSet -import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet +import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions +import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation internal class DetektJvm(private val project: Project) { fun registerTasks(extension: DetektExtension) { - project.convention.getPlugin(JavaPluginConvention::class.java).sourceSets.all { sourceSet -> - project.registerJvmDetektTask(extension, sourceSet) - project.registerJvmCreateBaselineTask(extension, sourceSet) + project.extensions.getByType(KotlinJvmProjectExtension::class.java).target.compilations.all { compilation -> + val inputSource = compilation.kotlinSourceSets + .map { it.kotlin.sourceDirectories } + .fold(project.files() as FileCollection) { collection, next -> collection.plus(next) } + project.registerJvmDetektTask(compilation, extension, inputSource) + project.registerJvmCreateBaselineTask(compilation, extension, inputSource) } } - private fun Project.registerJvmDetektTask(extension: DetektExtension, sourceSet: SourceSet) { - val kotlinSourceSet = (sourceSet as HasConvention).convention.plugins["kotlin"] as? KotlinSourceSet - ?: throw GradleException("Kotlin source set not found. Please report on detekt's issue tracker") - registerDetektTask(DetektPlugin.DETEKT_TASK_NAME + sourceSet.name.capitalize(), extension) { - source = kotlinSourceSet.kotlin - classpath.setFrom(sourceSet.compileClasspath.existingFiles(), sourceSet.output.classesDirs.existingFiles()) + private fun Project.registerJvmDetektTask( + compilation: KotlinCompilation, + extension: DetektExtension, + inputSource: FileCollection + ) { + registerDetektTask(DetektPlugin.DETEKT_TASK_NAME + compilation.name.capitalize(), extension) { + setSource(inputSource) + classpath.setFrom(inputSource, compilation.compileDependencyFiles) // If a baseline file is configured as input file, it must exist to be configured, otherwise the task fails. // We try to find the configured baseline or alternatively a specific variant matching this task. - extension.baseline?.existingVariantOrBaseFile(sourceSet.name)?.let { baselineFile -> - baseline.convention(layout.file(project.provider { baselineFile })) + extension.baseline?.existingVariantOrBaseFile(compilation.name)?.let { baselineFile -> + baseline.convention(layout.file(provider { baselineFile })) } - setReportOutputConventions(reports, extension, sourceSet.name) - description = "EXPERIMENTAL: Run detekt analysis for ${sourceSet.name} classes with type resolution" + setReportOutputConventions(reports, extension, compilation.name) + description = "EXPERIMENTAL: Run detekt analysis for ${compilation.name} classes with type resolution" } } - private fun Project.registerJvmCreateBaselineTask(extension: DetektExtension, sourceSet: SourceSet) { - val kotlinSourceSet = (sourceSet as HasConvention).convention.plugins["kotlin"] as? KotlinSourceSet - ?: throw GradleException("Kotlin source set not found. Please report on detekt's issue tracker") - registerCreateBaselineTask(DetektPlugin.BASELINE_TASK_NAME + sourceSet.name.capitalize(), extension) { - source = kotlinSourceSet.kotlin - classpath.setFrom(sourceSet.compileClasspath.existingFiles(), sourceSet.output.classesDirs.existingFiles()) - val variantBaselineFile = extension.baseline?.addVariantName(sourceSet.name) - baseline.convention(project.layout.file(project.provider { variantBaselineFile })) - description = "EXPERIMENTAL: Creates detekt baseline for ${sourceSet.name} classes with type resolution" + private fun Project.registerJvmCreateBaselineTask( + compilation: KotlinCompilation, + extension: DetektExtension, + inputSource: FileCollection + ) { + registerCreateBaselineTask(DetektPlugin.BASELINE_TASK_NAME + compilation.name.capitalize(), extension) { + setSource(inputSource) + classpath.setFrom(inputSource, compilation.compileDependencyFiles) + val variantBaselineFile = extension.baseline?.addVariantName(compilation.name) + baseline.convention(layout.file(provider { variantBaselineFile })) + description = "EXPERIMENTAL: Creates detekt baseline for ${compilation.name} classes with type resolution" } } - - private fun FileCollection.existingFiles() = filter { it.exists() } } diff --git a/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/DuplicateCaseInWhenExpression.kt b/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/DuplicateCaseInWhenExpression.kt index f38e950eef82..22623f69e9ce 100644 --- a/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/DuplicateCaseInWhenExpression.kt +++ b/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/DuplicateCaseInWhenExpression.kt @@ -32,6 +32,7 @@ import org.jetbrains.kotlin.psi.KtWhenExpression * */ @ActiveByDefault(since = "1.0.0") +@Deprecated("Rule deprecated as compiler performs this check by default") class DuplicateCaseInWhenExpression(config: Config) : Rule(config) { override val issue = Issue( diff --git a/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/MissingWhenCase.kt b/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/MissingWhenCase.kt index 5a4f1d28467e..4547927d92a8 100644 --- a/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/MissingWhenCase.kt +++ b/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/MissingWhenCase.kt @@ -68,6 +68,7 @@ import org.jetbrains.kotlin.resolve.calls.util.getType */ @ActiveByDefault(since = "1.2.0") @RequiresTypeResolution +@Deprecated("Rule deprecated as compiler performs this check by default") class MissingWhenCase(config: Config = Config.empty) : Rule(config) { override val issue: Issue = Issue( diff --git a/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/PotentialBugProvider.kt b/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/PotentialBugProvider.kt index 87481632ea42..91c18d83ecf0 100644 --- a/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/PotentialBugProvider.kt +++ b/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/PotentialBugProvider.kt @@ -20,7 +20,7 @@ class PotentialBugProvider : DefaultRuleSetProvider { Deprecation(config), DontDowncastCollectionTypes(config), DoubleMutabilityForCollection(config), - DuplicateCaseInWhenExpression(config), + @Suppress("DEPRECATION") DuplicateCaseInWhenExpression(config), ElseCaseInsteadOfExhaustiveWhen(config), EqualsAlwaysReturnsTrueOrFalse(config), EqualsWithHashCodeExist(config), @@ -34,11 +34,12 @@ class PotentialBugProvider : DefaultRuleSetProvider { LateinitUsage(config), MapGetWithNotNullAssertionOperator(config), MissingPackageDeclaration(config), - MissingWhenCase(config), + @Suppress("DEPRECATION") MissingWhenCase(config), NullCheckOnMutableProperty(config), - RedundantElseInWhen(config), + @Suppress("DEPRECATION") RedundantElseInWhen(config), UnconditionalJumpStatementInLoop(config), UnnecessaryNotNullOperator(config), + UnnecessaryNotNullCheck(config), UnnecessarySafeCall(config), UnreachableCode(config), UnsafeCallOnNullableType(config), diff --git a/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/RedundantElseInWhen.kt b/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/RedundantElseInWhen.kt index 042a03569bbd..4b9b83cdbbe3 100644 --- a/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/RedundantElseInWhen.kt +++ b/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/RedundantElseInWhen.kt @@ -59,6 +59,7 @@ import org.jetbrains.kotlin.psi.KtWhenExpression */ @RequiresTypeResolution @ActiveByDefault(since = "1.2.0") +@Deprecated("Rule deprecated as compiler performs this check by default") class RedundantElseInWhen(config: Config = Config.empty) : Rule(config) { override val issue: Issue = Issue( diff --git a/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnnecessaryNotNullCheck.kt b/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnnecessaryNotNullCheck.kt new file mode 100644 index 000000000000..1c7b7dafa6e0 --- /dev/null +++ b/detekt-rules-errorprone/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnnecessaryNotNullCheck.kt @@ -0,0 +1,70 @@ +package io.gitlab.arturbosch.detekt.rules.bugs + +import io.gitlab.arturbosch.detekt.api.CodeSmell +import io.gitlab.arturbosch.detekt.api.Config +import io.gitlab.arturbosch.detekt.api.Debt +import io.gitlab.arturbosch.detekt.api.Entity +import io.gitlab.arturbosch.detekt.api.Issue +import io.gitlab.arturbosch.detekt.api.Rule +import io.gitlab.arturbosch.detekt.api.Severity +import io.gitlab.arturbosch.detekt.api.internal.RequiresTypeResolution +import io.gitlab.arturbosch.detekt.rules.isCalling +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.psi.KtCallExpression +import org.jetbrains.kotlin.psi.KtExpression +import org.jetbrains.kotlin.psi.psiUtil.getCallNameExpression +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.calls.util.getType +import org.jetbrains.kotlin.types.typeUtil.TypeNullability +import org.jetbrains.kotlin.types.typeUtil.nullability + +/** + * Reports unnecessary not-null checks with `requireNotNull` or `checkNotNull` that can be removed by the user. + * + * + * var string = "foo" + * println(requireNotNull(string)) + * + * + * + * var string : String? = "foo" + * println(requireNotNull(string)) + * + */ +@RequiresTypeResolution +class UnnecessaryNotNullCheck(config: Config = Config.empty) : Rule(config) { + + override val issue = Issue( + "UnnecessaryNotNullCheck", + Severity.Defect, + "Remove unnecessary not-null checks on non-null types.", + Debt.FIVE_MINS, + ) + + override fun visitCallExpression(expression: KtCallExpression) { + super.visitCallExpression(expression) + + if (bindingContext == BindingContext.EMPTY) return + + if (expression.isCalling(requireNotNullFunctionFqName, bindingContext) || + expression.isCalling(checkNotNullFunctionFqName, bindingContext) + ) { + val argument = expression.valueArguments[0].lastChild as KtExpression + if (argument.getType(bindingContext)?.nullability() == TypeNullability.NOT_NULL) { + val callName = expression.getCallNameExpression()?.text + report( + CodeSmell( + issue = issue, + entity = Entity.from(expression), + message = "Using `$callName` on non-null `${argument.text}` is unnecessary", + ) + ) + } + } + } + + companion object { + private val requireNotNullFunctionFqName = FqName("kotlin.requireNotNull") + private val checkNotNullFunctionFqName = FqName("kotlin.checkNotNull") + } +} diff --git a/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/DuplicateCaseInWhenExpressionSpec.kt b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/DuplicateCaseInWhenExpressionSpec.kt index 5f2885d3d834..ec33f8d41d75 100644 --- a/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/DuplicateCaseInWhenExpressionSpec.kt +++ b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/DuplicateCaseInWhenExpressionSpec.kt @@ -7,6 +7,7 @@ import org.junit.jupiter.api.Test class DuplicateCaseInWhenExpressionSpec { + @Suppress("DEPRECATION") private val subject = DuplicateCaseInWhenExpression(Config.empty) @Test diff --git a/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/MissingWhenCaseSpec.kt b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/MissingWhenCaseSpec.kt index ea5d784ff304..2c47dca89527 100644 --- a/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/MissingWhenCaseSpec.kt +++ b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/MissingWhenCaseSpec.kt @@ -15,6 +15,7 @@ class MissingWhenCaseSpec(private val env: KotlinCoreEnvironment) { @Nested inner class `MissingWhenCase rule` { + @Suppress("DEPRECATION") private val subject = MissingWhenCase() @Nested @@ -311,6 +312,7 @@ class MissingWhenCaseSpec(private val env: KotlinCoreEnvironment) { @Nested inner class `MissingWhenCase rule when else expression is not considered` { + @Suppress("DEPRECATION") private val subject = MissingWhenCase( TestConfig(mapOf("allowElseExpression" to false)) ) diff --git a/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/RedundantElseInWhenSpec.kt b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/RedundantElseInWhenSpec.kt index 7ab32e64bf83..689d9c3231ae 100644 --- a/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/RedundantElseInWhenSpec.kt +++ b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/RedundantElseInWhenSpec.kt @@ -11,6 +11,7 @@ import org.junit.jupiter.api.Test @KotlinCoreEnvironmentTest class RedundantElseInWhenSpec(private val env: KotlinCoreEnvironment) { + @Suppress("DEPRECATION") private val subject = RedundantElseInWhen() @Nested diff --git a/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnnecessaryNotNullCheckSpec.kt b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnnecessaryNotNullCheckSpec.kt new file mode 100644 index 000000000000..a6b2b3519640 --- /dev/null +++ b/detekt-rules-errorprone/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/bugs/UnnecessaryNotNullCheckSpec.kt @@ -0,0 +1,158 @@ +package io.gitlab.arturbosch.detekt.rules.bugs + +import io.gitlab.arturbosch.detekt.rules.KotlinCoreEnvironmentTest +import io.gitlab.arturbosch.detekt.test.assertThat +import io.gitlab.arturbosch.detekt.test.lintWithContext +import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment +import org.junit.jupiter.api.Nested +import org.junit.jupiter.api.Test + +@KotlinCoreEnvironmentTest +class UnnecessaryNotNullCheckSpec(private val env: KotlinCoreEnvironment) { + private val subject = UnnecessaryNotNullCheck() + + @Nested + inner class `check unnecessary not null checks` { + + @Test + fun shouldDetectNotNullCallOnVariable() { + val code = """ + val x = 5 + val y = requireNotNull(x) + """.trimIndent() + val findings = subject.lintWithContext(env, code) + assertThat(findings).hasSize(1) + assertThat(findings).hasTextLocations(18 to 35) + } + + @Test + fun shouldDetectNotNullCallOnVariableUsingCheckNotNull() { + val code = """ + val x = 5 + val y = checkNotNull(x) + """.trimIndent() + val findings = subject.lintWithContext(env, code) + assertThat(findings).hasSize(1) + assertThat(findings).hasTextLocations(18 to 33) + } + + @Test + fun shouldDetectNotNullCallOnFunctionReturn() { + val code = """ + fun foo(): Int { + return 5 + } + fun bar() { + requireNotNull(foo()) + } + """.trimIndent() + val findings = subject.lintWithContext(env, code) + assertThat(findings).hasSize(1) + assertThat(findings).hasTextLocations(48 to 69) + } + + @Test + fun shouldDetectWhenCallingDefinitelyNonNullableGenericFunction() { + val code = """ + fun foo(x: T & Any): T & Any { + return x + } + fun bar() { + requireNotNull(foo(5)) + } + """.trimIndent() + val findings = subject.lintWithContext(env, code) + assertThat(findings).hasSize(1) + assertThat(findings).hasTextLocations(66 to 88) + } + + @Test + fun shouldDetectWhenCallingPrimitiveJavaMethod() { + val code = """ + fun foo() { + requireNotNull(System.currentTimeMillis()) + } + """.trimIndent() + val findings = subject.lintWithContext(env, code) + assertThat(findings).hasSize(1) + assertThat(findings).hasTextLocations(16 to 58) + } + } + + @Nested + inner class `check valid not null check usage` { + + @Test + fun shouldIgnoreNotNullCallOnNullableVariableWithValue() { + val code = """ + val x: Int? = 5 + val y = requireNotNull(x) + """.trimIndent() + val findings = subject.lintWithContext(env, code) + assertThat(findings).isEmpty() + } + + @Test + fun shouldIgnoreNotNullCallOnNullableVariableWithNull() { + val code = """ + val x: Int? = null + val y = requireNotNull(x) + """.trimIndent() + val findings = subject.lintWithContext(env, code) + assertThat(findings).isEmpty() + } + + @Test + fun shouldIgnoreNotNullCallOnNullableFunctionReturnWithValue() { + val code = """ + fun foo(): Int? { + return 5 + } + fun bar() { + requireNotNull(foo()) + } + """.trimIndent() + val findings = subject.lintWithContext(env, code) + assertThat(findings).isEmpty() + } + + @Test + fun shouldIgnoreNotNullCallOnNullableFunctionReturnWithNull() { + val code = """ + fun foo(): Int? { + return null + } + fun bar() { + requireNotNull(foo()) + } + """.trimIndent() + val findings = subject.lintWithContext(env, code) + assertThat(findings).isEmpty() + } + + @Test + fun shouldIgnoreWhenCallingNullableGenericFunction() { + val code = """ + fun foo(x: T): T { + return x + } + fun bar() { + requireNotNull(foo(5)) + } + """.trimIndent() + val findings = subject.lintWithContext(env, code) + assertThat(findings).isEmpty() + } + + @Test + fun shouldIgnoreWhenCallingObjectJavaMethod() { + val code = """ + fun foo() { + requireNotNull(System.getLogger()) + } + """.trimIndent() + val findings = subject.lintWithContext(env, code) + assertThat(findings).isEmpty() + } + } +} diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/AlsoCouldBeApply.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/AlsoCouldBeApply.kt new file mode 100644 index 000000000000..fc6cb2689c40 --- /dev/null +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/AlsoCouldBeApply.kt @@ -0,0 +1,62 @@ +package io.gitlab.arturbosch.detekt.rules.style + +import io.gitlab.arturbosch.detekt.api.CodeSmell +import io.gitlab.arturbosch.detekt.api.Config +import io.gitlab.arturbosch.detekt.api.Debt +import io.gitlab.arturbosch.detekt.api.Entity +import io.gitlab.arturbosch.detekt.api.Issue +import io.gitlab.arturbosch.detekt.api.Rule +import io.gitlab.arturbosch.detekt.api.Severity +import io.gitlab.arturbosch.detekt.rules.IT_LITERAL +import io.gitlab.arturbosch.detekt.rules.safeAs +import org.jetbrains.kotlin.psi.KtCallExpression +import org.jetbrains.kotlin.psi.KtQualifiedExpression + +/** + * Detects when an `also` block contains only `it`-started expressions. + * + * By refactoring the `also` block to an `apply` block makes it so that all `it`s can be removed + * thus making the block more concise and easier to read. + * + * + * Buzz().also { + * it.init() + * it.block() + * } + * + * + * + * Buzz().apply { + * init() + * block() + * } + * + * // Also compliant + * fun foo(a: Int): Int { + * return a.also { println(it) } + * } + * + */ +class AlsoCouldBeApply(config: Config = Config.empty) : Rule(config) { + + override val issue = Issue( + "AlsoCouldBeApply", + Severity.Style, + "When an `also` block contains only `it`-started expressions, simplify it to the `apply` block.", + Debt.FIVE_MINS + ) + + @Suppress("ReturnCount") + override fun visitCallExpression(expression: KtCallExpression) { + super.visitCallExpression(expression) + + val callee = expression.calleeExpression?.takeIf { it.text == "also" } ?: return + val lambda = expression.lambdaArguments.singleOrNull()?.getLambdaExpression() + ?: expression.valueArguments.singleOrNull()?.getArgumentExpression()?.safeAs() + ?: return + val statements = lambda.bodyExpression?.statements.orEmpty().ifEmpty { return } + if (statements.all { it.safeAs()?.receiverExpression?.text == IT_LITERAL }) { + report(CodeSmell(issue, Entity.from(callee), issue.description)) + } + } +} diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/StyleGuideProvider.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/StyleGuideProvider.kt index f505fac8a034..cdab5191a923 100644 --- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/StyleGuideProvider.kt +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/StyleGuideProvider.kt @@ -104,6 +104,7 @@ class StyleGuideProvider : DefaultRuleSetProvider { UseAnyOrNoneInsteadOfFind(config), UnnecessaryBackticks(config), MaxChainedCallsOnSameLine(config), + AlsoCouldBeApply(config), ) ) } diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateMember.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateMember.kt index 85513599e4be..81642b889946 100644 --- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateMember.kt +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateMember.kt @@ -39,6 +39,7 @@ import org.jetbrains.kotlin.psi.KtProperty import org.jetbrains.kotlin.psi.KtPropertyDelegate import org.jetbrains.kotlin.psi.KtReferenceExpression import org.jetbrains.kotlin.psi.KtSecondaryConstructor +import org.jetbrains.kotlin.psi.KtValueArgumentName import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType import org.jetbrains.kotlin.psi.psiUtil.isPrivate @@ -260,7 +261,9 @@ private class UnusedParameterVisitor(allowedNames: Regex) : UnusedMemberVisitor( } override fun visitReferenceExpression(expression: KtReferenceExpression) { - parameters.remove(expression.text.removeSurrounding("`")) + if (expression.parent !is KtValueArgumentName) { + parameters.remove(expression.text.removeSurrounding("`")) + } super.visitReferenceExpression(expression) } }) diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/AlsoCouldBeApplySpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/AlsoCouldBeApplySpec.kt new file mode 100644 index 000000000000..56a0ac35b389 --- /dev/null +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/AlsoCouldBeApplySpec.kt @@ -0,0 +1,153 @@ +package io.gitlab.arturbosch.detekt.rules.style + +import io.gitlab.arturbosch.detekt.api.Config +import io.gitlab.arturbosch.detekt.test.assertThat +import io.gitlab.arturbosch.detekt.test.compileAndLint +import org.junit.jupiter.api.Test + +class AlsoCouldBeApplySpec { + val subject = AlsoCouldBeApply(Config.empty) + + @Test + fun `does not report when no also is used`() { + val code = """ + fun f(a: Int) { + a.let { + it.plus(5) + it.minus(10) + } + } + """.trimIndent() + assertThat(subject.compileAndLint(code)).isEmpty() + } + + @Test + fun `reports an also where only it is used in block`() { + val code = """ + fun f(a: Int) { + a.also { + it.plus(5) + } + } + """.trimIndent() + assertThat(subject.compileAndLint(code)).hasSize(1) + } + + @Test + fun `report is focused on also keyword`() { + val code = """ + fun f(a: Int) { + a.also { + it.plus(5) + } + } + """.trimIndent() + + val findings = subject.compileAndLint(code) + + assertThat(findings).hasSize(1) + assertThat(findings).hasStartSourceLocation(2, 7) + assertThat(findings).hasEndSourceLocation(2, 11) + } + + @Test + fun `reports an also on nullable type`() { + val code = """ + fun f(a: Int?) { + a?.also { + it.plus(5) + } + } + """.trimIndent() + assertThat(subject.compileAndLint(code)).hasSize(1) + } + + @Test + fun `reports an also with lambda passed as Argument in parenthesis`() { + val code = """ + fun f(a: Int?) { + a?.also({ + it.plus(5) + }) + } + """.trimIndent() + assertThat(subject.compileAndLint(code)).hasSize(1) + } + + @Test + fun `does not report if it is not used in also`() { + val code = """ + fun f(a: Int?, b: Int) { + a?.also { + b.plus(5) + } + } + """.trimIndent() + assertThat(subject.compileAndLint(code)).isEmpty() + } + + @Test + fun `does not report if it is renamed`() { + val code = """ + fun f(x: Int, y: Int) { + x.also { named -> + named.plus(5) + named.minus(y) + } + } + """.trimIndent() + assertThat(subject.compileAndLint(code)).isEmpty() + } + + @Test + fun `does report if it is on one line separated by semicolon`() { + val code = """ + fun f(a: Int) { + a.also { it.plus(5); it.minus(10) } + } + """.trimIndent() + assertThat(subject.compileAndLint(code)).hasSize(1) + } + + @Test + fun `detect violation in also nested in also`() { + val code = """ + fun f(a: Int) { + a.also { x -> x.also { it.plus(10) } } + } + """.trimIndent() + assertThat(subject.compileAndLint(code)).hasSize(1) + } + + @Test + fun `does not report when all statements are not 'it'-started expressions`() { + val code = """ + fun test(foo: Foo) { + foo.also { + it.bar() + println(it) + it.baz() + } + } + + class Foo { + fun bar() {} + fun baz() {} + } + """.trimIndent() + assertThat(subject.compileAndLint(code)).isEmpty() + } + + @Test + fun `does not report when no statements`() { + val code = """ + fun test(foo: Foo) { + foo.also { + } + } + + class Foo + """.trimIndent() + assertThat(subject.compileAndLint(code)).isEmpty() + } +} diff --git a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateMemberSpec.kt b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateMemberSpec.kt index 62812d702259..2ee3f6f43ef1 100644 --- a/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateMemberSpec.kt +++ b/detekt-rules-style/src/test/kotlin/io/gitlab/arturbosch/detekt/rules/style/UnusedPrivateMemberSpec.kt @@ -1648,4 +1648,35 @@ class UnusedPrivateMemberSpec(val env: KotlinCoreEnvironment) { assertThat(subject.lint(code)).hasSize(1).hasStartSourceLocation(6, 9) } } + + @Nested + inner class `parameter with the same name as a named argument #5373` { + @Test + fun `unused parameter`() { + val code = """ + fun foo(modifier: Int) { + bar(modifier = 1) + } + + fun bar(modifier: Int) { + println(modifier) + } + """.trimIndent() + assertThat(subject.compileAndLintWithContext(env, code)).hasSize(1).hasStartSourceLocation(1, 9) + } + + @Test + fun `used parameter`() { + val code = """ + fun foo(modifier: Int) { + bar(modifier = modifier) + } + + fun bar(modifier: Int) { + println(modifier) + } + """.trimIndent() + assertThat(subject.compileAndLintWithContext(env, code)).isEmpty() + } + } } diff --git a/scripts/github-milestone-report.main.kts b/scripts/github-milestone-report.main.kts index 8f1ccc359612..8bfd2ef68ebc 100755 --- a/scripts/github-milestone-report.main.kts +++ b/scripts/github-milestone-report.main.kts @@ -9,7 +9,7 @@ // for the exec line @file:Suppress("detekt.CommentSpacing") -@file:DependsOn("org.kohsuke:github-api:1.308") +@file:DependsOn("org.kohsuke:github-api:1.313") @file:DependsOn("com.github.ajalt:clikt:2.8.0") import com.github.ajalt.clikt.core.CliktCommand diff --git a/scripts/release.sh b/scripts/release.sh index bc4aa40cf279..551f8a1539cb 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -1,8 +1,9 @@ #!/usr/bin/env sh -gradle publishToMavenLocal || exit -gradle build || exit -gradle publishAllToMavenCentral --max-workers 1 || exit -gradle :detekt-gradle-plugin:publishPlugins || exit -gradle githubRelease || exit -gradle applyDocVersion || exit -gradle closeAndReleaseRepository || exit +set -e +gradle publishToMavenLocal +gradle build +gradle publishAllToMavenCentral --max-workers 1 +gradle :detekt-gradle-plugin:publishPlugins +gradle githubRelease +gradle applyDocVersion +gradle closeAndReleaseRepository diff --git a/website/versioned_docs/version-1.21.0/rules/formatting.md b/website/versioned_docs/version-1.21.0/rules/formatting.md index 74f1dd12966e..939c547a7923 100644 --- a/website/versioned_docs/version-1.21.0/rules/formatting.md +++ b/website/versioned_docs/version-1.21.0/rules/formatting.md @@ -94,7 +94,7 @@ See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for docu See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for documentation. -This rules overlaps with [naming>MatchingDeclarationName](https://detekt.dev/naming.html#matchingdeclarationname) +This rules overlaps with [naming>MatchingDeclarationName](https://detekt.dev/docs/rules/naming/#matchingdeclarationname) from the standard rules, make sure to enable just one. **Active by default**: Yes - Since v1.0.0 @@ -103,7 +103,7 @@ from the standard rules, make sure to enable just one. See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for documentation. -This rules overlaps with [style>NewLineAtEndOfFile](https://detekt.dev/style.html#newlineatendoffile) +This rules overlaps with [style>NewLineAtEndOfFile](https://detekt.dev/docs/rules/style/#newlineatendoffile) from the standard rules, make sure to enable just one. The pro of this rule is that it can auto-correct the issue. **Active by default**: Yes - Since v1.0.0 @@ -174,7 +174,7 @@ See [ktlint-readme](https://github.com/pinterest/ktlint#experimental-rules) for See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for documentation. -This rules overlaps with [style>MaxLineLength](https://detekt.dev/style.html#maxlinelength) +This rules overlaps with [style>MaxLineLength](https://detekt.dev/docs/rules/style/#maxlinelength) from the standard rules, make sure to enable just one or keep them aligned. The pro of this rule is that it can auto-correct the issue. @@ -200,7 +200,7 @@ See [ktlint-readme](https://github.com/pinterest/ktlint#experimental-rules) for See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for documentation. -This rules overlaps with [style>ModifierOrder](https://detekt.dev/style.html#modifierorder) +This rules overlaps with [style>ModifierOrder](https://detekt.dev/docs/rules/style/#modifierorder) from the standard rules, make sure to enable just one. The pro of this rule is that it can auto-correct the issue. **Active by default**: Yes - Since v1.0.0 @@ -227,6 +227,9 @@ See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for docu See [ktlint-readme](https://github.com/pinterest/ktlint#standard-rules) for documentation. +This rules overlaps with [empty-blocks>EmptyClassBlock](https://detekt.dev/docs/rules/empty-blocks/#emptyclassblock) +from the standard rules, make sure to enable just one. The pro of this rule is that it can auto-correct the issue. + **Active by default**: Yes - Since v1.0.0 ### NoEmptyFirstLineInMethodBlock