Skip to content

Commit c7d64a1

Browse files
fix: upgrade edge-cases
1 parent fa066f5 commit c7d64a1

2 files changed

Lines changed: 117 additions & 30 deletions

File tree

src/commands/add.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ pub fn handle_add(apk: &Apk, args: &[String]) {
2929
};
3030

3131
let mut resolved_args: Vec<String> = Vec::new();
32+
let mut resolved_packages: Vec<String> = Vec::new();
3233
let mut has_incompatible = false;
3334

3435
for arg in args {
@@ -40,6 +41,7 @@ pub fn handle_add(apk: &Apk, args: &[String]) {
4041
match find_best_compatible_version(arg, &os_version, &index) {
4142
Some(pkg) => {
4243
resolved_args.push(format!("{}={}", pkg.name, pkg.version));
44+
resolved_packages.push(pkg.name.clone());
4345
}
4446
None => {
4547
let has_any_version = index.iter().any(|p| p.name == *arg);
@@ -66,6 +68,10 @@ pub fn handle_add(apk: &Apk, args: &[String]) {
6668
if result.is_err() {
6769
process::exit(1);
6870
}
71+
72+
if !resolved_packages.is_empty() {
73+
clean_world_file_pins(&resolved_packages);
74+
}
6975
}
7076

7177
fn run_add_directly(apk: &Apk, args: &[String]) {
@@ -120,3 +126,26 @@ fn get_repo_url() -> Option<String> {
120126
}
121127
None
122128
}
129+
130+
fn clean_world_file_pins(packages: &[String]) {
131+
let world_path = format!("{VELLUM_ROOT}/etc/apk/world");
132+
let content = match fs::read_to_string(&world_path) {
133+
Ok(c) => c,
134+
Err(_) => return,
135+
};
136+
137+
let new_content: String = content
138+
.lines()
139+
.map(|line| {
140+
for pkg in packages {
141+
if line.starts_with(&format!("{pkg}=")) {
142+
return pkg.clone();
143+
}
144+
}
145+
line.to_string()
146+
})
147+
.collect::<Vec<_>>()
148+
.join("\n");
149+
150+
let _ = fs::write(&world_path, new_content + "\n");
151+
}

src/commands/upgrade.rs

Lines changed: 88 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ pub fn handle_upgrade(
5656
process::exit(1);
5757
}
5858

59-
println!("All packages have compatible versions. Syncing OS version...");
59+
println!("All packages have compatible versions. Preparing upgrade...");
6060

6161
let arch = get_apk_arch();
6262
let repo_dir = format!("{VELLUM_ROOT}/local-repo/{arch}");
@@ -73,32 +73,7 @@ pub fn handle_upgrade(
7373
eprintln!("warning: failed to update local repo index: {e}");
7474
}
7575

76-
let pkg_version = format!("remarkable-os={os_cur}-r0");
77-
if let Err(e) = apk.run_silent(&["add", &pkg_version]) {
78-
eprintln!("warning: failed to register remarkable-os package: {e}");
79-
}
80-
81-
match apk.get_package_version("remarkable-os") {
82-
Ok(Some(installed_ver)) if installed_ver == os_cur => {
83-
if let Err(e) = state.set_os_version(os_cur) {
84-
eprintln!("warning: failed to save OS version: {e}");
85-
}
86-
}
87-
Ok(Some(installed_ver)) => {
88-
eprintln!("error: remarkable-os package is at {installed_ver}, expected {os_cur}");
89-
eprintln!("OS version sync failed. Run 'vellum upgrade' to retry.");
90-
process::exit(1);
91-
}
92-
Ok(None) => {
93-
eprintln!("error: remarkable-os package not found after installation");
94-
process::exit(1);
95-
}
96-
Err(e) => {
97-
eprintln!("warning: could not verify remarkable-os version: {e}");
98-
}
99-
}
100-
101-
println!("Upgrading packages...");
76+
clean_world_file_pins(apk);
10277
}
10378

10479
let mut simulate_args = vec!["upgrade", "--simulate"];
@@ -130,6 +105,17 @@ pub fn handle_upgrade(
130105
}
131106

132107
if packages.is_empty() {
108+
if os_mismatch {
109+
match apk.get_package_version("remarkable-os") {
110+
Ok(Some(installed_ver)) if installed_ver == os_cur => {
111+
if let Err(e) = state.set_os_version(os_cur) {
112+
eprintln!("warning: failed to save OS version: {e}");
113+
}
114+
println!("OS version synced to {os_cur}");
115+
}
116+
_ => {}
117+
}
118+
}
133119
println!("No packages to upgrade.");
134120
return;
135121
}
@@ -159,9 +145,37 @@ pub fn handle_upgrade(
159145
}
160146
upgrade_args.extend(remaining_args.iter().map(|s| s.as_str()));
161147

162-
if let Err(e) = apk.exec(&upgrade_args) {
163-
eprintln!("exec error: {e}");
164-
process::exit(1);
148+
if os_mismatch {
149+
if let Err(e) = apk.run(&upgrade_args) {
150+
eprintln!("upgrade error: {e}");
151+
process::exit(1);
152+
}
153+
154+
match apk.get_package_version("remarkable-os") {
155+
Ok(Some(installed_ver)) if installed_ver == os_cur => {
156+
if let Err(e) = state.set_os_version(os_cur) {
157+
eprintln!("warning: failed to save OS version: {e}");
158+
}
159+
println!("OS version synced to {os_cur}");
160+
}
161+
Ok(Some(installed_ver)) => {
162+
eprintln!("error: remarkable-os package is at {installed_ver}, expected {os_cur}");
163+
eprintln!("OS version sync failed. Run 'vellum upgrade' to retry.");
164+
process::exit(1);
165+
}
166+
Ok(None) => {
167+
eprintln!("error: remarkable-os package not found after upgrade");
168+
process::exit(1);
169+
}
170+
Err(e) => {
171+
eprintln!("warning: could not verify remarkable-os version: {e}");
172+
}
173+
}
174+
} else {
175+
if let Err(e) = apk.exec(&upgrade_args) {
176+
eprintln!("exec error: {e}");
177+
process::exit(1);
178+
}
165179
}
166180
}
167181

@@ -243,3 +257,47 @@ fn get_repo_url() -> Option<String> {
243257
None
244258
}
245259

260+
fn clean_world_file_pins(apk: &Apk) {
261+
let installed = match apk.list_installed() {
262+
Ok(list) => list,
263+
Err(_) => return,
264+
};
265+
266+
let packages_with_os_dep: Vec<String> = installed
267+
.into_iter()
268+
.filter(|p| !VIRTUAL_PKGS.contains(&p.as_str()))
269+
.filter(|p| {
270+
if let Ok(deps) = apk.get_dependencies(p) {
271+
deps.iter().any(|d| d.contains("remarkable-os"))
272+
} else {
273+
false
274+
}
275+
})
276+
.collect();
277+
278+
if packages_with_os_dep.is_empty() {
279+
return;
280+
}
281+
282+
let world_path = format!("{VELLUM_ROOT}/etc/apk/world");
283+
let content = match fs::read_to_string(&world_path) {
284+
Ok(c) => c,
285+
Err(_) => return,
286+
};
287+
288+
let new_content: String = content
289+
.lines()
290+
.map(|line| {
291+
for pkg in &packages_with_os_dep {
292+
if line.starts_with(&format!("{pkg}=")) {
293+
return pkg.clone();
294+
}
295+
}
296+
line.to_string()
297+
})
298+
.collect::<Vec<_>>()
299+
.join("\n");
300+
301+
let _ = fs::write(&world_path, new_content + "\n");
302+
}
303+

0 commit comments

Comments
 (0)