Refactor to clean up main, add unit tests around command selection
This commit is contained in:
parent
00e1cbcc62
commit
ad32b47827
87
loader/loader.go
Normal file
87
loader/loader.go
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
package loader
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"pikman/alpine"
|
||||||
|
"pikman/arch"
|
||||||
|
"pikman/fedora"
|
||||||
|
"pikman/flatpak"
|
||||||
|
"pikman/ubuntu"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type OSType = int
|
||||||
|
|
||||||
|
const (
|
||||||
|
Ubuntu OSType = iota
|
||||||
|
Arch
|
||||||
|
Fedora
|
||||||
|
Alpine
|
||||||
|
Flatpak
|
||||||
|
)
|
||||||
|
|
||||||
|
func ProcessCommand(command string, osType OSType, containerName string, packageName []string) error {
|
||||||
|
var err error
|
||||||
|
if osType != Ubuntu && osType != Flatpak && containerName != "" {
|
||||||
|
containerName = "--name " + containerName
|
||||||
|
} else {
|
||||||
|
containerName = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
commandToExecute, err := getCommand(command, osType, containerName, packageName)
|
||||||
|
cmd := exec.Command("/bin/sh", "-c", commandToExecute)
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
cmd.Stdin = os.Stdin
|
||||||
|
err = cmd.Run()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getCommand(command string, osType OSType, containerName string, packageName []string) (string, error) {
|
||||||
|
switch osType {
|
||||||
|
case Arch:
|
||||||
|
cmd, ok := arch.Commands[command]
|
||||||
|
if ok {
|
||||||
|
return fmt.Sprintf("%s %s %s %s", arch.PackageManager, cmd, containerName, strings.Join(packageName, " ")), nil
|
||||||
|
} else {
|
||||||
|
return "", fmt.Errorf("%s: is not a valid command for Arch", command)
|
||||||
|
}
|
||||||
|
case Fedora:
|
||||||
|
cmd, ok := fedora.Commands[command]
|
||||||
|
if ok {
|
||||||
|
return fmt.Sprintf("%s %s %s %s", fedora.PackageManager, cmd, containerName, strings.Join(packageName, " ")), nil
|
||||||
|
} else {
|
||||||
|
return "", fmt.Errorf("%s: is not a valid command for Fedora", command)
|
||||||
|
}
|
||||||
|
case Flatpak:
|
||||||
|
cmd, ok := flatpak.Commands[command]
|
||||||
|
if ok {
|
||||||
|
return fmt.Sprintf("%s %s %s", flatpak.PackageManager, cmd, strings.Join(packageName, " ")), nil
|
||||||
|
} else {
|
||||||
|
return "", fmt.Errorf("%s: is not a valid command for Flatpak", command)
|
||||||
|
}
|
||||||
|
case Alpine:
|
||||||
|
cmd, ok := alpine.Commands[command]
|
||||||
|
if ok {
|
||||||
|
return fmt.Sprintf("%s %s %s %s", alpine.PackageManager, cmd, containerName, strings.Join(packageName, " ")), nil
|
||||||
|
} else {
|
||||||
|
return "", fmt.Errorf("%s: is not a valid command for Alpine", command)
|
||||||
|
}
|
||||||
|
case Ubuntu:
|
||||||
|
cmd, ok := ubuntu.Commands[command]
|
||||||
|
if ok {
|
||||||
|
return fmt.Sprintf("%s %s %s", ubuntu.PackageManager, cmd, strings.Join(packageName, " ")), nil
|
||||||
|
} else {
|
||||||
|
return "", fmt.Errorf("%s: is not a valid command for Ubuntu", command)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", fmt.Errorf("%s: was passed without a valid backend", command)
|
||||||
|
}
|
86
loader/loader_test.go
Normal file
86
loader/loader_test.go
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
package loader
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func Test_getCommand(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
command string
|
||||||
|
osType OSType
|
||||||
|
containerName string
|
||||||
|
packageName []string
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want string
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Ubuntu single package",
|
||||||
|
args: args{
|
||||||
|
command: "install",
|
||||||
|
osType: Ubuntu,
|
||||||
|
containerName: "",
|
||||||
|
packageName: []string{"testPackage"},
|
||||||
|
},
|
||||||
|
want: "sudo -S nala install testPackage",
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Arch single package",
|
||||||
|
args: args{
|
||||||
|
command: "install",
|
||||||
|
osType: Arch,
|
||||||
|
containerName: "",
|
||||||
|
packageName: []string{"testPackage"},
|
||||||
|
},
|
||||||
|
want: "apx --aur install testPackage",
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Arch single package with container name",
|
||||||
|
args: args{
|
||||||
|
command: "install",
|
||||||
|
osType: Arch,
|
||||||
|
containerName: "--name testName",
|
||||||
|
packageName: []string{"testPackage"},
|
||||||
|
},
|
||||||
|
want: "apx --aur install --name testName testPackage",
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Ubuntu single package, container name not used",
|
||||||
|
args: args{
|
||||||
|
command: "install",
|
||||||
|
osType: Ubuntu,
|
||||||
|
containerName: "--name testName",
|
||||||
|
packageName: []string{"testPackage"},
|
||||||
|
},
|
||||||
|
want: "sudo -S nala install testPackage",
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Ubuntu invalid command should return nothing and error",
|
||||||
|
args: args{
|
||||||
|
command: "init",
|
||||||
|
osType: Ubuntu,
|
||||||
|
containerName: "",
|
||||||
|
packageName: []string{"testPackage"},
|
||||||
|
},
|
||||||
|
want: "",
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got, err := getCommand(tt.args.command, tt.args.osType, tt.args.containerName, tt.args.packageName)
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("getCommand() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if got != tt.want {
|
||||||
|
t.Errorf("getCommand() got = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
105
main.go
105
main.go
@ -1,17 +1,10 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"pikman/loader"
|
||||||
"pikman/alpine"
|
|
||||||
"pikman/arch"
|
|
||||||
"pikman/fedora"
|
|
||||||
"pikman/flatpak"
|
|
||||||
"pikman/ubuntu"
|
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type OSType = int
|
type OSType = int
|
||||||
@ -96,7 +89,7 @@ func main() {
|
|||||||
Name: "autoremove",
|
Name: "autoremove",
|
||||||
Usage: "Remove all unused packages",
|
Usage: "Remove all unused packages",
|
||||||
Action: func(cCtx *cli.Context) error {
|
Action: func(cCtx *cli.Context) error {
|
||||||
return processCommand(cCtx.Command.FullName(), osType, containerName, cCtx.Args().Slice())
|
return loader.ProcessCommand(cCtx.Command.FullName(), osType, containerName, cCtx.Args().Slice())
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -104,28 +97,28 @@ func main() {
|
|||||||
Aliases: []string{"cl"},
|
Aliases: []string{"cl"},
|
||||||
Usage: "Clean the package manager cache",
|
Usage: "Clean the package manager cache",
|
||||||
Action: func(cCtx *cli.Context) error {
|
Action: func(cCtx *cli.Context) error {
|
||||||
return processCommand(cCtx.Command.FullName(), osType, containerName, cCtx.Args().Slice())
|
return loader.ProcessCommand(cCtx.Command.FullName(), osType, containerName, cCtx.Args().Slice())
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "enter",
|
Name: "enter",
|
||||||
Usage: "Enter the container instance for select package manager",
|
Usage: "Enter the container instance for select package manager",
|
||||||
Action: func(cCtx *cli.Context) error {
|
Action: func(cCtx *cli.Context) error {
|
||||||
return processCommand(cCtx.Command.FullName(), osType, containerName, cCtx.Args().Slice())
|
return loader.ProcessCommand(cCtx.Command.FullName(), osType, containerName, cCtx.Args().Slice())
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "export",
|
Name: "export",
|
||||||
Usage: "Export/Recreate a program's desktop entry from the container",
|
Usage: "Export/Recreate a program's desktop entry from the container",
|
||||||
Action: func(cCtx *cli.Context) error {
|
Action: func(cCtx *cli.Context) error {
|
||||||
return processCommand(cCtx.Command.FullName(), osType, containerName, cCtx.Args().Slice())
|
return loader.ProcessCommand(cCtx.Command.FullName(), osType, containerName, cCtx.Args().Slice())
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "init",
|
Name: "init",
|
||||||
Usage: "Initialize a managed container",
|
Usage: "Initialize a managed container",
|
||||||
Action: func(cCtx *cli.Context) error {
|
Action: func(cCtx *cli.Context) error {
|
||||||
return processCommand(cCtx.Command.FullName(), osType, containerName, cCtx.Args().Slice())
|
return loader.ProcessCommand(cCtx.Command.FullName(), osType, containerName, cCtx.Args().Slice())
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -133,7 +126,7 @@ func main() {
|
|||||||
Aliases: []string{"i"},
|
Aliases: []string{"i"},
|
||||||
Usage: "Install the specified package(s)",
|
Usage: "Install the specified package(s)",
|
||||||
Action: func(cCtx *cli.Context) error {
|
Action: func(cCtx *cli.Context) error {
|
||||||
return processCommand(cCtx.Command.FullName(), osType, containerName, cCtx.Args().Slice())
|
return loader.ProcessCommand(cCtx.Command.FullName(), osType, containerName, cCtx.Args().Slice())
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -141,28 +134,28 @@ func main() {
|
|||||||
Aliases: []string{"l"},
|
Aliases: []string{"l"},
|
||||||
Usage: "List installed packages",
|
Usage: "List installed packages",
|
||||||
Action: func(cCtx *cli.Context) error {
|
Action: func(cCtx *cli.Context) error {
|
||||||
return processCommand(cCtx.Command.FullName(), osType, containerName, cCtx.Args().Slice())
|
return loader.ProcessCommand(cCtx.Command.FullName(), osType, containerName, cCtx.Args().Slice())
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "log",
|
Name: "log",
|
||||||
Usage: "Show package manager logs",
|
Usage: "Show package manager logs",
|
||||||
Action: func(cCtx *cli.Context) error {
|
Action: func(cCtx *cli.Context) error {
|
||||||
return processCommand(cCtx.Command.FullName(), osType, containerName, cCtx.Args().Slice())
|
return loader.ProcessCommand(cCtx.Command.FullName(), osType, containerName, cCtx.Args().Slice())
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "purge",
|
Name: "purge",
|
||||||
Usage: "Fully purge a package",
|
Usage: "Fully purge a package",
|
||||||
Action: func(cCtx *cli.Context) error {
|
Action: func(cCtx *cli.Context) error {
|
||||||
return processCommand(cCtx.Command.FullName(), osType, containerName, cCtx.Args().Slice())
|
return loader.ProcessCommand(cCtx.Command.FullName(), osType, containerName, cCtx.Args().Slice())
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "run",
|
Name: "run",
|
||||||
Usage: "Run a command inside a managed container",
|
Usage: "Run a command inside a managed container",
|
||||||
Action: func(cCtx *cli.Context) error {
|
Action: func(cCtx *cli.Context) error {
|
||||||
return processCommand(cCtx.Command.FullName(), osType, containerName, cCtx.Args().Slice())
|
return loader.ProcessCommand(cCtx.Command.FullName(), osType, containerName, cCtx.Args().Slice())
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -170,7 +163,7 @@ func main() {
|
|||||||
Aliases: []string{"r"},
|
Aliases: []string{"r"},
|
||||||
Usage: "Remove an installed package",
|
Usage: "Remove an installed package",
|
||||||
Action: func(cCtx *cli.Context) error {
|
Action: func(cCtx *cli.Context) error {
|
||||||
return processCommand(cCtx.Command.FullName(), osType, containerName, cCtx.Args().Slice())
|
return loader.ProcessCommand(cCtx.Command.FullName(), osType, containerName, cCtx.Args().Slice())
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -178,28 +171,28 @@ func main() {
|
|||||||
Aliases: []string{"s"},
|
Aliases: []string{"s"},
|
||||||
Usage: "Search for a package",
|
Usage: "Search for a package",
|
||||||
Action: func(cCtx *cli.Context) error {
|
Action: func(cCtx *cli.Context) error {
|
||||||
return processCommand(cCtx.Command.FullName(), osType, containerName, cCtx.Args().Slice())
|
return loader.ProcessCommand(cCtx.Command.FullName(), osType, containerName, cCtx.Args().Slice())
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "show",
|
Name: "show",
|
||||||
Usage: "Show details for a package",
|
Usage: "Show details for a package",
|
||||||
Action: func(cCtx *cli.Context) error {
|
Action: func(cCtx *cli.Context) error {
|
||||||
return processCommand(cCtx.Command.FullName(), osType, containerName, cCtx.Args().Slice())
|
return loader.ProcessCommand(cCtx.Command.FullName(), osType, containerName, cCtx.Args().Slice())
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "unexport",
|
Name: "unexport",
|
||||||
Usage: "Unexport/Remove a program's desktop entry",
|
Usage: "Unexport/Remove a program's desktop entry",
|
||||||
Action: func(cCtx *cli.Context) error {
|
Action: func(cCtx *cli.Context) error {
|
||||||
return processCommand(cCtx.Command.FullName(), osType, containerName, cCtx.Args().Slice())
|
return loader.ProcessCommand(cCtx.Command.FullName(), osType, containerName, cCtx.Args().Slice())
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "update",
|
Name: "update",
|
||||||
Usage: "Update the list of available packages",
|
Usage: "Update the list of available packages",
|
||||||
Action: func(cCtx *cli.Context) error {
|
Action: func(cCtx *cli.Context) error {
|
||||||
return processCommand(cCtx.Command.FullName(), osType, containerName, cCtx.Args().Slice())
|
return loader.ProcessCommand(cCtx.Command.FullName(), osType, containerName, cCtx.Args().Slice())
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -207,7 +200,7 @@ func main() {
|
|||||||
Usage: "Upgrade the system by installing/upgrading available packages",
|
Usage: "Upgrade the system by installing/upgrading available packages",
|
||||||
Action: func(cCtx *cli.Context) error {
|
Action: func(cCtx *cli.Context) error {
|
||||||
cCtx.Args().Tail()
|
cCtx.Args().Tail()
|
||||||
return processCommand(cCtx.Command.FullName(), osType, containerName, cCtx.Args().Slice())
|
return loader.ProcessCommand(cCtx.Command.FullName(), osType, containerName, cCtx.Args().Slice())
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -219,67 +212,3 @@ func main() {
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func processCommand(command string, osType OSType, containerName string, packageName []string) error {
|
|
||||||
var err error
|
|
||||||
if osType == Arch && containerName != "" {
|
|
||||||
containerName = "--name " + containerName
|
|
||||||
} else {
|
|
||||||
containerName = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
commandToExecute, err := getCommand(command, osType, containerName, packageName)
|
|
||||||
cmd := exec.Command("/bin/sh", "-c", commandToExecute)
|
|
||||||
cmd.Stdout = os.Stdout
|
|
||||||
cmd.Stderr = os.Stderr
|
|
||||||
cmd.Stdin = os.Stdin
|
|
||||||
err = cmd.Run()
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getCommand(command string, osType OSType, containerName string, packageName []string) (string, error) {
|
|
||||||
switch osType {
|
|
||||||
case Arch:
|
|
||||||
cmd, ok := arch.Commands[command]
|
|
||||||
if ok {
|
|
||||||
return fmt.Sprintf("%s %s %s %s", arch.PackageManager, cmd, containerName, strings.Join(packageName, " ")), nil
|
|
||||||
} else {
|
|
||||||
return "", fmt.Errorf("%s: is not a valid command for Arch", command)
|
|
||||||
}
|
|
||||||
case Fedora:
|
|
||||||
cmd, ok := fedora.Commands[command]
|
|
||||||
if ok {
|
|
||||||
return fmt.Sprintf("%s %s %s %s", fedora.PackageManager, cmd, containerName, strings.Join(packageName, " ")), nil
|
|
||||||
} else {
|
|
||||||
return "", fmt.Errorf("%s: is not a valid command for Fedora", command)
|
|
||||||
}
|
|
||||||
case Flatpak:
|
|
||||||
cmd, ok := flatpak.Commands[command]
|
|
||||||
if ok {
|
|
||||||
return fmt.Sprintf("%s %s %s", flatpak.PackageManager, cmd, strings.Join(packageName, " ")), nil
|
|
||||||
} else {
|
|
||||||
return "", fmt.Errorf("%s: is not a valid command for Flatpak", command)
|
|
||||||
}
|
|
||||||
case Alpine:
|
|
||||||
cmd, ok := alpine.Commands[command]
|
|
||||||
if ok {
|
|
||||||
return fmt.Sprintf("%s %s %s %s", alpine.PackageManager, cmd, containerName, strings.Join(packageName, " ")), nil
|
|
||||||
} else {
|
|
||||||
return "", fmt.Errorf("%s: is not a valid command for Alpine", command)
|
|
||||||
}
|
|
||||||
case Ubuntu:
|
|
||||||
cmd, ok := ubuntu.Commands[command]
|
|
||||||
if ok {
|
|
||||||
return fmt.Sprintf("%s %s %s", ubuntu.PackageManager, cmd, strings.Join(packageName, " ")), nil
|
|
||||||
} else {
|
|
||||||
return "", fmt.Errorf("%s: is not a valid command for Ubuntu", command)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return "", fmt.Errorf("%s: was passed without a valid backend", command)
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user