diff --git a/.depcheckrc b/.depcheckrc new file mode 100644 index 0000000..2f87528 --- /dev/null +++ b/.depcheckrc @@ -0,0 +1,9 @@ +{ + "ignores": [], + "skip-missing": false, + "ignore-patterns": [ + "static", + "lib/document_stores/memcached.js", + "lib/document_stores/rethinkdb.js" + ] +} diff --git a/.woodpecker.yml b/.woodpecker.yml index 56d31ef..13bb3ed 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -25,6 +25,22 @@ steps: branch: main event: [push, pull_request, cron] + # Scan for unused code and dependencies + scan-unused: + name: scan-unused + image: node:22-alpine + commands: + - echo "nameserver 1.1.1.1" > /etc/resolv.conf + - echo "nameserver 1.0.0.1" >> /etc/resolv.conf + - npm ci + - echo "=== Scanning for unused files/exports/dependencies (knip) ===" + - npx --yes knip || echo "knip found issues (non-blocking)" + - echo "=== Scanning for unused npm dependencies (depcheck) ===" + - npx --yes depcheck || echo "depcheck found issues (non-blocking)" + when: + branch: main + event: [push, pull_request, cron] + # SBOM for source code sbom-source: name: sbom-source diff --git a/knip.json b/knip.json new file mode 100644 index 0000000..b7fc9e9 --- /dev/null +++ b/knip.json @@ -0,0 +1,12 @@ +{ + "$schema": "https://unpkg.com/knip@latest/schema.json", + "entry": [ + "lib/document_stores/*.js", + "lib/key_generators/*.js" + ], + "ignore": [ + "static/**", + "lib/document_stores/memcached.js", + "lib/document_stores/rethinkdb.js" + ] +} diff --git a/package.json b/package.json index 01db7de..342947d 100644 --- a/package.json +++ b/package.json @@ -73,7 +73,9 @@ "scan:trivy": "./scripts/scan-trivy-fs.sh", "scan:trivy:image": "./scripts/scan-trivy-image.sh", "scan:sbom:image": "./scripts/scan-sbom-image.sh", - "scan:all": "npm run scan:sbom && npm run scan:trivy" + "scan:unused": "npx --yes knip", + "scan:deps": "npx --yes depcheck", + "scan:all": "npm run scan:sbom && npm run scan:trivy && npm run scan:unused && npm run scan:deps" }, "repository": { "type": "git", diff --git a/scripts/install-git-hooks.sh b/scripts/install-git-hooks.sh index a49ce51..ac85ba7 100755 --- a/scripts/install-git-hooks.sh +++ b/scripts/install-git-hooks.sh @@ -1,7 +1,7 @@ #!/bin/bash # Installation script for Git hooks in Hastebin -# This script sets up pre-commit hooks to prevent pushing broken code +# This script sets up pre-commit hooks (tests) and pre-push hooks (unused code scans) set -e @@ -94,9 +94,87 @@ HOOK_EOF chmod +x "$PRE_COMMIT_HOOK" echo -e "${GREEN}✅ Pre-commit hook installed successfully${NC}" + +# --- Pre-push hook --- +PRE_PUSH_HOOK="$HOOKS_DIR/pre-push" + +# Check if pre-push hook already exists +if [ -f "$PRE_PUSH_HOOK" ]; then + echo -e "${YELLOW}⚠️ Pre-push hook already exists${NC}" + read -p "Do you want to overwrite it? (y/N): " -n 1 -r + echo + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + echo -e "${YELLOW}Skipping pre-push hook installation${NC}" + else + mv "$PRE_PUSH_HOOK" "$PRE_PUSH_HOOK.backup.$(date +%Y%m%d_%H%M%S)" + echo -e "${YELLOW}Backed up existing pre-push hook${NC}" + fi +fi + +if [ ! -f "$PRE_PUSH_HOOK" ] || [[ $REPLY =~ ^[Yy]$ ]]; then + cat > "$PRE_PUSH_HOOK" << 'HOOK_EOF' +#!/bin/bash + +# Git pre-push hook for Hastebin +# Scans for unused code/dependencies before pushing + +set -e + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[0;33m' +NC='\033[0m' # No Color + +echo -e "${YELLOW}Running pre-push checks...${NC}" + +# Get the repository root +REPO_ROOT=$(git rev-parse --show-toplevel) +cd "$REPO_ROOT" + +# Check if node_modules exists, if not, install dependencies +if [ ! -d "node_modules" ]; then + echo -e "${YELLOW}Installing dependencies...${NC}" + npm ci +fi + +# Scan for unused code/dependencies +SCAN_FAILED=0 + +echo -e "${YELLOW}Scanning for unused files/exports/dependencies (knip)...${NC}" +if npx --yes knip 2>/dev/null; then + echo -e "${GREEN}✅ knip passed${NC}" +else + echo -e "${RED}❌ knip found unused code${NC}" + SCAN_FAILED=1 +fi + +echo -e "${YELLOW}Scanning for unused npm dependencies (depcheck)...${NC}" +if npx --yes depcheck 2>/dev/null; then + echo -e "${GREEN}✅ depcheck passed${NC}" +else + echo -e "${RED}❌ depcheck found issues${NC}" + SCAN_FAILED=1 +fi + +if [ $SCAN_FAILED -ne 0 ]; then + echo -e "${RED}❌ Unused code/dependencies detected. Push aborted.${NC}" + echo -e "${YELLOW}To skip this check, use: git push --no-verify${NC}" + exit 1 +fi + +echo -e "${GREEN}✅ Pre-push checks passed${NC}" +exit 0 +HOOK_EOF + + chmod +x "$PRE_PUSH_HOOK" + echo -e "${GREEN}✅ Pre-push hook installed successfully${NC}" +fi echo "" -echo -e "${BLUE}The hook will now run tests before each commit.${NC}" -echo -e "${YELLOW}To skip the hook, use: git commit --no-verify${NC}" +echo -e "${BLUE}Hooks installed:${NC}" +echo -e "${BLUE} - pre-commit: runs core tests before each commit${NC}" +echo -e "${BLUE} - pre-push: scans for unused code/deps before each push${NC}" +echo -e "${YELLOW}To skip hooks, use: git commit --no-verify / git push --no-verify${NC}" echo "" # Check if dependencies are installed