aux-search/flake-info/src/commands/nixpkgs_info.rs

98 lines
2.9 KiB
Rust
Raw Normal View History

2021-08-17 08:55:08 +00:00
use anyhow::{Context, Result};
use serde_json::Deserializer;
2021-08-17 08:55:08 +00:00
use std::io::Write;
use std::{collections::HashMap, fmt::Display, fs::File};
use command_run::{Command, LogTo};
2021-08-17 08:55:08 +00:00
use log::{debug, error};
use crate::data::import::{NixOption, NixpkgsEntry, Package};
const FLAKE_INFO_SCRIPT: &str = include_str!("flake_info.nix");
pub fn get_nixpkgs_info<T: AsRef<str> + Display>(nixpkgs_channel: T) -> Result<Vec<NixpkgsEntry>> {
let mut command = Command::new("nix-env");
command.add_args(&[
2021-08-17 08:55:08 +00:00
"-f",
"<nixpkgs>",
"-I",
format!("nixpkgs={}", nixpkgs_channel.as_ref()).as_str(),
"--arg",
"config",
"import <nixpkgs/pkgs/top-level/packages-config.nix>",
2021-08-17 08:55:08 +00:00
"-qa",
"--meta",
2021-08-17 08:55:08 +00:00
"--json",
]);
command.enable_capture();
command.log_to = LogTo::Log;
command.log_output_on_error = true;
2021-08-17 08:55:08 +00:00
let parsed: Result<Vec<NixpkgsEntry>> = command
.run()
.with_context(|| {
format!(
"Failed to gather information about nixpkgs {}",
nixpkgs_channel.as_ref()
)
})
.and_then(|o| {
let output = &*o.stdout_string_lossy();
let de = &mut Deserializer::from_str(output);
2021-08-17 08:55:08 +00:00
let attr_set: HashMap<String, Package> =
serde_path_to_error::deserialize(de).with_context(|| "Could not parse packages")?;
2021-08-17 08:55:08 +00:00
Ok(attr_set
.into_iter()
.map(|(attribute, package)| NixpkgsEntry::Derivation { attribute, package })
.collect())
});
parsed
}
pub fn get_nixpkgs_options<T: AsRef<str> + Display>(
nixpkgs_channel: T,
) -> Result<Vec<NixpkgsEntry>> {
let script_dir = tempfile::tempdir()?;
let script_path = script_dir.path().join("flake_info.nix");
writeln!(File::create(&script_path)?, "{}", FLAKE_INFO_SCRIPT)?;
let mut command = Command::new("nix");
command.add_args(&[
2021-08-17 08:55:08 +00:00
"eval",
"--json",
"-f",
script_path.to_str().unwrap(),
"-I",
format!("nixpkgs={}", nixpkgs_channel.as_ref()).as_str(),
2021-08-17 08:55:08 +00:00
"--arg",
"flake",
nixpkgs_channel.as_ref(),
"nixos-options",
]);
command.enable_capture();
command.log_to = LogTo::Log;
command.log_output_on_error = true;
2021-08-17 08:55:08 +00:00
let parsed = command.run().with_context(|| {
format!(
"Failed to gather information about nixpkgs {}",
nixpkgs_channel.as_ref()
)
});
if let Err(ref e) = parsed {
error!("Command error: {}", e);
}
parsed.and_then(|o| {
let output = &*o.stdout_string_lossy();
let de = &mut Deserializer::from_str(output);
let attr_set: Vec<NixOption> =
serde_path_to_error::deserialize(de).with_context(|| "Could not parse options")?;
2021-08-17 08:55:08 +00:00
Ok(attr_set.into_iter().map(NixpkgsEntry::Option).collect())
})
}