feat: add alias command

This commit is contained in:
DataHearth 2022-10-01 18:13:18 +02:00
parent 76a9973dc1
commit 74e595401f
No known key found for this signature in database
GPG Key ID: E88FD356ACC5F3C4
5 changed files with 228 additions and 75 deletions

View File

@ -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

96
pkg/alias.go Normal file
View File

@ -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
}

View File

@ -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)
}

View File

@ -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
}

View File

@ -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 (