Compare commits

...

13 Commits

24 changed files with 454 additions and 307 deletions

View File

@@ -1 +0,0 @@
make

View File

@@ -1,13 +0,0 @@
if command -v apt &> /dev/null; then
make aptinstall
elif command -v aptitude &> /dev/null; then
make aptitude
elif command -v brew &> /dev/null; then
make brewinstall
elif command -v zypper &> /dev/null; then
make zyppinstall
elif command -v yay &> /dev/null; then
make yayinstall
elif command -v pacman &> /dev/null; then
make pacinstall
fi

View File

@@ -1,16 +0,0 @@
name = "Pak"
desc = "Wrapper written in Go designed for package managers to unify software management commands between distros"
[dependencies]
brew = []
apt = []
dnf = []
yum = []
zypper = []
yay = []
pacman = []
[scripts]
build = "build.sh"
install = "install.sh"
remove = "remove.sh"

View File

@@ -1,2 +0,0 @@
rm /usr/bin/pak
rm /etc/pak.cfg

1
.gitignore vendored
View File

@@ -2,4 +2,5 @@ pak
pak-linux-x86_64 pak-linux-x86_64
pak-linux-aarch64 pak-linux-aarch64
pak-macos pak-macos
pak-new.toml
.idea .idea

4
.gitm.toml Normal file
View File

@@ -0,0 +1,4 @@
[repos]
origin = "ssh://git@192.168.100.62:2222/Arsen6331/pak.git"
gitlab = "git@gitlab.com:moussaelianarsen/pak.git"
github = "git@github.com:Arsen6331/pak.git"

39
AdvMakefile Normal file
View File

@@ -0,0 +1,39 @@
defaultName = "pak"
defaultTarget = "build"
availableManagers = [
"apk",
"apt",
"aptitude",
"brew",
"dnf",
"yum",
"npm",
"pacman",
"yay",
"pip",
"snap",
"zypper"
]
def pak_build():
if lookPath("go") == -1:
log("Go must be installed to compile pak", level="fatal")
execute("go build")
def pak_install():
mappings = {"PKGMANAGER": userChoice("Choose package manager", availableManagers)}
expandFile("pak.toml", mappings)
execute("""
install -Dm755 pak $DESTDIR/usr/bin/pak
install -Dm644 pak.toml $DESTDIR/etc/pak.toml
""")
def pak_install_noninteractive():
expandFile("pak.toml", {"PKGMANAGER": getEnv("PAK_CFG_MGR")})
execute("""
install -Dm755 pak $DESTDIR/usr/bin/pak
install -Dm644 pak.toml $DESTDIR/etc/pak.toml
""")

View File

@@ -1,87 +1,15 @@
GOBUILD ?= go build GOBUILD ?= go build
pak: main.go all: main.go
$(GOBUILD) $(GOBUILD)
install: PAK_CFG_MGR ?= apt
install: pak.toml pak
install -Dm755 pak $(DESTDIR)/usr/bin/pak
sed -i 's/activeManager = "\$PKGMANAGER"/activeManager = "$(PAK_CFG_MGR)"/' pak.toml
install -Dm644 pak.toml $(DESTDIR)/etc/pak.toml
installbinonly: pak installbinonly: pak
install -Dm755 pak $(DESTDIR)/usr/bin/pak install -Dm755 pak $(DESTDIR)/usr/bin/pak
mkdir -p $(DESTDIR)/etc/pak.d
aptinstall: plugins/apt/pak.cfg pak .PHONY: all install installbinonly
install -Dm644 plugins/apt/pak.cfg $(DESTDIR)/etc/pak.cfg
mkdir -p $(DESTDIR)/etc/pak.d
install -Dm644 plugins/snap/pak.cfg $(DESTDIR)/etc/pak.d/snap.cfg
install -Dm644 plugins/yay/pak.cfg $(DESTDIR)/etc/pak.d/yay.cfg
install -Dm644 plugins/zypper/pak.cfg $(DESTDIR)/etc/pak.d/zypper.cfg
install -Dm644 plugins/pacman/pak.cfg $(DESTDIR)/etc/pak.d/pacman.cfg
install -Dm644 plugins/brew/pak.cfg $(DESTDIR)/etc/pak.d/brew.cfg
install -Dm644 plugins/aptitude/pak.cfg $(DESTDIR)/etc/pak.d/aptitude.cfg
install -Dm755 pak $(DESTDIR)/usr/bin/pak
snapinstall: plugins/snap/pak.cfg pak
install -Dm644 plugins/snap/pak.cfg $(DESTDIR)/etc/pak.cfg
mkdir -p $(DESTDIR)/etc/pak.d
install -Dm644 plugins/apt/pak.cfg $(DESTDIR)/etc/pak.d/apt.cfg
install -Dm644 plugins/yay/pak.cfg $(DESTDIR)/etc/pak.d/yay.cfg
install -Dm644 plugins/zypper/pak.cfg $(DESTDIR)/etc/pak.d/zypper.cfg
install -Dm644 plugins/pacman/pak.cfg $(DESTDIR)/etc/pak.d/pacman.cfg
install -Dm644 plugins/brew/pak.cfg $(DESTDIR)/etc/pak.d/brew.cfg
install -Dm644 plugins/aptitude/pak.cfg $(DESTDIR)/etc/pak.d/aptitude.cfg
install -Dm755 pak $(DESTDIR)/usr/bin/pak
yayinstall: plugins/yay/pak.cfg pak
install -Dm644 plugins/yay/pak.cfg $(DESTDIR)/etc/pak.cfg
mkdir -p $(DESTDIR)/etc/pak.d
install -Dm644 plugins/snap/pak.cfg $(DESTDIR)/etc/pak.d/snap.cfg
install -Dm644 plugins/apt/pak.cfg $(DESTDIR)/etc/pak.d/apt.cfg
install -Dm644 plugins/zypper/pak.cfg $(DESTDIR)/etc/pak.d/zypper.cfg
install -Dm644 plugins/pacman/pak.cfg $(DESTDIR)/etc/pak.d/pacman.cfg
install -Dm644 plugins/brew/pak.cfg $(DESTDIR)/etc/pak.d/brew.cfg
install -Dm644 plugins/aptitude/pak.cfg $(DESTDIR)/etc/pak.d/aptitude.cfg
install -Dm755 pak $(DESTDIR)/usr/bin/pak
pacinstall: plugins/pacman/pak.cfg pak
install -Dm644 plugins/pacman/pak.cfg $(DESTDIR)/etc/pak.cfg
mkdir -p $(DESTDIR)/etc/pak.d
install -Dm644 plugins/snap/pak.cfg $(DESTDIR)/etc/pak.d/snap.cfg
install -Dm644 plugins/yay/pak.cfg $(DESTDIR)/etc/pak.d/yay.cfg
install -Dm644 plugins/zypper/pak.cfg $(DESTDIR)/etc/pak.d/zypper.cfg
install -Dm644 plugins/apt/pak.cfg $(DESTDIR)/etc/pak.d/apt.cfg
install -Dm644 plugins/brew/pak.cfg $(DESTDIR)/etc/pak.d/brew.cfg
install -Dm644 plugins/aptitude/pak.cfg $(DESTDIR)/etc/pak.d/aptitude.cfg
install -Dm755 pak $(DESTDIR)/usr/bin/pak
aptitude: plugins/aptitude/pak.cfg pak
install -Dm644 plugins/aptitude/pak.cfg $(DESTDIR)/etc/pak.cfg
mkdir -p $(DESTDIR)/etc/pak.d
install -Dm644 plugins/snap/pak.cfg $(DESTDIR)/etc/pak.d/snap.cfg
install -Dm644 plugins/yay/pak.cfg $(DESTDIR)/etc/pak.d/yay.cfg
install -Dm644 plugins/zypper/pak.cfg $(DESTDIR)/etc/pak.d/zypper.cfg
install -Dm644 plugins/pacman/pak.cfg $(DESTDIR)/etc/pak.d/pacman.cfg
install -Dm644 plugins/brew/pak.cfg $(DESTDIR)/etc/pak.d/brew.cfg
install -Dm644 plugins/apt/pak.cfg $(DESTDIR)/etc/pak.d/apt.cfg
install -Dm755 pak $(DESTDIR)/usr/bin/pak
brewinstall: plugins/brew/pak.cfg pak
install -Dm644 plugins/brew/pak.cfg $(DESTDIR)/etc/pak.cfg
mkdir -p $(DESTDIR)/etc/pak.d
install -Dm644 plugins/snap/pak.cfg $(DESTDIR)/etc/pak.d/snap.cfg
install -Dm644 plugins/yay/pak.cfg $(DESTDIR)/etc/pak.d/yay.cfg
install -Dm644 plugins/zypper/pak.cfg $(DESTDIR)/etc/pak.d/zypper.cfg
install -Dm644 plugins/pacman/pak.cfg $(DESTDIR)/etc/pak.d/pacman.cfg
install -Dm644 plugins/apt/pak.cfg $(DESTDIR)/etc/pak.d/apt.cfg
install -Dm644 plugins/aptitude/pak.cfg $(DESTDIR)/etc/pak.d/aptitude.cfg
install -Dm755 pak $(DESTDIR)/usr/bin/pak
zyppinstall: plugins/zypper/pak.cfg pak
install -Dm644 plugins/zypper/pak.cfg $(DESTDIR)/etc/pak.cfg
mkdir -p $(DESTDIR)/etc/pak.d
install -Dm644 plugins/snap/pak.cfg $(DESTDIR)/etc/pak.d/snap.cfg
install -Dm644 plugins/yay/pak.cfg $(DESTDIR)/etc/pak.d/yay.cfg
install -Dm644 plugins/apt/pak.cfg $(DESTDIR)/etc/pak.d/apt.cfg
install -Dm644 plugins/pacman/pak.cfg $(DESTDIR)/etc/pak.d/pacman.cfg
install -Dm644 plugins/brew/pak.cfg $(DESTDIR)/etc/pak.d/brew.cfg
install -Dm644 plugins/aptitude/pak.cfg $(DESTDIR)/etc/pak.d/aptitude.cfg
install -Dm755 pak $(DESTDIR)/usr/bin/pak
.PHONY: pak $(MAKECMDGOALS)

