macos
This commit is contained in:
parent
ccd20f5461
commit
8709ef9de9
4 changed files with 330 additions and 203 deletions
|
@ -295,15 +295,7 @@ namespace package {
|
||||||
if (cargoPath.empty() || !fs::exists(cargoPath))
|
if (cargoPath.empty() || !fs::exists(cargoPath))
|
||||||
return Err(DracError(DracErrorCode::NotFound, "Could not find cargo directory"));
|
return Err(DracError(DracErrorCode::NotFound, "Could not find cargo directory"));
|
||||||
|
|
||||||
u64 count = 0;
|
return GetCountFromDirectory("cargo", cargoPath);
|
||||||
|
|
||||||
for (const fs::directory_entry& entry : fs::directory_iterator(cargoPath))
|
|
||||||
if (entry.is_regular_file())
|
|
||||||
++count;
|
|
||||||
|
|
||||||
debug_log("Found {} packages in cargo directory: {}", count, cargoPath.string());
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn GetTotalCount() -> Result<u64> {
|
fn GetTotalCount() -> Result<u64> {
|
||||||
|
|
520
src/os/macos.cpp
520
src/os/macos.cpp
|
@ -5,229 +5,365 @@
|
||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
|
|
||||||
#include "macos/bridge.hpp"
|
#include "src/core/package.hpp"
|
||||||
#include "os.hpp"
|
|
||||||
#include "src/util/defs.hpp"
|
#include "src/util/defs.hpp"
|
||||||
#include "src/util/error.hpp"
|
#include "src/util/error.hpp"
|
||||||
|
#include "src/util/helpers.hpp"
|
||||||
#include "src/util/types.hpp"
|
#include "src/util/types.hpp"
|
||||||
|
|
||||||
|
#include "macos/bridge.hpp"
|
||||||
|
#include "os.hpp"
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
using namespace util::types;
|
using namespace util::types;
|
||||||
using util::error::DracError;
|
using util::error::DracError, util::error::DracErrorCode;
|
||||||
|
using util::helpers::GetEnv;
|
||||||
|
|
||||||
fn os::GetMemInfo() -> Result<u64> {
|
namespace {
|
||||||
u64 mem = 0;
|
fn StrEqualsIgnoreCase(std::string_view strA, std::string_view strB) -> bool {
|
||||||
usize size = sizeof(mem);
|
if (strA.length() != strB.length())
|
||||||
|
return false;
|
||||||
|
|
||||||
if (sysctlbyname("hw.memsize", &mem, &size, nullptr, 0) == -1)
|
return std::equal(strA.begin(), strA.end(), strB.begin(), [](char aChar, char bChar) {
|
||||||
return Err(DracError::withErrno("Failed to get memory info"));
|
return std::tolower(static_cast<unsigned char>(aChar)) == std::tolower(static_cast<unsigned char>(bChar));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return mem;
|
fn Capitalize(std::string_view sview) -> Option<String> {
|
||||||
}
|
if (sview.empty())
|
||||||
|
return None;
|
||||||
|
|
||||||
fn os::GetNowPlaying() -> Result<MediaInfo> { return GetCurrentPlayingInfo(); }
|
String result(sview);
|
||||||
|
result[0] = static_cast<char>(std::toupper(static_cast<unsigned char>(result[0])));
|
||||||
|
|
||||||
fn os::GetOSVersion() -> Result<String> { return GetMacOSVersion(); }
|
return result;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
fn os::GetDesktopEnvironment() -> Result<String> {
|
namespace os {
|
||||||
return "Aqua"; // TODO: Implement
|
fn GetMemInfo() -> Result<u64> {
|
||||||
}
|
u64 mem = 0;
|
||||||
|
usize size = sizeof(mem);
|
||||||
|
|
||||||
fn os::GetWindowManager() -> Result<String> {
|
if (sysctlbyname("hw.memsize", &mem, &size, nullptr, 0) == -1)
|
||||||
return "Yabai"; // TODO: Implement
|
return Err(DracError("Failed to get memory info"));
|
||||||
}
|
|
||||||
|
|
||||||
fn os::GetKernelVersion() -> Result<String> {
|
return mem;
|
||||||
Array<char, 256> kernelVersion {};
|
}
|
||||||
usize kernelVersionLen = sizeof(kernelVersion);
|
|
||||||
|
|
||||||
if (sysctlbyname("kern.osrelease", kernelVersion.data(), &kernelVersionLen, nullptr, 0) == -1)
|
fn GetNowPlaying() -> Result<MediaInfo> { return GetCurrentPlayingInfo(); }
|
||||||
return Err(DracError::withErrno("Failed to get kernel version"));
|
|
||||||
|
|
||||||
return kernelVersion.data();
|
fn GetOSVersion() -> Result<String> { return GetMacOSVersion(); }
|
||||||
}
|
|
||||||
|
|
||||||
fn os::GetHost() -> Result<String> {
|
fn GetDesktopEnvironment() -> Result<String> { return "Aqua"; }
|
||||||
Array<char, 256> hwModel {};
|
|
||||||
usize hwModelLen = sizeof(hwModel);
|
|
||||||
|
|
||||||
if (sysctlbyname("hw.model", hwModel.data(), &hwModelLen, nullptr, 0) == -1)
|
fn GetWindowManager() -> Result<String> {
|
||||||
return Err(DracError::withErrno("Failed to get host info"));
|
constexpr std::array<std::string_view, 6> knownWms = {
|
||||||
|
"yabai", "kwm", "chunkwm", "amethyst", "spectacle", "rectangle",
|
||||||
|
};
|
||||||
|
|
||||||
// taken from https://github.com/fastfetch-cli/fastfetch/blob/dev/src/detection/host/host_mac.c
|
Array<i32, 3> request = { CTL_KERN, KERN_PROC, KERN_PROC_ALL };
|
||||||
// shortened a lot of the entries to remove unnecessary info
|
|
||||||
std::flat_map<StringView, StringView> modelNameByHwModel = {
|
|
||||||
// MacBook Pro
|
|
||||||
{ "MacBookPro18,3", "MacBook Pro (14-inch, 2021)" },
|
|
||||||
{ "MacBookPro18,4", "MacBook Pro (14-inch, 2021)" },
|
|
||||||
{ "MacBookPro18,1", "MacBook Pro (16-inch, 2021)" },
|
|
||||||
{ "MacBookPro18,2", "MacBook Pro (16-inch, 2021)" },
|
|
||||||
{ "MacBookPro17,1", "MacBook Pro (13-inch, M1, 2020)" },
|
|
||||||
{ "MacBookPro16,3", "MacBook Pro (13-inch, 2020)" },
|
|
||||||
{ "MacBookPro16,2", "MacBook Pro (13-inch, 2020)" },
|
|
||||||
{ "MacBookPro16,4", "MacBook Pro (16-inch, 2019)" },
|
|
||||||
{ "MacBookPro16,1", "MacBook Pro (16-inch, 2019)" },
|
|
||||||
{ "MacBookPro15,4", "MacBook Pro (13-inch, 2019)" },
|
|
||||||
{ "MacBookPro15,3", "MacBook Pro (15-inch, 2019)" },
|
|
||||||
{ "MacBookPro15,2", "MacBook Pro (13-inch, 2018/2019)" },
|
|
||||||
{ "MacBookPro15,1", "MacBook Pro (15-inch, 2018/2019)" },
|
|
||||||
{ "MacBookPro14,3", "MacBook Pro (15-inch, 2017)" },
|
|
||||||
{ "MacBookPro14,2", "MacBook Pro (13-inch, 2017)" },
|
|
||||||
{ "MacBookPro14,1", "MacBook Pro (13-inch, 2017)" },
|
|
||||||
{ "MacBookPro13,3", "MacBook Pro (15-inch, 2016)" },
|
|
||||||
{ "MacBookPro13,2", "MacBook Pro (13-inch, 2016)" },
|
|
||||||
{ "MacBookPro13,1", "MacBook Pro (13-inch, 2016)" },
|
|
||||||
{ "MacBookPro12,1", "MacBook Pro (13-inch, 2015)" },
|
|
||||||
{ "MacBookPro11,4", "MacBook Pro (15-inch, 2015)" },
|
|
||||||
{ "MacBookPro11,5", "MacBook Pro (15-inch, 2015)" },
|
|
||||||
{ "MacBookPro11,2", "MacBook Pro (15-inch, 2013/2014)" },
|
|
||||||
{ "MacBookPro11,3", "MacBook Pro (15-inch, 2013/2014)" },
|
|
||||||
{ "MacBookPro11,1", "MacBook Pro (13-inch, 2013/2014)" },
|
|
||||||
{ "MacBookPro10,2", "MacBook Pro (13-inch, 2012/2013)" },
|
|
||||||
{ "MacBookPro10,1", "MacBook Pro (15-inch, 2012/2013)" },
|
|
||||||
{ "MacBookPro9,2", "MacBook Pro (13-inch, 2012)" },
|
|
||||||
{ "MacBookPro9,1", "MacBook Pro (15-inch, 2012)" },
|
|
||||||
{ "MacBookPro8,3", "MacBook Pro (17-inch, 2011)" },
|
|
||||||
{ "MacBookPro8,2", "MacBook Pro (15-inch, 2011)" },
|
|
||||||
{ "MacBookPro8,1", "MacBook Pro (13-inch, 2011)" },
|
|
||||||
{ "MacBookPro7,1", "MacBook Pro (13-inch, 2010)" },
|
|
||||||
{ "MacBookPro6,2", "MacBook Pro (15-inch, 2010)" },
|
|
||||||
{ "MacBookPro6,1", "MacBook Pro (17-inch, 2010)" },
|
|
||||||
{ "MacBookPro5,5", "MacBook Pro (13-inch, 2009)" },
|
|
||||||
{ "MacBookPro5,3", "MacBook Pro (15-inch, 2009)" },
|
|
||||||
{ "MacBookPro5,2", "MacBook Pro (17-inch, 2009)" },
|
|
||||||
{ "MacBookPro5,1", "MacBook Pro (15-inch, 2008)" },
|
|
||||||
{ "MacBookPro4,1", "MacBook Pro (17/15-inch, 2008)" },
|
|
||||||
|
|
||||||
// MacBook Air
|
usize len = 0;
|
||||||
{ "MacBookAir10,1", "MacBook Air (M1, 2020)" },
|
|
||||||
{ "MacBookAir9,1", "MacBook Air (13-inch, 2020)" },
|
|
||||||
{ "MacBookAir8,2", "MacBook Air (13-inch, 2019)" },
|
|
||||||
{ "MacBookAir8,1", "MacBook Air (13-inch, 2018)" },
|
|
||||||
{ "MacBookAir7,2", "MacBook Air (13-inch, 2015/2017)" },
|
|
||||||
{ "MacBookAir7,1", "MacBook Air (11-inch, 2015)" },
|
|
||||||
{ "MacBookAir6,2", "MacBook Air (13-inch, 2013/2014)" },
|
|
||||||
{ "MacBookAir6,1", "MacBook Air (11-inch, 2013/2014)" },
|
|
||||||
{ "MacBookAir5,2", "MacBook Air (13-inch, 2012)" },
|
|
||||||
{ "MacBookAir5,1", "MacBook Air (11-inch, 2012)" },
|
|
||||||
{ "MacBookAir4,2", "MacBook Air (13-inch, 2011)" },
|
|
||||||
{ "MacBookAir4,1", "MacBook Air (11-inch, 2011)" },
|
|
||||||
{ "MacBookAir3,2", "MacBook Air (13-inch, 2010)" },
|
|
||||||
{ "MacBookAir3,1", "MacBook Air (11-inch, 2010)" },
|
|
||||||
{ "MacBookAir2,1", "MacBook Air (2009)" },
|
|
||||||
|
|
||||||
// Mac mini
|
if (sysctl(request.data(), request.size(), nullptr, &len, nullptr, 0) == -1)
|
||||||
{ "Macmini9,1", "Mac mini (M1, 2020)" },
|
return Err(DracError("sysctl size query failed for KERN_PROC_ALL"));
|
||||||
{ "Macmini8,1", "Mac mini (2018)" },
|
|
||||||
{ "Macmini7,1", "Mac mini (2014)" },
|
|
||||||
{ "Macmini6,1", "Mac mini (2012)" },
|
|
||||||
{ "Macmini6,2", "Mac mini (2012)" },
|
|
||||||
{ "Macmini5,1", "Mac mini (2011)" },
|
|
||||||
{ "Macmini5,2", "Mac mini (2011)" },
|
|
||||||
{ "Macmini4,1", "Mac mini (2010)" },
|
|
||||||
{ "Macmini3,1", "Mac mini (2009)" },
|
|
||||||
|
|
||||||
// MacBook
|
if (len == 0)
|
||||||
{ "MacBook10,1", "MacBook (12-inch, 2017)" },
|
return Err(DracError(DracErrorCode::NotFound, "sysctl for KERN_PROC_ALL returned zero length"));
|
||||||
{ "MacBook9,1", "MacBook (12-inch, 2016)" },
|
|
||||||
{ "MacBook8,1", "MacBook (12-inch, 2015)" },
|
|
||||||
{ "MacBook7,1", "MacBook (13-inch, 2010)" },
|
|
||||||
{ "MacBook6,1", "MacBook (13-inch, 2009)" },
|
|
||||||
{ "MacBook5,2", "MacBook (13-inch, 2009)" },
|
|
||||||
|
|
||||||
// Mac Pro
|
Vec<char> buf(len);
|
||||||
{ "MacPro7,1", "Mac Pro (2019)" },
|
|
||||||
{ "MacPro6,1", "Mac Pro (2013)" },
|
|
||||||
{ "MacPro5,1", "Mac Pro (2010 - 2012)" },
|
|
||||||
{ "MacPro4,1", "Mac Pro (2009)" },
|
|
||||||
|
|
||||||
// Mac (Generic)
|
if (sysctl(request.data(), request.size(), buf.data(), &len, nullptr, 0) == -1)
|
||||||
{ "Mac16,3", "iMac (24-inch, 2024)" },
|
return Err(DracError("sysctl data fetch failed for KERN_PROC_ALL"));
|
||||||
{ "Mac16,2", "iMac (24-inch, 2024)" },
|
|
||||||
{ "Mac16,1", "MacBook Pro (14-inch, 2024)" },
|
|
||||||
{ "Mac16,6", "MacBook Pro (14-inch, 2024)" },
|
|
||||||
{ "Mac16,8", "MacBook Pro (14-inch, 2024)" },
|
|
||||||
{ "Mac16,7", "MacBook Pro (16-inch, 2024)" },
|
|
||||||
{ "Mac16,5", "MacBook Pro (16-inch, 2024)" },
|
|
||||||
{ "Mac16,15", "Mac mini (2024)" },
|
|
||||||
{ "Mac16,10", "Mac mini (2024)" },
|
|
||||||
{ "Mac15,13", "MacBook Air (15-inch, M3, 2024)" },
|
|
||||||
{ "Mac15,2", "MacBook Air (13-inch, M3, 2024)" },
|
|
||||||
{ "Mac15,3", "MacBook Pro (14-inch, Nov 2023)" },
|
|
||||||
{ "Mac15,4", "iMac (24-inch, 2023)" },
|
|
||||||
{ "Mac15,5", "iMac (24-inch, 2023)" },
|
|
||||||
{ "Mac15,6", "MacBook Pro (14-inch, Nov 2023)" },
|
|
||||||
{ "Mac15,8", "MacBook Pro (14-inch, Nov 2023)" },
|
|
||||||
{ "Mac15,10", "MacBook Pro (14-inch, Nov 2023)" },
|
|
||||||
{ "Mac15,7", "MacBook Pro (16-inch, Nov 2023)" },
|
|
||||||
{ "Mac15,9", "MacBook Pro (16-inch, Nov 2023)" },
|
|
||||||
{ "Mac15,11", "MacBook Pro (16-inch, Nov 2023)" },
|
|
||||||
{ "Mac14,15", "MacBook Air (15-inch, M2, 2023)" },
|
|
||||||
{ "Mac14,14", "Mac Studio (M2 Ultra, 2023)" },
|
|
||||||
{ "Mac14,13", "Mac Studio (M2 Max, 2023)" },
|
|
||||||
{ "Mac14,8", "Mac Pro (2023)" },
|
|
||||||
{ "Mac14,6", "MacBook Pro (16-inch, 2023)" },
|
|
||||||
{ "Mac14,10", "MacBook Pro (16-inch, 2023)" },
|
|
||||||
{ "Mac14,5", "MacBook Pro (14-inch, 2023)" },
|
|
||||||
{ "Mac14,9", "MacBook Pro (14-inch, 2023)" },
|
|
||||||
{ "Mac14,3", "Mac mini (M2, 2023)" },
|
|
||||||
{ "Mac14,12", "Mac mini (M2, 2023)" },
|
|
||||||
{ "Mac14,7", "MacBook Pro (13-inch, M2, 2022)" },
|
|
||||||
{ "Mac14,2", "MacBook Air (M2, 2022)" },
|
|
||||||
{ "Mac13,1", "Mac Studio (M1 Max, 2022)" },
|
|
||||||
{ "Mac13,2", "Mac Studio (M1 Ultra, 2022)" },
|
|
||||||
|
|
||||||
// iMac
|
if (len % sizeof(kinfo_proc) != 0)
|
||||||
{ "iMac21,1", "iMac (24-inch, M1, 2021)" },
|
return Err(DracError(
|
||||||
{ "iMac21,2", "iMac (24-inch, M1, 2021)" },
|
DracErrorCode::PlatformSpecific,
|
||||||
{ "iMac20,1", "iMac (27-inch, 2020)" },
|
std::format("sysctl returned size {} which is not a multiple of kinfo_proc size {}", len, sizeof(kinfo_proc))
|
||||||
{ "iMac20,2", "iMac (27-inch, 2020)" },
|
));
|
||||||
{ "iMac19,1", "iMac (27-inch, 2019)" },
|
|
||||||
{ "iMac19,2", "iMac (21.5-inch, 2019)" },
|
|
||||||
{ "iMacPro1,1", "iMac Pro (2017)" },
|
|
||||||
{ "iMac18,3", "iMac (27-inch, 2017)" },
|
|
||||||
{ "iMac18,2", "iMac (21.5-inch, 2017)" },
|
|
||||||
{ "iMac18,1", "iMac (21.5-inch, 2017)" },
|
|
||||||
{ "iMac17,1", "iMac (27-inch, 2015)" },
|
|
||||||
{ "iMac16,2", "iMac (21.5-inch, 2015)" },
|
|
||||||
{ "iMac16,1", "iMac (21.5-inch, 2015)" },
|
|
||||||
{ "iMac15,1", "iMac (27-inch, 2014/2015)" },
|
|
||||||
{ "iMac14,4", "iMac (21.5-inch, 2014)" },
|
|
||||||
{ "iMac14,2", "iMac (27-inch, 2013)" },
|
|
||||||
{ "iMac14,1", "iMac (21.5-inch, 2013)" },
|
|
||||||
{ "iMac13,2", "iMac (27-inch, 2012)" },
|
|
||||||
{ "iMac13,1", "iMac (21.5-inch, 2012)" },
|
|
||||||
{ "iMac12,2", "iMac (27-inch, 2011)" },
|
|
||||||
{ "iMac12,1", "iMac (21.5-inch, 2011)" },
|
|
||||||
{ "iMac11,3", "iMac (27-inch, 2010)" },
|
|
||||||
{ "iMac11,2", "iMac (21.5-inch, 2010)" },
|
|
||||||
{ "iMac10,1", "iMac (27/21.5-inch, 2009)" },
|
|
||||||
{ "iMac9,1", "iMac (24/20-inch, 2009)" },
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto iter = modelNameByHwModel.find(hwModel.data());
|
usize count = len / sizeof(kinfo_proc);
|
||||||
if (iter == modelNameByHwModel.end())
|
|
||||||
return Err(DracError::withErrno("Failed to get host info"));
|
|
||||||
|
|
||||||
return String(iter->second);
|
std::span<const kinfo_proc> processes = std::span(
|
||||||
}
|
reinterpret_cast<const kinfo_proc*>(buf.data()), count // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||||
|
);
|
||||||
|
|
||||||
fn os::GetDiskUsage() -> Result<DiskSpace> {
|
for (const kinfo_proc& procInfo : processes) {
|
||||||
struct statvfs vfs;
|
StringView comm(procInfo.kp_proc.p_comm);
|
||||||
|
|
||||||
if (statvfs("/", &vfs) != 0)
|
for (const auto& wmName : knownWms)
|
||||||
return Err(DracError::withErrno("Failed to get disk usage"));
|
if (StrEqualsIgnoreCase(comm, wmName)) {
|
||||||
|
const auto capitalized = Capitalize(comm);
|
||||||
|
return capitalized ? Result<String>(*capitalized)
|
||||||
|
: Err(DracError(DracErrorCode::ParseError, "Failed to capitalize window manager name"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return DiskSpace { .used_bytes = (vfs.f_blocks - vfs.f_bfree) * vfs.f_frsize,
|
return "Quartz";
|
||||||
.total_bytes = vfs.f_blocks * vfs.f_frsize };
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn os::GetPackageCount() -> Result<u64> {
|
fn GetKernelVersion() -> Result<String> {
|
||||||
return Err(DracError(DracErrorCode::NotSupported, "Package count is not supported on macOS")); // TODO: Implement
|
Array<char, 256> kernelVersion {};
|
||||||
}
|
usize kernelVersionLen = sizeof(kernelVersion);
|
||||||
|
|
||||||
fn os::GetShell() -> Result<String> {
|
if (sysctlbyname("kern.osrelease", kernelVersion.data(), &kernelVersionLen, nullptr, 0) == -1)
|
||||||
return "Fish"; // TODO: Implement
|
return Err(DracError("Failed to get kernel version"));
|
||||||
}
|
|
||||||
|
return kernelVersion.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn GetHost() -> Result<String> {
|
||||||
|
Array<char, 256> hwModel {};
|
||||||
|
usize hwModelLen = sizeof(hwModel);
|
||||||
|
|
||||||
|
if (sysctlbyname("hw.model", hwModel.data(), &hwModelLen, nullptr, 0) == -1)
|
||||||
|
return Err(DracError("Failed to get host info"));
|
||||||
|
|
||||||
|
// taken from https://github.com/fastfetch-cli/fastfetch/blob/dev/src/detection/host/host_mac.c
|
||||||
|
// shortened a lot of the entries to remove unnecessary info
|
||||||
|
std::flat_map<StringView, StringView> modelNameByHwModel = {
|
||||||
|
// MacBook Pro
|
||||||
|
{ "MacBookPro18,3", "MacBook Pro (14-inch, 2021)" },
|
||||||
|
{ "MacBookPro18,4", "MacBook Pro (14-inch, 2021)" },
|
||||||
|
{ "MacBookPro18,1", "MacBook Pro (16-inch, 2021)" },
|
||||||
|
{ "MacBookPro18,2", "MacBook Pro (16-inch, 2021)" },
|
||||||
|
{ "MacBookPro17,1", "MacBook Pro (13-inch, M1, 2020)" },
|
||||||
|
{ "MacBookPro16,3", "MacBook Pro (13-inch, 2020)" },
|
||||||
|
{ "MacBookPro16,2", "MacBook Pro (13-inch, 2020)" },
|
||||||
|
{ "MacBookPro16,4", "MacBook Pro (16-inch, 2019)" },
|
||||||
|
{ "MacBookPro16,1", "MacBook Pro (16-inch, 2019)" },
|
||||||
|
{ "MacBookPro15,4", "MacBook Pro (13-inch, 2019)" },
|
||||||
|
{ "MacBookPro15,3", "MacBook Pro (15-inch, 2019)" },
|
||||||
|
{ "MacBookPro15,2", "MacBook Pro (13-inch, 2018/2019)" },
|
||||||
|
{ "MacBookPro15,1", "MacBook Pro (15-inch, 2018/2019)" },
|
||||||
|
{ "MacBookPro14,3", "MacBook Pro (15-inch, 2017)" },
|
||||||
|
{ "MacBookPro14,2", "MacBook Pro (13-inch, 2017)" },
|
||||||
|
{ "MacBookPro14,1", "MacBook Pro (13-inch, 2017)" },
|
||||||
|
{ "MacBookPro13,3", "MacBook Pro (15-inch, 2016)" },
|
||||||
|
{ "MacBookPro13,2", "MacBook Pro (13-inch, 2016)" },
|
||||||
|
{ "MacBookPro13,1", "MacBook Pro (13-inch, 2016)" },
|
||||||
|
{ "MacBookPro12,1", "MacBook Pro (13-inch, 2015)" },
|
||||||
|
{ "MacBookPro11,4", "MacBook Pro (15-inch, 2015)" },
|
||||||
|
{ "MacBookPro11,5", "MacBook Pro (15-inch, 2015)" },
|
||||||
|
{ "MacBookPro11,2", "MacBook Pro (15-inch, 2013/2014)" },
|
||||||
|
{ "MacBookPro11,3", "MacBook Pro (15-inch, 2013/2014)" },
|
||||||
|
{ "MacBookPro11,1", "MacBook Pro (13-inch, 2013/2014)" },
|
||||||
|
{ "MacBookPro10,2", "MacBook Pro (13-inch, 2012/2013)" },
|
||||||
|
{ "MacBookPro10,1", "MacBook Pro (15-inch, 2012/2013)" },
|
||||||
|
{ "MacBookPro9,2", "MacBook Pro (13-inch, 2012)" },
|
||||||
|
{ "MacBookPro9,1", "MacBook Pro (15-inch, 2012)" },
|
||||||
|
{ "MacBookPro8,3", "MacBook Pro (17-inch, 2011)" },
|
||||||
|
{ "MacBookPro8,2", "MacBook Pro (15-inch, 2011)" },
|
||||||
|
{ "MacBookPro8,1", "MacBook Pro (13-inch, 2011)" },
|
||||||
|
{ "MacBookPro7,1", "MacBook Pro (13-inch, 2010)" },
|
||||||
|
{ "MacBookPro6,2", "MacBook Pro (15-inch, 2010)" },
|
||||||
|
{ "MacBookPro6,1", "MacBook Pro (17-inch, 2010)" },
|
||||||
|
{ "MacBookPro5,5", "MacBook Pro (13-inch, 2009)" },
|
||||||
|
{ "MacBookPro5,3", "MacBook Pro (15-inch, 2009)" },
|
||||||
|
{ "MacBookPro5,2", "MacBook Pro (17-inch, 2009)" },
|
||||||
|
{ "MacBookPro5,1", "MacBook Pro (15-inch, 2008)" },
|
||||||
|
{ "MacBookPro4,1", "MacBook Pro (17/15-inch, 2008)" },
|
||||||
|
|
||||||
|
// MacBook Air
|
||||||
|
{ "MacBookAir10,1", "MacBook Air (M1, 2020)" },
|
||||||
|
{ "MacBookAir9,1", "MacBook Air (13-inch, 2020)" },
|
||||||
|
{ "MacBookAir8,2", "MacBook Air (13-inch, 2019)" },
|
||||||
|
{ "MacBookAir8,1", "MacBook Air (13-inch, 2018)" },
|
||||||
|
{ "MacBookAir7,2", "MacBook Air (13-inch, 2015/2017)" },
|
||||||
|
{ "MacBookAir7,1", "MacBook Air (11-inch, 2015)" },
|
||||||
|
{ "MacBookAir6,2", "MacBook Air (13-inch, 2013/2014)" },
|
||||||
|
{ "MacBookAir6,1", "MacBook Air (11-inch, 2013/2014)" },
|
||||||
|
{ "MacBookAir5,2", "MacBook Air (13-inch, 2012)" },
|
||||||
|
{ "MacBookAir5,1", "MacBook Air (11-inch, 2012)" },
|
||||||
|
{ "MacBookAir4,2", "MacBook Air (13-inch, 2011)" },
|
||||||
|
{ "MacBookAir4,1", "MacBook Air (11-inch, 2011)" },
|
||||||
|
{ "MacBookAir3,2", "MacBook Air (13-inch, 2010)" },
|
||||||
|
{ "MacBookAir3,1", "MacBook Air (11-inch, 2010)" },
|
||||||
|
{ "MacBookAir2,1", "MacBook Air (2009)" },
|
||||||
|
|
||||||
|
// Mac mini
|
||||||
|
{ "Macmini9,1", "Mac mini (M1, 2020)" },
|
||||||
|
{ "Macmini8,1", "Mac mini (2018)" },
|
||||||
|
{ "Macmini7,1", "Mac mini (2014)" },
|
||||||
|
{ "Macmini6,1", "Mac mini (2012)" },
|
||||||
|
{ "Macmini6,2", "Mac mini (2012)" },
|
||||||
|
{ "Macmini5,1", "Mac mini (2011)" },
|
||||||
|
{ "Macmini5,2", "Mac mini (2011)" },
|
||||||
|
{ "Macmini4,1", "Mac mini (2010)" },
|
||||||
|
{ "Macmini3,1", "Mac mini (2009)" },
|
||||||
|
|
||||||
|
// MacBook
|
||||||
|
{ "MacBook10,1", "MacBook (12-inch, 2017)" },
|
||||||
|
{ "MacBook9,1", "MacBook (12-inch, 2016)" },
|
||||||
|
{ "MacBook8,1", "MacBook (12-inch, 2015)" },
|
||||||
|
{ "MacBook7,1", "MacBook (13-inch, 2010)" },
|
||||||
|
{ "MacBook6,1", "MacBook (13-inch, 2009)" },
|
||||||
|
{ "MacBook5,2", "MacBook (13-inch, 2009)" },
|
||||||
|
|
||||||
|
// Mac Pro
|
||||||
|
{ "MacPro7,1", "Mac Pro (2019)" },
|
||||||
|
{ "MacPro6,1", "Mac Pro (2013)" },
|
||||||
|
{ "MacPro5,1", "Mac Pro (2010 - 2012)" },
|
||||||
|
{ "MacPro4,1", "Mac Pro (2009)" },
|
||||||
|
|
||||||
|
// Mac (Generic)
|
||||||
|
{ "Mac16,3", "iMac (24-inch, 2024)" },
|
||||||
|
{ "Mac16,2", "iMac (24-inch, 2024)" },
|
||||||
|
{ "Mac16,1", "MacBook Pro (14-inch, 2024)" },
|
||||||
|
{ "Mac16,6", "MacBook Pro (14-inch, 2024)" },
|
||||||
|
{ "Mac16,8", "MacBook Pro (14-inch, 2024)" },
|
||||||
|
{ "Mac16,7", "MacBook Pro (16-inch, 2024)" },
|
||||||
|
{ "Mac16,5", "MacBook Pro (16-inch, 2024)" },
|
||||||
|
{ "Mac16,15", "Mac mini (2024)" },
|
||||||
|
{ "Mac16,10", "Mac mini (2024)" },
|
||||||
|
{ "Mac15,13", "MacBook Air (15-inch, M3, 2024)" },
|
||||||
|
{ "Mac15,2", "MacBook Air (13-inch, M3, 2024)" },
|
||||||
|
{ "Mac15,3", "MacBook Pro (14-inch, Nov 2023)" },
|
||||||
|
{ "Mac15,4", "iMac (24-inch, 2023)" },
|
||||||
|
{ "Mac15,5", "iMac (24-inch, 2023)" },
|
||||||
|
{ "Mac15,6", "MacBook Pro (14-inch, Nov 2023)" },
|
||||||
|
{ "Mac15,8", "MacBook Pro (14-inch, Nov 2023)" },
|
||||||
|
{ "Mac15,10", "MacBook Pro (14-inch, Nov 2023)" },
|
||||||
|
{ "Mac15,7", "MacBook Pro (16-inch, Nov 2023)" },
|
||||||
|
{ "Mac15,9", "MacBook Pro (16-inch, Nov 2023)" },
|
||||||
|
{ "Mac15,11", "MacBook Pro (16-inch, Nov 2023)" },
|
||||||
|
{ "Mac14,15", "MacBook Air (15-inch, M2, 2023)" },
|
||||||
|
{ "Mac14,14", "Mac Studio (M2 Ultra, 2023)" },
|
||||||
|
{ "Mac14,13", "Mac Studio (M2 Max, 2023)" },
|
||||||
|
{ "Mac14,8", "Mac Pro (2023)" },
|
||||||
|
{ "Mac14,6", "MacBook Pro (16-inch, 2023)" },
|
||||||
|
{ "Mac14,10", "MacBook Pro (16-inch, 2023)" },
|
||||||
|
{ "Mac14,5", "MacBook Pro (14-inch, 2023)" },
|
||||||
|
{ "Mac14,9", "MacBook Pro (14-inch, 2023)" },
|
||||||
|
{ "Mac14,3", "Mac mini (M2, 2023)" },
|
||||||
|
{ "Mac14,12", "Mac mini (M2, 2023)" },
|
||||||
|
{ "Mac14,7", "MacBook Pro (13-inch, M2, 2022)" },
|
||||||
|
{ "Mac14,2", "MacBook Air (M2, 2022)" },
|
||||||
|
{ "Mac13,1", "Mac Studio (M1 Max, 2022)" },
|
||||||
|
{ "Mac13,2", "Mac Studio (M1 Ultra, 2022)" },
|
||||||
|
|
||||||
|
// iMac
|
||||||
|
{ "iMac21,1", "iMac (24-inch, M1, 2021)" },
|
||||||
|
{ "iMac21,2", "iMac (24-inch, M1, 2021)" },
|
||||||
|
{ "iMac20,1", "iMac (27-inch, 2020)" },
|
||||||
|
{ "iMac20,2", "iMac (27-inch, 2020)" },
|
||||||
|
{ "iMac19,1", "iMac (27-inch, 2019)" },
|
||||||
|
{ "iMac19,2", "iMac (21.5-inch, 2019)" },
|
||||||
|
{ "iMacPro1,1", "iMac Pro (2017)" },
|
||||||
|
{ "iMac18,3", "iMac (27-inch, 2017)" },
|
||||||
|
{ "iMac18,2", "iMac (21.5-inch, 2017)" },
|
||||||
|
{ "iMac18,1", "iMac (21.5-inch, 2017)" },
|
||||||
|
{ "iMac17,1", "iMac (27-inch, 2015)" },
|
||||||
|
{ "iMac16,2", "iMac (21.5-inch, 2015)" },
|
||||||
|
{ "iMac16,1", "iMac (21.5-inch, 2015)" },
|
||||||
|
{ "iMac15,1", "iMac (27-inch, 2014/2015)" },
|
||||||
|
{ "iMac14,4", "iMac (21.5-inch, 2014)" },
|
||||||
|
{ "iMac14,2", "iMac (27-inch, 2013)" },
|
||||||
|
{ "iMac14,1", "iMac (21.5-inch, 2013)" },
|
||||||
|
{ "iMac13,2", "iMac (27-inch, 2012)" },
|
||||||
|
{ "iMac13,1", "iMac (21.5-inch, 2012)" },
|
||||||
|
{ "iMac12,2", "iMac (27-inch, 2011)" },
|
||||||
|
{ "iMac12,1", "iMac (21.5-inch, 2011)" },
|
||||||
|
{ "iMac11,3", "iMac (27-inch, 2010)" },
|
||||||
|
{ "iMac11,2", "iMac (21.5-inch, 2010)" },
|
||||||
|
{ "iMac10,1", "iMac (27/21.5-inch, 2009)" },
|
||||||
|
{ "iMac9,1", "iMac (24/20-inch, 2009)" },
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto iter = modelNameByHwModel.find(hwModel.data());
|
||||||
|
if (iter == modelNameByHwModel.end())
|
||||||
|
return Err(DracError("Failed to get host info"));
|
||||||
|
|
||||||
|
return String(iter->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn GetDiskUsage() -> Result<DiskSpace> {
|
||||||
|
struct statvfs vfs;
|
||||||
|
|
||||||
|
if (statvfs("/", &vfs) != 0)
|
||||||
|
return Err(DracError("Failed to get disk usage"));
|
||||||
|
|
||||||
|
return DiskSpace { .usedBytes = (vfs.f_blocks - vfs.f_bfree) * vfs.f_frsize,
|
||||||
|
.totalBytes = vfs.f_blocks * vfs.f_frsize };
|
||||||
|
}
|
||||||
|
|
||||||
|
fn GetShell() -> Result<String> {
|
||||||
|
if (const Result<String> shellPath = GetEnv("SHELL")) {
|
||||||
|
// clang-format off
|
||||||
|
constexpr Array<Pair<StringView, StringView>, 5> shellMap {{
|
||||||
|
{ "bash", "Bash" },
|
||||||
|
{ "zsh", "Zsh" },
|
||||||
|
{ "fish", "Fish" },
|
||||||
|
{ "nu", "Nushell" },
|
||||||
|
{ "sh", "SH" }, // sh last because other shells contain "sh"
|
||||||
|
}};
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
for (const auto& [exe, name] : shellMap)
|
||||||
|
if (shellPath->contains(exe))
|
||||||
|
return String(name);
|
||||||
|
|
||||||
|
return *shellPath; // fallback to the raw shell path
|
||||||
|
}
|
||||||
|
|
||||||
|
return Err(DracError(DracErrorCode::NotFound, "Could not find SHELL environment variable"));
|
||||||
|
}
|
||||||
|
}; // namespace os
|
||||||
|
|
||||||
|
namespace package {
|
||||||
|
fn GetHomebrewCount() -> Result<u64> {
|
||||||
|
u64 count = 0;
|
||||||
|
|
||||||
|
Array<fs::path, 2> cellarPaths {
|
||||||
|
"/opt/homebrew/Cellar",
|
||||||
|
"/usr/local/Cellar",
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const auto& cellarPath : cellarPaths) {
|
||||||
|
if (std::error_code errc; !fs::exists(cellarPath, errc) || errc) {
|
||||||
|
if (errc && errc != std::errc::no_such_file_or_directory)
|
||||||
|
return Err(DracError(errc));
|
||||||
|
|
||||||
|
return Err(DracError(DracErrorCode::NotFound, "Homebrew Cellar directory not found at: " + cellarPath.string())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<u64> dirCount = GetCountFromDirectory("homebrew", cellarPath, true);
|
||||||
|
|
||||||
|
if (!dirCount) {
|
||||||
|
if (dirCount.error().code != DracErrorCode::NotFound)
|
||||||
|
return dirCount;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
count += *dirCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn GetMacPortsCount() -> Result<u64> {
|
||||||
|
const PackageManagerInfo macPortsInfo = {
|
||||||
|
.id = "macports",
|
||||||
|
.dbPath = "/opt/local/var/macports/registry/registry.db",
|
||||||
|
.countQuery = "SELECT COUNT(*) FROM ports WHERE state='installed';",
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check if the database file exists before trying to query
|
||||||
|
std::error_code errc;
|
||||||
|
if (!fs::exists(macPortsInfo.dbPath, errc) || errc) {
|
||||||
|
if (errc && errc != std::errc::no_such_file_or_directory)
|
||||||
|
return Err(DracError(errc));
|
||||||
|
|
||||||
|
return Err(
|
||||||
|
DracError(DracErrorCode::NotFound, "MacPorts registry database not found at: " + macPortsInfo.dbPath.string())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetCountFromDb(macPortsInfo);
|
||||||
|
}
|
||||||
|
} // namespace package
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -99,6 +99,7 @@ namespace util {
|
||||||
: message(std::format("{}: {}", context, std::system_category().message(errno))), location(loc) {
|
: message(std::format("{}: {}", context, std::system_category().message(errno))), location(loc) {
|
||||||
using namespace matchit;
|
using namespace matchit;
|
||||||
using enum DracErrorCode;
|
using enum DracErrorCode;
|
||||||
|
|
||||||
code = match(errno)(
|
code = match(errno)(
|
||||||
is | EACCES = PermissionDenied,
|
is | EACCES = PermissionDenied,
|
||||||
is | ENOENT = NotFound,
|
is | ENOENT = NotFound,
|
||||||
|
|
|
@ -11,8 +11,6 @@
|
||||||
#include <utility> // std::pair (Pair)
|
#include <utility> // std::pair (Pair)
|
||||||
#include <vector> // std::vector (Vec)
|
#include <vector> // std::vector (Vec)
|
||||||
|
|
||||||
#include "include/matchit.h"
|
|
||||||
|
|
||||||
namespace util::types {
|
namespace util::types {
|
||||||
using u8 = std::uint8_t; ///< 8-bit unsigned integer.
|
using u8 = std::uint8_t; ///< 8-bit unsigned integer.
|
||||||
using u16 = std::uint16_t; ///< 16-bit unsigned integer.
|
using u16 = std::uint16_t; ///< 16-bit unsigned integer.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue