aboutsummaryrefslogtreecommitdiff
path: root/yae.go
diff options
context:
space:
mode:
authorFuwn <[email protected]>2024-10-11 00:36:28 -0700
committerFuwn <[email protected]>2024-10-11 00:36:28 -0700
commit756d44530f1411f35a532318a377a6fa76efa090 (patch)
tree08d548e0652c2cc3d24ae260d4bdc872e78b2741 /yae.go
parenta4645b34d92fef94350b570b8e99e8cc13195f41 (diff)
downloadyae-756d44530f1411f35a532318a377a6fa76efa090.tar.xz
yae-756d44530f1411f35a532318a377a6fa76efa090.zip
feat(yae): git sources and remote git source updater
Diffstat (limited to 'yae.go')
-rw-r--r--yae.go167
1 files changed, 126 insertions, 41 deletions
diff --git a/yae.go b/yae.go
index 3917a86..351e987 100644
--- a/yae.go
+++ b/yae.go
@@ -13,7 +13,7 @@ import (
func main() {
sources := Sources{}
- (&cli.App{
+ if err := (&cli.App{
Name: "yae",
Usage: "Nix Dependency Manager",
Description: "Nix Dependency Manager",
@@ -42,6 +42,7 @@ func main() {
ExitErrHandler: func(c *cli.Context, err error) {
if err != nil {
fmt.Println(err)
+ os.Exit(1)
}
},
Suggest: true,
@@ -68,6 +69,26 @@ func main() {
Usage: "Unpack the source into the Nix Store",
Value: true,
},
+ &cli.StringFlag{
+ Name: "type",
+ Usage: "Source type",
+ Required: true,
+ Action: func(c *cli.Context, value string) error {
+ if value != "binary" && value != "git" {
+ return fmt.Errorf("invalid source type: must be 'binary' or 'git'")
+ }
+
+ return nil
+ },
+ },
+ &cli.StringFlag{
+ Name: "version",
+ Usage: "Source version used in identifying latest git source",
+ },
+ &cli.StringFlag{
+ Name: "tag-predicate",
+ Usage: "Git tag predicate used in identifying latest git source",
+ },
},
Action: func(c *cli.Context) error {
if c.Args().Len() != 2 {
@@ -78,17 +99,34 @@ func main() {
return fmt.Errorf("source already exists")
}
- sha256, err := fetchSHA256(c.Args().Get(1), c.Bool("unpack"))
+ source := Source{
+ Unpack: c.Bool("unpack"),
+ Type: c.String("type"),
+ }
+ version := c.String("version")
+
+ if version != "" {
+ source.URITemplate = c.Args().Get(1)
+ source.Version = c.String("version")
- if err != nil {
+ if strings.Contains(source.URITemplate, "{version}") {
+ source.URI = strings.Replace(source.URITemplate, "{version}", source.Version, 1)
+ }
+ } else {
+ source.URI = c.Args().Get(1)
+ }
+
+ if source.Type == "git" && c.String("tag-predicate") != "" {
+ source.TagPredicate = c.String("tag-predicate")
+ }
+
+ if sha256, err := fetchSHA256(source.URI, c.Bool("unpack")); err != nil {
return err
+ } else {
+ source.SHA256 = sha256
}
- if err = sources.Add(c.Args().Get(0), Source{
- URI: c.Args().Get(1),
- SHA256: sha256,
- Unpack: c.Bool("unpack"),
- }); err != nil {
+ if err := sources.Add(c.Args().Get(0), source); err != nil {
return err
}
@@ -127,53 +165,30 @@ func main() {
Action: func(c *cli.Context) error {
if c.Args().Len() == 0 {
for key, value := range sources {
- sha256, err := fetchSHA256(value.URI, value.Unpack)
-
- if err != nil {
- return err
- }
-
- if sha256 != value.SHA256 {
- sources[key] = Source{
- URI: value.URI,
- SHA256: sha256,
- Unpack: value.Unpack,
- }
-
- fmt.Println("updated hash for", key)
- }
-
- if err = sources.Save(c.String("sources")); err != nil {
+ if err := updateSource(&sources, key, value); err != nil {
return err
}
}
} else {
- if !sources.Exists(c.Args().Get(0)) {
- return fmt.Errorf("source does not exist")
- }
+ name := c.Args().Get(0)
- sha256, err := fetchSHA256(sources[c.Args().Get(0)].URI, c.Bool("unpack"))
-
- if err != nil {
+ if err := updateSource(&sources, name, sources[name]); err != nil {
return err
}
+ }
- sources[c.Args().Get(0)] = Source{
- URI: sources[c.Args().Get(0)].URI,
- SHA256: sha256,
- Unpack: c.Bool("unpack"),
- }
-
- if err = sources.Save(c.String("sources")); err != nil {
- return err
- }
+ if err := sources.Save(c.String("sources")); err != nil {
+ return err
}
return nil
},
},
},
- }).Run(os.Args)
+ }).Run(os.Args); err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
}
func fetchSHA256(uri string, unpack bool) (string, error) {
@@ -204,3 +219,73 @@ func commandOutput(name string, args ...string) (string, error) {
return string(out), err
}
+
+func fetchLatestGitTag(source Source) (string, error) {
+ if source.Type == "git" {
+ repository := "https://github.com/" + strings.Split(source.URI, "/")[3] + "/" + strings.Split(source.URI, "/")[4]
+ remotes, err := commandOutput("git", "ls-remote", "--tags", repository)
+
+ if err != nil {
+ return "", err
+ }
+
+ refs := strings.Split(remotes, "\n")
+ var latest string
+
+ if source.TagPredicate == "" {
+ latest = refs[len(refs)-2]
+ } else {
+ for i := len(refs) - 2; i >= 0; i-- {
+ if strings.Contains(refs[i], source.TagPredicate) {
+ latest = strings.Split(refs[i], "/")[2]
+
+ break
+ }
+ }
+ }
+
+ return latest, nil
+ }
+
+ return "", fmt.Errorf("source is not a git repository")
+}
+
+func updateSource(sources *Sources, name string, source Source) error {
+ if !sources.Exists(name) {
+ return fmt.Errorf("source does not exist")
+ }
+
+ if source.Type == "git" {
+ tag, err := fetchLatestGitTag(source)
+
+ if err != nil {
+ return err
+ }
+
+ if tag != source.Version {
+ fmt.Println("updated version for", name, "from", source.Version, "to", tag)
+
+ source.Version = tag
+
+ if strings.Contains(source.URITemplate, "{version}") {
+ source.URI = strings.Replace(source.URITemplate, "{version}", source.Version, 1)
+ }
+ }
+ }
+
+ sha256, err := fetchSHA256(source.URI, source.Unpack)
+
+ if err != nil {
+ return err
+ }
+
+ if sha256 != source.SHA256 {
+ fmt.Println("updated hash for", name, "from", source.SHA256, "to", sha256)
+
+ source.SHA256 = sha256
+ }
+
+ (*sources)[name] = source
+
+ return nil
+}