@@ -2,6 +2,7 @@ package matr
22
33import (
44 "bytes"
5+ "crypto/sha256"
56 "errors"
67 "flag"
78 "fmt"
@@ -22,51 +23,66 @@ var (
2223 matrFilePath string
2324 helpFlag bool
2425 versionFlag bool
26+ cleanFlag bool
27+ noCacheFlag bool
2528)
2629
2730// Run is the primary entrypoint to matrs cli tool.
2831// This is where the matrfile path is resolved, compiled and executed
2932func Run () {
3033 // 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 )
3852 }
3953
40- args := flag .Args ()
41-
4254 if helpFlag {
43- args = append ([] string { "-h" }, args ... )
55+ fs . Usage ( )
4456 }
4557
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 )
5560 return
5661 }
5762
58- matrCachePath , err := build (matrFilePath , cmds )
63+ matrCachePath , err := build (matrFilePath , noCacheFlag )
5964 if err != nil {
65+ fs .Usage ()
6066 os .Stderr .WriteString (err .Error () + "\n " )
6167 return
6268 }
6369
64- if err := run (matrCachePath , args ... ); err != nil {
70+ if err := run (matrCachePath , fs . Args () ... ); err != nil {
6571 os .Stderr .WriteString (err .Error () + "\n " )
6672 return
6773 }
6874}
6975
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+
7086func parseMatrfile (path string ) ([]parser.Command , error ) {
7187 var err error
7288 var cmds []parser.Command
@@ -96,38 +112,65 @@ func run(matrCachePath string, args ...string) error {
96112 return c .Run ()
97113}
98114
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" )
101123
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+ }
104129
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
105140 if dir , err := os .Stat (matrCachePath ); err != nil || ! dir .IsDir () {
106141 if err := os .Mkdir (matrCachePath , 0777 ); err != nil {
107142 return "" , err
108143 }
109144 }
110145
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 {
113148 return "" , err
114149 }
115- defer f .Close ()
116150
117151 if ! symlinkValid (matrCachePath ) {
118152 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 {
120154 if os .IsExist (err ) {
121155 return "" , err
122156 }
123157 }
124158 }
125159
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 {
127164 return "" , err
128165 }
166+ defer f .Close ()
129167
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 {
131174 return "" , err
132175 }
133176
@@ -141,6 +184,20 @@ func build(matrFilePath string, cmds []parser.Command) (string, error) {
141184 return matrCachePath , cmd .Run ()
142185}
143186
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+
144201func getMatrfilePath (matrFilePath string ) (string , error ) {
145202 matrFilePath , err := filepath .Abs (matrFilePath )
146203 if err != nil {
0 commit comments