fix: themes are now not saved in installed pkg db

This commit is contained in:
Byson94
2025-08-28 09:14:16 +05:30
parent 51d0be0dc0
commit dff3fc8793
5 changed files with 35 additions and 201 deletions

View File

@@ -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

View File

@@ -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<u32>) -> Result<Repository, Error> {
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<u32>,
) -> Result<Repository, Error> {
// 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<bool, Error> {
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)
}

View File

@@ -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

View File

@@ -113,22 +113,24 @@ pub fn install_package(package_name: &str) -> Result<(), Box<dyn Error>> {
}
}
// 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 '{}'",

View File

@@ -21,6 +21,8 @@ pub fn update_package(package_name: &Option<String>) -> Result<(), Box<dyn Error
pkg.pkg_type
);
// there is no way that it can be a theme
// but... what if?
if pkg.pkg_type == "theme" {
info!("Skipping theme package '{}'", name.yellow().bold());
} else {