From b3d8ef1675fdab3545011142eddfaa49215eeb3a Mon Sep 17 00:00:00 2001 From: rick Date: Thu, 16 Feb 2023 10:09:07 +0800 Subject: [PATCH] feat: support to print the output in-time --- README.md | 10 +++++++++ cli/golang_runner.go | 17 ++------------- cli/python_runner.go | 17 ++------------- cli/root.go | 22 +++++++++++++------ cli/root_test.go | 4 +++- cli/shell_runner.go | 50 +++++++++++++++++--------------------------- cli/types.go | 18 ++++++++++++++++ go.mod | 15 +++++++------ go.sum | 36 ++++++++++++++++++++++++------- main.go | 3 ++- 10 files changed, 110 insertions(+), 82 deletions(-) diff --git a/README.md b/README.md index 3c2c6f7..19e6f09 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,16 @@ name=linuxsuren echo hello $name ``` +### Run in long time +```shell +#!title: Run long time +for i in 1 2 3 4 5 +do + echo $i + sleep 1 +done +``` + ### Run Python Script ```python3 #!title: Python Hello World diff --git a/cli/golang_runner.go b/cli/golang_runner.go index 7c95791..83164eb 100644 --- a/cli/golang_runner.go +++ b/cli/golang_runner.go @@ -3,7 +3,7 @@ package cli import ( "fmt" "os" - "os/exec" + "path" "strings" ) @@ -39,20 +39,7 @@ func (s *GolangScript) Run() (err error) { }() } - var goExec string - if goExec, err = exec.LookPath("go"); err != nil { - return - } - - cmd := exec.Command(goExec, "run", goSourceFile) - cmd.Env = os.Environ() - - var output []byte - if output, err = cmd.CombinedOutput(); err != nil { - fmt.Println(string(output), err) - return - } - fmt.Print(string(output)) + err = s.Execer.RunCommandInDir("go", s.Dir, "run", path.Base(goSourceFile)) return } diff --git a/cli/python_runner.go b/cli/python_runner.go index 5c06312..420fbed 100644 --- a/cli/python_runner.go +++ b/cli/python_runner.go @@ -3,7 +3,7 @@ package cli import ( "fmt" "os" - "os/exec" + "path" ) // PythonScript represents the Python script @@ -24,20 +24,7 @@ func (s *PythonScript) Run() (err error) { }() } - var pyExec string - if pyExec, err = exec.LookPath("python3"); err != nil { - return - } - - cmd := exec.Command(pyExec, shellFile) - cmd.Env = os.Environ() - - var output []byte - if output, err = cmd.CombinedOutput(); err != nil { - fmt.Println(string(output), err) - return - } - fmt.Print(string(output)) + err = s.Execer.RunCommandInDir("python3", s.Dir, path.Base(shellFile)) return } diff --git a/cli/root.go b/cli/root.go index d8f3eda..75b347c 100644 --- a/cli/root.go +++ b/cli/root.go @@ -3,6 +3,7 @@ package cli import ( "fmt" + "io" "os" "path" "path/filepath" @@ -10,6 +11,7 @@ import ( "github.com/AlecAivazis/survey/v2" "github.com/golang-commonmark/markdown" + "github.com/linuxsuren/http-downloader/pkg/exec" "github.com/spf13/cobra" ) @@ -17,14 +19,17 @@ import ( var version string // NewRootCommand returns the instance of cobra.Command -func NewRootCommand() (cmd *cobra.Command) { - opt := &option{} +func NewRootCommand(execer exec.Execer, out io.Writer) (cmd *cobra.Command) { + opt := &option{ + execer: execer, + } cmd = &cobra.Command{ Use: "mde", Example: "mde README.md", Args: cobra.MinimumNArgs(1), RunE: opt.runE, } + cmd.SetOut(out) cmd.Version = version flags := cmd.Flags() flags.BoolVarP(&opt.loop, "loop", "", true, "Run the Markdown in loop mode.") @@ -52,11 +57,13 @@ func (o *option) runE(cmd *cobra.Command, args []string) (err error) { } } - for { - err = o.executeScripts(scriptRunners) + if scriptRunners.Size() > 1 { + for { + err = o.executeScripts(scriptRunners) - if !o.loop { - break + if !o.loop { + break + } } } return @@ -109,6 +116,7 @@ func (o *option) parseMarkdownRunner(mdFilePath string) (scriptList ScriptRunner Content: originalContent, Dir: path.Dir(mdFilePath), KeepScripts: o.keepScripts, + Execer: o.execer, } switch lang { @@ -133,6 +141,8 @@ type option struct { loop bool keepFilter bool keepScripts bool + + execer exec.Execer } func (o *option) executeScripts(scriptRunners ScriptRunners) (err error) { diff --git a/cli/root_test.go b/cli/root_test.go index 2bf6378..6afa023 100644 --- a/cli/root_test.go +++ b/cli/root_test.go @@ -1,8 +1,10 @@ package cli import ( + "bytes" "testing" + "github.com/linuxsuren/http-downloader/pkg/exec" "github.com/stretchr/testify/assert" ) @@ -18,7 +20,7 @@ func TestNewRootCommand(t *testing.T) { }} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - cmd := NewRootCommand() + cmd := NewRootCommand(exec.FakeExecer{}, &bytes.Buffer{}) assert.True(t, cmd.HasExample()) cmd.SetArgs(tt.args) diff --git a/cli/shell_runner.go b/cli/shell_runner.go index 9134d57..5c1cfdc 100644 --- a/cli/shell_runner.go +++ b/cli/shell_runner.go @@ -4,7 +4,6 @@ import ( "fmt" "io" "os" - "os/exec" "path" "regexp" "strings" @@ -29,7 +28,7 @@ func (s *ShellScript) Run() (err error) { lines := strings.Split(s.Content, "\n")[1:] preDefinedEnv := os.Environ() - for _, cmdLine := range lines { + for i, cmdLine := range lines { var pair []string var ok bool ok, pair, err = isInputRequest(cmdLine) @@ -43,10 +42,8 @@ func (s *ShellScript) Run() (err error) { } os.Setenv(pair[0], pair[1]) continue - } - - err = runCmdLine(cmdLine, s.Dir, s.KeepScripts) - if err != nil { + } else { + err = s.runCmdLine(strings.Join(lines[i:], "\n"), s.Dir, s.KeepScripts) break } } @@ -59,6 +56,22 @@ func (s *ShellScript) Run() (err error) { return } +func (s *ShellScript) runCmdLine(cmdLine, contextDir string, keepScripts bool) (err error) { + var shellFile string + if shellFile, err = writeAsShell(cmdLine, contextDir); err != nil { + fmt.Println(err) + return + } + if !keepScripts { + defer func() { + _ = os.RemoveAll(shellFile) + }() + } + + err = s.Execer.RunCommandInDir("bash", contextDir, path.Base(shellFile)) + return +} + // GetTitle returns the title of this script func (s *ShellScript) GetTitle() string { return s.Title @@ -91,31 +104,6 @@ func inputRequest(pair []string) (result []string, err error) { return } -func runCmdLine(cmdLine, contextDir string, keepScripts bool) (err error) { - var shellFile string - if shellFile, err = writeAsShell(cmdLine, contextDir); err != nil { - fmt.Println(err) - return - } - if !keepScripts { - defer func() { - _ = os.RemoveAll(shellFile) - }() - } - - cmd := exec.Command("bash", path.Base(shellFile)) - cmd.Dir = contextDir - cmd.Env = os.Environ() - - var output []byte - if output, err = cmd.CombinedOutput(); err != nil { - fmt.Println(string(output), err) - return - } - fmt.Print(string(output)) - return -} - func writeAsShell(content, dir string) (targetPath string, err error) { var f *os.File if f, err = os.CreateTemp(dir, "sh"); err == nil { diff --git a/cli/types.go b/cli/types.go index b2ae228..3891244 100644 --- a/cli/types.go +++ b/cli/types.go @@ -1,5 +1,7 @@ package cli +import "github.com/linuxsuren/http-downloader/pkg/exec" + // Script represents a script object type Script struct { Kind string @@ -7,19 +9,24 @@ type Script struct { Content string Dir string KeepScripts bool + Execer exec.Execer } +// ScriptRunner is the interface of a common runner type ScriptRunner interface { Run() error GetTitle() string } +// NewScriptRunners returns the instance of ScriptRunners func NewScriptRunners() ScriptRunners { return []ScriptRunner{&QuitRunner{}} } +// ScriptRunners is an alias of the ScriptRunner slice type ScriptRunners []ScriptRunner +// GetTitles returns all the titles func (s ScriptRunners) GetTitles() (titles []string) { titles = make([]string, len(s)) for i, r := range s { @@ -27,6 +34,8 @@ func (s ScriptRunners) GetTitles() (titles []string) { } return } + +// GetRunner returns the runner by title func (s ScriptRunners) GetRunner(title string) ScriptRunner { for _, runner := range s { if runner.GetTitle() == title { @@ -36,11 +45,20 @@ func (s ScriptRunners) GetRunner(title string) ScriptRunner { return nil } +// Size returns the size of the script runners +func (s ScriptRunners) Size() int { + return len(s) +} + +// QuitRunner represents a runner for quit type QuitRunner struct{} +// Run does nothing func (r *QuitRunner) Run() error { return nil } + +// GetTitle returns the title func (r *QuitRunner) GetTitle() string { return "Quit" } diff --git a/go.mod b/go.mod index 7e0a6da..fc99ba4 100644 --- a/go.mod +++ b/go.mod @@ -4,22 +4,25 @@ go 1.18 require ( github.com/golang-commonmark/markdown v0.0.0-20180910011815-a8f139058164 + github.com/linuxsuren/http-downloader v0.0.82 github.com/spf13/cobra v1.6.1 - github.com/stretchr/testify v1.6.1 + github.com/stretchr/testify v1.8.1 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/inconshreveable/mousetrap v1.0.1 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect - github.com/mattn/go-colorable v0.1.2 // indirect - github.com/mattn/go-isatty v0.0.8 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/mattn/go-colorable v0.1.6 // indirect + github.com/mattn/go-isatty v0.0.12 // indirect github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 // indirect - golang.org/x/term v0.0.0-20210503060354-a79de5458b56 // indirect - golang.org/x/text v0.3.3 // indirect + golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect + golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect + golang.org/x/text v0.3.8 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 733d42c..7d5b47d 100644 --- a/go.sum +++ b/go.sum @@ -3,6 +3,7 @@ github.com/AlecAivazis/survey/v2 v2.3.6/go.mod h1:4AuI9b7RjAR+G7v9+C4YSlX/YL3K3c github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s= github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI= github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -24,10 +25,20 @@ github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7P github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= -github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/linuxsuren/http-downloader v0.0.82 h1:O9d/euvR8Uc/nguQX4FyPOc2hRE0rcWoUZZ0n1jeuRY= +github.com/linuxsuren/http-downloader v0.0.82/go.mod h1:6gacLcDwDGo3E8hwcvzQALfIjkTfAENX6LOgeOfL9ww= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= +github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/opennota/wd v0.0.0-20180911144301-b446539ab1e7 h1:cVQhwfBgiKTMAdYPbVeuIiTkdY59qZ3sp5RpyO8CNtg= @@ -42,19 +53,30 @@ github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUq github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 h1:xHms4gcpe1YE7A3yIllJXP16CMAGuqwO2lX1mTyyRRc= golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20210503060354-a79de5458b56 h1:b8jxX3zqjpqb2LklXPzKSGJhzyxCOZSz8ncv8Nv+y7w= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY= -golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go index 0fb309c..6431226 100644 --- a/main.go +++ b/main.go @@ -5,11 +5,12 @@ import ( "context" "os" + "github.com/linuxsuren/http-downloader/pkg/exec" "github.com/linuxsuren/md-exec/cli" ) func main() { - cmd := cli.NewRootCommand() + cmd := cli.NewRootCommand(exec.DefaultExecer{}, os.Stdout) if err := cmd.ExecuteContext(context.Background()); err != nil { os.Exit(1) }