From 1ba345c905fa5d2630cd6a2b5888d5354eeff06e Mon Sep 17 00:00:00 2001 From: Tom Ashworth Date: Sun, 12 Jun 2022 12:48:18 +0100 Subject: [PATCH 01/13] redo file structure for commands and add gitignores --- .gitignore | 1 + Go.AllowList.gitignore | 26 ++++++++++++++++++++++++++ cli-files/README.md | 8 ++++++++ cli-files/go-ls/cmd/root.go | 21 +++++++++++++++++++++ cli-files/go-ls/go.mod | 10 ++++++++++ cli-files/go-ls/go.sum | 10 ++++++++++ cli-files/go-ls/main.go | 9 +++++++++ 7 files changed, 85 insertions(+) create mode 100644 .gitignore create mode 100644 Go.AllowList.gitignore create mode 100644 cli-files/go-ls/cmd/root.go create mode 100644 cli-files/go-ls/go.mod create mode 100644 cli-files/go-ls/go.sum create mode 100644 cli-files/go-ls/main.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..cf92ac7b0 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +!*/assets \ No newline at end of file diff --git a/Go.AllowList.gitignore b/Go.AllowList.gitignore new file mode 100644 index 000000000..a048e5ab7 --- /dev/null +++ b/Go.AllowList.gitignore @@ -0,0 +1,26 @@ + + + +# Allowlisting gitignore template for GO projects prevents us +# from adding various unwanted local files, such as generated +# files, developer configurations or IDE-specific files etc. +# +# Recommended: Go.AllowList.gitignore + +# Ignore everything +* + +# But not these files... +!/.gitignore + +!*.go +!go.sum +!go.mod + +!README.md +!LICENSE + +# !Makefile + +# ...even if they are in subdirectories +!*/ \ No newline at end of file diff --git a/cli-files/README.md b/cli-files/README.md index 1c2538008..5f75d1121 100644 --- a/cli-files/README.md +++ b/cli-files/README.md @@ -61,6 +61,7 @@ And within every dewdrop A world of struggle. ``` +<<<<<<< HEAD ### go-ls These steps will leave some work for you to do. If something's not clear, search around for to find the answer. If you're stuck for half an hour at most, ask for help. Remember to use Git to store your progress, committing often in small increments with useful descriptions. @@ -165,6 +166,13 @@ Let's try it out: `go install . && go-cat`. It will do nothing, but it's a start Now it's over to you: set up a command that takes a path to a file as an argument, then opens that file and prints it out. You'll need the built-in go functions `os.ReadFile` and `os.Stdout.Write`, as well as more from the `os` package. Bonus task: handle the error if you pass it a directory rather than a file, like cat does. +======= +### Steps (notes) + +- Setup cobra with https://github.com/spf13/cobra/blob/master/user_guide.md +- install in cli-files `go get -u github.com/spf13/cobra@latest` +- `cmd` directory, `root.go` +>>>>>>> 740abac (redo file structure for commands and add gitignores) [go]: https://go.dev/ [cat]: https://en.m.wikipedia.org/wiki/Cat_(Unix) diff --git a/cli-files/go-ls/cmd/root.go b/cli-files/go-ls/cmd/root.go new file mode 100644 index 000000000..e6f8da6fd --- /dev/null +++ b/cli-files/go-ls/cmd/root.go @@ -0,0 +1,21 @@ +package cmd + +import ( + "fmt" + "os" + + "github.com/spf13/cobra" +) + +var rootCmd = &cobra.Command{ + Use: "go-ls", + Short: "go-ls is a re-implementation of the ls command", + Run: func(cmd *cobra.Command, args []string) {}, +} + +func Execute() { + if err := rootCmd.Execute(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} diff --git a/cli-files/go-ls/go.mod b/cli-files/go-ls/go.mod new file mode 100644 index 000000000..ccb33b1bc --- /dev/null +++ b/cli-files/go-ls/go.mod @@ -0,0 +1,10 @@ +module vinery/cli-files/go-ls + +go 1.18 + +require github.com/spf13/cobra v1.4.0 + +require ( + github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect +) diff --git a/cli-files/go-ls/go.sum b/cli-files/go-ls/go.sum new file mode 100644 index 000000000..0dd8697bc --- /dev/null +++ b/cli-files/go-ls/go.sum @@ -0,0 +1,10 @@ +github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q= +github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/cli-files/go-ls/main.go b/cli-files/go-ls/main.go new file mode 100644 index 000000000..7a8c1a8a9 --- /dev/null +++ b/cli-files/go-ls/main.go @@ -0,0 +1,9 @@ +package main + +import ( + "vinery/cli-files/go-ls/cmd" +) + +func main() { + cmd.Execute() +} From 062ba5d53993c977f0b02804f6f5e3f29377df71 Mon Sep 17 00:00:00 2001 From: Tom Ashworth Date: Sun, 12 Jun 2022 12:53:17 +0100 Subject: [PATCH 02/13] Hello, world --- cli-files/go-ls/cmd/root.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cli-files/go-ls/cmd/root.go b/cli-files/go-ls/cmd/root.go index e6f8da6fd..f5c8b928a 100644 --- a/cli-files/go-ls/cmd/root.go +++ b/cli-files/go-ls/cmd/root.go @@ -10,7 +10,9 @@ import ( var rootCmd = &cobra.Command{ Use: "go-ls", Short: "go-ls is a re-implementation of the ls command", - Run: func(cmd *cobra.Command, args []string) {}, + Run: func(cmd *cobra.Command, args []string) { + fmt.Println("Hello, world!") + }, } func Execute() { From 882e0f4204e354708db4d0d87da8637a41105e37 Mon Sep 17 00:00:00 2001 From: Tom Ashworth Date: Sun, 12 Jun 2022 13:10:05 +0100 Subject: [PATCH 03/13] basic ls --- cli-files/README.md | 8 +------- cli-files/go-ls/cmd/root.go | 11 +++++++++-- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/cli-files/README.md b/cli-files/README.md index 5f75d1121..1b19b521f 100644 --- a/cli-files/README.md +++ b/cli-files/README.md @@ -62,6 +62,7 @@ A world of struggle. ``` <<<<<<< HEAD + ### go-ls These steps will leave some work for you to do. If something's not clear, search around for to find the answer. If you're stuck for half an hour at most, ask for help. Remember to use Git to store your progress, committing often in small increments with useful descriptions. @@ -166,13 +167,6 @@ Let's try it out: `go install . && go-cat`. It will do nothing, but it's a start Now it's over to you: set up a command that takes a path to a file as an argument, then opens that file and prints it out. You'll need the built-in go functions `os.ReadFile` and `os.Stdout.Write`, as well as more from the `os` package. Bonus task: handle the error if you pass it a directory rather than a file, like cat does. -======= -### Steps (notes) - -- Setup cobra with https://github.com/spf13/cobra/blob/master/user_guide.md -- install in cli-files `go get -u github.com/spf13/cobra@latest` -- `cmd` directory, `root.go` ->>>>>>> 740abac (redo file structure for commands and add gitignores) [go]: https://go.dev/ [cat]: https://en.m.wikipedia.org/wiki/Cat_(Unix) diff --git a/cli-files/go-ls/cmd/root.go b/cli-files/go-ls/cmd/root.go index f5c8b928a..c924e70ed 100644 --- a/cli-files/go-ls/cmd/root.go +++ b/cli-files/go-ls/cmd/root.go @@ -10,8 +10,15 @@ import ( var rootCmd = &cobra.Command{ Use: "go-ls", Short: "go-ls is a re-implementation of the ls command", - Run: func(cmd *cobra.Command, args []string) { - fmt.Println("Hello, world!") + RunE: func(cmd *cobra.Command, args []string) error { + files, err := os.ReadDir(".") + if err != nil { + return err + } + for _, file := range files { + fmt.Println(file.Name()) + } + return nil }, } From edfa9ba4599897c004a608f595c72929c568084c Mon Sep 17 00:00:00 2001 From: Tom Ashworth Date: Sun, 12 Jun 2022 16:09:19 +0100 Subject: [PATCH 04/13] accept an argument --- cli-files/go-ls/cmd/root.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/cli-files/go-ls/cmd/root.go b/cli-files/go-ls/cmd/root.go index c924e70ed..5a04d307a 100644 --- a/cli-files/go-ls/cmd/root.go +++ b/cli-files/go-ls/cmd/root.go @@ -11,10 +11,20 @@ var rootCmd = &cobra.Command{ Use: "go-ls", Short: "go-ls is a re-implementation of the ls command", RunE: func(cmd *cobra.Command, args []string) error { - files, err := os.ReadDir(".") + // By default, ls the current directory + dir := "." + // If an argument was passed, use the first as our directory + if len(args) > 0 { + dir = args[0] + } + + // Read this directory to get a list of files + // https://pkg.go.dev/os#ReadDir + files, err := os.ReadDir(dir) if err != nil { return err } + // Iterate through each file in the directory, printing the file name for _, file := range files { fmt.Println(file.Name()) } From 7147b317f808c8056350f3096dfea9388d94a6f7 Mon Sep 17 00:00:00 2001 From: Tom Ashworth Date: Sun, 12 Jun 2022 16:48:30 +0100 Subject: [PATCH 05/13] add a simple test --- cli-files/go-ls/cmd/root.go | 48 +++++++++++++++++--------------- cli-files/go-ls/cmd/root_test.go | 25 +++++++++++++++++ 2 files changed, 51 insertions(+), 22 deletions(-) create mode 100644 cli-files/go-ls/cmd/root_test.go diff --git a/cli-files/go-ls/cmd/root.go b/cli-files/go-ls/cmd/root.go index 5a04d307a..f3380be2c 100644 --- a/cli-files/go-ls/cmd/root.go +++ b/cli-files/go-ls/cmd/root.go @@ -7,32 +7,36 @@ import ( "github.com/spf13/cobra" ) -var rootCmd = &cobra.Command{ - Use: "go-ls", - Short: "go-ls is a re-implementation of the ls command", - RunE: func(cmd *cobra.Command, args []string) error { - // By default, ls the current directory - dir := "." - // If an argument was passed, use the first as our directory - if len(args) > 0 { - dir = args[0] - } +func NewRoodCmd() *cobra.Command { + return &cobra.Command{ + Use: "go-ls", + Short: "go-ls is a re-implementation of the ls command", + Args: cobra.ArbitraryArgs, + RunE: func(cmd *cobra.Command, args []string) error { + // By default, ls the current directory + dir := "." + // If an argument was passed, use the first as our directory + if len(args) > 0 { + dir = args[0] + } - // Read this directory to get a list of files - // https://pkg.go.dev/os#ReadDir - files, err := os.ReadDir(dir) - if err != nil { - return err - } - // Iterate through each file in the directory, printing the file name - for _, file := range files { - fmt.Println(file.Name()) - } - return nil - }, + // Read this directory to get a list of files + // https://pkg.go.dev/os#ReadDir + files, err := os.ReadDir(dir) + if err != nil { + return err + } + // Iterate through each file in the directory, printing the file name + for _, file := range files { + fmt.Fprintln(cmd.OutOrStdout(), file.Name()) + } + return nil + }, + } } func Execute() { + rootCmd := NewRoodCmd() if err := rootCmd.Execute(); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) diff --git a/cli-files/go-ls/cmd/root_test.go b/cli-files/go-ls/cmd/root_test.go new file mode 100644 index 000000000..7791180a9 --- /dev/null +++ b/cli-files/go-ls/cmd/root_test.go @@ -0,0 +1,25 @@ +package cmd + +import ( + "bytes" + "io/ioutil" + "testing" +) + +func TestRootCmd(t *testing.T) { + cmd := NewRoodCmd() + b := bytes.NewBufferString("") + cmd.SetOut(b) + cmd.SetArgs([]string{}) + cmd.Execute() + out, err := ioutil.ReadAll(b) + if err != nil { + t.Fatal(err) + } + expected := `root.go +root_test.go +` + if string(out) != expected { + t.Fatalf("expected \"%s\" got \"%s\"", expected, string(out)) + } +} From 06b71c6282dda748914f6975b20caa87898e7efc Mon Sep 17 00:00:00 2001 From: Tom Ashworth Date: Sun, 12 Jun 2022 16:51:19 +0100 Subject: [PATCH 06/13] add relative path test --- cli-files/go-ls/cmd/root_test.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/cli-files/go-ls/cmd/root_test.go b/cli-files/go-ls/cmd/root_test.go index 7791180a9..55026ec0a 100644 --- a/cli-files/go-ls/cmd/root_test.go +++ b/cli-files/go-ls/cmd/root_test.go @@ -23,3 +23,22 @@ root_test.go t.Fatalf("expected \"%s\" got \"%s\"", expected, string(out)) } } + +func TestRootCmdRelative(t *testing.T) { + cmd := NewRoodCmd() + b := bytes.NewBufferString("") + cmd.SetOut(b) + cmd.SetArgs([]string{"../assets"}) + cmd.Execute() + out, err := ioutil.ReadAll(b) + if err != nil { + t.Fatal(err) + } + expected := `dew.txt +for_you.txt +rain.txt +` + if string(out) != expected { + t.Fatalf("expected \"%s\" got \"%s\"", expected, string(out)) + } +} From 82435446d77ce3f8743218082349aaf33e4c4d17 Mon Sep 17 00:00:00 2001 From: Tom Ashworth Date: Tue, 21 Jun 2022 21:33:18 +0100 Subject: [PATCH 07/13] more steps --- cli-files/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/cli-files/README.md b/cli-files/README.md index 1b19b521f..1c2538008 100644 --- a/cli-files/README.md +++ b/cli-files/README.md @@ -61,8 +61,6 @@ And within every dewdrop A world of struggle. ``` -<<<<<<< HEAD - ### go-ls These steps will leave some work for you to do. If something's not clear, search around for to find the answer. If you're stuck for half an hour at most, ask for help. Remember to use Git to store your progress, committing often in small increments with useful descriptions. From 7208af16c751f6909c6ff664de7e9038d67da86b Mon Sep 17 00:00:00 2001 From: Tom Ashworth Date: Tue, 21 Jun 2022 21:39:21 +0100 Subject: [PATCH 08/13] print file name if passed a file --- cli-files/go-ls/cmd/root.go | 18 ++++++++++++++++++ cli-files/go-ls/cmd/root_test.go | 17 +++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/cli-files/go-ls/cmd/root.go b/cli-files/go-ls/cmd/root.go index f3380be2c..959d54f47 100644 --- a/cli-files/go-ls/cmd/root.go +++ b/cli-files/go-ls/cmd/root.go @@ -20,6 +20,24 @@ func NewRoodCmd() *cobra.Command { dir = args[0] } + // Stat the file so we can check if it's a directory or not before + // we try to read it as a directory using ReadDir. os.ReadDir will + // generates an error if the thing you pass to it is not a directory. + // https://pkg.go.dev/os#Stat + fileInfo, err := os.Stat(dir) + if err != nil { + return err + } + + // We can only list the contents of a directory. + // To match the real ls, if we're asked to ls a file, we'll just print + // out the file's name. + // https://pkg.go.dev/io/fs#FileInfo + if fileInfo.IsDir() == false { + fmt.Fprintln(cmd.OutOrStdout(), fileInfo.Name()) + return nil + } + // Read this directory to get a list of files // https://pkg.go.dev/os#ReadDir files, err := os.ReadDir(dir) diff --git a/cli-files/go-ls/cmd/root_test.go b/cli-files/go-ls/cmd/root_test.go index 55026ec0a..bbecc7de6 100644 --- a/cli-files/go-ls/cmd/root_test.go +++ b/cli-files/go-ls/cmd/root_test.go @@ -42,3 +42,20 @@ rain.txt t.Fatalf("expected \"%s\" got \"%s\"", expected, string(out)) } } + +func TestRootCmdFile(t *testing.T) { + cmd := NewRoodCmd() + b := bytes.NewBufferString("") + cmd.SetOut(b) + cmd.SetArgs([]string{"../assets/dew.txt"}) + cmd.Execute() + out, err := ioutil.ReadAll(b) + if err != nil { + t.Fatal(err) + } + expected := `dew.txt +` + if string(out) != expected { + t.Fatalf("expected \"%s\" got \"%s\"", expected, string(out)) + } +} From 981f7eb002a65404c95563d13cad62adcedfa51b Mon Sep 17 00:00:00 2001 From: Tom Ashworth Date: Wed, 22 Jun 2022 21:33:36 +0100 Subject: [PATCH 09/13] initial go-cat commit --- cli-files/go-cat/LICENSE | 0 cli-files/go-cat/cmd/root.go | 47 ++++++++++++++++++++++++++++++++++++ cli-files/go-cat/go.mod | 9 +++++++ cli-files/go-cat/go.sum | 10 ++++++++ cli-files/go-cat/main.go | 11 +++++++++ 5 files changed, 77 insertions(+) create mode 100644 cli-files/go-cat/LICENSE create mode 100644 cli-files/go-cat/cmd/root.go create mode 100644 cli-files/go-cat/go.mod create mode 100644 cli-files/go-cat/go.sum create mode 100644 cli-files/go-cat/main.go diff --git a/cli-files/go-cat/LICENSE b/cli-files/go-cat/LICENSE new file mode 100644 index 000000000..e69de29bb diff --git a/cli-files/go-cat/cmd/root.go b/cli-files/go-cat/cmd/root.go new file mode 100644 index 000000000..57b6d48dd --- /dev/null +++ b/cli-files/go-cat/cmd/root.go @@ -0,0 +1,47 @@ +/* +Copyright © 2022 NAME HERE + +*/ +package cmd + +import ( + "os" + + "github.com/spf13/cobra" +) + +// rootCmd represents the base command when called without any subcommands +var rootCmd = &cobra.Command{ + Use: "go-cat", + Short: "A brief description of your application", + Long: `A longer description that spans multiple lines and likely contains +examples and usage of using your application. For example: + +Cobra is a CLI library for Go that empowers applications. +This application is a tool to generate the needed files +to quickly create a Cobra application.`, + // Uncomment the following line if your bare application + // has an action associated with it: + // Run: func(cmd *cobra.Command, args []string) { }, +} + +// Execute adds all child commands to the root command and sets flags appropriately. +// This is called by main.main(). It only needs to happen once to the rootCmd. +func Execute() { + err := rootCmd.Execute() + if err != nil { + os.Exit(1) + } +} + +func init() { + // Here you will define your flags and configuration settings. + // Cobra supports persistent flags, which, if defined here, + // will be global for your application. + + // rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.go-cat.yaml)") + + // Cobra also supports local flags, which will only run + // when this action is called directly. + rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") +} diff --git a/cli-files/go-cat/go.mod b/cli-files/go-cat/go.mod new file mode 100644 index 000000000..9b20879fa --- /dev/null +++ b/cli-files/go-cat/go.mod @@ -0,0 +1,9 @@ +module go-cat + +go 1.18 + +require ( + github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/spf13/cobra v1.5.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect +) diff --git a/cli-files/go-cat/go.sum b/cli-files/go-cat/go.sum new file mode 100644 index 000000000..0d85248bf --- /dev/null +++ b/cli-files/go-cat/go.sum @@ -0,0 +1,10 @@ +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= +github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/cli-files/go-cat/main.go b/cli-files/go-cat/main.go new file mode 100644 index 000000000..cca0ed59e --- /dev/null +++ b/cli-files/go-cat/main.go @@ -0,0 +1,11 @@ +/* +Copyright © 2022 NAME HERE + +*/ +package main + +import "go-cat/cmd" + +func main() { + cmd.Execute() +} From 5d76dbd8d9d2bd3265b95188b10ee3ac898b8b07 Mon Sep 17 00:00:00 2001 From: Tom Ashworth Date: Wed, 22 Jun 2022 21:39:29 +0100 Subject: [PATCH 10/13] passing test --- cli-files/go-cat/cmd/root.go | 40 ++++++++++--------------------- cli-files/go-cat/cmd/root_test.go | 23 ++++++++++++++++++ 2 files changed, 35 insertions(+), 28 deletions(-) create mode 100644 cli-files/go-cat/cmd/root_test.go diff --git a/cli-files/go-cat/cmd/root.go b/cli-files/go-cat/cmd/root.go index 57b6d48dd..c3761ba79 100644 --- a/cli-files/go-cat/cmd/root.go +++ b/cli-files/go-cat/cmd/root.go @@ -5,43 +5,27 @@ Copyright © 2022 NAME HERE package cmd import ( + "fmt" "os" "github.com/spf13/cobra" ) // rootCmd represents the base command when called without any subcommands -var rootCmd = &cobra.Command{ - Use: "go-cat", - Short: "A brief description of your application", - Long: `A longer description that spans multiple lines and likely contains -examples and usage of using your application. For example: - -Cobra is a CLI library for Go that empowers applications. -This application is a tool to generate the needed files -to quickly create a Cobra application.`, - // Uncomment the following line if your bare application - // has an action associated with it: - // Run: func(cmd *cobra.Command, args []string) { }, +func NewRoodCmd() *cobra.Command { + return &cobra.Command{ + Use: "go-cat", + Short: "Go implementation of cat", + Long: `Works like cat`, + Run: func(cmd *cobra.Command, args []string) { + }, + } } -// Execute adds all child commands to the root command and sets flags appropriately. -// This is called by main.main(). It only needs to happen once to the rootCmd. func Execute() { - err := rootCmd.Execute() - if err != nil { + rootCmd := NewRoodCmd() + if err := rootCmd.Execute(); err != nil { + fmt.Fprintln(os.Stderr, err) os.Exit(1) } } - -func init() { - // Here you will define your flags and configuration settings. - // Cobra supports persistent flags, which, if defined here, - // will be global for your application. - - // rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.go-cat.yaml)") - - // Cobra also supports local flags, which will only run - // when this action is called directly. - rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") -} diff --git a/cli-files/go-cat/cmd/root_test.go b/cli-files/go-cat/cmd/root_test.go new file mode 100644 index 000000000..d6aef311f --- /dev/null +++ b/cli-files/go-cat/cmd/root_test.go @@ -0,0 +1,23 @@ +package cmd + +import ( + "bytes" + "io/ioutil" + "testing" +) + +func TestRootCmd(t *testing.T) { + cmd := NewRoodCmd() + b := bytes.NewBufferString("") + cmd.SetOut(b) + cmd.SetArgs([]string{}) + cmd.Execute() + out, err := ioutil.ReadAll(b) + if err != nil { + t.Fatal(err) + } + expected := `` + if string(out) != expected { + t.Fatalf("expected \"%s\" got \"%s\"", expected, string(out)) + } +} From 55e0e2598da1f31fa8972079fac3556d8076f42f Mon Sep 17 00:00:00 2001 From: Tom Ashworth Date: Wed, 22 Jun 2022 21:52:36 +0100 Subject: [PATCH 11/13] basic go-cat implementation --- cli-files/go-cat/assets/dew.txt | 5 +++++ cli-files/go-cat/assets/for_you.txt | 5 +++++ cli-files/go-cat/assets/rain.txt | 5 +++++ cli-files/go-cat/cmd/root.go | 29 ++++++++++++++++++++++++++++- cli-files/go-cat/cmd/root_test.go | 20 ++++++++++++++++++++ 5 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 cli-files/go-cat/assets/dew.txt create mode 100644 cli-files/go-cat/assets/for_you.txt create mode 100644 cli-files/go-cat/assets/rain.txt diff --git a/cli-files/go-cat/assets/dew.txt b/cli-files/go-cat/assets/dew.txt new file mode 100644 index 000000000..74c9b6edb --- /dev/null +++ b/cli-files/go-cat/assets/dew.txt @@ -0,0 +1,5 @@ +“A World of Dew” by Kobayashi Issa + +A world of dew, +And within every dewdrop +A world of struggle. \ No newline at end of file diff --git a/cli-files/go-cat/assets/for_you.txt b/cli-files/go-cat/assets/for_you.txt new file mode 100644 index 000000000..9e01a74ca --- /dev/null +++ b/cli-files/go-cat/assets/for_you.txt @@ -0,0 +1,5 @@ +Sonia Sanchez “Haiku [for you]” + +Love between us is +speech and breath. Loving you is +a long river running. \ No newline at end of file diff --git a/cli-files/go-cat/assets/rain.txt b/cli-files/go-cat/assets/rain.txt new file mode 100644 index 000000000..149523ec7 --- /dev/null +++ b/cli-files/go-cat/assets/rain.txt @@ -0,0 +1,5 @@ +“The Taste of Rain” by Jack Kerouac + +The taste +Of rain +—Why kneel? \ No newline at end of file diff --git a/cli-files/go-cat/cmd/root.go b/cli-files/go-cat/cmd/root.go index c3761ba79..927e65e21 100644 --- a/cli-files/go-cat/cmd/root.go +++ b/cli-files/go-cat/cmd/root.go @@ -17,7 +17,34 @@ func NewRoodCmd() *cobra.Command { Use: "go-cat", Short: "Go implementation of cat", Long: `Works like cat`, - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { + // Don't do anything if we didn't get an arg + if len(args) < 1 { + return nil + } + path := args[0] + + // Get data about the file so we can do this safely + file, err := os.Stat(path) + if err != nil { + return err + } + + // If it's a directory, do the right thing and error + if file.IsDir() { + return fmt.Errorf("go-cat: %s: Is a directory", path) + } + + data, err := os.ReadFile(path) + if err != nil { + return err + } + + // Print those lovely bytes + out := cmd.OutOrStdout() + out.Write(data) + + return nil }, } } diff --git a/cli-files/go-cat/cmd/root_test.go b/cli-files/go-cat/cmd/root_test.go index d6aef311f..0c9774a82 100644 --- a/cli-files/go-cat/cmd/root_test.go +++ b/cli-files/go-cat/cmd/root_test.go @@ -21,3 +21,23 @@ func TestRootCmd(t *testing.T) { t.Fatalf("expected \"%s\" got \"%s\"", expected, string(out)) } } + +func TestRootCmdWithFile(t *testing.T) { + cmd := NewRoodCmd() + b := bytes.NewBufferString("") + cmd.SetOut(b) + cmd.SetArgs([]string{"../assets/dew.txt"}) + cmd.Execute() + out, err := ioutil.ReadAll(b) + if err != nil { + t.Fatal(err) + } + expected := `“A World of Dew” by Kobayashi Issa + +A world of dew, +And within every dewdrop +A world of struggle.` + if string(out) != expected { + t.Fatalf("expected \"%s\" got \"%s\"", expected, string(out)) + } +} From ce4defc30fd41eba89f471962112ee7944bfb346 Mon Sep 17 00:00:00 2001 From: Tom Ashworth Date: Sat, 25 Jun 2022 11:02:13 +0100 Subject: [PATCH 12/13] further docs --- cli-files/go-cat/cmd/root.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cli-files/go-cat/cmd/root.go b/cli-files/go-cat/cmd/root.go index 927e65e21..c55a1c5f6 100644 --- a/cli-files/go-cat/cmd/root.go +++ b/cli-files/go-cat/cmd/root.go @@ -35,6 +35,8 @@ func NewRoodCmd() *cobra.Command { return fmt.Errorf("go-cat: %s: Is a directory", path) } + // Read the data from the file + // https://pkg.go.dev/os#ReadFile data, err := os.ReadFile(path) if err != nil { return err From 47d3f02f95e314311a7688adcbb8bfe304492fda Mon Sep 17 00:00:00 2001 From: Tom Ashworth Date: Sat, 25 Jun 2022 11:30:56 +0100 Subject: [PATCH 13/13] sort out some module mistakes (new to go!) --- cli-files/go-cat/go.mod | 3 ++- cli-files/go-ls/go.mod | 4 ++-- cli-files/go-ls/go.sum | 6 +++--- cli-files/go-ls/main.go | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/cli-files/go-cat/go.mod b/cli-files/go-cat/go.mod index 9b20879fa..2367b1c00 100644 --- a/cli-files/go-cat/go.mod +++ b/cli-files/go-cat/go.mod @@ -2,8 +2,9 @@ module go-cat go 1.18 +require github.com/spf13/cobra v1.5.0 + require ( github.com/inconshreveable/mousetrap v1.0.0 // indirect - github.com/spf13/cobra v1.5.0 // indirect github.com/spf13/pflag v1.0.5 // indirect ) diff --git a/cli-files/go-ls/go.mod b/cli-files/go-ls/go.mod index ccb33b1bc..c533a5046 100644 --- a/cli-files/go-ls/go.mod +++ b/cli-files/go-ls/go.mod @@ -1,8 +1,8 @@ -module vinery/cli-files/go-ls +module go-ls go 1.18 -require github.com/spf13/cobra v1.4.0 +require github.com/spf13/cobra v1.5.0 require ( github.com/inconshreveable/mousetrap v1.0.0 // indirect diff --git a/cli-files/go-ls/go.sum b/cli-files/go-ls/go.sum index 0dd8697bc..0d85248bf 100644 --- a/cli-files/go-ls/go.sum +++ b/cli-files/go-ls/go.sum @@ -1,9 +1,9 @@ -github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q= -github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= +github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= +github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/cli-files/go-ls/main.go b/cli-files/go-ls/main.go index 7a8c1a8a9..de33020d8 100644 --- a/cli-files/go-ls/main.go +++ b/cli-files/go-ls/main.go @@ -1,7 +1,7 @@ package main import ( - "vinery/cli-files/go-ls/cmd" + "go-ls/cmd" ) func main() {