feat: add alias command
This commit is contained in:
parent
76a9973dc1
commit
74e595401f
155
cmd/cmd.go
155
cmd/cmd.go
|
@ -16,7 +16,9 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
dgfFolder = strings.Replace(pkg.DGF_FOLDER, "~", os.Getenv("HOME"), 1)
|
||||
dgfFolder = strings.ReplaceAll("~/.local/doggofetcher", "~", os.Getenv("HOME"))
|
||||
hashFile = filepath.Join(dgfFolder, "hash.txt")
|
||||
aliasFile = filepath.Join(dgfFolder, "alias.txt")
|
||||
re = regexp.MustCompile(`\d*\.?\d*\.?\d(rc|beta)?\d*?`)
|
||||
Logger = &logrus.Logger{
|
||||
Out: os.Stdout,
|
||||
|
@ -117,19 +119,25 @@ Release(s) folder will be removed from "~/.local/doggofetcher" and thus not avai
|
|||
Action: lsRemote,
|
||||
},
|
||||
{
|
||||
Name: "ls-remote",
|
||||
Usage: "List all remote references",
|
||||
Name: "alias",
|
||||
Usage: "Set an alias for a GoLang version",
|
||||
Action: alias,
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
Name: "rc",
|
||||
Usage: "Allow \"rc\" version to be fetched",
|
||||
Name: "list",
|
||||
Aliases: []string{"l"},
|
||||
Usage: "List all set alias and their version",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "beta",
|
||||
Usage: "Allow \"beta\" version to be fetched",
|
||||
&cli.StringFlag{
|
||||
Name: "get",
|
||||
Usage: "Get a version for a given alias",
|
||||
},
|
||||
&cli.StringSliceFlag{
|
||||
Name: "rename",
|
||||
Usage: "Rename an already existing alias",
|
||||
Value: nil,
|
||||
},
|
||||
},
|
||||
Action: lsRemote,
|
||||
},
|
||||
},
|
||||
Flags: []cli.Flag{
|
||||
|
@ -151,10 +159,19 @@ func Execute() error {
|
|||
}
|
||||
|
||||
func use(ctx *cli.Context) error {
|
||||
if err := checkInitialized(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ctx.Bool("verbose") {
|
||||
Logger.Level = logrus.DebugLevel
|
||||
}
|
||||
|
||||
alias, err := pkg.NewAlias(aliasFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var release string
|
||||
if ctx.NArg() == 0 {
|
||||
if !ctx.Bool("latest") {
|
||||
|
@ -164,27 +181,9 @@ func use(ctx *cli.Context) error {
|
|||
} else {
|
||||
release = ctx.Args().First()
|
||||
if !re.Match([]byte(release)) {
|
||||
return errors.New("release doesn't match \"\\d*\\.?\\d*\\.?\\d(rc|beta)?\\d*?\" format")
|
||||
}
|
||||
}
|
||||
|
||||
localFolder := dgfFolder
|
||||
fi, err := os.Stat(localFolder)
|
||||
if err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(localFolder, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if !fi.IsDir() {
|
||||
if err := os.RemoveAll(localFolder); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.MkdirAll(localFolder, 0755); err != nil {
|
||||
return err
|
||||
release = alias.GetAliasVersion(release)
|
||||
if release == "" {
|
||||
return fmt.Errorf("release doesn't match \"%s\" format nor is an existing alias", re.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -194,11 +193,11 @@ func use(ctx *cli.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
hash, err := pkg.NewHash(localFolder)
|
||||
hash, err := pkg.NewHash(hashFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r := pkg.NewRelease(release, filepath.Join(localFolder, release))
|
||||
r := pkg.NewRelease(release, filepath.Join(dgfFolder, release))
|
||||
|
||||
if err := r.CheckReleaseExists(); err != nil {
|
||||
if err != pkg.ErrReleaseNotFound {
|
||||
|
@ -248,7 +247,7 @@ func use(ctx *cli.Context) error {
|
|||
}
|
||||
|
||||
Logger.Info("Setting golang binary")
|
||||
if err := pkg.UpdateRelease(r.GetReleaseFolder()); err != nil {
|
||||
if err := pkg.UpdateRelease(filepath.Join(dgfFolder, "go"), r.GetReleaseFolder()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -261,14 +260,40 @@ func initFunc(ctx *cli.Context) error {
|
|||
Logger.Level = logrus.DebugLevel
|
||||
}
|
||||
|
||||
return pkg.Init(Logger)
|
||||
Logger.WithField("folder", dgfFolder).Infoln("Initializing doggofetcher folder")
|
||||
|
||||
if err := os.MkdirAll(dgfFolder, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
f, err := os.Create(hashFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f.Close()
|
||||
|
||||
f, err = os.Create(aliasFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f.Close()
|
||||
|
||||
Logger.Infoln("Add doggofetcher to your shell configuration file with the following command:")
|
||||
fmt.Fprintln(os.Stdout, "\n# doggofetcher section")
|
||||
fmt.Fprintf(os.Stdout, "export PATH=%s:$PATH\n", filepath.Join(dgfFolder, "go", "bin"))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// todo:
|
||||
func uninstall(ctx *cli.Context) error {
|
||||
return os.RemoveAll(filepath.Join(dgfFolder, "go"))
|
||||
}
|
||||
|
||||
func ls(ctx *cli.Context) error {
|
||||
if err := checkInitialized(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ctx.Bool("verbose") {
|
||||
Logger.Level = logrus.DebugLevel
|
||||
}
|
||||
|
@ -288,6 +313,10 @@ func ls(ctx *cli.Context) error {
|
|||
}
|
||||
|
||||
func remove(ctx *cli.Context) error {
|
||||
if err := checkInitialized(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ctx.Bool("verbose") {
|
||||
Logger.Level = logrus.DebugLevel
|
||||
}
|
||||
|
@ -360,6 +389,10 @@ func remove(ctx *cli.Context) error {
|
|||
}
|
||||
|
||||
func execCommand(ctx *cli.Context) error {
|
||||
if err := checkInitialized(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ctx.Bool("verbose") {
|
||||
Logger.Level = logrus.DebugLevel
|
||||
}
|
||||
|
@ -392,7 +425,59 @@ func lsRemote(ctx *cli.Context) error {
|
|||
continue
|
||||
}
|
||||
|
||||
fmt.Println(strings.Split(r.GetRef(), "/")[2])
|
||||
fmt.Println(strings.ReplaceAll(strings.Split(ref, "/")[2], "go", ""))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func alias(ctx *cli.Context) error {
|
||||
if err := checkInitialized(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
alias, err := pkg.NewAlias(aliasFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if ctx.Bool("list") {
|
||||
for a, v := range alias.GetAllAlias() {
|
||||
fmt.Printf("alias: %s | version: %s\n", a, v)
|
||||
}
|
||||
return nil
|
||||
} else if a := ctx.String("get"); a != "" {
|
||||
fmt.Printf("alias: %s | version: %s\n", a, alias.GetAliasVersion(a))
|
||||
return nil
|
||||
} else if values := ctx.StringSlice("rename"); len(values) != 0 {
|
||||
if len(values) != 2 {
|
||||
return errors.New("rename takes 2 parameters")
|
||||
}
|
||||
|
||||
if err := alias.RenameAlias(ctx.Args().Get(0), ctx.Args().Get(1)); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if ctx.NArg() != 2 {
|
||||
return errors.New("an alias needs an alias name and a golang version")
|
||||
}
|
||||
|
||||
alias.SetAlias(ctx.Args().Get(0), ctx.Args().Get(1))
|
||||
}
|
||||
|
||||
return alias.WriteAliasFile()
|
||||
}
|
||||
|
||||
func checkInitialized() error {
|
||||
fi, err := os.Stat(dgfFolder)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return fmt.Errorf("\"%s\" not initialized. Initialize it with \"doggo-fetcher init\"", dgfFolder)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
if !fi.IsDir() {
|
||||
return fmt.Errorf("\"%s\" is not a directory", dgfFolder)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
package pkg
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Alias struct {
|
||||
file string
|
||||
aliases map[string]string
|
||||
}
|
||||
|
||||
type Aliaser interface {
|
||||
GetAliasVersion(alias string) string
|
||||
GetAllAlias() map[string]string
|
||||
SetAlias(alias, version string)
|
||||
RenameAlias(old, new string) error
|
||||
WriteAliasFile() error
|
||||
}
|
||||
|
||||
func NewAlias(path string) (Aliaser, error) {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
alias := make(map[string]string)
|
||||
sc := bufio.NewScanner(f)
|
||||
for sc.Scan() {
|
||||
splittedLine := strings.Split(sc.Text(), " ")
|
||||
if len(splittedLine) != 2 {
|
||||
return nil, errors.New("alias file malformatted")
|
||||
}
|
||||
if splittedLine[1] == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
alias[splittedLine[0]] = splittedLine[1]
|
||||
}
|
||||
|
||||
return &Alias{
|
||||
file: path,
|
||||
aliases: alias,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a *Alias) GetAliasVersion(alias string) string {
|
||||
if v, ok := a.aliases[alias]; !ok {
|
||||
return ""
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
func (a *Alias) GetAllAlias() map[string]string {
|
||||
return a.aliases
|
||||
}
|
||||
|
||||
func (a *Alias) SetAlias(alias, version string) {
|
||||
a.aliases[alias] = strings.ReplaceAll(version, "go", "")
|
||||
}
|
||||
|
||||
func (a *Alias) WriteAliasFile() error {
|
||||
f, err := os.OpenFile(a.file, os.O_WRONLY|os.O_TRUNC, 06664)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
d := []byte{}
|
||||
for k, v := range a.aliases {
|
||||
d = append(d, []byte(fmt.Sprintf("%s %s", k, v))...)
|
||||
}
|
||||
|
||||
if _, err := f.Write(d); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *Alias) RenameAlias(old, new string) error {
|
||||
if _, ok := a.aliases[old]; !ok {
|
||||
return fmt.Errorf("\"%s\" isn't an alias", old)
|
||||
}
|
||||
|
||||
version := a.aliases[old]
|
||||
a.aliases[new] = version
|
||||
|
||||
delete(a.aliases, old)
|
||||
|
||||
return nil
|
||||
}
|
17
pkg/hash.go
17
pkg/hash.go
|
@ -22,21 +22,20 @@ type HashActions interface {
|
|||
}
|
||||
|
||||
type Hash struct {
|
||||
hashTable map[string]string
|
||||
hashTablePath string
|
||||
hashTable map[string]string
|
||||
hashFile string
|
||||
}
|
||||
|
||||
// NewHash returns a new Hash object. It reads the hashes from the ~/.local/doggofetcher/hashes.txt file then loads
|
||||
// them into the hash table.
|
||||
func NewHash(localFolder string) (HashActions, error) {
|
||||
hashTablePath := filepath.Join(localFolder, HASHES_FILE)
|
||||
f, err := os.OpenFile(hashTablePath, os.O_CREATE|os.O_RDONLY, 0644)
|
||||
func NewHash(hashFile string) (HashActions, error) {
|
||||
f, err := os.Open(hashFile)
|
||||
if err != nil {
|
||||
return &Hash{}, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
hashTable := map[string]string{}
|
||||
hashTable := make(map[string]string)
|
||||
sc := bufio.NewScanner(f)
|
||||
for sc.Scan() {
|
||||
l := strings.Split(sc.Text(), " ")
|
||||
|
@ -44,8 +43,8 @@ func NewHash(localFolder string) (HashActions, error) {
|
|||
}
|
||||
|
||||
return &Hash{
|
||||
hashTable: hashTable,
|
||||
hashTablePath: hashTablePath,
|
||||
hashTable: hashTable,
|
||||
hashFile: hashFile,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -153,5 +152,5 @@ func (h *Hash) writeHashTable() error {
|
|||
data = append(data, []byte(fmt.Sprintf("%s %s", path, hash))...)
|
||||
}
|
||||
|
||||
return os.WriteFile(h.hashTablePath, data, 0644)
|
||||
return os.WriteFile(h.hashFile, data, 0644)
|
||||
}
|
||||
|
|
33
pkg/utils.go
33
pkg/utils.go
|
@ -1,25 +1,20 @@
|
|||
package pkg
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func UpdateRelease(releaseFolder string) error {
|
||||
activeReleaseFolder := filepath.Join(strings.Replace(DGF_FOLDER, "~", os.Getenv("HOME"), 1), "go")
|
||||
if err := os.RemoveAll(activeReleaseFolder); err != nil {
|
||||
func UpdateRelease(activeRelease, releaseFolder string) error {
|
||||
if err := os.RemoveAll(activeRelease); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.MkdirAll(activeReleaseFolder, 0755); err != nil {
|
||||
if err := os.MkdirAll(activeRelease, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return CopyFolder(releaseFolder, activeReleaseFolder, true)
|
||||
return CopyFolder(releaseFolder, activeRelease, true)
|
||||
}
|
||||
|
||||
func CopyFolder(src, dst string, init bool) error {
|
||||
|
@ -68,23 +63,3 @@ func CopyFolder(src, dst string, init bool) error {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Init(logger *logrus.Logger) error {
|
||||
dgfFolder := strings.Replace(DGF_FOLDER, "~", os.Getenv("HOME"), 1)
|
||||
logger.WithField("folder", dgfFolder).Infoln("Initializing doggofetcher folder")
|
||||
|
||||
if err := os.MkdirAll(dgfFolder, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
f, err := os.Create(filepath.Join(dgfFolder, "hashes.txt"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f.Close()
|
||||
|
||||
logger.Infoln("Add doggofetcher to your shell configuration file with the following command:")
|
||||
fmt.Fprintln(os.Stdout, "\n# doggofetcher section")
|
||||
fmt.Fprintf(os.Stdout, "export PATH=%s:$PATH\n", filepath.Join(dgfFolder, "go", "bin"))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -3,8 +3,6 @@ package pkg
|
|||
import "errors"
|
||||
|
||||
const GO_DL_SERVER = "https://go.dev/dl"
|
||||
const DGF_FOLDER = "~/.local/doggofetcher"
|
||||
const HASHES_FILE = "hashes.txt"
|
||||
const LTS = "lts"
|
||||
|
||||
var (
|
||||
|
|
Reference in New Issue