-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathmain.igo
127 lines (105 loc) · 2.46 KB
/
main.igo
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
package main
import
"bytes"
"flag"
"fmt"
"os"
"os/exec"
"path"
"path/filepath"
"regexp"
"runtime"
"strconv"
"strings"
"github.com/DAddYE/igo/cmd"
type Cmd int
const
INVALID Cmd = iota
COMPILE
PARSE
BUILD
RUN
TEST
var commands = []string{
COMPILE: "compile",
PARSE: "parse",
BUILD: "build",
RUN: "run",
TEST: "test",
}
func usage()
fmt.Fprintf(os.Stderr, "usage: igo ["+strings.Join(commands[1:], "|")+"] [flags] [path ...]\n")
flag.PrintDefaults()
os.Exit(2)
func toCmd(c string) Cmd
for i, command := range commands
if c == command
return Cmd(i)
return Cmd(0)
func abs(i int) int
switch
case i < 0:
return -i
default:
return i
func parseError(err []byte)
const regex = `^(.*):(\d+):(\d+)?\s*(.*)`
re := regexp.MustCompile(regex)
# Iterate over each error message.
for _, line := range bytes.Split(err, []byte{'\n'})
# if the error message is kind of:
# ./path/name.go:line:col error message
#
match := re.FindAllStringSubmatch(string(line), 4)
if len(match) == 1
file, _ := filepath.Rel("./", match[0][1]) # TODO: check this under chdir
line, _ := strconv.Atoi(match[0][2])
col, _ := strconv.Atoi(match[0][3])
message := match[0][4]
igoFile := strings.TrimSuffix(file, ".go") + ".igo"
if pos := cmd.IgoPositions[igoFile]; pos != nil
var cols []int
for in, out := range *pos
if out.Line == line
cols = append(cols, in.Column)
if len(cols) > 0
closest := abs(cols[0] - col)
for _, c := range cols
if cd := abs(c - col); cd < closest
closest = cd
fmt.Printf("%s:%d:%d %s\n", igoFile, line, closest, message)
else
fmt.Printf("%s:%d:%d %s\n", igoFile, line, col, message)
func main()
flag.Usage = usage
flag.Parse()
var
command Cmd
paths []string
exitCode = 0
for i := 0; i < flag.NArg(); i++
s := flag.Arg(i)
if cmd := toCmd(s); cmd > 0
command = cmd
else
# Could be a path
paths = append(paths, s)
switch command
case PARSE:
exitCode = cmd.To(cmd.IGO, paths)
case COMPILE:
os.Chdir(*cmd.DestDir)
exitCode = cmd.To(cmd.GO, paths)
case BUILD, RUN, TEST:
os.Chdir(*cmd.DestDir)
exitCode = cmd.To(cmd.GO, paths)
if exitCode == 0
gocmd := path.Join(runtime.GOROOT(), "bin", "go")
out, err := exec.Command(gocmd, commands[command]).CombinedOutput()
if err != nil
parseError(out)
exitCode = 1
default:
fmt.Fprintln(os.Stderr, "Invalid command")
usage()
os.Exit(exitCode)