Skip to content

Commit

Permalink
More usage cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
kenshaw committed Mar 31, 2024
1 parent 3a9334d commit 44c8877
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 76 deletions.
25 changes: 0 additions & 25 deletions handler/errors.go

This file was deleted.

50 changes: 50 additions & 0 deletions handler/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -1416,6 +1416,32 @@ func (h *Handler) SetOutput(o io.WriteCloser) {
h.out = o
}

// Error wraps handler errors.
type Error struct {
Buf string
Err error
}

// WrapErr wraps an [error] using the specified driver when err is not nil.
func WrapErr(buf string, err error) error {
if err == nil {
return nil
}
// avoid double wrapping error
if _, ok := err.(*Error); ok {
return err
}
return &Error{buf, err}
}

// Error satisfies the [error] interface, returning the original error message.
func (e *Error) Error() string {
return e.Err.Error()
}

// Unwrap returns the original error.
func (e *Error) Unwrap() error { return e.Err }

func readerOpts() []metadata.ReaderOption {
var opts []metadata.ReaderOption
envs := env.All()
Expand Down Expand Up @@ -1472,3 +1498,27 @@ func grab(r []rune, i, end int) rune {
}
return 0
}

// linetermRE is the end of line terminal.
var linetermRE = regexp.MustCompile(`(?:\r?\n)+$`)

// empty reports whether s contains at least one printable, non-space character.
func empty(s string) bool {
i := strings.IndexFunc(s, func(r rune) bool {
return unicode.IsPrint(r) && !unicode.IsSpace(r)
})
return i == -1
}

var ansiRE = regexp.MustCompile(`\x1b[[0-9]+([:;][0-9]+)*m`)

// lastcolor returns the last defined color in s, if any.
func lastcolor(s string) string {
if i := strings.LastIndex(s, "\n"); i != -1 {
s = s[:i]
}
if i := strings.LastIndex(s, "\x1b[0m"); i != -1 {
s = s[i+4:]
}
return strings.Join(ansiRE.FindAllString(s, -1), "")
}
31 changes: 0 additions & 31 deletions handler/util.go

This file was deleted.

13 changes: 12 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ func main() {
return
}
// run
if err := Run(context.Background(), os.Args); err != nil && err != io.EOF && err != rline.ErrInterrupt {
c := NewCommand(os.Args)
if err := c.ExecuteContext(context.Background()); err != nil && err != io.EOF && err != rline.ErrInterrupt {
var he *handler.Error
if !errors.As(err, &he) {
fmt.Fprintf(os.Stderr, "error: %v\n", err)
Expand All @@ -58,6 +59,16 @@ func main() {
}
fmt.Fprintf(os.Stderr, "\ntry:\n\n go install -tags %s github.com/xo/usql@%s\n\n", tag, rev)
}
/*
switch estr := err.Error(); {
case err == text.ErrWrongNumberOfArguments,
strings.HasPrefix(estr, "unknown flag:"),
strings.HasPrefix(estr, "unknown shorthand flag:"),
strings.HasPrefix(estr, "bad flag syntax:"),
strings.HasPrefix(estr, "flag needs an argument:"):
metacmd.Usage(os.Stderr, false)
}
*/
os.Exit(1)
}
}
4 changes: 2 additions & 2 deletions metacmd/cmds.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func init() {
}
switch name = strings.TrimSpace(strings.ToLower(name)); {
case name == "options":
Usage(stdout)
Usage(stdout, true)
case name == "variables":
env.Listing(stdout)
default:
Expand Down Expand Up @@ -981,5 +981,5 @@ func init() {
}

// Usage is used by the [Question] command to display command line options
var Usage = func(io.Writer) {
var Usage = func(io.Writer, bool) {
}
43 changes: 26 additions & 17 deletions run.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,25 @@ import (
"github.com/xo/usql/text"
)

// Run processes args, processing args.CommandOrFiles if non-empty, if
// specified, otherwise launch an interactive readline from stdin.
func Run(ctx context.Context, cliargs []string) error {
// ContextExecutor is the command context.
type ContextExecutor interface {
ExecuteContext(context.Context) error
}

// NewCommand builds the command context.
func NewCommand(cliargs []string) ContextExecutor {
args := &Args{}
v := viper.New()
c := &cobra.Command{
Use: text.CommandName + " [flags]... [DSN]",
Short: text.Short(),
Version: text.CommandVersion,
Args: cobra.RangeArgs(0, 1),
Args: func(_ *cobra.Command, cliargs []string) error {
if len(cliargs) > 1 {
return text.ErrWrongNumberOfArguments
}
return nil
},
PersistentPreRunE: func(cmd *cobra.Command, _ []string) error {
commandUpper := text.CommandUpper()
configFile := strings.TrimSpace(os.Getenv(commandUpper + "_CONFIG"))
Expand Down Expand Up @@ -68,13 +77,13 @@ func Run(ctx context.Context, cliargs []string) error {
if len(cliargs) > 0 {
args.DSN = cliargs[0]
}
return run(cmd.Context(), args)
return Run(cmd.Context(), args)
},
}

c.SetVersionTemplate("{{ .Name }} {{ .Version }}\n")
c.SetArgs(cliargs[1:])
c.SilenceErrors = true
c.SilenceUsage, c.SilenceErrors = true, true
c.SetUsageTemplate(text.UsageTemplate)

flags := c.Flags()
Expand Down Expand Up @@ -128,19 +137,24 @@ func Run(ctx context.Context, cliargs []string) error {
flags.Bool("help", false, "show this help, then exit")
_ = c.Flags().SetAnnotation("help", cobra.FlagSetByCobraAnnotation, []string{"true"})
// expose to metacmd
metacmd.Usage = func(w io.Writer) {
_, _ = w.Write([]byte(text.Short() + "\n\n" + c.UsageString()))
metacmd.Usage = func(w io.Writer, banner bool) {
s := "\n\n" + c.UsageString()
if banner {
s = text.Short() + s
}
_, _ = w.Write([]byte(s))
}
// mark hidden
for _, s := range []string{"no-psqlrc", "no-usqlrc", "var", "variable"} {
if err := flags.MarkHidden(s); err != nil {
return err
panic(err)
}
}
return c.ExecuteContext(ctx)
return c
}

func run(ctx context.Context, args *Args) error {
// Run runs the application.
func Run(ctx context.Context, args *Args) error {
// get user
u, err := user.Current()
if err != nil {
Expand Down Expand Up @@ -329,17 +343,12 @@ func (vs) String() string {

// Type satisfies the [pflag.Value] interface.
func (p vs) Type() string {
if p.isBool() {
if p.typ == "" {
return "bool"
}
return p.typ
}

// isBool satisfies the pflag.boolFlag interface.
func (p vs) isBool() bool {
return len(p.vals) != 0 && !strings.Contains(p.vals[0], "%")
}

// filevar is a file var.
type filevar struct {
v *string
Expand Down

0 comments on commit 44c8877

Please sign in to comment.