mirror of
https://github.com/Jguer/yay
synced 2024-10-31 13:42:27 +00:00
8fb83f3e70
Save the VSC Info as soon as the package install finishes. This should ensure the VSC db does not end up in an incorrect state if an install fails or is cancelled by the user. This also adds better support for split packages. When one or more packages are installed from the same base each individual package is added to the db not just the base. This allows us to track individual updates from the same base so that if one package gets updated we don't assume all packages in the base are updated.
193 lines
4.2 KiB
Go
193 lines
4.2 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
// branch contains the information of a repository branch
|
|
type branch struct {
|
|
Name string `json:"name"`
|
|
Commit struct {
|
|
SHA string `json:"sha"`
|
|
} `json:"commit"`
|
|
}
|
|
|
|
type branches []branch
|
|
|
|
// Info contains the last commit sha of a repo
|
|
type Info struct {
|
|
Package string `json:"pkgname"`
|
|
URL string `json:"url"`
|
|
SHA string `json:"sha"`
|
|
}
|
|
|
|
type infos []Info
|
|
|
|
// Repo contains information about the repository
|
|
type repo struct {
|
|
Name string `json:"name"`
|
|
FullName string `json:"full_name"`
|
|
DefaultBranch string `json:"default_branch"`
|
|
}
|
|
|
|
// createDevelDB forces yay to create a DB of the existing development packages
|
|
func createDevelDB() error {
|
|
_, _, _, remoteNames, err := filterPackages()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
config.NoConfirm = true
|
|
arguments := makeArguments()
|
|
arguments.addArg("gendb")
|
|
arguments.addTarget(remoteNames...)
|
|
err = install(arguments)
|
|
return err
|
|
}
|
|
|
|
// parseSource returns owner and repo from source
|
|
func parseSource(source string) (owner string, repo string) {
|
|
if !(strings.Contains(source, "git://") ||
|
|
strings.Contains(source, ".git") ||
|
|
strings.Contains(source, "git+https://")) {
|
|
return
|
|
}
|
|
split := strings.Split(source, "github.com/")
|
|
if len(split) > 1 {
|
|
secondSplit := strings.Split(split[1], "/")
|
|
if len(secondSplit) > 1 {
|
|
owner = secondSplit[0]
|
|
thirdSplit := strings.Split(secondSplit[1], ".git")
|
|
if len(thirdSplit) > 0 {
|
|
repo = thirdSplit[0]
|
|
}
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func (info *Info) needsUpdate() bool {
|
|
var newRepo repo
|
|
var newBranches branches
|
|
if strings.HasSuffix(info.URL, "/branches") {
|
|
info.URL = info.URL[:len(info.URL)-9]
|
|
}
|
|
infoResp, infoErr := http.Get(info.URL)
|
|
if infoErr != nil {
|
|
fmt.Println(infoErr)
|
|
return false
|
|
}
|
|
defer infoResp.Body.Close()
|
|
|
|
infoBody, _ := ioutil.ReadAll(infoResp.Body)
|
|
var err = json.Unmarshal(infoBody, &newRepo)
|
|
if err != nil {
|
|
fmt.Printf("Cannot update '%v'\nError: %v\nStatus code: %v\nBody: %v\n",
|
|
info.Package, err, infoResp.StatusCode, string(infoBody))
|
|
return false
|
|
}
|
|
|
|
defaultBranch := newRepo.DefaultBranch
|
|
branchesURL := info.URL + "/branches"
|
|
|
|
branchResp, branchErr := http.Get(branchesURL)
|
|
if branchErr != nil {
|
|
fmt.Println(branchErr)
|
|
return false
|
|
}
|
|
defer branchResp.Body.Close()
|
|
|
|
branchBody, _ := ioutil.ReadAll(branchResp.Body)
|
|
err = json.Unmarshal(branchBody, &newBranches)
|
|
if err != nil {
|
|
fmt.Printf("Cannot update '%v'\nError: %v\nStatus code: %v\nBody: %v\n",
|
|
info.Package, err, branchResp.StatusCode, string(branchBody))
|
|
return false
|
|
}
|
|
|
|
for _, e := range newBranches {
|
|
if e.Name == defaultBranch {
|
|
return e.Commit.SHA != info.SHA
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func inStore(pkgName string) *Info {
|
|
for i, e := range savedInfo {
|
|
if pkgName == e.Package {
|
|
return &savedInfo[i]
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// branchInfo updates saved information
|
|
func branchInfo(pkgName string, owner string, repoName string) (err error) {
|
|
updated := false
|
|
var newRepo repo
|
|
var newBranches branches
|
|
url := "https://api.github.com/repos/" + owner + "/" + repoName
|
|
repoResp, err := http.Get(url)
|
|
if err != nil {
|
|
return
|
|
}
|
|
defer repoResp.Body.Close()
|
|
|
|
_ = json.NewDecoder(repoResp.Body).Decode(&newRepo)
|
|
defaultBranch := newRepo.DefaultBranch
|
|
branchesURL := url + "/branches"
|
|
|
|
branchResp, err := http.Get(branchesURL)
|
|
if err != nil {
|
|
return
|
|
}
|
|
defer branchResp.Body.Close()
|
|
|
|
_ = json.NewDecoder(branchResp.Body).Decode(&newBranches)
|
|
|
|
packinfo := inStore(pkgName)
|
|
|
|
for _, e := range newBranches {
|
|
if e.Name == defaultBranch {
|
|
updated = true
|
|
|
|
if packinfo != nil {
|
|
packinfo.Package = pkgName
|
|
packinfo.URL = url
|
|
packinfo.SHA = e.Commit.SHA
|
|
} else {
|
|
savedInfo = append(savedInfo, Info{Package: pkgName, URL: url, SHA: e.Commit.SHA})
|
|
}
|
|
}
|
|
}
|
|
|
|
if updated {
|
|
saveVCSInfo()
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func saveVCSInfo() error {
|
|
marshalledinfo, err := json.MarshalIndent(savedInfo, "", "\t")
|
|
if err != nil || string(marshalledinfo) == "null" {
|
|
return err
|
|
}
|
|
in, err := os.OpenFile(vcsFile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer in.Close()
|
|
_, err = in.Write(marshalledinfo)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = in.Sync()
|
|
return err
|
|
}
|