@@ -2,6 +2,7 @@ package matr
2
2
3
3
import (
4
4
"bytes"
5
+ "crypto/sha256"
5
6
"errors"
6
7
"flag"
7
8
"fmt"
@@ -22,51 +23,66 @@ var (
22
23
matrFilePath string
23
24
helpFlag bool
24
25
versionFlag bool
26
+ cleanFlag bool
27
+ noCacheFlag bool
25
28
)
26
29
27
30
// Run is the primary entrypoint to matrs cli tool.
28
31
// This is where the matrfile path is resolved, compiled and executed
29
32
func Run () {
30
33
// TODO: clean up this shit show
31
- flag .StringVar (& matrFilePath , "matrfile" , "./" , "path to Matrfile" )
32
- flag .BoolVar (& helpFlag , "h" , false , "Display usage info" )
33
- flag .BoolVar (& versionFlag , "v" , false , "Display version" )
34
- flag .Parse ()
35
- if versionFlag {
36
- fmt .Println (Version )
37
- return
34
+ // create a new flagset
35
+ fs := flag .NewFlagSet ("matr" , flag .ExitOnError )
36
+ fs .StringVar (& matrFilePath , "matrfile" , "./Matrfile.go" , "path to Matrfile" )
37
+ fs .BoolVar (& cleanFlag , "clean" , false , "clean the matr cache" )
38
+ fs .BoolVar (& helpFlag , "h" , false , "Display usage info" )
39
+ fs .BoolVar (& versionFlag , "v" , false , "Display version" )
40
+ fs .BoolVar (& noCacheFlag , "no-cache" , false , "Don't use the matr cache" )
41
+ if err := fs .Parse (os .Args [1 :]); err != nil {
42
+ fmt .Println (err )
43
+ os .Exit (1 )
44
+ }
45
+
46
+ if cleanFlag {
47
+ if err := clean (matrFilePath ); err != nil {
48
+ fmt .Println (err )
49
+ os .Exit (1 )
50
+ }
51
+ os .Exit (0 )
38
52
}
39
53
40
- args := flag .Args ()
41
-
42
54
if helpFlag {
43
- args = append ([] string { "-h" }, args ... )
55
+ fs . Usage ( )
44
56
}
45
57
46
- cmds , err := parseMatrfile (matrFilePath )
47
- if err != nil {
48
- flag .Usage ()
49
- if helpFlag && flag .Arg (0 ) == "" {
50
- fmt .Print ("\n Targets:\n No Matrfile.go or Matrfile found\n " )
51
- return
52
- }
53
-
54
- fmt .Print ("\n " + err .Error () + "\n " )
58
+ if versionFlag {
59
+ fmt .Printf ("\n matr version: %s\n \n " , Version )
55
60
return
56
61
}
57
62
58
- matrCachePath , err := build (matrFilePath , cmds )
63
+ matrCachePath , err := build (matrFilePath , noCacheFlag )
59
64
if err != nil {
65
+ fs .Usage ()
60
66
os .Stderr .WriteString (err .Error () + "\n " )
61
67
return
62
68
}
63
69
64
- if err := run (matrCachePath , args ... ); err != nil {
70
+ if err := run (matrCachePath , fs . Args () ... ); err != nil {
65
71
os .Stderr .WriteString (err .Error () + "\n " )
66
72
return
67
73
}
68
74
}
69
75
76
+ func clean (matrfilePath string ) error {
77
+ matrfilePath , err := getMatrfilePath (matrfilePath )
78
+ if err != nil {
79
+ return err
80
+ }
81
+
82
+ cachePath := filepath .Join (filepath .Dir (matrfilePath ), defaultCacheFolder )
83
+ return os .RemoveAll (cachePath )
84
+ }
85
+
70
86
func parseMatrfile (path string ) ([]parser.Command , error ) {
71
87
var err error
72
88
var cmds []parser.Command
@@ -96,38 +112,65 @@ func run(matrCachePath string, args ...string) error {
96
112
return c .Run ()
97
113
}
98
114
99
- func build (matrFilePath string , cmds []parser.Command ) (string , error ) {
100
- var b bytes.Buffer
115
+ func build (matrFilePath string , noCache bool ) (string , error ) {
116
+ // get absolute path to matrfile
117
+ matrFilePath , err := filepath .Abs (matrFilePath )
118
+ if err != nil {
119
+ return "" , err
120
+ }
121
+
122
+ matrCachePath := filepath .Join (filepath .Dir (matrFilePath ), ".matr" )
101
123
102
- matrPath , matrFile := filepath .Split (matrFilePath )
103
- matrCachePath := filepath .Join (matrPath , ".matr" )
124
+ // check if the matrfile has changed
125
+ newHash , err := getSha256 (matrFilePath )
126
+ if err != nil {
127
+ return "" , err
128
+ }
104
129
130
+ // read the hash from the matrfileSha256 file
131
+ oldHash , err := os .ReadFile (filepath .Join (matrCachePath , "matrfile.sha256" ))
132
+ if err == nil && ! noCache {
133
+ // if the hash is the same, we can skip the build
134
+ if ok := bytes .Equal (oldHash , newHash ); ok {
135
+ return matrCachePath , nil
136
+ }
137
+ }
138
+
139
+ // check if the cache folder exists
105
140
if dir , err := os .Stat (matrCachePath ); err != nil || ! dir .IsDir () {
106
141
if err := os .Mkdir (matrCachePath , 0777 ); err != nil {
107
142
return "" , err
108
143
}
109
144
}
110
145
111
- f , err := os . OpenFile ( filepath . Join ( matrCachePath , "main.go" ), os . O_RDWR | os . O_CREATE | os . O_TRUNC , 0755 )
112
- if err != nil {
146
+ // if the file doesn't exist, create it
147
+ if err := os . WriteFile ( filepath . Join ( matrCachePath , "matrfile.sha256" ), [] byte ( newHash ), 0644 ); err != nil {
113
148
return "" , err
114
149
}
115
- defer f .Close ()
116
150
117
151
if ! symlinkValid (matrCachePath ) {
118
152
os .Remove (filepath .Join (matrCachePath , defaultMatrFile ))
119
- if err := os .Symlink (filepath . Join ( matrPath , matrFile ) , filepath .Join (matrCachePath , defaultMatrFile )); err != nil {
153
+ if err := os .Symlink (matrFilePath , filepath .Join (matrCachePath , defaultMatrFile )); err != nil {
120
154
if os .IsExist (err ) {
121
155
return "" , err
122
156
}
123
157
}
124
158
}
125
159
126
- if err := generate (cmds , & b ); err != nil {
160
+ // create the main.go file in the matr cache folder
161
+ // for the generated code to write to
162
+ f , err := os .OpenFile (filepath .Join (matrCachePath , "main.go" ), os .O_RDWR | os .O_CREATE | os .O_TRUNC , 0755 )
163
+ if err != nil {
127
164
return "" , err
128
165
}
166
+ defer f .Close ()
129
167
130
- if _ , err := io .Copy (f , & b ); err != nil {
168
+ cmds , err := parseMatrfile (matrFilePath )
169
+ if err != nil {
170
+ return "" , err
171
+ }
172
+
173
+ if err := generate (cmds , f ); err != nil {
131
174
return "" , err
132
175
}
133
176
@@ -141,6 +184,20 @@ func build(matrFilePath string, cmds []parser.Command) (string, error) {
141
184
return matrCachePath , cmd .Run ()
142
185
}
143
186
187
+ func getSha256 (path string ) ([]byte , error ) {
188
+ f , err := os .Open (path )
189
+ if err != nil {
190
+ return nil , err
191
+ }
192
+
193
+ h := sha256 .New ()
194
+ if _ , err := io .Copy (h , f ); err != nil {
195
+ return nil , err
196
+ }
197
+
198
+ return h .Sum (nil ), nil
199
+ }
200
+
144
201
func getMatrfilePath (matrFilePath string ) (string , error ) {
145
202
matrFilePath , err := filepath .Abs (matrFilePath )
146
203
if err != nil {
0 commit comments