Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

create qpm #1

Merged
merged 12 commits into from
May 6, 2022
34 changes: 34 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
module github.com/anoriqq/qpm

go 1.18

require (
github.com/AlecAivazis/survey/v2 v2.3.4
github.com/spf13/cobra v1.4.0
github.com/spf13/viper v1.11.0
)

require (
github.com/fsnotify/fsnotify v1.5.1 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
github.com/magiconair/properties v1.8.6 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
github.com/mitchellh/mapstructure v1.4.3 // indirect
github.com/pelletier/go-toml v1.9.4 // indirect
github.com/pelletier/go-toml/v2 v2.0.0-beta.8 // indirect
github.com/spf13/afero v1.8.2 // indirect
github.com/spf13/cast v1.4.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.2.0 // indirect
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect
golang.org/x/term v0.0.0-20210503060354-a79de5458b56 // indirect
golang.org/x/text v0.3.7 // indirect
gopkg.in/ini.v1 v1.66.4 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)
503 changes: 503 additions & 0 deletions go.sum

Large diffs are not rendered by default.

46 changes: 46 additions & 0 deletions internal/cmd/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package cmd

import (
"errors"
"fmt"
"strings"

"github.com/anoriqq/qpm/internal/config"
"github.com/spf13/cobra"
)

var configCmd = &cobra.Command{
Use: "config",
Short: "update config",
Example: ` # set ScriptDir to ~/.qpm
qpm config ScriptDir ~/.qpm`,
RunE: configRun,
}

func init() {
rootCmd.AddCommand(configCmd)
}

var r = strings.NewReplacer("{", "", "}", "", ":", ": ")

func configRun(_ *cobra.Command, args []string) error {
if len(args) < 2 {
return errors.New("config field and value is required")
}
if len(args) != 2 {
return errors.New("too many arguments")
}

configField, configValue := args[0], args[1]

switch strings.ToLower(configField) {
case "scriptdir":
config.SetScriptDir(configValue)
default:
return fmt.Errorf("unknown config field: %s", configField)
}

fmt.Println(r.Replace(fmt.Sprintf("%+v\n", config.Cfg)))

return nil
}
110 changes: 110 additions & 0 deletions internal/cmd/install.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package cmd

import (
"bufio"
"errors"
"fmt"
"os"
"os/exec"
"path/filepath"
"runtime"

"github.com/AlecAivazis/survey/v2"
"github.com/anoriqq/qpm/internal/config"
"github.com/spf13/cobra"
)

var installCmd = &cobra.Command{
Use: "install",
Short: "install packages",
RunE: installRun,
}

func init() {
rootCmd.AddCommand(installCmd)
}

func installRun(_ *cobra.Command, args []string) error {
if !config.HasScriptDir() {
scriptDir, err := surveyScriptDir()
if err != nil {
return err
}

err = config.SetScriptDir(scriptDir)
if err != nil {
return err
}
}

pkgName, err := getPkgName(args)
if err != nil {
return err
}

installScriptPath, err := getInstallScriptPaht(config.Cfg.ScriptDir, pkgName)
if err != nil {
return err
}

return execInstallScript(installScriptPath)
}

func surveyScriptDir() (string, error) {
home, err := os.UserHomeDir()
if err != nil {
return "", err
}

var scriptDir string
p := &survey.Input{
Message: "Please enter qpm script path.",
Default: filepath.Join(home, ".qpm"),
}
err = survey.AskOne(p, &scriptDir, survey.WithValidator(survey.Required))
if err != nil {
return "", err
}

return scriptDir, nil
}

func getPkgName(args []string) (string, error) {
if len(args) == 0 {
return "", errors.New("package name required")
}

return args[0], nil
}

func getInstallScriptPaht(scriptDir, pkgName string) (string, error) {
installScriptPath, err := filepath.Abs(fmt.Sprintf("%s/%s/latest.sh", scriptDir, pkgName))
if err != nil {
return "", err
}

return installScriptPath, nil
}

func execInstallScript(installScriptPath string) error {
_, err := os.Stat(installScriptPath)
if os.IsNotExist(err) {
return fmt.Errorf("install script not found: %s", installScriptPath)
}

c := exec.Command("/bin/sh", installScriptPath, "install", runtime.GOOS, runtime.GOARCH)

stdout, err := c.StdoutPipe()
if err != nil {
return err
}

c.Start()

scanner := bufio.NewScanner(stdout)
for scanner.Scan() {
fmt.Println(scanner.Text())
}

return c.Wait()
}
24 changes: 24 additions & 0 deletions internal/cmd/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package cmd

import (
"github.com/anoriqq/qpm/internal/config"
"github.com/spf13/cobra"
)

var rootCmd = &cobra.Command{
Use: "qpm",
Short: "qpm",
}

func Execute() error {
return rootCmd.Execute()
}

func init() {
cobra.OnInitialize(func() {
err := config.InitConfig()
if err != nil {
panic(err)
}
})
}
96 changes: 96 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package config

import (
"os"
"path/filepath"

"github.com/spf13/viper"
)

const (
configName = "config"
configType = "yml"
)

func InitConfig() error {
configHome, err := getConfigHomeDir()
if err != nil {
return err
}

err = createIfNotExistConfigFile(configHome, configName, configType)
if err != nil {
return err
}

viper.AddConfigPath(configHome)
viper.SetConfigName(configName)
viper.SetConfigType(configType)

viper.AutomaticEnv()

return Load()
}

func getConfigHomeDir() (string, error) {
home, err := os.UserHomeDir()
if err != nil {
return "", err
}

return filepath.Join(home, ".config/qpm"), nil
}

func createIfNotExistConfigFile(configHome, configName, configType string) error {
err := os.MkdirAll(configHome, os.ModePerm)
if err != nil {
return err
}

configPath := filepath.Join(configHome, configName+"."+configType)

_, err = os.Stat(configPath)
if os.IsNotExist(err) {
_, err := os.Create(configPath)
if err != nil {
return err
}
}

return nil
}

var Cfg Config

type Config struct {
ScriptDir string
}

func Load() error {
err := viper.ReadInConfig()
if err != nil {
return err
}

err = viper.Unmarshal(&Cfg)
if err != nil {
return err
}

return nil
}

func HasScriptDir() bool {
return len(Cfg.ScriptDir) != 0
}

func SetScriptDir(scriptDir string) error {
viper.Set("ScriptDir", scriptDir)

err := viper.WriteConfig()
if err != nil {
return err
}

return viper.Unmarshal(&Cfg)
}
14 changes: 14 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package main

import (
"os"

"github.com/anoriqq/qpm/internal/cmd"
)

func main() {
err := cmd.Execute()
if err != nil {
os.Exit(1)
}
}