-
-
Notifications
You must be signed in to change notification settings - Fork 200
Expand file tree
/
Copy pathcommands.go
More file actions
157 lines (142 loc) · 5.34 KB
/
commands.go
File metadata and controls
157 lines (142 loc) · 5.34 KB
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
150
151
152
153
154
155
156
157
package main
import (
"fmt"
"slices"
"strings"
"github.com/urfave/cli/v2"
)
var commands = []*cli.Command{
commandGet,
commandList,
commandRm,
commandRoot,
commandCreate,
commandMigrate,
}
var commandGet = &cli.Command{
Name: "get",
Aliases: []string{"clone"},
Usage: "Clone/sync with a remote repository",
Description: `
Clone a repository under ghq root directory. If the repository is
already cloned to local, nothing will happen unless '-u' ('--update')
flag is supplied, in which case 'git remote update' is executed.
When you use '-p' option, the repository is cloned via SSH.`,
Action: doGet,
Flags: []cli.Flag{
&cli.BoolFlag{Name: "update", Aliases: []string{"u"},
Usage: "Update local repository if cloned already"},
&cli.BoolFlag{Name: "p", Usage: "Clone with SSH"},
&cli.BoolFlag{Name: "shallow", Usage: "Do a shallow clone"},
&cli.BoolFlag{Name: "look", Aliases: []string{"l"}, Usage: "Look after get"},
&cli.StringFlag{Name: "vcs", Usage: "Specify `vcs` backend for cloning"},
&cli.BoolFlag{Name: "silent", Aliases: []string{"s"}, Usage: "clone or update silently"},
&cli.BoolFlag{Name: "no-recursive", Usage: "prevent recursive fetching"},
&cli.StringFlag{Name: "branch", Aliases: []string{"b"},
Usage: "Specify `branch` name. This flag implies --single-branch on Git"},
&cli.BoolFlag{Name: "parallel", Aliases: []string{"P"}, Usage: "Import parallelly"},
&cli.BoolFlag{Name: "bare", Usage: "Do a bare clone"},
&cli.StringFlag{
Name: "partial",
Usage: "Do a partial clone. Can specify either \"blobless\" or \"treeless\"",
Action: func(ctx *cli.Context, v string) error {
expected := []string{"blobless", "treeless"}
if !slices.Contains(expected, v) {
return fmt.Errorf("flag partial value \"%v\" is not allowed", v)
}
return nil
}},
},
}
var commandList = &cli.Command{
Name: "list",
Usage: "List local repositories",
Description: `
List locally cloned repositories. If a query argument is given, only
repositories whose names contain that query text are listed.
'-e' ('--exact') forces the match to be an exact one (i.e. the query equals to
project or user/project) If '-p' ('--full-path') is given, the full paths
to the repository root are printed instead of relative ones.`,
Action: doList,
Flags: []cli.Flag{
&cli.BoolFlag{Name: "exact", Aliases: []string{"e"}, Usage: "Perform an exact match"},
&cli.StringFlag{Name: "vcs", Usage: "Specify `vcs` backend for matching"},
&cli.BoolFlag{Name: "full-path", Aliases: []string{"p"}, Usage: "Print full paths"},
&cli.BoolFlag{Name: "unique", Usage: "Print unique subpaths"},
&cli.BoolFlag{Name: "bare", Usage: "Query bare repositories"},
},
}
var commandRm = &cli.Command{
Name: "rm",
Usage: "Remove local repository",
Action: doRm,
Flags: []cli.Flag{
&cli.BoolFlag{Name: "dry-run", Usage: "Do not remove actually"},
&cli.BoolFlag{Name: "bare", Usage: "Remove a bare repository"},
},
}
var commandRoot = &cli.Command{
Name: "root",
Usage: "Show repositories' root",
Action: doRoot,
Flags: []cli.Flag{
&cli.BoolFlag{Name: "all", Usage: "Show all roots"},
},
}
var commandCreate = &cli.Command{
Name: "create",
Usage: "Create a new repository",
Action: doCreate,
Flags: []cli.Flag{
&cli.StringFlag{Name: "vcs", Usage: "Specify `vcs` backend explicitly"},
&cli.BoolFlag{Name: "bare", Usage: "Create a bare repository"},
},
}
type commandDoc struct {
Parent string
Arguments string
}
var commandDocs = map[string]commandDoc{
"get": {"", "[-u] [-p] [--shallow] [--vcs <vcs>] [--look] [--silent] [--branch <branch>] [--no-recursive] [--bare] [--partial blobless|treeless] <repository URL>|<project>|<user>/<project>|<host>/<user>/<project>"},
"list": {"", "[-p] [-e] [<query>]"},
"create": {"", "<project>|<user>/<project>|<host>/<user>/<project>"},
"rm": {"", "<project>|<user>/<project>|<host>/<user>/<project>"},
"root": {"", "[-all]"},
"migrate": {"", "[-y] [--dry-run] <repository-directory>"},
}
// Makes template conditionals to generate per-command documents.
func mkCommandsTemplate(genTemplate func(commandDoc) string) string {
template := "{{if false}}"
for _, command := range commands {
template = template + fmt.Sprintf("{{else if (eq .Name %q)}}%s", command.Name, genTemplate(commandDocs[command.Name]))
}
return template + "{{end}}"
}
func init() {
argsTemplate := mkCommandsTemplate(func(doc commandDoc) string { return doc.Arguments })
parentTemplate := mkCommandsTemplate(func(doc commandDoc) string { return strings.TrimLeft(doc.Parent+" ", " ") })
cli.CommandHelpTemplate = `NAME:
{{.Name}} - {{.Usage}}
USAGE:
ghq ` + parentTemplate + `{{.Name}} ` + argsTemplate + `
{{if (len .Description)}}
DESCRIPTION: {{.Description}}
{{end}}{{if (len .Flags)}}
OPTIONS:
{{range .Flags}}{{.}}
{{end}}
{{end}}`
}
var commandMigrate = &cli.Command{
Name: "migrate",
Usage: "Migrate existing repository to ghq-managed directory",
Description: `
Migrate an existing repository directory to the ghq-managed directory structure.
The command detects the VCS backend, retrieves the remote URL, and moves
the repository to the appropriate location under ghq root.`,
Action: doMigrate,
Flags: []cli.Flag{
&cli.BoolFlag{Name: "y", Usage: "Skip confirmation prompt"},
&cli.BoolFlag{Name: "dry-run", Usage: "Show what would happen without moving"},
},
}