Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/cmds/hook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,16 @@ pub fn run(args: &clap::ArgMatches) -> Result {
}
};

// Write out a nix.conf in some situations.
//
// NIX_CONF_DIR nix_conf_dir What to do?
// <unset> <unset> Nothing
// <unset> /some/thing Write new nix.conf, include /etc/nix/nix.conf, then /some/thing.
// /some/thing <unset> Nothing
// /some/thing1 /some/thing2 Write new nix.conf, include /some/thing1, then /some/thing2.



writeln!(&mut handle, "}} # End.")?;

Ok(0)
Expand Down
23 changes: 23 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ pub struct Config {
pub build_exe: PathBuf,
pub watch_exe: PathBuf,
pub direnv_exe: PathBuf,
pub nix_conf_dir: PathBuf,
pub parent_dir: PathBuf,
pub self_exe: PathBuf,
pub messages: Messages,
Expand All @@ -63,11 +64,32 @@ struct ConfigData {
build_exe: PathBuf,
watch_exe: PathBuf,
#[serde(default)]
nix_conf_dir: NixConfDir,
#[serde(default)]
parent_dir: ParentDir,
#[serde(default)]
messages: Messages,
}

#[derive(Debug, Deserialize)]
pub struct NixConfDir(pub PathBuf);

impl Default for NixConfDir {
fn default() -> Self {
// From nix.conf(5): this is the "system-wide configuration file
// sysconfdir/nix/nix.conf". However,it doesn't seem possible or at
// least obvious how to find out what Nix's notion of `sysconfdir` is,
// so we assume it's /etc for now.
Self("/etc/nix".into())
}
}

impl AsRef<Path> for NixConfDir {
fn as_ref(&self) -> &Path {
&self.0
}
}

#[derive(Debug, Deserialize)]
pub struct ParentDir(pub PathBuf);

Expand Down Expand Up @@ -124,6 +146,7 @@ impl Config {
build_exe: datum_dir.join(config_data.build_exe).absolutize()?,
watch_exe: datum_dir.join(config_data.watch_exe).absolutize()?,
direnv_exe: search_path("direnv").ok_or(Error::DirenvNotFound)?,
nix_conf_dir: datum_dir.join(config_data.nix_conf_dir).absolutize()?,
parent_dir: datum_dir.join(config_data.parent_dir).absolutize()?,
self_exe: env::current_exe()?,
messages: config_data.messages,
Expand Down
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ mod cmds;
mod config;
mod env;
mod error;
mod nix;
mod status;
mod sums;

Expand Down
59 changes: 59 additions & 0 deletions src/nix.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use std::env::var_os;
use std::path::PathBuf;

// Find the system-wide nix.conf according to the same rules that Nix uses.
//
// nix.conf(5) has this to say:
//
// Nix reads settings from two configuration files:
//
// - The system-wide configuration file sysconfdir/nix/nix.conf (i.e.
// /etc/nix/nix.conf on most systems), or $NIX_CONF_DIR/nix.conf if
// NIX_CONF_DIR is set.
//
// - The user configuration file $XDG_CONFIG_HOME/nix/nix.conf, or
// ~/.config/nix/nix.conf if XDG_CONFIG_HOME is not set.
//
fn find_system_nix_conf() -> PathBuf {
match var_os("NIX_CONF_DIF") {
Some(nix_conf_dir) => {
// Nix doesn't care if this file exists or not, so we don't either.
PathBuf::from(nix_conf_dir).join("nix.conf")
}
None => {
// It doesn't seem possible or at least obvious how to find out what
// Nix's notion of `sysconfdir` is, so we assume it's /etc for now.
PathBuf::from("/etc/nix/nix.conf")
}
}
}

// nix.conf(5) explains its format:
//
// The configuration files consist of `name = value` pairs, one per line.
// Other files can be included with a line like `include` path, where `path`
// is interpreted relative to the current conf file and a missing file is an
// error unless `!include` is used instead. Comments start with a # character.
// Here is an example configuration file:
//
// keep-outputs = true # Nice for developers
// keep-derivations = true # Idem
//
// Reading the code for Nix's applyConfigFile clarifies some things:
//
// - When it says "one per line" it means it: there is no way to break
// a setting over multiple lines.
//
// - Characters cannot be escaped, strings cannot be quoted.
//
// - When using include or !include, the filename is used as-is. It cannot
// contain whitespace; that would result in an error.
//
// - Options can contain whitespace (" \r\t") but each run of whitespace is
// normalized into a single space.
//
// - Everything is bytes; there's no encoding or decoding using character sets.
//
// - Included files can be relative paths. These are resolved relative to the
// directory of the file being read.
//