Skip to content

Commit

Permalink
Use std::path and canonicalization for the paths in Choo
Browse files Browse the repository at this point in the history
  • Loading branch information
bitemyapp committed Jan 13, 2025
1 parent ee9fc83 commit 6cdc585
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 14 deletions.
46 changes: 32 additions & 14 deletions apps/choo/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ struct ChooCli {
boot: BootCli,

#[arg(help = "Path to file to compile")]
entry: String,
entry: std::path::PathBuf,

#[arg(help = "Path to root of dependency directory", default_value = "hoon")]
directory: String,
directory: std::path::PathBuf,

#[arg(
long,
Expand Down Expand Up @@ -91,10 +91,18 @@ async fn main() -> Result<(), Error> {
Ok(())
}

async fn initialize_nockapp(cli: ChooCli) -> Result<crown::nockapp::NockApp, Error> {
// Remove trailing slash from directory if present
let directory = cli.directory.trim_end_matches('/').to_string();
fn canonicalize_and_string(path: &std::path::Path) -> Result<String, Error> {
let path = path.canonicalize()?;
let path = path.to_str().ok_or_else(|| {
std::io::Error::new(
std::io::ErrorKind::NotFound,
"Path is not valid or file cannot be found",
)
})?;
Ok(path.to_string())
}

async fn initialize_nockapp(cli: ChooCli) -> Result<crown::nockapp::NockApp, Error> {
let mut nockapp = boot::setup(KERNEL_JAM, Some(cli.boot.clone()), &[], "choo")?;
boot::init_default_tracing(&cli.boot.clone());
let mut slab = NounSlab::new();
Expand All @@ -114,17 +122,11 @@ async fn initialize_nockapp(cli: ChooCli) -> Result<crown::nockapp::NockApp, Err
Atom::from_value(&mut slab, contents_vec).unwrap().as_noun()
};

let mut entry = cli.entry.clone();

// Insert a leading slash if it is not present
// Needed to make the entry path an actual hoon $path type
if !entry.starts_with('/') {
entry.insert(0, '/');
}

let entry_path = Atom::from_value(&mut slab, entry).unwrap().as_noun();
let entry_string = canonicalize_and_string(&cli.entry)?;
let entry_path = Atom::from_value(&mut slab, entry_string).unwrap().as_noun();

let mut directory_noun = D(0);
let directory = canonicalize_and_string(&cli.directory)?;

let walker = WalkDir::new(&directory)
.follow_links(true)
Expand Down Expand Up @@ -176,3 +178,19 @@ async fn work_loop(mut nockapp: crown::nockapp::NockApp) {
}
}
}

#[cfg(test)]
mod test {
#[test]
#[cfg_attr(miri, ignore)]
fn test_canonicalize_and_string() {
let path = std::path::Path::new("Cargo.toml");
let result = super::canonicalize_and_string(path);
assert!(result.is_ok());
// left: "/Users/callen/work/zorp/nockapp/apps/choo/Cargo.toml"
// right: "Cargo.toml"
let pwd = std::env::current_dir().unwrap();
let cargo_toml = pwd.join("Cargo.toml").canonicalize().unwrap();
assert_eq!(result.unwrap(), cargo_toml.to_str().unwrap());
}
}
6 changes: 6 additions & 0 deletions crown/src/noun/extensions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ impl NounExt for Noun {
}
}

// TODO: This exists largely because crown doesn't own the [`Atom`] type from [`sword`].
// TODO: The next step for this should be to lower the methods on this trait to a concrete `impl` stanza for [`Atom`] in [`sword`].
// TODO: In the course of doing so, we should split out a serialization trait that has only the [`AtomExt::from_value`] method as a public API in [`sword`].
// The goal would be to canonicalize the Atom representations of various Rust types. When it needs to be specialized, users can make a newtype.
pub trait AtomExt {
fn from_bytes<A: NounAllocator>(allocator: &mut A, bytes: &Bytes) -> Atom;
fn from_value<A: NounAllocator, T: ToBytes>(allocator: &mut A, value: T) -> Result<Atom>;
Expand All @@ -59,12 +63,14 @@ pub trait AtomExt {
}

impl AtomExt for Atom {
// TODO: This is iffy. What byte representation is it expecting and why?
fn from_bytes<A: NounAllocator>(allocator: &mut A, bytes: &Bytes) -> Atom {
unsafe {
IndirectAtom::new_raw_bytes(allocator, bytes.len(), bytes.as_ptr()).normalize_as_atom()
}
}

// TODO: This is worth making into a public/supported part of [`sword`]'s API.
fn from_value<A: NounAllocator, T: ToBytes>(allocator: &mut A, value: T) -> Result<Atom> {
unsafe {
let data: Bytes = value.as_bytes()?;
Expand Down

0 comments on commit 6cdc585

Please sign in to comment.