diff --git a/.gitignore b/.gitignore index 007c4a4..1c22bbd 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ tmp/ .bundle/ _site/ Gemfile.lock +.goxc.local.json +*.exe diff --git a/Makefile b/Makefile index fdde545..da16e6e 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,7 @@ -# build the binary -# note starting in go1.18 vcs information will be available via go version -m +# set version in main.go for `go install` and build binary build: $(eval VERSION := $(shell git describe --tags HEAD 2>/dev/null || echo unknown)) - @echo "Building as version: $(VERSION)" + $(shell sed -E -i '' -e "s/^var version = \"[A-Za-z0-9\.-_]+\"/var version = \"$(VERSION)\"/" main.go) go build -o bin/scmpuff -mod=readonly -ldflags "-X main.version=$(VERSION)" # run unit tests diff --git a/README.md b/README.md index 6692b94..02051d1 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,10 @@ This will define the scmpuff shell functions as well as some handy shortcuts. [fish]: https://fishshell.com/ +For Powershell on Windows, add the following to your `$PROFILE` file: + + scmpuff init --shell=pwsh | Out-String | Invoke-Expression + ## Usage diff --git a/go.mod b/go.mod index b3b706f..63eb000 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,10 @@ -module github.com/mroth/scmpuff +module github.com/kmatt/scmpuff go 1.24 -require ( - github.com/google/go-cmp v0.7.0 - github.com/spf13/cobra v1.9.1 -) +require github.com/spf13/cobra v1.9.1 + +require github.com/google/go-cmp v0.7.0 require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect diff --git a/internal/commands/exec/exec.go b/internal/commands/exec/exec.go index dbe2792..2eb1572 100644 --- a/internal/commands/exec/exec.go +++ b/internal/commands/exec/exec.go @@ -5,7 +5,7 @@ import ( "os" "os/exec" - "github.com/mroth/scmpuff/internal/arguments" + "github.com/kmatt/scmpuff/internal/arguments" "github.com/spf13/cobra" ) @@ -16,7 +16,7 @@ var expandRelative bool // Allows expansion of numbered shortcuts, ranges of shortcuts, or standard paths. // Numbered shortcut variables are produced by various commands, such as: // -// * scmpuff_status() - git status implementation +// - scmpuff_status() - git status implementation func CommandExec() *cobra.Command { var expandCmd = &cobra.Command{ diff --git a/internal/commands/expand/expand.go b/internal/commands/expand/expand.go index a8d8c64..2d11658 100644 --- a/internal/commands/expand/expand.go +++ b/internal/commands/expand/expand.go @@ -5,7 +5,7 @@ import ( "regexp" "strings" - "github.com/mroth/scmpuff/internal/arguments" + "github.com/kmatt/scmpuff/internal/arguments" "github.com/spf13/cobra" ) diff --git a/internal/commands/inits/data/aliases.ps1 b/internal/commands/inits/data/aliases.ps1 new file mode 100644 index 0000000..a8067f4 --- /dev/null +++ b/internal/commands/inits/data/aliases.ps1 @@ -0,0 +1,6 @@ +function gs { scmpuff_status } +function ga { git add } +function gd { git diff } +function gl { git log } +function gco { git checkout } +function grs { git reset } diff --git a/internal/commands/inits/data/git_wrapper.ps1 b/internal/commands/inits/data/git_wrapper.ps1 new file mode 100644 index 0000000..d9c24a5 --- /dev/null +++ b/internal/commands/inits/data/git_wrapper.ps1 @@ -0,0 +1,19 @@ +$SCMPUFF_GIT_CMD = Get-Command git | Select-Object -ExpandProperty Definition + +function git { + switch -regex -casesensitive($args[0]) { + "^(commit|blame|log|rebase|merge)$" { + & scmpuff exec -- $SCMPUFF_GIT_CMD $args + } + "^(checkout|diff|rm|reset)$" { + & scmpuff exec --relative -- $SCMPUFF_GIT_CMD $args + } + "^add$" { + & scmpuff exec -- $SCMPUFF_GIT_CMD $args + scmpuff_status + } + default { + & $SCMPUFF_GIT_CMD $args + } + } +} diff --git a/internal/commands/inits/data/status_shortcuts.ps1 b/internal/commands/inits/data/status_shortcuts.ps1 new file mode 100644 index 0000000..eae3826 --- /dev/null +++ b/internal/commands/inits/data/status_shortcuts.ps1 @@ -0,0 +1,42 @@ +function scmpuff_status { + $scmpuff_env_char = "e" + + # Run scmpuff status command and capture the output + $cmd_output = & scmpuff status --filelist @args + + # if there was an error, exit prematurely, and pass along the exit code + $es = $LastExitCode + if ($es -ne 0) { + return $es + } + + # Fetch list of files (from first line of script output) + $files = ($cmd_output | Select-Object -First 1) -split '\s+' + + # Export numbered env variables for each file + scmpuff_clear_vars + $e = 1 + foreach ($file in $files) { + Set-Item "env:$($scmpuff_env_char + $e)" $file + $e++ + } + + # Print status (from line two onward) + $cmd_output | Select-Object -Skip 1 +} + +# Clear numbered env variables +function scmpuff_clear_vars { + # Define the environment variable character + $scmpuff_env_char = "e" + + # Iterate through environment variables and unset those starting with 'e' + for ($i = 1; $i -le 999; $i++) { + $env_var_i = $scmpuff_env_char + $i + if (Get-Item "env:$($env_var_i)" -ErrorAction Ignore) { + Remove-Item "env:$env_var_i" + } else { + break + } + } +} diff --git a/internal/commands/inits/init.go b/internal/commands/inits/init.go index 5aaca0f..7369d95 100644 --- a/internal/commands/inits/init.go +++ b/internal/commands/inits/init.go @@ -53,6 +53,10 @@ There are a number of flags to customize the shell integration. fmt.Println(fishCollection.Output(wrapGit, includeAliases)) os.Exit(0) + case "pwsh": + fmt.Println(pwshCollection.Output(wrapGit, includeAliases)) + os.Exit(0) + default: fmt.Fprintf(os.Stderr, "Unrecognized shell '%s'\n", shellType) os.Exit(1) @@ -88,7 +92,7 @@ There are a number of flags to customize the shell integration. InitCmd.Flags().StringVarP( &shellType, "shell", "s", "", - "Output shell type: sh | bash | zsh | fish", + "Output shell type: sh | bash | zsh | fish | pwsh", ) InitCmd.Flag("shell").NoOptDefVal = defaultShellType() @@ -101,7 +105,7 @@ func defaultShellType() string { if shellenv, ok := os.LookupEnv("SHELL"); ok { base := filepath.Base(shellenv) switch base { - case "sh", "bash", "zsh", "fish": + case "sh", "bash", "zsh", "fish", "pwsh": return base } } diff --git a/internal/commands/inits/scripts.go b/internal/commands/inits/scripts.go index 6787679..d50a59c 100644 --- a/internal/commands/inits/scripts.go +++ b/internal/commands/inits/scripts.go @@ -11,15 +11,24 @@ var scriptStatusShortcuts string //go:embed data/status_shortcuts.fish var scriptStatusShortcutsFish string +//go:embed data/status_shortcuts.ps1 +var scriptStatusShortcutsPwsh string + //go:embed data/aliases.sh var scriptAliases string +//go:embed data/aliases.ps1 +var scriptAliasesPwsh string + //go:embed data/git_wrapper.sh var scriptGitWrapper string //go:embed data/git_wrapper.fish var scriptGitWrapperFish string +//go:embed data/git_wrapper.ps1 +var scriptGitWrapperPwsh string + type scriptCollection struct { statusShortcuts string gitWrapper string @@ -38,6 +47,12 @@ var fishCollection = scriptCollection{ aliases: scriptAliases, } +var pwshCollection = scriptCollection{ + statusShortcuts: scriptStatusShortcutsPwsh, + gitWrapper: scriptGitWrapperPwsh, + aliases: scriptAliasesPwsh, +} + func (sc scriptCollection) Output(wrapGit, aliases bool) string { var b strings.Builder b.WriteString(sc.statusShortcuts) diff --git a/internal/commands/status/color.go b/internal/commands/status/color.go index 6128c43..9246fb0 100644 --- a/internal/commands/status/color.go +++ b/internal/commands/status/color.go @@ -1,6 +1,6 @@ package status -import "github.com/mroth/scmpuff/internal/gitstatus" +import "github.com/kmatt/scmpuff/internal/gitstatus" // Color represents an ANSI color code type Color string diff --git a/internal/commands/status/render.go b/internal/commands/status/render.go index 850e134..b7f50d4 100644 --- a/internal/commands/status/render.go +++ b/internal/commands/status/render.go @@ -6,7 +6,7 @@ import ( "io" "strings" - "github.com/mroth/scmpuff/internal/gitstatus" + "github.com/kmatt/scmpuff/internal/gitstatus" ) // A Renderer formats git status information for display to the screen. diff --git a/internal/commands/status/render_test.go b/internal/commands/status/render_test.go index c5f1f66..bf06cb4 100644 --- a/internal/commands/status/render_test.go +++ b/internal/commands/status/render_test.go @@ -9,7 +9,7 @@ import ( "path/filepath" "testing" - "github.com/mroth/scmpuff/internal/gitstatus" + "github.com/kmatt/scmpuff/internal/gitstatus" ) var ( diff --git a/internal/commands/status/status.go b/internal/commands/status/status.go index c1e8351..f8602e5 100644 --- a/internal/commands/status/status.go +++ b/internal/commands/status/status.go @@ -9,7 +9,7 @@ import ( "os/exec" "path/filepath" - "github.com/mroth/scmpuff/internal/gitstatus/porcelainv1" + "github.com/kmatt/scmpuff/internal/gitstatus/porcelainv1" "github.com/spf13/cobra" ) diff --git a/internal/gitstatus/porcelainv1/golden_test.go b/internal/gitstatus/porcelainv1/golden_test.go index 299861e..14338de 100644 --- a/internal/gitstatus/porcelainv1/golden_test.go +++ b/internal/gitstatus/porcelainv1/golden_test.go @@ -6,7 +6,7 @@ import ( "testing" "github.com/google/go-cmp/cmp" - "github.com/mroth/scmpuff/internal/gitstatus" + "github.com/kmatt/scmpuff/internal/gitstatus" ) func TestProcess(t *testing.T) { diff --git a/internal/gitstatus/porcelainv1/process.go b/internal/gitstatus/porcelainv1/process.go index cea2da5..46e74cc 100644 --- a/internal/gitstatus/porcelainv1/process.go +++ b/internal/gitstatus/porcelainv1/process.go @@ -9,7 +9,7 @@ import ( "regexp" "strconv" - "github.com/mroth/scmpuff/internal/gitstatus" + "github.com/kmatt/scmpuff/internal/gitstatus" ) // Process takes the raw output of `git status --porcelain=v1 -b -z` and diff --git a/internal/gitstatus/porcelainv1/process_test.go b/internal/gitstatus/porcelainv1/process_test.go index 71caec6..572ac7a 100644 --- a/internal/gitstatus/porcelainv1/process_test.go +++ b/internal/gitstatus/porcelainv1/process_test.go @@ -5,7 +5,7 @@ import ( "slices" "testing" - "github.com/mroth/scmpuff/internal/gitstatus" + "github.com/kmatt/scmpuff/internal/gitstatus" ) func Test_extractFilePaths(t *testing.T) { diff --git a/main.go b/main.go index ce4a093..b983317 100644 --- a/main.go +++ b/main.go @@ -3,18 +3,18 @@ package main import ( "fmt" - "github.com/mroth/scmpuff/internal/commands/exec" - "github.com/mroth/scmpuff/internal/commands/expand" - "github.com/mroth/scmpuff/internal/commands/inits" - "github.com/mroth/scmpuff/internal/commands/intro" - "github.com/mroth/scmpuff/internal/commands/status" + "github.com/kmatt/scmpuff/internal/commands/exec" + "github.com/kmatt/scmpuff/internal/commands/expand" + "github.com/kmatt/scmpuff/internal/commands/inits" + "github.com/kmatt/scmpuff/internal/commands/intro" + "github.com/kmatt/scmpuff/internal/commands/status" "github.com/spf13/cobra" + + _ "embed" ) -// version is the default version of the program -// ...in almost all cases this should be overriden by the buildscript. -var version = "0.0.0-development" +var version = "v0.5.0" var puffCmd = &cobra.Command{ Use: "scmpuff",