1
+ const { Binary } = require ( 'binary-install-raw' )
1
2
const os = require ( 'os' )
2
3
const chalk = require ( 'chalk' )
3
4
const fetch = require ( 'node-fetch' )
@@ -10,10 +11,12 @@ const HELP = `
10
11
${ chalk . bold ( 'graph test' ) } ${ chalk . dim ( '[options]' ) } ${ chalk . bold ( '<datasource>' ) }
11
12
12
13
${ chalk . dim ( 'Options:' ) }
14
+ -c, --coverage Run the tests in coverage mode. Works with v0.2.1 and above (0.2.2 and above in docker mode).
15
+ -d, --docker Run the tests in a docker container
16
+ -f --force Overwrite folder + file when downloading
13
17
-h, --help Show usage information
18
+ -l, --logs Logs to the console information about the OS, CPU model and download url (debugging purposes)
14
19
-v, --version <tag> Choose the version of the rust binary that you want to be downloaded/used
15
- -c, --coverage Run tests in coverage mode (works with v0.2.2 and above)
16
- -f, --flags <flags>
17
20
`
18
21
19
22
module . exports = {
@@ -23,20 +26,42 @@ module.exports = {
23
26
let { print } = toolbox
24
27
25
28
// Read CLI parameters
26
- let { h, help, v, version, c, coverage } = toolbox . parameters . options
29
+ let {
30
+ c,
31
+ coverage,
32
+ d,
33
+ docker,
34
+ f,
35
+ force,
36
+ h,
37
+ help,
38
+ l,
39
+ logs,
40
+ v,
41
+ version,
42
+ } = toolbox . parameters . options
27
43
28
44
// Support both long and short option variants
45
+ let coverage_opt = coverage || c
46
+ let docker_opt = docker || d
47
+ let force_opt = force || f
29
48
let help_opt = help || h
49
+ let logs_opt = logs || l
30
50
let version_opt = version || v
31
- let coverage_opt = coverage || c
32
51
33
- // Fix if a boolean flag (-h, --help, -c, --coverage) has an argument
52
+ // Fix if a boolean flag (e.g -c, --coverage) has an argument
34
53
try {
35
54
fixParameters ( toolbox . parameters , {
36
55
h,
37
56
help,
38
57
c,
39
58
coverage,
59
+ d,
60
+ docker,
61
+ f,
62
+ force,
63
+ l,
64
+ logs
40
65
} )
41
66
} catch ( e ) {
42
67
print . error ( e . message )
@@ -52,117 +77,174 @@ module.exports = {
52
77
return
53
78
}
54
79
55
- if ( version_opt ) {
56
- let url = `https://github.com/LimeChain/matchstick/releases/download/${ version_opt || "0.2.2a" } /binary-linux-20` ;
80
+ if ( docker_opt ) {
81
+ runDocker ( coverage_opt , datasource , version_opt )
82
+ } else {
83
+ runBinary ( coverage_opt , datasource , force_opt , logs_opt , version_opt )
84
+ }
85
+ }
86
+ }
87
+
88
+ async function runBinary ( coverage_opt , datasource , force_opt , logs_opt , version_opt ) {
89
+ const platform = getPlatform ( logs_opt )
90
+
91
+ if ( ! version_opt ) {
92
+ let result = await fetch ( 'https://api.github.com/repos/LimeChain/matchstick/releases/latest' )
93
+ let json = await result . json ( )
94
+ version_opt = json . tag_name
95
+ }
96
+
97
+ const url = `https://github.com/LimeChain/matchstick/releases/download/${ version_opt } /${ platform } `
98
+
99
+ if ( logs_opt ) {
100
+ console . log ( `Download link: ${ url } ` )
101
+ }
57
102
58
- await fetch ( url )
59
- . then ( response => {
60
- if ( response . status === 404 ) {
61
- print . info ( `Error: Invalid Matchstick version '${ version_opt } '` ) ;
62
- process . exit ( 1 ) ;
63
- }
64
- } )
103
+ let binary = new Binary ( platform , url , version_opt )
104
+ force_opt ? await binary . install ( true ) : await binary . install ( false )
105
+ let args = ""
106
+
107
+ if ( datasource ) { args = datasource }
108
+ if ( coverage_opt ) { args = args + ' -c' }
109
+ args !== '' ? binary . run ( args . trim ( ) ) : binary . run ( )
110
+ }
111
+
112
+ function getPlatform ( logs_opt ) {
113
+ const type = os . type ( )
114
+ const arch = os . arch ( )
115
+ const release = os . release ( )
116
+ const cpuCore = os . cpus ( ) [ 0 ]
117
+ const majorVersion = semver . major ( release )
118
+ const isM1 = cpuCore . model . includes ( "Apple M1" )
119
+
120
+ if ( logs_opt ) {
121
+ console . log ( `OS type: ${ type } \nOS arch: ${ arch } \nOS release: ${ release } \nOS major version: ${ majorVersion } \nCPU model: ${ cpuCore . model } ` )
122
+ }
123
+
124
+ if ( arch === 'x64' || ( arch === 'arm64' && isM1 ) ) {
125
+ if ( type === 'Darwin' ) {
126
+ if ( majorVersion === 19 ) {
127
+ return 'binary-macos-10.15'
128
+ } else if ( majorVersion === 18 ) {
129
+ return 'binary-macos-10.14'
130
+ } else if ( isM1 ) {
131
+ return 'binary-macos-11-m1'
132
+ }
133
+ return 'binary-macos-11'
134
+ } else if ( type === 'Linux' ) {
135
+ if ( majorVersion === 18 ) {
136
+ return 'binary-linux-18'
137
+ }
138
+ return 'binary-linux-20'
139
+ } else if ( type === 'Windows_NT' ) {
140
+ return 'binary-windows'
65
141
}
142
+ }
66
143
67
- // TODO: Move these in separate file (in a function maybe)
68
- let contents = `# I'll try to run it on alpine
69
- FROM ubuntu:20.04
144
+ throw new Error ( `Unsupported platform: ${ type } ${ arch } ${ majorVersion } ` )
145
+ }
70
146
71
- # Not sure if this ENV declaration is necessary
72
- ENV ARGS=""
147
+ function runDocker ( coverage_opt , datasource , version_opt ) {
148
+ fs . rmSync ( "node_modules/binary-install-raw/bin" , { force : true , recursive : true } ) ;
73
149
74
- # Install necessary packages
75
- RUN apt update
76
- RUN apt install -y nodejs
77
- RUN apt install -y npm
78
- RUN apt install -y git
79
- RUN apt install -y postgresql
80
- RUN apt install -y curl
81
- RUN npm install -g @graphprotocol/graph-cli
150
+ let dir = 'tests/.docker' ;
82
151
83
- # Download the latest linux binary
84
- RUN curl -OL https://github.com/LimeChain/matchstick/releases/download/${ version_opt || "0.2.2a" } /binary-linux-20
85
- # Make it executable
86
- RUN chmod a+x binary-linux-20
152
+ if ( ! fs . existsSync ( dir ) ) {
153
+ fs . mkdirSync ( dir , { recursive : true } ) ;
154
+ }
87
155
88
- # Create a matchstick dir where the host will be copied
89
- RUN mkdir matchstick
90
- WORKDIR matchstick
156
+ fs . writeFileSync ( 'tests/.docker/Dockerfile' , dockerfile ( version_opt ) , ( err ) => {
157
+ if ( err ) {
158
+ print . info ( 'A problem occurred while generating the Dockerfile. Please attend to the errors below.' ) ;
159
+ print . info ( err ) ;
160
+ }
161
+ else {
162
+ print . info ( 'Successfully generated Dockerfile.' )
163
+ }
164
+ } )
91
165
92
- # Copy host to /matchstick
93
- COPY ../ .
166
+ // Run a command to check if matchstick image already exists
167
+ exec ( 'docker images -q matchstick' , ( error , stdout , stderr ) => {
168
+ // Getting the current working folder that will be passed to the
169
+ // `docker run` command to be bind mounted.
170
+ let current_folder = process . cwd ( ) ;
171
+ let test_args = '' ;
94
172
95
- RUN graph codegen
96
- RUN graph build
173
+ if ( datasource ) {
174
+ test_args = test_args + datasource
175
+ }
97
176
98
- CMD ../binary-linux-20 \${ARGS}
99
- `
177
+ if ( coverage_opt ) {
178
+ test_args = test_args + ' ' + '-c'
179
+ }
100
180
101
- let dir = 'tests/.docker' ;
181
+ let docker_run_opts = [ 'run' , '-it' , '--rm' , '--mount' , `type=bind,source= ${ current_folder } ,target=/matchstick` ] ;
102
182
103
- if ( ! fs . existsSync ( dir ) ) {
104
- fs . mkdirSync ( dir , { recursive : true } ) ;
183
+ if ( test_args !== '' ) {
184
+ docker_run_opts . push ( '-e' )
185
+ docker_run_opts . push ( `ARGS=${ test_args . trim ( ) } ` ) ;
105
186
}
106
187
107
- fs . writeFileSync ( 'tests/.docker/Dockerfile' , contents , ( err ) => {
108
- if ( err ) {
109
- print . info ( 'A problem occurred while generating the Dockerfile. Please attend to the errors below.' ) ;
110
- print . info ( err ) ;
111
- }
112
- else {
113
- print . info ( 'Successfully generated Dockerfile.' )
188
+ docker_run_opts . push ( 'matchstick' )
189
+
190
+ // If a matchstick image does not exists, the command returns an empty string,
191
+ // else it'll return the image ID. Skip `docker build` if an image already exists
192
+ // If `-v/--version` is specified, delete current image(if any) and rebuild.
193
+ // Use spawn() and {stdio: 'inherit'} so we can see the logs in real time.
194
+ if ( stdout === '' || version_opt ) {
195
+ if ( stdout !== '' && version_opt ) {
196
+ exec ( 'docker image rm matchstick' , ( error , stdout , stderr ) => {
197
+ print . info ( chalk . bold ( `Removing matchstick image\n${ stdout } ` ) ) ;
198
+ } ) ;
114
199
}
115
- } )
200
+ // Build a docker image. If the process has executed successfully
201
+ // run a container from that image.
202
+ spawn (
203
+ 'docker' ,
204
+ [ 'build' , '-f' , 'tests/.docker/Dockerfile' , '-t' , 'matchstick' , '.' ] ,
205
+ { stdio : 'inherit' }
206
+ ) . on ( 'close' , code => {
207
+ if ( code === 0 ) {
208
+ spawn ( 'docker' , docker_run_opts , { stdio : 'inherit' } ) ;
209
+ }
210
+ } )
211
+ } else {
212
+ // Run the container from the existing matchstick docker image
213
+ spawn ( 'docker' , docker_run_opts , { stdio : 'inherit' } ) ;
214
+ }
215
+ } )
216
+ }
116
217
117
- // Run a command to check if matchstick image already exists
118
- exec ( 'docker images -q matchstick' , ( error , stdout , stderr ) => {
119
- // Getting the current working folder that will be passed to the
120
- // `docker run` command to be bind mounted.
121
- let current_folder = process . cwd ( ) ;
122
- let test_args = '' ;
218
+ // TODO: Move these in separate file (in a function maybe)
219
+ function dockerfile ( version_opt ) {
220
+ return `
221
+ FROM ubuntu:20.04
222
+ ENV ARGS=""
123
223
124
- if ( datasource ) {
125
- test_args = test_args + datasource
126
- }
224
+ # Install necessary packages
225
+ RUN apt update
226
+ RUN apt install -y nodejs
227
+ RUN apt install -y npm
228
+ RUN apt install -y git
229
+ RUN apt install -y postgresql
230
+ RUN apt install -y curl
231
+ RUN npm install -g @graphprotocol/graph-cli
127
232
128
- if ( coverage_opt ) {
129
- test_args = test_args + ' ' + '-c'
130
- }
233
+ # Download the latest linux binary
234
+ RUN curl -OL https://github.com/LimeChain/matchstick/releases/download/${ version_opt || "0.2.2a" } /binary-linux-20
131
235
132
- let docker_run_opts = [ 'run' , '-it' , '--rm' , '--mount' , `type=bind,source=${ current_folder } ,target=/matchstick` ] ;
236
+ # Make it executable
237
+ RUN chmod a+x binary-linux-20
133
238
134
- if ( test_args !== '' ) {
135
- docker_run_opts . push ( '-e' )
136
- docker_run_opts . push ( `ARGS=${ test_args . trim ( ) } ` ) ;
137
- }
239
+ # Create a matchstick dir where the host will be copied
240
+ RUN mkdir matchstick
241
+ WORKDIR matchstick
138
242
139
- docker_run_opts . push ( 'matchstick' )
140
-
141
- // If a matchstick image does not exists, the command returns an empty string,
142
- // else it'll return the image ID. Skip `docker build` if an image already exists
143
- // If `-v/--version` is specified, delete current image(if any) and rebuild.
144
- // Use spawn() and {stdio: 'inherit'} so we can see the logs in real time.
145
- if ( stdout === '' || version_opt ) {
146
- if ( stdout !== '' && version_opt ) {
147
- exec ( 'docker image rm matchstick' , ( error , stdout , stderr ) => {
148
- print . info ( chalk . bold ( `Removing matchstick image\n${ stdout } ` ) ) ;
149
- } ) ;
150
- }
151
- // Build a docker image. If the process has executed successfully
152
- // run a container from that image.
153
- spawn (
154
- 'docker' ,
155
- [ 'build' , '-f' , 'tests/.docker/Dockerfile' , '-t' , 'matchstick' , '.' ] ,
156
- { stdio : 'inherit' }
157
- ) . on ( 'close' , code => {
158
- if ( code === 0 ) {
159
- spawn ( 'docker' , docker_run_opts , { stdio : 'inherit' } ) ;
160
- }
161
- } )
162
- } else {
163
- // Run the container from the existing matchstick docker image
164
- spawn ( 'docker' , docker_run_opts , { stdio : 'inherit' } ) ;
165
- }
166
- } )
167
- } ,
243
+ # Copy host to /matchstick
244
+ COPY ../ .
245
+
246
+ RUN graph codegen
247
+ RUN graph build
248
+
249
+ CMD ../binary-linux-20 \${ARGS}`
168
250
}
0 commit comments