Compare commits

...

24 commits
v0.0.2 ... main

Author SHA1 Message Date
Christina Sørensen
b60bbc162f
chore(release): cargo v0.0.4
All checks were successful
conventional commits / conventional commits (push) Successful in 9s
build / run (push) Successful in 8m14s
check / run (push) Successful in 1m40s
Signed-off-by: Christina Sørensen <christina@cafkafk.com>
2024-09-13 07:19:58 +02:00
Christina Sørensen
85a6d6cc9a
refactor: handle clippy lints
All checks were successful
conventional commits / conventional commits (push) Successful in 13s
build / run (push) Successful in 1m1s
check / run (push) Successful in 1m50s
Signed-off-by: Christina Sørensen <christina@cafkafk.com>
2024-09-13 07:16:34 +02:00
Christina Sørensen
cb34302e17
refactor(nix): tidy things into separate functions (this should be typestate but I'm eepy)
Some checks failed
conventional commits / conventional commits (push) Successful in 9s
build / run (push) Successful in 41s
check / run (push) Failing after 1m26s
Signed-off-by: Christina Sørensen <christina@cafkafk.com>
2024-09-12 19:15:11 +02:00
Christina Sørensen
8c271f669a
fix: relative dir installables
Some checks failed
conventional commits / conventional commits (push) Successful in 6s
build / run (push) Successful in 36s
check / run (push) Failing after 56s
A leftover `current_dir` in the command builder for installables
resulted in `nix-weather ./#` invocations, and others relying on
relative filesystem paths failing.

Resolves: #20
Signed-off-by: Christina Sørensen <christina@cafkafk.com>
2024-09-12 13:09:18 +02:00
Christina Sørensen
e949478754
feat: parse installables
Some checks failed
conventional commits / conventional commits (push) Successful in 10s
build / run (push) Successful in 54s
check / run (push) Failing after 1m4s
Signed-off-by: Christina Sørensen <christina@cafkafk.com>
2024-09-12 11:56:04 +02:00
Christina Sørensen
419976d275
feat(args): add -L/--print-build-logs flag, to feel more like nix3
All checks were successful
conventional commits / conventional commits (push) Successful in 12s
build / run (push) Successful in 1m3s
check / run (push) Successful in 1m38s
Signed-off-by: Christina Sørensen <christina@cafkafk.com>
2024-09-12 11:21:10 +02:00
Jalil David Salamé Messina
6efdad5e66
fix: the small things
All checks were successful
conventional commits / conventional commits (push) Successful in 13s
build / run (push) Successful in 21s
check / run (push) Successful in 1m15s
* small typo on the flake description
* crane went full lib mode so it doesn't have any inputs to override
* `treefmt` warns on `nixfmt-rfc-style` as its `nixfmt` module is also
  `nixfmt-rfc-style`, switch to the `nixfmt` module.
* `pre-commit-hooks` uses `nixfmt-classic` when requesting `nixfmt` so
  we need to filter out `nixfmt` and enable `nixfmt-rfc-style` manually.
* there was an unneeded with statement warning from `nixd`

Signed-off-by: Jalil David Salame Messina <jalil.salame@gmail.com>
2024-09-11 09:29:02 +02:00
Christina Sørensen
19fa28545f
merge: fix-darwin from #27 into main
All checks were successful
conventional commits / conventional commits (push) Successful in 5s
build / run (push) Successful in 11s
check / run (push) Successful in 36s
2024-09-09 07:57:40 +02:00
Christina Sørensen
0a7cf9f016
fix: use our own forgejo actions repo
All checks were successful
conventional commits / conventional commits (pull_request) Successful in 9s
build / run (pull_request) Successful in 12s
check / run (pull_request) Successful in 46s
Signed-off-by: Christina Sørensen <christina@cafkafk.com>
2024-09-09 07:50:42 +02:00
Christina Sørensen
bef974eda7
build(darwin): add nescesarry apple_sdk packages
Some checks failed
conventional commits / conventional commits (pull_request) Failing after 3s
check / run (pull_request) Failing after 4s
build / run (pull_request) Failing after 1s
Signed-off-by: Christina Sørensen <christina@cafkafk.com>
2024-09-08 22:21:22 +02:00
Christina Sørensen
f68cbc2f5a
chore(release): cargo v0.0.3
All checks were successful
conventional commits / conventional commits (push) Successful in 9s
build / run (push) Successful in 7m43s
check / run (push) Successful in 1m28s
Signed-off-by: Christina Sørensen <christina@cafkafk.com>
2024-09-08 15:21:48 +02:00
Christina Sørensen
4be508a330
merge: downgrade-rustc from #26 into main
All checks were successful
conventional commits / conventional commits (push) Successful in 9s
build / run (push) Successful in 14s
check / run (push) Successful in 48s
2024-09-08 15:17:42 +02:00
Christina Sørensen
c7da345cf4
build: use nixpkgs compatible rustc
All checks were successful
conventional commits / conventional commits (pull_request) Successful in 9s
build / run (pull_request) Successful in 7m48s
check / run (pull_request) Successful in 1m24s
Keep this on anything that isn't EOL, we'll be nice to nixpkgs as long
as they don't literally actually unironically lock all our deps for us
or go on EOL rustc >_>

...also if we wanna play with bench we can probably cfg gate that :p

Closes: #25
Signed-off-by: Christina Sørensen <christina@cafkafk.com>
2024-09-08 15:04:35 +02:00
Christina Sørensen
701c86d650
merge: fix-eval-cache from #24 into main
All checks were successful
conventional commits / conventional commits (push) Successful in 9s
build / run (push) Successful in 13s
check / run (push) Successful in 58s
2024-09-08 14:52:49 +02:00
Christina Sørensen
beef106b41
fix: actually cache evals
All checks were successful
conventional commits / conventional commits (pull_request) Successful in 10s
build / run (pull_request) Successful in 52s
check / run (pull_request) Successful in 1m33s
Signed-off-by: Christina Sørensen <christina@cafkafk.com>
2024-09-08 14:36:18 +02:00
Christina Sørensen
5922220498
merge: tabwidth from #23 into main
All checks were successful
conventional commits / conventional commits (push) Successful in 6s
build / run (push) Successful in 11s
check / run (push) Successful in 38s
2024-09-07 12:12:48 +02:00
Christina Sørensen
149d353019
ci: change names
All checks were successful
conventional commits / conventional commits (pull_request) Successful in 6s
build / run (pull_request) Successful in 11s
check / run (pull_request) Successful in 47s
Signed-off-by: Christina Sørensen <christina@cafkafk.com>
2024-09-07 12:07:44 +02:00
Christina Sørensen
b69542d9a6
ci: add nix build step
All checks were successful
Conventional Commits / conventional commits (pull_request) Successful in 6s
build flake / security_audit (pull_request) Successful in 11s
check flake / security_audit (pull_request) Successful in 41s
Signed-off-by: Christina Sørensen <christina@cafkafk.com>
2024-09-07 12:04:15 +02:00
Christina Sørensen
b05095ff35
refactor: various clippy lints
Some checks failed
Security audit / security_audit (pull_request) Has been cancelled
Conventional Commits / Conventional Commits (pull_request) Successful in 6s
Check Flake / security_audit (pull_request) Successful in 7m2s
Signed-off-by: Christina Sørensen <christina@cafkafk.com>
2024-09-07 11:44:24 +02:00
Christina Sørensen
0863eae4b4
ci: check flake
Signed-off-by: Christina Sørensen <christina@cafkafk.com>
2024-09-07 11:44:01 +02:00
Christina Sørensen
133584c1e6
ci: allow own license
Signed-off-by: Christina Sørensen <christina@cafkafk.com>
2024-09-07 11:43:47 +02:00
Christina Sørensen
747e481bcb
style: nixfmt-rfc-style
Signed-off-by: Christina Sørensen <christina@cafkafk.com>
2024-09-07 11:43:13 +02:00
Christina Sørensen
7db9d3a2e1
style(rust): format to tabwidth-2
Fix: #22
Signed-off-by: Christina Sørensen <christina@cafkafk.com>
2024-09-06 11:26:56 +02:00
Christina Sørensen
c7f6b2c256
build: change rust tabwidth
Signed-off-by: Christina Sørensen <christina@cafkafk.com>
2024-09-06 11:24:30 +02:00
14 changed files with 329 additions and 284 deletions

View file

@ -5,7 +5,7 @@
{
projectRootFile = "Cargo.toml";
programs = {
nixpkgs-fmt.enable = true; # nix
nixfmt.enable = true; # nix
statix.enable = true; # nix static analysis
deadnix.enable = true; # find dead nix code
rustfmt.enable = true; # rust

View file

@ -2,7 +2,7 @@
#
# SPDX-License-Identifier: EUPL-1.2
name: Conventional Commits
name: conventional commits
on:
push:
branches: [main]
@ -12,9 +12,9 @@ concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.sha }}
cancel-in-progress: true
jobs:
build:
name: Conventional Commits
check:
name: conventional commits
runs-on: native
steps:
- uses: actions/checkout@v4
- uses: https://github.com/webiny/action-conventional-commits@v1.3.0
- uses: actions/action-conventional-commits@v1.3.0

View file

@ -2,18 +2,16 @@
#
# SPDX-License-Identifier: EUPL-1.2
name: Security audit
name: build
on:
schedule:
- cron: '0 0 * * *'
push:
branches: [main]
pull_request:
branches: [main]
jobs:
security_audit:
run:
runs-on: native
steps:
- uses: actions/checkout@v4
- name: Scan for vulnerabilities
run: nix develop --accept-flake-config --command cargo deny check
- name: build flake
run: nix build

View file

@ -0,0 +1,17 @@
# SPDX-FileCopyrightText: 2024 Christina Sørensen
#
# SPDX-License-Identifier: EUPL-1.2
name: check
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
run:
runs-on: native
steps:
- uses: actions/checkout@v4
- name: flake checks
run: nix flake check

5
.rustfmt.toml Normal file
View file

@ -0,0 +1,5 @@
# SPDX-FileCopyrightText: 2024 Christina Sørensen
#
# SPDX-License-Identifier: EUPL-1.2
tab_spaces = 2

4
Cargo.lock generated
View file

@ -304,7 +304,7 @@ checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0"
[[package]]
name = "common"
version = "0.0.2"
version = "0.0.4"
dependencies = [
"workspace-hack",
]
@ -1109,7 +1109,7 @@ checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
[[package]]
name = "nix-weather"
version = "0.0.2"
version = "0.0.4"
dependencies = [
"clap",
"clap_complete",

View file

@ -8,13 +8,19 @@ members = ["crates/*", "crates/workspace-hack"]
[workspace.package]
description = "Guix weather, for nix!"
version = "0.0.2"
version = "0.0.4"
edition = "2021"
rust-version = "1.81"
license = "EUPL-1.2"
authors = ["Christina Sørensen <christina@cafkafk.com>"]
categories = ["command-line-utilities"]
# Keep this on anything that isn't EOL, we'll be nice to nixpkgs as long as
# they don't literally actually unironically lock all our deps for us or go on
# EOL rustc >_>
#
# ...also if we wanna play with bench we can probably cfg gate that :p
rust-version = "1.80.1"
[workspace.metadata.crane]
name = "nix-weather"

View file

@ -14,30 +14,33 @@ use std::path::PathBuf;
include!("src/cli.rs");
fn main() -> Result<(), Error> {
let real_outdir = match env::var_os("OUT_DIR") {
None => return Ok(()),
Some(outdir) => outdir,
};
let real_outdir = match env::var_os("OUT_DIR") {
None => return Ok(()),
Some(outdir) => outdir,
};
let outdir = match env::var_os("MAN_OUT") {
None => real_outdir,
Some(outdir) => outdir,
};
let outdir = match env::var_os("MAN_OUT") {
None => real_outdir,
Some(outdir) => outdir,
};
let mut cmd = build_cli();
for &shell in Shell::value_variants() {
// HACK: this is gross :(
let output = std::process::Command::new("mkdir").arg("man").output();
let mut cmd = build_cli();
for &shell in Shell::value_variants() {
// HACK: this is gross :(
std::process::Command::new("mkdir")
.arg("man")
.output()
.expect("failed to make man directory");
generate_to(shell, &mut cmd, "nix-weather", &outdir)?;
}
generate_to(shell, &mut cmd, "nix-weather", &outdir)?;
}
let file = PathBuf::from(&outdir).join("nix-weather.1");
let mut file = File::create(file)?;
let file = PathBuf::from(&outdir).join("nix-weather.1");
let mut file = File::create(file)?;
Man::new(cmd).render(&mut file)?;
Man::new(cmd).render(&mut file)?;
println!("cargo:warning=completion file is generated: {outdir:?}");
println!("cargo:warning=completion file is generated: {outdir:?}");
Ok(())
Ok(())
}

View file

@ -3,36 +3,39 @@
//
// SPDX-License-Identifier: EUPL-1.2
use std::{cell::OnceCell, sync::OnceLock};
use clap::{arg, command, crate_authors, value_parser, Arg, ArgAction, Command};
use clap::{arg, command, crate_authors, value_parser, ArgAction, Command};
const DEFAULT_CACHE: &str = "cache.nixos.org";
pub fn build_cli() -> Command {
use std::path::PathBuf;
command!()
.author(crate_authors!("\n"))
.arg(
arg!(--cache <CACHE> "check a specific cache")
.required(false)
.default_value(DEFAULT_CACHE),
)
.arg(
arg!(-n --name <HOST> "Hostname of machine.")
.required(false)
.value_parser(value_parser!(String)),
)
.arg(
arg!(-c --config <FILE> "Path to NixOS config.")
.required(false)
.value_parser(value_parser!(String)),
)
.arg(
arg!(--timestamp "Add timestamp to log output.")
.action(ArgAction::SetTrue)
.required(false),
)
.arg(arg!(-v --verbose ... "Verbosity level."))
command!()
.author(crate_authors!("\n"))
// TODO: parse multiple installables, like e.g. build does?
.arg(arg!([installable] "A nix installable").required(false))
.arg(
arg!(--cache <CACHE> "Check a specific cache")
.required(false)
.default_value(DEFAULT_CACHE),
)
.arg(
arg!(-n --name <HOST> "Hostname of machine.")
.required(false)
.value_parser(value_parser!(String)),
)
.arg(
arg!(-c --config <FILE> "Path to NixOS config.")
.required(false)
.value_parser(value_parser!(String)),
)
.arg(
arg!(--timestamp "Add timestamp to log output.")
.action(ArgAction::SetTrue)
.required(false),
)
.arg(arg!(-v --verbose ... "Verbosity level."))
.arg(
arg!(printBuildLogs: -L "Verbosity level.")
.long("print-build-logs")
.conflicts_with("verbose"),
)
}

View file

@ -3,7 +3,7 @@
//
// SPDX-License-Identifier: EUPL-1.2
use std::time::{Duration, Instant};
use std::time::Instant;
use std::{env, io, net::SocketAddr};
use dns_lookup::lookup_host;
@ -11,8 +11,6 @@ use futures::future::join_all;
use gethostname::gethostname;
use itertools::Itertools;
use log;
use crate::nix::get_requisites;
mod cli;
@ -27,123 +25,134 @@ const DEFAULT_CONFIG_DIR: &str = "/etc/nixos";
#[tokio::main(flavor = "multi_thread")]
async fn main() -> io::Result<()> {
let initial_time = Instant::now();
let initial_time = Instant::now();
let host_name: String;
let cache_url: String;
let config_dir: String;
let host_name: String;
let cache_url: String;
let config_dir: String;
let matches = cli::build_cli().get_matches();
let matches = cli::build_cli().get_matches();
/// If the users inputs more -v flags than we have log levels, send them a
/// message informing them.
let mut very_bose = false;
// If the users inputs more -v flags than we have log levels, send them a
// message informing them.
let mut very_bose = false;
match matches
.get_one::<u8>("verbose")
.expect("Counts aren't defaulted")
{
0 => env::set_var("RUST_LOG", "error"),
1 => env::set_var("RUST_LOG", "warn"),
2 => env::set_var("RUST_LOG", "info"),
3 => env::set_var("RUST_LOG", "debug"),
4 => env::set_var("RUST_LOG", "trace"),
_ => {
very_bose = true;
env::set_var("RUST_LOG", "trace")
}
// The Normal verbose flag, allowing multiple levels. Conflicts with
// printBuildLogs.
match matches
.get_one::<u8>("verbose")
.expect("Counts aren't defaulted")
{
0 => env::set_var("RUST_LOG", "error"),
1 => env::set_var("RUST_LOG", "warn"),
2 => env::set_var("RUST_LOG", "info"),
3 => env::set_var("RUST_LOG", "debug"),
4 => env::set_var("RUST_LOG", "trace"),
_ => {
very_bose = true;
env::set_var("RUST_LOG", "trace")
}
}
if matches.get_flag("timestamp") {
pretty_env_logger::formatted_timed_builder()
.parse_env("RUST_LOG")
.init();
} else {
pretty_env_logger::formatted_builder()
.parse_env("RUST_LOG")
.init();
}
// The -L flag, to give a more nix3 feel
if matches.get_flag("printBuildLogs") {
env::set_var("RUST_LOG", "trace")
}
if very_bose {
log::trace!("More than four -v flags don't increase log level.");
}
if matches.get_flag("timestamp") {
pretty_env_logger::formatted_timed_builder()
.parse_env("RUST_LOG")
.init();
} else {
pretty_env_logger::formatted_builder()
.parse_env("RUST_LOG")
.init();
}
if let Some(name) = matches.get_one::<String>("name") {
host_name = name.to_owned();
} else {
host_name = gethostname().into_string().unwrap();
}
if very_bose {
log::trace!("More than four -v flags don't increase log level.");
}
if let Some(cache) = matches.get_one::<String>("cache") {
cache_url = cache.to_owned();
} else {
cache_url = DEFAULT_CACHE.to_string();
}
if let Some(name) = matches.get_one::<String>("name") {
host_name = name.to_owned();
} else {
host_name = gethostname().into_string().unwrap();
}
if let Some(config) = matches.get_one::<String>("config") {
config_dir = config.to_owned();
} else {
config_dir = DEFAULT_CONFIG_DIR.to_string();
}
if let Some(cache) = matches.get_one::<String>("cache") {
cache_url = cache.to_owned();
} else {
cache_url = DEFAULT_CACHE.to_string();
}
let domain = cache_url.to_owned();
let ips: Vec<std::net::IpAddr> = lookup_host(&domain).unwrap();
if let Some(config) = matches.get_one::<String>("config") {
config_dir = config.to_owned();
} else {
config_dir = DEFAULT_CONFIG_DIR.to_string();
}
log::debug!("{:#?}", &ips);
let domain = cache_url.to_owned();
let ips: Vec<std::net::IpAddr> = lookup_host(&domain).unwrap();
let domain_addr = SocketAddr::new(ips[0], 443);
log::debug!("{:#?}", &ips);
let client = reqwest::Client::builder()
.resolve(&domain, domain_addr)
.build()
.unwrap();
let domain_addr = SocketAddr::new(ips[0], 443);
let binding = get_requisites(&host_name, &config_dir);
let client = reqwest::Client::builder()
.resolve(&domain, domain_addr)
.build()
.unwrap();
let get_requisites_duration = initial_time.elapsed().as_secs();
let binding = get_requisites(
&host_name,
&config_dir,
matches.get_one::<String>("installable").cloned(),
);
println!(
"Found Nix Requisites in {} seconds",
get_requisites_duration
);
let get_requisites_duration = initial_time.elapsed().as_secs();
let network_time = Instant::now();
println!(
"Found Nix Requisites in {} seconds",
get_requisites_duration
);
let lines = binding
.lines()
.map(|line| line.to_owned())
.collect::<Vec<_>>();
let network_time = Instant::now();
let count = lines.len();
let lines = binding
.lines()
.map(|line| line.to_owned())
.collect::<Vec<_>>();
let tasks = lines
.into_iter()
.map(|hash| {
let client = client.clone();
let domain = domain.clone();
tokio::spawn(async move {
log::trace!("connecting to {domain} {domain_addr:#?} for {hash}");
net::nar_exists(client, &domain, &hash, SLIDE).await
})
})
.collect_vec();
let count = lines.len();
let sum: usize = join_all(tasks)
.await
.into_iter()
.map(|result| result.unwrap())
.sum();
let tasks = lines
.into_iter()
.map(|hash| {
let client = client.clone();
let domain = domain.clone();
tokio::spawn(async move {
log::trace!("connecting to {domain} {domain_addr:#?} for {hash}");
net::nar_exists(client, &domain, &hash, SLIDE).await
})
})
.collect_vec();
println!(
"Checked {count} packages in {} seconds",
network_time.elapsed().as_secs()
);
println!(
"Found {:#?}/{} ({:.2}%) in cache",
sum,
count,
(sum as f64 / count as f64) * 100.
);
let sum: usize = join_all(tasks)
.await
.into_iter()
.map(|result| result.unwrap())
.sum();
Ok(())
println!(
"Checked {count} packages in {} seconds",
network_time.elapsed().as_secs()
);
println!(
"Found {:#?}/{} ({:.2}%) in cache",
sum,
count,
(sum as f64 / count as f64) * 100.
);
Ok(())
}

View file

@ -8,33 +8,31 @@ use std::time::Duration;
use reqwest::Client;
use tokio::time::sleep;
use log;
const MAX_SLIDE: u64 = 1000;
pub async fn nar_exists(client: Client, domain: &str, hash: &str, slide: u64) -> usize {
let response = client
.head(format!("https://{domain}/{hash}.narinfo"))
.send()
.await;
let response = client
.head(format!("https://{domain}/{hash}.narinfo"))
.send()
.await;
match response {
Ok(response) if response.status().as_u16() == 200 => 1,
Ok(response) if response.status().as_u16() == 404 => 0,
_ => {
// We're so fast now we get rate limited.
//
// Writng an actual sliding window seems kinda hard,
// so we do this instead.
log::trace!("rate limited! {slide}");
sleep(Duration::from_millis(slide)).await;
Box::pin(nar_exists(
client,
domain,
hash,
std::cmp::min(slide * 2, MAX_SLIDE),
))
.await
}
match response {
Ok(response) if response.status().as_u16() == 200 => 1,
Ok(response) if response.status().as_u16() == 404 => 0,
_ => {
// We're so fast now we get rate limited.
//
// Writng an actual sliding window seems kinda hard,
// so we do this instead.
log::trace!("rate limited! {slide}");
sleep(Duration::from_millis(slide)).await;
Box::pin(nar_exists(
client,
domain,
hash,
std::cmp::min(slide * 2, MAX_SLIDE),
))
.await
}
}
}

View file

@ -5,53 +5,89 @@
use serde_json::Value;
use std::{
path::Path,
process::{Command, Stdio},
path::Path,
process::{Command, Stdio},
};
pub fn get_requisites(host: &str, config_dir: &str) -> String {
let get_drv_path = Command::new("nix")
.current_dir(Path::new(config_dir))
.args([
"build",
"--impure",
"--quiet",
&format!(
"./#nixosConfigurations.{}.config.system.build.toplevel",
host
),
"--dry-run",
"--json",
"--option",
"eval-cache",
"true",
])
.output()
.unwrap();
let drv_path_json: Value =
serde_json::from_str(&String::from_utf8(get_drv_path.stdout).unwrap()).unwrap();
let drv_path = drv_path_json[0]["drvPath"].clone();
log::debug!("drv_path: {}", &drv_path);
let get_drv_requisites = Command::new("nix-store")
.args(["--query", "--requisites", drv_path.as_str().unwrap()])
.stdout(Stdio::piped())
.spawn()
.unwrap();
let drv_requisites_remove_base = Command::new("cut")
.args(["-d", "/", "-f4"])
.stdin(Stdio::from(get_drv_requisites.stdout.unwrap()))
.stdout(Stdio::piped())
.spawn()
.unwrap();
let drv_requisites_to_hash = Command::new("cut")
.args(["-d", "-", "-f1"])
.stdin(Stdio::from(drv_requisites_remove_base.stdout.unwrap()))
.stdout(Stdio::piped())
.spawn()
.unwrap();
String::from_utf8(drv_requisites_to_hash.wait_with_output().unwrap().stdout).unwrap()
/// Get nixosConfiguration derivation path
#[inline]
fn get_config_drv_path(host: &str, config_dir: &str) -> std::io::Result<std::process::Output> {
Command::new("nix")
.current_dir(Path::new(config_dir))
.args([
"build",
"--quiet",
&format!(
"./#nixosConfigurations.{}.config.system.build.toplevel",
host
),
"--dry-run",
"--json",
])
.output()
}
/// Get installable derivation path
#[inline]
fn get_installable_drv_path(installable: &str) -> std::io::Result<std::process::Output> {
Command::new("nix")
.args(["build", "--quiet", installable, "--dry-run", "--json"])
.output()
}
/// Takes a drv_path and gets all it's requisites from the nix store.
#[inline]
fn get_requisites_from_drv_path(drv_path: &str) -> std::io::Result<std::process::Child> {
Command::new("nix-store")
.args(["--query", "--requisites", drv_path])
.stdout(Stdio::piped())
.spawn()
}
/// Turns requisites into hashes
#[inline]
fn requisites_to_hashes(
drv_requisites: std::process::Child,
) -> std::io::Result<std::process::Child> {
let drv_requisites_remove_base = Command::new("cut")
.args(["-d", "/", "-f4"])
.stdin(Stdio::from(drv_requisites.stdout.unwrap()))
.stdout(Stdio::piped())
.spawn()
.unwrap();
Command::new("cut")
.args(["-d", "-", "-f1"])
.stdin(Stdio::from(drv_requisites_remove_base.stdout.unwrap()))
.stdout(Stdio::piped())
.spawn()
}
pub fn get_requisites(host: &str, config_dir: &str, installable: Option<String>) -> String {
// If the users specified an installable, we interpret that, instead of trying
// to guess their config location.
let drv_path;
if let Some(installable) = installable {
drv_path = get_installable_drv_path(&installable).unwrap();
} else {
drv_path = get_config_drv_path(host, config_dir).unwrap();
}
let drv_path_json: Value =
serde_json::from_str(&String::from_utf8(drv_path.stdout).unwrap()).unwrap();
let drv_path = drv_path_json[0]["drvPath"].clone();
log::debug!("drv_path: {}", &drv_path);
let drv_requisites = get_requisites_from_drv_path(drv_path.as_str().unwrap()).unwrap();
let drv_requisite_hashes = requisites_to_hashes(drv_requisites);
String::from_utf8(
drv_requisite_hashes
.unwrap()
.wait_with_output()
.unwrap()
.stdout,
)
.unwrap()
}

View file

@ -7,4 +7,4 @@ multiple-versions = 'allow'
[licenses]
private = { ignore = true }
allow = ["MIT", "ISC", "MPL-2.0", "Apache-2.0", "Unicode-DFS-2016", "BSD-3-Clause"]
allow = ["MIT", "ISC", "MPL-2.0", "Apache-2.0", "Unicode-DFS-2016", "BSD-3-Clause", "EUPL-1.2"]

View file

@ -3,7 +3,7 @@
# SPDX-License-Identifier: EUPL-1.2
{
description = "Nix Weather - Check Cache Availablility of NixOS Configurations";
description = "Nix Weather - Check Cache Availability of NixOS Configurations";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
@ -13,10 +13,7 @@
inputs.nixpkgs.follows = "nixpkgs";
};
crane = {
url = "github:ipetkov/crane";
inputs.nixpkgs.follows = "nixpkgs";
};
crane.url = "github:ipetkov/crane";
fenix = {
url = "github:nix-community/fenix";
@ -85,9 +82,7 @@
let
overlays = [ (import rust-overlay) ];
pkgs = (import nixpkgs) {
inherit system overlays;
};
pkgs = (import nixpkgs) { inherit system overlays; };
inherit (pkgs) lib;
@ -101,9 +96,7 @@
inherit src;
strictDeps = true;
nativeBuildInputs = [
pkgs.pkg-config
];
nativeBuildInputs = [ pkgs.pkg-config ];
buildInputs =
[
@ -113,6 +106,8 @@
++ lib.optionals pkgs.stdenv.isDarwin [
# Additional darwin specific inputs can be set here
pkgs.libiconv
pkgs.darwin.apple_sdk.frameworks.Security
pkgs.darwin.apple_sdk.frameworks.SystemConfiguration
];
# Additional environment variables can be set directly
@ -205,27 +200,16 @@
}
);
cargo-workspace-doc = craneLib.cargoDoc (
commonArgs
// {
inherit cargoArtifacts;
}
);
cargo-workspace-doc = craneLib.cargoDoc (commonArgs // { inherit cargoArtifacts; });
# Check formatting
cargo-workspace-fmt = craneLib.cargoFmt {
inherit src;
};
cargo-workspace-fmt = craneLib.cargoFmt { inherit src; };
# Audit dependencies
cargo-workspace-audit = craneLib.cargoAudit {
inherit src advisory-db;
};
cargo-workspace-audit = craneLib.cargoAudit { inherit src advisory-db; };
# Audit licenses
cargo-workspace-deny = craneLib.cargoDeny {
inherit src;
};
cargo-workspace-deny = craneLib.cargoDeny { inherit src; };
# Run tests with cargo-nextest
# Consider setting `doCheck = false` on other crate derivations
@ -252,14 +236,15 @@
cargo hakari verify
'';
nativeBuildInputs = [
pkgs.cargo-hakari
];
nativeBuildInputs = [ pkgs.cargo-hakari ];
};
pre-commit-check =
let
# some treefmt formatters are not supported in pre-commit-hooks we filter them out for now.
toFilter = [ "yamlfmt" ];
toFilter = [
"yamlfmt"
"nixfmt"
];
filterFn = n: _v: (!builtins.elem n toFilter);
treefmtFormatters = pkgs.lib.mapAttrs (_n: v: { inherit (v) enable; }) (
pkgs.lib.filterAttrs filterFn (import ./.config/treefmt.nix).programs
@ -268,11 +253,14 @@
pre-commit-hooks.lib.${system}.run {
src = ./.;
hooks = treefmtFormatters // {
convco.enable = true; # not in treefmt
# not in treefmt
convco.enable = true;
# named nixfmt in treefmt (which defaults to nixfmt-classic for pre-commit-hooks)
nixfmt-rfc-style.enable = true;
reuse = {
enable = true;
name = "reuse";
entry = with pkgs; "${pkgs.reuse}/bin/reuse lint";
entry = with pkgs; "${reuse}/bin/reuse lint";
pass_filenames = false;
};
};
@ -287,17 +275,12 @@
}
// lib.optionalAttrs (!pkgs.stdenv.isDarwin) {
cargo-workspace-llvm-coverage = craneLibLLvmTools.cargoLlvmCov (
commonArgs
// {
inherit cargoArtifacts;
}
commonArgs // { inherit cargoArtifacts; }
);
};
apps = {
nix-weather = flake-utils.lib.mkApp {
drv = nix-weather;
};
nix-weather = flake-utils.lib.mkApp { drv = nix-weather; };
};
# For `nix develop`:
@ -332,16 +315,3 @@
];
};
}