@@ -30,10 +30,10 @@ pub fn main() !void {
3030 switch (command ) {
3131 Cli .install = > | version | {
3232 var rel = try Release .releasefromVersion (version );
33- if (! (try utils . check_not_installed (alloc , rel , cp ))) {
33+ if (cp . install_dir . openDir (try common . release_name (alloc , rel ), .{})) | _ | {
3434 std .log .err ("Version already installled. Quitting" , .{});
3535 std .process .exit (0 );
36- }
36+ } else | _ | {}
3737
3838 var client = Client { .allocator = alloc };
3939 defer client .deinit ();
@@ -122,44 +122,74 @@ pub fn main() !void {
122122 Cli .update_self = > try update_self .update_self (alloc , cp ),
123123 Cli .update = > | version_possible | {
124124 var versions : [][]const u8 = undefined ;
125- var check_installed = false ;
126125 if (version_possible ) | v | {
127126 versions = @constCast (&[1 ][]const u8 {v });
128- check_installed = true ;
129127 } else versions = try installed_versions (alloc , cp );
130128
131- var uptodate = std .ArrayList ([]const u8 ).init (alloc );
129+ var already_update = std .ArrayList ([]const u8 ).init (alloc );
132130 var client = Client { .allocator = alloc };
133131 defer client .deinit ();
134132 const resp = try install .get_json_dslist (& client );
135133 const releases = try json .parseFromSliceLeaky (json .Value , alloc , resp .body [0.. resp .length ], .{});
136134
137135 for (versions ) | v | {
138136 var rel = try Release .releasefromVersion (v );
139- if (check_installed and try utils .check_not_installed (alloc , rel , cp )) {
137+ const release_name = try common .release_name (alloc , rel );
138+ if (cp .install_dir .openDir (release_name , .{})) | _ | {
139+ var to_update = false ;
140+ if (rel .spec == common .ReleaseSpec .FullVersionSpec ) {
141+ to_update = false ;
142+ } else if (rel .spec == common .ReleaseSpec .Master ) {
143+ const zig_version = try std .SemanticVersion .parse ((try get_version_from_exe (alloc , release_name )).items );
144+ var next_master_release = try Release .releasefromVersion ("master" );
145+ try next_master_release .resolve (releases );
146+ if (zig_version .order (next_master_release .actual_version .? ) != std .math .Order .eq ) {
147+ to_update = false ;
148+ }
149+ } else if (rel .spec == common .ReleaseSpec .Stable ) {
150+ const zig_version = try std .SemanticVersion .parse ((try get_version_from_exe (alloc , release_name )).items );
151+ var next_stable_release = try Release .releasefromVersion ("stable" );
152+ try next_stable_release .resolve (releases );
153+
154+ if (next_stable_release .actual_version .? .order (zig_version ) == std .math .Order .gt ) {
155+ to_update = true ;
156+ }
157+ } else {
158+ var zig_version = try std .SemanticVersion .parse ((try get_version_from_exe (alloc , release_name )).items );
159+ var format_buf : [32 ]u8 = undefined ;
160+ var format_buf_stream = std .io .fixedBufferStream (& format_buf );
161+ zig_version .patch += 1 ;
162+ try zig_version .format ("" , .{}, format_buf_stream .writer ());
163+ to_update = releases .object .contains (format_buf_stream .getWritten ());
164+ while (releases .object .contains (format_buf_stream .getWritten ())) {
165+ zig_version .patch += 1 ;
166+ try format_buf_stream .seekTo (0 );
167+ try zig_version .format ("" , .{}, format_buf_stream .writer ());
168+ }
169+ }
170+ if (to_update ) {
171+ try install .install_release (alloc , & client , releases , & rel , cp );
172+ } else {
173+ try already_update .append (v );
174+ }
175+ } else | _ | {
140176 try install .install_release (alloc , & client , releases , & rel , cp );
141- return ;
142177 }
143- if (rel .spec == common .ReleaseSpec .FullVersionSpec ) {
144- try uptodate .append (v );
145- continue ;
146- }
147- try install .install_release (alloc , & client , releases , & rel , cp );
148178 }
149- if (uptodate .items .len > 0 ) std .debug .print ("\n " , .{});
179+ if (already_update .items .len > 0 ) std .debug .print ("\n " , .{});
150180
151- for (uptodate .items ) | v | {
181+ for (already_update .items ) | v | {
152182 std .debug .print ("\t {s} : Up to date\n " , .{v });
153183 }
154184 },
155185 }
156186}
157187
158188fn remove_release (alloc : Allocator , rel : Release , cp : CommonPaths ) ! void {
159- if ((try utils . check_not_installed (alloc , rel , cp ))) {
189+ if (cp . install_dir . openDir (try common . release_name (alloc , rel ), .{})) | _ | {
160190 std .log .err ("Version not installled. Quitting" , .{});
161191 std .process .exit (0 );
162- }
192+ } else | _ | {}
163193 const release_dir = try common .release_name (alloc , rel );
164194 try cp .install_dir .deleteTree (release_dir );
165195 std .log .info ("Removed {s}" , .{release_dir });
@@ -219,3 +249,24 @@ fn installed_versions(alloc: Allocator, cp: CommonPaths) ![][]const u8 {
219249 }
220250 return versions .items ;
221251}
252+
253+ fn get_version_from_exe (alloc : Allocator , release_name : []const u8 ) ! std. ArrayList (u8 ) {
254+ var executable = [2 ][]const u8 { undefined , "version" };
255+ executable [0 ] = try std .fs .path .join (alloc , &.{
256+ common .paths .CommonPaths .get_zigverm_root (),
257+ "installs/" ,
258+ release_name ,
259+ "zig" ,
260+ });
261+ var version = std .ArrayList (u8 ).init (alloc );
262+ var stderr = std .ArrayList (u8 ).init (alloc );
263+ var child = std .process .Child .init (& executable , alloc );
264+ child .stdout_behavior = .Pipe ;
265+ child .stderr_behavior = .Pipe ;
266+ try child .spawn ();
267+ try child .collectOutput (& version , & stderr , 256 );
268+ _ = try child .wait ();
269+ _ = version .pop ();
270+
271+ return version ;
272+ }
0 commit comments