-
Notifications
You must be signed in to change notification settings - Fork 0
/
run.go
152 lines (133 loc) · 2.96 KB
/
run.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package main
import (
"errors"
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
"path/filepath"
"runtime"
)
func main() {
args := os.Args[1:]
os.Exit(command(args))
}
func runDir() string {
path := os.Getenv("GORUNDIR")
if len(path) == 0 {
path = os.Getenv("GOPATH")
if len(path) == 0 {
fmt.Println("GORUNDIR or GOPATH environment variable needs to be set to scripts directory")
os.Exit(1)
}
path = filepath.Join(path, "src")
}
return path
}
func command(args []string) int {
if len(args) < 1 {
fmt.Println("Add the name of the package in the run folder you want to run,\n" +
"or run 'run {packagename} new'. ")
return 1
}
var pkg = args[0]
dir, bin, err := findPackageFolder(pkg)
if err != nil {
if len(args) > 1 && args[1] == "new" {
err := newPackage(args[0])
if err != nil {
fmt.Println(err)
return 1
}
return 0
}
fmt.Println(err)
return 1
}
err = runCmd(dir, "go", "install")
if err != nil {
fmt.Println(err)
return 1
}
err = runCmd(".", append([]string{bin}, args[1:]...)...)
if err != nil {
fmt.Println(err)
}
return 0
}
func findPackageFolder(in string) (pkg string, bin string, err error) {
// convert to absolute path (if necessary)
dir, err := filepath.Abs(in)
if err != nil {
return "", "", err
}
// get package name from absolute path (also works if in is ".")
bin = filepath.Base(dir)
// check if path exists and contains go files
info, err := os.Stat(dir)
if err == nil && info.IsDir() {
if !containsGoFiles(dir) {
return "", "", fmt.Errorf("%s does not contain any go files", dir)
}
return dir, bin, nil
}
// try package name in gorundir
dir = filepath.Join(runDir(), in)
info, err = os.Stat(dir)
if err == nil && info.IsDir() {
if !containsGoFiles(dir) {
return "", "", fmt.Errorf("%s does not contain any go files", dir)
}
return dir, bin, nil
}
// no package found
return "", "", fmt.Errorf(`couldn't find the source folder for package %s (create it with "run %s new")`,
in, in)
}
func containsGoFiles(path string) bool {
files, err := ioutil.ReadDir(path)
if err != nil {
log.Fatal(err)
}
for _, f := range files {
if filepath.Ext(f.Name()) == ".go" {
return true
}
}
return false
}
func runCmd(dir string, cmd ...string) error {
c := exec.Command(cmd[0], cmd[1:]...)
c.Dir = dir
c.Stdout = os.Stdout
c.Stderr = os.Stderr
c.Stdin = os.Stdin
return c.Run()
}
var content = `package main
func main() {
}`
func newPackage(name string) error {
path := runDir()
dir := filepath.Join(path, name)
file := filepath.Join(path, name, name+".go")
info, err := os.Stat(file)
if err == nil && !info.IsDir() {
return errors.New(fmt.Sprint("The file ", file, " already exists, doing nothing."))
}
err = os.MkdirAll(dir, 0755)
if err != nil {
return err
}
err = ioutil.WriteFile(file, []byte(content), 0644)
if err != nil {
return err
}
if runtime.GOOS == "darwin" {
runCmd("/", "open", file)
} else {
runCmd("/", "xdg-open", file)
}
return nil
}