Skip to content

Commit 5211aca

Browse files
authored
Update upgrade.rs
1 parent 93a3d69 commit 5211aca

1 file changed

Lines changed: 150 additions & 150 deletions

File tree

source-code/src/commands/upgrade.rs

Lines changed: 150 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -8,214 +8,214 @@ use crate::{config, output, progress};
88

99
fn local_version_file() -> PathBuf {
1010
config::home()
11-
.join(".hackeros")
12-
.join("hnm")
13-
.join("version.hacker")
11+
.join(".hackeros")
12+
.join("hnm")
13+
.join("version.hacker")
1414
}
1515

1616
fn tmp_version_file() -> PathBuf {
1717
std::env::temp_dir().join(".hnm_upstream_version.hacker")
1818
}
1919

2020
const UPSTREAM_VERSION_URL: &str =
21-
"https://raw.githubusercontent.com/HackerOS-Linux-System/HackerOS-Nix-Manager/main/version.hacker";
21+
"https://raw.githubusercontent.com/HackerOS-Linux-System/HackerOS-Nix-Manager/main/version.hacker";
2222

23-
const UPSTREAM_RELEASE_URL: &str =
23+
const UPSTREAM_RELEASE_URL: &str =
2424
"https://github.com/HackerOS-Linux-System/HackerOS-Nix-Manager/releases/download";
2525

