difftreelog
build enable gc debugging
in: trunk
9 files changed
Cargo.lockdiffbeforeafterboth--- a/Cargo.lock
+++ b/Cargo.lock
@@ -126,17 +126,6 @@
]
[[package]]
-name = "alejandra"
-version = "4.0.0"
-source = "git+https://github.com/kamadorueda/alejandra#c68bef57c1db3add865493d9cb741a14618bdc28"
-dependencies = [
- "mimalloc",
- "rnix",
- "rowan",
- "serde",
-]
-
-[[package]]
name = "android-tzdata"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -673,12 +662,6 @@
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
-
-[[package]]
-name = "countme"
-version = "3.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7704b5fdd17b18ae31c4c1da5a2e0305a2bf17b5249300a9ee9ed7b72114c636"
[[package]]
name = "cpufeatures"
@@ -1352,12 +1335,6 @@
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
-
-[[package]]
-name = "hashbrown"
-version = "0.14.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
[[package]]
name = "hashbrown"
@@ -1793,16 +1770,6 @@
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"
-
-[[package]]
-name = "libmimalloc-sys"
-version = "0.1.44"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "667f4fec20f29dfc6bc7357c582d91796c169ad7e2fce709468aefeb2c099870"
-dependencies = [
- "cc",
- "libc",
-]
[[package]]
name = "link-cplusplus"
@@ -1873,24 +1840,6 @@
version = "2.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
-
-[[package]]
-name = "memoffset"
-version = "0.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
-dependencies = [
- "autocfg",
-]
-
-[[package]]
-name = "mimalloc"
-version = "0.1.48"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e1ee66a4b64c74f4ef288bcbb9192ad9c3feaad75193129ac8509af543894fd8"
-dependencies = [
- "libmimalloc-sys",
-]
[[package]]
name = "mime"
@@ -1969,7 +1918,6 @@
name = "nixlike"
version = "0.1.0"
dependencies = [
- "alejandra",
"linked-hash-map",
"peg",
"ron",
@@ -2569,15 +2517,6 @@
"byteorder",
"rmp",
"serde",
-]
-
-[[package]]
-name = "rnix"
-version = "0.12.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6f15e00b0ab43abd70d50b6f8cd021290028f9b7fdd7cdfa6c35997173bc1ba9"
-dependencies = [
- "rowan",
]
[[package]]
@@ -2591,19 +2530,6 @@
"serde",
"serde_derive",
"unicode-ident",
-]
-
-[[package]]
-name = "rowan"
-version = "0.15.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d4f1e4a001f863f41ea8d0e6a0c34b356d5b733db50dadab3efef640bafb779b"
-dependencies = [
- "countme",
- "hashbrown 0.14.5",
- "memoffset",
- "rustc-hash 1.1.0",
- "text-size",
]
[[package]]
@@ -3155,12 +3081,6 @@
dependencies = [
"unicode-width 0.2.1",
]
-
-[[package]]
-name = "text-size"
-version = "1.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f18aa187839b2bdb1ad2fa35ead8c4c2976b64e4363c386d45ac0f7ee85c9233"
[[package]]
name = "tf-provider"
cmds/fleet/src/main.rsdiffbeforeafterboth1#![recursion_limit = "512"]23pub(crate) mod cmds;4// pub(crate) mod command;5pub(crate) mod extra_args;67use std::{ffi::OsString, process::ExitCode};89use anyhow::{Result, bail};10use clap::{CommandFactory, Parser};11use cmds::{12 build_systems::{BuildSystems, Deploy},13 complete::Complete,14 info::Info,15 rollback::RollbackSingle,16 secrets::Secret,17 tf::Tf,18};19use fleet_base::{host::Config, opts::FleetOpts};20use futures::{TryStreamExt, future::LocalBoxFuture, stream::FuturesUnordered};21// use host::Config;22#[cfg(feature = "indicatif")]23use human_repr::HumanCount;24#[cfg(feature = "indicatif")]25use indicatif::{ProgressState, ProgressStyle};26use nix_eval::{gc_register_my_thread, gc_unregister_my_thread, init_libraries};27use tracing::{Instrument, error, info, info_span};28#[cfg(feature = "indicatif")]29use tracing_indicatif::IndicatifLayer;30use tracing_subscriber::{EnvFilter, prelude::*};3132#[derive(Parser)]33struct Prefetch {}34impl Prefetch {35 async fn run(&self, config: &Config) -> Result<()> {36 let mut prefetch_dir = config.directory.to_path_buf();37 prefetch_dir.push("prefetch");38 if !prefetch_dir.is_dir() {39 info!("nothing to prefetch: no prefetch directory");40 return Ok(());41 }42 let tasks = <FuturesUnordered<LocalBoxFuture<Result<()>>>>::new();43 for entry in std::fs::read_dir(&prefetch_dir)? {44 tasks.push(Box::pin(async {45 let entry = entry?;46 if !entry.metadata()?.is_file() {47 bail!("only files should exist in prefetch directory");48 }49 let span = info_span!(50 "prefetching",51 name = entry.file_name().to_string_lossy().as_ref()52 );53 let mut path = OsString::new();54 path.push("file://");55 path.push(entry.path());5657 let mut status = config.local_host().cmd("nix").await?;58 status.args(&config.nix_args);59 status.arg("store").arg("prefetch-file").arg(path);60 status.run_nix_string().instrument(span).await?;61 Ok(())62 }));63 }64 tasks.try_collect::<Vec<()>>().await?;65 Ok(())66 }67}6869#[derive(Parser)]70enum Opts {71 /// Build system closures72 BuildSystems(BuildSystems),73 /// Upload and switch system closures74 Deploy(Deploy),75 /// Rollback remote machine by redeploying old generation as the new one76 RollbackSingle(RollbackSingle),77 /// Secret management78 #[clap(subcommand)]79 Secret(Secret),80 /// Upload prefetch directory to the nix store81 Prefetch(Prefetch),82 /// Config parsing83 Info(Info),84 /// Command completions85 #[clap(hide(true))]86 Complete(Complete),87 /// Compile and evaluate terranix configuration88 Tf(Tf),89}9091#[derive(Parser)]92#[clap(version, author)]93struct RootOpts {94 #[clap(flatten)]95 fleet_opts: FleetOpts,96 #[clap(subcommand)]97 command: Opts,98}99100async fn run_command(config: &Config, opts: FleetOpts, command: Opts) -> Result<()> {101 match command {102 Opts::BuildSystems(c) => c.run(config, &opts).await?,103 Opts::Deploy(d) => d.run(config, &opts).await?,104 Opts::RollbackSingle(r) => r.run(config, &opts).await?,105 Opts::Secret(s) => s.run(config, &opts).await?,106 Opts::Info(i) => i.run(config).await?,107 Opts::Prefetch(p) => p.run(config).await?,108 Opts::Tf(t) => t.run(config).await?,109 // TODO: actually parse commands before starting the async runtime110 Opts::Complete(c) => {111 tokio::task::spawn_blocking(move || c.run(RootOpts::command())).await?112 }113 };114 Ok(())115}116117fn setup_logging() {118 #[cfg(feature = "indicatif")]119 let indicatif_layer = {120 use std::time::Duration;121122 IndicatifLayer::new().with_progress_style(123 ProgressStyle::with_template(124 "{color_start}{span_child_prefix} {span_name}{{{span_fields}}}{color_end} {wide_msg} {color_start}{download_progress} {elapsed}{color_end}",125 )126 .unwrap()127 .with_key("download_progress", |state: &ProgressState, writer: &mut dyn std::fmt::Write| {128 let Some(len) = state.len() else {129 return;130 };131 let pos = state.pos();132 if pos > len {133 let _ = write!(writer, "{}", pos.human_count_bare());134 } else {135 let _ = write!(writer, "{} / {}", pos.human_count_bare(), len.human_count_bare());136 }137 })138 .with_key(139 "color_start",140 |state: &ProgressState, writer: &mut dyn std::fmt::Write| {141 let elapsed = state.elapsed();142143 if elapsed > Duration::from_secs(60) {144 // Red145 let _ = write!(writer, "\x1b[{}m", 1 + 30);146 } else if elapsed > Duration::from_secs(30) {147 // Yellow148 let _ = write!(writer, "\x1b[{}m", 3 + 30);149 }150 },151 )152 .with_key(153 "color_end",154 |state: &ProgressState, writer: &mut dyn std::fmt::Write| {155 if state.elapsed() > Duration::from_secs(30) {156 let _ = write!(writer, "\x1b[0m");157 }158 },159 ),160 )161 };162163 let filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info"));164165 let reg = tracing_subscriber::registry().with({166 let sub = tracing_subscriber::fmt::layer()167 .without_time()168 .with_target(false);169 #[cfg(feature = "indicatif")]170 let sub = sub.with_writer(indicatif_layer.get_stderr_writer());171 sub.with_filter(filter) // .without,172 });173 // #[cfg(feature = "indicatif")]174 #[cfg(feature = "indicatif")]175 let reg = reg.with(indicatif_layer);176 reg.init();177}178179fn main() -> ExitCode {180 let opts = RootOpts::parse();181 if let Opts::Complete(c) = &opts.command {182 c.run(RootOpts::command());183 return ExitCode::SUCCESS;184 }185186 setup_logging();187188 init_libraries();189190 tokio::runtime::Builder::new_multi_thread()191 .enable_all()192 .on_thread_start(|| {193 gc_register_my_thread();194 })195 .on_thread_stop(|| {196 gc_unregister_my_thread();197 })198 .build()199 .expect("failed to build runtime")200 .block_on(async {201 if let Err(e) = main_real(opts).await {202 error!("{e:#}");203 ExitCode::FAILURE204 } else {205 ExitCode::SUCCESS206 }207 })208 // async_main(opts)209}210211async fn main_real(opts: RootOpts) -> Result<()> {212 let nix_args = std::env::var_os("NIX_ARGS")213 .map(|a| extra_args::parse_os(&a))214 .transpose()?215 .unwrap_or_default();216 let config = opts217 .fleet_opts218 .build(219 nix_args,220 matches!(opts.command, Opts::Deploy(_) | Opts::BuildSystems(_)),221 )222 .await?;223224 match run_command(&config, opts.fleet_opts, opts.command).await {225 Ok(()) => {226 config.save()?;227 Ok(())228 }229 Err(e) => {230 let _ = config.save();231 Err(e)232 }233 }234}235236#[cfg(test)]237mod tests {238 use super::*;239240 #[test]241 fn verify_command() {242 use clap::CommandFactory;243 RootOpts::command().debug_assert();244 }245}crates/fleet-base/src/opts.rsdiffbeforeafterboth--- a/crates/fleet-base/src/opts.rs
+++ b/crates/fleet-base/src/opts.rs
@@ -9,7 +9,7 @@
use anyhow::{Context, Result, bail};
use nix_eval::{
FetchSettings, FlakeLockFlags, FlakeReference, FlakeReferenceParseFlags, FlakeSettings, Value,
- nix_go, util::assert_warn,
+ gc_now, nix_go, util::assert_warn,
};
use nom::{
Parser,
@@ -260,6 +260,10 @@
system: self.local_system.clone(),
}));
+ if cfg!(debug_assertions) {
+ gc_now();
+ }
+
Ok(Config(Arc::new(FleetConfigInternals {
directory,
data,
crates/nix-eval/src/lib.rsdiffbeforeafterboth--- a/crates/nix-eval/src/lib.rs
+++ b/crates/nix-eval/src/lib.rs
@@ -1,29 +1,42 @@
+use std::alloc::{GlobalAlloc, Layout};
use std::borrow::Cow;
use std::cell::RefCell;
use std::ffi::{CStr, CString, c_char, c_int, c_uint, c_void};
-use std::fmt;
+use std::mem::forget;
use std::ptr::null_mut;
use std::sync::LazyLock;
use std::{collections::HashMap, path::PathBuf};
+use std::{fmt, slice};
use anyhow::{Context, anyhow, bail};
use serde::Serialize;
use serde::de::DeserializeOwned;
pub use anyhow::Result;
-use tracing::instrument;
+use tracing::{info, instrument};
use self::logging::nix_logging_cxx;
use self::nix_cxx::set_fetcher_setting;
use self::nix_raw::{
- alloc_value, c_context, c_context_create, err_code, err_info_msg, eval_state_build,
- eval_state_builder_new, expr_eval_from_string, fetchers_settings, fetchers_settings_free,
- fetchers_settings_new, flake_lock, flake_lock_flags, flake_lock_flags_free,
- flake_lock_flags_new, flake_reference_parse_flags, flake_reference_parse_flags_free,
- flake_reference_parse_flags_new, flake_reference_parse_flags_set_base_directory,
- flake_settings, flake_settings_free, flake_settings_new, get_string, init_bool, init_int,
- init_string, locked_flake_free, locked_flake_get_output_attrs, set_err_msg, setting_set,
- state_free, value_decref, value_incref,
+ BindingsBuilder as c_bindings_builder, EvalState as c_eval_state, GC_SUCCESS,
+ GC_allow_register_threads, GC_free, GC_get_stack_base, GC_init, GC_malloc, GC_realloc,
+ GC_register_my_thread, GC_stack_base, GC_thread_is_registered, GC_unregister_my_thread,
+ Store as c_store, alloc_value, bindings_builder_free, bindings_builder_insert, c_context,
+ c_context_create, c_context_free, clear_err, err_code, err_info_msg, err_msg, eval_state_build,
+ eval_state_builder_load, eval_state_builder_new, eval_state_builder_set_eval_setting,
+ expr_eval_from_string, fetchers_settings, fetchers_settings_free, fetchers_settings_new,
+ flake_lock, flake_lock_flags, flake_lock_flags_free, flake_lock_flags_new, flake_reference,
+ flake_reference_and_fragment_from_string, flake_reference_parse_flags,
+ flake_reference_parse_flags_free, flake_reference_parse_flags_new,
+ flake_reference_parse_flags_set_base_directory, flake_settings, flake_settings_free,
+ flake_settings_new, get_attr_byname, get_attr_name_byidx, get_attrs_size, get_list_byidx,
+ get_list_size, get_string, get_type, has_attr_byname, init_bool, init_int, init_string,
+ libexpr_init, libstore_init, libutil_init, locked_flake, locked_flake_free,
+ locked_flake_get_output_attrs, make_attrs, make_bindings_builder, realised_string,
+ realised_string_free, realised_string_get_buffer_size, realised_string_get_buffer_start,
+ realised_string_get_store_path, realised_string_get_store_path_count, set_err_msg, setting_set,
+ state_free, store_open, store_path_name, string_realise, value, value_call, value_decref,
+ value_incref,
};
// Contains macros helpers
@@ -117,22 +130,26 @@
}
}
+pub fn gc_now() {
+ unsafe { nix_raw::gc_now() };
+}
+
pub fn gc_register_my_thread() {
- assert_eq!(unsafe { nix_raw::GC_thread_is_registered() }, 0);
+ assert_eq!(unsafe { GC_thread_is_registered() }, 0);
- let mut sb = nix_raw::GC_stack_base {
+ let mut sb = GC_stack_base {
mem_base: null_mut(),
};
- let r = unsafe { nix_raw::GC_get_stack_base(&mut sb) };
- if r as u32 != nix_raw::GC_SUCCESS {
+ let r = unsafe { GC_get_stack_base(&mut sb) };
+ if r as u32 != GC_SUCCESS {
panic!("failed to get thread stack base");
}
- unsafe { nix_raw::GC_register_my_thread(&sb) };
+ unsafe { GC_register_my_thread(&sb) };
}
pub fn gc_unregister_my_thread() {
- assert_eq!(unsafe { nix_raw::GC_thread_is_registered() }, 1);
+ assert_eq!(unsafe { GC_thread_is_registered() }, 1);
- unsafe { nix_raw::GC_unregister_my_thread() };
+ unsafe { GC_unregister_my_thread() };
}
pub struct ThreadRegisterGuard {}
@@ -178,12 +195,12 @@
// TODO: Can throw error (resulting in panic) if unable to retrieve error. Should be able to resolve by passing context as a first argument,
// but it looks ugly
- let str = unsafe { nix_raw::err_msg(null_mut(), self.0, null_mut()) };
+ let str = unsafe { err_msg(null_mut(), self.0, null_mut()) };
Some(unsafe { CStr::from_ptr(str) }.to_string_lossy())
}
fn clean_err(&mut self) {
unsafe {
- nix_raw::clear_err(self.0);
+ clear_err(self.0);
}
}
@@ -211,7 +228,7 @@
impl Drop for NixContext {
fn drop(&mut self) {
unsafe {
- nix_raw::c_context_free(self.0);
+ c_context_free(self.0);
}
}
}
@@ -225,35 +242,26 @@
fn new() -> Result<Self> {
let mut ctx = NixContext::new();
let store = ctx
- .run_in_context(|c| unsafe { nix_raw::store_open(c, c"auto".as_ptr(), null_mut()) })
+ .run_in_context(|c| unsafe { store_open(c, c"auto".as_ptr(), null_mut()) })
.map(Store)?;
let builder = ctx.run_in_context(|c| unsafe { eval_state_builder_new(c, store.0) })?;
- ctx.run_in_context(|c| {
- unsafe { nix_raw::eval_state_builder_load(c, builder) }
- // eval_s
- })?;
- ctx.run_in_context(|c| {
- unsafe {
- nix_raw::eval_state_builder_set_eval_setting(
- c,
- builder,
- c"lazy-trees".as_ptr(),
- c"true".as_ptr(),
- )
- }
- // eval_s
+ ctx.run_in_context(|c| unsafe { eval_state_builder_load(c, builder) })?;
+ ctx.run_in_context(|c| unsafe {
+ eval_state_builder_set_eval_setting(
+ c,
+ builder,
+ c"lazy-trees".as_ptr(),
+ c"true".as_ptr(),
+ )
})?;
- ctx.run_in_context(|c| {
- unsafe {
- nix_raw::eval_state_builder_set_eval_setting(
- c,
- builder,
- c"lazy-locks".as_ptr(),
- c"true".as_ptr(),
- )
- }
- // eval_s
+ ctx.run_in_context(|c| unsafe {
+ eval_state_builder_set_eval_setting(
+ c,
+ builder,
+ c"lazy-locks".as_ptr(),
+ c"true".as_ptr(),
+ )
})?;
let state = ctx
.run_in_context(|c| unsafe { eval_state_build(c, builder) })
@@ -280,9 +288,7 @@
thread_local! {
static THREAD_STATE: RefCell<ThreadState> = RefCell::new(ThreadState::new().expect("thread state init shouldn't fail"));
}
-fn with_default_context<T>(
- f: impl FnOnce(*mut c_context, *mut nix_raw::EvalState) -> T,
-) -> Result<T> {
+fn with_default_context<T>(f: impl FnOnce(*mut c_context, *mut c_eval_state) -> T) -> Result<T> {
let global = &GLOBAL_STATE.state;
let (ctx, state) = THREAD_STATE.with_borrow_mut(|w| (w.ctx.0, global.0));
let mut ctx = NixContext(ctx);
@@ -385,16 +391,16 @@
}
unsafe extern "C" fn copy_nix_str(start: *const c_char, n: c_uint, user_data: *mut c_void) {
- let s = unsafe { std::slice::from_raw_parts(start.cast::<u8>(), n as usize) };
+ let s = unsafe { slice::from_raw_parts(start.cast::<u8>(), n as usize) };
let s = std::str::from_utf8(s).expect("c string has invalid utf-8");
unsafe { *user_data.cast::<String>() = s.to_owned() };
}
-struct Store(*mut nix_raw::Store);
+struct Store(*mut c_store);
unsafe impl Send for Store {}
unsafe impl Sync for Store {}
-struct EvalState(*mut nix_raw::EvalState);
+struct EvalState(*mut c_eval_state);
unsafe impl Send for EvalState {}
unsafe impl Sync for EvalState {}
@@ -406,7 +412,7 @@
}
}
-pub struct FlakeReference(*mut nix_raw::flake_reference);
+pub struct FlakeReference(*mut flake_reference);
impl FlakeReference {
#[instrument(name = "new-flake-reference", skip(flake, parse, fetch))]
pub fn new(
@@ -419,7 +425,7 @@
let mut fragment = String::new();
// let fetch_settings = fetcher_settings;
with_default_context(|c, _| unsafe {
- nix_raw::flake_reference_and_fragment_from_string(
+ flake_reference_and_fragment_from_string(
c,
fetch.0,
flake.0,
@@ -449,7 +455,7 @@
unsafe impl Send for FlakeReference {}
unsafe impl Sync for FlakeReference {}
-pub struct LockedFlake(*mut nix_raw::locked_flake);
+pub struct LockedFlake(*mut locked_flake);
impl LockedFlake {
pub fn get_attrs(&self, settings: &mut FlakeSettings) -> Result<Value> {
with_default_context(|c, es| unsafe {
@@ -480,7 +486,7 @@
f
}
-pub struct RealisedString(*mut nix_raw::realised_string);
+pub struct RealisedString(*mut realised_string);
impl fmt::Debug for RealisedString {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.as_str().fmt(f)
@@ -489,19 +495,19 @@
impl RealisedString {
pub fn as_str(&self) -> &str {
- let len = unsafe { nix_raw::realised_string_get_buffer_size(self.0) };
- let data: *const u8 = unsafe { nix_raw::realised_string_get_buffer_start(self.0) }.cast();
- let data = unsafe { std::slice::from_raw_parts(data, len) };
+ let len = unsafe { realised_string_get_buffer_size(self.0) };
+ let data: *const u8 = unsafe { realised_string_get_buffer_start(self.0) }.cast();
+ let data = unsafe { slice::from_raw_parts(data, len) };
std::str::from_utf8(data).expect("non-utf8 strings not supported")
}
pub fn path_count(&self) -> usize {
- unsafe { nix_raw::realised_string_get_store_path_count(self.0) }
+ unsafe { realised_string_get_store_path_count(self.0) }
}
pub fn path(&self, i: usize) -> String {
assert!(i < self.path_count());
- let path = unsafe { nix_raw::realised_string_get_store_path(self.0, i) };
+ let path = unsafe { realised_string_get_store_path(self.0, i) };
let mut err_out = String::new();
- unsafe { nix_raw::store_path_name(path, Some(copy_nix_str), (&raw mut err_out).cast()) };
+ unsafe { store_path_name(path, Some(copy_nix_str), (&raw mut err_out).cast()) };
err_out
}
}
@@ -509,11 +515,11 @@
unsafe impl Send for RealisedString {}
impl Drop for RealisedString {
fn drop(&mut self) {
- unsafe { nix_raw::realised_string_free(self.0) }
+ unsafe { realised_string_free(self.0) }
}
}
-pub struct Value(*mut nix_raw::value);
+pub struct Value(*mut value);
unsafe impl Send for Value {}
unsafe impl Sync for Value {}
@@ -544,17 +550,18 @@
}
}
-struct AttrsBuilder(*mut nix_raw::BindingsBuilder);
+struct AttrsBuilder(*mut c_bindings_builder);
impl AttrsBuilder {
fn new(capacity: usize) -> Self {
- with_default_context(|c, es| unsafe { nix_raw::make_bindings_builder(c, es, capacity) })
+ with_default_context(|c, es| unsafe { make_bindings_builder(c, es, capacity) })
.map(Self)
.expect("alloc should not fail")
}
fn insert(&mut self, k: &impl AsFieldName, v: Value) {
k.as_field_name(|name| {
with_default_context(|c, _| unsafe {
- nix_raw::bindings_builder_insert(c, self.0, name.as_ptr().cast(), v.0)
+ bindings_builder_insert(c, self.0, name.as_ptr().cast(), v.0);
+ // bindings_builder_insert doesn't do incref
})
})
.expect("builder insert shouldn't fail");
@@ -562,7 +569,7 @@
}
impl Drop for AttrsBuilder {
fn drop(&mut self) {
- unsafe { nix_raw::bindings_builder_free(self.0) };
+ unsafe { bindings_builder_free(self.0) };
}
}
@@ -573,8 +580,9 @@
for (k, v) in v {
b.insert(&k, v);
}
- with_default_context(|c, _| unsafe { nix_raw::make_attrs(c, out.0, b.0) })
+ with_default_context(|c, _| unsafe { make_attrs(c, out.0, b.0) })
.expect("attrs initialization should not fail");
+
out
}
fn new_list<T: Into<Self>>(v: Vec<T>) -> Self {
@@ -611,7 +619,7 @@
// Ok(())
// }
pub fn type_of(&self) -> NixType {
- let ty = with_default_context(|c, _| unsafe { nix_raw::get_type(c, self.0) })
+ let ty = with_default_context(|c, _| unsafe { get_type(c, self.0) })
.expect("get_type should not fail");
NixType::from_int(ty)
}
@@ -628,7 +636,7 @@
Ok(str_out)
}
pub fn to_realised_string(&self) -> Result<RealisedString> {
- with_default_context(|c, es| unsafe { nix_raw::string_realise(c, es, self.0, false) })
+ with_default_context(|c, es| unsafe { string_realise(c, es, self.0, false) })
.map(RealisedString)
// let store_paths = unsafe { nix_raw::realised_string_get_store_path_count(str) };
@@ -642,9 +650,7 @@
pub fn has_field(&self, field: &str) -> Result<bool> {
let f = init_field_name(field);
- with_default_context(|c, es| unsafe {
- nix_raw::has_attr_byname(c, self.0, es, f.as_ptr().cast())
- })
+ with_default_context(|c, es| unsafe { has_attr_byname(c, self.0, es, f.as_ptr().cast()) })
}
// pub fn derivation_path(&self) {
// nix_raw::real
@@ -654,13 +660,12 @@
bail!("invalid type: expected attrs");
}
- let len = with_default_context(|c, _| unsafe { nix_raw::get_attrs_size(c, self.0) })?;
+ let len = with_default_context(|c, _| unsafe { get_attrs_size(c, self.0) })?;
let mut out = Vec::with_capacity(len as usize);
for i in 0..len {
- let name = with_default_context(|c, es| unsafe {
- nix_raw::get_attr_name_byidx(c, self.0, es, i)
- })?;
+ let name =
+ with_default_context(|c, es| unsafe { get_attr_name_byidx(c, self.0, es, i) })?;
let c = unsafe { CStr::from_ptr(name) };
out.push(c.to_str().expect("nix field names are utf-8").to_owned());
}
@@ -670,14 +675,12 @@
if !matches!(self.type_of(), NixType::List) {
bail!("invalid type: expected list");
}
- let len =
- with_default_context(|c, _| unsafe { nix_raw::get_list_size(c, self.0) })? as usize;
+ let len = with_default_context(|c, _| unsafe { get_list_size(c, self.0) })? as usize;
if v >= len {
bail!("oob list get: {v} >= {len}");
}
- with_default_context(|c, es| unsafe { nix_raw::get_list_byidx(c, self.0, es, v as u32) })
- .map(Self)
+ with_default_context(|c, es| unsafe { get_list_byidx(c, self.0, es, v as u32) }).map(Self)
}
pub fn attrs_update(self, other: Value) -> Result<Self> {
let a_fields = self.list_fields()?;
@@ -710,7 +713,7 @@
name.as_field_name(|name| {
with_default_context(|c, es| unsafe {
- nix_raw::get_attr_byname(c, self.0, es, name.as_ptr().cast())
+ get_attr_byname(c, self.0, es, name.as_ptr().cast())
})
.map(Self)
})
@@ -735,9 +738,7 @@
};
let out = Value::new_uninit();
- with_default_context(|c, es| unsafe {
- nix_raw::value_call(c, es, function.0, v.0, out.0)
- })?;
+ with_default_context(|c, es| unsafe { value_call(c, es, function.0, v.0, out.0) })?;
Ok(out)
}
@@ -745,7 +746,7 @@
let s = CString::new(v).expect("expression shouldn't have internal NULs");
let out = Self::new_uninit();
with_default_context(|c, es| unsafe {
- expr_eval_from_string(c, es, s.as_ptr(), c"/homeless-shelter".as_ptr(), out.0)
+ expr_eval_from_string(c, es, s.as_ptr(), c"/root".as_ptr(), out.0)
})?;
Ok(out)
}
@@ -764,11 +765,10 @@
self.clone()
};
// to_string here blocks until the path is built
- let drv_path =
- tokio::task::spawn_blocking(move || v.builtin_to_string()?.to_realised_string())
- .await
- .expect("spawn should not fail")?;
- Ok(PathBuf::from(drv_path.as_str()))
+ let s = v.builtin_to_string()?;
+ let rs = s.to_realised_string()?;
+ let drv_path = rs.as_str().to_owned();
+ Ok(PathBuf::from(drv_path))
}
pub fn as_json<T: DeserializeOwned>(&self) -> Result<T> {
let to_json = Self::eval("builtins.toJSON")?;
@@ -848,17 +848,14 @@
}
pub fn init_libraries() {
- unsafe { nix_raw::GC_allow_register_threads() };
- unsafe {
- nix_raw::GC_init();
- };
+ unsafe { GC_allow_register_threads() };
let mut ctx = NixContext::new();
- ctx.run_in_context(|c| unsafe { nix_raw::libutil_init(c) })
+ ctx.run_in_context(|c| unsafe { libutil_init(c) })
.expect("util init should not fail");
- ctx.run_in_context(|c| unsafe { nix_raw::libstore_init(c) })
+ ctx.run_in_context(|c| unsafe { libstore_init(c) })
.expect("store init should not fail");
- ctx.run_in_context(|c| unsafe { nix_raw::libexpr_init(c) })
+ ctx.run_in_context(|c| unsafe { libexpr_init(c) })
.expect("expr init should not fail");
nix_logging_cxx::apply_tracing_logger();
@@ -872,8 +869,11 @@
fetch_settings.set(c"warn-dirty", c"false");
let manifest = format!("{}/../../", env!("CARGO_MANIFEST_DIR"));
- let (mut r, _) = FlakeReference::new(&manifest, &fetch_settings)?;
- let locked = r.lock(&fetch_settings)?;
+ let flake = FlakeSettings::new()?;
+ let parse = FlakeReferenceParseFlags::new(&flake)?;
+ let (mut r, _) = FlakeReference::new(&manifest, &flake, &parse, &fetch_settings)?;
+ let lock = FlakeLockFlags::new(&flake)?;
+ let locked = r.lock(&fetch_settings, &flake, &lock)?;
let attrs = locked.get_attrs(&mut FlakeSettings::new()?)?;
let builtins = Value::eval("builtins")?;
@@ -887,3 +887,22 @@
Ok(())
}
+
+// pub struct GcAlloc;
+// unsafe impl GlobalAlloc for GcAlloc {
+// unsafe fn alloc(&self, l: Layout) -> *mut u8 {
+// let ptr = unsafe { GC_malloc(l.size()) };
+// ptr.cast()
+// }
+// unsafe fn dealloc(&self, ptr: *mut u8, _: Layout) {
+// // unsafe { GC_free(ptr.cast()) };
+// }
+//
+// unsafe fn realloc(&self, ptr: *mut u8, _: Layout, new_size: usize) -> *mut u8 {
+// let ptr = unsafe { GC_realloc(ptr.cast(), new_size) };
+// ptr.cast()
+// }
+// }
+//
+// #[global_allocator]
+// static GC: GcAlloc = GcAlloc;
crates/nix-eval/src/logging.rsdiffbeforeafterboth--- a/crates/nix-eval/src/logging.rs
+++ b/crates/nix-eval/src/logging.rs
@@ -504,7 +504,7 @@
// Only plain colors are enabled, everything other might corrupt the output
return;
}
- self.output.push_str("IDK\x1b[");
+ self.output.push_str("\x1b[");
for (i, par) in params.iter().enumerate() {
if i != 0 {
let _ = write!(self.output, ";");
crates/nixlike/Cargo.tomldiffbeforeafterboth--- a/crates/nixlike/Cargo.toml
+++ b/crates/nixlike/Cargo.toml
@@ -7,7 +7,6 @@
[dependencies]
thiserror.workspace = true
-alejandra = { git = "https://github.com/kamadorueda/alejandra" }
linked-hash-map = "0.5.6"
peg = "0.8.5"
ron = "0.11.0"
crates/nixlike/src/lib.rsdiffbeforeafterboth--- a/crates/nixlike/src/lib.rs
+++ b/crates/nixlike/src/lib.rs
@@ -5,7 +5,6 @@
//! expressions and expect it to work, only basic primitives are supported, and there is no
//! variables/recursive records, interpolation, e.t.c.
-use alejandra::config::Indentation;
use linked_hash_map::LinkedHashMap;
use peg::str::LineCol;
use se_impl::MySerialize;
@@ -197,14 +196,8 @@
assert_eq!(serialize("Hello\nworld").unwrap(), "\"Hello\\nworld\"\n");
}
pub fn format_nix(value: &String) -> String {
- let (_, out) = alejandra::format::in_memory(
- "".to_owned(),
- value.to_owned(),
- alejandra::config::Config {
- indentation: Indentation::TwoSpaces,
- },
- );
- out
+ // TODO
+ value.to_owned()
}
#[test]
crates/nixlike/src/to_string.rsdiffbeforeafterboth--- a/crates/nixlike/src/to_string.rs
+++ b/crates/nixlike/src/to_string.rs
@@ -1,5 +1,3 @@
-use alejandra::config::Indentation;
-
use crate::Value;
pub fn write_identifier(k: &str, out: &mut String) {
@@ -100,12 +98,5 @@
pub fn write_nix(value: &Value) -> String {
let mut out = String::new();
write_nix_buf(value, &mut out);
- let (_, out) = alejandra::format::in_memory(
- "".to_owned(),
- out,
- alejandra::config::Config {
- indentation: Indentation::TwoSpaces,
- },
- );
out
}
flake.nixdiffbeforeafterboth--- a/flake.nix
+++ b/flake.nix
@@ -114,7 +114,13 @@
{
_module.args.pkgs = import inputs.nixpkgs {
inherit system;
- overlays = [ (inputs.rust-overlay.overlays.default) ];
+ overlays = [ (inputs.rust-overlay.overlays.default) (final: prev: {
+ boehmgc = prev.boehmgc.overrideAttrs (prevAttrs: {
+ configureFlags = prevAttrs.configureFlags ++ [
+ "--enable-gc-assertions"
+ ];
+ });
+ }) ];
};
# Reference fleet package should be built with nightly rust, specified in rust-toolchain.toml.
packages = lib.mkIf deployerSystem (
@@ -157,7 +163,6 @@
factory = craneLib.devShell;
packages = with pkgs; [
rust
- alejandra
cargo-edit
cargo-udeps
cargo-fuzz