zk/main.go

133 lines
3.3 KiB
Go
Raw Normal View History

2020-12-24 15:02:19 +00:00
package main
import (
2021-01-24 11:10:13 +00:00
"fmt"
"os"
"os/exec"
2021-03-17 17:04:27 +00:00
"strings"
2021-01-24 11:10:13 +00:00
2020-12-24 15:02:19 +00:00
"github.com/alecthomas/kong"
"github.com/mickael-menu/zk/cmd"
"github.com/mickael-menu/zk/core/style"
2021-01-24 11:10:13 +00:00
executil "github.com/mickael-menu/zk/util/exec"
2020-12-24 15:02:19 +00:00
)
2021-01-02 11:08:58 +00:00
var Version = "dev"
var Build = "dev"
2020-12-24 15:02:19 +00:00
var cli struct {
Init cmd.Init `cmd group:"zk" help:"Create a new notebook in the given directory."`
Index cmd.Index `cmd group:"zk" help:"Index the notes to be searchable."`
New cmd.New `cmd group:"notes" help:"Create a new note in the given notebook directory."`
List cmd.List `cmd group:"notes" help:"List notes matching the given criteria."`
Edit cmd.Edit `cmd group:"notes" help:"Edit notes matching the given criteria."`
NoInput NoInput `help:"Never prompt or ask for confirmation."`
2021-02-07 18:03:27 +00:00
ShowHelp ShowHelp `cmd default:"1" hidden:true`
Version kong.VersionFlag `help:"Print zk version." hidden:true`
2020-12-24 15:02:19 +00:00
}
2021-01-24 11:10:13 +00:00
// NoInput is a flag preventing any user prompt when enabled.
type NoInput bool
func (f NoInput) BeforeApply(container *cmd.Container) error {
container.Terminal.NoInput = true
return nil
}
2021-02-07 18:03:27 +00:00
// ShowHelp is the default command run. It's equivalent to `zk --help`.
type ShowHelp struct{}
func (cmd *ShowHelp) Run(container *cmd.Container) error {
parser, err := kong.New(&cli, options(container)...)
if err != nil {
return err
}
ctx, err := parser.Parse([]string{"--help"})
if err != nil {
return err
}
return ctx.Run(container)
}
2020-12-24 15:02:19 +00:00
func main() {
2020-12-28 12:15:56 +00:00
// Create the dependency graph.
2021-03-17 17:04:27 +00:00
container, err := cmd.NewContainer()
fatalIfError(err)
2020-12-27 17:58:22 +00:00
2021-01-24 11:10:13 +00:00
if isAlias, err := runAlias(container, os.Args[1:]); isAlias {
fatalIfError(err)
} else {
2021-02-07 18:03:27 +00:00
ctx := kong.Parse(&cli, options(container)...)
2021-01-24 11:10:13 +00:00
err := ctx.Run(container)
ctx.FatalIfErrorf(err)
}
2020-12-24 15:02:19 +00:00
}
2021-01-23 20:15:17 +00:00
2021-02-07 18:03:27 +00:00
func options(container *cmd.Container) []kong.Option {
term := container.Terminal
2021-02-07 18:03:27 +00:00
return []kong.Option{
kong.Bind(container),
kong.Name("zk"),
kong.UsageOnError(),
kong.HelpOptions{
Compact: true,
FlagsLast: true,
},
2021-02-07 18:03:27 +00:00
kong.Vars{
2021-03-18 18:39:06 +00:00
"version": "zk " + strings.TrimPrefix(Version, "v"),
2021-02-07 18:03:27 +00:00
},
kong.Groups(map[string]string{
"filter": "Filtering",
"sort": "Sorting",
"format": "Formatting",
"notes": term.MustStyle("NOTES", style.RuleYellow, style.RuleBold) + "\n" + term.MustStyle("Edit or browse your notes", style.RuleBold),
"zk": term.MustStyle("NOTEBOOK", style.RuleYellow, style.RuleBold) + "\n" + term.MustStyle("A notebook is a directory containing a collection of notes", style.RuleBold),
}),
2021-02-07 18:03:27 +00:00
}
}
2021-01-24 11:10:13 +00:00
func fatalIfError(err error) {
if err != nil {
fmt.Fprintf(os.Stderr, "zk: error: %v\n", err)
os.Exit(1)
}
}
2021-01-23 20:15:17 +00:00
2021-01-24 11:10:13 +00:00
// runAlias will execute a user alias if the command is one of them.
func runAlias(container *cmd.Container, args []string) (bool, error) {
2021-03-17 17:04:27 +00:00
if len(args) < 1 {
return false, nil
}
2021-02-13 20:07:06 +00:00
runningAlias := os.Getenv("ZK_RUNNING_ALIAS")
2021-03-17 17:04:27 +00:00
for alias, cmdStr := range container.Config.Aliases {
if alias == runningAlias || alias != args[0] {
continue
}
2021-01-24 11:10:13 +00:00
2021-03-17 17:04:27 +00:00
// Prevent infinite loop if an alias calls itself.
os.Setenv("ZK_RUNNING_ALIAS", alias)
cmd := executil.CommandFromString(cmdStr, args[1:]...)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err := cmd.Run()
if err != nil {
if err, ok := err.(*exec.ExitError); ok {
os.Exit(err.ExitCode())
return true, nil
} else {
return true, err
2021-01-24 11:10:13 +00:00
}
}
2021-03-17 17:04:27 +00:00
return true, nil
2021-01-24 11:10:13 +00:00
}
return false, nil
2021-01-23 20:15:17 +00:00
}