@sebastienrousseau/dotfiles 0.2.481 → 0.2.499
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/ARCHITECTURE.md +29 -196
- package/docs/COMPLIANCE.md +10 -10
- package/docs/COPYRIGHT +3 -4
- package/docs/OPERATIONS.md +38 -65
- package/docs/PLAN.md +3 -3
- package/docs/PR_DESCRIPTION.md +85 -84
- package/docs/ROADMAP.md +11 -11
- package/docs/ROADMAP_legacy.md +556 -0
- package/docs/SECURITY_CHECKLIST.md +1 -1
- package/docs/TASK.md +4 -4
- package/docs/WALKTHROUGH.md +33 -152
- package/package.json +17 -5
- package/scripts/backup.sh +142 -0
- package/scripts/banner.sh +20 -0
- package/scripts/benchmark.sh +20 -0
- package/scripts/build.sh +41 -0
- package/scripts/clean.sh +31 -0
- package/scripts/compile.sh +54 -0
- package/scripts/copy.sh +108 -0
- package/scripts/{tools/detect-collisions.py → detect-collisions.py} +1 -1
- package/scripts/doctor.sh +79 -0
- package/scripts/dotfiles.sh +63 -0
- package/scripts/download.sh +35 -0
- package/scripts/help.sh +57 -0
- package/scripts/lock-configs.sh +57 -0
- package/scripts/package.sh +46 -0
- package/scripts/ssh.sh +55 -0
- package/scripts/teleport.sh +23 -0
- package/scripts/{tests/test-aliases.sh → test-aliases.sh} +3 -3
- package/scripts/test_smoke.sh +88 -0
- package/scripts/unpack.sh +28 -0
- package/scripts/{diagnostics/verify_state.sh → verify_state.sh} +21 -21
- package/templates/projects/go/README.md +0 -4
- package/templates/projects/node/README.md +0 -4
- package/templates/projects/python/README.md +0 -4
- package/templates/projects/python/pyproject.toml +0 -15
- package/CHANGELOG.md +0 -285
- package/LICENSE +0 -1283
- package/README.md +0 -315
- package/docs/ALIASES.md +0 -128
- package/docs/FEATURES.md +0 -166
- package/docs/FONTS.md +0 -147
- package/docs/INSTALL.md +0 -119
- package/docs/KEYS.md +0 -40
- package/docs/KEY_ROTATION.md +0 -219
- package/docs/LEGACY_ROADMAP.md +0 -142
- package/docs/NEOVIM_IDE_GUIDE.md +0 -52
- package/docs/README.md +0 -269
- package/docs/REPO_AUDIT.md +0 -23
- package/docs/SCREENSHOTS.md +0 -116
- package/docs/SECRETS.md +0 -76
- package/docs/SECURITY.md +0 -30
- package/docs/TESTING.md +0 -190
- package/docs/TOOLS.md +0 -146
- package/docs/TROUBLESHOOTING.md +0 -112
- package/docs/UTILS.md +0 -105
- package/docs/WSL2_NIX_TROUBLESHOOTING.md +0 -723
- package/docs/adr/ADR-001-ci-cd-pipeline.md +0 -101
- package/docs/adr/ADR-002-shell-performance.md +0 -121
- package/docs/adr/ADR-003-security-first.md +0 -140
- package/docs/adr/ADR-004-cli-architecture.md +0 -157
- package/docs/adr/ADR-005-chezmoi-choice.md +0 -89
- package/docs/adr/ADR-006-shell-selection.md +0 -115
- package/docs/adr/README.md +0 -33
- package/docs/themes/README.md +0 -20
- package/dot_config/aider/aider.conf.yml +0 -32
- package/dot_config/alacritty/alacritty.toml.tmpl +0 -483
- package/dot_config/ansible/ansible.cfg.tmpl +0 -11
- package/dot_config/atuin/config.toml +0 -23
- package/dot_config/bat/config +0 -8
- package/dot_config/brave-flags.conf.tmpl +0 -7
- package/dot_config/btop/btop.conf +0 -16
- package/dot_config/btop/themes/tokyonight.theme +0 -34
- package/dot_config/bun/bunfig.toml.tmpl +0 -33
- package/dot_config/claude/mcp_servers.json +0 -49
- package/dot_config/clippy.toml +0 -55
- package/dot_config/containers/containers.conf +0 -14
- package/dot_config/curl/dot_curlrc +0 -18
- package/dot_config/dlv/config.yml +0 -39
- package/dot_config/docker/config.json.tmpl +0 -15
- package/dot_config/dotfiles/boot/README.md +0 -11
- package/dot_config/dotfiles/grub/README.md +0 -11
- package/dot_config/dotfiles/lock/README.md +0 -11
- package/dot_config/dotfiles/versions.env.tmpl +0 -19
- package/dot_config/duf/duf.conf +0 -6
- package/dot_config/duti/defaults.duti +0 -5
- package/dot_config/emoji/emoji.txt +0 -34
- package/dot_config/fastfetch/config.jsonc +0 -28
- package/dot_config/firefox/user.js +0 -8
- package/dot_config/flatpak/flatpak.list +0 -4
- package/dot_config/fontconfig/fonts.conf.tmpl +0 -44
- package/dot_config/gem/gemrc +0 -9
- package/dot_config/gh/config.yml +0 -12
- package/dot_config/ghostty/config.tmpl +0 -661
- package/dot_config/git/attributes +0 -12
- package/dot_config/git/config.tmpl +0 -77
- package/dot_config/git/ignore +0 -27
- package/dot_config/gnupg/gpg-agent.conf.tmpl +0 -11
- package/dot_config/go/aliases.sh +0 -61
- package/dot_config/go/env.sh +0 -24
- package/dot_config/go/golangci.yml +0 -118
- package/dot_config/go/gopls.json +0 -30
- package/dot_config/goose/config.yaml +0 -29
- package/dot_config/gtk-3.0/gtk.css.tmpl +0 -305
- package/dot_config/gtk-3.0/settings.ini.tmpl +0 -66
- package/dot_config/gtk-4.0/gtk.css.tmpl +0 -309
- package/dot_config/gtk-4.0/settings.ini.tmpl +0 -21
- package/dot_config/htop/htoprc +0 -20
- package/dot_config/ice/README.md +0 -13
- package/dot_config/inputrc +0 -2
- package/dot_config/ipython/profile_default/ipython_config.py.tmpl +0 -5
- package/dot_config/just/justfile +0 -104
- package/dot_config/k9s/config.yaml.tmpl +0 -65
- package/dot_config/k9s/skins/catppuccin-mocha.yaml +0 -116
- package/dot_config/karabiner/karabiner.json +0 -14
- package/dot_config/kitty/kitty.conf.tmpl +0 -517
- package/dot_config/lazydocker/config.yml +0 -186
- package/dot_config/lazygit/config.yml +0 -23
- package/dot_config/lsd/config.yaml +0 -19
- package/dot_config/mas/masapps.txt +0 -5
- package/dot_config/minikube/config.json +0 -13
- package/dot_config/mise/config.toml +0 -41
- package/dot_config/mongosh/mongoshrc.js +0 -67
- package/dot_config/mycli/myclirc +0 -67
- package/dot_config/nano/nanorc +0 -28
- package/dot_config/ncdu/config +0 -12
- package/dot_config/nvim/init.lua +0 -4
- package/dot_config/nvim/lazy-lock.json +0 -27
- package/dot_config/nvim/lua/config/autocmds.lua +0 -63
- package/dot_config/nvim/lua/config/keymaps.lua +0 -87
- package/dot_config/nvim/lua/config/lazy.lua +0 -34
- package/dot_config/nvim/lua/config/options.lua +0 -48
- package/dot_config/nvim/lua/plugins/coding.lua +0 -234
- package/dot_config/nvim/lua/plugins/dap.lua +0 -201
- package/dot_config/nvim/lua/plugins/editor.lua +0 -59
- package/dot_config/nvim/lua/plugins/git.lua +0 -9
- package/dot_config/nvim/lua/plugins/lsp.lua +0 -221
- package/dot_config/nvim/lua/plugins/markdown.lua +0 -17
- package/dot_config/nvim/lua/plugins/rust.lua +0 -33
- package/dot_config/nvim/lua/plugins/sessions.lua +0 -32
- package/dot_config/nvim/lua/plugins/ui.lua +0 -537
- package/dot_config/nvim/snippets/all.lua +0 -9
- package/dot_config/nvim/snippets/python.lua +0 -16
- package/dot_config/pip/pip.conf.tmpl +0 -32
- package/dot_config/pypoetry/config.toml.tmpl +0 -6
- package/dot_config/pyrightconfig.json.tmpl +0 -5
- package/dot_config/raycast/README.md +0 -13
- package/dot_config/redis/redisclirc +0 -41
- package/dot_config/shell/00-container-detect.sh +0 -53
- package/dot_config/shell/00-core-paths.sh.tmpl +0 -95
- package/dot_config/shell/05-core-safety.sh.tmpl +0 -13
- package/dot_config/shell/40-ls-colors.sh.tmpl +0 -31
- package/dot_config/shell/50-logic-functions.sh.tmpl +0 -10
- package/dot_config/shell/90-theme-switch.sh +0 -70
- package/dot_config/shell/90-ux-aliases.sh.tmpl +0 -35
- package/dot_config/shell/91-ux-aliases-lazy.sh.tmpl +0 -23
- package/dot_config/shell/Brewfile +0 -207
- package/dot_config/shell/Brewfile.cask +0 -92
- package/dot_config/shell/Brewfile.cli +0 -119
- package/dot_config/shell/README.md +0 -267
- package/dot_config/shell/custom/context_suggest.zsh +0 -68
- package/dot_config/shell/custom/error_analysis.zsh +0 -45
- package/dot_config/sops/dot_sops.yaml +0 -23
- package/dot_config/starship.toml.tmpl +0 -124
- package/dot_config/task/Taskfile.yml +0 -86
- package/dot_config/tflint/tflint.hcl.tmpl +0 -9
- package/dot_config/tmux/tmux.conf.tmpl +0 -181
- package/dot_config/topgrade/topgrade.toml.tmpl +0 -42
- package/dot_config/vscode/extensions.txt +0 -11
- package/dot_config/vscode/settings.json.tmpl +0 -123
- package/dot_config/waybar/style.css +0 -8
- package/dot_config/wezterm/wezterm.lua.tmpl +0 -236
- package/dot_config/wget/wgetrc +0 -12
- package/dot_config/yarn/yarnrc.yml.tmpl +0 -36
- package/dot_config/yazi/yazi.toml +0 -40
- package/dot_config/zellij/config.kdl +0 -79
- package/dot_config/zsh/dot_zprofile +0 -13
- package/dot_config/zsh/dot_zshenv +0 -6
- package/dot_config/zsh/dot_zshrc.tmpl +0 -199
- package/dot_config/zsh/rc.d/05-ssh-agent.zsh +0 -5
- package/dot_config/zsh/rc.d/10-env.zsh.tmpl +0 -28
- package/dot_config/zsh/rc.d/20-zinit.zsh.tmpl +0 -22
- package/dot_config/zsh/rc.d/30-options.zsh.tmpl +0 -123
- package/dot_config/zsh/rc.d/40-bell.zsh.tmpl +0 -20
- package/dot_config/zsh/rc.d/50-login-fortune.zsh.tmpl +0 -9
- package/dot_local/bin/executable_ai_core +0 -130
- package/dot_local/bin/executable_b64 +0 -59
- package/dot_local/bin/executable_dot +0 -178
- package/dot_local/bin/executable_dot_completion +0 -55
- package/dot_local/bin/executable_epoch +0 -62
- package/dot_local/bin/executable_extract +0 -108
- package/dot_local/bin/executable_git-ai-commit +0 -160
- package/dot_local/bin/executable_git-ai-diff +0 -154
- package/dot_local/bin/executable_hash +0 -123
- package/dot_local/bin/executable_hex +0 -79
- package/dot_local/bin/executable_ip +0 -37
- package/dot_local/bin/executable_jsonv +0 -54
- package/dot_local/bin/executable_jwt +0 -78
- package/dot_local/bin/executable_kill-port +0 -59
- package/dot_local/bin/executable_lorem +0 -103
- package/dot_local/bin/executable_regex +0 -96
- package/dot_local/bin/executable_tmux-sessionizer +0 -187
- package/dot_local/bin/executable_tour +0 -137
- package/dot_local/bin/executable_update +0 -108
- package/dot_local/bin/executable_uuid +0 -57
- package/dot_local/bin/executable_yamlv +0 -39
- package/dot_local/bin/executable_zig-install +0 -89
- package/dot_local/bin/voice_ops +0 -7
- package/dot_local/share/bash-completion/completions/dot +0 -54
- package/dot_local/share/zsh/completions/.keep +0 -0
- package/install.sh +0 -255
- package/scripts/ci/validate-ci-config.sh +0 -222
- package/scripts/demo/record.sh +0 -41
- package/scripts/diagnostics/benchmark.sh +0 -201
- package/scripts/diagnostics/doctor.sh +0 -115
- package/scripts/diagnostics/drift-dashboard.sh +0 -26
- package/scripts/diagnostics/health.sh +0 -356
- package/scripts/diagnostics/history-analysis.sh +0 -77
- package/scripts/diagnostics/security-score.sh +0 -392
- package/scripts/dot/commands/appearance.sh +0 -63
- package/scripts/dot/commands/core.sh +0 -130
- package/scripts/dot/commands/diagnostics.sh +0 -100
- package/scripts/dot/commands/meta.sh +0 -117
- package/scripts/dot/commands/restore.sh +0 -209
- package/scripts/dot/commands/secrets.sh +0 -81
- package/scripts/dot/commands/security.sh +0 -73
- package/scripts/dot/commands/tools.sh +0 -228
- package/scripts/dot/lib/utils.sh +0 -72
- package/scripts/fonts/install-nerd-fonts.sh +0 -59
- package/scripts/fonts/patch-fonts.sh +0 -34
- package/scripts/ops/chezmoi-apply.sh +0 -42
- package/scripts/ops/chezmoi-diff.sh +0 -14
- package/scripts/ops/chezmoi-remove.sh +0 -43
- package/scripts/ops/chezmoi-update.sh +0 -16
- package/scripts/ops/heal.sh +0 -466
- package/scripts/ops/health-check.sh +0 -380
- package/scripts/ops/rollback.sh +0 -531
- package/scripts/ops/teleport.sh +0 -32
- package/scripts/secrets/age-init.sh +0 -69
- package/scripts/secrets/create-secrets-file.sh +0 -44
- package/scripts/secrets/encrypt-ssh-key.sh +0 -42
- package/scripts/security/backup.sh +0 -17
- package/scripts/security/dns-doh.sh +0 -29
- package/scripts/security/encryption-check.sh +0 -39
- package/scripts/security/enforce-policies.sh +0 -339
- package/scripts/security/firewall.sh +0 -34
- package/scripts/security/lock-configs.sh +0 -57
- package/scripts/security/lock-screen.sh +0 -33
- package/scripts/security/manage-secrets.sh +0 -415
- package/scripts/security/telemetry-kill.sh +0 -28
- package/scripts/security/usb-safety.sh +0 -29
- package/scripts/tests/README.md +0 -241
- package/scripts/tests/benchmark.sh +0 -91
- package/scripts/tests/framework/assertions.sh +0 -283
- package/scripts/tests/framework/mocks.sh +0 -201
- package/scripts/tests/framework/test_runner.sh +0 -189
- package/scripts/tests/integration/test_install.sh +0 -237
- package/scripts/tests/performance/benchmark_runner.sh +0 -156
- package/scripts/tests/performance/regression_check.sh +0 -73
- package/scripts/tests/performance/stress_test.sh +0 -65
- package/scripts/tests/test-docker.sh +0 -48
- package/scripts/tests/unit/test_ai_aliases.sh +0 -158
- package/scripts/tests/unit/test_ai_cli_checks.sh +0 -47
- package/scripts/tests/unit/test_backup.sh +0 -227
- package/scripts/tests/unit/test_case_functions.sh +0 -238
- package/scripts/tests/unit/test_cd_aliases.sh +0 -367
- package/scripts/tests/unit/test_dot_cli.sh +0 -217
- package/scripts/tests/unit/test_encode64.sh +0 -67
- package/scripts/tests/unit/test_environment.sh +0 -78
- package/scripts/tests/unit/test_extract.sh +0 -163
- package/scripts/tests/unit/test_framework_edge_cases.sh +0 -113
- package/scripts/tests/unit/test_genpass.sh +0 -298
- package/scripts/tests/unit/test_install_edge_cases.sh +0 -167
- package/scripts/tests/unit/test_installers.sh +0 -172
- package/scripts/tests/unit/test_keygen.sh +0 -68
- package/scripts/tests/unit/test_logging.sh +0 -96
- package/scripts/tests/unit/test_os_detection_comprehensive.sh +0 -388
- package/scripts/tests/unit/test_package_managers_comprehensive.sh +0 -321
- package/scripts/tests/unit/test_prependpath.sh +0 -66
- package/scripts/tests/unit/test_prependpath_refactored.sh +0 -89
- package/scripts/tests/unit/test_rd.sh +0 -230
- package/scripts/tests/unit/test_security_fixes.sh +0 -130
- package/scripts/tests/unit/test_security_scripts.sh +0 -87
- package/scripts/tests/unit/test_template_validation.sh +0 -238
- package/scripts/tests/unit/test_utility_functions.sh +0 -144
- package/scripts/tests/unit/test_wave1_alias_split.sh +0 -132
- package/scripts/tests/unit/test_wave1_ci_pinning.sh +0 -61
- package/scripts/tests/unit/test_wave1_gitleaks_config.sh +0 -52
- package/scripts/tests/unit/test_wave1_heal_fixes.sh +0 -97
- package/scripts/tests/unit/test_wave1_install_gpg.sh +0 -35
- package/scripts/tests/unit/test_wave1_zshenv_path.sh +0 -89
- package/scripts/tests/unit/test_wave1_zshrc_lazy_hook.sh +0 -115
- package/scripts/tests/unit/test_wave2_dot_new_guard.sh +0 -75
- package/scripts/tests/unit/test_zipf.sh +0 -76
- package/scripts/theme/apply-gnome-theme.sh +0 -297
- package/scripts/theme/install-boot-logo.sh +0 -61
- package/scripts/theme/install-catppuccin-themes.sh +0 -346
- package/scripts/theme/install-cursors.sh +0 -24
- package/scripts/theme/install-file-icons.sh +0 -25
- package/scripts/theme/install-grub-theme.sh +0 -51
- package/scripts/theme/install-lock-icon.sh +0 -29
- package/scripts/theme/switch.sh +0 -250
- package/scripts/theme/wallpaper-rotate.sh +0 -82
- package/scripts/theme/wallpaper-sync.sh +0 -42
- package/scripts/tools/cmatrix.sh +0 -20
- package/scripts/tools/emoji-picker.sh +0 -45
- package/scripts/tools/figlet-banner.sh +0 -17
- package/scripts/tools/log-rotate.sh +0 -29
- package/scripts/tools/lolcat-wrap.sh +0 -18
- package/scripts/tools/pipes.sh +0 -47
- package/scripts/tuning/linux.sh +0 -175
- package/scripts/tuning/macos.sh +0 -46
- package/templates/projects/molecule/README.md +0 -7
- package/templates/projects/molecule/converge.yml +0 -7
- package/templates/projects/molecule/molecule.yml +0 -16
- package/templates/projects/packer/README.md +0 -15
- package/templates/projects/packer/main.pkr.hcl +0 -15
|
@@ -1,415 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# Secure Configuration Management Script
|
|
3
|
-
# Helps manage environment variables and secrets securely
|
|
4
|
-
|
|
5
|
-
set -euo pipefail
|
|
6
|
-
|
|
7
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
8
|
-
readonly SCRIPT_DIR
|
|
9
|
-
REPO_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
|
|
10
|
-
readonly REPO_ROOT
|
|
11
|
-
readonly ENV_TEMPLATE="${REPO_ROOT}/.github/security-policies/environment-template.env"
|
|
12
|
-
readonly ENV_LOCAL="${REPO_ROOT}/.env.local"
|
|
13
|
-
|
|
14
|
-
# Color codes (respect NO_COLOR: https://no-color.org)
|
|
15
|
-
if [[ -z "${NO_COLOR:-}" ]] && [[ -t 1 ]]; then
|
|
16
|
-
readonly RED='\033[0;31m'
|
|
17
|
-
readonly GREEN='\033[0;32m'
|
|
18
|
-
readonly YELLOW='\033[1;33m'
|
|
19
|
-
readonly BLUE='\033[0;34m'
|
|
20
|
-
readonly NC='\033[0m'
|
|
21
|
-
else
|
|
22
|
-
readonly RED='' GREEN='' YELLOW='' BLUE='' NC=''
|
|
23
|
-
fi
|
|
24
|
-
|
|
25
|
-
# Help text
|
|
26
|
-
show_help() {
|
|
27
|
-
cat <<EOF
|
|
28
|
-
Secure Configuration Management
|
|
29
|
-
|
|
30
|
-
USAGE:
|
|
31
|
-
$0 <command> [options]
|
|
32
|
-
|
|
33
|
-
COMMANDS:
|
|
34
|
-
init Initialize secure environment configuration
|
|
35
|
-
validate Validate environment variables and security
|
|
36
|
-
template Show environment variable template
|
|
37
|
-
check Check for hardcoded secrets
|
|
38
|
-
rotate Help rotate secrets and tokens
|
|
39
|
-
clean Clean temporary files and logs
|
|
40
|
-
|
|
41
|
-
OPTIONS:
|
|
42
|
-
-h, --help Show this help message
|
|
43
|
-
-v, --verbose Verbose output
|
|
44
|
-
-f, --force Force operations (use with caution)
|
|
45
|
-
|
|
46
|
-
EXAMPLES:
|
|
47
|
-
$0 init # Initialize .env.local from template
|
|
48
|
-
$0 validate # Validate current configuration
|
|
49
|
-
$0 check # Scan for hardcoded secrets
|
|
50
|
-
$0 rotate github # Guide for rotating GitHub tokens
|
|
51
|
-
$0 clean # Clean up temporary files
|
|
52
|
-
|
|
53
|
-
SECURITY NOTES:
|
|
54
|
-
- Never commit .env.local to version control
|
|
55
|
-
- Use different tokens for different environments
|
|
56
|
-
- Rotate secrets regularly (every 90 days)
|
|
57
|
-
- Use least-privilege principle
|
|
58
|
-
EOF
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
# Logging functions
|
|
62
|
-
log_info() {
|
|
63
|
-
echo -e "${BLUE}[INFO]${NC} $*"
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
log_success() {
|
|
67
|
-
echo -e "${GREEN}[SUCCESS]${NC} $*"
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
log_warning() {
|
|
71
|
-
echo -e "${YELLOW}[WARNING]${NC} $*"
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
log_error() {
|
|
75
|
-
echo -e "${RED}[ERROR]${NC} $*"
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
# Initialize environment configuration
|
|
79
|
-
init_config() {
|
|
80
|
-
local force_init=false
|
|
81
|
-
if [[ "${1:-}" == "--force" ]]; then
|
|
82
|
-
force_init=true
|
|
83
|
-
fi
|
|
84
|
-
|
|
85
|
-
log_info "Initializing secure environment configuration..."
|
|
86
|
-
|
|
87
|
-
if [[ -f "$ENV_LOCAL" ]] && [[ "$force_init" == "false" ]]; then
|
|
88
|
-
log_warning ".env.local already exists"
|
|
89
|
-
echo "Use --force to overwrite, or edit the existing file manually"
|
|
90
|
-
return 1
|
|
91
|
-
fi
|
|
92
|
-
|
|
93
|
-
if [[ ! -f "$ENV_TEMPLATE" ]]; then
|
|
94
|
-
log_error "Environment template not found: $ENV_TEMPLATE"
|
|
95
|
-
return 1
|
|
96
|
-
fi
|
|
97
|
-
|
|
98
|
-
# Copy template
|
|
99
|
-
cp "$ENV_TEMPLATE" "$ENV_LOCAL"
|
|
100
|
-
|
|
101
|
-
# Set secure permissions
|
|
102
|
-
chmod 600 "$ENV_LOCAL"
|
|
103
|
-
|
|
104
|
-
log_success ".env.local created from template"
|
|
105
|
-
log_info "Next steps:"
|
|
106
|
-
echo " 1. Edit .env.local and configure required variables"
|
|
107
|
-
echo " 2. Run '$0 validate' to check configuration"
|
|
108
|
-
echo " 3. Source the file: source .env.local"
|
|
109
|
-
|
|
110
|
-
# Add to .gitignore if not present
|
|
111
|
-
if [[ -f "${REPO_ROOT}/.gitignore" ]]; then
|
|
112
|
-
if ! grep -q "\.env\.local" "${REPO_ROOT}/.gitignore"; then
|
|
113
|
-
echo ".env.local" >>"${REPO_ROOT}/.gitignore"
|
|
114
|
-
log_info "Added .env.local to .gitignore"
|
|
115
|
-
fi
|
|
116
|
-
fi
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
# Validate environment configuration
|
|
120
|
-
validate_config() {
|
|
121
|
-
log_info "Validating environment configuration..."
|
|
122
|
-
|
|
123
|
-
local issues=0
|
|
124
|
-
|
|
125
|
-
# Check if .env.local exists
|
|
126
|
-
if [[ ! -f "$ENV_LOCAL" ]]; then
|
|
127
|
-
log_error ".env.local not found. Run '$0 init' to create it."
|
|
128
|
-
return 1
|
|
129
|
-
fi
|
|
130
|
-
|
|
131
|
-
# Check file permissions
|
|
132
|
-
local perms
|
|
133
|
-
perms=$(stat -c %a "$ENV_LOCAL" 2>/dev/null || stat -f %A "$ENV_LOCAL")
|
|
134
|
-
if [[ "$perms" != "600" ]]; then
|
|
135
|
-
log_warning ".env.local has incorrect permissions ($perms). Should be 600."
|
|
136
|
-
log_info "Fix with: chmod 600 $ENV_LOCAL"
|
|
137
|
-
issues=$((issues + 1))
|
|
138
|
-
fi
|
|
139
|
-
|
|
140
|
-
# Source and validate environment
|
|
141
|
-
# shellcheck source=/dev/null
|
|
142
|
-
if source "$ENV_LOCAL" 2>/dev/null; then
|
|
143
|
-
log_success ".env.local loads successfully"
|
|
144
|
-
else
|
|
145
|
-
log_error ".env.local has syntax errors"
|
|
146
|
-
issues=$((issues + 1))
|
|
147
|
-
fi
|
|
148
|
-
|
|
149
|
-
# Check for required variables
|
|
150
|
-
local required_vars=("GITHUB_TOKEN")
|
|
151
|
-
|
|
152
|
-
for var in "${required_vars[@]}"; do
|
|
153
|
-
if [[ -z "${!var:-}" ]]; then
|
|
154
|
-
log_warning "Required variable $var is not set or empty"
|
|
155
|
-
issues=$((issues + 1))
|
|
156
|
-
else
|
|
157
|
-
log_success "$var is configured"
|
|
158
|
-
fi
|
|
159
|
-
done
|
|
160
|
-
|
|
161
|
-
# Check for security patterns
|
|
162
|
-
if grep -E '(password|secret|key|token)="[^"]{1,}"' "$ENV_LOCAL" >/dev/null 2>&1; then
|
|
163
|
-
log_warning "Found configured credentials (this is expected)"
|
|
164
|
-
fi
|
|
165
|
-
|
|
166
|
-
if [[ $issues -eq 0 ]]; then
|
|
167
|
-
log_success "Environment configuration is valid"
|
|
168
|
-
return 0
|
|
169
|
-
else
|
|
170
|
-
log_error "Found $issues configuration issues"
|
|
171
|
-
return 1
|
|
172
|
-
fi
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
# Show template
|
|
176
|
-
show_template() {
|
|
177
|
-
if [[ -f "$ENV_TEMPLATE" ]]; then
|
|
178
|
-
log_info "Environment variable template:"
|
|
179
|
-
echo "----------------------------------------"
|
|
180
|
-
cat "$ENV_TEMPLATE"
|
|
181
|
-
else
|
|
182
|
-
log_error "Template file not found: $ENV_TEMPLATE"
|
|
183
|
-
return 1
|
|
184
|
-
fi
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
# Check for hardcoded secrets
|
|
188
|
-
check_secrets() {
|
|
189
|
-
log_info "Scanning for hardcoded secrets..."
|
|
190
|
-
|
|
191
|
-
local violations=0
|
|
192
|
-
|
|
193
|
-
# Define patterns to search for
|
|
194
|
-
local patterns=(
|
|
195
|
-
'password\s*=\s*["\047][^"\047]*["\047]'
|
|
196
|
-
'token\s*=\s*["\047][^"\047]*["\047]'
|
|
197
|
-
'secret\s*=\s*["\047][^"\047]*["\047]'
|
|
198
|
-
'key\s*=\s*["\047][^"\047]*["\047]'
|
|
199
|
-
'AKIA[0-9A-Z]{16}' # AWS Access Key
|
|
200
|
-
'ghp_[A-Za-z0-9_]{36}' # GitHub Personal Access Token
|
|
201
|
-
'[0-9a-f]{32,64}' # Potential hash/token
|
|
202
|
-
)
|
|
203
|
-
|
|
204
|
-
# Search in specific file types
|
|
205
|
-
local file_patterns=("*.sh" "*.yml" "*.yaml" "*.toml" "*.json" "*.tmpl")
|
|
206
|
-
|
|
207
|
-
for file_pattern in "${file_patterns[@]}"; do
|
|
208
|
-
while IFS= read -r -d '' file; do
|
|
209
|
-
# Skip the security management files themselves
|
|
210
|
-
if [[ "$file" =~ (environment-template\.env|manage-secrets\.sh|\.env\.local) ]]; then
|
|
211
|
-
continue
|
|
212
|
-
fi
|
|
213
|
-
|
|
214
|
-
for pattern in "${patterns[@]}"; do
|
|
215
|
-
if grep -H -n -E -i "$pattern" "$file" 2>/dev/null; then
|
|
216
|
-
log_warning "Potential secret in $file"
|
|
217
|
-
violations=$((violations + 1))
|
|
218
|
-
fi
|
|
219
|
-
done
|
|
220
|
-
done < <(find "$REPO_ROOT" -name "$file_pattern" -not -path "*/.git/*" -print0)
|
|
221
|
-
done
|
|
222
|
-
|
|
223
|
-
if [[ $violations -eq 0 ]]; then
|
|
224
|
-
log_success "No hardcoded secrets detected"
|
|
225
|
-
else
|
|
226
|
-
log_error "Found $violations potential hardcoded secrets"
|
|
227
|
-
log_info "Review the output above and replace with environment variables"
|
|
228
|
-
fi
|
|
229
|
-
|
|
230
|
-
return $violations
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
# Guide for rotating secrets
|
|
234
|
-
rotate_secrets() {
|
|
235
|
-
local service="${1:-}"
|
|
236
|
-
|
|
237
|
-
if [[ -z "$service" ]]; then
|
|
238
|
-
log_info "Available rotation guides:"
|
|
239
|
-
echo " github - GitHub Personal Access Tokens"
|
|
240
|
-
echo " aws - AWS Access Keys"
|
|
241
|
-
echo " gcp - GCP Service Account Keys"
|
|
242
|
-
echo " ssh - SSH Keys"
|
|
243
|
-
echo ""
|
|
244
|
-
echo "Usage: $0 rotate <service>"
|
|
245
|
-
return 0
|
|
246
|
-
fi
|
|
247
|
-
|
|
248
|
-
case "$service" in
|
|
249
|
-
"github")
|
|
250
|
-
cat <<'EOF'
|
|
251
|
-
GitHub Token Rotation Guide:
|
|
252
|
-
|
|
253
|
-
1. Create new Personal Access Token:
|
|
254
|
-
- Go to https://github.com/settings/tokens
|
|
255
|
-
- Click "Generate new token (classic)"
|
|
256
|
-
- Set expiration (90 days recommended)
|
|
257
|
-
- Select minimal required scopes:
|
|
258
|
-
• repo (for private repos)
|
|
259
|
-
• workflow (for GitHub Actions)
|
|
260
|
-
|
|
261
|
-
2. Update environment:
|
|
262
|
-
- Edit .env.local
|
|
263
|
-
- Replace GITHUB_TOKEN value
|
|
264
|
-
- Test with: gh auth status
|
|
265
|
-
|
|
266
|
-
3. Update CI/CD:
|
|
267
|
-
- Go to repository Settings → Secrets and variables → Actions
|
|
268
|
-
- Update GITHUB_TOKEN secret
|
|
269
|
-
|
|
270
|
-
4. Revoke old token:
|
|
271
|
-
- Go back to https://github.com/settings/tokens
|
|
272
|
-
- Find old token and click "Delete"
|
|
273
|
-
|
|
274
|
-
5. Verify:
|
|
275
|
-
- Run: scripts/security/manage-secrets.sh validate
|
|
276
|
-
- Test repository operations
|
|
277
|
-
EOF
|
|
278
|
-
;;
|
|
279
|
-
"aws")
|
|
280
|
-
cat <<'EOF'
|
|
281
|
-
AWS Access Key Rotation Guide:
|
|
282
|
-
|
|
283
|
-
1. Create new access key:
|
|
284
|
-
- AWS Console → IAM → Users → [Your User] → Security credentials
|
|
285
|
-
- Click "Create access key"
|
|
286
|
-
- Download credentials
|
|
287
|
-
|
|
288
|
-
2. Update environment:
|
|
289
|
-
- Edit .env.local
|
|
290
|
-
- Update AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
|
|
291
|
-
- Test with: aws sts get-caller-identity
|
|
292
|
-
|
|
293
|
-
3. Update CI/CD:
|
|
294
|
-
- Update secrets in GitHub repository
|
|
295
|
-
- Test AWS operations in pipeline
|
|
296
|
-
|
|
297
|
-
4. Deactivate old key:
|
|
298
|
-
- In AWS Console, set old key status to "Inactive"
|
|
299
|
-
- Wait 24-48 hours, monitor for issues
|
|
300
|
-
- Delete old key if no issues
|
|
301
|
-
|
|
302
|
-
5. Security best practices:
|
|
303
|
-
- Use IAM roles where possible
|
|
304
|
-
- Implement least privilege access
|
|
305
|
-
- Enable CloudTrail logging
|
|
306
|
-
EOF
|
|
307
|
-
;;
|
|
308
|
-
"ssh")
|
|
309
|
-
cat <<'EOF'
|
|
310
|
-
SSH Key Rotation Guide:
|
|
311
|
-
|
|
312
|
-
1. Generate new SSH key:
|
|
313
|
-
- Run: ssh-keygen -t ed25519 -C "your_email@example.com"
|
|
314
|
-
- Save to new file: ~/.ssh/id_ed25519_new
|
|
315
|
-
|
|
316
|
-
2. Add to SSH agent:
|
|
317
|
-
- Run: ssh-add ~/.ssh/id_ed25519_new
|
|
318
|
-
|
|
319
|
-
3. Update remote services:
|
|
320
|
-
- GitHub: Settings → SSH and GPG keys → Add new key
|
|
321
|
-
- Servers: Add to ~/.ssh/authorized_keys
|
|
322
|
-
|
|
323
|
-
4. Update local config:
|
|
324
|
-
- Edit ~/.ssh/config
|
|
325
|
-
- Update IdentityFile paths
|
|
326
|
-
|
|
327
|
-
5. Test connections:
|
|
328
|
-
- ssh -T git@github.com
|
|
329
|
-
- Test server connections
|
|
330
|
-
|
|
331
|
-
6. Remove old keys:
|
|
332
|
-
- Remove from remote authorized_keys
|
|
333
|
-
- Remove from local ~/.ssh/
|
|
334
|
-
- Remove from SSH agent
|
|
335
|
-
EOF
|
|
336
|
-
;;
|
|
337
|
-
*)
|
|
338
|
-
log_error "Unknown service: $service"
|
|
339
|
-
log_info "Available services: github, aws, gcp, ssh"
|
|
340
|
-
return 1
|
|
341
|
-
;;
|
|
342
|
-
esac
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
# Clean temporary files
|
|
346
|
-
clean_files() {
|
|
347
|
-
log_info "Cleaning temporary files and logs..."
|
|
348
|
-
|
|
349
|
-
local files_to_clean=(
|
|
350
|
-
"${REPO_ROOT}/.security-audit.log"
|
|
351
|
-
"${REPO_ROOT}/security-report.md"
|
|
352
|
-
"${REPO_ROOT}/trivy-results.sarif"
|
|
353
|
-
"${REPO_ROOT}/grype-results.sarif"
|
|
354
|
-
"${REPO_ROOT}/checkov-results.sarif"
|
|
355
|
-
"${REPO_ROOT}/shellcheck-results.sarif"
|
|
356
|
-
"${REPO_ROOT}/container-scan.sarif"
|
|
357
|
-
"${REPO_ROOT}/security-attestation.json"
|
|
358
|
-
)
|
|
359
|
-
|
|
360
|
-
local cleaned=0
|
|
361
|
-
for file in "${files_to_clean[@]}"; do
|
|
362
|
-
if [[ -f "$file" ]]; then
|
|
363
|
-
rm "$file"
|
|
364
|
-
log_success "Removed $file"
|
|
365
|
-
cleaned=$((cleaned + 1))
|
|
366
|
-
fi
|
|
367
|
-
done
|
|
368
|
-
|
|
369
|
-
if [[ $cleaned -eq 0 ]]; then
|
|
370
|
-
log_info "No temporary files to clean"
|
|
371
|
-
else
|
|
372
|
-
log_success "Cleaned $cleaned temporary files"
|
|
373
|
-
fi
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
# Main function
|
|
377
|
-
main() {
|
|
378
|
-
local command="${1:-}"
|
|
379
|
-
shift || true
|
|
380
|
-
|
|
381
|
-
case "$command" in
|
|
382
|
-
"init")
|
|
383
|
-
init_config "$@"
|
|
384
|
-
;;
|
|
385
|
-
"validate")
|
|
386
|
-
validate_config
|
|
387
|
-
;;
|
|
388
|
-
"template")
|
|
389
|
-
show_template
|
|
390
|
-
;;
|
|
391
|
-
"check")
|
|
392
|
-
check_secrets
|
|
393
|
-
;;
|
|
394
|
-
"rotate")
|
|
395
|
-
rotate_secrets "$@"
|
|
396
|
-
;;
|
|
397
|
-
"clean")
|
|
398
|
-
clean_files
|
|
399
|
-
;;
|
|
400
|
-
"-h" | "--help" | "help" | "")
|
|
401
|
-
show_help
|
|
402
|
-
;;
|
|
403
|
-
*)
|
|
404
|
-
log_error "Unknown command: $command"
|
|
405
|
-
echo ""
|
|
406
|
-
show_help
|
|
407
|
-
exit 1
|
|
408
|
-
;;
|
|
409
|
-
esac
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
# Execute if run directly
|
|
413
|
-
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|
414
|
-
main "$@"
|
|
415
|
-
fi
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
#!/bin/sh
|
|
2
|
-
set -e
|
|
3
|
-
|
|
4
|
-
if [ "${DOTFILES_TELEMETRY:-}" != "1" ]; then
|
|
5
|
-
echo "Telemetry script is disabled by default."
|
|
6
|
-
echo "Re-run with DOTFILES_TELEMETRY=1 to apply."
|
|
7
|
-
exit 1
|
|
8
|
-
fi
|
|
9
|
-
|
|
10
|
-
case "$(uname -s)" in
|
|
11
|
-
Linux)
|
|
12
|
-
echo "Disabling Ubuntu crash reporting (whoopsie/apport)..."
|
|
13
|
-
sudo systemctl disable --now whoopsie 2>/dev/null || true
|
|
14
|
-
sudo systemctl disable --now apport 2>/dev/null || true
|
|
15
|
-
sudo systemctl mask apport 2>/dev/null || true
|
|
16
|
-
echo "Disabling popularity-contest (if present)..."
|
|
17
|
-
sudo systemctl disable --now popularity-contest 2>/dev/null || true
|
|
18
|
-
;;
|
|
19
|
-
Darwin)
|
|
20
|
-
echo "Disabling macOS analytics (manual confirmation may be required)."
|
|
21
|
-
sudo defaults write /Library/Application\ Support/CrashReporter/DiagnosticMessagesHistory.plist AutoSubmit -bool false || true
|
|
22
|
-
sudo defaults write /Library/Application\ Support/CrashReporter/DiagnosticMessagesHistory.plist ThirdPartyDataSubmit -bool false || true
|
|
23
|
-
;;
|
|
24
|
-
*)
|
|
25
|
-
echo "Unsupported OS for telemetry kill."
|
|
26
|
-
exit 1
|
|
27
|
-
;;
|
|
28
|
-
esac
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
#!/bin/sh
|
|
2
|
-
set -e
|
|
3
|
-
|
|
4
|
-
if [ "${DOTFILES_USB_SAFETY:-}" != "1" ]; then
|
|
5
|
-
echo "USB safety script is disabled by default."
|
|
6
|
-
echo "Re-run with DOTFILES_USB_SAFETY=1 to apply."
|
|
7
|
-
exit 1
|
|
8
|
-
fi
|
|
9
|
-
|
|
10
|
-
case "$(uname -s)" in
|
|
11
|
-
Linux)
|
|
12
|
-
if command -v gsettings >/dev/null; then
|
|
13
|
-
echo "Disabling GNOME automount for removable media..."
|
|
14
|
-
gsettings set org.gnome.desktop.media-handling automount false || true
|
|
15
|
-
gsettings set org.gnome.desktop.media-handling automount-open false || true
|
|
16
|
-
else
|
|
17
|
-
echo "gsettings not found."
|
|
18
|
-
exit 1
|
|
19
|
-
fi
|
|
20
|
-
;;
|
|
21
|
-
Darwin)
|
|
22
|
-
echo "macOS does not expose a simple CLI toggle for USB automount."
|
|
23
|
-
echo "Use System Settings > General > Login Items > External disks."
|
|
24
|
-
;;
|
|
25
|
-
*)
|
|
26
|
-
echo "Unsupported OS for USB safety."
|
|
27
|
-
exit 1
|
|
28
|
-
;;
|
|
29
|
-
esac
|
package/scripts/tests/README.md
DELETED
|
@@ -1,241 +0,0 @@
|
|
|
1
|
-
# Dotfiles Test Suite
|
|
2
|
-
|
|
3
|
-
A comprehensive shell testing framework for validating dotfiles functionality.
|
|
4
|
-
|
|
5
|
-
## Directory Structure
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
scripts/tests/
|
|
9
|
-
├── framework/
|
|
10
|
-
│ ├── test_runner.sh # Main test runner
|
|
11
|
-
│ ├── assertions.sh # Assert functions
|
|
12
|
-
│ └── mocks.sh # Mock utilities
|
|
13
|
-
├── unit/
|
|
14
|
-
│ ├── test_extract.sh # Tests for extract function
|
|
15
|
-
│ ├── test_backup.sh # Tests for backup function
|
|
16
|
-
│ ├── test_genpass.sh # Tests for genpass function
|
|
17
|
-
│ ├── test_rd.sh # Tests for rd function
|
|
18
|
-
│ └── test_cd_aliases.sh # Tests for cd aliases
|
|
19
|
-
├── integration/
|
|
20
|
-
│ └── test_install.sh # Tests for install.sh
|
|
21
|
-
└── README.md # This file
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
## Quick Start
|
|
25
|
-
|
|
26
|
-
### Run All Unit Tests
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
|
-
./scripts/tests/framework/test_runner.sh
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
### Run Specific Test
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
# Run only extract tests
|
|
36
|
-
./scripts/tests/framework/test_runner.sh extract
|
|
37
|
-
|
|
38
|
-
# Run only backup tests
|
|
39
|
-
./scripts/tests/framework/test_runner.sh backup
|
|
40
|
-
|
|
41
|
-
# Run only genpass tests
|
|
42
|
-
./scripts/tests/framework/test_runner.sh genpass
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
### Run with Integration Tests
|
|
46
|
-
|
|
47
|
-
```bash
|
|
48
|
-
# Using environment variable
|
|
49
|
-
RUN_INTEGRATION=1 ./scripts/tests/framework/test_runner.sh
|
|
50
|
-
|
|
51
|
-
# Using flag
|
|
52
|
-
./scripts/tests/framework/test_runner.sh -i
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
### Run Individual Test File
|
|
56
|
-
|
|
57
|
-
```bash
|
|
58
|
-
# Source assertions and run directly
|
|
59
|
-
source ./scripts/tests/framework/assertions.sh
|
|
60
|
-
source ./scripts/tests/unit/test_extract.sh
|
|
61
|
-
print_summary
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
## Test Framework
|
|
65
|
-
|
|
66
|
-
### Assertions
|
|
67
|
-
|
|
68
|
-
The framework provides these assertion functions:
|
|
69
|
-
|
|
70
|
-
| Function | Description |
|
|
71
|
-
|----------|-------------|
|
|
72
|
-
| `assert_equals expected actual [msg]` | Assert two values are equal |
|
|
73
|
-
| `assert_not_equals unexpected actual [msg]` | Assert two values differ |
|
|
74
|
-
| `assert_exit_code code command` | Assert command exits with code |
|
|
75
|
-
| `assert_output_contains needle command` | Assert output contains string |
|
|
76
|
-
| `assert_output_not_contains needle command` | Assert output lacks string |
|
|
77
|
-
| `assert_output_matches pattern command` | Assert output matches regex |
|
|
78
|
-
| `assert_file_exists path [msg]` | Assert file exists |
|
|
79
|
-
| `assert_file_not_exists path [msg]` | Assert file doesn't exist |
|
|
80
|
-
| `assert_dir_exists path [msg]` | Assert directory exists |
|
|
81
|
-
| `assert_dir_not_exists path [msg]` | Assert directory doesn't exist |
|
|
82
|
-
| `assert_true condition [msg]` | Assert condition is true |
|
|
83
|
-
| `assert_false condition [msg]` | Assert condition is false |
|
|
84
|
-
| `assert_empty value [msg]` | Assert string is empty |
|
|
85
|
-
| `assert_not_empty value [msg]` | Assert string is not empty |
|
|
86
|
-
| `assert_file_contains file needle [msg]` | Assert file contains text |
|
|
87
|
-
|
|
88
|
-
### Mocks
|
|
89
|
-
|
|
90
|
-
The mock library provides utilities for test isolation:
|
|
91
|
-
|
|
92
|
-
| Function | Description |
|
|
93
|
-
|----------|-------------|
|
|
94
|
-
| `mock_init` | Initialize mock environment |
|
|
95
|
-
| `mock_command name output [exit_code]` | Create mock command |
|
|
96
|
-
| `mock_command_spy name [output] [exit_code]` | Create mock that records calls |
|
|
97
|
-
| `mock_get_calls name` | Get spy call history |
|
|
98
|
-
| `mock_call_count name` | Get number of spy calls |
|
|
99
|
-
| `mock_file content [filename]` | Create temp file with content |
|
|
100
|
-
| `mock_dir [prefix]` | Create temp directory |
|
|
101
|
-
| `mock_archive type [content]` | Create mock archive file |
|
|
102
|
-
| `mock_env var_name value` | Set environment variable |
|
|
103
|
-
| `mock_cleanup` | Clean up all mocks |
|
|
104
|
-
|
|
105
|
-
## Writing Tests
|
|
106
|
-
|
|
107
|
-
### Basic Test Structure
|
|
108
|
-
|
|
109
|
-
```bash
|
|
110
|
-
#!/usr/bin/env bash
|
|
111
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
112
|
-
source "$SCRIPT_DIR/../framework/assertions.sh"
|
|
113
|
-
source "$SCRIPT_DIR/../framework/mocks.sh"
|
|
114
|
-
|
|
115
|
-
# Source function being tested
|
|
116
|
-
source "$REPO_ROOT/.chezmoitemplates/functions/myfunction.sh"
|
|
117
|
-
|
|
118
|
-
# Test case
|
|
119
|
-
test_start "my_function_basic"
|
|
120
|
-
output=$(myfunction "arg" 2>&1)
|
|
121
|
-
assert_equals "expected" "$output" "should return expected"
|
|
122
|
-
|
|
123
|
-
# Another test
|
|
124
|
-
test_start "my_function_error"
|
|
125
|
-
output=$(myfunction 2>&1)
|
|
126
|
-
exit_code=$?
|
|
127
|
-
assert_equals "1" "$exit_code" "should fail without args"
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
### Using Mocks
|
|
131
|
-
|
|
132
|
-
```bash
|
|
133
|
-
test_start "function_with_mock"
|
|
134
|
-
# Create temp directory
|
|
135
|
-
test_dir=$(mock_dir "test")
|
|
136
|
-
test_file="$test_dir/file.txt"
|
|
137
|
-
echo "content" > "$test_file"
|
|
138
|
-
|
|
139
|
-
# Run test
|
|
140
|
-
result=$(myfunction "$test_file")
|
|
141
|
-
|
|
142
|
-
# Verify
|
|
143
|
-
assert_equals "expected" "$result"
|
|
144
|
-
|
|
145
|
-
# Cleanup is automatic via trap
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
### Test Naming Convention
|
|
149
|
-
|
|
150
|
-
- Test files: `test_<functionality>.sh`
|
|
151
|
-
- Test functions: Descriptive names with `test_start`
|
|
152
|
-
- Example: `test_start "extract_handles_missing_file"`
|
|
153
|
-
|
|
154
|
-
## Environment Variables
|
|
155
|
-
|
|
156
|
-
| Variable | Default | Description |
|
|
157
|
-
|----------|---------|-------------|
|
|
158
|
-
| `RUN_INTEGRATION` | `0` | Set to `1` to run integration tests |
|
|
159
|
-
| `VERBOSE` | `0` | Set to `1` for verbose output |
|
|
160
|
-
| `REPO_ROOT` | Auto-detected | Repository root directory |
|
|
161
|
-
| `TESTS_DIR` | Auto-detected | Tests directory |
|
|
162
|
-
|
|
163
|
-
## Test Categories
|
|
164
|
-
|
|
165
|
-
### Unit Tests
|
|
166
|
-
|
|
167
|
-
Located in `scripts/tests/unit/`. These test individual functions in isolation:
|
|
168
|
-
|
|
169
|
-
- **test_extract.sh** - Archive extraction function
|
|
170
|
-
- **test_backup.sh** - Backup creation function
|
|
171
|
-
- **test_genpass.sh** - Password generation function
|
|
172
|
-
- **test_rd.sh** - Directory removal function (with security tests)
|
|
173
|
-
- **test_cd_aliases.sh** - Directory navigation aliases
|
|
174
|
-
|
|
175
|
-
### Integration Tests
|
|
176
|
-
|
|
177
|
-
Located in `scripts/tests/integration/`. These test complete workflows:
|
|
178
|
-
|
|
179
|
-
- **test_install.sh** - Installation script validation
|
|
180
|
-
|
|
181
|
-
## CI/CD Integration
|
|
182
|
-
|
|
183
|
-
Add to your CI pipeline:
|
|
184
|
-
|
|
185
|
-
```yaml
|
|
186
|
-
# GitHub Actions example
|
|
187
|
-
- name: Run Tests
|
|
188
|
-
run: |
|
|
189
|
-
chmod +x ./scripts/tests/framework/test_runner.sh
|
|
190
|
-
./scripts/tests/framework/test_runner.sh
|
|
191
|
-
|
|
192
|
-
- name: Run Integration Tests
|
|
193
|
-
run: |
|
|
194
|
-
RUN_INTEGRATION=1 ./scripts/tests/framework/test_runner.sh
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
## Best Practices
|
|
198
|
-
|
|
199
|
-
1. **Isolation**: Each test should be independent
|
|
200
|
-
2. **Cleanup**: Use mocks that auto-cleanup via traps
|
|
201
|
-
3. **No Sleep**: Avoid `sleep` or hardcoded delays
|
|
202
|
-
4. **Descriptive Names**: Test names should describe what's being tested
|
|
203
|
-
5. **Edge Cases**: Test error conditions, not just happy paths
|
|
204
|
-
6. **Security**: Include tests for dangerous input rejection
|
|
205
|
-
|
|
206
|
-
## Troubleshooting
|
|
207
|
-
|
|
208
|
-
### Tests Not Found
|
|
209
|
-
|
|
210
|
-
Ensure test files match the pattern `test_*.sh` and are executable:
|
|
211
|
-
|
|
212
|
-
```bash
|
|
213
|
-
chmod +x scripts/tests/unit/test_*.sh
|
|
214
|
-
chmod +x scripts/tests/integration/test_*.sh
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
### Function Not Available
|
|
218
|
-
|
|
219
|
-
If a test shows "function not available", the source file may not exist:
|
|
220
|
-
|
|
221
|
-
```bash
|
|
222
|
-
# Check if function file exists
|
|
223
|
-
ls -la .chezmoitemplates/functions/
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
### Mock Cleanup Issues
|
|
227
|
-
|
|
228
|
-
If mocks aren't cleaning up, ensure you're not running with `set -e` before mock operations that might fail.
|
|
229
|
-
|
|
230
|
-
## Contributing
|
|
231
|
-
|
|
232
|
-
When adding new functions to the dotfiles:
|
|
233
|
-
|
|
234
|
-
1. Create corresponding test file in `unit/`
|
|
235
|
-
2. Test happy path and error conditions
|
|
236
|
-
3. Include security-relevant test cases
|
|
237
|
-
4. Run full test suite before committing
|
|
238
|
-
|
|
239
|
-
---
|
|
240
|
-
|
|
241
|
-
Made with ❤️ by [Sebastien Rousseau](https://github.com/sebastienrousseau)
|