Implement proper diff display

As raised in #994, diff display was not proper when interrupting during
download or diff review.

This commit introduce:
- Add a ref in the git tree named "YAY_DIFF_REVIEW" which is set to the last
diff reviewed by the user.
- Change the function displaying diff to user to make proper use of this
new ref. If the ref does not exist in the git tree, it will display the
diff from origin to HEAD@{upstream}.
- Add a function updating the YAY_DIFF_REVIEW after it has been reviewed
by user. It uses the `toDiff` list in the `install` function.
- Add utils function related to handling this change in download.go.

This change only consider diff reviewed to update the YAY_DIFF_REVIEW ref.
If a user does not enable review, the ref will not be updated and the
user will be prompted for review when he enables diff review.

Signed-off-by: Loic Reyreaud <reyreaud.loic@gmail.com>
This commit is contained in:
Loic Reyreaud 2019-10-07 12:24:19 +02:00
parent 6e2a4def99
commit 7ee206f36e
No known key found for this signature in database
GPG key ID: 9A0DA198DEC5C3FA
2 changed files with 62 additions and 9 deletions

View file

@ -48,17 +48,55 @@ func downloadFile(path string, url string) (err error) {
return err
}
func gitHasDiff(path string, name string) (bool, error) {
stdout, stderr, err := capture(passToGit(filepath.Join(path, name), "rev-parse", "HEAD", "HEAD@{upstream}"))
// Update the YAY_DIFF_REVIEW ref to HEAD. We use this ref to determine which diff were
// reviewed by the user
func gitUpdateSeenRef(path string, name string) error {
_, stderr, err := capture(passToGit(filepath.Join(path, name), "update-ref", "YAY_DIFF_REVIEW", "HEAD"))
if err != nil {
return false, fmt.Errorf("%s%s", stderr, err)
return fmt.Errorf("%s%s", stderr, err)
}
return nil
}
lines := strings.Split(stdout, "\n")
head := lines[0]
upstream := lines[1]
// Return wether or not we have reviewed a diff yet. It checks for the existence of
// YAY_DIFF_REVIEW in the git ref-list
func gitHasLastSeenRef(path string, name string) bool {
_, _, err := capture(passToGit(filepath.Join(path, name), "rev-parse", "--quiet", "--verify", "YAY_DIFF_REVIEW"))
return err == nil
}
return head != upstream, nil
// Returns the last reviewed hash. If YAY_DIFF_REVIEW exists it will return this hash.
// If it does not it will return empty tree as no diff have been reviewed yet.
func getLastSeenHash(path string, name string) (string, error) {
if gitHasLastSeenRef(path, name) {
stdout, stderr, err := capture(passToGit(filepath.Join(path, name), "rev-parse", "YAY_DIFF_REVIEW"))
if err != nil {
return "", fmt.Errorf("%s%s", stderr, err)
}
lines := strings.Split(stdout, "\n")
return lines[0], nil
}
return gitEmptyTree, nil
}
// Check whether or not a diff exists between the last reviewed diff and
// HEAD@{upstream}
func gitHasDiff(path string, name string) (bool, error) {
if gitHasLastSeenRef(path, name) {
stdout, stderr, err := capture(passToGit(filepath.Join(path, name), "rev-parse", "YAY_DIFF_REVIEW", "HEAD@{upstream}"))
if err != nil {
return false, fmt.Errorf("%s%s", stderr, err)
}
lines := strings.Split(stdout, "\n")
lastseen := lines[0]
upstream := lines[1]
return lastseen != upstream, nil
}
// If YAY_DIFF_REVIEW does not exists, we have never reviewed a diff for this package
// and should display it.
return true, nil
}
// TODO: yay-next passes args through the header, use that to unify ABS and AUR

View file

@ -224,6 +224,7 @@ func install(parser *arguments) (err error) {
if !continueTask(bold(green("Proceed with install?")), true) {
return fmt.Errorf("Aborting due to user")
}
updatePkgbuildSeenRef(toDiff, cloned)
config.NoConfirm = oldValue
}
@ -676,12 +677,26 @@ func editDiffNumberMenu(bases []Base, installed types.StringSet, diff bool) ([]B
return toEdit, nil
}
func updatePkgbuildSeenRef(bases []Base, cloned types.StringSet) error {
for _, base := range bases {
pkg := base.Pkgbase()
dir := filepath.Join(config.BuildDir, pkg)
if shouldUseGit(dir) {
gitUpdateSeenRef(config.BuildDir, pkg)
}
}
return nil
}
func showPkgbuildDiffs(bases []Base, cloned types.StringSet) error {
for _, base := range bases {
pkg := base.Pkgbase()
dir := filepath.Join(config.BuildDir, pkg)
if shouldUseGit(dir) {
start := "HEAD"
start, err := getLastSeenHash(config.BuildDir, pkg)
if err != nil {
return err
}
if cloned.Get(pkg) {
start = gitEmptyTree
@ -703,7 +718,7 @@ func showPkgbuildDiffs(bases []Base, cloned types.StringSet) error {
} else {
args = append(args, "--color=never")
}
err := show(passToGit(dir, args...))
err = show(passToGit(dir, args...))
if err != nil {
return err
}