1+ // clang-format off
2+ #include " utils/cortex_utils.h"
3+ // clang-format on
4+ #include " cortex_upd_cmd.h"
5+ #include " httplib.h"
6+ #include " nlohmann/json.hpp"
7+ #include " services/download_service.h"
8+ #include " utils/archive_utils.h"
9+ #include " utils/logging_utils.h"
10+ #include " utils/system_info_utils.h"
11+ #if defined(_WIN32) || defined(__linux__)
12+ #include " utils/file_manager_utils.h"
13+ #endif
14+
15+ namespace commands {
16+ CortexUpdCmd::CortexUpdCmd () {}
17+
18+ void CortexUpdCmd::Exec () {
19+ std::cout << " 1" << std::endl;
20+ // Check if the architecture and OS are supported
21+ auto system_info = system_info_utils::GetSystemInfo ();
22+ if (system_info.arch == system_info_utils::kUnsupported ||
23+ system_info.os == system_info_utils::kUnsupported ) {
24+ CTL_ERR (" Unsupported OS or architecture: " << system_info.os << " , "
25+ << system_info.arch );
26+ return ;
27+ }
28+ CTL_INF (" OS: " << system_info.os << " , Arch: " << system_info.arch );
29+
30+ // Download file
31+ constexpr auto github_host = " https://api.github.com" ;
32+ // std::string version = version_.empty() ? "latest" : version_;
33+ std::string version = " latest" ;
34+ std::ostringstream release_path;
35+ release_path << " /repos/janhq/cortex.cpp/releases/" << version;
36+ CTL_INF (" Engine release path: " << github_host << release_path.str ());
37+
38+ httplib::Client cli (github_host);
39+ if (auto res = cli.Get (release_path.str ())) {
40+ if (res->status == httplib::StatusCode::OK_200) {
41+ try {
42+ auto jsonResponse = nlohmann::json::parse (res->body );
43+ auto assets = jsonResponse[" assets" ];
44+ auto os_arch{system_info.os + " -" + system_info.arch };
45+
46+ std::string matched_variant = " " ;
47+ for (auto & asset : assets) {
48+ auto asset_name = asset[" name" ].get <std::string>();
49+ if (asset_name.find (" cortex-cpp" ) != std::string::npos &&
50+ asset_name.find (os_arch) != std::string::npos) {
51+ matched_variant = asset_name;
52+ break ;
53+ }
54+ CTL_INF (asset_name);
55+ }
56+ if (matched_variant.empty ()) {
57+ CTL_ERR (" No variant found for " << os_arch);
58+ return ;
59+ }
60+ CTL_INF (" Matched variant: " << matched_variant);
61+
62+ for (auto & asset : assets) {
63+ auto asset_name = asset[" name" ].get <std::string>();
64+ if (asset_name == matched_variant) {
65+ std::string host{" https://github.com" };
66+
67+ auto full_url = asset[" browser_download_url" ].get <std::string>();
68+ std::string path = full_url.substr (host.length ());
69+
70+ auto fileName = asset[" name" ].get <std::string>();
71+ CTL_INF (" URL: " << full_url);
72+
73+ auto download_task = DownloadTask{.id = " cortex" ,
74+ .type = DownloadType::Cortex,
75+ .error = std::nullopt ,
76+ .items = {DownloadItem{
77+ .id = " cortex" ,
78+ .host = host,
79+ .fileName = fileName,
80+ .type = DownloadType::Cortex,
81+ .path = path,
82+ }}};
83+
84+ DownloadService download_service;
85+ download_service.AddDownloadTask (
86+ download_task,
87+ [this ](const std::string& absolute_path, bool unused) {
88+ // try to unzip the downloaded file
89+ std::filesystem::path download_path{absolute_path};
90+ CTL_INF (" Downloaded engine path: " << download_path.string ());
91+
92+ std::filesystem::path extract_path =
93+ download_path.parent_path ().parent_path ();
94+
95+ archive_utils::ExtractArchive (download_path.string (),
96+ extract_path.string ());
97+
98+ // remove the downloaded file
99+ // TODO(any) Could not delete file on Windows because it is currently hold by httplib(?)
100+ // Not sure about other platforms
101+ try {
102+ std::filesystem::remove (absolute_path);
103+ } catch (const std::exception& e) {
104+ CTL_WRN (" Could not delete file: " << e.what ());
105+ }
106+ CTL_INF (" Finished!" );
107+ });
108+ break ;
109+ }
110+ }
111+ } catch (const nlohmann::json::parse_error& e) {
112+ std::cerr << " JSON parse error: " << e.what () << std::endl;
113+ return ;
114+ }
115+ } else {
116+ CTL_ERR (" HTTP error: " << res->status );
117+ return ;
118+ }
119+ } else {
120+ auto err = res.error ();
121+ CTL_ERR (" HTTP error: " << httplib::to_string (err));
122+ return ;
123+ }
124+ #if defined(_WIN32)
125+ std::string temp = " .\\ cortex-cpp_tmp.exe" ;
126+ remove (temp.c_str ()); // ignore return code
127+
128+ std::string src = " .\\ misc\\ cortex-cpp\\ cortex-cpp.exe" ;
129+ std::string dst = " .\\ cortex-cpp.exe" ;
130+ // Rename
131+ rename (dst.c_str (), temp.c_str ());
132+ // Update
133+ CopyFile (const_cast <char *>(src.c_str ()), const_cast <char *>(dst.c_str ()),
134+ false );
135+ #else
136+ std::string src = " ./misc/cortex-cpp/cortex-cpp" ;
137+ std::string dst = " ./cortex-cpp" ;
138+ std::filesystem::copy_file (src, dst,
139+ std::filesystem::copy_options::overwrite_existing);
140+ #endif
141+ CLI_LOG (" Update cortex sucessfully" );
142+ }
143+ } // namespace commands
0 commit comments