1
Fork 0
mirror of https://github.com/RGBCube/dix synced 2025-07-28 04:07:46 +00:00

first working version

This commit is contained in:
Bloxx12 2025-05-04 14:03:15 +02:00
parent 6ed66b4351
commit 289881373a
No known key found for this signature in database
3 changed files with 181 additions and 1 deletions

45
Cargo.lock generated
View file

@ -2,6 +2,15 @@
# It is not intended for manual editing.
version = 4
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[package]]
name = "anstream"
version = "0.6.18"
@ -110,6 +119,12 @@ version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "memchr"
version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "once_cell"
version = "1.21.3"
@ -134,6 +149,35 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "regex"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "strsim"
version = "0.11.1"
@ -168,6 +212,7 @@ name = "version-diff"
version = "0.1.0"
dependencies = [
"clap",
"regex",
]
[[package]]

View file

@ -5,4 +5,5 @@ edition = "2024"
[dependencies]
clap = { version = "4.5.37", features = ["derive"] }
regex = "1.11.1"

View file

@ -1,13 +1,147 @@
use clap::Parser;
use core::str;
use regex::Regex;
use std::{process::Command, string::String};
#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
struct Args {
path: std::path::PathBuf,
path2: std::path::PathBuf,
/// Print the whole store paths
#[arg(short, long)]
paths: bool,
}
#[derive(Debug, PartialEq, PartialOrd, Eq, Clone, Hash)]
struct Package {
name: String,
version: String,
}
// Only there to make the compiler shut up for now.
#[derive(Debug)]
enum BlaErr {
LolErr,
}
fn main() {
let args = Args::parse();
println!("{:?}", args.path.into_os_string());
println!("Nix available: {}", check_nix_available());
println!("Checking path one:");
println!(
"Path one is a system: {}",
&args.path.join("activate").exists()
);
println!("Checking path two:");
println!(
"Path two is a system: {}",
&args.path2.join("activate").exists()
);
if check_if_system(&args.path) && check_if_system(&args.path2) {
let packages = get_packages(&args.path);
let packages2 = get_packages(&args.path2);
// println!("{:?}", packages);
if let (Ok(packages), Ok(packages2)) = (packages, packages2) {
let mut added = vec![];
let mut removed = vec![];
for i in &packages {
if !packages2.contains(i) {
added.push(i);
}
}
for i in &packages {
if !packages2.contains(i) {
removed.push(i);
}
}
let added_pretty: Vec<Package> =
added.iter().map(|p| get_version(p.to_string())).collect();
let removed_pretty: Vec<Package> =
removed.iter().map(|p| get_version(p.to_string())).collect();
println!("Difference between the two generations:");
println!("Packages added: ");
if args.paths {
for p in added.iter() {
println!("A: {:?}", p);
}
println!();
println!("Packages removed: ");
for p in removed.iter() {
println!("R: {:?}", p);
}
} else {
for p in added_pretty.iter() {
if !p.name.is_empty() {
println!("A: {} @ {}", p.name, p.version);
}
}
println!();
println!("Packages removed: ");
for p in removed_pretty.iter() {
if !p.name.is_empty() {
println!("R: {} @ {}", p.name, p.version);
}
}
}
}
} else {
println!("One of them is not a system!")
}
}
fn check_if_system(path: &std::path::Path) -> bool {
path.join("activate").exists()
}
fn get_packages(path: &std::path::Path) -> Result<Vec<String>, BlaErr> {
let references = Command::new("nix-store")
.arg("--query")
.arg("--references")
.arg(path.join("sw"))
.output();
if let Ok(query) = references {
let list = str::from_utf8(&query.stdout);
if let Ok(list) = list {
let res: Vec<String> = list.lines().map(|s| s.to_string()).collect();
return Ok(res);
}
}
Err(BlaErr::LolErr)
}
fn get_version(pack: String) -> Package {
// This is bound to break sooner or later
let re = Regex::new(r"^/nix/store/[a-z0-9]+-([^-]+(?:-[^-]+)*)-([\d][^/]*)$").unwrap();
// No cap frfr
if let Some(cap) = re.captures(&pack) {
let name = cap.get(1).unwrap().as_str().to_string();
let version = cap.get(2).unwrap().as_str().to_string();
return Package { name, version };
}
Package {
name: "".to_string(),
version: "".to_string(),
}
}
fn check_nix_available() -> bool {
let nix_available = Command::new("nix").arg("--version").output().ok();
let nix_query_available = Command::new("nix-store").arg("--version").output().ok();
nix_available.is_some() && nix_query_available.is_some()
}