mirror of
https://github.com/packwiz/packwiz.git
synced 2025-05-06 04:26:31 +02:00
Add bash/powershell/zsh completions
Was this really necessary? No Are there more important things to implement? Yes Do I care? No
This commit is contained in:
parent
36093f0e2a
commit
7ecf2cd215
1
main.go
1
main.go
@ -4,6 +4,7 @@ import (
|
|||||||
// Modules of packwiz
|
// Modules of packwiz
|
||||||
"github.com/comp500/packwiz/cmd"
|
"github.com/comp500/packwiz/cmd"
|
||||||
_ "github.com/comp500/packwiz/curseforge"
|
_ "github.com/comp500/packwiz/curseforge"
|
||||||
|
_ "github.com/comp500/packwiz/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
186
utils/completion.go
Normal file
186
utils/completion.go
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
)
|
||||||
|
|
||||||
|
// completionCmd represents the completion command
|
||||||
|
var completionCmd = &cobra.Command{
|
||||||
|
Use: "completion [bash/powershell/zsh]",
|
||||||
|
Short: "Installs bash/powershell/zsh completion commands",
|
||||||
|
Long: `Installs bash/powershell/zsh completion commands.
|
||||||
|
Please note that the completions may be incomplete or broken, see https://github.com/spf13/cobra`,
|
||||||
|
Args: cobra.ExactValidArgs(1),
|
||||||
|
ValidArgs: []string{"bash", "powershell", "zsh"},
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
if args[0] == "bash" {
|
||||||
|
if viper.GetBool("utils.completion.source") {
|
||||||
|
cmd.Root().GenBashCompletion(os.Stdout)
|
||||||
|
} else {
|
||||||
|
file, err := getConfigPath("completion.sh")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error saving completion file: %s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
err = cmd.Root().GenBashCompletionFile(file)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error saving completion file: %s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the value of $HOME
|
||||||
|
home, err := os.UserHomeDir()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Failed to get $HOME location: %s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
bashrc := filepath.Join(home, ".bashrc")
|
||||||
|
|
||||||
|
absFile, err := filepath.Abs(file)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Failed to resolve path: %s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
command := ". " + absFile
|
||||||
|
commandFound := false
|
||||||
|
// Check for existing text in bashrc
|
||||||
|
data, err := ioutil.ReadFile(bashrc)
|
||||||
|
if err == nil {
|
||||||
|
commandFound = strings.Contains(string(data), command)
|
||||||
|
}
|
||||||
|
if !commandFound {
|
||||||
|
// Append to bashrc
|
||||||
|
os.MkdirAll(filepath.Dir(bashrc), os.ModePerm)
|
||||||
|
f, err := os.OpenFile(bashrc, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Failed to open bashrc: %s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
_, err = f.WriteString("\r\n" + command + "\r\n")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Failed to write to bashrc: %s\n", err)
|
||||||
|
f.Close()
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
f.Close()
|
||||||
|
}
|
||||||
|
fmt.Println("Completions installed! Restart your shell to load them.")
|
||||||
|
}
|
||||||
|
} else if args[0] == "powershell" {
|
||||||
|
if viper.GetBool("utils.completion.source") {
|
||||||
|
cmd.Root().GenPowerShellCompletion(os.Stdout)
|
||||||
|
} else {
|
||||||
|
file, err := getConfigPath("completion.ps1")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error saving completion file: %s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
err = cmd.Root().GenPowerShellCompletionFile(file)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error saving completion file: %s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the value of $PROFILE (not an environment variable!!)
|
||||||
|
profile, err := getPowershellProfile()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Failed to get profile location: %s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
absFile, err := filepath.Abs(file)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Failed to resolve path: %s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
command := ". " + absFile
|
||||||
|
commandFound := false
|
||||||
|
// Check for existing text in profile
|
||||||
|
data, err := ioutil.ReadFile(profile)
|
||||||
|
if err == nil {
|
||||||
|
commandFound = strings.Contains(string(data), command)
|
||||||
|
}
|
||||||
|
if !commandFound {
|
||||||
|
// Append to profile
|
||||||
|
os.MkdirAll(filepath.Dir(profile), os.ModePerm)
|
||||||
|
f, err := os.OpenFile(profile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Failed to open profile: %s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
_, err = f.WriteString("\r\n" + command + "\r\n")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Failed to write to profile: %s\n", err)
|
||||||
|
f.Close()
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
f.Close()
|
||||||
|
}
|
||||||
|
fmt.Println("Completions installed! Restart your shell to load them.")
|
||||||
|
}
|
||||||
|
} else if args[0] == "zsh" {
|
||||||
|
if viper.GetBool("utils.completion.source") {
|
||||||
|
cmd.Root().GenZshCompletion(os.Stdout)
|
||||||
|
} else {
|
||||||
|
file, err := getConfigPath("completion.zsh")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error saving completion file: %s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
err = cmd.Root().GenZshCompletionFile(file)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error saving completion file: %s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If someone knows how to do this automagically, please PR it!!
|
||||||
|
fmt.Println("Completions saved to " + file)
|
||||||
|
fmt.Println("You need to put this file in your $fpath manually!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func getConfigPath(fileName string) (string, error) {
|
||||||
|
dir, err := os.UserConfigDir()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
dir = filepath.Join(dir, "packwiz")
|
||||||
|
err = os.MkdirAll(dir, os.ModePerm)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return filepath.Join(dir, fileName), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getPowershellProfile() (string, error) {
|
||||||
|
ps, err := exec.LookPath("powershell.exe")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
cmd := exec.Command(ps, "-NoProfile", "-NonInteractive", "-Command", "$PROFILE")
|
||||||
|
var stdout bytes.Buffer
|
||||||
|
cmd.Stdout = &stdout
|
||||||
|
err = cmd.Run()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return strings.TrimSpace(stdout.String()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
utilsCmd.AddCommand(completionCmd)
|
||||||
|
|
||||||
|
completionCmd.Flags().Bool("source", false, "Output the source of the commands to be installed, rather than installing them")
|
||||||
|
viper.BindPFlag("utils.completion.source", completionCmd.Flags().Lookup("source"))
|
||||||
|
}
|
16
utils/utils.go
Normal file
16
utils/utils.go
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/comp500/packwiz/cmd"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// utilsCmd represents the base command when called without any subcommands
|
||||||
|
var utilsCmd = &cobra.Command{
|
||||||
|
Use: "utils",
|
||||||
|
Short: "Utilities for managing packwiz itself",
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
cmd.Add(utilsCmd)
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user