github.com/kachick/nixpkgs-url@v0.3.2-0.20230806085406-bafeb8c13c92/core.go (about) 1 package core 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "io" 8 "net/http" 9 "os" 10 "path/filepath" 11 "regexp" 12 ) 13 14 var ( 15 importRe = regexp.MustCompile(`(?s)(import\s+\(fetchTarball\s+"https://github.com/NixOS/nixpkgs/archive/)([^"]+?)(\.tar\.gz"\))`) 16 flakeRe = regexp.MustCompile(`(nixpkgs\.url\s+=\s+"github:NixOS/nixpkgs/)([^"]+)(")`) 17 ) 18 19 // Returned regex should have 3 size captured groups 20 func GetRegexp(path string) *regexp.Regexp { 21 if filepath.Base(path) == "flake.nix" { 22 return flakeRe 23 } 24 25 return importRe 26 } 27 28 func Bump(path string, last string) error { 29 origin, err := os.ReadFile(path) 30 if err != nil { 31 return err 32 } 33 re := GetRegexp(path) 34 replaced := re.ReplaceAll(origin, []byte("${1}"+last+"${3}")) 35 if bytes.Equal(origin, replaced) { 36 return nil 37 } 38 39 return os.WriteFile(path, replaced, os.ModePerm) 40 } 41 42 func GetTargetPath() (string, error) { 43 paths := [3]string{"flake.nix", "default.nix", "shell.nix"} 44 for _, path := range paths { 45 _, err := os.Stat(path) 46 if err == nil { 47 return path, nil 48 } 49 50 if !os.IsNotExist(err) { 51 return "", fmt.Errorf("can not open %s: %w", path, err) 52 } 53 } 54 return "", fmt.Errorf("%v are not found", paths) 55 } 56 57 func GetCurrentVersion(path string) (string, error) { 58 origin, err := os.ReadFile(path) 59 if err != nil { 60 return "", err 61 } 62 re := GetRegexp(path) 63 matches := re.FindStringSubmatch(string(origin)) 64 if err != nil || len(matches) < 2 { 65 return "", err 66 } 67 68 return matches[2], nil 69 } 70 71 func GetLastVersion() (string, error) { 72 type commit struct { 73 Sha string `json:"sha"` 74 } 75 76 type response struct { 77 Commit commit `json:"commit"` 78 } 79 80 // https://docs.github.com/en/rest/branches/branches?apiVersion=2022-11-28#get-a-branch 81 req, _ := http.NewRequest("GET", "https://api.github.com/repos/NixOS/nixpkgs/branches/master", nil) 82 // May be necessary to set "Authorization" header if frequent requests are needed. 83 // -H "Authorization: Bearer <YOUR-TOKEN>"\ 84 req.Header.Set("Accept", "application/vnd.github+json") 85 req.Header.Set("X-GitHub-Api-Version", "2022-11-28") 86 client := new(http.Client) 87 res, err := client.Do(req) 88 if err != nil { 89 return "", err 90 } 91 defer res.Body.Close() 92 body, err := io.ReadAll(res.Body) 93 if err != nil { 94 return "", err 95 } 96 jsonRes := &response{} 97 if json.Unmarshal(body, jsonRes) != nil { 98 return "", err 99 } 100 return jsonRes.Commit.Sha, nil 101 }