39
config.go Normal file
View File

@@ -0,0 +1,39 @@
package main
import (
"github.com/pelletier/go-toml"
"io/ioutil"
"path/filepath"
)
// Config contains the root of the TOML config file
type Config struct {
ActiveManager string
RootCommand string
Managers map[string]Manager
}
// Manager contains the root of all manager sections in the TOML config file
type Manager struct {
UseRoot bool
Commands map[string]string
Shortcuts map[string]string
}
// Create new Config{} with values from file path given
func NewConfig(path string) Config {
// Read file at path
data, err := ioutil.ReadFile(path)
if err != nil {
Log.Fatal().Err(err).Str("file", filepath.Base(path)).Msg("Error reading config")
}
// Create new Config{}
cfg := Config{}
// Unmarshal TOML in config
err = toml.Unmarshal(data, &cfg)
if err != nil {
Log.Fatal().Err(err).Str("file", filepath.Base(path)).Msg("Error unmarshalling TOML")
}
// Return config
return cfg
}

View File

@@ -41,7 +41,6 @@ func Jaro(a, b string) float64 {
return ((matches / la) + (matches / lb) + (matches-transposes)/matches) / 3.0 return ((matches / la) + (matches / lb) + (matches-transposes)/matches) / 3.0
} }
func JaroWinkler(a, b string, boostThreshold float64, prefixSize int) float64 { func JaroWinkler(a, b string, boostThreshold float64, prefixSize int) float64 {
j := Jaro(a, b) j := Jaro(a, b)

55
extra.go Normal file
View File

@@ -0,0 +1,55 @@
package main
// Check if slice contains string
func Contains(slice []string, val string) bool {
for _, item := range slice {
if item == val {
return true
}
}
return false
}
func Max(array []float64) float64 {
var max = array[0]
var min = array[0]
for _, value := range array {
if max < value {
max = value
}
if min > value {
min = value
}
}
return max
}
// Get key from map given value
func GetKey(inMap map[string]string, val string) string {
// For every key/value pair in map
for key, value := range inMap {
// If value found
if value == val {
// Return key
return key
}
}
// If fails, return empty string
return ""
}
// Get slice of float64 given map[string]float64
func GetValuesDist(inMap map[string]float64) []float64 {
// Make new slice with set capacity
values := make([]float64, len(inMap))
// Set index to 0
index := 0
for _, value := range inMap {
// Set index of slice to value
values[index] = value
// Increment index
index++
}
// Return completed slice
return values
}

9
go.mod
View File

@@ -1,5 +1,10 @@
module pak module go.arsenm.dev/pak
go 1.15 go 1.15
require github.com/pelletier/go-toml v1.8.2-0.20201124181426-2e01f733df54 require (
github.com/alessio/shellescape v1.4.1
github.com/pelletier/go-toml v1.8.2-0.20201124181426-2e01f733df54
github.com/rs/zerolog v1.20.0
github.com/spf13/pflag v1.0.5
)

27
go.sum
View File

@@ -1,3 +1,30 @@
github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVKJUX0=
github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pelletier/go-toml v1.8.2-0.20201124181426-2e01f733df54 h1:U7n5zyrdmyUTvXR7DRuSRrdFBkjcIPeCjSG2GScQSL8= github.com/pelletier/go-toml v1.8.2-0.20201124181426-2e01f733df54 h1:U7n5zyrdmyUTvXR7DRuSRrdFBkjcIPeCjSG2GScQSL8=
github.com/pelletier/go-toml v1.8.2-0.20201124181426-2e01f733df54/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= github.com/pelletier/go-toml v1.8.2-0.20201124181426-2e01f733df54/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
github.com/rs/zerolog v1.20.0 h1:38k9hgtUBdxFwE34yS8rTHmHBa4eN16E4DJlv177LNs=
github.com/rs/zerolog v1.20.0/go.mod h1:IzD0RJ65iWH0w97OQQebJEvTZYvsCUm9WVLWBQrJRjo=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74 h1:4cFkmztxtMslUX2SctSl+blCyXfpzhGOy9LhKAqSMA4=
golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

151
main.go
View File

@@ -19,152 +19,138 @@
package main package main
import ( import (
"flag"
"fmt" "fmt"
"github.com/pelletier/go-toml" "github.com/alessio/shellescape"
"io/ioutil" "github.com/rs/zerolog"
"log" "github.com/rs/zerolog/log"
flag "github.com/spf13/pflag"
"os" "os"
"os/exec" "os/exec"
"os/user" "os/user"
"regexp"
"strings" "strings"
) )
var Log = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
func main() { func main() {
// Put all arguments into a variable
args := os.Args[1:]
// Check which currentUser is running command // Create help flag
currentUser, err := user.Current() helpFlagGiven := flag.BoolP("help", "h", false, "Show help screen")
if err != nil { log.Fatal(err) } // Create package manager override flag
packageManagerOverride := flag.StringP("package-manager", "p", os.Getenv("PAK_MGR_OVERRIDE"), "Override package manager wrapped by pak")
// Create help flags
var helpFlagGiven bool
flag.BoolVar(&helpFlagGiven, "help", false, "Show help screen")
flag.BoolVar(&helpFlagGiven, "h", false, "Show help screen (shorthand)")
// Check to make sure root is not being used unless -r/--root specified
var rootCheckBypass bool
// Create --root and -r flags for root check bypass
flag.BoolVar(&rootCheckBypass,"root", false, "Bypass root check")
flag.BoolVar(&rootCheckBypass,"r", false, "Bypass root check (shorthand)")
// Parse arguments for flags // Parse arguments for flags
flag.Parse() flag.Parse()
// If flag not given // Check which user is running command
if !rootCheckBypass { currentUser, err := user.Current()
// If current user is root if err != nil {
if strings.Contains(currentUser.Username, "root") { Log.Fatal().Err(err).Msg("Error getting current user")
// Print warning message and exit
fmt.Println("Do not run as root, this program will invoke root for you if selected in config.")
fmt.Println("If you would like to bypass this, run this command with -r or --root.")
os.Exit(1)
} }
// If running as root
if strings.Contains(currentUser.Username, "root") {
// Print warning message
Log.Warn().Msg("Running as root may cause extraneous root invocation")
} }
// Create regex to remove all flags using ";;;" as it is uncommon to use in command line // Get arguments without flags
flagRegex := regexp.MustCompile(`-+[^;]*;;;`) args := flag.Args()
// Join args into string
argsStr := strings.Join(args, ";;;")
// Remove all flags from join args
argsStr = flagRegex.ReplaceAllString(argsStr, "")
// Separate args back into slice
args = strings.Split(argsStr, ";;;")
// Define variables for config file location, and override state boolean // Define variables for config file location, and override state boolean
var configFileLocation string
var isOverridden bool var isOverridden bool
// Get PAK_MGR_OVERRIDE environment variable
override := os.Getenv("PAK_MGR_OVERRIDE") // Read /etc/pak.toml into new Config{}
config := NewConfig("/etc/pak.toml")
// If override is set // If override is set
if override != "" { if *packageManagerOverride != "" {
// Set configFileLocation to /etc/pak.d/{override}.cfg // Set active package manager to override
configFileLocation = "/etc/pak.d/" + override + ".cfg" config.ActiveManager = *packageManagerOverride
// Set override state to true // Set override state to true
isOverridden = true isOverridden = true
} else { } else {
// Otherwise, set configFileLocation to default config
configFileLocation = "/etc/pak.cfg"
// Set override state to false // Set override state to false
isOverridden = false isOverridden = false
} }
// Parse config file removing all comments and empty lines
config, err := ioutil.ReadFile(configFileLocation)
parsedConfig, _ := toml.Load(string(config))
// Set first line of config to variable
packageManagerCommand := parsedConfig.Get("packageManager").(string)
//fmt.Println(packageManagerCommand) //DEBUG
// Parse list of commands in config line 2 and set to variable as array // Parse list of commands in config line 2 and set to variable as array
commands := InterfaceToString(parsedConfig.Get("commands").([]interface{})) commands := config.Managers[config.ActiveManager].Commands
//fmt.Println(commands) //DEBUG //fmt.Println(commands) //DEBUG
// Set the root option in config line 3 to a variable // Set the root option in config line 3 to a variable
useRoot := parsedConfig.Get("useRoot").(bool) useRoot := config.Managers[config.ActiveManager].UseRoot
//fmt.Println(useRoot) //DEBUG //fmt.Println(useRoot) //DEBUG
// Set command to use to invoke root at config line 4 to a variable // Set command to use to invoke root at config line 4 to a variable
rootCommand := parsedConfig.Get("rootCommand").(string) rootCommand := config.RootCommand
//fmt.Println(rootCommand) //DEBUG //fmt.Println(rootCommand) //DEBUG
// Parse list of shortcuts in config and line 5 set to variable as an array // Parse list of shortcuts in config and line 5 set to variable as an array
shortcuts := InterfaceToString(parsedConfig.Get("shortcuts").([]interface{})) shortcuts := config.Managers[config.ActiveManager].Shortcuts
//fmt.Println(shortcuts) //DEBUG //fmt.Println(shortcuts) //DEBUG
// Parse list of shortcuts in config line 6 and set to variable as array
shortcutMappings := InterfaceToString(parsedConfig.Get("shortcutMappings").([]interface{}))
//fmt.Println(shortcutMappings) //DEBUG
// Create similar to slice to put all matched commands into // Create similar to slice to put all matched commands into
var similarTo []string similarTo := []string{}
// Displays help message if no arguments provided or -h/--help is passed // Displays help message if no arguments provided or -h/--help is passed
if len(args) == 0 || helpFlagGiven || Contains(args, "help") { if len(args) == 0 || *helpFlagGiven || Contains(args, "help") {
printHelpMessage(packageManagerCommand, useRoot, rootCommand, commands, shortcuts, shortcutMappings, isOverridden) printHelpMessage(config.ActiveManager, rootCommand, commands, shortcuts, useRoot, isOverridden)
os.Exit(0) os.Exit(0)
} }
// Create distance slice to store JaroWinkler distance values // Create distance slice to store JaroWinkler distance values
var distance []float64 distance := map[string]float64{}
// Appends JaroWinkler distance between each available command and the first argument to an array // Appends JaroWinkler distance between each available command and the first argument to an array
for _,command := range commands { for command := range commands {
distance = append(distance, JaroWinkler(command, args[0], 1, 0)) distance[command] = JaroWinkler(command, args[0], 1, 0)
} }
// Deals with shortcuts // Deals with shortcuts
for index, shortcut := range shortcuts { for shortcut, mapping := range shortcuts {
// If the first argument is a shortcut and similarTo does not already contain its mapping, append it // If the first argument is a shortcut and similarTo does not already contain its mapping, append it
if args[0] == shortcut && !Contains(similarTo, shortcutMappings[index]) { if args[0] == shortcut && !Contains(similarTo, mapping) {
similarTo = append(similarTo, shortcutMappings[index]) similarTo = append(similarTo, mapping)
} }
} }
// Compares each distance to the max of the distance slice and appends the closest command to similarTo // Compares each distance to the max of the distance slice and appends the closest command to similarTo
for index, element := range distance { for command, cmdDist := range distance {
// If current element is the closest to the first argument // If current element is the closest to the first argument
if element == Max(distance) { if cmdDist == Max(GetValuesDist(distance)) {
// Append command at same index as distance to similarTo // Append command at same index as distance to similarTo
similarTo = append(similarTo, commands[index]) similarTo = append(similarTo, commands[command])
} }
} }
// If similarTo is still empty, log it fatally as something is wrong with the config or the code // If similarTo is still empty, log it fatally as something is wrong with the config or the code
if len(similarTo) == 0 { log.Fatalln("This command does not match any known commands or shortcuts") } if len(similarTo) == 0 {
// Anonymous function to decide whether to print (overridden) Log.Fatal().Msg("This command does not match any known commands or shortcuts")
printOverridden := func() string { if isOverridden { return "(overridden)" } else { return "" } } }
var overriddenStr string
if isOverridden {
overriddenStr = "(overridden)"
} else {
overriddenStr = ""
}
// Print text showing command being run and package manager being used // Print text showing command being run and package manager being used
fmt.Println("Running:", strings.Title(similarTo[0]), "using", strings.Title(packageManagerCommand), printOverridden()) fmt.Println("Running:", strings.Title(GetKey(commands, similarTo[0])), "using", strings.Title(config.ActiveManager), overriddenStr)
// Run package manager with the proper arguments passed if more than one argument exists // Run package manager with the proper arguments passed if more than one argument exists
var cmdArr []string var cmdArr []string
// If root is to be used, append it to cmdArr // If root is to be used, append it to cmdArr
if useRoot { cmdArr = append(cmdArr, rootCommand) } if useRoot {
// Create slice with all commands and arguments for the package manager cmdArr = append(cmdArr, rootCommand)
cmdArr = append(cmdArr, []string{packageManagerCommand, similarTo[0]}...) }
// If command to be run has a prefix of "cmd:"
if strings.HasPrefix(similarTo[0], "cmd:") {
// Append the command to the slice without the prefix
cmdArr = append(cmdArr, strings.TrimPrefix(similarTo[0], "cmd:"))
} else {
// Otherwise, append all commands and arguments for the package manager to slice
cmdArr = append(cmdArr, config.ActiveManager, similarTo[0])
}
// If greater than 2 arguments, append them to cmdArr // If greater than 2 arguments, append them to cmdArr
if len(args) >= 2 { cmdArr = append(cmdArr, strings.Join(args[1:], " ")) } if len(args) >= 2 {
cmdArr = append(cmdArr, shellescape.QuoteCommand(args[1:]))
}
// Create space separated string from cmdArr // Create space separated string from cmdArr
cmdStr := strings.Join(cmdArr, " ") cmdStr := strings.Join(cmdArr, " ")
// Instantiate exec.Command object with command sh, flag -c, and cmdStr // Instantiate exec.Command object with command sh, flag -c, and cmdStr
@@ -177,7 +163,6 @@ func main() {
err = command.Run() err = command.Run()
// If command returned an error, log fatally with explanation // If command returned an error, log fatally with explanation
if err != nil { if err != nil {
fmt.Println("Error received from child process") Log.Fatal().Err(err).Msg("Error received from child process")
log.Fatal(err)
} }
} }

184
pak.toml Normal file
View File

@@ -0,0 +1,184 @@
activeManager = "$PKGMANAGER"
rootCommand = "sudo"
[managers]
[managers.apt]
useRoot = true
[managers.apt.commands]
install = "install"
remove = "remove"
search = "search"
list = "list"
refresh = "update"
upgrade = "upgrade"
download = "download"
clean = "clean"
file-refresh = "cmd:apt-file update"
file-search = "cmd:apt-file search"
add-key = "cmd:apt-key add"
add-repo = "cmd:add-apt-repository"
[managers.apt.shortcuts]
arm = "autoremove"
[managers.aptitude]
useRoot = true
[managers.aptitude.commands]
install = "install"
remove = "remove"
download = "download"
refresh = "update"
upgrade = "upgrade"
full-upgrade = "full-upgrade"
safe-upgrade = "safe-upgrade"
clean = "clean"
hold = "hold"
unhold = "unhold"
mark-auto = "markauto"
unmark-auto = "unmarkauto"
why = "why"
whynot = "whynot"
reinstall = "reinstall"
search = "search"
show = "show"
list = "search '~i'"
changelog = "changelog"
file-refresh = "cmd:apt-file update"
file-search = "cmd:apt-file search"
add-key = "cmd:apt-key add"
add-repo = "cmd:add-apt-repository"
[managers.brew]
useRoot = false
[managers.brew.commands]
install = "install"
remove = "remove"
reinstall = "reinstall"
cask-install = "cask install"
cask-remove = "cask remove"
cask-reinstall = "cask reinstall"
cask = "cask"
list = "list"
refresh = "update"
upgrade = "upgrade"
search = "search"
doctor = "doctor"
edit = "edit"
[managers.snap]
useRoot = true
[managers.snap.commands]
install = "install"
remove = "remove"
upgrade = "refresh"
downgrade = "revert"
run = "run"
download = "download"
[managers.npm]
useRoot = false
[managers.npm.commands]
whoami = "whoami"
view = "view"
version = "version"
update = "update"
test = "test"
stop = "stop"
start = "start"
publish = "publish"
prune = "prune"
deprecate = "deprecate"
doctor = "doctor"
logout = "logout"
login = "login"
list = "list"
link = "link"
rebuild = "rebuild"
repo = "repo"
search = "search"
docs = "docs"
create = "create"
remove = "uninstall"
install = "install"
[managers.pip]
useRoot = false
[managers.pacman]
useRoot = true
[managers.pacman.commands]
install = "-S"
remove = "-R"
upgrade = "-Syu"
update = "-Su"
refresh = "-Sy"
autoremove = "-Rss $(pacman -Qdtq)"
search = "-Ss"
list = "-Qi"
file-refresh = "-Fy"
file-search = "-Fx"
[managers.pacman.shortcuts]
arm = "-Rss $(pacman -Qdtq)"
[managers.yay]
useRoot = false
[managers.yay.commands]
install = "-S"
remove = "-R"
upgrade = "-Syu"
update = "-Su"
refresh = "-Sy"
autoremove = "-Rss $(yay -Qdtq)"
search = "-Ss"
list = "-Qi"
file-refresh = "-Fy"
file-search = "-Fx"
interactive = ""
[managers.yay.shortcuts]
arm = "-Rss $(yay -Qdtq)"
[managers.apk]
useRoot = true
[managers.apk.commands]
install = "add"
remove = "del"
fix = "fix"
refresh = "update"
upgrade = "upgrade"
search = "search"
list = "info"
[managers.dnf]
useRoot = true
[managers.dnf.commands]
install = "install"
remove = "remove"
reinstall = "reinstall"
list = "list"
search = "search"
clean = "clean"
downgrade = "downgrade"
[managers.yum]
useRoot = true
[managers.yum.commands]
install = "install"
remove = "remove"
reinstall = "reinstall"
list = "list"
search = "search"
clean = "clean"
downgrade = "downgrade"
[managers.zypper]
useRoot = true
[managers.zypper.commands]
install = "install"
remove = "remove"
refresh = "refresh"
clean = "clean"
addrepo = "addrepo"
removerepo = "removerepo"
list-repos = "repos"
list = "packages -i"
search = "search"

View File

@@ -1,7 +0,0 @@
# Config for the pak package manager wrapper
packageManager = "apt"
commands = ["install", "remove", "update", "upgrade", "search", "download"]
useRoot = true
rootCommand = "sudo"
shortcuts = ["rm", "inst"]
shortcutMappings = ["remove", "install"]

View File

@@ -1,7 +0,0 @@
# Config for the pak package manager wrapper
packageManager = "aptitude"
commands = ["install", "remove", "download", "update", "upgrade", "full-upgrade", "safe-upgrade", "clean", "hold", "unhold", "markauto", "unmarkauto", "why", "whynot", "reinstall", "search", "show", "changelog"]
useRoot = true
rootCommand = "sudo"
shortcuts = ["rm", "inst"]
shortcutMappings = ["remove", "install"]

View File

@@ -1,7 +0,0 @@
# Config for the pak package manager wrapper
packageManager = "brew"
commands = ["install", "reinstall", "remove", "upgrade", "update", "search", "cask", "list", "doctor", "edit"]
useRoot = false
rootCommand = "sudo"
shortcuts = ["rm", "src", "dl", "ci", "cr", "cre"]
shortcutMappings = ["remove", "search", "download", "cask install", "cask remove", "cask reinstall"]

View File

@@ -1,7 +0,0 @@
# Config for the pak package manager wrapper
packageManager = "aptman"
commands = ["install", "remove", "upgrade", "update", "refresh", "autoremove", "search", "filesearch", "list"]
useRoot = true
rootCommand = "sudo"
shortcuts = ["rm", "arm", "ls"]
shortcutMappings = ["remove", "autoremove", "list"]

View File

@@ -1,7 +0,0 @@
# Config for the pak package manager wrapper
packageManager = "snap"
commands = ["install", "remove", "refresh", "revert", "run", "download"]
useRoot = true
rootCommand = "sudo"
shortcuts = ["rm", "inst"]
shortcutMappings = ["remove", "install"]

View File

@@ -1,7 +0,0 @@
# Config for the pak package manager wrapper
packageManager = "aptyay"
commands = ["install", "remove", "upgrade", "update", "refresh", "autoremove", "search", "filesearch", "list", "interactive"]
useRoot = false
rootCommand = "sudo"
shortcuts = ["rm", "arm", "ls", "int"]
shortcutMappings = ["remove", "autoremove", "list", "interactive"]

View File

@@ -1,7 +0,0 @@
# Config for the pak package manager wrapper
packageManager = "zypper"
commands = ["install", "remove", "refresh", "search", "update", "addrepo"]
useRoot = true
rootCommand = "sudo"
shortcuts = ["rm", "ar", "inst"]
shortcutMappings = ["remove", "addrepo", "install"]

View File

@@ -1,49 +0,0 @@
package main
import "fmt"
// Remove an element at an index from a slice
func removeAtIndex(s []string, index int) []string {
return append(s[:index], s[index+1:]...)
}
// Check if slice contains string
func Contains(slice []string, val string) bool {
for _, item := range slice {
if item == val {
return true
}
}
return false
}
func Max(array []float64) float64 {
var max = array[0]
var min = array[0]
for _, value := range array {
if max < value {
max = value
}
if min > value {
min = value
}
}
return max
}
func Find(slice []string, val string) int {
for i, item := range slice {
if item == val {
return i
}
}
return -1
}
func InterfaceToString(interfaceSlice []interface{}) []string {
returnedSlice := make([]string, len(interfaceSlice))
for index, element := range interfaceSlice {
returnedSlice[index] = fmt.Sprint(element)
}
return returnedSlice
}

View File

@@ -2,24 +2,35 @@ package main
import ( import (
"fmt" "fmt"
"strings"
) )
// Print help screen // Print help screen
func printHelpMessage(packageManagerCommand string, useRoot bool, rootCommand string, commands []string, shortcuts []string, shortcutMappings []string, isOverridden bool) { func printHelpMessage(packageManagerCommand, rootCommand string, commands, shortcuts map[string]string, useRoot, isOverridden bool) {
fmt.Println("Arsen Musayelyan's Package Manager Wrapper") fmt.Println("Arsen Musayelyan's Package Manager Wrapper")
fmt.Print("Current package manager is: ", packageManagerCommand) fmt.Print("Current package manager is: ", packageManagerCommand)
if isOverridden { fmt.Println(" (overridden)") } else { fmt.Print("\n") } if isOverridden {
if useRoot { fmt.Println("Using root with command:", rootCommand) } else { fmt.Println("Not using root") } fmt.Println(" (overridden)")
} else {
fmt.Print("\n")
}
if useRoot {
fmt.Println("Using root with command:", rootCommand)
} else {
fmt.Println("Not using root")
}
fmt.Println() fmt.Println()
fmt.Println("Usage: pak <command> [package]") fmt.Println("Usage: pak <command> [package]")
fmt.Println("Example: pak in hello") fmt.Println("Example: pak in hello")
fmt.Println() fmt.Println()
fmt.Println("The available commands are:") fmt.Println("The available commands are:")
fmt.Println(strings.Join(commands, "\n")) for command, mapping := range commands {
fmt.Println(command+":", mapping)
}
fmt.Println() fmt.Println()
fmt.Println("The available shortcuts are:") fmt.Println("The available shortcuts are:")
for index, element := range shortcuts { fmt.Println(element + ":", shortcutMappings[index]) } for shortcut, mapping := range shortcuts {
fmt.Println(shortcut+":", mapping)
}
fmt.Println() fmt.Println()
fmt.Println("The available flags are:") fmt.Println("The available flags are:")
fmt.Println("--help, -h: Shows this help screen") fmt.Println("--help, -h: Shows this help screen")