Merge pull request #447 from Morganamilo/fix#131

Implement diffs for pkgbuild viewing.
This commit is contained in:
Anna 2018-06-01 19:11:52 +01:00 committed by GitHub
commit 5b6c4101f8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 137 additions and 20 deletions

24
cmd.go
View file

@ -304,6 +304,10 @@ func handleConfig(option, value string) bool {
config.PGPFetch = true
case "nopgpfetch":
config.PGPFetch = false
case "showdiffs":
config.ShowDiffs = true
case "noshowdiffs":
config.ShowDiffs = false
case "a", "aur":
mode = ModeAUR
case "repo":
@ -603,7 +607,6 @@ func passToMakepkgCapture(dir string, args ...string) (string, string, error) {
args = append(args, mflags...)
cmd := exec.Command(config.MakepkgBin, args...)
cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
cmd.Dir = dir
cmd.Stdout = &outbuf
cmd.Stderr = &errbuf
@ -630,3 +633,22 @@ func passToGit(dir string, _args ...string) (err error) {
err = cmd.Run()
return
}
func passToGitCapture(dir string, _args ...string) (string, string, error) {
var outbuf, errbuf bytes.Buffer
gitflags := strings.Fields(config.GitFlags)
args := []string{"-C", dir}
args = append(args, gitflags...)
args = append(args, _args...)
cmd := exec.Command(config.GitBin, args...)
cmd.Dir = dir
cmd.Stdout = &outbuf
cmd.Stderr = &errbuf
err := cmd.Run()
stdout := outbuf.String()
stderr := errbuf.String()
return stdout, stderr, err
}

View file

@ -64,6 +64,7 @@ type Configuration struct {
GitClone bool `json:"gitclone"`
Provides bool `json:"provides"`
PGPFetch bool `json:"pgpfetch"`
ShowDiffs bool `json:"showdifs"`
}
var version = "5.688"
@ -167,6 +168,7 @@ func defaultSettings(config *Configuration) {
config.AnswerUpgrade = ""
config.GitClone = true
config.Provides = true
config.ShowDiffs = true
}
// Editor returns the preferred system editor.

View file

@ -7,6 +7,7 @@ import (
"os"
"os/exec"
"path/filepath"
"strings"
)
// Decide what download method to use:
@ -20,7 +21,7 @@ func shouldUseGit(path string) bool {
}
_, err = os.Stat(filepath.Join(path, ".git"))
return os.IsExist(err)
return err == nil || os.IsExist(err)
}
func downloadFile(path string, url string) (err error) {
@ -43,6 +44,15 @@ func downloadFile(path string, url string) (err error) {
return err
}
func gitGetHash(path string, name string) (string, error) {
stdout, stderr, err := passToGitCapture(filepath.Join(path, name), "rev-parse", "HEAD")
if err != nil {
return "", fmt.Errorf("%s%s", stderr, err)
}
return strings.TrimSpace(stdout), nil
}
func gitDownload(url string, path string, name string) error {
_, err := os.Stat(filepath.Join(path, name, ".git"))
if os.IsNotExist(err) {
@ -74,6 +84,12 @@ func gitDownload(url string, path string, name string) error {
return nil
}
func gitDiff(path string, name string) error {
err := passToGit(filepath.Join(path, name), "diff", "HEAD..HEAD@{upstream}")
return err
}
// DownloadAndUnpack downloads url tgz and extracts to path.
func downloadAndUnpack(url string, path string) (err error) {
err = os.MkdirAll(path, 0755)

View file

@ -153,13 +153,17 @@ func install(parser *arguments) error {
cleanBuilds(toClean)
err = downloadPkgBuilds(do.Aur, parser.targets, do.Bases)
oldHashes, err := downloadPkgBuilds(do.Aur, parser.targets, do.Bases)
if err != nil {
return err
}
if len(toEdit) > 0 {
err = editPkgBuilds(toEdit)
if config.ShowDiffs {
err = showPkgBuildDiffs(toEdit, do.Bases, oldHashes)
} else {
err = editPkgBuilds(toEdit, do.Bases, oldHashes)
}
if err != nil {
return err
}
@ -422,7 +426,11 @@ func cleanEditNumberMenu(pkgs []*rpc.Pkg, bases map[string][]*rpc.Pkg, installed
}
}
fmt.Println(bold(green(arrow + " PKGBUILDs to edit?")))
if config.ShowDiffs {
fmt.Println(bold(green(arrow + " Diffs to show?")))
} else {
fmt.Println(bold(green(arrow + " PKGBUILDs to edit?")))
}
fmt.Println(bold(green(arrow) + cyan(" [N]one ") + "[A]ll [Ab]ort [I]nstalled [No]tInstalled or (1 2 3, 1-3, ^4)"))
fmt.Print(bold(green(arrow + " ")))
@ -481,20 +489,66 @@ func cleanBuilds(pkgs []*rpc.Pkg) {
}
}
func editPkgBuilds(pkgs []*rpc.Pkg) error {
func showPkgBuildDiffs(pkgs []*rpc.Pkg, bases map[string][]*rpc.Pkg, hashes map[string]string) error {
for _, pkg := range pkgs {
dir := filepath.Join(config.BuildDir, pkg.PackageBase)
if shouldUseGit(dir) {
hash, _ := hashes[pkg.PackageBase]
if hash == "" {
hash = gitEmptyTree
}
head, err := gitGetHash(config.BuildDir, pkg.PackageBase)
if err != nil {
return err
}
if head == hash {
fmt.Printf("%s %s: %s\n", bold(yellow(arrow)), cyan(formatPkgbase(pkg, bases)), bold("No changes -- skipping"))
continue
}
args := []string{"diff", hash + "..HEAD", "--src-prefix", dir + "/", "--dst-prefix", dir + "/"}
if useColor {
args = append(args, "--color=always")
} else {
args = append(args, "--color=never")
}
err = passToGit(dir, args...)
if err != nil {
return err
}
} else {
editor, editorArgs := editor()
editorArgs = append(editorArgs, filepath.Join(dir, "PKGBUILD"))
editcmd := exec.Command(editor, editorArgs...)
editcmd.Stdin, editcmd.Stdout, editcmd.Stderr = os.Stdin, os.Stdout, os.Stderr
err := editcmd.Run()
if err != nil {
return fmt.Errorf("Editor did not exit successfully, Aborting: %s", err)
}
}
}
return nil
}
func editPkgBuilds(pkgs []*rpc.Pkg, bases map[string][]*rpc.Pkg, hashes map[string]string) error {
pkgbuilds := make([]string, 0, len(pkgs))
for _, pkg := range pkgs {
dir := filepath.Join(config.BuildDir, pkg.PackageBase)
pkgbuilds = append(pkgbuilds, filepath.Join(dir, "PKGBUILD"))
}
editor, editorArgs := editor()
editorArgs = append(editorArgs, pkgbuilds...)
editcmd := exec.Command(editor, editorArgs...)
editcmd.Stdin, editcmd.Stdout, editcmd.Stderr = os.Stdin, os.Stdout, os.Stderr
err := editcmd.Run()
if err != nil {
return fmt.Errorf("Editor did not exit successfully, Aborting: %s", err)
if len(pkgbuilds) > 0 {
editor, editorArgs := editor()
editorArgs = append(editorArgs, pkgbuilds...)
editcmd := exec.Command(editor, editorArgs...)
editcmd.Stdin, editcmd.Stdout, editcmd.Stderr = os.Stdin, os.Stdout, os.Stderr
err := editcmd.Run()
if err != nil {
return fmt.Errorf("Editor did not exit successfully, Aborting: %s", err)
}
}
return nil
@ -535,8 +589,11 @@ func tryParsesrcinfosFile(pkgs []*rpc.Pkg, srcinfos map[string]*gopkg.PKGBUILD,
}
}
func downloadPkgBuilds(pkgs []*rpc.Pkg, targets stringSet, bases map[string][]*rpc.Pkg) error {
for k, pkg := range pkgs {
func downloadPkgBuilds(pkgs []*rpc.Pkg, targets stringSet, bases map[string][]*rpc.Pkg) (map[string]string, error) {
toSkip := make(stringSet)
hashes := make(map[string]string)
for _, pkg := range pkgs {
if config.ReDownload == "no" || (config.ReDownload == "yes" && !targets.get(pkg.Name)) {
dir := filepath.Join(config.BuildDir, pkg.PackageBase, ".SRCINFO")
pkgbuild, err := gopkg.ParseSRCINFO(dir)
@ -546,13 +603,28 @@ func downloadPkgBuilds(pkgs []*rpc.Pkg, targets stringSet, bases map[string][]*r
versionPKG, errP := gopkg.NewCompleteVersion(pkgbuild.Version())
if errP == nil && errR == nil {
if !versionRPC.Newer(versionPKG) {
str := bold(cyan("::") + " PKGBUILD up to date, Skipping (%d/%d): %s\n")
fmt.Printf(str, k+1, len(pkgs), cyan(formatPkgbase(pkg, bases)))
continue
toSkip.set(pkg.PackageBase)
}
}
}
}
}
for k, pkg := range pkgs {
if shouldUseGit(filepath.Join(config.BuildDir, pkg.PackageBase)) {
hash, err := gitGetHash(config.BuildDir, pkg.PackageBase)
if err == nil {
hashes[pkg.PackageBase] = hash
} else {
hashes[pkg.PackageBase] = ""
}
}
if toSkip.get(pkg.PackageBase) {
str := bold(cyan("::") + " PKGBUILD up to date, Skipping (%d/%d): %s\n")
fmt.Printf(str, k+1, len(pkgs), cyan(formatPkgbase(pkg, bases)))
continue
}
str := bold(cyan("::") + " Downloading PKGBUILD (%d/%d): %s\n")
@ -561,15 +633,18 @@ func downloadPkgBuilds(pkgs []*rpc.Pkg, targets stringSet, bases map[string][]*r
var err error
if shouldUseGit(filepath.Join(config.BuildDir, pkg.PackageBase)) {
err = gitDownload(baseURL+"/"+pkg.PackageBase+".git", config.BuildDir, pkg.PackageBase)
if err != nil {
return hashes, err
}
} else {
err = downloadAndUnpack(baseURL+pkg.URLPath, config.BuildDir)
}
if err != nil {
return err
return hashes, err
}
}
return nil
return hashes, nil
}
func downloadPkgBuildsSources(pkgs []*rpc.Pkg, bases map[string][]*rpc.Pkg, incompatible stringSet) (err error) {

View file

@ -5,6 +5,8 @@ import (
"unicode"
)
const gitEmptyTree = "4b825dc642cb6eb9a060e54bf8d69288fbee4904"
type mapStringSet map[string]stringSet
type intRange struct {