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  }