From 024a41484af2e15c9295f4ab7b4a0662cbaa9fca Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Tue, 13 Apr 2021 14:46:39 +0000 Subject: Initial commit --- src/main.rs | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 src/main.rs (limited to 'src') diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..dd4a56c --- /dev/null +++ b/src/main.rs @@ -0,0 +1,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, +} + +#[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 = 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") + ); +} -- cgit 1.4.1