Skip to content

Instantly share code, notes, and snippets.

@doccaico
Last active August 21, 2024 15:18
Show Gist options
  • Save doccaico/cd5108160e1ded01144b67f0026b623b to your computer and use it in GitHub Desktop.
Save doccaico/cd5108160e1ded01144b67f0026b623b to your computer and use it in GitHub Desktop.
Ziglang Updater in Ziglang
// Date: 2024/08/22
// Zig version: 0.14.0-dev.1224+16d74809d
// Build: zig build-exe -Doptimize=ReleaseFast zig_update.zig
// 必要なソフト
// Windows: curl, 7za
// その他(Linux、Macなど): curl
// zigディレクトリの位置
// Windows: c:\Langs\zig
// その他(Linux、Macなど): ~/Langs/zig
// WindowsとLinux上でしかテストしていません
const builtin = @import("builtin");
const std = @import("std");
const fs = std.fs;
const heap = std.heap;
const json = std.json;
const log = std.log;
const math = std.math;
const mem = std.mem;
const os = std.os;
const posix = std.posix;
const print = std.debug.print;
const process = std.process;
const zig_dirname = "zig";
const home_env = if (builtin.os.tag == .windows) "USERPROFILE" else "HOME";
const ext = if (builtin.os.tag == .windows) ".zip" else ".tar.xz";
const os_tag = if (builtin.os.tag == .windows)
"x86_64-windows"
else if (builtin.os.tag == .linux)
"x86_64-linux"
else if (builtin.os.tag == .macos)
"x86_64-macos"
else
@compileError("Unsupported OS.");
pub fn main() !void {
var arena_instance = heap.ArenaAllocator.init(heap.page_allocator);
defer arena_instance.deinit();
const arena = arena_instance.allocator();
// ディレクトリを~/Downloadsに変更
const home = try process.getEnvVarOwned(arena, home_env);
const current_dir_path = try fs.path.join(arena, &[_][]const u8{ home, "Downloads" });
try posix.chdir(current_dir_path);
std.log.info("Changed directory => {s}\n", .{current_dir_path});
// index.jsonをダウンロード
const curl_json = [_][]const u8{ "curl", "-OL", "https://ziglang.org/download/index.json" };
_ = try process.Child.run(.{ .allocator = arena, .argv = &curl_json });
// index.jsonを読み込む
const json_path = try fs.path.join(arena, &[_][]const u8{ current_dir_path, "index.json" });
const file = try fs.cwd().readFileAlloc(arena, json_path, math.maxInt(usize));
// index.jsonをパースしてURLを取得
var parsed = try json.parseFromSlice(json.Value, arena, file, .{});
const url =
parsed.value.object.get("master").?.object.get(os_tag).?.object.get("tarball").?.string;
std.log.info("Download's URL => {s}\n", .{url});
// ファイル(.zip or .tar.xz)をダウンロード
const curl_zig = [_][]const u8{ "curl", "-OL", url };
_ = try process.Child.run(.{ .allocator = arena, .argv = &curl_zig });
std.log.info("Download is done.\n", .{});
// URLからファイル名を取得
var iter = mem.splitBackwardsScalar(u8, url, '/');
const filename = iter.next().?;
// ファイルを解凍
// https://qiita.com/h_pon_heapon/items/d7f7d38d11bfe15eebf8
const extraction = if (builtin.os.tag == .windows)
[_][]const u8{ "7za", "x", "-aoa", filename }
else if (builtin.os.tag == .linux or builtin.os.tag == .macos)
[_][]const u8{ "tar", "xf", filename }
else
@compileError("Unsupported OS.");
const ret = try process.Child.run(.{ .allocator = arena, .argv = &extraction });
print("{s}\n", .{ret.stdout});
std.log.info("Extraction is done.\n", .{});
// 移動先のパスを決定
// Windows: c:\Langs\zig
// Linux, Mac: ~/Langs/zig
const new_path = if (builtin.os.tag == .windows) blk: {
const system_drive = try process.getEnvVarOwned(arena, "SystemDrive");
const path = try fs.path.join(arena, &[_][]const u8{ system_drive, "Langs", zig_dirname });
break :blk path;
} else blk: {
const path = try fs.path.join(arena, &[_][]const u8{ home, "Langs", zig_dirname });
break :blk path;
};
// 既にzigディレクトリが存在すれば削除
try fs.cwd().deleteTree(new_path);
// ファイル名から拡張子(.zip or .tar.xz)を除去
var iter_fn = mem.splitSequence(u8, filename, ext);
const filename_without_ext = iter_fn.next().?;
// zigディレクトリを移動
std.debug.print("{s}\n{s}\n", .{filename_without_ext, new_path});
try fs.Dir.rename(fs.cwd(), filename_without_ext, new_path);
// index.jsonとzig-windows-x86_64-0.12.0-dev.1388+d89266569.zipを削除
fs.cwd().deleteFile(json_path) catch {};
fs.cwd().deleteFile(filename) catch {};
}
@rofrol
Copy link

rofrol commented Jul 3, 2023

My fork https://gist.github.com/rofrol/9e7aa84ad027426d46b574359e756017 uses tar as it is available on newer Windows

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment