Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/app/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ pub struct KernelTree {
branch: String,
}

impl KernelTree {
pub fn new(path: String, branch: String) -> Self {
Self { path, branch }
}
}

impl Default for Config {
fn default() -> Self {
let home = env::var("HOME").unwrap_or_else(|_| {
Expand Down Expand Up @@ -151,6 +157,10 @@ impl Config {
self.page_size
}

pub fn add_kernel_tree(&mut self, id: String, kernel_tree: KernelTree) {
self.kernel_trees.insert(id, kernel_tree);
}

pub fn set_page_size(&mut self, page_size: usize) {
self.page_size = page_size;
}
Expand All @@ -176,6 +186,10 @@ impl Config {
self.git_am_options = git_am_options;
}

pub fn set_target_kernel_tree(&mut self, kernel_tree_id: Option<String>) {
self.target_kernel_tree = kernel_tree_id;
}

#[allow(dead_code)]
/// Returns the list of names of the registered kernel trees
pub fn kernel_trees(&self) -> HashSet<&String> {
Expand Down
2 changes: 1 addition & 1 deletion src/app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ impl App {
.details_actions
.as_ref()
.unwrap()
.apply_patchset(&self.config)
.apply_patchset(&mut self.config)
{
Ok(msg) => InfoPopUp::generate_info_popup("Patchset Apply Success", &msg),
Err(msg) => InfoPopUp::generate_info_popup("Patchset Apply Fail", &msg),
Expand Down
85 changes: 66 additions & 19 deletions src/app/screens/details_actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,18 +231,35 @@ impl DetailsActions {
/// Checks if there is a `target_kernel_tree` and if it is in `Config::kernel_trees` and if
/// that kernel tree is a valid git directory.
///
/// Returns the a valid `KernelTree` or a `String` with the error message on failure.
fn validate_kernel_tree<'a>(&self, config: &'a Config) -> Result<&'a KernelTree, String> {
let kernel_tree_id = if let Some(target) = config.target_kernel_tree() {
target
/// Returns the a valid `KernelTree` and whether it was auto-detected.
fn validate_kernel_tree(&self, config: &mut Config) -> Result<(KernelTree, bool), String> {
let (kernel_tree, is_autodetected) = if let Some(target) = config.target_kernel_tree() {
(config.get_kernel_tree(target)
.ok_or_else(|| format!("invalid target kernel tree '{target}'"))?.clone(), false)
} else {
return Err("target kernel tree unset".to_string());
};
let kernel_tree_path = self.get_current_kernel_tree()?;
let current_branch = self.get_current_branch(&KernelTree::new(
kernel_tree_path.clone(),
"".to_string(),
))?;
let kernel_tree = KernelTree::new(kernel_tree_path, current_branch);

let kernel_tree_id = kernel_tree.path()
.split('/')
.last()
.unwrap_or("default")
.to_string();

config.set_target_kernel_tree(Some(kernel_tree_id.clone()));
config.add_kernel_tree(
kernel_tree_id.clone(),
kernel_tree.clone(),
);
config
.save_patch_hub_config()
.map_err(|e| format!("failed to save config: {e}"))?;

let kernel_tree = if let Some(tree) = config.get_kernel_tree(kernel_tree_id) {
tree
} else {
return Err(format!("invalid target kernel tree '{kernel_tree_id}'"));
(kernel_tree, true)
};

let kernel_tree_path = Path::new(kernel_tree.path());
Expand All @@ -252,7 +269,7 @@ impl DetailsActions {
return Err(format!("{} isn't a git repository", kernel_tree.path()));
}

Ok(kernel_tree)
Ok((kernel_tree, is_autodetected))
}

// Ensures the kernel directory is not currently in another git operation,
Expand Down Expand Up @@ -318,6 +335,32 @@ impl DetailsActions {
Ok(())
}

/// Get the current kernel tree
///
/// Returns the kernel tree path as a `String` or a `String` with the error message on failure
fn get_current_kernel_tree(&self) -> Result<String, String> {
if Command::new("make")
.args(["-s", "kernelversion"])
.output()
.map_err(|_| "failed to get current kernel tree state".to_string())?
.status
.success()
{
let output = Command::new("git")
.args(["rev-parse", "--show-toplevel"])
.output()
.map_err(|_| "failed to get current kernel tree path".to_string())?;

if output.status.success() {
Ok(String::from_utf8_lossy(&output.stdout).trim().to_owned())
} else {
Err("not in a valid kernel tree".to_string())
}
} else {
Err("not in a valid kernel tree".to_string())
}
}

/// Get the current branch of the supplied kernel tree
///
/// Returns the branch name as a `String` or a `String` with the error message on failure
Expand Down Expand Up @@ -435,19 +478,23 @@ impl DetailsActions {
/// Returns a `Result<String, String>` containing either the success or the error message.
/// # TODO:
/// - Add unit tests
pub fn apply_patchset(&self, config: &Config) -> Result<String, String> {
let kernel_tree = self.validate_kernel_tree(config)?;
self.check_git_state(kernel_tree)?;
pub fn apply_patchset(&self, config: &mut Config) -> Result<String, String> {
let (kernel_tree, is_autodetected) = self.validate_kernel_tree(config)?;
self.check_git_state(&kernel_tree)?;

let original_branch = self.get_current_branch(kernel_tree)?;
let target_branch = self.create_target_branch(kernel_tree, config)?;
let original_branch = self.get_current_branch(&kernel_tree)?;
let target_branch = self.create_target_branch(&kernel_tree, config)?;

let git_am_result = self.run_git_am(kernel_tree, config);
self.switch_to_branch(kernel_tree, &original_branch)?;
let git_am_result = self.run_git_am(&kernel_tree, config);
self.switch_to_branch(&kernel_tree, &original_branch)?;

match git_am_result {
Ok(_) => {
Ok(format!(" Patchset '{}' applied successfully!\n\n - Kernel Tree: '{}'\n\n - Base Branch: '{}'\n\n - Applied branch: '{}'", self.representative_patch.title(), kernel_tree.path(), kernel_tree.branch(), &target_branch))
Ok(format!(" Patchset '{}' applied successfully!\n\n - Kernel Tree: '{}'{}\n\n - Base Branch: '{}'{}\n\n - Applied branch: '{}'",
self.representative_patch.title(),
kernel_tree.path(), if is_autodetected { " (auto-detected)" } else { "" },
kernel_tree.branch(), if is_autodetected { " (auto-detected)" } else { "" },
&target_branch))
},
Err(e) => Err(format!( "`git am` failed\n{}{}", &original_branch, e))
}
Expand Down