@@ -22,8 +22,8 @@ const os = switch (builtin.os.tag) {
2222 .windows = > "windows" ,
2323 else = > @compileError ("Unsupported OS" ),
2424};
25- const url_platform = os ++ "-" ++ arch ;
26- const json_platform = arch ++ "-" ++ os ;
25+ const os_arch = os ++ "-" ++ arch ;
26+ const arch_os = arch ++ "-" ++ os ;
2727const archive_ext = if (builtin .os .tag == .windows ) "zip" else "tar.xz" ;
2828
2929var global_override_appdata : ? []const u8 = null ; // only used for testing
@@ -605,7 +605,7 @@ fn fetchCompiler(
605605 optional_download_index = try fetchDownloadIndex (allocator , index_url );
606606 const master = optional_download_index .? .json .value .object .get (version_arg ).? ;
607607 const compiler_version = master .object .get ("version" ).? .string ;
608- const master_linux = master .object .get (json_platform ).? ;
608+ const master_linux = master .object .get (arch_os ).? ;
609609 const master_linux_tarball = master_linux .object .get ("tarball" ).? .string ;
610610 break :blk VersionUrl { .version = compiler_version , .url = master_linux_tarball };
611611 };
@@ -1147,10 +1147,114 @@ fn determineVersionKind(version: []const u8) VersionKind {
11471147 return if (std .mem .indexOfAny (u8 , version , "-+" )) | _ | .dev else .release ;
11481148}
11491149
1150+ const SemanticVersionRelease = struct {
1151+ major : usize ,
1152+ minor : usize ,
1153+ patch : usize ,
1154+ pub fn order (a : SemanticVersionRelease , b : SemanticVersionRelease ) std.math.Order {
1155+ if (a .major != b .major ) return std .math .order (a .major , b .major );
1156+ if (a .minor != b .minor ) return std .math .order (a .minor , b .minor );
1157+ return std .math .order (a .patch , b .patch );
1158+ }
1159+ };
1160+
1161+ // The Zig release where the OS-ARCH in the url was swapped to ARCH-OS
1162+ const arch_os_swap_release : SemanticVersionRelease = .{ .major = 0 , .minor = 14 , .patch = 1 };
1163+
1164+ const SemanticVersion = struct {
1165+ const max_pre = 50 ;
1166+ const max_build = 50 ;
1167+ const max_string = 50 + max_pre + max_build ;
1168+
1169+ major : usize ,
1170+ minor : usize ,
1171+ patch : usize ,
1172+ pre : ? std .BoundedArray (u8 , max_pre ),
1173+ build : ? std .BoundedArray (u8 , max_build ),
1174+
1175+ pub fn array (self : * const SemanticVersion ) std.BoundedArray (u8 , max_string ) {
1176+ var result : std .BoundedArray (u8 , max_string ) = undefined ;
1177+ const roundtrip = std .fmt .bufPrint (& result .buffer , "{}" , .{self }) catch unreachable ;
1178+ result .len = roundtrip .len ;
1179+ return result ;
1180+ }
1181+
1182+ pub fn parse (s : []const u8 ) ? SemanticVersion {
1183+ const parsed = std .SemanticVersion .parse (s ) catch | e | switch (e ) {
1184+ error .Overflow , error .InvalidVersion = > return null ,
1185+ };
1186+ std .debug .assert (s .len <= max_string );
1187+
1188+ var result : SemanticVersion = .{
1189+ .major = parsed .major ,
1190+ .minor = parsed .minor ,
1191+ .patch = parsed .patch ,
1192+ .pre = if (parsed .pre ) | pre | std .BoundedArray (u8 , max_pre ).init (pre .len ) catch | e | switch (e ) {
1193+ error .Overflow = > std .debug .panic ("semantic version pre '{s}' is too long (max is {})" , .{ pre , max_pre }),
1194+ } else null ,
1195+ .build = if (parsed .build ) | build | std .BoundedArray (u8 , max_build ).init (build .len ) catch | e | switch (e ) {
1196+ error .Overflow = > std .debug .panic ("semantic version build '{s}' is too long (max is {})" , .{ build , max_build }),
1197+ } else null ,
1198+ };
1199+ if (parsed .pre ) | pre | @memcpy (result .pre .? .slice (), pre );
1200+ if (parsed .build ) | build | @memcpy (result .build .? .slice (), build );
1201+
1202+ {
1203+ // sanity check, ensure format gives us the same string back we just parsed
1204+ const roundtrip = result .array ();
1205+ if (! std .mem .eql (u8 , roundtrip .slice (), s )) std .debug .panic (
1206+ "codebug parse/format version mismatch:\n parsed: '{s}'\n format: '{s}'\n " ,
1207+ .{ s , roundtrip .slice () },
1208+ );
1209+ }
1210+
1211+ return result ;
1212+ }
1213+ pub fn ref (self : * const SemanticVersion ) std.SemanticVersion {
1214+ return .{
1215+ .major = self .major ,
1216+ .minor = self .minor ,
1217+ .patch = self .patch ,
1218+ .pre = if (self .pre ) | * pre | pre .slice () else null ,
1219+ .build = if (self .build ) | * build | build .slice () else null ,
1220+ };
1221+ }
1222+ pub fn eql (self : SemanticVersion , other : SemanticVersion ) bool {
1223+ return self .major == other .major and self .minor == other .minor and self .patch == other .patch ;
1224+ }
1225+ pub fn format (
1226+ self : SemanticVersion ,
1227+ comptime fmt : []const u8 ,
1228+ options : std.fmt.FormatOptions ,
1229+ writer : anytype ,
1230+ ) ! void {
1231+ try self .ref ().format (fmt , options , writer );
1232+ }
1233+ };
1234+
11501235fn getDefaultUrl (allocator : Allocator , compiler_version : []const u8 ) ! []const u8 {
1236+ const semantic_version = SemanticVersion .parse (compiler_version ) orelse {
1237+ std .log .err ("invalid compiler version '{s}'" , .{compiler_version });
1238+ return error .AlreadyReported ;
1239+ };
1240+
11511241 return switch (determineVersionKind (compiler_version )) {
1152- .dev = > try std .fmt .allocPrint (allocator , "https://ziglang.org/builds/zig-" ++ url_platform ++ "-{0s}." ++ archive_ext , .{compiler_version }),
1153- .release = > try std .fmt .allocPrint (allocator , "https://ziglang.org/download/{s}/zig-" ++ url_platform ++ "-{0s}." ++ archive_ext , .{compiler_version }),
1242+ .dev = > try std .fmt .allocPrint (allocator , "https://ziglang.org/builds/zig-" ++ arch_os ++ "-{0s}." ++ archive_ext , .{compiler_version }),
1243+ .release = > try std .fmt .allocPrint (
1244+ allocator ,
1245+ "https://ziglang.org/download/{s}/zig-{1s}-{0s}." ++ archive_ext ,
1246+ .{
1247+ compiler_version ,
1248+ switch (arch_os_swap_release .order (.{
1249+ .major = semantic_version .major ,
1250+ .minor = semantic_version .minor ,
1251+ .patch = semantic_version .patch ,
1252+ })) {
1253+ .lt = > os_arch ,
1254+ .gt , .eq = > arch_os ,
1255+ },
1256+ },
1257+ ),
11541258 };
11551259}
11561260
0 commit comments