From 8a08f429d260ab4b15825c7906bb94ca4fcb9ba8 Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Mon, 12 Nov 2018 23:38:37 +0100 Subject: [PATCH] update cli UI/UX with elapsed time on success | add run command (issue with indentation) --- internal/buildfile/reader.go | 13 ++++++++----- internal/instruction/common.go | 22 ++++++++++++--------- internal/instruction/delete.go | 2 +- internal/instruction/install.go | 2 +- internal/instruction/reader.go | 4 ++++ internal/instruction/run.go | 34 +++++++++++++++++++++++++++++++++ internal/instruction/service.go | 2 +- internal/instruction/set.go | 2 +- main.go | 11 +++++++---- 9 files changed, 70 insertions(+), 22 deletions(-) create mode 100644 internal/instruction/run.go diff --git a/internal/buildfile/reader.go b/internal/buildfile/reader.go index 7a9f486..7ec2a60 100644 --- a/internal/buildfile/reader.go +++ b/internal/buildfile/reader.go @@ -8,6 +8,7 @@ import ( "git.xdrm.io/go/nix-amer/internal/instruction" "io" "strings" + "time" ) // ErrNullContext is raised when the given context is nil @@ -84,19 +85,21 @@ func (r *Reader) Execute() error { // 3. exec each instruction for i, inst := range r.Content { - clifmt.Align(fmt.Sprintf("(%d) %s", i, clifmt.Color(34, inst.Raw()))) - fmt.Printf("%s", clifmt.Color(33, "running")) + clifmt.Align(fmt.Sprintf("(%d) %s", i, clifmt.Color(0, inst.Raw()))) + fmt.Printf("%s", clifmt.Color(33, "processing")) + + start := time.Now() _, err := inst.Exec(*r.Context) if err != nil { fmt.Printf("\r") - clifmt.Align(fmt.Sprintf("(%d) %s", i, clifmt.Color(34, inst.Raw()))) - fmt.Printf("%s \n", clifmt.Color(31, err.Error())) + clifmt.Align(fmt.Sprintf("(%d) %s", i, clifmt.Color(0, inst.Raw()))) + fmt.Printf("%s \n", clifmt.Color(31, err.Error())) continue } else { fmt.Printf("\r") clifmt.Align(fmt.Sprintf("(%d) %s", i, clifmt.Color(34, inst.Raw()))) - fmt.Printf("%s \n", clifmt.Color(32, "done")) + fmt.Printf("%ss \n", clifmt.Color(32, fmt.Sprintf("%.2f", time.Now().Sub(start).Seconds()))) } } diff --git a/internal/instruction/common.go b/internal/instruction/common.go index 7106edd..efb63b1 100644 --- a/internal/instruction/common.go +++ b/internal/instruction/common.go @@ -17,21 +17,18 @@ type T interface { Exec(ExecutionContext) ([]byte, error) } -// Executor is the common interface to execute commands -type Executor interface { - Execute(...string) error -} - // ExecutionContext contains system-specific drivers to manage the host type ExecutionContext struct { - ExecContext Executor PackageManager pkg.PackageManager ServiceManager ser.ServiceManager + Executor exec.Executor + Alias map[string]string } // CreateContext creates an execution contet with the given package-manager and service-manager // default values are taken from each go package (pkg, ser) -func CreateContext(_pkg, _ser string) (*ExecutionContext, error) { +// if _exec is set, it will override the default (os) executor +func CreateContext(_pkg, _ser string, _exec ...exec.Executor) (*ExecutionContext, error) { // 1. fail if no value and no defaults if len(_pkg)+len(pkg.DefaultManager) < 1 { @@ -49,9 +46,14 @@ func CreateContext(_pkg, _ser string) (*ExecutionContext, error) { _ser = ser.DefaultManager } - executor := new(exec.Default) + var executor exec.Executor = new(exec.Default) - // 3. load managers + // 3. load custom executor (optional) + if len(_exec) > 0 && _exec[0] != nil { + executor = _exec[0] + } + + // 4. load managers pkg, err := pkg.Load(_pkg, executor) if err != nil { return nil, fmt.Errorf("package manager: %s", err) @@ -65,6 +67,8 @@ func CreateContext(_pkg, _ser string) (*ExecutionContext, error) { return &ExecutionContext{ PackageManager: pkg, ServiceManager: ser, + Executor: executor, + Alias: make(map[string]string), }, nil } diff --git a/internal/instruction/delete.go b/internal/instruction/delete.go index 646d578..fe4dfdf 100644 --- a/internal/instruction/delete.go +++ b/internal/instruction/delete.go @@ -10,7 +10,7 @@ type delete struct { Packages []string } -func (d *delete) Raw() string { return d.raw } +func (d *delete) Raw() string { return strings.Join([]string{"delete", d.raw}, " ") } func (d *delete) Build(_args string) error { d.Packages = strings.Split(_args, " ") diff --git a/internal/instruction/install.go b/internal/instruction/install.go index 368a71e..958e54a 100644 --- a/internal/instruction/install.go +++ b/internal/instruction/install.go @@ -10,7 +10,7 @@ type install struct { Packages []string } -func (d *install) Raw() string { return d.raw } +func (d *install) Raw() string { return strings.Join([]string{"install", d.raw}, " ") } func (d *install) Build(_args string) error { d.Packages = strings.Split(_args, " ") diff --git a/internal/instruction/reader.go b/internal/instruction/reader.go index e7ca520..958ca1a 100644 --- a/internal/instruction/reader.go +++ b/internal/instruction/reader.go @@ -32,6 +32,10 @@ func Parse(raw string) (T, error) { i := &service{} err := i.Build(split[1]) return i, err + case "run": + i := &run{} + err := i.Build(split[1]) + return i, err case "set": i := &set{} err := i.Build(split[1]) diff --git a/internal/instruction/run.go b/internal/instruction/run.go new file mode 100644 index 0000000..c19df98 --- /dev/null +++ b/internal/instruction/run.go @@ -0,0 +1,34 @@ +package instruction + +import ( + "fmt" + "os" + "strings" +) + +type run struct { + raw string +} + +func (d *run) Raw() string { return strings.Join([]string{"run", d.raw}, " ") } + +func (d *run) Build(_args string) error { + d.raw = _args + return nil +} + +func (d run) Exec(ctx ExecutionContext) ([]byte, error) { + + // 1. fail if file not found + if _, err := os.Stat(d.raw); os.IsNotExist(err) { + return nil, fmt.Errorf("cannot find script '%s'", d.raw) + } + + // 2. execute script + if err := ctx.Executor.Command(d.raw).Run(); err != nil { + return nil, fmt.Errorf("cannot run '%s' | %s", d.raw, err) + } + + return nil, nil + +} diff --git a/internal/instruction/service.go b/internal/instruction/service.go index 791a93c..76d6305 100644 --- a/internal/instruction/service.go +++ b/internal/instruction/service.go @@ -13,7 +13,7 @@ type service struct { Services []string } -func (d *service) Raw() string { return d.raw } +func (d *service) Raw() string { return strings.Join([]string{"service", d.raw}, " ") } func (d *service) Build(_args string) error { diff --git a/internal/instruction/set.go b/internal/instruction/set.go index 3cbf966..48650f0 100644 --- a/internal/instruction/set.go +++ b/internal/instruction/set.go @@ -23,7 +23,7 @@ type set struct { Format *cnf.ConfigurationFormat } -func (d *set) Raw() string { return d.raw } +func (d *set) Raw() string { return strings.Join([]string{"set", d.raw}, " ") } func (d *set) Build(_args string) error { diff --git a/main.go b/main.go index 0e5c723..5dbbb89 100644 --- a/main.go +++ b/main.go @@ -5,10 +5,13 @@ import ( "git.xdrm.io/go/nix-amer/internal/buildfile" "git.xdrm.io/go/nix-amer/internal/clifmt" "os" + "time" ) func main() { + start := time.Now() + // Manage arguments ctx, bf, dryRun, err := GetArgs() if err != nil { @@ -40,14 +43,14 @@ func main() { } // 3. Execute - clifmt.Align("execution") - fmt.Printf("start\n") + fmt.Printf("------\n") err = instructions.Execute() if err != nil { fmt.Printf("%s\n", clifmt.Warn(err.Error())) return } - clifmt.Align("execution") - fmt.Printf("%s\n", clifmt.Color(32, "finished")) + fmt.Printf("------\n") + clifmt.Align("finished in") + fmt.Printf("%ss\n", clifmt.Color(32, fmt.Sprintf("%.2f", time.Now().Sub(start).Seconds()))) }