-
Notifications
You must be signed in to change notification settings - Fork 3
/
main.go
87 lines (73 loc) · 2.54 KB
/
main.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
package main
import (
"context"
"errors"
"fmt"
_ "embed"
"github.com/avamsi/climate"
"github.com/avamsi/climate/cmd/examples/jj/util"
)
// See ../greet/main.go first for some details that are not covered here.
// Struct is automatically converted to a command --
// 1. Struct names are converted to lowercase and used as the command name.
// 2. Struct fields are automatically declared as "global" flags.
// 3. Struct methods are automatically converted to subcommands --
// 1. Method names are converted to lowercase and used as the command name.
// 2. Method docs are truncated and are used* as short help strings.
// 3. Method directives are used* to declare aliases or explicitly set the
// short help strings (//cli:aliases, for example).
// 4. "Sub-structs" are automatically converted to subcommands, recursively.
// Jujutsu (an experimental VCS).
type jj struct {
Repository string `cli:"short=R"` // `path` to the repo to operate on
IgnoreWorkingCopy bool // don't snapshot / update the working copy
}
// Create a new repo in the given directory.
func (j *jj) Init(ctx context.Context, dir *string) {
fmt.Println("init", ctx, j, dir)
}
type squashOptions struct {
Revision string `cli:"short" default:"@"`
Interactive bool `cli:"short"` // interactively choose which parts to squash
}
// Move changes from a revision into its parent.
//
// After moving the changes into the parent, the child revision will have the
// same content state as before. If that means that the change is now empty
// compared to its parent, it will be abandoned. Without `--interactive`, the
// child change will always be empty.
//
//cli:aliases am, amend
func (j *jj) Squash(opts *squashOptions, paths [5]string) {
fmt.Println("squash", j, opts, paths)
}
// Commands for working with the underlying Git repo.
type git struct {
J *jj
}
// Manage Git remotes.
func (g *git) Remote() error {
return errors.New("not implemented")
}
// Update the underlying Git repo with changes made in the repo.
func (g *git) Export() {
fmt.Println("export", g.J)
}
//go:generate go run github.com/avamsi/climate/cmd/cligen --out=md.cli
//go:embed md.cli
var md []byte
func main() {
// Note the recursive struct embedding below, which lets us create "deep"
// subcommands like this (indentation implies subcommand) --
//
// jj
// init
// squash
// git
// remote
// export
// util
// completion
p := climate.Struct[jj](climate.Struct[git](), climate.Struct[util.Util]())
climate.RunAndExit(p, climate.WithMetadata(md))
}