26-
// ─── version.hacker parser ────────────────────────────────────────────────────
27-
// Format:
28-
// [
29-
// 0.1
30-
// ]
31-
32-
fn parse_version(content: &str) -> Option<String> {
33-
for line in content.lines() {
34-
let t = line.trim().trim_matches('[').trim_matches(']').trim();
35-
if t.is_empty() { continue; }
36-
// Validate it looks like a version (digits and dots only)
37-
if t.chars().all(|c| c.is_ascii_digit() || c == '.') {
38-
return Some(t.to_string());
39-
}
26+
// ─── version.hacker parser ────────────────────────────────────────────────────
27+
// Format:
28+
// [
29+
// 0.1
30+
// ]
31+
32+
fn parse_version(content: &str) -> Option<String> {
33+
for line in content.lines() {
34+
let t = line.trim().trim_matches('[').trim_matches(']').trim();
35+
if t.is_empty() { continue; }
36+
// Validate it looks like a version (digits and dots only)
37+
if t.chars().all(|c| c.is_ascii_digit() || c == '.') {
38+
return Some(t.to_string());
4039
}
41-
None
4240
}
41+
None
42+
}
4343

44-
fn version_greater(upstream: &str, local: &str) -> bool {
45-
let parse = |s: &str| -> Vec<u64> {
46-
s.split('.').map(|p| p.parse().unwrap_or(0)).collect()
47-
};
48-
let u = parse(upstream);
49-
let l = parse(local);
50-
let max_len = u.len().max(l.len());
51-
for i in 0..max_len {
52-
let ui = u.get(i).copied().unwrap_or(0);
53-
let li = l.get(i).copied().unwrap_or(0);
54-
if ui > li { return true; }
55-
if ui < li { return false; }
56-
}
57-
false
44+
fn version_greater(upstream: &str, local: &str) -> bool {
45+
let parse = |s: &str| -> Vec<u64> {
46+
s.split('.').map(|p| p.parse().unwrap_or(0)).collect()
47+
};
48+
let u = parse(upstream);
49+
let l = parse(local);
50+
let max_len = u.len().max(l.len());
51+
for i in 0..max_len {
52+
let ui = u.get(i).copied().unwrap_or(0);
53+
let li = l.get(i).copied().unwrap_or(0);
54+
if ui > li { return true; }
55+
if ui < li { return false; }
5856
}
57+
false
58+
}
5959

60-
// ─── network helpers ──────────────────────────────────────────────────────────
60+
// ─── network helpers ──────────────────────────────────────────────────────────
6161

62-
fn curl_download(url: &str, dest: &PathBuf, task: &progress::TaskProgress) -> Result<()> {
63-
task.log(&format!("curl -fsSL {} -o {}", url, dest.display()));
64-
let status = Command::new("curl")
62+
fn curl_download(url: &str, dest: &PathBuf, task: &progress::TaskProgress) -> Result<()> {
63+
task.log(&format!("curl -fsSL {} -o {}", url, dest.display()));
64+
let status = Command::new("curl")
6565
.args(["-fsSL", url, "-o", dest.to_str().unwrap()])
6666
.status()
6767
.map_err(|e| anyhow!("curl not found: {}", e))?;
68-
if !status.success() {
69-
return Err(anyhow!("curl failed downloading {}", url));
70-
}
71-
Ok(())
68+
if !status.success() {
69+
return Err(anyhow!("curl failed downloading {}", url));
7270
}
71+
Ok(())
72+
}
7373

74-
// ─── main upgrade logic ───────────────────────────────────────────────────────
74+
// ─── main upgrade logic ───────────────────────────────────────────────────────
7575

76-
pub fn run() -> Result<()> {
77-
output::header("HNM Self-Upgrade");
76+
pub fn run() -> Result<()> {
77+
output::header("HNM Self-Upgrade");
7878

79-
// ── 1. Read local version ─────────────────────────────────────────────────
80-
let local_ver_path = local_version_file();
81-
let local_version = if local_ver_path.exists() {
82-
let content = fs::read_to_string(&local_ver_path)
79+
// ── 1. Read local version ─────────────────────────────────────────────────
80+
let local_ver_path = local_version_file();
81+
let local_version = if local_ver_path.exists() {
82+
let content = fs::read_to_string(&local_ver_path)
8383
.map_err(|e| anyhow!("cannot read {}: {}", local_ver_path.display(), e))?;
84-
parse_version(&content)
84+
parse_version(&content)
8585
.ok_or_else(|| anyhow!("cannot parse local version file at {}", local_ver_path.display()))?
86-
} else {
87-
// Create with current cargo version as default
88-
let ver = env!("CARGO_PKG_VERSION").to_string();
89-
output::warn(&format!(
90-
"local version file not found at {} — creating with version {}",
91-
local_ver_path.display(), ver
92-
));
93-
if let Some(parent) = local_ver_path.parent() {
94-
fs::create_dir_all(parent)?;
95-
}
96-
let content = format!("[\n {}\n]\n", ver);
97-
fs::write(&local_ver_path, &content)?;
98-
ver
99-
};
100-
101-
output::label("current version", &local_version);
102-
103-
// ── 2. Download upstream version.hacker ──────────────────────────────────
104-
{
105-
let task = progress::TaskProgress::new(100, "checking for updates...");
106-
task.log(&format!("fetching {}", UPSTREAM_VERSION_URL));
107-
108-
let tmp = tmp_version_file();
109-
let result = curl_download(UPSTREAM_VERSION_URL, &tmp, &task);
110-
task.inc(50);
111-
112-
match result {
113-
Ok(_) => task.finish_ok("version info fetched"),
114-
Err(e) => {
115-
task.finish_err(&format!("{}", e));
116-
output::warn("Could not reach GitHub — check your internet connection.");
117-
return Err(anyhow!("cannot check for updates: {}", e));
118-
}
119-
}
86+
} else {
87+
// Create with current cargo version as default
88+
let ver = env!("CARGO_PKG_VERSION").to_string();
89+
output::warn(&format!(
90+
"local version file not found at {} — creating with version {}",
91+
local_ver_path.display(), ver
92+
));
93+
if let Some(parent) = local_ver_path.parent() {
94+
fs::create_dir_all(parent)?;
12095
}
96+
let content = format!("[\n {}\n]\n", ver);
97+
fs::write(&local_ver_path, &content)?;
98+
ver
99+
};
121100

122-
// ── 3. Parse upstream version ─────────────────────────────────────────────
123-
let tmp = tmp_version_file();
124-
let upstream_content = fs::read_to_string(&tmp)
125-
.map_err(|e| anyhow!("cannot read downloaded version file: {}", e))?;
126-
let _ = fs::remove_file(&tmp);
127-
128-
let upstream_version = parse_version(&upstream_content)
129-
.ok_or_else(|| anyhow!("cannot parse upstream version.hacker"))?;
101+
output::label("current version", &local_version);
130102

131-
output::label("latest version", &upstream_version);
103+
// ── 2. Download upstream version.hacker ──────────────────────────────────
104+
{
105+
let task = progress::TaskProgress::new(100, "checking for updates...");
106+
task.log(&format!("fetching {}", UPSTREAM_VERSION_URL));
132107

133-
// ── 4. Compare ────────────────────────────────────────────────────────────
134-
if !version_greater(&upstream_version, &local_version) {
135-
println!();
136-
output::ok(&format!("HNM is up to date (v{})", local_version));
137-
return Ok(());
108+
let tmp = tmp_version_file();
109+
let result = curl_download(UPSTREAM_VERSION_URL, &tmp, &task);
110+
task.inc(50);
111+
112+
match result {
113+
Ok(_) => task.finish_ok("version info fetched"),
114+
Err(e) => {
115+
task.finish_err(&format!("{}", e));
116+
output::warn("Could not reach GitHub — check your internet connection.");
117+
return Err(anyhow!("cannot check for updates: {}", e));
118+
}
138119
}
120+
}
139121

140-
println!();
141-
output::info(&format!(
142-
"New version available: {} → {}",
143-
local_version, upstream_version
144-
));
145-
println!();
122+
// ── 3. Parse upstream version ─────────────────────────────────────────────
123+
let tmp = tmp_version_file();
124+
let upstream_content = fs::read_to_string(&tmp)
125+
.map_err(|e| anyhow!("cannot read downloaded version file: {}", e))?;
126+
let _ = fs::remove_file(&tmp);
146127

147-
// ── 5. Download new binary ────────────────────────────────────────────────
148-
let download_url = format!("{}/v{}/hnm", UPSTREAM_RELEASE_URL, upstream_version);
149-
let tmp_bin = std::env::temp_dir().join(".hnm_upgrade_bin");
128+
let upstream_version = parse_version(&upstream_content)
129+
.ok_or_else(|| anyhow!("cannot parse upstream version.hacker"))?;
150130

151-
{
152-
let task = progress::TaskProgress::new(100, &format!("downloading hnm v{}", upstream_version));
153-
task.log(&format!("curl -fsSL {} -o {}", download_url, tmp_bin.display()));
131+
output::label("latest version", &upstream_version);
154132

155-
let result = curl_download(&download_url, &tmp_bin, &task);
156-
task.inc(70);
133+
// ── 4. Compare ────────────────────────────────────────────────────────────
134+
if !version_greater(&upstream_version, &local_version) {
135+
println!();
136+
output::ok(&format!("HNM is up to date (v{})", local_version));
137+
return Ok(());
138+
}
157139

158-
match result {
159-
Ok(_) => { task.inc(30); task.finish_ok("binary downloaded"); }
160-
Err(e) => {
161-
task.finish_err(&format!("{}", e));
162-
return Err(anyhow!("failed to download new binary: {}", e));
163-
}
140+
println!();
141+
output::info(&format!(
142+
"New version available: {} → {}",
143+
local_version, upstream_version
144+
));
145+
println!();
146+
147+
// ── 5. Download new binary ────────────────────────────────────────────────
148+
let download_url = format!("{}/v{}/hnm", UPSTREAM_RELEASE_URL, upstream_version);
149+
let tmp_bin = std::env::temp_dir().join(".hnm_upgrade_bin");
150+
151+
{
152+
let task = progress::TaskProgress::new(100, &format!("downloading hnm v{}", upstream_version));
153+
task.log(&format!("curl -fsSL {} -o {}", download_url, tmp_bin.display()));
154+
155+
let result = curl_download(&download_url, &tmp_bin, &task);
156+
task.inc(70);
157+
158+
match result {
159+
Ok(_) => { task.inc(30); task.finish_ok("binary downloaded"); }
160+
Err(e) => {
161+
task.finish_err(&format!("{}", e));
162+
return Err(anyhow!("failed to download new binary: {}", e));
164163
}
165164
}
165+
}
166166

167-
// ── 6. chmod +x ──────────────────────────────────────────────────────────
168-
let chmod_ok = Command::new("chmod")
167+
// ── 6. chmod +x ──────────────────────────────────────────────────────────
168+
let chmod_ok = Command::new("chmod")
169169
.args(["a+x", tmp_bin.to_str().unwrap()])
170170
.status()
171171
.map(|s| s.success())
172172
.unwrap_or(false);
173173

174-
if !chmod_ok {
175-
return Err(anyhow!("chmod a+x failed on downloaded binary"));
176-
}
174+
if !chmod_ok {
175+
return Err(anyhow!("chmod a+x failed on downloaded binary"));
176+
}
177177

178-
// ── 7. sudo mv to /usr/bin/hnm ───────────────────────────────────────────
179-
output::info("Installing to /usr/bin/hnm (requires sudo)...");
178+
// ── 7. sudo mv to /usr/bin/hnm ───────────────────────────────────────────
179+
output::info("Installing to /usr/bin/hnm (requires sudo)...");
180180

181-
{
182-
let task = progress::TaskProgress::new(100, "installing to /usr/bin/hnm");
183-
task.log("sudo rm -rf /usr/bin/hnm");
181+
{
182+
let task = progress::TaskProgress::new(100, "installing to /usr/bin/hnm");
183+
task.log("sudo rm -rf /usr/bin/hnm");
184184

185-
let rm_ok = Command::new("sudo")
185+
let rm_ok = Command::new("sudo")
186186
.args(["rm", "-rf", "/usr/bin/hnm"])
187187
.status()
188188
.map(|s| s.success())
189189
.unwrap_or(false);
190190

191-
if !rm_ok {
192-
task.finish_err("sudo rm /usr/bin/hnm failed");
193-
return Err(anyhow!("failed to remove old /usr/bin/hnm — do you have sudo?"));
194-
}
195-
task.inc(30);
191+
if !rm_ok {
192+
task.finish_err("sudo rm /usr/bin/hnm failed");
193+
return Err(anyhow!("failed to remove old /usr/bin/hnm — do you have sudo?"));
194+
}
195+
task.inc(30);
196196

197-
task.log(&format!("sudo mv {} /usr/bin/hnm", tmp_bin.display()));
198-
let mv_ok = Command::new("sudo")
197+
task.log(&format!("sudo mv {} /usr/bin/hnm", tmp_bin.display()));
198+
let mv_ok = Command::new("sudo")
199199
.args(["mv", tmp_bin.to_str().unwrap(), "/usr/bin/hnm"])
200200
.status()
201201
.map(|s| s.success())
202202
.unwrap_or(false);
203203

204-
if !mv_ok {
205-
task.finish_err("sudo mv failed");
206-
return Err(anyhow!("failed to move binary to /usr/bin/hnm"));
207-
}
208-
task.inc(70);
209-
task.finish_ok(&format!("hnm v{} installed to /usr/bin/hnm", upstream_version));
204+
if !mv_ok {
205+
task.finish_err("sudo mv failed");
206+
return Err(anyhow!("failed to move binary to /usr/bin/hnm"));
210207
}
208+
task.inc(70);
209+
task.finish_ok(&format!("hnm v{} installed to /usr/bin/hnm", upstream_version));
210+
}
211211

212-
// ── 8. Update local version file ─────────────────────────────────────────
213-
let new_content = format!("[\n {}\n]\n", upstream_version);
214-
fs::write(&local_ver_path, new_content)?;
212+
// ── 8. Update local version file ─────────────────────────────────────────
213+
let new_content = format!("[\n {}\n]\n", upstream_version);
214+
fs::write(&local_ver_path, new_content)?;
215215

216-
println!();
217-
output::ok(&format!("HNM upgraded v{} → v{}", local_version, upstream_version));
218-
output::dim("Run `hnm version` to confirm.");
216+
println!();
217+
output::ok(&format!("HNM upgraded v{} → v{}", local_version, upstream_version));
218+
output::dim("Run `hnm version` to confirm.");
219219

220-
Ok(())
221-
}
220+
Ok(())
221+
}

0 commit comments

Comments
 (0)