@@ -9,10 +9,16 @@ const VERSIONS_JSON = 'https://ziglang.org/download/index.json';
9
9
const MACH_VERSIONS_JSON = 'https://pkg.machengine.org/zig/index.json' ;
10
10
const CACHE_PREFIX = "setup-zig-global-cache-" ;
11
11
12
+ // The following regexes pull specific values out of ZON.
13
+ // This is bad and should be replaced with an actual parser -- see #50.
14
+
12
15
// Mach uses `mach_zig_version` in `build.zig.zon` to signify Mach nominated versions.
13
16
// See: https://github.com/marler8997/anyzig?tab=readme-ov-file#mach-versions-and-download-mirror
14
17
const MACH_ZIG_VERSION_REGEX = / \. \s * m a c h _ z i g _ v e r s i o n \s * = \s * " ( .* ?) " / ;
15
18
const MINIMUM_ZIG_VERSION_REGEX = / \. \s * m i n i m u m _ z i g _ v e r s i o n \s * = \s * " ( .* ?) " / ;
19
+ // This is tied quite precisely to the output of `zig env`. It's just a temporary workaround until
20
+ // I get around to implementing a ZON parser here.
21
+ const ZIG_ENV_CACHE_DIR_REGEX = / ^ \s * \. g l o b a l _ c a c h e _ d i r = " ( .* ) " , $ / m;
16
22
17
23
let _cached_version = null ;
18
24
async function getVersion ( ) {
@@ -200,15 +206,46 @@ async function getCachePrefix() {
200
206
}
201
207
202
208
async function getZigCachePath ( ) {
203
- let env_output = '' ;
204
- await exec . exec ( 'zig' , [ 'env' ] , {
205
- listeners : {
206
- stdout : ( data ) => {
207
- env_output += data . toString ( ) ;
208
- } ,
209
- } ,
210
- } ) ;
211
- return JSON . parse ( env_output ) [ 'global_cache_dir' ] ;
209
+ const env_zon = ( await exec . getExecOutput ( 'zig' , [ 'env' ] ) ) . stdout ;
210
+ if ( env_zon [ 0 ] !== '.' ) {
211
+ // JSON (legacy)
212
+ return JSON . parse ( env_zon ) [ 'global_cache_dir' ] ;
213
+ }
214
+ const match = ZIG_ENV_CACHE_DIR_REGEX . exec ( env_zon ) ;
215
+ if ( ! match ) throw new Error ( "Failed to parse cache directory from 'zig env' output" ) ;
216
+ return parseZigString ( match [ 1 ] ) ;
217
+ }
218
+ function parseZigString ( raw ) {
219
+ // This function is neither complete (Unicode codepoint literals), nor correct (byte-escapes
220
+ // aren't really compatible with JS "strings"). It's just a temporary best-effort implementation
221
+ // which can hopefully handle any real-world directory path we encounter.
222
+ let result = "" ;
223
+ let i = 0 ;
224
+ while ( i < raw . length ) {
225
+ if ( raw [ i ] != '\\' ) {
226
+ result += raw [ i ] ;
227
+ i += 1 ;
228
+ continue ;
229
+ }
230
+ i += 2 ;
231
+ switch ( raw [ i - 1 ] ) {
232
+ case 'n' : result += '\n' ; break ;
233
+ case 'r' : result += '\r' ; break ;
234
+ case '\\' : result += '\\' ; break ;
235
+ case 't' : result += '\t' ; break ;
236
+ case '\'' : result += '\'' ; break ;
237
+ case '"' : result += '"' ; break ;
238
+ case 'x' : {
239
+ const byte_val = parseInt ( raw . slice ( i , i + 2 ) , 16 ) ;
240
+ result += String . fromCharCode ( byte_val ) ;
241
+ i += 2 ;
242
+ break ;
243
+ }
244
+ case 'u' : throw new Error ( "unsupported Unicode codepoint literal in string" ) ;
245
+ default : throw new Error ( "invalid escape code in string" ) ;
246
+ }
247
+ }
248
+ return result ;
212
249
}
213
250
214
251
async function getTarballCachePath ( ) {
0 commit comments