@fredlackey/devutils 0.0.18 → 0.1.0
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/README.md +214 -141
- package/package.json +8 -83
- package/src/api/loader.js +229 -0
- package/src/api/registry.json +62 -0
- package/src/cli.js +293 -60
- package/src/commands/ai/index.js +16 -0
- package/src/commands/ai/launch.js +112 -0
- package/src/commands/ai/list.js +54 -0
- package/src/commands/ai/resume.js +70 -0
- package/src/commands/ai/sessions.js +121 -0
- package/src/commands/ai/set.js +131 -0
- package/src/commands/ai/show.js +74 -0
- package/src/commands/ai/tools.js +46 -0
- package/src/commands/alias/add.js +93 -0
- package/src/commands/alias/helpers.js +107 -0
- package/src/commands/alias/index.js +14 -0
- package/src/commands/alias/list.js +55 -0
- package/src/commands/alias/remove.js +62 -0
- package/src/commands/alias/sync.js +109 -0
- package/src/commands/api/disable.js +73 -0
- package/src/commands/api/enable.js +148 -0
- package/src/commands/api/index.js +15 -0
- package/src/commands/api/list.js +66 -0
- package/src/commands/api/update.js +87 -0
- package/src/commands/auth/index.js +15 -0
- package/src/commands/auth/list.js +49 -0
- package/src/commands/auth/login.js +384 -0
- package/src/commands/auth/logout.js +111 -0
- package/src/commands/auth/refresh.js +184 -0
- package/src/commands/auth/services.js +169 -0
- package/src/commands/auth/status.js +104 -0
- package/src/commands/config/export.js +224 -0
- package/src/commands/config/get.js +52 -0
- package/src/commands/config/import.js +308 -0
- package/src/commands/config/index.js +17 -0
- package/src/commands/config/init.js +143 -0
- package/src/commands/config/reset.js +57 -0
- package/src/commands/config/set.js +93 -0
- package/src/commands/config/show.js +35 -0
- package/src/commands/help.js +338 -0
- package/src/commands/identity/add.js +133 -0
- package/src/commands/identity/index.js +17 -0
- package/src/commands/identity/link.js +76 -0
- package/src/commands/identity/list.js +48 -0
- package/src/commands/identity/remove.js +72 -0
- package/src/commands/identity/show.js +65 -0
- package/src/commands/identity/sync.js +172 -0
- package/src/commands/identity/unlink.js +57 -0
- package/src/commands/ignore/add.js +165 -0
- package/src/commands/ignore/index.js +14 -0
- package/src/commands/ignore/list.js +89 -0
- package/src/commands/ignore/markers.js +43 -0
- package/src/commands/ignore/remove.js +164 -0
- package/src/commands/ignore/show.js +169 -0
- package/src/commands/machine/detect.js +122 -0
- package/src/commands/machine/index.js +14 -0
- package/src/commands/machine/list.js +74 -0
- package/src/commands/machine/set.js +106 -0
- package/src/commands/machine/show.js +35 -0
- package/src/commands/schema.js +152 -0
- package/src/commands/search/collections.js +134 -0
- package/src/commands/search/get.js +71 -0
- package/src/commands/search/index-cmd.js +54 -0
- package/src/commands/search/index.js +21 -0
- package/src/commands/search/keyword.js +60 -0
- package/src/commands/search/qmd.js +70 -0
- package/src/commands/search/query.js +64 -0
- package/src/commands/search/semantic.js +62 -0
- package/src/commands/search/status.js +46 -0
- package/src/commands/status.js +224 -171
- package/src/commands/tools/check.js +79 -0
- package/src/commands/tools/index.js +14 -0
- package/src/commands/tools/install.js +110 -0
- package/src/commands/tools/list.js +91 -0
- package/src/commands/tools/search.js +60 -0
- package/src/commands/update.js +83 -112
- package/src/commands/util/add.js +151 -0
- package/src/commands/util/index.js +15 -0
- package/src/commands/util/list.js +97 -0
- package/src/commands/util/remove.js +76 -0
- package/src/commands/util/run.js +79 -0
- package/src/commands/util/show.js +67 -0
- package/src/commands/version.js +21 -88
- package/src/installers/_template.js +104 -0
- package/src/installers/git.js +150 -0
- package/src/installers/homebrew.js +190 -0
- package/src/installers/node.js +223 -0
- package/src/installers/registry.json +29 -0
- package/src/lib/config.js +125 -0
- package/src/lib/detect.js +74 -0
- package/src/lib/errors.js +114 -0
- package/src/lib/github.js +315 -0
- package/src/lib/installer.js +225 -0
- package/src/lib/output.js +239 -0
- package/src/lib/platform.js +112 -0
- package/src/lib/platforms/amazon-linux.js +41 -0
- package/src/lib/platforms/gitbash.js +46 -0
- package/src/lib/platforms/macos.js +45 -0
- package/src/lib/platforms/raspbian.js +41 -0
- package/src/lib/platforms/ubuntu.js +39 -0
- package/src/lib/platforms/windows.js +45 -0
- package/src/lib/prompt.js +161 -0
- package/src/lib/schema.js +211 -0
- package/src/lib/shell.js +75 -0
- package/src/patterns/gitignore/claude-code.txt +25 -0
- package/src/patterns/gitignore/docker.txt +15 -0
- package/src/patterns/gitignore/go.txt +24 -0
- package/src/patterns/gitignore/java.txt +38 -0
- package/src/patterns/gitignore/jetbrains.txt +26 -0
- package/src/patterns/gitignore/linux.txt +18 -0
- package/src/patterns/gitignore/macos.txt +27 -0
- package/src/patterns/gitignore/node.txt +51 -0
- package/src/patterns/gitignore/python.txt +55 -0
- package/src/patterns/gitignore/rust.txt +14 -0
- package/src/patterns/gitignore/terraform.txt +30 -0
- package/src/patterns/gitignore/vscode.txt +15 -0
- package/src/patterns/gitignore/windows.txt +25 -0
- package/src/utils/clone/index.js +165 -0
- package/src/utils/git-push/index.js +230 -0
- package/src/utils/git-status/index.js +116 -0
- package/src/utils/git-status/unix.sh +75 -0
- package/src/utils/registry.json +41 -0
- package/bin/dev.js +0 -16
- package/files/README.md +0 -0
- package/files/claude/.claude/commands/setup-context.md +0 -3
- package/files/monorepos/_archive/README.md +0 -36
- package/files/monorepos/_legacy/README.md +0 -36
- package/files/monorepos/ai-docs/README.md +0 -33
- package/files/monorepos/apps/README.md +0 -24
- package/files/monorepos/docs/README.md +0 -40
- package/files/monorepos/packages/README.md +0 -25
- package/files/monorepos/research/README.md +0 -29
- package/files/monorepos/scripts/README.md +0 -24
- package/src/commands/README.md +0 -41
- package/src/commands/configure.js +0 -199
- package/src/commands/identity.js +0 -1630
- package/src/commands/ignore.js +0 -247
- package/src/commands/install.js +0 -526
- package/src/commands/setup.js +0 -246
- package/src/completion.js +0 -284
- package/src/constants.js +0 -45
- package/src/ignore/claude-code.txt +0 -10
- package/src/ignore/docker.txt +0 -18
- package/src/ignore/linux.txt +0 -23
- package/src/ignore/macos.txt +0 -36
- package/src/ignore/node.txt +0 -55
- package/src/ignore/terraform.txt +0 -37
- package/src/ignore/vscode.txt +0 -18
- package/src/ignore/windows.txt +0 -35
- package/src/index.js +0 -0
- package/src/installs/README.md +0 -399
- package/src/installs/adobe-creative-cloud.js +0 -546
- package/src/installs/adobe-creative-cloud.md +0 -605
- package/src/installs/appcleaner.js +0 -321
- package/src/installs/appcleaner.md +0 -699
- package/src/installs/apt-transport-https.js +0 -390
- package/src/installs/apt-transport-https.md +0 -678
- package/src/installs/atomicparsley.js +0 -642
- package/src/installs/atomicparsley.md +0 -795
- package/src/installs/aws-cli.js +0 -797
- package/src/installs/aws-cli.md +0 -727
- package/src/installs/balena-etcher.js +0 -710
- package/src/installs/balena-etcher.md +0 -761
- package/src/installs/bambu-studio.js +0 -1143
- package/src/installs/bambu-studio.md +0 -780
- package/src/installs/bash-completion.js +0 -575
- package/src/installs/bash-completion.md +0 -833
- package/src/installs/bash.js +0 -417
- package/src/installs/bash.md +0 -993
- package/src/installs/beyond-compare.js +0 -603
- package/src/installs/beyond-compare.md +0 -813
- package/src/installs/brave-browser.js +0 -968
- package/src/installs/brave-browser.md +0 -650
- package/src/installs/build-essential.js +0 -529
- package/src/installs/build-essential.md +0 -977
- package/src/installs/ca-certificates.js +0 -618
- package/src/installs/ca-certificates.md +0 -937
- package/src/installs/caffeine.js +0 -508
- package/src/installs/caffeine.md +0 -839
- package/src/installs/camtasia.js +0 -596
- package/src/installs/camtasia.md +0 -762
- package/src/installs/chatgpt.js +0 -476
- package/src/installs/chatgpt.md +0 -814
- package/src/installs/chocolatey.js +0 -456
- package/src/installs/chocolatey.md +0 -661
- package/src/installs/chrome-canary.js +0 -419
- package/src/installs/chrome-canary.md +0 -641
- package/src/installs/chromium.js +0 -667
- package/src/installs/chromium.md +0 -838
- package/src/installs/claude-code.js +0 -576
- package/src/installs/claude-code.md +0 -1173
- package/src/installs/cloudflare-warp.js +0 -900
- package/src/installs/cloudflare-warp.md +0 -1047
- package/src/installs/comet-browser.js +0 -588
- package/src/installs/comet-browser.md +0 -731
- package/src/installs/curl.js +0 -379
- package/src/installs/curl.md +0 -714
- package/src/installs/cursor.js +0 -579
- package/src/installs/cursor.md +0 -970
- package/src/installs/dbeaver.js +0 -924
- package/src/installs/dbeaver.md +0 -939
- package/src/installs/dbschema.js +0 -692
- package/src/installs/dbschema.md +0 -925
- package/src/installs/dependencies.md +0 -453
- package/src/installs/development-tools.js +0 -600
- package/src/installs/development-tools.md +0 -977
- package/src/installs/docker.js +0 -1029
- package/src/installs/docker.md +0 -1109
- package/src/installs/drawio.js +0 -1019
- package/src/installs/drawio.md +0 -795
- package/src/installs/elmedia-player.js +0 -347
- package/src/installs/elmedia-player.md +0 -556
- package/src/installs/ffmpeg.js +0 -889
- package/src/installs/ffmpeg.md +0 -852
- package/src/installs/file.js +0 -464
- package/src/installs/file.md +0 -987
- package/src/installs/gemini-cli.js +0 -811
- package/src/installs/gemini-cli.md +0 -1153
- package/src/installs/git.js +0 -400
- package/src/installs/git.md +0 -907
- package/src/installs/gitego.js +0 -949
- package/src/installs/gitego.md +0 -1172
- package/src/installs/go.js +0 -931
- package/src/installs/go.md +0 -958
- package/src/installs/google-antigravity.js +0 -913
- package/src/installs/google-antigravity.md +0 -1075
- package/src/installs/google-chrome.js +0 -833
- package/src/installs/google-chrome.md +0 -862
- package/src/installs/gpg.js +0 -480
- package/src/installs/gpg.md +0 -1056
- package/src/installs/homebrew.js +0 -1028
- package/src/installs/homebrew.md +0 -988
- package/src/installs/imageoptim.js +0 -968
- package/src/installs/imageoptim.md +0 -1119
- package/src/installs/installers.json +0 -4032
- package/src/installs/installers.json.tmp +0 -3953
- package/src/installs/jq.js +0 -400
- package/src/installs/jq.md +0 -809
- package/src/installs/keyboard-maestro.js +0 -719
- package/src/installs/keyboard-maestro.md +0 -825
- package/src/installs/kiro.js +0 -864
- package/src/installs/kiro.md +0 -1015
- package/src/installs/latex.js +0 -789
- package/src/installs/latex.md +0 -1095
- package/src/installs/lftp.js +0 -356
- package/src/installs/lftp.md +0 -907
- package/src/installs/lsb-release.js +0 -346
- package/src/installs/lsb-release.md +0 -814
- package/src/installs/messenger.js +0 -847
- package/src/installs/messenger.md +0 -900
- package/src/installs/microsoft-office.js +0 -568
- package/src/installs/microsoft-office.md +0 -760
- package/src/installs/microsoft-teams.js +0 -801
- package/src/installs/microsoft-teams.md +0 -886
- package/src/installs/moom.js +0 -326
- package/src/installs/moom.md +0 -570
- package/src/installs/node.js +0 -904
- package/src/installs/node.md +0 -1153
- package/src/installs/nordpass.js +0 -716
- package/src/installs/nordpass.md +0 -921
- package/src/installs/nordvpn.js +0 -892
- package/src/installs/nordvpn.md +0 -1052
- package/src/installs/nvm.js +0 -995
- package/src/installs/nvm.md +0 -1057
- package/src/installs/ohmyzsh.js +0 -529
- package/src/installs/ohmyzsh.md +0 -1094
- package/src/installs/openssh.js +0 -804
- package/src/installs/openssh.md +0 -1056
- package/src/installs/pandoc.js +0 -662
- package/src/installs/pandoc.md +0 -1036
- package/src/installs/parallels-desktop.js +0 -431
- package/src/installs/parallels-desktop.md +0 -446
- package/src/installs/pinentry.js +0 -510
- package/src/installs/pinentry.md +0 -1142
- package/src/installs/pngyu.js +0 -869
- package/src/installs/pngyu.md +0 -896
- package/src/installs/postman.js +0 -799
- package/src/installs/postman.md +0 -940
- package/src/installs/procps.js +0 -425
- package/src/installs/procps.md +0 -851
- package/src/installs/safari-tech-preview.js +0 -374
- package/src/installs/safari-tech-preview.md +0 -533
- package/src/installs/sfnt2woff.js +0 -658
- package/src/installs/sfnt2woff.md +0 -795
- package/src/installs/shellcheck.js +0 -481
- package/src/installs/shellcheck.md +0 -1005
- package/src/installs/slack.js +0 -741
- package/src/installs/slack.md +0 -865
- package/src/installs/snagit.js +0 -585
- package/src/installs/snagit.md +0 -844
- package/src/installs/software-properties-common.js +0 -372
- package/src/installs/software-properties-common.md +0 -805
- package/src/installs/spotify.js +0 -877
- package/src/installs/spotify.md +0 -901
- package/src/installs/studio-3t.js +0 -823
- package/src/installs/studio-3t.md +0 -918
- package/src/installs/sublime-text.js +0 -804
- package/src/installs/sublime-text.md +0 -914
- package/src/installs/superwhisper.js +0 -706
- package/src/installs/superwhisper.md +0 -630
- package/src/installs/tailscale.js +0 -745
- package/src/installs/tailscale.md +0 -1100
- package/src/installs/tar.js +0 -389
- package/src/installs/tar.md +0 -946
- package/src/installs/termius.js +0 -798
- package/src/installs/termius.md +0 -844
- package/src/installs/terraform.js +0 -779
- package/src/installs/terraform.md +0 -899
- package/src/installs/tfenv.js +0 -778
- package/src/installs/tfenv.md +0 -1091
- package/src/installs/tidal.js +0 -771
- package/src/installs/tidal.md +0 -864
- package/src/installs/tmux.js +0 -346
- package/src/installs/tmux.md +0 -1030
- package/src/installs/tree.js +0 -411
- package/src/installs/tree.md +0 -833
- package/src/installs/unzip.js +0 -460
- package/src/installs/unzip.md +0 -879
- package/src/installs/vim.js +0 -421
- package/src/installs/vim.md +0 -1040
- package/src/installs/vlc.js +0 -821
- package/src/installs/vlc.md +0 -927
- package/src/installs/vscode.js +0 -843
- package/src/installs/vscode.md +0 -1002
- package/src/installs/wget.js +0 -420
- package/src/installs/wget.md +0 -791
- package/src/installs/whatsapp.js +0 -729
- package/src/installs/whatsapp.md +0 -854
- package/src/installs/winpty.js +0 -352
- package/src/installs/winpty.md +0 -620
- package/src/installs/woff2.js +0 -553
- package/src/installs/woff2.md +0 -977
- package/src/installs/wsl.js +0 -572
- package/src/installs/wsl.md +0 -699
- package/src/installs/xcode-clt.js +0 -520
- package/src/installs/xcode-clt.md +0 -351
- package/src/installs/xcode.js +0 -560
- package/src/installs/xcode.md +0 -573
- package/src/installs/yarn.js +0 -824
- package/src/installs/yarn.md +0 -1074
- package/src/installs/yq.js +0 -654
- package/src/installs/yq.md +0 -944
- package/src/installs/yt-dlp.js +0 -701
- package/src/installs/yt-dlp.md +0 -946
- package/src/installs/yum-utils.js +0 -297
- package/src/installs/yum-utils.md +0 -648
- package/src/installs/zoom.js +0 -759
- package/src/installs/zoom.md +0 -884
- package/src/installs/zsh.js +0 -455
- package/src/installs/zsh.md +0 -1008
- package/src/scripts/README.md +0 -617
- package/src/scripts/STATUS.md +0 -208
- package/src/scripts/afk.js +0 -411
- package/src/scripts/backup-all.js +0 -746
- package/src/scripts/backup-source.js +0 -727
- package/src/scripts/brewd.js +0 -389
- package/src/scripts/brewi.js +0 -520
- package/src/scripts/brewr.js +0 -527
- package/src/scripts/brews.js +0 -477
- package/src/scripts/brewu.js +0 -504
- package/src/scripts/c.js +0 -201
- package/src/scripts/ccurl.js +0 -341
- package/src/scripts/certbot-crontab-init.js +0 -504
- package/src/scripts/certbot-init.js +0 -657
- package/src/scripts/ch.js +0 -355
- package/src/scripts/claude-danger.js +0 -268
- package/src/scripts/clean-dev.js +0 -435
- package/src/scripts/clear-dns-cache.js +0 -541
- package/src/scripts/clone.js +0 -435
- package/src/scripts/code-all.js +0 -437
- package/src/scripts/count-files.js +0 -211
- package/src/scripts/count-folders.js +0 -211
- package/src/scripts/count.js +0 -264
- package/src/scripts/d.js +0 -219
- package/src/scripts/datauri.js +0 -389
- package/src/scripts/delete-files.js +0 -380
- package/src/scripts/docker-clean.js +0 -426
- package/src/scripts/dp.js +0 -442
- package/src/scripts/e.js +0 -390
- package/src/scripts/empty-trash.js +0 -513
- package/src/scripts/evm.js +0 -444
- package/src/scripts/fetch-github-repos.js +0 -456
- package/src/scripts/get-channel.js +0 -345
- package/src/scripts/get-course.js +0 -399
- package/src/scripts/get-dependencies.js +0 -306
- package/src/scripts/get-folder.js +0 -799
- package/src/scripts/get-tunes.js +0 -426
- package/src/scripts/get-video.js +0 -367
- package/src/scripts/git-backup.js +0 -577
- package/src/scripts/git-clone.js +0 -493
- package/src/scripts/git-pup.js +0 -319
- package/src/scripts/git-push.js +0 -396
- package/src/scripts/h.js +0 -622
- package/src/scripts/hide-desktop-icons.js +0 -499
- package/src/scripts/hide-hidden-files.js +0 -538
- package/src/scripts/install-dependencies-from.js +0 -456
- package/src/scripts/ips.js +0 -663
- package/src/scripts/iso.js +0 -370
- package/src/scripts/killni.js +0 -577
- package/src/scripts/ll.js +0 -467
- package/src/scripts/local-ip.js +0 -325
- package/src/scripts/m.js +0 -524
- package/src/scripts/map.js +0 -309
- package/src/scripts/mkd.js +0 -351
- package/src/scripts/ncu-update-all.js +0 -457
- package/src/scripts/nginx-init.js +0 -718
- package/src/scripts/npmi.js +0 -382
- package/src/scripts/o.js +0 -511
- package/src/scripts/org-by-date.js +0 -338
- package/src/scripts/p.js +0 -224
- package/src/scripts/packages.js +0 -330
- package/src/scripts/path.js +0 -225
- package/src/scripts/ports.js +0 -597
- package/src/scripts/q.js +0 -305
- package/src/scripts/refresh-files.js +0 -394
- package/src/scripts/remove-smaller-files.js +0 -516
- package/src/scripts/rename-files-with-date.js +0 -533
- package/src/scripts/resize-image.js +0 -539
- package/src/scripts/rm-safe.js +0 -669
- package/src/scripts/s.js +0 -540
- package/src/scripts/set-git-public.js +0 -365
- package/src/scripts/show-desktop-icons.js +0 -475
- package/src/scripts/show-hidden-files.js +0 -472
- package/src/scripts/tpa.js +0 -280
- package/src/scripts/tpo.js +0 -280
- package/src/scripts/u.js +0 -505
- package/src/scripts/vpush.js +0 -437
- package/src/scripts/y.js +0 -283
- package/src/utils/README.md +0 -95
- package/src/utils/common/apps.js +0 -143
- package/src/utils/common/display.js +0 -157
- package/src/utils/common/network.js +0 -185
- package/src/utils/common/os.js +0 -294
- package/src/utils/common/package-manager.js +0 -301
- package/src/utils/common/privileges.js +0 -138
- package/src/utils/common/shell.js +0 -261
- package/src/utils/macos/apps.js +0 -228
- package/src/utils/macos/brew.js +0 -315
- package/src/utils/ubuntu/apt.js +0 -307
- package/src/utils/ubuntu/desktop.js +0 -292
- package/src/utils/ubuntu/snap.js +0 -344
- package/src/utils/ubuntu/systemd.js +0 -286
- package/src/utils/windows/choco.js +0 -465
- package/src/utils/windows/env.js +0 -246
- package/src/utils/windows/registry.js +0 -269
- package/src/utils/windows/shell.js +0 -240
- package/src/utils/windows/winget.js +0 -489
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
# Patterns for Python projects.
|
|
3
|
+
|
|
4
|
+
# Byte-compiled files
|
|
5
|
+
__pycache__/
|
|
6
|
+
*.py[cod]
|
|
7
|
+
*$py.class
|
|
8
|
+
|
|
9
|
+
# Distribution and packaging
|
|
10
|
+
dist/
|
|
11
|
+
build/
|
|
12
|
+
*.egg-info/
|
|
13
|
+
*.egg
|
|
14
|
+
eggs/
|
|
15
|
+
wheels/
|
|
16
|
+
sdist/
|
|
17
|
+
|
|
18
|
+
# Virtual environments
|
|
19
|
+
.venv/
|
|
20
|
+
venv/
|
|
21
|
+
env/
|
|
22
|
+
ENV/
|
|
23
|
+
|
|
24
|
+
# Environment and secrets
|
|
25
|
+
.env
|
|
26
|
+
.env.*
|
|
27
|
+
!.env.example
|
|
28
|
+
|
|
29
|
+
# Installer logs
|
|
30
|
+
pip-log.txt
|
|
31
|
+
pip-delete-this-directory.txt
|
|
32
|
+
|
|
33
|
+
# Unit test and coverage
|
|
34
|
+
htmlcov/
|
|
35
|
+
.tox/
|
|
36
|
+
.nox/
|
|
37
|
+
.coverage
|
|
38
|
+
.coverage.*
|
|
39
|
+
coverage.xml
|
|
40
|
+
*.cover
|
|
41
|
+
*.py,cover
|
|
42
|
+
.hypothesis/
|
|
43
|
+
.pytest_cache/
|
|
44
|
+
nosetests.xml
|
|
45
|
+
|
|
46
|
+
# Type checker cache
|
|
47
|
+
.mypy_cache/
|
|
48
|
+
.pytype/
|
|
49
|
+
.pyre/
|
|
50
|
+
|
|
51
|
+
# Jupyter Notebook checkpoints
|
|
52
|
+
.ipynb_checkpoints/
|
|
53
|
+
|
|
54
|
+
# pyenv
|
|
55
|
+
.python-version
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Terraform
|
|
2
|
+
# Patterns for Terraform and OpenTofu infrastructure-as-code projects.
|
|
3
|
+
|
|
4
|
+
# Provider plugins and modules
|
|
5
|
+
.terraform/
|
|
6
|
+
|
|
7
|
+
# State files (contain secrets -- never commit these)
|
|
8
|
+
*.tfstate
|
|
9
|
+
*.tfstate.*
|
|
10
|
+
|
|
11
|
+
# Crash logs
|
|
12
|
+
crash.log
|
|
13
|
+
crash.*.log
|
|
14
|
+
|
|
15
|
+
# Variable files that may contain secrets
|
|
16
|
+
*.tfvars
|
|
17
|
+
*.tfvars.json
|
|
18
|
+
!*.tfvars.example
|
|
19
|
+
|
|
20
|
+
# Override files (local developer overrides)
|
|
21
|
+
override.tf
|
|
22
|
+
override.tf.json
|
|
23
|
+
*_override.tf
|
|
24
|
+
*_override.tf.json
|
|
25
|
+
|
|
26
|
+
# Plan files (binary, can contain secrets)
|
|
27
|
+
*.tfplan
|
|
28
|
+
|
|
29
|
+
# Lock file (commit this for consistent provider versions)
|
|
30
|
+
# .terraform.lock.hcl
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Visual Studio Code
|
|
2
|
+
# Patterns for VS Code workspace and user-level files.
|
|
3
|
+
|
|
4
|
+
# Workspace settings (user-specific)
|
|
5
|
+
.vscode/
|
|
6
|
+
|
|
7
|
+
# Workspace file
|
|
8
|
+
*.code-workspace
|
|
9
|
+
|
|
10
|
+
# VS Code local history
|
|
11
|
+
.history/
|
|
12
|
+
|
|
13
|
+
# VS Code extensions recommendation (optional -- remove this line
|
|
14
|
+
# if your team uses shared extension recommendations)
|
|
15
|
+
# .vscode/extensions.json
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Windows
|
|
2
|
+
# Patterns for Windows system and Explorer metadata files.
|
|
3
|
+
|
|
4
|
+
# Thumbnail cache
|
|
5
|
+
Thumbs.db
|
|
6
|
+
Thumbs.db:encryptable
|
|
7
|
+
ehthumbs.db
|
|
8
|
+
ehthumbs_vista.db
|
|
9
|
+
|
|
10
|
+
# Folder config
|
|
11
|
+
desktop.ini
|
|
12
|
+
Desktop.ini
|
|
13
|
+
|
|
14
|
+
# Recycle Bin
|
|
15
|
+
$RECYCLE.BIN/
|
|
16
|
+
|
|
17
|
+
# Shortcut files
|
|
18
|
+
*.lnk
|
|
19
|
+
|
|
20
|
+
# Windows Installer files
|
|
21
|
+
*.cab
|
|
22
|
+
*.msi
|
|
23
|
+
*.msix
|
|
24
|
+
*.msm
|
|
25
|
+
*.msp
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const { spawnSync } = require('child_process');
|
|
6
|
+
|
|
7
|
+
const meta = {
|
|
8
|
+
name: 'clone',
|
|
9
|
+
description: 'Clone a git repo and auto-install dependencies using the detected package manager',
|
|
10
|
+
platforms: ['macos', 'ubuntu', 'raspbian', 'amazon-linux', 'windows', 'gitbash'],
|
|
11
|
+
arguments: [
|
|
12
|
+
{ name: 'url', required: true, description: 'Git repository URL (SSH or HTTPS)' },
|
|
13
|
+
{ name: 'directory', required: false, description: 'Target directory name (defaults to repo name)' },
|
|
14
|
+
],
|
|
15
|
+
flags: [],
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Extract the repository name from a git URL.
|
|
20
|
+
* Handles HTTPS, SSH, and bare path formats.
|
|
21
|
+
*
|
|
22
|
+
* @param {string} url - The git repository URL.
|
|
23
|
+
* @returns {string} The extracted repo name.
|
|
24
|
+
*/
|
|
25
|
+
function extractRepoName(url) {
|
|
26
|
+
let cleaned = url.replace(/\/+$/, '');
|
|
27
|
+
cleaned = cleaned.replace(/\.git$/, '');
|
|
28
|
+
|
|
29
|
+
const lastSegment = cleaned.split('/').pop() || '';
|
|
30
|
+
|
|
31
|
+
if (lastSegment.includes(':')) {
|
|
32
|
+
return lastSegment.split(':').pop() || 'cloned-repo';
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return lastSegment || 'cloned-repo';
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Detect which package manager to use based on lock files in the directory.
|
|
40
|
+
* Checks lock files in order: yarn.lock, pnpm-lock.yaml, package-lock.json.
|
|
41
|
+
* Falls back to npm if no lock file is found but package.json exists.
|
|
42
|
+
*
|
|
43
|
+
* @param {string} dir - The directory to check.
|
|
44
|
+
* @returns {{ name: string, installCmd: string }|null} Package manager info, or null if not a JS project.
|
|
45
|
+
*/
|
|
46
|
+
function detectPackageManager(dir) {
|
|
47
|
+
const hasPackageJson = fs.existsSync(path.join(dir, 'package.json'));
|
|
48
|
+
if (!hasPackageJson) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (fs.existsSync(path.join(dir, 'yarn.lock'))) {
|
|
53
|
+
return { name: 'yarn', installCmd: 'yarn install' };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (fs.existsSync(path.join(dir, 'pnpm-lock.yaml'))) {
|
|
57
|
+
return { name: 'pnpm', installCmd: 'pnpm install' };
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (fs.existsSync(path.join(dir, 'package-lock.json'))) {
|
|
61
|
+
return { name: 'npm', installCmd: 'npm install' };
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// package.json exists but no lock file -- default to npm
|
|
65
|
+
return { name: 'npm', installCmd: 'npm install' };
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Check if a command is available on the system.
|
|
70
|
+
*
|
|
71
|
+
* @param {string} cmd - The command name to check.
|
|
72
|
+
* @returns {boolean} True if the command exists on PATH.
|
|
73
|
+
*/
|
|
74
|
+
function isAvailable(cmd) {
|
|
75
|
+
const shell = require('../../lib/shell');
|
|
76
|
+
return shell.commandExists(cmd);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async function run(args) {
|
|
80
|
+
const shell = require('../../lib/shell');
|
|
81
|
+
|
|
82
|
+
if (!shell.commandExists('git')) {
|
|
83
|
+
console.error('Error: git is not installed.');
|
|
84
|
+
console.error('Install git first, then try again.');
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const url = args[0];
|
|
89
|
+
if (!url) {
|
|
90
|
+
console.error('Usage: dev util run clone <url> [directory]');
|
|
91
|
+
console.error('');
|
|
92
|
+
console.error('Examples:');
|
|
93
|
+
console.error(' dev util run clone git@github.com:user/repo.git');
|
|
94
|
+
console.error(' dev util run clone https://github.com/user/repo.git');
|
|
95
|
+
console.error(' dev util run clone git@github.com:user/repo.git my-project');
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const targetDir = args[1] || extractRepoName(url);
|
|
100
|
+
const fullPath = path.resolve(process.cwd(), targetDir);
|
|
101
|
+
|
|
102
|
+
if (fs.existsSync(fullPath)) {
|
|
103
|
+
console.error(`Error: Directory "${targetDir}" already exists.`);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
console.log(`Cloning ${url} into ${targetDir}...`);
|
|
108
|
+
console.log('');
|
|
109
|
+
|
|
110
|
+
const cloneResult = spawnSync('git', ['clone', url, targetDir], {
|
|
111
|
+
stdio: 'inherit',
|
|
112
|
+
cwd: process.cwd(),
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
if (cloneResult.status !== 0) {
|
|
116
|
+
console.error('');
|
|
117
|
+
console.error('git clone failed.');
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (!fs.existsSync(fullPath)) {
|
|
122
|
+
console.error('Clone appeared to succeed but the directory was not created.');
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const pm = detectPackageManager(fullPath);
|
|
127
|
+
|
|
128
|
+
if (!pm) {
|
|
129
|
+
console.log('');
|
|
130
|
+
console.log(`Cloned into "${targetDir}".`);
|
|
131
|
+
console.log('No package.json found -- skipping dependency installation.');
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (!isAvailable(pm.name)) {
|
|
136
|
+
console.log('');
|
|
137
|
+
console.log(`Cloned into "${targetDir}".`);
|
|
138
|
+
console.log(`package.json found, but ${pm.name} is not installed.`);
|
|
139
|
+
console.log(`Install ${pm.name} and run: ${pm.installCmd}`);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
console.log('');
|
|
144
|
+
console.log(`Installing dependencies with ${pm.name}...`);
|
|
145
|
+
console.log('');
|
|
146
|
+
|
|
147
|
+
const installResult = spawnSync(pm.name, ['install'], {
|
|
148
|
+
stdio: 'inherit',
|
|
149
|
+
cwd: fullPath,
|
|
150
|
+
shell: true,
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
if (installResult.status !== 0) {
|
|
154
|
+
console.error('');
|
|
155
|
+
console.error(`${pm.name} install finished with errors. Check the output above.`);
|
|
156
|
+
} else {
|
|
157
|
+
console.log('');
|
|
158
|
+
console.log('Dependencies installed.');
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
console.log('');
|
|
162
|
+
console.log(`Done. To enter the project: cd ${targetDir}`);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
module.exports = { meta, run };
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const meta = {
|
|
4
|
+
name: 'git-push',
|
|
5
|
+
description: 'Safer git push: shows what will be pushed, confirms before pushing, and protects main/master',
|
|
6
|
+
platforms: ['macos', 'ubuntu', 'raspbian', 'amazon-linux', 'windows', 'gitbash'],
|
|
7
|
+
arguments: [
|
|
8
|
+
{ name: 'message', required: true, description: 'Commit message (all arguments after the name are joined)' },
|
|
9
|
+
],
|
|
10
|
+
flags: [
|
|
11
|
+
{ name: 'force', type: 'boolean', description: 'Allow pushing to protected branches (main/master)' },
|
|
12
|
+
{ name: 'yes', type: 'boolean', description: 'Skip the confirmation prompt' },
|
|
13
|
+
],
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const shell = require('../../lib/shell');
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Check if the current directory is inside a git repo.
|
|
20
|
+
* @returns {boolean}
|
|
21
|
+
*/
|
|
22
|
+
function isGitRepo() {
|
|
23
|
+
const result = shell.execSync('git rev-parse --is-inside-work-tree');
|
|
24
|
+
return result === 'true';
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Get the current branch name.
|
|
29
|
+
* @returns {string|null} Branch name, or null if in detached HEAD state.
|
|
30
|
+
*/
|
|
31
|
+
function getCurrentBranch() {
|
|
32
|
+
return shell.execSync('git symbolic-ref --short HEAD') || null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Get a list of changed files (staged, unstaged, and untracked).
|
|
37
|
+
* @returns {Array<{ status: string, file: string }>}
|
|
38
|
+
*/
|
|
39
|
+
function getChangedFiles() {
|
|
40
|
+
const result = shell.execSync('git status --porcelain');
|
|
41
|
+
if (!result) return [];
|
|
42
|
+
|
|
43
|
+
return result.split('\n').filter(Boolean).map(line => {
|
|
44
|
+
const status = line.substring(0, 2).trim();
|
|
45
|
+
const file = line.substring(3);
|
|
46
|
+
return { status, file };
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Get the list of commits that would be pushed (ahead of remote).
|
|
52
|
+
* @returns {string[]} Array of commit summary lines.
|
|
53
|
+
*/
|
|
54
|
+
function getUnpushedCommits() {
|
|
55
|
+
const result = shell.execSync('git log @{upstream}..HEAD --oneline');
|
|
56
|
+
if (!result) return [];
|
|
57
|
+
return result.split('\n').filter(Boolean);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Check if there is a tracking branch configured.
|
|
62
|
+
* @returns {boolean}
|
|
63
|
+
*/
|
|
64
|
+
function hasTrackingBranch() {
|
|
65
|
+
const result = shell.execSync('git rev-parse --abbrev-ref @{upstream}');
|
|
66
|
+
return result !== null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Check if --force flag was passed.
|
|
71
|
+
* @param {string[]} args - Raw args array.
|
|
72
|
+
* @param {object} context - Command context.
|
|
73
|
+
* @returns {boolean}
|
|
74
|
+
*/
|
|
75
|
+
function isForceFlag(args, context) {
|
|
76
|
+
if (context && context.flags && context.flags.force) return true;
|
|
77
|
+
return args.includes('--force');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Check if --yes flag was passed.
|
|
82
|
+
* @param {string[]} args - Raw args array.
|
|
83
|
+
* @param {object} context - Command context.
|
|
84
|
+
* @returns {boolean}
|
|
85
|
+
*/
|
|
86
|
+
function isYesFlag(args, context) {
|
|
87
|
+
if (context && context.flags && context.flags.yes) return true;
|
|
88
|
+
return args.includes('--yes') || args.includes('-y');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Convert a git status code to a human-readable label.
|
|
93
|
+
* @param {string} status - Status code from git status --porcelain.
|
|
94
|
+
* @returns {string}
|
|
95
|
+
*/
|
|
96
|
+
function statusLabel(status) {
|
|
97
|
+
const labels = {
|
|
98
|
+
'M': 'modified',
|
|
99
|
+
'A': 'added',
|
|
100
|
+
'D': 'deleted',
|
|
101
|
+
'R': 'renamed',
|
|
102
|
+
'C': 'copied',
|
|
103
|
+
'?': 'untracked',
|
|
104
|
+
'!': 'ignored',
|
|
105
|
+
};
|
|
106
|
+
const char = status.replace(/\s/g, '') || '?';
|
|
107
|
+
return labels[char[0]] || status;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async function run(args, context) {
|
|
111
|
+
if (!shell.commandExists('git')) {
|
|
112
|
+
console.error('Error: git is not installed.');
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (!isGitRepo()) {
|
|
117
|
+
console.error('Error: Not inside a git repository.');
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Filter out flags from args to build the commit message
|
|
122
|
+
const messageArgs = args.filter(a => !a.startsWith('--') && a !== '-y');
|
|
123
|
+
const message = messageArgs.join(' ').trim();
|
|
124
|
+
if (!message) {
|
|
125
|
+
console.error('Usage: dev util run git-push "your commit message"');
|
|
126
|
+
console.error('');
|
|
127
|
+
console.error('All arguments after the utility name become the commit message.');
|
|
128
|
+
console.error('Example: dev util run git-push Fix the login button color');
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const branch = getCurrentBranch();
|
|
133
|
+
if (!branch) {
|
|
134
|
+
console.error('Error: Not on a branch (detached HEAD).');
|
|
135
|
+
console.error('Check out a branch first: git checkout <branch>');
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Check for protected branches
|
|
140
|
+
const protectedBranches = ['main', 'master'];
|
|
141
|
+
if (protectedBranches.includes(branch) && !isForceFlag(args, context)) {
|
|
142
|
+
console.error(`Warning: You are on the "${branch}" branch.`);
|
|
143
|
+
console.error('Pushing directly to this branch is usually not recommended.');
|
|
144
|
+
console.error('');
|
|
145
|
+
|
|
146
|
+
if (!context || !context.prompt) {
|
|
147
|
+
console.error('Use --force to push to protected branches in non-interactive mode.');
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const proceed = await context.prompt.confirm(
|
|
152
|
+
`Are you sure you want to push directly to ${branch}?`,
|
|
153
|
+
false
|
|
154
|
+
);
|
|
155
|
+
if (!proceed) {
|
|
156
|
+
console.log('Cancelled.');
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const changedFiles = getChangedFiles();
|
|
162
|
+
const existingUnpushed = hasTrackingBranch() ? getUnpushedCommits() : [];
|
|
163
|
+
|
|
164
|
+
if (changedFiles.length === 0 && existingUnpushed.length === 0) {
|
|
165
|
+
console.log('Nothing to commit or push. Working tree is clean.');
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Display what will happen
|
|
170
|
+
console.log('');
|
|
171
|
+
console.log(`Branch: ${branch}`);
|
|
172
|
+
console.log(`Commit message: "${message}"`);
|
|
173
|
+
console.log('');
|
|
174
|
+
|
|
175
|
+
if (changedFiles.length > 0) {
|
|
176
|
+
console.log(`Files to be committed (${changedFiles.length}):`);
|
|
177
|
+
for (const f of changedFiles) {
|
|
178
|
+
const label = statusLabel(f.status);
|
|
179
|
+
console.log(` ${label} ${f.file}`);
|
|
180
|
+
}
|
|
181
|
+
console.log('');
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (existingUnpushed.length > 0) {
|
|
185
|
+
console.log(`Already unpushed commits (${existingUnpushed.length}):`);
|
|
186
|
+
for (const c of existingUnpushed) {
|
|
187
|
+
console.log(` ${c}`);
|
|
188
|
+
}
|
|
189
|
+
console.log('');
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Confirm
|
|
193
|
+
if (!isYesFlag(args, context)) {
|
|
194
|
+
if (context && context.prompt) {
|
|
195
|
+
const ok = await context.prompt.confirm('Proceed with commit and push?', true);
|
|
196
|
+
if (!ok) {
|
|
197
|
+
console.log('Cancelled.');
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Execute: add, commit, push
|
|
204
|
+
console.log('Staging all changes...');
|
|
205
|
+
const addResult = await shell.exec('git add -A');
|
|
206
|
+
if (addResult.exitCode !== 0) {
|
|
207
|
+
console.error('git add failed: ' + addResult.stderr);
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
console.log('Committing...');
|
|
212
|
+
const escapedMessage = message.replace(/"/g, '\\"');
|
|
213
|
+
const commitResult = await shell.exec(`git commit -m "${escapedMessage}"`);
|
|
214
|
+
if (commitResult.exitCode !== 0) {
|
|
215
|
+
console.error('git commit failed: ' + commitResult.stderr);
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
console.log(`Pushing to origin/${branch}...`);
|
|
220
|
+
const pushResult = await shell.exec(`git push origin "${branch}"`);
|
|
221
|
+
if (pushResult.exitCode !== 0) {
|
|
222
|
+
console.error('git push failed: ' + pushResult.stderr);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
console.log('');
|
|
227
|
+
console.log('Done. Changes committed and pushed.');
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
module.exports = { meta, run };
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
|
|
6
|
+
const meta = {
|
|
7
|
+
name: 'git-status',
|
|
8
|
+
description: 'Scan directories for git repos and show a color-coded status summary',
|
|
9
|
+
platforms: ['macos', 'ubuntu', 'raspbian', 'amazon-linux', 'windows', 'gitbash'],
|
|
10
|
+
arguments: [
|
|
11
|
+
{ name: 'path', required: false, description: 'Directory to scan (defaults to current directory)' },
|
|
12
|
+
],
|
|
13
|
+
flags: [
|
|
14
|
+
{ name: 'depth', type: 'number', description: 'How many levels deep to scan for repos (default: 1)' },
|
|
15
|
+
],
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Run the Unix bash script for git status scanning.
|
|
20
|
+
* @param {string} dir - The directory to scan.
|
|
21
|
+
*/
|
|
22
|
+
async function runUnixScript(dir) {
|
|
23
|
+
const shell = require('../../lib/shell');
|
|
24
|
+
const scriptPath = path.join(__dirname, 'unix.sh');
|
|
25
|
+
|
|
26
|
+
const result = await shell.exec(`bash "${scriptPath}" "${dir}"`);
|
|
27
|
+
|
|
28
|
+
if (result.exitCode !== 0) {
|
|
29
|
+
console.error(result.stderr || 'git-status script failed');
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (result.stdout) {
|
|
34
|
+
console.log(result.stdout);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Pure JavaScript fallback for platforms without bash (Windows, Git Bash).
|
|
40
|
+
* @param {string} dir - The directory to scan.
|
|
41
|
+
*/
|
|
42
|
+
async function runJsFallback(dir) {
|
|
43
|
+
const shell = require('../../lib/shell');
|
|
44
|
+
|
|
45
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
46
|
+
const repos = entries
|
|
47
|
+
.filter(e => e.isDirectory() && fs.existsSync(path.join(dir, e.name, '.git')))
|
|
48
|
+
.map(e => ({ name: e.name, path: path.join(dir, e.name) }));
|
|
49
|
+
|
|
50
|
+
if (repos.length === 0) {
|
|
51
|
+
console.log('No git repositories found in ' + dir);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
for (const repo of repos) {
|
|
56
|
+
const opts = { cwd: repo.path };
|
|
57
|
+
|
|
58
|
+
// Get branch
|
|
59
|
+
let branch = shell.execSync('git symbolic-ref --short HEAD', opts);
|
|
60
|
+
if (branch === null) branch = 'detached';
|
|
61
|
+
|
|
62
|
+
// Get dirty count
|
|
63
|
+
const porcelain = shell.execSync('git status --porcelain', opts) || '';
|
|
64
|
+
const dirtyCount = porcelain ? porcelain.split('\n').filter(Boolean).length : 0;
|
|
65
|
+
|
|
66
|
+
// Get stash count
|
|
67
|
+
const stashList = shell.execSync('git stash list', opts) || '';
|
|
68
|
+
const stashCount = stashList ? stashList.split('\n').filter(Boolean).length : 0;
|
|
69
|
+
|
|
70
|
+
// Get ahead/behind
|
|
71
|
+
let ahead = 0;
|
|
72
|
+
let behind = 0;
|
|
73
|
+
const tracking = shell.execSync('git rev-parse --abbrev-ref @{upstream}', opts);
|
|
74
|
+
if (tracking) {
|
|
75
|
+
const counts = shell.execSync('git rev-list --left-right --count HEAD...@{upstream}', opts);
|
|
76
|
+
if (counts) {
|
|
77
|
+
const parts = counts.split(/\s+/);
|
|
78
|
+
ahead = parseInt(parts[0], 10) || 0;
|
|
79
|
+
behind = parseInt(parts[1], 10) || 0;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Build status string
|
|
84
|
+
const statusParts = [];
|
|
85
|
+
if (dirtyCount > 0) statusParts.push(`${dirtyCount} dirty`);
|
|
86
|
+
if (ahead > 0) statusParts.push(`+${ahead}`);
|
|
87
|
+
if (behind > 0) statusParts.push(`-${behind}`);
|
|
88
|
+
if (stashCount > 0) statusParts.push(`${stashCount} stash`);
|
|
89
|
+
if (statusParts.length === 0) statusParts.push('clean');
|
|
90
|
+
|
|
91
|
+
const nameCol = repo.name.padEnd(30);
|
|
92
|
+
const branchCol = branch.padEnd(20);
|
|
93
|
+
console.log(`${nameCol} ${branchCol} ${statusParts.join(' ')}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async function run(args) {
|
|
98
|
+
const platform = require('../../lib/platform').detect();
|
|
99
|
+
const targetDir = args[0] || process.cwd();
|
|
100
|
+
const resolvedDir = path.resolve(targetDir);
|
|
101
|
+
|
|
102
|
+
if (!fs.existsSync(resolvedDir)) {
|
|
103
|
+
console.error(`Directory not found: ${resolvedDir}`);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const unixPlatforms = ['macos', 'ubuntu', 'raspbian', 'amazon-linux'];
|
|
108
|
+
|
|
109
|
+
if (unixPlatforms.includes(platform.type)) {
|
|
110
|
+
await runUnixScript(resolvedDir);
|
|
111
|
+
} else {
|
|
112
|
+
await runJsFallback(resolvedDir);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
module.exports = { meta, run };
|