Skip to content

feat: uninstall#95

Open
addrian-77 wants to merge 1 commit into
feat/install_reworkfrom
add/uninstall
Open

feat: uninstall#95
addrian-77 wants to merge 1 commit into
feat/install_reworkfrom
add/uninstall

Conversation

@addrian-77
Copy link
Copy Markdown

Pull Request Overview

This pull request adds the uninstall feature

TODO or Help Wanted

Checks

Using Rust tooling

  • Ran cargo fmt
  • Ran cargo clippy
  • Ran cargo test
  • Ran cargo build

Features tested:

  • uninstall on microbit-v2
  • I tested on apps installed both from tockloader-rs and the python version. Both features, individual app or Delete all work as intended. Removing an app that is located in the middle of the list will result in a left shift of remaining apps.

GitHub Issue

This pull request closes <Implement uninstall #88 >

@addrian-77 addrian-77 self-assigned this Sep 12, 2025
@addrian-77 addrian-77 linked an issue Sep 12, 2025 that may be closed by this pull request
@eva-cosma
Copy link
Copy Markdown
Collaborator

@addrian-77 Should we close this? After we have reorder_apps, we will uninstall stuff using it. What do you think?

@addrian-77 addrian-77 changed the base branch from main to feat/install_rework April 16, 2026 18:28
@addrian-77 addrian-77 force-pushed the add/uninstall branch 2 times, most recently from 1bc82cf to 91c0c94 Compare April 17, 2026 19:30
Comment thread tockloader-cli/src/main.rs Outdated
Comment on lines +255 to +263
match installed_apps
.iter()
.find(|iter| iter.tbf_header.get_package_name().unwrap_or("") == app_name)
{
Some(_) => conn
.uninstall_app(Some(app_name.to_string()), None)
.await
.context("Failed to uninstall app.")?,
None => panic!("Specified app is not installed!"),
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of match and panic on none, you can use expect

Comment thread tockloader-cli/src/main.rs Outdated
let app_name = sub_matches.get_one::<String>("name").map(String::as_str);

if installed_apps.is_empty() {
panic!("No apps installed");
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't panic, I would just write a message to the user.

Comment on lines +24 to +51
#[derive(Debug)]
pub struct AppOption<'a> {
pub index: usize,
pub app: &'a AppAttributes,
}

impl<'a> std::fmt::Display for AppOption<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if self.index == 0 {
write!(f, "Delete all")
} else {
write!(
f,
"{}. {} - start: {:#x}, size: {}, type: {}",
self.index,
self.app.tbf_header.get_package_name().unwrap_or(""),
self.app.address,
self.app.tbf_header.total_size(),
if self.app.tbf_header.get_fixed_address_flash().is_none() {
"C (flexible)"
} else {
"Rust (fixed)"
}
)
}
}
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this structure only used in CLI? What is its purpose?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it is used for displaying the list of installed apps.


let mut address = settings.start_address;
for app in app_attributes_list.iter() {
let address = app.address;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the reasoning behind this change?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is simpler and safer this way, the apps can be spaced out in memory and incrementing the address might not work every time. We already have every app's address and size.

Comment thread tockloader-lib/src/lib.rs
pub trait CommandUninstall {
async fn uninstall_app(
&mut self,
app_name: Option<String>,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does uninstalling an with None name mean?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When calling the uninstall option we can specify the name of the app (or not), that's why the name is optional. If name is specified, index is None.

Comment thread tockloader-lib/src/lib.rs
async fn uninstall_app(
&mut self,
app_name: Option<String>,
app_index: Option<usize>,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this index for?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This parameter is the selected index from the provided apps list. When --name is not used, app_name is None and index is Some(value). There is no scenario in which both have Some() or None values.

Copy link
Copy Markdown
Collaborator

@eva-cosma eva-cosma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am a bit confused why you made some of the design choices like you did. I would like some doc comments that explain it for both the user and me why what and how

Signed-off-by: Adrian Lungu <lunguadrian30@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement uninstall using reorder_apps

2 participants