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