-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathbranch.go
149 lines (127 loc) · 3.6 KB
/
branch.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/*
Copyright © 2023 NAME HERE <EMAIL ADDRESS>
*/
package cmd
import (
"fmt"
"os"
"path/filepath"
"github.com/JunNishimura/Goit/internal/store"
"github.com/fatih/color"
"github.com/spf13/cobra"
)
var (
renameOption string = ""
deleteOption string = ""
)
func listBranch(client *store.Client) {
for _, branch := range client.Refs.Heads {
if branch.Name == client.Head.Reference {
color.Green("* %s", branch.Name)
} else {
fmt.Println(branch.Name)
}
}
}
func renameBranch(client *store.Client, newName string) error {
// check if new name is not used for other branches
for _, branch := range client.Refs.Heads {
if branch.Name == newName {
return fmt.Errorf("fatal: branch named '%s' already exists", newName)
}
}
// rename current branch
branch, err := client.Refs.GetBranch(client.Head.Reference)
if err != nil {
return err
}
branch.Name = newName
// rename file
oldPath := filepath.Join(client.RootGoitPath, "refs", "heads", client.Head.Reference)
newPath := filepath.Join(client.RootGoitPath, "refs", "heads", newName)
if err := os.Rename(oldPath, newPath); err != nil {
return fmt.Errorf("fail to rename: %w", err)
}
// rename HEAD
if err := client.Head.Update(client.RootGoitPath, newName); err != nil {
return err
}
return nil
}
func deleteBranch(client *store.Client, branchName string) error {
// branch validation
if branchName == client.Head.Reference {
return fmt.Errorf("error: cannot delete current branch '%s'", client.Head.Reference)
}
isBranchFound := false
for _, branch := range client.Refs.Heads {
if branch.Name == branchName {
isBranchFound = true
}
}
if !isBranchFound {
return fmt.Errorf("error: branch '%s' not found", branchName)
}
// delete branch
if err := client.Refs.DeleteBranch(client.RootGoitPath, branchName); err != nil {
return err
}
return nil
}
// branchCmd represents the branch command
var branchCmd = &cobra.Command{
Use: "branch",
Short: "handle with branch operation",
Long: "handle with branch operation",
PreRunE: func(cmd *cobra.Command, args []string) error {
if client.RootGoitPath == "" {
return ErrGoitNotInitialized
}
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
// get list flag
isList, err := cmd.Flags().GetBool("list")
if err != nil {
return fmt.Errorf("fail to get list flag: %w", err)
}
// parameter validation
if !((len(args) == 1 && !isList && renameOption == "" && deleteOption == "") ||
(len(args) == 0 && isList && renameOption == "" && deleteOption == "") ||
(len(args) == 0 && !isList && renameOption != "" && deleteOption == "") ||
(len(args) == 0 && !isList && renameOption == "" && deleteOption != "")) {
return fmt.Errorf("parameters are not valid")
}
// add branch
if len(args) == 1 {
// check if
addBranchName := args[0]
addBranchHash := client.Head.Commit.Hash
if err := client.Refs.AddBranch(addBranchName, addBranchHash); err != nil {
return fmt.Errorf("fail to add branch '%s': %w", addBranchName, err)
}
}
// list branches
if isList {
listBranch(client)
}
// rename current branch
if renameOption != "" {
if err := renameBranch(client, renameOption); err != nil {
return err
}
}
if deleteOption != "" {
if err := deleteBranch(client, deleteOption); err != nil {
return err
}
}
return nil
},
}
func init() {
rootCmd.AddCommand(branchCmd)
branchCmd.Flags().BoolP("list", "l", false, "show list of branches")
branchCmd.Flags().StringVarP(&renameOption, "rename", "r", "", "rename branch")
branchCmd.Flags().StringVarP(&deleteOption, "delete", "d", "", "delete branch")
}