barkfetch/src/sys.zig
2024-09-23 21:46:15 +02:00

246 lines
7 KiB
Zig

const std = @import("std");
const builtin = @import("builtin");
const vaxis = @import("vaxis");
const linux = @import("linux.zig");
const macos = @import("macos.zig");
const OSVersion = struct {
name: []const u8,
major: []u64,
minor: []u64,
patch: []u64,
};
const Shell = struct {
name: []const u8,
version: []const u8,
};
pub fn get_dns_servers(allocator: std.mem.Allocator) !vaxis.Cell.Segment {
switch (builtin.os.tag) {
.macos => {
return .{
.text = try macos.get_dns_servers(allocator),
};
},
else => return .{ .text = try std.fmt.allocPrint(allocator, ": unknown", .{}) },
}
}
pub fn get_default_gateway(buf: []u8) !vaxis.Cell.Segment {
switch (builtin.os.tag) {
.macos => {
return .{
.text = try macos.get_default_gateway(buf),
};
},
else => return .{ .text = try std.fmt.bufPrint(buf, ": unknown", .{}) },
}
}
pub fn get_shell(allocator: std.mem.Allocator) !vaxis.Cell.Segment {
const shell_env = std.posix.getenv("SHELL") orelse "Unknown";
var shell_path = std.mem.splitBackwards(u8, shell_env, "/");
var buf: [64]u8 = undefined;
const filename = shell_path.first();
if (std.mem.eql(u8, filename, "zsh")) {
const zsh_version = try get_zsh_version(allocator, &buf, shell_env);
// defer allocator.free(zsh_version);
return .{
.text = try std.fmt.allocPrint(
allocator,
": {s} {s}\n",
.{
filename,
zsh_version,
},
),
};
} else if (std.mem.eql(u8, filename, "bash")) {
const bash_version = try get_bash_version(allocator, &buf, shell_env);
return .{
.text = try std.fmt.allocPrint(
allocator,
": bash {s}\n",
.{bash_version},
),
};
} else if (std.mem.eql(u8, filename, "bash")) {
const version = try std.process.Child.run(
.{
.allocator = allocator,
.argv = &.{ shell_env, "--version" },
},
);
defer allocator.free(version.stdout);
defer allocator.free(version.stderr);
return .{
.text = try std.fmt.allocPrint(
allocator,
": {s}\n",
.{version.stdout},
),
};
}
return .{
.text = try std.fmt.allocPrint(allocator, ": {s}\n", .{shell_env}),
};
}
pub fn get_kernel_version(buf: []u8) !vaxis.Cell.Segment {
switch (builtin.os.tag) {
.macos => {
return .{
.text = try macos.get_kernel_version(buf),
};
},
else => return .{ .text = try std.fmt.bufPrint(buf, "unknown", .{}) },
}
}
pub fn get_uptime(buf: []u8) !vaxis.Cell.Segment {
switch (builtin.os.tag) {
.macos => {
return .{
.text = try macos.get_uptime(buf),
};
},
else => return .{ .text = try std.fmt.bufPrint(buf, "unknown", .{}) },
}
}
pub fn get_cpu_info(buf: []u8) !vaxis.Cell.Segment {
switch (builtin.os.tag) {
.macos => {
return .{
.text = try macos.get_cpu_info(buf),
};
},
else => return .{ .text = try std.fmt.bufPrint(buf, "unknown", .{}) },
}
}
pub fn get_mem_info(buf: []u8) !vaxis.Cell.Segment {
switch (builtin.os.tag) {
.macos => {
return .{
.text = try macos.get_mem_info(buf),
};
},
else => return .{ .text = try std.fmt.bufPrint(buf, "unknown", .{}) },
}
}
pub fn get_battery(buf: []u8) !vaxis.Cell.Segment {
switch (builtin.os.tag) {
.macos => {
return .{
.text = try macos.get_battery_info(buf),
};
},
else => return .{ .text = "unknown" },
}
}
pub fn get_os_version(buf: []u8) !vaxis.Cell.Segment {
switch (builtin.os.tag) {
.macos => {
return .{
.text = try macos.macos_version(buf),
};
},
.linux => {
return .{
.text = try std.fmt.bufPrint(buf, "{s} {s}", .{ try linux.kernel_version(), try linux.distribution() }),
};
},
.freebsd => {
return .{
.text = try std.fmt.bufPrint(buf, "not implemented", .{}),
};
},
else => return .{ .text = try std.fmt.bufPrint(buf, "unknown", .{}) },
}
}
pub fn get_terminal(buf: []u8) !vaxis.Cell.Segment {
const term_program = std.posix.getenv("TERM_PROGRAM") orelse "Unknown";
if (std.mem.eql(u8, term_program, "ghostty")) {
return .{
.text = try std.fmt.bufPrint(buf, ": {s} 󰊠\n", .{term_program}),
};
}
return .{
.text = try std.fmt.bufPrint(buf, ": {s}\n", .{term_program}),
};
}
fn get_zsh_version(allocator: std.mem.Allocator, buf: []u8, zsh_path: []const u8) ![]const u8 {
const zsh_version = try std.fmt.bufPrint(buf, "Unknown", .{});
const version_string = std.process.Child.run(
.{
.allocator = allocator,
.argv = &.{ zsh_path, "--version" },
},
) catch {
return zsh_version;
};
defer allocator.free(version_string.stdout);
defer allocator.free(version_string.stderr);
var version = std.mem.split(u8, version_string.stdout, " ");
_ = version.first();
return try std.fmt.bufPrint(buf, "{s}", .{version.next() orelse "Uknown"});
// return try std.fmt.allocPrint(allocator, "{s}", .{version.next() orelse "Unknown"});
}
fn get_bash_version(allocator: std.mem.Allocator, buf: []u8, bash_path: []const u8) ![]const u8 {
const version_string = try std.process.Child.run(
.{
.allocator = allocator,
.argv = &.{ bash_path, "--version" },
},
);
defer allocator.free(version_string.stdout);
defer allocator.free(version_string.stderr);
var split_lines = std.mem.split(u8, version_string.stdout, "\n");
var version_line = std.mem.split(u8, split_lines.first(), " ");
var i: usize = 0;
while (version_line.next()) |word| {
std.debug.print("version_line: {s}", .{word});
if (i == 3) {
return try std.fmt.bufPrint(buf, "{s}", .{word});
}
i += 1;
}
return try std.fmt.bufPrint(buf, "Unknown", .{});
}
pub fn get_user(buf: []u8) ![]const u8 {
const user = std.posix.getenv("USER") orelse "Unknown";
return try std.fmt.bufPrint(buf, "{s}", .{user});
}
pub fn get_hostname(buf: *[std.posix.HOST_NAME_MAX]u8) ![]const u8 {
const hostname = try std.posix.gethostname(&buf);
return try std.fmt.bufPrint(buf, hostname, .{});
}
test "get_bash_version" {
var buf: [8]u8 = undefined;
const bash_version = try get_bash_version(std.testing.allocator, &buf, "/run/current-system/sw/bin/bash");
try std.testing.expectEqualSlices(u8, "5.2.32(1)-release", bash_version);
}