diff --git a/CHANGELOG.md b/CHANGELOG.md index 6921438..9fa0c55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/). - Added commit hash based install/update for security reasons. - `install.sh` file for easy install in Linux. +### Fxied + +- Themes being saved in eiipm installed package database. + ## [0.3.0] - 2025-08-22 ### Added diff --git a/deprecated/git.mod.bak.rs b/deprecated/git.mod.bak.rs deleted file mode 100644 index bba1c77..0000000 --- a/deprecated/git.mod.bak.rs +++ /dev/null @@ -1,182 +0,0 @@ -//! Working with git2 API's - -use crate::other::confirm_action::confirm; -use git2::{Cred, Error, FetchOptions, RemoteCallbacks, Repository, build::RepoBuilder}; -use std::fs; -use std::path::Path; - -pub fn clone_https(repo_url: &str, path: &Path, depth: Option) -> Result { - let callbacks = RemoteCallbacks::new(); - - // Set up fetch options - let mut fetch_options = FetchOptions::new(); - fetch_options.remote_callbacks(callbacks); - - // Apply shallow clone if depth is specified - if let Some(d) = depth { - fetch_options.depth(d as i32); - } - - // Use RepoBuilder directly - let mut builder = RepoBuilder::new(); - builder.fetch_options(fetch_options); - - let repo = builder.clone(repo_url, path)?; - Ok(repo) -} - -pub fn pull_https(repo: &Repository) -> Result<(), Error> { - let head_ref = repo.head()?; - let branch_name = head_ref - .shorthand() - .ok_or_else(|| Error::from_str("Invalid branch"))?; - - // Fetch remote branch - let callbacks = RemoteCallbacks::new(); - let mut fetch_options = FetchOptions::new(); - fetch_options.remote_callbacks(callbacks); - - let mut remote = repo.find_remote("origin")?; - remote.fetch(&[branch_name], Some(&mut fetch_options), None)?; - - // Find fetched commit - let fetch_ref = repo.find_reference(&format!("refs/remotes/origin/{}", branch_name))?; - let fetch_commit = repo.reference_to_annotated_commit(&fetch_ref)?; - - // Merge analysis - let analysis = repo.merge_analysis(&[&fetch_commit])?; - - if analysis.0.is_fast_forward() { - // Fast-forward - let mut ref_to_update = repo.find_reference(head_ref.name().unwrap())?; - ref_to_update.set_target(fetch_commit.id(), "Fast-forward")?; - repo.set_head(head_ref.name().unwrap())?; - repo.checkout_head(Some(git2::build::CheckoutBuilder::default().force()))?; - log::info!("Fast-forward merge completed"); - } else { - // Real merge - log::info!("Fast-forward not possible, performing merge..."); - - let head_commit = repo.reference_to_annotated_commit(&head_ref)?; - let head_tree = repo.find_commit(head_commit.id())?.tree()?; - let fetch_tree = repo.find_commit(fetch_commit.id())?.tree()?; - - let ancestor_commit = repo - .merge_base(head_commit.id(), fetch_commit.id()) - .and_then(|oid| repo.find_commit(oid))?; - let ancestor_tree = ancestor_commit.tree()?; - - let mut idx = repo.merge_trees(&ancestor_tree, &head_tree, &fetch_tree, None)?; - if idx.has_conflicts() { - return Err(Error::from_str( - "Merge conflicts detected. Please resolve manually.", - )); - } - - // Write the merged tree - let result_tree_id = idx.write_tree_to(repo)?; - let result_tree = repo.find_tree(result_tree_id)?; - - // Create merge commit - let sig = repo.signature()?; - let head_commit_obj = repo.find_commit(head_commit.id())?; - let fetch_commit_obj = repo.find_commit(fetch_commit.id())?; - - repo.commit( - Some(head_ref.name().unwrap()), // update current branch - &sig, - &sig, - "Merge commit from pull", - &result_tree, - &[&head_commit_obj, &fetch_commit_obj], - )?; - - // Checkout updated HEAD - repo.checkout_head(Some(git2::build::CheckoutBuilder::default().force()))?; - log::info!("Merge completed successfully"); - } - - Ok(()) -} - -pub fn pull_but_reclone_on_fail( - repo_url: &str, - repo_path: &Path, - depth: Option, -) -> Result { - // Try opening the repo if it exists - if let Ok(repo) = Repository::open(repo_path) { - // Try to pull - match pull_https(&repo) { - Ok(_) => return Ok(repo), - Err(err) => { - log::warn!("Pull failed: {}.", err); - - let user_confirm = confirm("Failed to update cache (outdated). Remove and retry?"); - - let home_dir = dirs::home_dir() - .ok_or_else(|| Error::from_str("Failed to get home directory"))?; - let cache_root = home_dir.join(".eiipm/cache"); - - if user_confirm { - if !repo_path.starts_with(cache_root.as_path()) { - return Err(Error::from_str(&format!( - "Refusing to delete outside cache: {}", - repo_path.display() - ))); - } - - fs::remove_dir_all(repo_path) - .map_err(|e| Error::from_str(&format!("Failed to remove dir: {}", e)))?; - } else { - // user refused, so just return the repo as-is - return Ok(repo); - } - } - } - } - - // Either repo didn't exist or we removed it, so clone fresh - clone_https(repo_url, repo_path, depth) -} - -/// Checks if the current branch is behind its upstream. -/// Returns `Ok(true)` if the upstream has commits the local branch doesn't have. -pub fn is_upstream_ahead(repo_path: &str) -> Result { - let repo = Repository::open(repo_path)?; - - // Get the current branch - let head_ref = repo.head()?; - let branch_name = head_ref - .shorthand() - .ok_or_else(|| Error::from_str("Invalid branch name"))?; - - // Set up fetch options with authentication callbacks - let mut callbacks = RemoteCallbacks::new(); - callbacks.credentials(|_url, username_from_url, _allowed_types| { - Cred::ssh_key_from_agent(username_from_url.unwrap_or("git")) - }); - let mut fetch_options = FetchOptions::new(); - fetch_options.remote_callbacks(callbacks); - - // Fetch from origin - let mut remote = repo.find_remote("origin")?; - remote.fetch(&[branch_name], Some(&mut fetch_options), None)?; - - // Resolve upstream - let local_branch = repo.find_branch(branch_name, git2::BranchType::Local)?; - let upstream_branch = local_branch.upstream()?; - - let local_oid = local_branch - .get() - .target() - .ok_or_else(|| Error::from_str("Local branch has no commit"))?; - let upstream_oid = upstream_branch - .get() - .target() - .ok_or_else(|| Error::from_str("Upstream branch has no commit"))?; - - let (_ahead, behind) = repo.graph_ahead_behind(local_oid, upstream_oid)?; - - Ok(behind > 0) -} diff --git a/docs/src/introduction.md b/docs/src/introduction.md index c15a090..0970135 100644 --- a/docs/src/introduction.md +++ b/docs/src/introduction.md @@ -6,7 +6,7 @@ Eiipm is a fast and eligant package manager made in rust for [Ewwii](https://git You can install **eiipm** using the same [methods we discussed](https://ewwii-sh.github.io/ewwii/installation.html) of in Ewwii: -#### 1. From installer (fastest) +#### 1. From installer (Linux Only) ```bash curl -sSL https://raw.githubusercontent.com/Ewwii-sh/eiipm/main/install.sh -o install.sh @@ -24,7 +24,15 @@ eiipm --version > > If eiipm doesn't work after the installation, make sure that `/usr/local/bin` is in path. -#### 2. From source +#### 2. From GitHub releases (Linux Only) + +If you are on Linux, then you can install the pre-built binary from [eiipm GitHub releases](https://github.com/Ewwii-sh/eiipm/releases/latest). + +- Go to the latest GitHub release. [Click Me!](https://github.com/Ewwii-sh/eiipm/releases/latest) +- Install the binary (that is named `eiipm`) from assets section. +- Voila! You now have eiipm installed! + +#### 3. From source ```bash git clone https://github.com/Ewwii-sh/eiipm @@ -34,7 +42,7 @@ cargo build --release This will generate the `eiipm` binary in `target/release`. -#### 3. Using Cargo +#### 4. Using Cargo ```bash cargo install --git https://github.com/Ewwii-sh/eiipm diff --git a/src/functions/install.rs b/src/functions/install.rs index 34af6a2..404b054 100644 --- a/src/functions/install.rs +++ b/src/functions/install.rs @@ -113,22 +113,24 @@ pub fn install_package(package_name: &str) -> Result<(), Box> { } } - // Update DB - let mut db = load_db()?; - db.packages.insert( - meta.name.clone(), - InstalledPackage { - repo_fs_path: repo_fs_path.to_string_lossy().to_string(), - installed_files: installed_files, - copy_files: meta.files.clone(), - pkg_type: meta.pkg_type.clone(), - upstream_src: meta.src.clone(), - installed_hash: meta.commit_hash.clone(), - manifest_url: raw_manifest_url, - build_command: meta.build.clone(), - }, - ); - save_db(&db)?; + // Update DB if its not a theme + if !(meta.pkg_type == "theme") { + let mut db = load_db()?; + db.packages.insert( + meta.name.clone(), + InstalledPackage { + repo_fs_path: repo_fs_path.to_string_lossy().to_string(), + installed_files: installed_files, + copy_files: meta.files.clone(), + pkg_type: meta.pkg_type.clone(), + upstream_src: meta.src.clone(), + installed_hash: meta.commit_hash.clone(), + manifest_url: raw_manifest_url, + build_command: meta.build.clone(), + }, + ); + save_db(&db)?; + } info!( "Installation complete for '{}'", diff --git a/src/functions/update.rs b/src/functions/update.rs index 0b53951..e13b18d 100644 --- a/src/functions/update.rs +++ b/src/functions/update.rs @@ -21,6 +21,8 @@ pub fn update_package(package_name: &Option) -> Result<(), Box