diff options
author | Vincent Ambo <tazjin@google.com> | 2019-09-02T19·00+0100 |
---|---|---|
committer | Vincent Ambo <tazjin@google.com> | 2019-09-02T19·01+0100 |
commit | f2e0f3ee27ae59e45b92351d0956432920722b7e (patch) | |
tree | 6ae59ed4b6a931f4be79af4de6f3e6dc75cad2cf /third_party/go/git-appraise/commands | |
parent | 2f239426aa4b9783c301a0ecbb4a9a4fd8b8e6dd (diff) |
chore(third_party): Remove git-appraise r/74
Not actually in use here ...
Diffstat (limited to 'third_party/go/git-appraise/commands')
-rw-r--r-- | third_party/go/git-appraise/commands/abandon.go | 139 | ||||
-rw-r--r-- | third_party/go/git-appraise/commands/accept.go | 109 | ||||
-rw-r--r-- | third_party/go/git-appraise/commands/commands.go | 55 | ||||
-rw-r--r-- | third_party/go/git-appraise/commands/comment.go | 165 | ||||
-rw-r--r-- | third_party/go/git-appraise/commands/input/input.go | 118 | ||||
-rw-r--r-- | third_party/go/git-appraise/commands/list.go | 74 | ||||
-rw-r--r-- | third_party/go/git-appraise/commands/output/output.go | 216 | ||||
-rw-r--r-- | third_party/go/git-appraise/commands/pull.go | 93 | ||||
-rw-r--r-- | third_party/go/git-appraise/commands/push.go | 49 | ||||
-rw-r--r-- | third_party/go/git-appraise/commands/rebase.go | 100 | ||||
-rw-r--r-- | third_party/go/git-appraise/commands/reject.go | 119 | ||||
-rw-r--r-- | third_party/go/git-appraise/commands/request.go | 182 | ||||
-rw-r--r-- | third_party/go/git-appraise/commands/request_test.go | 36 | ||||
-rw-r--r-- | third_party/go/git-appraise/commands/show.go | 85 | ||||
-rw-r--r-- | third_party/go/git-appraise/commands/submit.go | 157 |
15 files changed, 0 insertions, 1697 deletions
diff --git a/third_party/go/git-appraise/commands/abandon.go b/third_party/go/git-appraise/commands/abandon.go deleted file mode 100644 index 6f408e1663c9..000000000000 --- a/third_party/go/git-appraise/commands/abandon.go +++ /dev/null @@ -1,139 +0,0 @@ -/* -Copyright 2015 Google Inc. All rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package commands - -import ( - "errors" - "flag" - "fmt" - - "github.com/google/git-appraise/commands/input" - "github.com/google/git-appraise/repository" - "github.com/google/git-appraise/review" - "github.com/google/git-appraise/review/comment" - "github.com/google/git-appraise/review/gpg" - "github.com/google/git-appraise/review/request" -) - -var abandonFlagSet = flag.NewFlagSet("abandon", flag.ExitOnError) - -var ( - abandonMessageFile = abandonFlagSet.String("F", "", "Take the comment from the given file. Use - to read the message from the standard input") - abandonMessage = abandonFlagSet.String("m", "", "Message to attach to the review") - - abandonSign = abandonFlagSet.Bool("S", false, - "Sign the contents of the abandonment") -) - -// abandonReview adds an NMW comment to the current code review. -func abandonReview(repo repository.Repo, args []string) error { - abandonFlagSet.Parse(args) - args = abandonFlagSet.Args() - - var r *review.Review - var err error - if len(args) > 1 { - return errors.New("Only abandon a single review is supported.") - } - - if len(args) == 1 { - r, err = review.Get(repo, args[0]) - } else { - r, err = review.GetCurrent(repo) - } - - if err != nil { - return fmt.Errorf("Failed to load the review: %v\n", err) - } - if r == nil { - return errors.New("There is no matching review.") - } - - if *abandonMessageFile != "" && *abandonMessage == "" { - *abandonMessage, err = input.FromFile(*abandonMessageFile) - if err != nil { - return err - } - } - if *abandonMessageFile == "" && *abandonMessage == "" { - *abandonMessage, err = input.LaunchEditor(repo, commentFilename) - if err != nil { - return err - } - } - - abandonedCommit, err := r.GetHeadCommit() - if err != nil { - return err - } - location := comment.Location{ - Commit: abandonedCommit, - } - resolved := false - userEmail, err := repo.GetUserEmail() - if err != nil { - return err - } - c := comment.New(userEmail, *abandonMessage) - c.Location = &location - c.Resolved = &resolved - - var key string - if *abandonSign { - key, err := repo.GetUserSigningKey() - if err != nil { - return err - } - err = gpg.Sign(key, &c) - if err != nil { - return err - } - } - - err = r.AddComment(c) - if err != nil { - return err - } - - // Empty target ref indicates that request was abandoned - r.Request.TargetRef = "" - // (re)sign the request after clearing out `TargetRef'. - if *abandonSign { - err = gpg.Sign(key, &r.Request) - if err != nil { - return err - } - } - - note, err := r.Request.Write() - if err != nil { - return err - } - - return repo.AppendNote(request.Ref, r.Revision, note) -} - -// abandonCmd defines the "abandon" subcommand. -var abandonCmd = &Command{ - Usage: func(arg0 string) { - fmt.Printf("Usage: %s abandon [<option>...] [<commit>]\n\nOptions:\n", arg0) - abandonFlagSet.PrintDefaults() - }, - RunMethod: func(repo repository.Repo, args []string) error { - return abandonReview(repo, args) - }, -} diff --git a/third_party/go/git-appraise/commands/accept.go b/third_party/go/git-appraise/commands/accept.go deleted file mode 100644 index b50f424c252b..000000000000 --- a/third_party/go/git-appraise/commands/accept.go +++ /dev/null @@ -1,109 +0,0 @@ -/* -Copyright 2015 Google Inc. All rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package commands - -import ( - "errors" - "flag" - "fmt" - "github.com/google/git-appraise/commands/input" - "github.com/google/git-appraise/repository" - "github.com/google/git-appraise/review" - "github.com/google/git-appraise/review/comment" - "github.com/google/git-appraise/review/gpg" -) - -var acceptFlagSet = flag.NewFlagSet("accept", flag.ExitOnError) - -var ( - acceptMessageFile = acceptFlagSet.String("F", "", "Take the comment from the given file. Use - to read the message from the standard input") - acceptMessage = acceptFlagSet.String("m", "", "Message to attach to the review") - - acceptSign = acceptFlagSet.Bool("S", false, - "sign the contents of the acceptance") -) - -// acceptReview adds an LGTM comment to the current code review. -func acceptReview(repo repository.Repo, args []string) error { - acceptFlagSet.Parse(args) - args = acceptFlagSet.Args() - - var r *review.Review - var err error - if len(args) > 1 { - return errors.New("Only accepting a single review is supported.") - } - - if len(args) == 1 { - r, err = review.Get(repo, args[0]) - } else { - r, err = review.GetCurrent(repo) - } - - if err != nil { - return fmt.Errorf("Failed to load the review: %v\n", err) - } - if r == nil { - return errors.New("There is no matching review.") - } - - acceptedCommit, err := r.GetHeadCommit() - if err != nil { - return err - } - location := comment.Location{ - Commit: acceptedCommit, - } - resolved := true - userEmail, err := repo.GetUserEmail() - if err != nil { - return err - } - - if *acceptMessageFile != "" && *acceptMessage == "" { - *acceptMessage, err = input.FromFile(*acceptMessageFile) - if err != nil { - return err - } - } - - c := comment.New(userEmail, *acceptMessage) - c.Location = &location - c.Resolved = &resolved - if *acceptSign { - key, err := repo.GetUserSigningKey() - if err != nil { - return err - } - err = gpg.Sign(key, &c) - if err != nil { - return err - } - } - return r.AddComment(c) -} - -// acceptCmd defines the "accept" subcommand. -var acceptCmd = &Command{ - Usage: func(arg0 string) { - fmt.Printf("Usage: %s accept [<option>...] [<commit>]\n\nOptions:\n", arg0) - acceptFlagSet.PrintDefaults() - }, - RunMethod: func(repo repository.Repo, args []string) error { - return acceptReview(repo, args) - }, -} diff --git a/third_party/go/git-appraise/commands/commands.go b/third_party/go/git-appraise/commands/commands.go deleted file mode 100644 index 75b8c72d3769..000000000000 --- a/third_party/go/git-appraise/commands/commands.go +++ /dev/null @@ -1,55 +0,0 @@ -/* -Copyright 2015 Google Inc. All rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package commands contains the assorted sub commands supported by the git-appraise tool. -package commands - -import ( - "github.com/google/git-appraise/repository" -) - -const notesRefPattern = "refs/notes/devtools/*" -const archiveRefPattern = "refs/devtools/archives/*" -const commentFilename = "APPRAISE_COMMENT_EDITMSG" - -// Command represents the definition of a single command. -type Command struct { - Usage func(string) - RunMethod func(repository.Repo, []string) error -} - -// Run executes a command, given its arguments. -// -// The args parameter is all of the command line args that followed the -// subcommand. -func (cmd *Command) Run(repo repository.Repo, args []string) error { - return cmd.RunMethod(repo, args) -} - -// CommandMap defines all of the available (sub)commands. -var CommandMap = map[string]*Command{ - "abandon": abandonCmd, - "accept": acceptCmd, - "comment": commentCmd, - "list": listCmd, - "pull": pullCmd, - "push": pushCmd, - "rebase": rebaseCmd, - "reject": rejectCmd, - "request": requestCmd, - "show": showCmd, - "submit": submitCmd, -} diff --git a/third_party/go/git-appraise/commands/comment.go b/third_party/go/git-appraise/commands/comment.go deleted file mode 100644 index 554ac6dc78b8..000000000000 --- a/third_party/go/git-appraise/commands/comment.go +++ /dev/null @@ -1,165 +0,0 @@ -/* -Copyright 2015 Google Inc. All rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package commands - -import ( - "errors" - "flag" - "fmt" - - "github.com/google/git-appraise/commands/input" - "github.com/google/git-appraise/repository" - "github.com/google/git-appraise/review" - "github.com/google/git-appraise/review/comment" - "github.com/google/git-appraise/review/gpg" -) - -var commentFlagSet = flag.NewFlagSet("comment", flag.ExitOnError) -var commentLocation = comment.Range{} - -var ( - commentMessageFile = commentFlagSet.String("F", "", "Take the comment from the given file. Use - to read the message from the standard input") - commentMessage = commentFlagSet.String("m", "", "Message to attach to the review") - commentParent = commentFlagSet.String("p", "", "Parent comment") - commentFile = commentFlagSet.String("f", "", "File being commented upon") - commentLgtm = commentFlagSet.Bool("lgtm", false, "'Looks Good To Me'. Set this to express your approval. This cannot be combined with nmw") - commentNmw = commentFlagSet.Bool("nmw", false, "'Needs More Work'. Set this to express your disapproval. This cannot be combined with lgtm") - commentSign = commentFlagSet.Bool("S", false, - "Sign the contents of the comment") -) - -func init() { - commentFlagSet.Var(&commentLocation, "l", - `File location to be commented upon; requires that the -f flag also be set. -Location follows the following format: - <START LINE>[+<START COLUMN>][:<END LINE>[+<END COLUMN>]] -So, in order to comment starting on the 5th character of the 2nd line until (and -including) the 4th character of the 7th line, use: - -l 2+5:7+4`) -} - -// commentHashExists checks if the given comment hash exists in the given comment threads. -func commentHashExists(hashToFind string, threads []review.CommentThread) bool { - for _, thread := range threads { - if thread.Hash == hashToFind { - return true - } - if commentHashExists(hashToFind, thread.Children) { - return true - } - } - return false -} - -// commentOnReview adds a comment to the current code review. -func commentOnReview(repo repository.Repo, args []string) error { - commentFlagSet.Parse(args) - args = commentFlagSet.Args() - - var r *review.Review - var err error - if len(args) > 1 { - return errors.New("Only accepting a single review is supported.") - } - - if len(args) == 1 { - r, err = review.Get(repo, args[0]) - } else { - r, err = review.GetCurrent(repo) - } - - if err != nil { - return fmt.Errorf("Failed to load the review: %v\n", err) - } - if r == nil { - return errors.New("There is no matching review.") - } - - if *commentLgtm && *commentNmw { - return errors.New("You cannot combine the flags -lgtm and -nmw.") - } - if commentLocation != (comment.Range{}) && *commentFile == "" { - return errors.New("Specifying a line number with the -l flag requires that you also specify a file name with the -f flag.") - } - if *commentParent != "" && !commentHashExists(*commentParent, r.Comments) { - return errors.New("There is no matching parent comment.") - } - - if *commentMessageFile != "" && *commentMessage == "" { - *commentMessage, err = input.FromFile(*commentMessageFile) - if err != nil { - return err - } - } - if *commentMessageFile == "" && *commentMessage == "" { - *commentMessage, err = input.LaunchEditor(repo, commentFilename) - if err != nil { - return err - } - } - - commentedUponCommit, err := r.GetHeadCommit() - if err != nil { - return err - } - location := comment.Location{ - Commit: commentedUponCommit, - } - if *commentFile != "" { - location.Path = *commentFile - location.Range = &commentLocation - if err := location.Check(r.Repo); err != nil { - return fmt.Errorf("Unable to comment on the given location: %v", err) - } - } - - userEmail, err := repo.GetUserEmail() - if err != nil { - return err - } - c := comment.New(userEmail, *commentMessage) - c.Location = &location - c.Parent = *commentParent - if *commentLgtm || *commentNmw { - resolved := *commentLgtm - c.Resolved = &resolved - } - - if *commentSign { - key, err := repo.GetUserSigningKey() - if err != nil { - return err - } - err = gpg.Sign(key, &c) - if err != nil { - return err - } - } - - return r.AddComment(c) -} - -// commentCmd defines the "comment" subcommand. -var commentCmd = &Command{ - Usage: func(arg0 string) { - fmt.Printf("Usage: %s comment [<option>...] [<review-hash>]\n\nOptions:\n", arg0) - commentFlagSet.PrintDefaults() - }, - RunMethod: func(repo repository.Repo, args []string) error { - return commentOnReview(repo, args) - }, -} diff --git a/third_party/go/git-appraise/commands/input/input.go b/third_party/go/git-appraise/commands/input/input.go deleted file mode 100644 index 9a8678a8272e..000000000000 --- a/third_party/go/git-appraise/commands/input/input.go +++ /dev/null @@ -1,118 +0,0 @@ -/* -Copyright 2015 Google Inc. All rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package input - -import ( - "bufio" - "bytes" - "fmt" - "github.com/google/git-appraise/repository" - "io/ioutil" - "os" - "os/exec" -) - -// LaunchEditor launches the default editor configured for the given repo. This -// method blocks until the editor command has returned. -// -// The specified filename should be a temporary file and provided as a relative path -// from the repo (e.g. "FILENAME" will be converted to ".git/FILENAME"). This file -// will be deleted after the editor is closed and its contents have been read. -// -// This method returns the text that was read from the temporary file, or -// an error if any step in the process failed. -func LaunchEditor(repo repository.Repo, fileName string) (string, error) { - editor, err := repo.GetCoreEditor() - if err != nil { - return "", fmt.Errorf("Unable to detect default git editor: %v\n", err) - } - - path := fmt.Sprintf("%s/.git/%s", repo.GetPath(), fileName) - - cmd, err := startInlineCommand(editor, path) - if err != nil { - // Running the editor directly did not work. This might mean that - // the editor string is not a path to an executable, but rather - // a shell command (e.g. "emacsclient --tty"). As such, we'll try - // to run the command through bash, and if that fails, try with sh - args := []string{"-c", fmt.Sprintf("%s %q", editor, path)} - cmd, err = startInlineCommand("bash", args...) - if err != nil { - cmd, err = startInlineCommand("sh", args...) - } - } - if err != nil { - return "", fmt.Errorf("Unable to start editor: %v\n", err) - } - - if err := cmd.Wait(); err != nil { - return "", fmt.Errorf("Editing finished with error: %v\n", err) - } - - output, err := ioutil.ReadFile(path) - if err != nil { - os.Remove(path) - return "", fmt.Errorf("Error reading edited file: %v\n", err) - } - os.Remove(path) - return string(output), err -} - -// FromFile loads and returns the contents of a given file. If - is passed -// through, much like git, it will read from stdin. This can be piped data, -// unless there is a tty in which case the user will be prompted to enter a -// message. -func FromFile(fileName string) (string, error) { - if fileName == "-" { - stat, err := os.Stdin.Stat() - if err != nil { - return "", fmt.Errorf("Error reading from stdin: %v\n", err) - } - if (stat.Mode() & os.ModeCharDevice) == 0 { - // There is no tty. This will allow us to read piped data instead. - output, err := ioutil.ReadAll(os.Stdin) - if err != nil { - return "", fmt.Errorf("Error reading from stdin: %v\n", err) - } - return string(output), err - } - - fmt.Printf("(reading comment from standard input)\n") - var output bytes.Buffer - s := bufio.NewScanner(os.Stdin) - for s.Scan() { - output.Write(s.Bytes()) - output.WriteRune('\n') - } - return output.String(), nil - } - - output, err := ioutil.ReadFile(fileName) - if err != nil { - return "", fmt.Errorf("Error reading file: %v\n", err) - } - return string(output), err -} - -func startInlineCommand(command string, args ...string) (*exec.Cmd, error) { - cmd := exec.Command(command, args...) - cmd.Stdin = os.Stdin - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - err := cmd.Start() - return cmd, err -} diff --git a/third_party/go/git-appraise/commands/list.go b/third_party/go/git-appraise/commands/list.go deleted file mode 100644 index cc9338dd7e97..000000000000 --- a/third_party/go/git-appraise/commands/list.go +++ /dev/null @@ -1,74 +0,0 @@ -/* -Copyright 2015 Google Inc. All rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package commands - -import ( - "encoding/json" - "flag" - "fmt" - "github.com/google/git-appraise/commands/output" - "github.com/google/git-appraise/repository" - "github.com/google/git-appraise/review" -) - -var listFlagSet = flag.NewFlagSet("list", flag.ExitOnError) - -var ( - listAll = listFlagSet.Bool("a", false, "List all reviews (not just the open ones).") - listJSONOutput = listFlagSet.Bool("json", false, "Format the output as JSON") -) - -// listReviews lists all extant reviews. -// TODO(ojarjur): Add more flags for filtering the output (e.g. filtering by reviewer or status). -func listReviews(repo repository.Repo, args []string) error { - listFlagSet.Parse(args) - var reviews []review.Summary - if *listAll { - reviews = review.ListAll(repo) - if !*listJSONOutput { - fmt.Printf("Loaded %d reviews:\n", len(reviews)) - } - } else { - reviews = review.ListOpen(repo) - if !*listJSONOutput { - fmt.Printf("Loaded %d open reviews:\n", len(reviews)) - } - } - if *listJSONOutput { - b, err := json.MarshalIndent(reviews, "", " ") - if err != nil { - return err - } - fmt.Println(string(b)) - return nil - } - for _, r := range reviews { - output.PrintSummary(&r) - } - return nil -} - -// listCmd defines the "list" subcommand. -var listCmd = &Command{ - Usage: func(arg0 string) { - fmt.Printf("Usage: %s list [<option>...]\n\nOptions:\n", arg0) - listFlagSet.PrintDefaults() - }, - RunMethod: func(repo repository.Repo, args []string) error { - return listReviews(repo, args) - }, -} diff --git a/third_party/go/git-appraise/commands/output/output.go b/third_party/go/git-appraise/commands/output/output.go deleted file mode 100644 index 4613cd38576b..000000000000 --- a/third_party/go/git-appraise/commands/output/output.go +++ /dev/null @@ -1,216 +0,0 @@ -/* -Copyright 2015 Google Inc. All rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package output contains helper methods for pretty-printing code reviews. -package output - -import ( - "fmt" - "strconv" - "strings" - "time" - - "github.com/google/git-appraise/review" -) - -const ( - // Template for printing the summary of a code review. - reviewSummaryTemplate = `[%s] %.12s - %s -` - // Template for printing the summary of a code review. - reviewDetailsTemplate = ` %q -> %q - reviewers: %q - requester: %q - build status: %s -` - // Template for printing the location of an inline comment - commentLocationTemplate = `%s%q@%.12s -` - // Template for printing a single comment. - commentTemplate = `comment: %s -author: %s -time: %s -status: %s -%s` - // Template for displaying the summary of the comment threads for a review - commentSummaryTemplate = ` comments (%d threads): -` - // Number of lines of context to print for inline comments - contextLineCount = 5 -) - -// getStatusString returns a human friendly string encapsulating both the review's -// resolved status, and its submitted status. -func getStatusString(r *review.Summary) string { - if r.Resolved == nil && r.Submitted { - return "tbr" - } - if r.Resolved == nil { - return "pending" - } - if *r.Resolved && r.Submitted { - return "submitted" - } - if *r.Resolved { - return "accepted" - } - if r.Submitted { - return "danger" - } - if r.Request.TargetRef == "" { - return "abandon" - } - return "rejected" -} - -// PrintSummary prints a single-line summary of a review. -func PrintSummary(r *review.Summary) { - statusString := getStatusString(r) - indentedDescription := strings.Replace(r.Request.Description, "\n", "\n ", -1) - fmt.Printf(reviewSummaryTemplate, statusString, r.Revision, indentedDescription) -} - -// reformatTimestamp takes a timestamp string of the form "0123456789" and changes it -// to the form "Mon Jan _2 13:04:05 UTC 2006". -// -// Timestamps that are not in the format we expect are left alone. -func reformatTimestamp(timestamp string) string { - parsedTimestamp, err := strconv.ParseInt(timestamp, 10, 64) - if err != nil { - // The timestamp is an unexpected format, so leave it alone - return timestamp - } - t := time.Unix(parsedTimestamp, 0) - return t.Format(time.UnixDate) -} - -// showThread prints the detailed output for an entire comment thread. -func showThread(r *review.Review, thread review.CommentThread) error { - comment := thread.Comment - indent := " " - if comment.Location != nil && comment.Location.Path != "" && comment.Location.Range != nil && comment.Location.Range.StartLine > 0 { - contents, err := r.Repo.Show(comment.Location.Commit, comment.Location.Path) - if err != nil { - return err - } - lines := strings.Split(contents, "\n") - err = comment.Location.Check(r.Repo) - if err != nil { - return err - } - if comment.Location.Range.StartLine <= uint32(len(lines)) { - firstLine := comment.Location.Range.StartLine - lastLine := comment.Location.Range.EndLine - - if firstLine == 0 { - firstLine = 1 - } - - if lastLine == 0 { - lastLine = firstLine - } - - if lastLine == firstLine { - minLine := int(lastLine) - int(contextLineCount) - if minLine <= 0 { - minLine = 1 - } - firstLine = uint32(minLine) - } - - fmt.Printf(commentLocationTemplate, indent, comment.Location.Path, comment.Location.Commit) - fmt.Println(indent + "|" + strings.Join(lines[firstLine-1:lastLine], "\n"+indent+"|")) - } - } - return showSubThread(r, thread, indent) -} - -// showSubThread prints the given comment (sub)thread, indented by the given prefix string. -func showSubThread(r *review.Review, thread review.CommentThread, indent string) error { - statusString := "fyi" - if thread.Resolved != nil { - if *thread.Resolved { - statusString = "lgtm" - } else { - statusString = "needs work" - } - } - comment := thread.Comment - threadHash := thread.Hash - timestamp := reformatTimestamp(comment.Timestamp) - commentSummary := fmt.Sprintf(indent+commentTemplate, threadHash, comment.Author, timestamp, statusString, comment.Description) - indent = indent + " " - indentedSummary := strings.Replace(commentSummary, "\n", "\n"+indent, -1) - fmt.Println(indentedSummary) - for _, child := range thread.Children { - err := showSubThread(r, child, indent) - if err != nil { - return err - } - } - return nil -} - -// printAnalyses prints the static analysis results for the latest commit in the review. -func printAnalyses(r *review.Review) { - fmt.Println(" analyses: ", r.GetAnalysesMessage()) -} - -// printComments prints all of the comments for the review, with snippets of the preceding source code. -func printComments(r *review.Review) error { - fmt.Printf(commentSummaryTemplate, len(r.Comments)) - for _, thread := range r.Comments { - err := showThread(r, thread) - if err != nil { - return err - } - } - return nil -} - -// PrintDetails prints a multi-line overview of a review, including all comments. -func PrintDetails(r *review.Review) error { - PrintSummary(r.Summary) - fmt.Printf(reviewDetailsTemplate, r.Request.ReviewRef, r.Request.TargetRef, - strings.Join(r.Request.Reviewers, ", "), - r.Request.Requester, r.GetBuildStatusMessage()) - printAnalyses(r) - if err := printComments(r); err != nil { - return err - } - return nil -} - -// PrintJSON pretty prints the given review in JSON format. -func PrintJSON(r *review.Review) error { - json, err := r.GetJSON() - if err != nil { - return err - } - fmt.Println(json) - return nil -} - -// PrintDiff prints the diff of the review. -func PrintDiff(r *review.Review, diffArgs ...string) error { - diff, err := r.GetDiff(diffArgs...) - if err != nil { - return err - } - fmt.Println(diff) - return nil -} diff --git a/third_party/go/git-appraise/commands/pull.go b/third_party/go/git-appraise/commands/pull.go deleted file mode 100644 index 809c20fdbbfe..000000000000 --- a/third_party/go/git-appraise/commands/pull.go +++ /dev/null @@ -1,93 +0,0 @@ -/* -Copyright 2015 Google Inc. All rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package commands - -import ( - "errors" - "flag" - "fmt" - - "github.com/google/git-appraise/repository" - "github.com/google/git-appraise/review" -) - -var ( - pullFlagSet = flag.NewFlagSet("pull", flag.ExitOnError) - pullVerify = pullFlagSet.Bool("verify-signatures", false, - "verify the signatures of pulled reviews") -) - -// pull updates the local git-notes used for reviews with those from a remote -// repo. -func pull(repo repository.Repo, args []string) error { - pullFlagSet.Parse(args) - pullArgs := pullFlagSet.Args() - - if len(pullArgs) > 1 { - return errors.New( - "Only pulling from one remote at a time is supported.") - } - - remote := "origin" - if len(pullArgs) == 1 { - remote = pullArgs[0] - } - // This is the easy case. We're not checking signatures so just go the - // normal route. - if !*pullVerify { - return repo.PullNotesAndArchive(remote, notesRefPattern, - archiveRefPattern) - } - - // Otherwise, we collect the fetched reviewed revisions (their hashes), get - // their reviews, and then one by one, verify them. If we make it through - // the set, _then_ we merge the remote reference into the local branch. - revisions, err := repo.FetchAndReturnNewReviewHashes(remote, - notesRefPattern, archiveRefPattern) - if err != nil { - return err - } - for _, revision := range revisions { - rvw, err := review.GetSummaryViaRefs(repo, - "refs/notes/"+remote+"/devtools/reviews", - "refs/notes/"+remote+"/devtools/discuss", revision) - if err != nil { - return err - } - err = rvw.Verify() - if err != nil { - return err - } - fmt.Println("verified review:", revision) - } - - err = repo.MergeNotes(remote, notesRefPattern) - if err != nil { - return err - } - return repo.MergeArchives(remote, archiveRefPattern) -} - -var pullCmd = &Command{ - Usage: func(arg0 string) { - fmt.Printf("Usage: %s pull [<option>] [<remote>]\n\nOptions:\n", arg0) - pullFlagSet.PrintDefaults() - }, - RunMethod: func(repo repository.Repo, args []string) error { - return pull(repo, args) - }, -} diff --git a/third_party/go/git-appraise/commands/push.go b/third_party/go/git-appraise/commands/push.go deleted file mode 100644 index c75a25eac738..000000000000 --- a/third_party/go/git-appraise/commands/push.go +++ /dev/null @@ -1,49 +0,0 @@ -/* -Copyright 2015 Google Inc. All rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package commands - -import ( - "errors" - "fmt" - "github.com/google/git-appraise/repository" -) - -// push pushes the local git-notes used for reviews to a remote repo. -func push(repo repository.Repo, args []string) error { - if len(args) > 1 { - return errors.New("Only pushing to one remote at a time is supported.") - } - - remote := "origin" - if len(args) == 1 { - remote = args[0] - } - - if err := repo.PushNotesAndArchive(remote, notesRefPattern, archiveRefPattern); err != nil { - return err - } - return nil -} - -var pushCmd = &Command{ - Usage: func(arg0 string) { - fmt.Printf("Usage: %s push [<remote>]\n", arg0) - }, - RunMethod: func(repo repository.Repo, args []string) error { - return push(repo, args) - }, -} diff --git a/third_party/go/git-appraise/commands/rebase.go b/third_party/go/git-appraise/commands/rebase.go deleted file mode 100644 index 2c4595a57693..000000000000 --- a/third_party/go/git-appraise/commands/rebase.go +++ /dev/null @@ -1,100 +0,0 @@ -/* -Copyright 2016 Google Inc. All rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package commands - -import ( - "errors" - "flag" - "fmt" - - "github.com/google/git-appraise/repository" - "github.com/google/git-appraise/review" -) - -var rebaseFlagSet = flag.NewFlagSet("rebase", flag.ExitOnError) - -var ( - rebaseArchive = rebaseFlagSet.Bool("archive", true, "Prevent the original commit from being garbage collected.") - rebaseSign = rebaseFlagSet.Bool("S", false, - "Sign the contents of the request after the rebase") -) - -// Validate that the user's request to rebase a review makes sense. -// -// This checks both that the request is well formed, and that the -// corresponding review is in a state where rebasing is appropriate. -func validateRebaseRequest(repo repository.Repo, args []string) (*review.Review, error) { - var r *review.Review - var err error - if len(args) > 1 { - return nil, errors.New("Only rebasing a single review is supported.") - } - if len(args) == 1 { - r, err = review.Get(repo, args[0]) - } else { - r, err = review.GetCurrent(repo) - } - if err != nil { - return nil, fmt.Errorf("Failed to load the review: %v\n", err) - } - if r == nil { - return nil, errors.New("There is no matching review.") - } - - if r.Submitted { - return nil, errors.New("The review has already been submitted.") - } - - if r.Request.TargetRef == "" { - return nil, errors.New("The review was abandoned.") - } - - target := r.Request.TargetRef - if err := repo.VerifyGitRef(target); err != nil { - return nil, err - } - - return r, nil -} - -// Rebase the current code review. -// -// The "args" parameter contains all of the command line arguments that followed the subcommand. -func rebaseReview(repo repository.Repo, args []string) error { - rebaseFlagSet.Parse(args) - args = rebaseFlagSet.Args() - - r, err := validateRebaseRequest(repo, args) - if err != nil { - return err - } - if *rebaseSign { - return r.RebaseAndSign(*rebaseArchive) - } - return r.Rebase(*rebaseArchive) -} - -// rebaseCmd defines the "rebase" subcommand. -var rebaseCmd = &Command{ - Usage: func(arg0 string) { - fmt.Printf("Usage: %s rebase [<option>...] [<review-hash>]\n\nOptions:\n", arg0) - rebaseFlagSet.PrintDefaults() - }, - RunMethod: func(repo repository.Repo, args []string) error { - return rebaseReview(repo, args) - }, -} diff --git a/third_party/go/git-appraise/commands/reject.go b/third_party/go/git-appraise/commands/reject.go deleted file mode 100644 index e0e45babf8bc..000000000000 --- a/third_party/go/git-appraise/commands/reject.go +++ /dev/null @@ -1,119 +0,0 @@ -/* -Copyright 2015 Google Inc. All rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package commands - -import ( - "errors" - "flag" - "fmt" - - "github.com/google/git-appraise/commands/input" - "github.com/google/git-appraise/repository" - "github.com/google/git-appraise/review" - "github.com/google/git-appraise/review/comment" - "github.com/google/git-appraise/review/gpg" -) - -var rejectFlagSet = flag.NewFlagSet("reject", flag.ExitOnError) - -var ( - rejectMessageFile = rejectFlagSet.String("F", "", "Take the comment from the given file. Use - to read the message from the standard input") - rejectMessage = rejectFlagSet.String("m", "", "Message to attach to the review") - - rejectSign = rejectFlagSet.Bool("S", false, - "Sign the contents of the rejection") -) - -// rejectReview adds an NMW comment to the current code review. -func rejectReview(repo repository.Repo, args []string) error { - rejectFlagSet.Parse(args) - args = rejectFlagSet.Args() - - var r *review.Review - var err error - if len(args) > 1 { - return errors.New("Only rejecting a single review is supported.") - } - - if len(args) == 1 { - r, err = review.Get(repo, args[0]) - } else { - r, err = review.GetCurrent(repo) - } - - if err != nil { - return fmt.Errorf("Failed to load the review: %v\n", err) - } - if r == nil { - return errors.New("There is no matching review.") - } - - if r.Request.TargetRef == "" { - return errors.New("The review was abandoned.") - } - - if *rejectMessageFile != "" && *rejectMessage == "" { - *rejectMessage, err = input.FromFile(*rejectMessageFile) - if err != nil { - return err - } - } - if *rejectMessageFile == "" && *rejectMessage == "" { - *rejectMessage, err = input.LaunchEditor(repo, commentFilename) - if err != nil { - return err - } - } - - rejectedCommit, err := r.GetHeadCommit() - if err != nil { - return err - } - location := comment.Location{ - Commit: rejectedCommit, - } - resolved := false - userEmail, err := repo.GetUserEmail() - if err != nil { - return err - } - c := comment.New(userEmail, *rejectMessage) - c.Location = &location - c.Resolved = &resolved - if *rejectSign { - key, err := repo.GetUserSigningKey() - if err != nil { - return err - } - err = gpg.Sign(key, &c) - if err != nil { - return err - } - } - return r.AddComment(c) -} - -// rejectCmd defines the "reject" subcommand. -var rejectCmd = &Command{ - Usage: func(arg0 string) { - fmt.Printf("Usage: %s reject [<option>...] [<commit>]\n\nOptions:\n", arg0) - rejectFlagSet.PrintDefaults() - }, - RunMethod: func(repo repository.Repo, args []string) error { - return rejectReview(repo, args) - }, -} diff --git a/third_party/go/git-appraise/commands/request.go b/third_party/go/git-appraise/commands/request.go deleted file mode 100644 index 9a9854c3f8a6..000000000000 --- a/third_party/go/git-appraise/commands/request.go +++ /dev/null @@ -1,182 +0,0 @@ -/* -Copyright 2015 Google Inc. All rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package commands - -import ( - "errors" - "flag" - "fmt" - "strings" - - "github.com/google/git-appraise/commands/input" - "github.com/google/git-appraise/repository" - "github.com/google/git-appraise/review/gpg" - "github.com/google/git-appraise/review/request" -) - -// Template for the "request" subcommand's output. -const requestSummaryTemplate = `Review requested: -Commit: %s -Target Ref: %s -Review Ref: %s -Message: "%s" -` - -var requestFlagSet = flag.NewFlagSet("request", flag.ExitOnError) - -var ( - requestMessageFile = requestFlagSet.String("F", "", "Take the comment from the given file. Use - to read the message from the standard input") - requestMessage = requestFlagSet.String("m", "", "Message to attach to the review") - requestReviewers = requestFlagSet.String("r", "", "Comma-separated list of reviewers") - requestSource = requestFlagSet.String("source", "HEAD", "Revision to review") - requestTarget = requestFlagSet.String("target", "refs/heads/master", "Revision against which to review") - requestQuiet = requestFlagSet.Bool("quiet", false, "Suppress review summary output") - requestAllowUncommitted = requestFlagSet.Bool("allow-uncommitted", false, "Allow uncommitted local changes.") - requestSign = requestFlagSet.Bool("S", false, - "GPG sign the content of the request") -) - -// Build the template review request based solely on the parsed flag values. -func buildRequestFromFlags(requester string) (request.Request, error) { - var reviewers []string - if len(*requestReviewers) > 0 { - for _, reviewer := range strings.Split(*requestReviewers, ",") { - reviewers = append(reviewers, strings.TrimSpace(reviewer)) - } - } - if *requestMessageFile != "" && *requestMessage == "" { - var err error - *requestMessage, err = input.FromFile(*requestMessageFile) - if err != nil { - return request.Request{}, err - } - } - - return request.New(requester, reviewers, *requestSource, *requestTarget, *requestMessage), nil -} - -// Get the commit at which the review request should be anchored. -func getReviewCommit(repo repository.Repo, r request.Request, args []string) (string, string, error) { - if len(args) > 1 { - return "", "", errors.New("Only updating a single review is supported.") - } - if len(args) == 1 { - base, err := repo.MergeBase(r.TargetRef, args[0]) - if err != nil { - return "", "", err - } - return args[0], base, nil - } - - base, err := repo.MergeBase(r.TargetRef, r.ReviewRef) - if err != nil { - return "", "", err - } - reviewCommits, err := repo.ListCommitsBetween(base, r.ReviewRef) - if err != nil { - return "", "", err - } - if reviewCommits == nil { - return "", "", errors.New("There are no commits included in the review request") - } - return reviewCommits[0], base, nil -} - -// Create a new code review request. -// -// The "args" parameter is all of the command line arguments that followed the subcommand. -func requestReview(repo repository.Repo, args []string) error { - requestFlagSet.Parse(args) - args = requestFlagSet.Args() - - if !*requestAllowUncommitted { - // Requesting a code review with uncommited local changes is usually a mistake, so - // we want to report that to the user instead of creating the request. - hasUncommitted, err := repo.HasUncommittedChanges() - if err != nil { - return err - } - if hasUncommitted { - return errors.New("You have uncommitted or untracked files. Use --allow-uncommitted to ignore those.") - } - } - - userEmail, err := repo.GetUserEmail() - if err != nil { - return err - } - r, err := buildRequestFromFlags(userEmail) - if err != nil { - return err - } - if r.ReviewRef == "HEAD" { - headRef, err := repo.GetHeadRef() - if err != nil { - return err - } - r.ReviewRef = headRef - } - if err := repo.VerifyGitRef(r.TargetRef); err != nil { - return err - } - if err := repo.VerifyGitRef(r.ReviewRef); err != nil { - return err - } - - reviewCommit, baseCommit, err := getReviewCommit(repo, r, args) - if err != nil { - return err - } - r.BaseCommit = baseCommit - if r.Description == "" { - description, err := repo.GetCommitMessage(reviewCommit) - if err != nil { - return err - } - r.Description = description - } - if *requestSign { - key, err := repo.GetUserSigningKey() - if err != nil { - return err - } - err = gpg.Sign(key, &r) - if err != nil { - return err - } - } - note, err := r.Write() - if err != nil { - return err - } - repo.AppendNote(request.Ref, reviewCommit, note) - if !*requestQuiet { - fmt.Printf(requestSummaryTemplate, reviewCommit, r.TargetRef, r.ReviewRef, r.Description) - } - return nil -} - -// requestCmd defines the "request" subcommand. -var requestCmd = &Command{ - Usage: func(arg0 string) { - fmt.Printf("Usage: %s request [<option>...] [<review-hash>]\n\nOptions:\n", arg0) - requestFlagSet.PrintDefaults() - }, - RunMethod: func(repo repository.Repo, args []string) error { - return requestReview(repo, args) - }, -} diff --git a/third_party/go/git-appraise/commands/request_test.go b/third_party/go/git-appraise/commands/request_test.go deleted file mode 100644 index 3e09892e5760..000000000000 --- a/third_party/go/git-appraise/commands/request_test.go +++ /dev/null @@ -1,36 +0,0 @@ -/* -Copyright 2015 Google Inc. All rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package commands - -import ( - "testing" -) - -func TestBuildRequestFromFlags(t *testing.T) { - args := []string{"-m", "Request message", "-r", "Me, Myself, \nAnd I "} - requestFlagSet.Parse(args) - r, err := buildRequestFromFlags("user@hostname.com") - if err != nil { - t.Fatal(err) - } - if r.Description != "Request message" { - t.Fatalf("Unexpected request description: '%s'", r.Description) - } - if r.Reviewers == nil || len(r.Reviewers) != 3 || r.Reviewers[0] != "Me" || r.Reviewers[1] != "Myself" || r.Reviewers[2] != "And I" { - t.Fatalf("Unexpected reviewers list: '%v'", r.Reviewers) - } -} diff --git a/third_party/go/git-appraise/commands/show.go b/third_party/go/git-appraise/commands/show.go deleted file mode 100644 index 9eb57dd093c7..000000000000 --- a/third_party/go/git-appraise/commands/show.go +++ /dev/null @@ -1,85 +0,0 @@ -/* -Copyright 2015 Google Inc. All rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package commands - -import ( - "errors" - "flag" - "fmt" - "github.com/google/git-appraise/commands/output" - "github.com/google/git-appraise/repository" - "github.com/google/git-appraise/review" - "strings" -) - -var showFlagSet = flag.NewFlagSet("show", flag.ExitOnError) - -var ( - showJSONOutput = showFlagSet.Bool("json", false, "Format the output as JSON") - showDiffOutput = showFlagSet.Bool("diff", false, "Show the current diff for the review") - showDiffOptions = showFlagSet.String("diff-opts", "", "Options to pass to the diff tool; can only be used with the --diff option") -) - -// showReview prints the current code review. -func showReview(repo repository.Repo, args []string) error { - showFlagSet.Parse(args) - args = showFlagSet.Args() - if *showDiffOptions != "" && !*showDiffOutput { - return errors.New("The --diff-opts flag can only be used if the --diff flag is set.") - } - - var r *review.Review - var err error - if len(args) > 1 { - return errors.New("Only showing a single review is supported.") - } - - if len(args) == 1 { - r, err = review.Get(repo, args[0]) - } else { - r, err = review.GetCurrent(repo) - } - - if err != nil { - return fmt.Errorf("Failed to load the review: %v\n", err) - } - if r == nil { - return errors.New("There is no matching review.") - } - if *showJSONOutput { - return output.PrintJSON(r) - } - if *showDiffOutput { - var diffArgs []string - if *showDiffOptions != "" { - diffArgs = strings.Split(*showDiffOptions, ",") - } - return output.PrintDiff(r, diffArgs...) - } - return output.PrintDetails(r) -} - -// showCmd defines the "show" subcommand. -var showCmd = &Command{ - Usage: func(arg0 string) { - fmt.Printf("Usage: %s show [<option>...] [<commit>]\n\nOptions:\n", arg0) - showFlagSet.PrintDefaults() - }, - RunMethod: func(repo repository.Repo, args []string) error { - return showReview(repo, args) - }, -} diff --git a/third_party/go/git-appraise/commands/submit.go b/third_party/go/git-appraise/commands/submit.go deleted file mode 100644 index 58fa00235087..000000000000 --- a/third_party/go/git-appraise/commands/submit.go +++ /dev/null @@ -1,157 +0,0 @@ -/* -Copyright 2015 Google Inc. All rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package commands - -import ( - "errors" - "flag" - "fmt" - "github.com/google/git-appraise/repository" - "github.com/google/git-appraise/review" -) - -var submitFlagSet = flag.NewFlagSet("submit", flag.ExitOnError) - -var ( - submitMerge = submitFlagSet.Bool("merge", false, "Create a merge of the source and target refs.") - submitRebase = submitFlagSet.Bool("rebase", false, "Rebase the source ref onto the target ref.") - submitFastForward = submitFlagSet.Bool("fast-forward", false, "Create a merge using the default fast-forward mode.") - submitTBR = submitFlagSet.Bool("tbr", false, "(To be reviewed) Force the submission of a review that has not been accepted.") - submitArchive = submitFlagSet.Bool("archive", true, "Prevent the original commit from being garbage collected; only affects rebased submits.") - - submitSign = submitFlagSet.Bool("S", false, - "Sign the contents of the submission") -) - -// Submit the current code review request. -// -// The "args" parameter contains all of the command line arguments that followed the subcommand. -func submitReview(repo repository.Repo, args []string) error { - submitFlagSet.Parse(args) - args = submitFlagSet.Args() - - if *submitMerge && *submitRebase { - return errors.New("Only one of --merge or --rebase is allowed.") - } - - var r *review.Review - var err error - if len(args) > 1 { - return errors.New("Only accepting a single review is supported.") - } - if len(args) == 1 { - r, err = review.Get(repo, args[0]) - } else { - r, err = review.GetCurrent(repo) - } - - if err != nil { - return fmt.Errorf("Failed to load the review: %v\n", err) - } - if r == nil { - return errors.New("There is no matching review.") - } - - if r.Submitted { - return errors.New("The review has already been submitted.") - } - - if !*submitTBR && (r.Resolved == nil || !*r.Resolved) { - return errors.New("Not submitting as the review has not yet been accepted.") - } - - target := r.Request.TargetRef - if err := repo.VerifyGitRef(target); err != nil { - return err - } - source, err := r.GetHeadCommit() - if err != nil { - return err - } - - isAncestor, err := repo.IsAncestor(target, source) - if err != nil { - return err - } - if !isAncestor { - return errors.New("Refusing to submit a non-fast-forward review. First merge the target ref.") - } - - if !(*submitRebase || *submitMerge || *submitFastForward) { - submitStrategy, err := repo.GetSubmitStrategy() - if err != nil { - return err - } - if submitStrategy == "merge" && !*submitRebase && !*submitFastForward { - *submitMerge = true - } - if submitStrategy == "rebase" && !*submitMerge && !*submitFastForward { - *submitRebase = true - } - if submitStrategy == "fast-forward" && !*submitRebase && !*submitMerge { - *submitFastForward = true - } - } - - if *submitRebase { - var err error - if *submitSign { - err = r.RebaseAndSign(*submitArchive) - } else { - err = r.Rebase(*submitArchive) - } - if err != nil { - return err - } - - source, err = r.GetHeadCommit() - if err != nil { - return err - } - } - - if err := repo.SwitchToRef(target); err != nil { - return err - } - if *submitMerge { - submitMessage := fmt.Sprintf("Submitting review %.12s", r.Revision) - if *submitSign { - return repo.MergeAndSignRef(source, false, submitMessage, - r.Request.Description) - } else { - return repo.MergeRef(source, false, submitMessage, - r.Request.Description) - } - } else { - if *submitSign { - return repo.MergeAndSignRef(source, true) - } else { - return repo.MergeRef(source, true) - } - } -} - -// submitCmd defines the "submit" subcommand. -var submitCmd = &Command{ - Usage: func(arg0 string) { - fmt.Printf("Usage: %s submit [<option>...] [<review-hash>]\n\nOptions:\n", arg0) - submitFlagSet.PrintDefaults() - }, - RunMethod: func(repo repository.Repo, args []string) error { - return submitReview(repo, args) - }, -} |