tangled
alpha
login
or
join now
tgirl.cloud
/
lix-diff
0
fork
atom
this repo has no description
0
fork
atom
overview
issues
pulls
pipelines
refactor: we are now clone free
isabelroses.com
10 months ago
eb77640f
5cf5e272
+71
-51
4 changed files
expand all
collapse all
unified
split
src
diff.rs
main.rs
package.rs
parser.rs
+28
-27
src/diff.rs
···
14
longest_name: usize,
15
}
16
17
-
pub fn partition_diff(diff: &DiffRoot) -> PackageListDiff {
18
-
let mut added = BTreeMap::new();
19
-
let mut removed = BTreeMap::new();
20
-
let mut changed = BTreeMap::new();
21
-
let mut size_delta: i64 = 0;
22
-
let mut longest_name = 0;
0
0
0
23
24
-
for (name, package) in &diff.packages {
25
-
match package.diff_type {
26
-
DiffType::Added => {
27
-
added.insert(name.clone(), package.clone());
28
-
}
29
-
DiffType::Removed => {
30
-
removed.insert(name.clone(), package.clone());
0
0
0
0
0
0
0
0
0
0
0
31
}
32
-
DiffType::Changed => {
33
-
changed.insert(name.clone(), package.clone());
34
-
}
35
-
_ => {}
36
}
37
38
-
size_delta += package.size_delta;
39
-
longest_name = longest_name.max(name.len());
40
-
}
41
-
42
-
PackageListDiff {
43
-
added,
44
-
removed,
45
-
changed,
46
-
size_delta,
47
-
longest_name,
48
}
49
}
50
···
14
longest_name: usize,
15
}
16
17
+
impl From<DiffRoot> for PackageListDiff {
18
+
fn from(diff: DiffRoot) -> Self {
19
+
let mut out = PackageListDiff {
20
+
added: BTreeMap::new(),
21
+
removed: BTreeMap::new(),
22
+
changed: BTreeMap::new(),
23
+
size_delta: 0,
24
+
longest_name: 0,
25
+
};
26
27
+
for (name, package) in diff.packages {
28
+
out.size_delta += package.size_delta;
29
+
out.longest_name = out.longest_name.max(name.len());
30
+
31
+
match package.diff_type {
32
+
DiffType::Added => {
33
+
out.added.insert(name, package);
34
+
}
35
+
DiffType::Removed => {
36
+
out.removed.insert(name, package);
37
+
}
38
+
DiffType::Changed => {
39
+
out.changed.insert(name, package);
40
+
}
41
+
DiffType::Unknown => {
42
+
// This should never happen, but just in case
43
+
eprintln!("Unknown diff type for package: {name}");
44
+
}
45
}
0
0
0
0
46
}
47
48
+
out
0
0
0
0
0
0
0
0
0
49
}
50
}
51
+2
-2
src/main.rs
···
2
3
use argh::FromArgs;
4
use color_eyre::Result;
0
5
use nu_ansi_term::{Color, Style};
6
7
mod diff;
···
44
std::process::exit(1);
45
}
46
47
-
let diff = parser::diff(&before, &after)?;
48
-
let packages = diff::partition_diff(&diff);
49
50
let arrow_style = Style::new().bold().fg(Color::LightGray);
51
···
2
3
use argh::FromArgs;
4
use color_eyre::Result;
5
+
use diff::PackageListDiff;
6
use nu_ansi_term::{Color, Style};
7
8
mod diff;
···
45
std::process::exit(1);
46
}
47
48
+
let packages: PackageListDiff = parser::diff(&before, &after)?.into();
0
49
50
let arrow_style = Style::new().bold().fg(Color::LightGray);
51
+6
-4
src/package.rs
···
0
0
1
use nu_ansi_term::Color::{Green, Red};
2
use serde::de::Deserializer;
3
use serde::Deserialize;
4
5
-
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
6
pub enum DiffType {
7
Added,
8
Removed,
···
12
Unknown,
13
}
14
15
-
#[derive(Deserialize, Clone, Debug)]
16
#[serde(rename_all = "camelCase")]
17
pub struct Package {
18
pub size_delta: i64,
···
32
where
33
D: Deserializer<'de>,
34
{
35
-
let vec = Vec::<String>::deserialize(deserializer)?;
36
Ok(vec
37
.into_iter()
38
.map(|s| {
39
if s.is_empty() {
40
"<none>".to_string()
41
} else {
42
-
s
43
}
44
})
45
.collect())
···
1
+
use std::borrow::Cow;
2
+
3
use nu_ansi_term::Color::{Green, Red};
4
use serde::de::Deserializer;
5
use serde::Deserialize;
6
7
+
#[derive(Default, Debug, PartialEq, Eq)]
8
pub enum DiffType {
9
Added,
10
Removed,
···
14
Unknown,
15
}
16
17
+
#[derive(Deserialize, Debug)]
18
#[serde(rename_all = "camelCase")]
19
pub struct Package {
20
pub size_delta: i64,
···
34
where
35
D: Deserializer<'de>,
36
{
37
+
let vec = Vec::<Cow<'de, str>>::deserialize(deserializer)?;
38
Ok(vec
39
.into_iter()
40
.map(|s| {
41
if s.is_empty() {
42
"<none>".to_string()
43
} else {
44
+
s.into_owned()
45
}
46
})
47
.collect())
+35
-18
src/parser.rs
···
4
5
use crate::package::{DiffType, Package};
6
7
-
#[derive(Deserialize, Debug)]
8
pub struct DiffRoot {
9
pub packages: BTreeMap<String, Package>,
10
···
12
pub schema: String,
13
}
14
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
15
fn run_diff(before: &str, after: &str) -> String {
16
let raw_diff = Command::new("nix")
17
.args(["store", "diff-closures", "--json", before, after])
18
.output()
19
-
.expect("Failed to execute command");
20
21
if !raw_diff.status.success() {
22
-
eprintln!("Error: {}", String::from_utf8_lossy(&raw_diff.stderr));
23
std::process::exit(1);
24
}
25
26
-
let diff_output = String::from_utf8_lossy(&raw_diff.stdout);
27
-
if diff_output.is_empty() {
28
eprintln!("No differences found.");
29
std::process::exit(0);
30
}
31
32
-
diff_output.into_owned()
0
33
}
34
35
fn parse_diff(input: &str) -> Result<DiffRoot> {
36
-
serde_json::from_str(input)
37
-
.map(|mut diff_root: DiffRoot| {
38
-
for package in diff_root.packages.values_mut() {
39
-
package.diff_type =
40
-
DiffType::from_versions(&package.versions_before, &package.versions_after);
41
-
}
42
-
diff_root
43
-
})
44
-
.map_err(|e| {
45
-
eprintln!("Failed to parse JSON: {e}");
46
-
std::process::exit(1);
47
-
})
48
}
49
50
pub fn diff(before: &str, after: &str) -> Result<DiffRoot> {
···
4
5
use crate::package::{DiffType, Package};
6
7
+
#[derive(Debug)]
8
pub struct DiffRoot {
9
pub packages: BTreeMap<String, Package>,
10
···
12
pub schema: String,
13
}
14
15
+
impl<'de> Deserialize<'de> for DiffRoot {
16
+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
17
+
where
18
+
D: serde::Deserializer<'de>,
19
+
{
20
+
#[derive(Deserialize)]
21
+
struct Raw {
22
+
packages: BTreeMap<String, Package>,
23
+
schema: String,
24
+
}
25
+
26
+
let Raw {
27
+
mut packages,
28
+
schema,
29
+
} = Raw::deserialize(deserializer)?;
30
+
31
+
for pkg in packages.values_mut() {
32
+
pkg.diff_type = DiffType::from_versions(&pkg.versions_before, &pkg.versions_after);
33
+
}
34
+
35
+
Ok(DiffRoot { packages, schema })
36
+
}
37
+
}
38
+
39
fn run_diff(before: &str, after: &str) -> String {
40
let raw_diff = Command::new("nix")
41
.args(["store", "diff-closures", "--json", before, after])
42
.output()
43
+
.expect("Failed to execute nix command");
44
45
if !raw_diff.status.success() {
46
+
eprintln!("{}", String::from_utf8_lossy(&raw_diff.stderr));
47
std::process::exit(1);
48
}
49
50
+
let stdout = raw_diff.stdout;
51
+
if stdout.is_empty() {
52
eprintln!("No differences found.");
53
std::process::exit(0);
54
}
55
56
+
// Assume nix output is valid UTF-8
57
+
String::from_utf8(stdout).expect("Output was not valid UTF-8")
58
}
59
60
fn parse_diff(input: &str) -> Result<DiffRoot> {
61
+
serde_json::from_str::<DiffRoot>(input).map_err(|e| {
62
+
eprintln!("Failed to parse JSON: {e}");
63
+
std::process::exit(1);
64
+
})
0
0
0
0
0
0
0
0
65
}
66
67
pub fn diff(before: &str, after: &str) -> Result<DiffRoot> {