blob: 831f69f07c054c13d7b4ff96e92b1408b1b01691 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"fmt"
"os"
"path/filepath"
"strings"
"fuchsia.googlesource.com/jiri"
"fuchsia.googlesource.com/jiri/cmdline"
"fuchsia.googlesource.com/jiri/gitutil"
"fuchsia.googlesource.com/jiri/project"
)
var branchFlags struct {
deleteFlag bool
forceDeleteFlag bool
listFlag bool
}
var cmdBranch = &cmdline.Command{
Runner: jiri.RunnerFunc(runBranch),
Name: "branch",
Short: "Show or delete branches",
Long: `
Show all the projects having branch <branch> .If -d or -D is passed, <branch>
is deleted. if <branch> is not passed, show all projects which have branches other than "master"`,
ArgsName: "<branch>",
ArgsLong: "<branch> is the name branch",
}
func init() {
flags := &cmdBranch.Flags
flags.BoolVar(&branchFlags.deleteFlag, "d", false, "Delete branch from project. Similar to running 'git branch -d <branch-name>'")
flags.BoolVar(&branchFlags.forceDeleteFlag, "D", false, "Force delete branch from project. Similar to running 'git branch -D <branch-name>'")
flags.BoolVar(&branchFlags.listFlag, "list", false, "Show only projects with current branch <branch>")
}
func displayProjects(jirix *jiri.X, branch string) error {
localProjects, err := project.LocalProjects(jirix, project.FastScan)
if err != nil {
return err
}
jirix.TimerPush("Get states")
states, err := project.GetProjectStates(jirix, localProjects, false)
if err != nil {
return err
}
jirix.TimerPop()
cDir, err := os.Getwd()
if err != nil {
return err
}
for _, state := range states {
relativePath, err := filepath.Rel(cDir, state.Project.Path)
if err != nil {
return err
}
if branch == "" {
var branches []string
master := ""
for _, b := range state.Branches {
name := b.Name
if state.CurrentBranch.Name == b.Name {
name = "*" + jirix.Color.Green("%s", b.Name)
}
if b.Name != "master" {
branches = append(branches, name)
} else {
master = name
}
}
if len(branches) != 0 {
if master != "" {
branches = append(branches, master)
}
fmt.Printf("%s: %s(%s)\n", jirix.Color.Yellow("Project"), state.Project.Name, relativePath)
fmt.Printf("%s: %s\n\n", jirix.Color.Yellow("Branch(es)"), strings.Join(branches, ", "))
}
} else if branchFlags.listFlag {
if state.CurrentBranch.Name == branch {
fmt.Printf("%s(%s)\n", state.Project.Name, relativePath)
}
} else {
for _, b := range state.Branches {
if b.Name == branch {
fmt.Printf("%s(%s)\n", state.Project.Name, relativePath)
break
}
}
}
}
jirix.TimerPop()
return nil
}
func runBranch(jirix *jiri.X, args []string) error {
branch := ""
if len(args) > 1 {
return jirix.UsageErrorf("Please provide only one branch")
} else if len(args) == 1 {
branch = args[0]
}
if !branchFlags.deleteFlag && !branchFlags.forceDeleteFlag {
return displayProjects(jirix, branch)
}
if branch == "" {
return jirix.UsageErrorf("Please provide branch to delete")
}
return deleteBranches(jirix, branch)
}
func deleteBranches(jirix *jiri.X, branchToDelete string) error {
localProjects, err := project.LocalProjects(jirix, project.FastScan)
if err != nil {
return err
}
cDir, err := os.Getwd()
if err != nil {
return err
}
jirix.TimerPush("Get states")
states, err := project.GetProjectStates(jirix, localProjects, false)
if err != nil {
return err
}
jirix.TimerPop()
projectMap := make(project.Projects)
jirix.TimerPush("Build Map")
for key, state := range states {
for _, branch := range state.Branches {
if branch.Name == branchToDelete {
projectMap[key] = state.Project
break
}
}
}
jirix.TimerPop()
if len(projectMap) == 0 {
fmt.Printf("Cannot find any project with branch %q\n", branchToDelete)
return nil
}
jirix.TimerPush("Process")
errors := false
for _, localProject := range projectMap {
relativePath, err := filepath.Rel(cDir, localProject.Path)
if err != nil {
return err
}
fmt.Printf("Project %s(%s): ", localProject.Name, relativePath)
git := gitutil.New(jirix, gitutil.RootDirOpt(localProject.Path))
if err := git.DeleteBranch(branchToDelete, gitutil.ForceOpt(branchFlags.forceDeleteFlag)); err != nil {
errors = true
fmt.Printf(jirix.Color.Red("Error while deleting branch: %s\n", err))
} else {
fmt.Printf(jirix.Color.Green("Branch deleted\n"))
}
}
jirix.TimerPop()
if errors {
fmt.Println(jirix.Color.Yellow("Please check errors above"))
}
return nil
}