1pub mod fragments;
13pub mod matrix;
14pub mod nix;
15pub mod source;
16pub mod target;
17pub mod version;
18
19use camino::{Utf8Path, Utf8PathBuf};
20
21pub use crate::cli::depend::{Channel, Kind, Manager};
22use crate::diagnostic::{Diagnostic, Reason};
23use crate::error::RkError;
24
25pub fn canonical_dir(path: &Utf8Path, role: &'static str) -> Result<Utf8PathBuf, RkError> {
32 if !path.is_dir() {
33 return Err(RkError::missing(
34 Diagnostic::new(
35 Reason::TargetNotFound,
36 format!("{role} {path} is not a directory"),
37 )
38 .expected(format!("an existing {role} directory to read")),
39 ));
40 }
41 Ok(path.canonicalize_utf8()?)
42}
43
44pub fn reject_url(raw: &Utf8Path) -> Result<(), RkError> {
52 let text = raw.as_str();
53 if text.contains("://") || text.starts_with("git@") {
54 return Err(RkError::Usage(
55 "--source takes a local checkout; clone the URL first, then pass the directory".into(),
56 ));
57 }
58 Ok(())
59}
60
61#[cfg(test)]
62mod tests {
63 use camino::Utf8Path;
64
65 use super::{canonical_dir, reject_url};
66 use crate::error::RkError;
67
68 #[test]
69 fn a_url_is_refused_before_the_disk_is_read() {
70 for raw in [
71 "https://github.com/owner/repo",
72 "git@github.com:owner/repo.git",
73 "ssh://git@github.com/owner/repo",
74 ] {
75 assert!(
76 matches!(reject_url(Utf8Path::new(raw)), Err(RkError::Usage(_))),
77 "{raw} is refused"
78 );
79 }
80 assert!(reject_url(Utf8Path::new("../repo")).is_ok());
81 }
82
83 #[test]
84 fn a_missing_directory_is_a_missing_error() {
85 let result = canonical_dir(Utf8Path::new("/nonexistent/depend/source"), "source");
86 assert!(matches!(result, Err(RkError::Missing(_))));
87 assert_eq!(result.err().map(|e| e.exit_code()), Some(66));
88 }
89}