this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 111 lines 2.9 kB view raw
1use std::path::PathBuf; 2 3use clap::Parser; 4use color_eyre::Result; 5use diff::PackageListDiff; 6use nu_ansi_term::{Color, Style}; 7use shellexpand::path::tilde; 8use terminal_light::luma; 9 10mod color; 11mod diff; 12mod package; 13mod parser; 14mod versioning; 15 16use self::parser::DiffRoot; 17 18#[allow(clippy::struct_excessive_bools)] 19#[derive(Parser, PartialEq, Debug)] 20/// List the package differences between two `NixOS` generations 21struct Args { 22 /// the path to the lix bin directory 23 #[arg(short, long)] 24 lix_bin: Option<PathBuf>, 25 26 /// the generation we are switching from 27 before: PathBuf, 28 29 /// the generation we are switching to 30 #[arg(default_value = "/run/current-system/")] 31 after: PathBuf, 32 33 /// sort by size difference 34 #[arg(short, long)] 35 size: bool, 36 37 /// disable colored output (also respects `NO_COLOR` env var and CI environments) 38 #[arg(long)] 39 no_color: bool, 40 41 /// disable the header showing the generation paths 42 #[arg(long)] 43 no_header: bool, 44 45 /// add a return code indicating whether there are changes or no (1 if there are no changes, 0 46 /// otherwise) 47 #[arg(short, long = "return")] 48 return_code: bool, 49} 50 51fn main() -> Result<()> { 52 let args = Args::parse(); 53 54 // Initialize color configuration 55 color::init(args.no_color); 56 57 let before = tilde(&args.before); 58 let after = tilde(&args.after); 59 let lix_bin = args.lix_bin.as_deref().map(tilde); 60 61 let mut lix_exe = None; 62 if let Some(lix_bin) = lix_bin { 63 lix_exe = if lix_bin.is_dir() { 64 Some(lix_bin.join("nix").into()) 65 } else { 66 Some(lix_bin) 67 } 68 } 69 70 if !before.exists() { 71 eprintln!("Before generation does not exist: {}", before.display()); 72 std::process::exit(1); 73 } 74 75 if !after.exists() { 76 eprintln!("After generation does not exist: {}", after.display()); 77 std::process::exit(1); 78 } 79 80 let packages_diff = DiffRoot::new(lix_exe.as_deref(), &before, &after)?; 81 let mut packages: PackageListDiff = PackageListDiff::new(); 82 packages.by_size = args.size; 83 packages.from_diff_root(packages_diff); 84 85 let before_text = format!("<<< {}", before.display()); 86 let after_text = format!(">>> {}", after.display()); 87 88 if !args.no_header { 89 if color::color_enabled() { 90 let text_color = if luma().is_ok_and(|luma| luma > 0.6) { 91 Color::DarkGray 92 } else { 93 Color::LightGray 94 }; 95 let arrow_style = Style::new().bold().fg(text_color); 96 println!("{}", arrow_style.paint(&before_text)); 97 println!("{}\n", arrow_style.paint(&after_text)); 98 } else { 99 println!("{before_text}"); 100 println!("{after_text}\n"); 101 } 102 } 103 104 println!("{packages}"); 105 106 if args.return_code { 107 std::process::exit(packages.is_empty().into()); 108 } 109 110 Ok(()) 111}