Skip to content

Commit

Permalink
added/updated builder/ subpackage
Browse files Browse the repository at this point in the history
  • Loading branch information
hedzr committed Mar 23, 2024
1 parent a0c8fb2 commit 494cb5c
Show file tree
Hide file tree
Showing 5 changed files with 655 additions and 0 deletions.
186 changes: 186 additions & 0 deletions builder/app.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
package builder

import (
"errors"

"github.com/hedzr/cmdr/v2/cli"
"github.com/hedzr/cmdr/v2/conf"
)

type appS struct {
cli.Runner
root *cli.RootCommand
args []string
inCmd bool
inFlg bool
}

func (s *appS) Run(opts ...cli.Opt) (err error) {
if s.inCmd {
return errors.New("a NewCommandBuilder()/Cmd() call needs ending with Build()")
}
if s.inFlg {
return errors.New("a NewFlagBuilder()/Flg() call needs ending with Build()")
}

if s.root == nil || s.root.Command == nil {
return cli.ErrEmptyRootCommand
}

// any structural errors causes panic instead of returning via an error object here.
s.Build() // set rootCommand into worker

s.Runner.InitGlobally() // let worker starts initializations

if !s.Runner.Ready() {
return cli.ErrCommandsNotReady
}

err = s.Runner.Run(opts...)

// if err != nil {
// s.Runner.DumpErrors(os.Stderr)
// }

return
}

func (s *appS) Name() string { return s.root.AppName }
func (s *appS) Version() string { return s.root.Version }
func (s *appS) Worker() cli.Runner { return s.Runner }
func (s *appS) Root() *cli.RootCommand { return s.root }

func (s *appS) Build() {
if sr, ok := s.Runner.(setRoot); ok {
s.root.EnsureTree(s, s.root)
sr.SetRoot(s.root, s.args)
}
}

func (s *appS) ensureNewApp() cli.App { //nolint:unparam
if s.root == nil {
s.root = &cli.RootCommand{
AppName: conf.AppName,
Version: conf.Version,
// Copyright: "",
// Author: "",
// HeaderLine: "",
// FooterLine: "",
// Command: nil,
}
}
if s.root.Command == nil {
s.root.Command = new(cli.Command)
s.root.Command.SetName(s.root.AppName)
}
return s
}

// func (s *appS) Store() store.Store {
// return s.Runner.Store()
// }

func (s *appS) Info(name, version string, desc ...string) cli.App {
s.ensureNewApp()
if s.root.AppName == "" {
s.root.AppName = name
}
if s.root.Version == "" {
s.root.Version = version
}
s.root.SetDescription("", desc...)
return s
}

func (s *appS) Examples(examples ...string) cli.App {
s.ensureNewApp()
s.root.SetExamples(examples...)
return s
}

func (s *appS) Copyright(copyright string) cli.App {
s.ensureNewApp()
s.root.Copyright = copyright
return s
}

func (s *appS) Author(author string) cli.App {
s.ensureNewApp()
s.root.Author = author
return s
}

func (s *appS) Header(headerLine string) cli.App {
s.ensureNewApp()
s.root.HeaderLine = headerLine
return s
}

func (s *appS) Footer(footerLine string) cli.App {
s.ensureNewApp()
s.root.FooterLine = footerLine
return s
}

func (s *appS) WithRootCommand(root *cli.RootCommand) cli.App {
s.root = root
return s
}

func (s *appS) RootCommand() *cli.RootCommand { return s.root }

func (s *appS) NewCommandBuilder(longTitle string, titles ...string) cli.CommandBuilder {
return s.Cmd(longTitle, titles...)
}

func (s *appS) NewFlagBuilder(longTitle string, titles ...string) cli.FlagBuilder {
return s.Flg(longTitle, titles...)
}

func (s *appS) Cmd(longTitle string, titles ...string) cli.CommandBuilder {
s.inCmd = true
return newCommandBuilderShort(s, longTitle, titles...)
}

func (s *appS) Flg(longTitle string, titles ...string) cli.FlagBuilder {
s.inFlg = true
return newFlagBuilderShort(s, longTitle, titles...)
}

func (s *appS) NewCmdFrom(from *cli.Command, cb func(b cli.CommandBuilder)) cli.App {
b := newCommandBuilderFrom(from, s, "")
defer b.Build()
cb(b)
return s
}

func (s *appS) NewFlgFrom(from *cli.Command, defaultValue any, cb func(b cli.FlagBuilder)) cli.App {
b := newFlagBuilderFrom(from, s, defaultValue, "")
defer b.Build()
cb(b)
return s
}

func (s *appS) AddCmd(cb func(b cli.CommandBuilder)) cli.App {
b := newCommandBuilderShort(s, "")
defer b.Build()
cb(b)
return s
}

func (s *appS) AddFlg(cb func(b cli.FlagBuilder)) cli.App {
b := newFlagBuilderShort(s, "")
defer b.Build()
cb(b)
return s
}

func (s *appS) addCommand(child *cli.Command) {
s.inCmd = false
s.root.AddSubCommand(child)
}

func (s *appS) addFlag(child *cli.Flag) {
s.inFlg = false
s.root.AddFlag(child)
}
36 changes: 36 additions & 0 deletions builder/builder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright © 2022 Hedzr Yeh.

package builder

import (
"os"

"github.com/hedzr/cmdr/v2/cli"
"github.com/hedzr/cmdr/v2/conf"
)

func New(w cli.Runner) cli.App {
b := &appS{
Runner: w,
root: newDefaultRoot(),
args: os.Args,
}
return b
}

func newDefaultRoot() *cli.RootCommand {
root := new(cli.RootCommand)
root.Command = new(cli.Command)
root.AppName = conf.AppName
root.Version = conf.Version
return root
}

type setRoot interface {
SetRoot(root *cli.RootCommand, args []string)
}

type adder interface {
addCommand(child *cli.Command)
addFlag(child *cli.Flag)
}
10 changes: 10 additions & 0 deletions builder/builder_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package builder

import (
"testing"
)

func TestNew(t *testing.T) {
v := New(nil)
t.Logf("v = %v", v)
}
Loading

0 comments on commit 494cb5c

Please sign in to comment.