// Clone creates a local copy of the repository accessible at
// github.com/user/repo with token, in a system temp directory.
func clone(c context.Context, repoOwner, repoName, userName, token string) (repository.Repo, error) {
	dir, err := ioutil.TempDir("", fmt.Sprintf("%s-%s", userName, repoName))
	if err != nil {
		return nil, err
	}
	cloneCmd := exec.Command("git", "clone", makeRemoteURL(userName, token, repoOwner, repoName), dir)
	if _, err := cloneCmd.CombinedOutput(); err != nil {
		return nil, err
	}
	repo, err := repository.NewGitRepo(dir)
	if err != nil {
		return nil, err
	}
	if err := repo.PullNotes(remoteName, notesRefPattern); err != nil {
		return nil, err
	}
	fetchCmd := exec.Command("git", "fetch", "origin", fetchSpec)
	fetchCmd.Dir = dir
	if _, err := fetchCmd.CombinedOutput(); err != nil {
		return nil, err
	}
	configUserCmd := exec.Command("git", "config", "--local", "--add", "user.name", "Github Mirror")
	configUserCmd.Dir = dir
	if _, err := configUserCmd.CombinedOutput(); err != nil {
		return nil, err
	}
	userEmail := appengine.AppID(c) + "@appspot.gserviceaccount.com"
	configEmailCmd := exec.Command("git", "config", "--local", "--add", "user.email", userEmail)
	configEmailCmd.Dir = dir
	if _, err := configEmailCmd.CombinedOutput(); err != nil {
		return nil, err
	}
	return repo, nil
}
Example #2
0
func main() {
	if len(os.Args) > 1 && os.Args[1] == "help" {
		help()
		return
	}
	cwd, err := os.Getwd()
	if err != nil {
		fmt.Printf("Unable to get the current working directory: %q\n", err)
		return
	}
	repo, err := repository.NewGitRepo(cwd)
	if err != nil {
		fmt.Printf("%s must be run from within a git repo.\n", os.Args[0])
		return
	}
	if len(os.Args) < 2 {
		subcommand, ok := commands.CommandMap["list"]
		if !ok {
			fmt.Printf("Unable to list reviews")
			return
		}
		subcommand.Run(repo, []string{})
		return
	}
	subcommand, ok := commands.CommandMap[os.Args[1]]
	if !ok {
		fmt.Printf("Unknown command: %q\n", os.Args[1])
		usage()
		return
	}
	if err := subcommand.Run(repo, os.Args[2:]); err != nil {
		fmt.Println(err.Error())
		os.Exit(1)
	}
}
func findRepos(searchDir string) ([]repository.Repo, error) {
	// This method finds repos by recursively traversing the given directory,
	// and looking for any git repos.
	var repos []repository.Repo
	filepath.Walk(searchDir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if info.IsDir() {
			gitRepo, err := repository.NewGitRepo(path)
			if err == nil {
				repos = append(repos, gitRepo)
				// Since we have found a git repo, we don't need to
				// traverse any of its child directories.
				return filepath.SkipDir
			}
		}
		return nil
	})
	return repos, nil
}
Example #4
0
func main() {
	flag.Parse()
	splitTarget := strings.Split(*remoteRepository, "/")
	if len(splitTarget) != 2 {
		usage("Target repository is required, in the format `user/repo'")
	}
	userName := splitTarget[0]
	repoName := splitTarget[1]

	localDirInfo, err := os.Stat(*localRepositoryDir)
	if err != nil {
		log.Fatal(err)
	}
	if !localDirInfo.IsDir() {
		usage("Local repository must be a directory")
	}

	local, err := repository.NewGitRepo(*localRepositoryDir)
	if err != nil {
		log.Fatal("Couldn't open local repository: ", err.Error(), "\n",
			"Make sure you clone the remote repository locally first!")
	}

	tokenAuth := *token != ""
	if !tokenAuth {
		fmt.Fprintln(os.Stderr, "Not using authentication. Note that this will be EXTREMELY SLOW;")
		fmt.Fprintln(os.Stderr, "you get 60 requests to the github API per hour.")
		fmt.Fprint(os.Stderr, auth.TokenHelp)
	}

	var client *github.Client
	if tokenAuth {
		client = auth.TokenClient(*token)
	} else {
		client = auth.UnauthenticatedClient()
	}

	_, _, err = client.Repositories.Get(userName, repoName)
	if err != nil {
		log.Fatal("Error fetching repository info: ", err.Error())
	}

	errOutput := make(chan error, 1000)
	nErrors := 0
	go func() {
		for err := range errOutput {
			if !*quiet {
				log.Println(err)
			}
			nErrors++
		}
	}()
	statuses, err := mirror.GetAllStatuses(userName, repoName, client, errOutput)
	if err != nil {
		log.Fatal("Error reading statuses: ", err.Error())
	}
	reviews, err := mirror.GetAllPullRequests(local, userName, repoName, client, errOutput)
	if err != nil {
		log.Fatal("Error reading pull requests: ", err.Error())
	}
	close(errOutput)

	nStatuses := len(statuses)
	nReviews := len(reviews)
	var l *log.Logger
	if *quiet {
		l = log.New(ioutil.Discard, "", 0)
	} else {
		l = log.New(os.Stdout, "", 0)
	}
	logChan := make(chan string, 1000)
	go func() {
		for msg := range logChan {
			l.Println(msg)
		}
	}()

	l.Printf("Done reading! Read %d statuses, %d PRs", nStatuses, nReviews)
	l.Printf("Committing...\n")
	if err := mirror.WriteNewReports(statuses, local, logChan); err != nil {
		log.Fatal(err)
	}
	if err := mirror.WriteNewReviews(reviews, local, logChan); err != nil {
		log.Fatal(err)
	}
	close(logChan)

	l.Printf("Done! Hit %d errors", nErrors)
	if nErrors > 0 {
		os.Exit(1)
	}
}