github.com/slspeek/camlistore_namedsearch@v0.0.0-20140519202248-ed6f70f7721a/dev/devcam/review.go (about)

     1  /*
     2  Copyright 2014 The Camlistore Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8       http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  // This file adds the "review" subcommand to devcam, to send changes for peer review.
    18  
    19  package main
    20  
    21  import (
    22  	"bufio"
    23  	"flag"
    24  	"fmt"
    25  	"io/ioutil"
    26  	"log"
    27  	"os"
    28  	"os/exec"
    29  	"path/filepath"
    30  
    31  	"camlistore.org/pkg/cmdmain"
    32  )
    33  
    34  var (
    35  	defaultHook = filepath.FromSlash("misc/commit-msg.githook")
    36  	hookFile    = filepath.FromSlash(".git/hooks/commit-msg")
    37  )
    38  
    39  type reviewCmd struct{}
    40  
    41  func init() {
    42  	cmdmain.RegisterCommand("review", func(flags *flag.FlagSet) cmdmain.CommandRunner {
    43  		return new(reviewCmd)
    44  	})
    45  }
    46  
    47  func (c *reviewCmd) Usage() {
    48  	fmt.Fprintf(cmdmain.Stderr, "Usage: devcam review\n")
    49  }
    50  
    51  func (c *reviewCmd) Describe() string {
    52  	return "Submit your git commits for review."
    53  }
    54  
    55  func (c *reviewCmd) RunCommand(args []string) error {
    56  	if len(args) > 0 {
    57  		return cmdmain.UsageError("too many arguments.")
    58  	}
    59  	goToCamliRoot()
    60  	c.checkHook()
    61  	gitPush()
    62  	return nil
    63  }
    64  
    65  func goToCamliRoot() {
    66  	prevDir, err := os.Getwd()
    67  	if err != nil {
    68  		log.Fatalf("could not get current directory: %v", err)
    69  	}
    70  	for {
    71  		if _, err := os.Stat(defaultHook); err == nil {
    72  			return
    73  		}
    74  		if err := os.Chdir(".."); err != nil {
    75  			log.Fatalf("Could not chdir: %v", err)
    76  		}
    77  		currentDir, err := os.Getwd()
    78  		if err != nil {
    79  			log.Fatalf("Could not get current directory: %v", err)
    80  		}
    81  		if currentDir == prevDir {
    82  			log.Fatal("Camlistore tree root not found. Run from within the Camlistore tree please.")
    83  		}
    84  		prevDir = currentDir
    85  	}
    86  }
    87  
    88  func (c *reviewCmd) checkHook() {
    89  	_, err := os.Stat(hookFile)
    90  	if err == nil {
    91  		return
    92  	}
    93  	if !os.IsNotExist(err) {
    94  		log.Fatal(err)
    95  	}
    96  	fmt.Fprintf(cmdmain.Stdout, "Presubmit hook to add Change-Id to commit messages is missing.\nNow automatically creating it at %v from %v\n\n", hookFile, defaultHook)
    97  	data, err := ioutil.ReadFile(defaultHook)
    98  	if err != nil {
    99  		log.Fatal(err)
   100  	}
   101  	if err := ioutil.WriteFile(hookFile, data, 0700); err != nil {
   102  		log.Fatal(err)
   103  	}
   104  	fmt.Fprintf(cmdmain.Stdout, "Amending last commit to add Change-Id.\nPlease re-save description without making changes.\n\n")
   105  	fmt.Fprintf(cmdmain.Stdout, "Press Enter to continue.\n")
   106  	if _, _, err := bufio.NewReader(cmdmain.Stdin).ReadLine(); err != nil {
   107  		log.Fatal(err)
   108  	}
   109  
   110  	cmd := exec.Command("git", []string{"commit", "--amend"}...)
   111  	cmd.Stdout = cmdmain.Stdout
   112  	cmd.Stderr = cmdmain.Stderr
   113  	if err := cmd.Run(); err != nil {
   114  		log.Fatal(err)
   115  	}
   116  }
   117  
   118  func gitPush() {
   119  	cmd := exec.Command("git",
   120  		[]string{"push", "https://camlistore.googlesource.com/camlistore", "HEAD:refs/for/master"}...)
   121  	cmd.Stdout = cmdmain.Stdout
   122  	cmd.Stderr = cmdmain.Stderr
   123  	if err := cmd.Run(); err != nil {
   124  		log.Fatalf("Could not git push: %v", err)
   125  	}
   126  }