1use std::path::PathBuf;
2
3use spin_common::{ui::quoted_path, url::parse_file_url};
4use spin_factors::anyhow::{ensure, Context};
5
6use crate::FilesMounter;
7
8pub struct SpinFilesMounter {
9 working_dir: PathBuf,
10 allow_transient_writes: bool,
11}
12
13impl SpinFilesMounter {
14 pub fn new(working_dir: impl Into<PathBuf>, allow_transient_writes: bool) -> Self {
15 Self {
16 working_dir: working_dir.into(),
17 allow_transient_writes,
18 }
19 }
20}
21
22impl FilesMounter for SpinFilesMounter {
23 fn mount_files(
24 &self,
25 app_component: &spin_factors::AppComponent,
26 mut ctx: crate::MountFilesContext,
27 ) -> spin_factors::anyhow::Result<()> {
28 for content_dir in app_component.files() {
29 let source_uri = content_dir
30 .content
31 .source
32 .as_deref()
33 .with_context(|| format!("Missing 'source' on files mount {content_dir:?}"))?;
34 let source_path = self.working_dir.join(parse_file_url(source_uri)?);
35 ensure!(
36 source_path.is_dir(),
37 "SpinFilesMounter only supports directory mounts; {} is not a directory",
38 quoted_path(&source_path),
39 );
40 let guest_path = &content_dir.path;
41 let guest_path = guest_path
42 .to_str()
43 .with_context(|| format!("guest path {guest_path:?} not valid UTF-8"))?;
44 ctx.preopened_dir(source_path, guest_path, self.allow_transient_writes)?;
45 }
46 Ok(())
47 }
48}