2023-03-16 22:50:02 +02:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"flag"
|
|
|
|
"log"
|
|
|
|
"os"
|
|
|
|
"os/exec"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"gopkg.in/yaml.v3"
|
|
|
|
)
|
|
|
|
|
|
|
|
type RequirementsFile []RequirementsEntry
|
|
|
|
type RequirementsEntry struct {
|
|
|
|
Src string `yaml:"src"`
|
|
|
|
Version string `yaml:"version"`
|
|
|
|
}
|
|
|
|
|
|
|
|
var requirementsPath string
|
|
|
|
var ignoredVersions = map[string]bool{
|
|
|
|
"main": true,
|
|
|
|
"master": true,
|
|
|
|
}
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
flag.StringVar(&requirementsPath, "r", "requirements.yml", "ansible-galaxy requirements file")
|
|
|
|
flag.Parse()
|
|
|
|
|
|
|
|
log.Println("updating requirements.yml...")
|
|
|
|
updateRequirements(requirementsPath)
|
|
|
|
}
|
|
|
|
|
|
|
|
func updateRequirements(path string) {
|
|
|
|
entries := parseRequirements(path)
|
|
|
|
for i, entry := range entries {
|
|
|
|
newVersion := updateRequirementEntry(entry)
|
|
|
|
if newVersion != "" {
|
|
|
|
log.Println(entry.Src, entry.Version, "->", newVersion)
|
|
|
|
entries[i].Version = newVersion
|
|
|
|
}
|
|
|
|
}
|
|
|
|
outb, err := yaml.Marshal(entries)
|
|
|
|
if err != nil {
|
|
|
|
log.Println("ERROR: ", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if err := os.WriteFile(path, outb, 0600); err != nil {
|
|
|
|
log.Println("ERROR: ", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func parseRequirements(path string) RequirementsFile {
|
|
|
|
fileb, err := os.ReadFile(path)
|
|
|
|
if err != nil {
|
|
|
|
log.Println("ERROR: ", err)
|
|
|
|
return RequirementsFile{}
|
|
|
|
}
|
|
|
|
var req RequirementsFile
|
|
|
|
if err := yaml.Unmarshal(fileb, &req); err != nil {
|
|
|
|
log.Println("ERROR: ", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return req
|
|
|
|
}
|
|
|
|
|
|
|
|
func updateRequirementEntry(entry RequirementsEntry) string {
|
|
|
|
if ignoredVersions[entry.Version] {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
|
|
|
// not a git repo
|
2023-03-16 23:29:28 +02:00
|
|
|
if !strings.Contains(entry.Src, "https") && !strings.Contains(entry.Src, "git") {
|
2023-03-16 22:50:02 +02:00
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
|
|
|
repo := strings.Replace(entry.Src, "git+https", "https", 1)
|
|
|
|
tags, err := execute("git ls-remote -tq --sort=-version:refname " + repo)
|
|
|
|
if err != nil {
|
|
|
|
log.Println("ERROR: ", err)
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
if tags == "" {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
|
|
|
lastline := strings.Split(tags, "\n")[0]
|
|
|
|
tagidx := strings.Index(lastline, "refs/tags/")
|
|
|
|
if tagidx == -1 {
|
|
|
|
log.Println("ERROR: lastline: ", lastline)
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
last := strings.Replace(lastline[tagidx:], "refs/tags/", "", 1)
|
|
|
|
if last != entry.Version {
|
|
|
|
return last
|
|
|
|
}
|
|
|
|
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
|
|
|
func execute(command string) (string, error) {
|
|
|
|
slice := strings.Split(command, " ")
|
2023-03-16 23:29:28 +02:00
|
|
|
out, err := exec.Command(slice[0], slice[1:]...).CombinedOutput()
|
2023-03-16 22:50:02 +02:00
|
|
|
if out == nil {
|
|
|
|
return "", err
|
|
|
|
}
|
2023-03-16 23:29:28 +02:00
|
|
|
|
2023-03-16 22:50:02 +02:00
|
|
|
return strings.TrimSuffix(string(out), "\n"), err
|
|
|
|
}
|