aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app.go68
-rw-r--r--command.go34
-rw-r--r--example/example.go42
-rw-r--r--go.mod3
4 files changed, 147 insertions, 0 deletions
diff --git a/app.go b/app.go
new file mode 100644
index 0000000..4e0865d
--- /dev/null
+++ b/app.go
@@ -0,0 +1,68 @@
+package app
+
+/*
+This file is part of the App project.
+Copyright (C) 2021 Alexander Kiryukhin <a.kiryukhin@mail.ru>
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+@license GPL-3.0+ <http://spdx.org/licenses/GPL-3.0+>
+*/
+
+import (
+ "fmt"
+ "os"
+)
+
+type App struct {
+ commands []Command
+}
+
+var ErrNoCommand = fmt.Errorf("No command provided")
+
+// New returns new App.
+func New(commands []Command) *App {
+ return &App{commands: commands}
+}
+
+// Start cli application
+func (a *App) Start(args []string) error {
+ if len(args) < 2 {
+ return a.showHelpAndExit()
+ }
+
+ cmd := args[1]
+ for _, c := range a.commands {
+ if cmd == c.Name() {
+ fs := c.Flags()
+ if err := fs.Parse(args[2:]); err != nil {
+ fs.Usage()
+ return err
+ }
+ if err := c.Run(fs.Args()); err != nil {
+ return err
+ }
+ return nil
+ }
+ }
+
+ return a.showHelpAndExit()
+}
+
+func (a *App) showHelpAndExit() error {
+ fmt.Printf("Usage: %s [command]\nCommands:\n", os.Args[0])
+ for _, c := range a.commands {
+ fmt.Printf("\t%s - %s", c.Name(), c.Usage())
+ }
+ return ErrNoCommand
+}
diff --git a/command.go b/command.go
new file mode 100644
index 0000000..5bf15c8
--- /dev/null
+++ b/command.go
@@ -0,0 +1,34 @@
+package app
+
+/*
+This file is part of the App project.
+Copyright (C) 2021 Alexander Kiryukhin <a.kiryukhin@mail.ru>
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+@license GPL-3.0+ <http://spdx.org/licenses/GPL-3.0+>
+*/
+
+import "flag"
+
+// Command represents top level command of cli application
+type Command interface {
+ // Name returns name of command
+ Name() string
+ // Usage returns short help to command
+ Usage() string
+ // Flags returns FlagSet with flags for current command
+ Flags() *flag.FlagSet
+ // Run command
+ Run(args []string) error
+}
diff --git a/example/example.go b/example/example.go
new file mode 100644
index 0000000..096e2b2
--- /dev/null
+++ b/example/example.go
@@ -0,0 +1,42 @@
+package app_test
+
+import (
+ "flag"
+ "fmt"
+ "os"
+
+ "github.com/neonxp/app"
+)
+
+func ExampleApp() {
+ app := app.New(commands)
+ if err := app.Start(os.Args); err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+}
+
+var commands = []app.Command{}
+
+type exampleCommand struct {
+ test string
+}
+
+func (c *exampleCommand) Name() string {
+ return "example"
+}
+
+func (c *exampleCommand) Usage() string {
+ return "just example command"
+}
+
+func (c *exampleCommand) Flags() *flag.FlagSet {
+ fs := flag.NewFlagSet(c.Name(), flag.ExitOnError)
+ fs.StringVar(&c.test, "test", "value", "test flag")
+ return fs
+}
+
+func (c *exampleCommand) Run(args []string) error {
+ fmt.Printf("Runned %s command with flag -test=%s and args: %v", c.Name(), c.test, args)
+ return nil
+}
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..7079b7e
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,3 @@
+module github.com/neonxp/app
+
+go 1.16