├── GO ILE CLI UYGULAMA GELİŞTİRME.pdf ├── Readme.md ├── examples ├── 01-understanding-args.go ├── 02-flag.go ├── 03-flagset.go ├── 04-cli.go ├── 05-cli-flags.go ├── 06-cli-commands.go ├── go.mod └── go.sum └── gocker ├── .gitignore ├── LICENSE ├── Readme.md ├── cmd ├── inspect.go ├── ps.go └── root.go ├── go.mod ├── go.sum ├── main.go └── pkg └── docker ├── docker_test.go ├── helper.go ├── main.go ├── mapper.go └── service.go /GO ILE CLI UYGULAMA GELİŞTİRME.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kevsersrca/golang-cli-example/2c75965ec06c8f9ba31268c4b8bbccc457dc0938/GO ILE CLI UYGULAMA GELİŞTİRME.pdf -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | Ankara Gophers CLI Uygulama Gelistirme Sunum ve Demo 2 | -------------------------------------------------------------------------------- /examples/01-understanding-args.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | // USAGE 9 | // 10 | // ./1 -help 11 | // ./1 -test 12 | // ./1 command -h 13 | 14 | func main() { 15 | // get all params 16 | params := os.Args 17 | 18 | // set args 19 | args := params[1:] 20 | 21 | // count of args 22 | count := len(args) 23 | 24 | // Program Name is always the first (implicit) argument 25 | programName := params[0] 26 | 27 | // List args 28 | for i, arg := range args { 29 | fmt.Printf("%d is: %s\n", i, arg) 30 | } 31 | 32 | fmt.Printf("Program Name: %s\n", programName) 33 | 34 | fmt.Printf("Total Arguments %d\n", count) 35 | 36 | } 37 | 38 | // ./1 help -flag=test -test 1 39 | -------------------------------------------------------------------------------- /examples/02-flag.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | ) 8 | 9 | // USAGE 10 | // 11 | // ./2 -server https://127.0.0.1 -p 8081 -ssl 12 | 13 | var banner = ` 14 | 15 | 16 | lllllll iiii 17 | l:::::l i::::i 18 | l:::::l iiii 19 | l:::::l 20 | cccccccccccccccc l::::l iiiiiii 21 | cc:::::::::::::::c l::::l i:::::i 22 | c:::::::::::::::::c l::::l i::::i 23 | c:::::::cccccc:::::c l::::l i::::i 24 | c::::::c ccccccc l::::l i::::i 25 | c:::::c l::::l i::::i 26 | c:::::c l::::l i::::i 27 | c::::::c ccccccc l::::l i::::i 28 | c:::::::cccccc:::::cl::::::li::::::i 29 | c:::::::::::::::::cl::::::li::::::i 30 | cc:::::::::::::::cl::::::li::::::i 31 | cccccccccccccccclllllllliiiiiiii 32 | 33 | 34 | 35 | ` 36 | 37 | func main() { 38 | var ( 39 | server string 40 | port int 41 | ) 42 | 43 | flag.StringVar(&server, "s", "http://127.0.0.1", "specify server address to use. defaults to http://127.0.0.1.") 44 | flag.IntVar(&port, "p", 8000, "specify port to use. defaults to 8000") 45 | ssl := flag.Bool("ssl", false, "specify ssl to use. defaults to false") 46 | 47 | flag.Usage = func() { 48 | fmt.Println(banner) 49 | fmt.Printf("Usage of %s:\n", os.Args[0]) 50 | fmt.Printf("./2 -s=https://127.0.0.1 -p=8080 -ssl true \n") 51 | flag.PrintDefaults() 52 | } 53 | 54 | flag.Parse() 55 | 56 | fmt.Printf("Starting Server \nListening %s:%d , SSL Mode: %v\n", server, port, *ssl) 57 | } 58 | -------------------------------------------------------------------------------- /examples/03-flagset.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | ) 8 | 9 | // USAGE 10 | // 11 | // ./3 apply 12 | // ./3 apply --silent 13 | // ./3 reset 14 | // ./3 reset --loud 15 | // ./3 reset --loud=false 16 | 17 | func main() { 18 | args := os.Args 19 | 20 | f1 := flag.NewFlagSet("f1", flag.ContinueOnError) 21 | silent := f1.Bool("silent", false, "") 22 | 23 | f2 := flag.NewFlagSet("f2", flag.ContinueOnError) 24 | loud := f2.Bool("loud", true, "") 25 | 26 | switch args[1] { 27 | case "apply": 28 | if err := f1.Parse(args[2:]); err == nil { 29 | fmt.Println("apply", *silent) 30 | } 31 | case "reset": 32 | if err := f2.Parse(args[2:]); err == nil { 33 | fmt.Println("reset", *loud) 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /examples/04-cli.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "os" 6 | 7 | "github.com/urfave/cli/v2" 8 | ) 9 | 10 | func main() { 11 | 12 | app := &cli.App{} 13 | 14 | app.Copyright = "2022 Ankara Gophers" 15 | app.Description = "Basic CRUD" 16 | app.Authors = []*cli.Author{ 17 | { 18 | Name: "Kevser Sirca", 19 | Email: "kevser.sirca@gmail.com", 20 | }, 21 | } 22 | app.EnableBashCompletion = true 23 | app.Usage = " " 24 | 25 | err := app.Run(os.Args) 26 | if err != nil { 27 | log.Fatal(err) 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /examples/05-cli-flags.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "os" 7 | 8 | "github.com/urfave/cli/v2" 9 | ) 10 | 11 | func main() { 12 | var version string 13 | 14 | app := &cli.App{ 15 | Flags: []cli.Flag{ 16 | &cli.StringFlag{ 17 | Name: "version", 18 | Aliases: []string{"v"}, 19 | Value: "1.2.4", 20 | Usage: "version of app", 21 | Destination: &version, 22 | }, 23 | }, 24 | Action: func(c *cli.Context) error { 25 | name := "someone" 26 | if version < "1.2.4" { 27 | fmt.Println("Please update your app, ", name) 28 | } 29 | return nil 30 | }, 31 | } 32 | 33 | err := app.Run(os.Args) 34 | if err != nil { 35 | log.Fatal(err) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /examples/06-cli-commands.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "os" 7 | 8 | "github.com/urfave/cli/v2" 9 | ) 10 | 11 | func main() { 12 | 13 | addCmd := &cli.Command{ 14 | Name: "add", 15 | Aliases: []string{"a"}, 16 | Usage: "add a task to the list", 17 | Action: func(c *cli.Context) error { 18 | fmt.Println("added task: ", c.Args().First()) 19 | return nil 20 | }, 21 | } 22 | 23 | templateCmd := &cli.Command{ 24 | Name: "template", 25 | Aliases: []string{"t"}, 26 | Usage: "options for task templates", 27 | Subcommands: []*cli.Command{ 28 | { 29 | Name: "add", 30 | Usage: "add a new template", 31 | Action: func(c *cli.Context) error { 32 | fmt.Println("new task template: ", c.Args().First()) 33 | return nil 34 | }, 35 | }, 36 | { 37 | Name: "remove", 38 | Usage: "remove an existing template", 39 | Action: func(c *cli.Context) error { 40 | fmt.Println("removed task template: ", c.Args().First()) 41 | return nil 42 | }, 43 | }, 44 | }, 45 | } 46 | 47 | app := &cli.App{ 48 | Commands: []*cli.Command{ 49 | addCmd, 50 | templateCmd, 51 | { 52 | Name: "complete", 53 | Aliases: []string{"c"}, 54 | Usage: "complete a task on the list", 55 | Action: func(c *cli.Context) error { 56 | fmt.Println("completed task: ", c.Args().First()) 57 | return nil 58 | }, 59 | }, 60 | }, 61 | } 62 | err := app.Run(os.Args) 63 | if err != nil { 64 | log.Fatal(err) 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /examples/go.mod: -------------------------------------------------------------------------------- 1 | module cli-tutorial 2 | 3 | go 1.17 4 | 5 | require github.com/urfave/cli/v2 v2.6.0 6 | 7 | require ( 8 | github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect 9 | github.com/inconshreveable/mousetrap v1.0.0 // indirect 10 | github.com/russross/blackfriday/v2 v2.1.0 // indirect 11 | github.com/spf13/cobra v1.4.0 // indirect 12 | github.com/spf13/pflag v1.0.5 // indirect 13 | ) 14 | -------------------------------------------------------------------------------- /examples/go.sum: -------------------------------------------------------------------------------- 1 | github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= 2 | github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU= 3 | github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 4 | github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= 5 | github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= 6 | github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= 7 | github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 8 | github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q= 9 | github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= 10 | github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= 11 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 12 | github.com/urfave/cli/v2 v2.6.0 h1:yj2Drkflh8X/zUrkWlWlUjZYHyWN7WMmpVxyxXIUyv8= 13 | github.com/urfave/cli/v2 v2.6.0/go.mod h1:oDzoM7pVwz6wHn5ogWgFUU1s4VJayeQS+aEZDqXIEJs= 14 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 15 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 16 | -------------------------------------------------------------------------------- /gocker/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.[56789ao] 3 | *.a[56789o] 4 | *.so 5 | *.pyc 6 | ._* 7 | .nfs.* 8 | [56789a].out 9 | *~ 10 | *.orig 11 | *.rej 12 | *.exe 13 | .*.swp 14 | core 15 | *.cgo*.go 16 | *.cgo*.c 17 | _cgo_* 18 | _obj 19 | _test 20 | _testmain.go 21 | .idea 22 | .env 23 | config.yml -------------------------------------------------------------------------------- /gocker/LICENSE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kevsersrca/golang-cli-example/2c75965ec06c8f9ba31268c4b8bbccc457dc0938/gocker/LICENSE -------------------------------------------------------------------------------- /gocker/Readme.md: -------------------------------------------------------------------------------- 1 | ## Gocker 2 | 3 | ``` 4 | / \ / \ / \ / \ / \ / \ 5 | ( g | o | c | k | e | r ) 6 | \_/ \_/ \_/ \_/ \_/ \_/ 7 | ``` 8 | 9 | Initialize cli application for gocker 10 | 11 | ``` 12 | cobra-cli init 13 | ``` 14 | 15 | add command 16 | 17 | ``` 18 | cobra-cli add ps 19 | ``` 20 | -------------------------------------------------------------------------------- /gocker/cmd/inspect.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2022 NAME HERE 3 | 4 | */ 5 | package cmd 6 | 7 | import ( 8 | "encoding/json" 9 | "fmt" 10 | "gocker/pkg/docker" 11 | "log" 12 | 13 | "github.com/spf13/cobra" 14 | ) 15 | 16 | // inspectCmd represents the inspect command 17 | var inspectCmd = &cobra.Command{ 18 | Use: "inspect", 19 | Short: "Get container detail", 20 | Run: func(cmd *cobra.Command, args []string) { 21 | id, err := cmd.Flags().GetString("id") 22 | if err != nil { 23 | log.Fatal(err) 24 | } 25 | s := docker.ProvideService() 26 | details, err := s.Get(id) 27 | if err != nil { 28 | log.Fatal(err) 29 | } 30 | detailString, err := json.Marshal(details) 31 | if err != nil { 32 | fmt.Println(err) 33 | } 34 | fmt.Println(string(detailString)) 35 | }, 36 | } 37 | 38 | func init() { 39 | rootCmd.AddCommand(inspectCmd) 40 | 41 | inspectCmd.Flags().String("id", "", "Help message for toggle") 42 | 43 | } 44 | -------------------------------------------------------------------------------- /gocker/cmd/ps.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2022 NAME HERE 3 | 4 | */ 5 | package cmd 6 | 7 | import ( 8 | "fmt" 9 | "gocker/pkg/docker" 10 | "log" 11 | "os" 12 | 13 | "github.com/jedib0t/go-pretty/v6/table" 14 | "github.com/spf13/cobra" 15 | ) 16 | 17 | // psCmd represents the ps command 18 | var psCmd = &cobra.Command{ 19 | Use: "ps", 20 | Short: "List containers", 21 | Run: func(cmd *cobra.Command, args []string) { 22 | all, err := cmd.Flags().GetBool("all") 23 | if err != nil { 24 | log.Fatal(err) 25 | } 26 | s := docker.ProvideService() 27 | 28 | containers, err := s.List() 29 | if all { 30 | containers, err = s.ListAll() 31 | } 32 | 33 | if err != nil { 34 | log.Fatal(err) 35 | } 36 | t := table.NewWriter() 37 | t.SetOutputMirror(os.Stdout) 38 | t.AppendHeader(table.Row{"#", "CONTAINER ID", "IMAGE", "CREATED", "STATUS"}) 39 | 40 | for i, container := range containers { 41 | t.AppendRows([]table.Row{ 42 | { 43 | converInterface(fmt.Sprintf("%d", i)), 44 | converInterface(container.ID[0:12]), 45 | converInterface(container.Image), 46 | converInterface(fmt.Sprintf("%d", container.Created)), 47 | converInterface(container.Status), 48 | }, 49 | }) 50 | 51 | } 52 | t.AppendSeparator() 53 | t.Render() 54 | }, 55 | } 56 | 57 | func init() { 58 | rootCmd.AddCommand(psCmd) 59 | psCmd.Flags().BoolP("all", "a", false, "gocker ps --all") 60 | } 61 | 62 | func converInterface(variable string) (a interface{}) { 63 | a = variable 64 | return 65 | } 66 | -------------------------------------------------------------------------------- /gocker/cmd/root.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2022 NAME HERE 3 | 4 | */ 5 | package cmd 6 | 7 | import ( 8 | "os" 9 | 10 | "github.com/spf13/cobra" 11 | ) 12 | 13 | 14 | 15 | // rootCmd represents the base command when called without any subcommands 16 | var rootCmd = &cobra.Command{ 17 | Use: "gocker", 18 | Short: "A brief description of your application", 19 | Long: `A longer description that spans multiple lines and likely contains 20 | examples and usage of using your application. For example: 21 | 22 | Cobra is a CLI library for Go that empowers applications. 23 | This application is a tool to generate the needed files 24 | to quickly create a Cobra application.`, 25 | // Uncomment the following line if your bare application 26 | // has an action associated with it: 27 | // Run: func(cmd *cobra.Command, args []string) { }, 28 | } 29 | 30 | // Execute adds all child commands to the root command and sets flags appropriately. 31 | // This is called by main.main(). It only needs to happen once to the rootCmd. 32 | func Execute() { 33 | err := rootCmd.Execute() 34 | if err != nil { 35 | os.Exit(1) 36 | } 37 | } 38 | 39 | func init() { 40 | // Here you will define your flags and configuration settings. 41 | // Cobra supports persistent flags, which, if defined here, 42 | // will be global for your application. 43 | 44 | // rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.gocker.yaml)") 45 | 46 | // Cobra also supports local flags, which will only run 47 | // when this action is called directly. 48 | rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") 49 | } 50 | 51 | 52 | -------------------------------------------------------------------------------- /gocker/go.mod: -------------------------------------------------------------------------------- 1 | module gocker 2 | 3 | go 1.17 4 | 5 | require ( 6 | github.com/docker/docker v20.10.16+incompatible 7 | github.com/jedib0t/go-pretty/v6 v6.3.1 8 | github.com/spf13/cobra v1.4.0 9 | ) 10 | 11 | require ( 12 | github.com/Microsoft/go-winio v0.5.2 // indirect 13 | github.com/docker/distribution v2.8.1+incompatible // indirect 14 | github.com/docker/go-connections v0.4.0 // indirect 15 | github.com/docker/go-units v0.4.0 // indirect 16 | github.com/gogo/protobuf v1.3.2 // indirect 17 | github.com/inconshreveable/mousetrap v1.0.0 // indirect 18 | github.com/mattn/go-runewidth v0.0.13 // indirect 19 | github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect 20 | github.com/morikuni/aec v1.0.0 // indirect 21 | github.com/opencontainers/go-digest v1.0.0 // indirect 22 | github.com/opencontainers/image-spec v1.0.2 // indirect 23 | github.com/pkg/errors v0.9.1 // indirect 24 | github.com/rivo/uniseg v0.2.0 // indirect 25 | github.com/sirupsen/logrus v1.8.1 // indirect 26 | github.com/spf13/pflag v1.0.5 // indirect 27 | golang.org/x/net v0.0.0-20201021035429-f5854403a974 // indirect 28 | golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 // indirect 29 | golang.org/x/time v0.0.0-20220411224347-583f2d630306 // indirect 30 | gotest.tools/v3 v3.2.0 // indirect 31 | ) 32 | -------------------------------------------------------------------------------- /gocker/go.sum: -------------------------------------------------------------------------------- 1 | github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= 2 | github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= 3 | github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA= 4 | github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= 5 | github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 6 | github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 7 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 8 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 9 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 10 | github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= 11 | github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= 12 | github.com/docker/docker v20.10.16+incompatible h1:2Db6ZR/+FUR3hqPMwnogOPHFn405crbpxvWzKovETOQ= 13 | github.com/docker/docker v20.10.16+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= 14 | github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= 15 | github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= 16 | github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= 17 | github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= 18 | github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= 19 | github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= 20 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 21 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 22 | github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= 23 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 24 | github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= 25 | github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= 26 | github.com/jedib0t/go-pretty/v6 v6.3.1 h1:aOXiD9oqiuLH8btPQW6SfgtQN5zwhyfzZls8a6sPJ/I= 27 | github.com/jedib0t/go-pretty/v6 v6.3.1/go.mod h1:FMkOpgGD3EZ91cW8g/96RfxoV7bdeJyzXPYgz1L1ln0= 28 | github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= 29 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= 30 | github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= 31 | github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= 32 | github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 h1:dcztxKSvZ4Id8iPpHERQBbIJfabdt4wUm5qy3wOL2Zc= 33 | github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= 34 | github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= 35 | github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= 36 | github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= 37 | github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= 38 | github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM= 39 | github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= 40 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 41 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 42 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 43 | github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= 44 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 45 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 46 | github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= 47 | github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= 48 | github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 49 | github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= 50 | github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= 51 | github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= 52 | github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q= 53 | github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= 54 | github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= 55 | github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= 56 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 57 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 58 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 59 | github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= 60 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 61 | github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 62 | github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 63 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 64 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 65 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 66 | golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 67 | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 68 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 69 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 70 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 71 | golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 72 | golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI= 73 | golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 74 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 75 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 76 | golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 77 | golang.org/x/sys v0.0.0-20180816055513-1c9583448a9c/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 78 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 79 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 80 | golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 81 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 82 | golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 83 | golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 84 | golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 h1:RqytpXGR1iVNX7psjB3ff8y7sNFinVFvkx1c8SjBkio= 85 | golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 86 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 87 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 88 | golang.org/x/time v0.0.0-20220411224347-583f2d630306 h1:+gHMid33q6pen7kv9xvT+JRinntgeXO2AeZVd0AWD3w= 89 | golang.org/x/time v0.0.0-20220411224347-583f2d630306/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 90 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 91 | golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 92 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 93 | golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 94 | golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 95 | golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= 96 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 97 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 98 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 99 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 100 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 101 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 102 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= 103 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 104 | gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= 105 | gotest.tools/v3 v3.2.0 h1:I0DwBVMGAx26dttAj1BtJLAkVGncrkkUXfJLC4Flt/I= 106 | gotest.tools/v3 v3.2.0/go.mod h1:Mcr9QNxkg0uMvy/YElmo4SpXgJKWgQvYrT7Kw5RzJ1A= 107 | -------------------------------------------------------------------------------- /gocker/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2022 NAME HERE 3 | 4 | */ 5 | package main 6 | 7 | import "gocker/cmd" 8 | 9 | func main() { 10 | cmd.Execute() 11 | } 12 | -------------------------------------------------------------------------------- /gocker/pkg/docker/docker_test.go: -------------------------------------------------------------------------------- 1 | package docker 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "testing" 7 | ) 8 | 9 | func TestDockerRun(t *testing.T) { 10 | imageName := "mongo:latest" 11 | containerName := fmt.Sprintf("image%d", rand.Int()) 12 | 13 | s := ProvideService() 14 | _, err := s.ImagePull(imageName) 15 | if err != nil { 16 | t.Error(err) 17 | } 18 | 19 | container, err := s.Create(imageName, containerName) 20 | if err != nil { 21 | t.Error(err) 22 | } 23 | 24 | err = s.Start(container.ID) 25 | if err != nil { 26 | t.Error(err) 27 | } 28 | 29 | err = s.ContainerWait(container.ID) 30 | if err != nil { 31 | t.Error(err) 32 | } 33 | } 34 | 35 | func TestDockerList(t *testing.T) { 36 | s := ProvideService() 37 | _, err := s.List() 38 | if err != nil { 39 | t.Error(err) 40 | } 41 | } 42 | 43 | func TestDockerGet(t *testing.T) { 44 | s := ProvideService() 45 | container, err := s.List() 46 | if err != nil { 47 | t.Error(err) 48 | } 49 | _, err = s.Get(container[0].ID) 50 | if err != nil { 51 | t.Error(err) 52 | } 53 | } 54 | 55 | func TestDockerLogs(t *testing.T) { 56 | s := ProvideService() 57 | container, err := s.List() 58 | if err != nil { 59 | t.Error(err) 60 | } 61 | _, err = s.Get(container[0].ID) 62 | if err != nil { 63 | t.Error(err) 64 | } 65 | } 66 | 67 | func TestDockerStop(t *testing.T) { 68 | s := ProvideService() 69 | container, err := s.List() 70 | if err != nil { 71 | t.Error(err) 72 | } 73 | err = s.Stop(container[0].ID) 74 | if err != nil { 75 | t.Error(err) 76 | } 77 | } 78 | 79 | func TestDockerStart(t *testing.T) { 80 | s := ProvideService() 81 | container, err := s.List() 82 | if err != nil { 83 | t.Error(err) 84 | } 85 | err = s.Start(container[0].ID) 86 | if err != nil { 87 | t.Error(err) 88 | } 89 | } 90 | 91 | func TestDockerImageList(t *testing.T) { 92 | s := ProvideService() 93 | _, err := s.ImageList() 94 | if err != nil { 95 | t.Error(err) 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /gocker/pkg/docker/helper.go: -------------------------------------------------------------------------------- 1 | package docker 2 | 3 | import "github.com/docker/docker/client" 4 | 5 | func connect() *client.Client { 6 | cli, err := client.NewClientWithOpts(client.FromEnv) 7 | if err != nil { 8 | panic(err) 9 | } 10 | return cli 11 | } 12 | -------------------------------------------------------------------------------- /gocker/pkg/docker/main.go: -------------------------------------------------------------------------------- 1 | package docker 2 | 3 | func GetService() *Service { 4 | return ProvideService() 5 | } 6 | -------------------------------------------------------------------------------- /gocker/pkg/docker/mapper.go: -------------------------------------------------------------------------------- 1 | package docker 2 | -------------------------------------------------------------------------------- /gocker/pkg/docker/service.go: -------------------------------------------------------------------------------- 1 | package docker 2 | 3 | import ( 4 | "context" 5 | "io" 6 | "os" 7 | 8 | "github.com/docker/docker/api/types" 9 | "github.com/docker/docker/api/types/container" 10 | "github.com/docker/docker/client" 11 | ) 12 | 13 | type IService interface { 14 | List() ([]types.Container, error) 15 | ListAll() ([]types.Container, error) 16 | Get(id string) (types.ContainerJSON, error) 17 | Logs(id string) (io.ReadCloser, error) 18 | Stop(id string) error 19 | Start(id string) error 20 | Create(imageName string, containerName string) (container.ContainerCreateCreatedBody, error) 21 | ImagePull(imageName string) (io.Reader, error) 22 | ImageList() ([]types.ImageSummary, error) 23 | ContainerWait(id string) error 24 | } 25 | 26 | type Service struct { 27 | cli *client.Client 28 | } 29 | 30 | func ProvideService() *Service { 31 | return &Service{ 32 | cli: connect(), 33 | } 34 | } 35 | 36 | // docker ps 37 | func (s *Service) List() ([]types.Container, error) { 38 | return s.cli.ContainerList(context.Background(), types.ContainerListOptions{}) 39 | } 40 | 41 | // docker ps --all 42 | func (s *Service) ListAll() ([]types.Container, error) { 43 | return s.cli.ContainerList(context.Background(), types.ContainerListOptions{All: true}) 44 | } 45 | 46 | // docker inspect 47 | func (s *Service) Get(id string) (types.ContainerJSON, error) { 48 | return s.cli.ContainerInspect(context.Background(), id) 49 | } 50 | 51 | // docker logs 52 | func (s *Service) Logs(id string) (io.ReadCloser, error) { 53 | out, err := s.cli.ContainerLogs(context.Background(), id, types.ContainerLogsOptions{ 54 | ShowStdout: true, 55 | }) 56 | io.Copy(os.Stdout, out) 57 | return out, err 58 | } 59 | 60 | // stop container 61 | func (s *Service) Stop(id string) error { 62 | return s.cli.ContainerStop(context.Background(), id, nil) 63 | } 64 | 65 | //delete container 66 | func (s *Service) Delete(id string) error { 67 | return s.cli.ContainerRemove(context.Background(), id, types.ContainerRemoveOptions{}) 68 | } 69 | 70 | // start container 71 | func (s *Service) Start(id string) error { 72 | return s.cli.ContainerStart(context.Background(), id, types.ContainerStartOptions{}) 73 | } 74 | 75 | // create container 76 | func (s *Service) Create(imageName string, containerName string) (container.ContainerCreateCreatedBody, error) { 77 | return s.cli.ContainerCreate(context.Background(), &container.Config{ 78 | Image: imageName, 79 | }, nil, nil, nil, containerName) 80 | 81 | } 82 | 83 | // pull image 84 | func (s *Service) ImagePull(imageName string) (io.Reader, error) { 85 | out, err := s.cli.ImagePull(context.Background(), imageName, types.ImagePullOptions{}) 86 | io.Copy(os.Stdout, out) 87 | return out, err 88 | } 89 | 90 | // image list 91 | func (s *Service) ImageList() ([]types.ImageSummary, error) { 92 | return s.cli.ImageList(context.Background(), types.ImageListOptions{}) 93 | } 94 | 95 | // container wait 96 | func (s *Service) ContainerWait(id string) error { 97 | statusCh, errCh := s.cli.ContainerWait(context.Background(), id, container.WaitConditionNotRunning) 98 | select { 99 | case err := <-errCh: 100 | if err != nil { 101 | return err 102 | } 103 | case <-statusCh: 104 | return nil 105 | } 106 | return nil 107 | } 108 | --------------------------------------------------------------------------------