diff --git a/.commitlintrc b/.commitlintrc new file mode 100644 index 00000000..8a0d8230 --- /dev/null +++ b/.commitlintrc @@ -0,0 +1,5 @@ +{ + "$schema": "https://json.schemastore.org/commitlintrc", + "extends": "@ivangabriele/commitlint-config", + "helpUrl": "https://github.com/ivangabriele/clamav-desktop/blob/main/CONTRIBUTING.md#commit-messages" +} diff --git a/.husky/commit-msg b/.husky/commit-msg new file mode 100755 index 00000000..0a360099 --- /dev/null +++ b/.husky/commit-msg @@ -0,0 +1,6 @@ +#!/bin/sh +. "$(dirname "$0")/_/husky.sh" + +[ -n "$CI" ] && exit 0 + +yarn commitlint --edit "$1" diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 00000000..13f9af66 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,12 @@ +#!/bin/sh +. "$(dirname "$0")/_/husky.sh" + +[ -n "$CI" ] && exit 0 + +if command -v ggshield >/dev/null; then + yarn test:sec +else + echo "\033[33mWARNING: ggshield is not installed, please install it: https://github.com/GitGuardian/ggshield#installation.\033[0m" +fi + +yarn lint-staged diff --git a/package.json b/package.json index 569e0b2a..0f2f2f05 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "clean": "rm -Rf ./.e2e ./coverage ./dist ./node_modules/.vite ./src-tauri/target ./src-tauri/cobertura.xml", "dev": "cross-env RUST_BACKTRACE=full TAURI_DEV=true tauri dev", "dev:webview": "vite", + "postinstall": "node ./scripts/dev/post_install.js", "release:bin": "tauri build -b none", "release:deb": "tauri build -b deb", "release:deb:install": "yarn release:deb && sudo dpkg -i ./src-tauri/target/release/bundle/deb/clamav-desktop_0.3.24_amd64.deb", @@ -24,7 +25,7 @@ "start": "./src-tauri/target/release/clamav-desktop", "test": "yarn test:lint && yarn test:type && yarn test:unit:core && test:unit:webview", "test:e2e": "xvfb-run wdio run ./configs/wdio.config.ts", - "test:lint": "eslint --ext js,ts,tsx .", + "test:lint": "eslint --ext cjs,cts,js,json,jsonc,mjs,mts,ts,tson,tsx .", "test:sec": "ggshield iac scan .", "test:type": "tsc --noEmit -p ./tsconfig.ci.json", "test:unit:core": "make test", @@ -96,6 +97,7 @@ "eslint-plugin-sort-keys-fix": "1.1.2", "eslint-plugin-typescript-sort-keys": "3.2.0", "esm-path": "1.0.1", + "execa": "9.2.0", "husky": "9.0.11", "jest": "29.7.0", "jest-environment-jsdom": "29.7.0", @@ -106,8 +108,17 @@ "ts-node": "10.9.2", "type-fest": "4.20.0", "use-debounce": "10.0.1", - "vite": "5.2.13" + "vite": "5.2.13", + "which": "4.0.0" }, + "lint-staged": { + "*.{md,yaml,yml}": "prettier --write", + "*.{ts,tsx}": [ + "yarn eslint --ext cjs,cts,js,json,jsonc,mjs,mts,ts,tson,tsx", + "bash -c 'npm run test:type'" + ] + }, + "pretter": "@ivangabriele/prettier-config", "author": { "name": "Ivan Gabriele", "email": "ivan.gabriele@gmail.com", diff --git a/scripts/dev/post_install.js b/scripts/dev/post_install.js new file mode 100644 index 00000000..da712e2a --- /dev/null +++ b/scripts/dev/post_install.js @@ -0,0 +1,17 @@ +/* eslint-disable @typescript-eslint/no-unused-expressions */ + +import { B } from 'bhala' +import { $ } from 'execa' +import which from 'which' + +B.log('[Post Install Script] Checking required dependencies...') +try { + which.sync('ggshield') +} catch (error) { + B.warn( + '[Post Install Script] ggshield is not installed, please install it: https://github.com/GitGuardian/ggshield#installation.', + ) +} + +B.log('[Post Install Script] Installing Git hooks (husky)...') +$`yarn husky` diff --git a/yarn.lock b/yarn.lock index ca88b45a..69c27334 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2202,6 +2202,13 @@ __metadata: languageName: node linkType: hard +"@sec-ant/readable-stream@npm:^0.4.1": + version: 0.4.1 + resolution: "@sec-ant/readable-stream@npm:0.4.1" + checksum: 10/aac89581652ac85debe7c5303451c2ebf8bf25ca25db680e4b9b73168f6940616d9a4bbe3348981827b1159b14e2f2e6af4b7bd5735cac898c12d5c51909c102 + languageName: node + linkType: hard + "@sinclair/typebox@npm:^0.27.8": version: 0.27.8 resolution: "@sinclair/typebox@npm:0.27.8" @@ -2216,6 +2223,13 @@ __metadata: languageName: node linkType: hard +"@sindresorhus/merge-streams@npm:^4.0.0": + version: 4.0.0 + resolution: "@sindresorhus/merge-streams@npm:4.0.0" + checksum: 10/16551c787f5328c8ef05fd9831ade64369ccc992df78deb635ec6c44af217d2f1b43f8728c348cdc4e00585ff2fad6e00d8155199cbf6b154acc45fe65cbf0aa + languageName: node + linkType: hard + "@sinonjs/commons@npm:^3.0.0": version: 3.0.1 resolution: "@sinonjs/commons@npm:3.0.1" @@ -4527,6 +4541,7 @@ __metadata: eslint-plugin-sort-keys-fix: "npm:1.1.2" eslint-plugin-typescript-sort-keys: "npm:3.2.0" esm-path: "npm:1.0.1" + execa: "npm:9.2.0" husky: "npm:9.0.11" jest: "npm:29.7.0" jest-environment-jsdom: "npm:29.7.0" @@ -4550,6 +4565,7 @@ __metadata: typescript: "npm:5.4.5" use-debounce: "npm:10.0.1" vite: "npm:5.2.13" + which: "npm:4.0.0" languageName: unknown linkType: soft @@ -6268,6 +6284,26 @@ __metadata: languageName: node linkType: hard +"execa@npm:9.2.0": + version: 9.2.0 + resolution: "execa@npm:9.2.0" + dependencies: + "@sindresorhus/merge-streams": "npm:^4.0.0" + cross-spawn: "npm:^7.0.3" + figures: "npm:^6.1.0" + get-stream: "npm:^9.0.0" + human-signals: "npm:^7.0.0" + is-plain-obj: "npm:^4.1.0" + is-stream: "npm:^4.0.1" + npm-run-path: "npm:^5.2.0" + pretty-ms: "npm:^9.0.0" + signal-exit: "npm:^4.1.0" + strip-final-newline: "npm:^4.0.0" + yoctocolors: "npm:^2.0.0" + checksum: 10/6fd8daf0297578c1013e4c67d4f2c35d8af76763ac8ad773e9c693ba3e6e3ae8cb71773b4e29d07b267f899c6df9d36f7be3b0a590ed0c11c7d429d29c190c95 + languageName: node + linkType: hard + "execa@npm:^5.0.0": version: 5.1.1 resolution: "execa@npm:5.1.1" @@ -6481,6 +6517,15 @@ __metadata: languageName: node linkType: hard +"figures@npm:^6.1.0": + version: 6.1.0 + resolution: "figures@npm:6.1.0" + dependencies: + is-unicode-supported: "npm:^2.0.0" + checksum: 10/9822d13630bee8e6a9f2da866713adf13854b07e0bfde042defa8bba32d47a1c0b2afa627ce73837c674cf9a5e3edce7e879ea72cb9ea7960b2390432d8e1167 + languageName: node + linkType: hard + "file-entry-cache@npm:^6.0.1": version: 6.0.1 resolution: "file-entry-cache@npm:6.0.1" @@ -6801,6 +6846,16 @@ __metadata: languageName: node linkType: hard +"get-stream@npm:^9.0.0": + version: 9.0.1 + resolution: "get-stream@npm:9.0.1" + dependencies: + "@sec-ant/readable-stream": "npm:^0.4.1" + is-stream: "npm:^4.0.1" + checksum: 10/ce56e6db6bcd29ca9027b0546af035c3e93dcd154ca456b54c298901eb0e5b2ce799c5d727341a100c99e14c523f267f1205f46f153f7b75b1f4da6d98a21c5e + languageName: node + linkType: hard + "get-symbol-description@npm:^1.0.2": version: 1.0.2 resolution: "get-symbol-description@npm:1.0.2" @@ -7222,6 +7277,13 @@ __metadata: languageName: node linkType: hard +"human-signals@npm:^7.0.0": + version: 7.0.0 + resolution: "human-signals@npm:7.0.0" + checksum: 10/f1356547f6553a90530527ba2325c2281e33fa3b9b372a647e377fd8f24e9eb8119082051ca6a9f8821e24f1faa13cd462c849a9476c86e7c190dbf0aa2ee8a4 + languageName: node + linkType: hard + "husky@npm:9.0.11": version: 9.0.11 resolution: "husky@npm:9.0.11" @@ -7683,6 +7745,13 @@ __metadata: languageName: node linkType: hard +"is-stream@npm:^4.0.1": + version: 4.0.1 + resolution: "is-stream@npm:4.0.1" + checksum: 10/cbea3f1fc271b21ceb228819d0c12a0965a02b57f39423925f99530b4eb86935235f258f06310b67cd02b2d10b49e9a0998f5ececf110ab7d3760bae4055ad23 + languageName: node + linkType: hard + "is-string@npm:^1.0.5, is-string@npm:^1.0.7": version: 1.0.7 resolution: "is-string@npm:1.0.7" @@ -7733,6 +7802,13 @@ __metadata: languageName: node linkType: hard +"is-unicode-supported@npm:^2.0.0": + version: 2.0.0 + resolution: "is-unicode-supported@npm:2.0.0" + checksum: 10/000b80639dedaf59a385f1c0a57f97a4d1435e0723716f24cc19ad94253a7a0a9f838bdc9ac49b10a29ac93b01f52ae9b2ed358a8876caf1eb74d73b4ede92b2 + languageName: node + linkType: hard + "is-weakmap@npm:^2.0.2": version: 2.0.2 resolution: "is-weakmap@npm:2.0.2" @@ -9558,7 +9634,7 @@ __metadata: languageName: node linkType: hard -"npm-run-path@npm:^5.1.0": +"npm-run-path@npm:^5.1.0, npm-run-path@npm:^5.2.0": version: 5.3.0 resolution: "npm-run-path@npm:5.3.0" dependencies: @@ -9896,6 +9972,13 @@ __metadata: languageName: node linkType: hard +"parse-ms@npm:^4.0.0": + version: 4.0.0 + resolution: "parse-ms@npm:4.0.0" + checksum: 10/673c801d9f957ff79962d71ed5a24850163f4181a90dd30c4e3666b3a804f53b77f1f0556792e8b2adbb5d58757907d1aa51d7d7dc75997c2a56d72937cbc8b7 + languageName: node + linkType: hard + "parse5@npm:^7.0.0, parse5@npm:^7.1.1": version: 7.1.2 resolution: "parse5@npm:7.1.2" @@ -10107,6 +10190,15 @@ __metadata: languageName: node linkType: hard +"pretty-ms@npm:^9.0.0": + version: 9.0.0 + resolution: "pretty-ms@npm:9.0.0" + dependencies: + parse-ms: "npm:^4.0.0" + checksum: 10/b11e1eda41a2efcc16aab218392c8e457a8ae5c8edf63aafba0477123426b1268136b9b532cbfd84625bcb826739120ec8490286dab66102b9f09e717bdb4e45 + languageName: node + linkType: hard + "proc-log@npm:^3.0.0": version: 3.0.0 resolution: "proc-log@npm:3.0.0" @@ -11429,6 +11521,13 @@ __metadata: languageName: node linkType: hard +"strip-final-newline@npm:^4.0.0": + version: 4.0.0 + resolution: "strip-final-newline@npm:4.0.0" + checksum: 10/b5fe48f695d74863153a3b3155220e6e9bf51f4447832998c8edec38e6559b3af87a9fe5ac0df95570a78a26f5fa91701358842eab3c15480e27980b154a145f + languageName: node + linkType: hard + "strip-indent@npm:^3.0.0": version: 3.0.0 resolution: "strip-indent@npm:3.0.0" @@ -12355,6 +12454,17 @@ __metadata: languageName: node linkType: hard +"which@npm:4.0.0, which@npm:^4.0.0": + version: 4.0.0 + resolution: "which@npm:4.0.0" + dependencies: + isexe: "npm:^3.1.1" + bin: + node-which: bin/which.js + checksum: 10/f17e84c042592c21e23c8195108cff18c64050b9efb8459589116999ea9da6dd1509e6a1bac3aeebefd137be00fabbb61b5c2bc0aa0f8526f32b58ee2f545651 + languageName: node + linkType: hard + "which@npm:^2.0.1, which@npm:^2.0.2": version: 2.0.2 resolution: "which@npm:2.0.2" @@ -12366,17 +12476,6 @@ __metadata: languageName: node linkType: hard -"which@npm:^4.0.0": - version: 4.0.0 - resolution: "which@npm:4.0.0" - dependencies: - isexe: "npm:^3.1.1" - bin: - node-which: bin/which.js - checksum: 10/f17e84c042592c21e23c8195108cff18c64050b9efb8459589116999ea9da6dd1509e6a1bac3aeebefd137be00fabbb61b5c2bc0aa0f8526f32b58ee2f545651 - languageName: node - linkType: hard - "word-wrap@npm:^1.2.5": version: 1.2.5 resolution: "word-wrap@npm:1.2.5" @@ -12635,6 +12734,13 @@ __metadata: languageName: node linkType: hard +"yoctocolors@npm:^2.0.0": + version: 2.0.2 + resolution: "yoctocolors@npm:2.0.2" + checksum: 10/cac20504b5fc954ff117e3a3fbde09db8ac0807bba59e68c5c08f3a43173ef46ccb1853b15b37bd96d0d8187bc444627f160fee7e5aede0b421382cf379d2438 + languageName: node + linkType: hard + "zip-stream@npm:^6.0.1": version: 6.0.1 resolution: "zip-stream@npm:6.0.1"