1use std::path::PathBuf;
2
3use clap::Parser;
4use snix_store::utils::ServiceUrlsMemory;
5
6#[derive(Parser, Clone)]
15pub struct Args {
16 pub script: Option<PathBuf>,
18
19 #[clap(long, short = 'E')]
20 pub expr: Option<String>,
21
22 #[clap(long, env = "SNIX_DISPLAY_AST")]
24 pub display_ast: bool,
25
26 #[clap(long, env = "SNIX_DUMP_BYTECODE")]
28 pub dump_bytecode: bool,
29
30 #[clap(long, env = "SNIX_TRACE_RUNTIME")]
32 pub trace_runtime: bool,
33
34 #[clap(long, env = "SNIX_TRACE_RUNTIME_TIMING", requires("trace_runtime"))]
37 pub trace_runtime_timing: bool,
38
39 #[clap(long)]
42 pub compile_only: bool,
43
44 #[clap(long)]
46 pub no_warnings: bool,
47
48 #[clap(long = "extra-nix-path", short = 'I', action = clap::ArgAction::Append)]
54 pub extra_nix_paths: Option<Vec<String>>,
55
56 #[clap(long)]
58 pub raw: bool,
59
60 #[clap(long)]
64 pub strict: bool,
65
66 #[clap(flatten)]
67 pub service_addrs: ServiceUrlsMemory,
68
69 #[arg(long, env, default_value = "dummy://")]
70 pub build_service_addr: String,
71
72 #[clap(long)]
81 pub drv_dumpdir: Option<PathBuf>,
82}
83
84impl Args {
85 pub fn nix_path(&self) -> Option<String> {
86 resolve_nix_path(std::env::var("NIX_PATH"), &self.extra_nix_paths)
87 }
88}
89
90fn resolve_nix_path(
91 nix_path: Result<String, std::env::VarError>,
92 extra_nix_paths: &Option<Vec<String>>,
93) -> Option<String> {
94 let nix_path_option = nix_path.ok().filter(|string| !string.is_empty());
95 let extra_nix_paths_option = extra_nix_paths.to_owned().map(|vec| vec.join(":"));
96 match (nix_path_option, extra_nix_paths_option) {
97 (Some(nix_path), Some(mut extra_nix_paths)) => {
98 extra_nix_paths.push(':');
99 Some(extra_nix_paths + &nix_path)
100 }
101 (nix_path_option, extra_nix_paths_option) => nix_path_option.or(extra_nix_paths_option),
102 }
103}
104
105#[cfg(test)]
106mod tests {
107 use super::resolve_nix_path;
108
109 #[test]
110 fn test_resolve_nix_path() {
111 let nix_path = Ok("/nixpath1:nixpath2=/nixpath2".to_owned());
112 let extra_nix_paths = Some(vec!["/extra1".to_owned(), "extra2=/extra2".to_owned()]);
113 let expected = Some("/extra1:extra2=/extra2:/nixpath1:nixpath2=/nixpath2".to_owned());
114 let actual = resolve_nix_path(nix_path, &extra_nix_paths);
115 assert!(actual == expected);
116 let nix_path = Err(std::env::VarError::NotPresent);
117 let extra_nix_paths = Some(vec!["/extra1".to_owned(), "extra2=/extra2".to_owned()]);
118 let expected = Some("/extra1:extra2=/extra2".to_owned());
119 let actual = resolve_nix_path(nix_path, &extra_nix_paths);
120 assert!(actual == expected);
121 let nix_path = Ok("/nixpath1:nixpath2=/nixpath2".to_owned());
122 let extra_nix_paths = None;
123 let expected = Some("/nixpath1:nixpath2=/nixpath2".to_owned());
124 let actual = resolve_nix_path(nix_path, &extra_nix_paths);
125 assert!(actual == expected);
126 let nix_path = Err(std::env::VarError::NotPresent);
127 let extra_nix_paths = None;
128 let expected = None;
129 let actual = resolve_nix_path(nix_path, &extra_nix_paths);
130 assert!(actual == expected);
131 }
132}