Skip to content

Commit

Permalink
Implement diffs for pkgbuild viewing.
Browse files Browse the repository at this point in the history
diff viewing can be toggled via --[no]showdiffs. When enabled diffs will
be shown for packages between the current HEAD and upstream's HEAD.
Packages downloaded via tarballs will be shown in full using the editor

git diff is used to show diffs. Therefore the pager for diffs can be
set via the PAGER and GIT_PAGER enviroment variables.
Morganamilo committed Jun 1, 2018
1 parent af91c2f commit f20fbd2
Showing 5 changed files with 137 additions and 20 deletions.
24 changes: 23 additions & 1 deletion cmd.go
Original file line number Diff line number Diff line change
@@ -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
}
2 changes: 2 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
@@ -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.
18 changes: 17 additions & 1 deletion download.go
Original file line number Diff line number Diff line change
@@ -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)
111 changes: 93 additions & 18 deletions install.go
Original file line number Diff line number Diff line change
@@ -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) {
2 changes: 2 additions & 0 deletions utils.go
Original file line number Diff line number Diff line change
@@ -4,6 +4,8 @@ import (
"unicode"
)

const gitEmptyTree = "4b825dc642cb6eb9a060e54bf8d69288fbee4904"

type mapStringSet map[string]stringSet

type intRange struct {

0 comments on commit f20fbd2

Please sign in to comment.