1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
use std::collections::BTreeSet;
use std::env::args_os;
use std::fs::File;
use std::io::Read;
use std::os::unix::prelude::*;
use std::process::{Command, Stdio};
use cargo::core::SourceId;
use serde::{Deserialize, Serialize};
use serde_json;
use toml::value::Table as TomlTable;
#[derive(Debug, Serialize)]
struct Output {
git: BTreeSet<PrefetchGit>,
}
#[derive(Debug, Serialize, Deserialize, Ord, PartialOrd, Eq, PartialEq)]
struct PrefetchGit {
url: String,
rev: String,
sha256: String,
#[serde(rename = "fetchSubmodules")]
fetch_submodules: bool,
#[serde(rename = "deepClone")]
deep_clone: bool,
#[serde(rename = "leaveDotGit")]
leave_dot_git: bool,
}
fn main() {
let lockfile_path = args_os().skip(1).next().expect("missing lockfile path");
let mut lockfile_bytes = vec![];
let mut lockfile_fd = File::open(lockfile_path).expect("lockfile does not exist");
lockfile_fd
.read_to_end(&mut lockfile_bytes)
.expect("failed to read lockfile");
let lockfile: TomlTable = toml::from_slice(&lockfile_bytes).expect("can't parse lockfile");
let packages = lockfile
.get("package")
.expect("missing 'package' key")
.as_array()
.expect("package is not array");
let sources: BTreeSet<_> = packages
.into_iter()
.flat_map(|package| package.get("source"))
.map(|source| {
SourceId::from_url(source.as_str().expect("source not string"))
.expect("source not string")
})
.filter(|source| source.is_git())
.collect();
let output: BTreeSet<PrefetchGit> = sources
.into_iter()
.map(|source| {
let output = Command::new("nix-prefetch-git")
.arg("--fetch-submodules")
.arg(source.url().as_str())
.arg(source.precise().expect("missing precise in source URL"))
.stderr(Stdio::inherit())
.output()
.expect("failed to spawn nix-prefetch-git");
if !output.status.success() {
if let Some(code) = output.status.code() {
panic!("nix-prefetch-git exited with status {}", code);
} else {
panic!(
"nix-prefetch-git exited with signal {}",
output.status.signal().unwrap()
);
}
}
// FIXME: no need to read stdout into a buffer.
serde_json::from_slice(&output.stdout).expect("failed to parse nix-prefetch-git output")
})
.collect();
println!(
"{}",
toml::ser::to_string_pretty(&Output { git: output })
.expect("failed to serialize nix-prefetch-git output as TOML")
);
}
|