├── LICENSE ├── README.md ├── go.mod ├── go.sum └── gommand.go /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 sno6 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gommand 2 | 3 | Go one liner program similar to python -c 4 | 5 | ## How can I get it? 6 | 7 | ``` 8 | go install github.com/sno6/gommand@latest 9 | ``` 10 | 11 | ## Examples 12 | 13 | Write any Go code in a single line context, gommand will handle your imports and main function for you. 14 | 15 | ```gommand 'fmt.Println("Hello gommand")'``` 16 | 17 | You could also quickly serve your current directory in one line. 18 | 19 | ```gommand 'http.Handle("/", http.FileServer(http.Dir("."))); fmt.Println(http.ListenAndServe(":8080", nil))'``` 20 | 21 | Quickly find the date. 22 | 23 | ```gommand 'fmt.Println(time.Now())'``` 24 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/sno6/gommand 2 | 3 | go 1.19 4 | 5 | require golang.org/x/tools v0.5.0 6 | 7 | require ( 8 | golang.org/x/mod v0.7.0 // indirect 9 | golang.org/x/sys v0.4.0 // indirect 10 | ) 11 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= 2 | golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 3 | golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= 4 | golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 5 | golang.org/x/tools v0.5.0 h1:+bSpV5HIeWkuvgaMfI3UmKRThoTA5ODJTUd8T17NO+4= 6 | golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= 7 | -------------------------------------------------------------------------------- /gommand.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "log" 7 | "os" 8 | "os/exec" 9 | "os/signal" 10 | 11 | "golang.org/x/tools/imports" 12 | ) 13 | 14 | func run(fileName string) error { 15 | cmd := exec.Command("go", "run", fileName) 16 | cmd.Stdin = os.Stdin 17 | cmd.Stdout = os.Stdout 18 | cmd.Stderr = os.Stderr 19 | return cmd.Run() 20 | } 21 | 22 | func tempFile() (*os.File, error) { 23 | curDir, err := os.Getwd() 24 | if err != nil { 25 | return nil, err 26 | } 27 | file, err := ioutil.TempFile(curDir, "temp") 28 | if err != nil { 29 | return nil, err 30 | } 31 | file.Close() 32 | 33 | // Add the .go suffix to the temp file. 34 | if err = os.Rename(file.Name(), file.Name()+".go"); err != nil { 35 | return nil, err 36 | } 37 | return os.Open(file.Name() + ".go") 38 | } 39 | 40 | func editImports(fileName string) error { 41 | data, err := ioutil.ReadFile(fileName) 42 | if err != nil { 43 | return err 44 | } 45 | 46 | // res holds the go file re-written with imports added. 47 | opt := &imports.Options{} 48 | res, err := imports.Process(fileName, data, opt) 49 | if err != nil { 50 | return err 51 | } 52 | return ioutil.WriteFile(fileName, res, 0644) 53 | } 54 | 55 | func usage() { 56 | fmt.Fprintln(os.Stderr, "Usage: gommand [code]") 57 | os.Exit(2) 58 | } 59 | 60 | func clean(f *os.File) { 61 | f.Close() 62 | if err := os.Remove(f.Name()); err != nil { 63 | log.Printf("main: error removing tempfile: %v\n", err) 64 | } 65 | } 66 | 67 | func main() { 68 | if len(os.Args) < 2 { 69 | usage() 70 | } 71 | code := os.Args[1] 72 | if code == "" { 73 | usage() 74 | } 75 | 76 | file, err := tempFile() 77 | if err != nil { 78 | log.Fatalf("main: error creating temp file: %v\n", err) 79 | } 80 | defer clean(file) 81 | 82 | c := make(chan os.Signal, 1) 83 | signal.Notify(c, os.Interrupt) 84 | 85 | go func() { 86 | <-c 87 | clean(file) 88 | os.Exit(1) 89 | }() 90 | 91 | // bp holds the go boiler plate code with user code added. 92 | bp := fmt.Sprintf("package main\nfunc main() {\n\t%v\n}", code) 93 | 94 | // Write go code to temp file and add missing imports. 95 | // Use Printf over Fatalf so removing of temp file will run through defer. 96 | if err = ioutil.WriteFile(file.Name(), []byte(bp), 0644); err != nil { 97 | log.Printf("main: error writing code to temp file: %v\n", err) 98 | } 99 | if err = editImports(file.Name()); err != nil { 100 | log.Printf("main: error editing imports: %v\n", err) 101 | } 102 | if err = run(file.Name()); err != nil { 103 | log.Printf("main: error running go code query: %v\n", err) 104 | } 105 | } 106 | --------------------------------------------------------------------------------