diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a2c5cb8..1efb99b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -75,5 +75,7 @@ jobs: run: cargo install cross - name: Test code + env: + CROSS_CONTAINER_OPTS: "--device /dev/fuse --cap-add SYS_ADMIN" run: | - cross test --workspace --verbose --target=i686-unknown-linux-gnu + cross test --workspace --verbose --target=i686-unknown-linux-gnu --features in_ci diff --git a/Cargo.lock b/Cargo.lock index 4243a14..43b6a07 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -164,7 +164,7 @@ dependencies = [ [[package]] name = "arx_test_dir" version = "0.1.0" -source = "git+https://github.com/jubako/arx_test_dir.git#4260f7883f493c24950a8b26d02c545b928cf1e9" +source = "git+https://github.com/jubako/arx_test_dir.git#b818e3c70401edf731748577da376fccb6b2058c" dependencies = [ "clap", "fuser", diff --git a/arx/Cargo.toml b/arx/Cargo.toml index 274cff0..1fc37e6 100644 --- a/arx/Cargo.toml +++ b/arx/Cargo.toml @@ -24,13 +24,26 @@ env_logger = "0.10.0" log = "0.4.20" tempfile = "3.10.1" -[dev-dependencies] +[target.'cfg(not(windows))'.dev-dependencies] arx_test_dir = { git = "https://github.com/jubako/arx_test_dir.git" } tempfile = "3.8.0" [features] -default = ["zstd"] +default = ["zstd", "fuse"] in_ci = [] lz4 = ["arx/lz4"] zstd = ["arx/zstd"] lzma = ["arx/lzma"] +fuse = ["arx/fuse", "arx_test_dir/fuse"] + +[[bin]] +name = "auto_mount" +required-features = ["fuse"] + +[[bin]] +name = "mount_fuse_arx" +required-features = ["fuse"] + +[[test]] +name = "create" +required-features = ["fuse"] diff --git a/arx/src/main.rs b/arx/src/main.rs index 9eaefcb..9233fc7 100644 --- a/arx/src/main.rs +++ b/arx/src/main.rs @@ -3,7 +3,7 @@ mod dump; mod extract; mod light_path; mod list; -#[cfg(not(windows))] +#[cfg(all(not(windows), feature = "fuse"))] mod mount; use anyhow::Result; @@ -29,7 +29,7 @@ struct Cli { "list", "dump", "extract", - #[cfg(not(windows))] + #[cfg(all(not(windows), feature = "fuse"))] "mount" ]) )] @@ -56,7 +56,7 @@ enum Commands { #[command(arg_required_else_help = true)] Extract(extract::Options), - #[cfg(not(windows))] + #[cfg(all(not(windows), feature = "fuse"))] #[command(arg_required_else_help = true)] Mount(mount::Options), } @@ -91,7 +91,7 @@ fn run() -> Result<()> { "list" => list::Options::command(), "dump" => dump::Options::command(), "extract" => extract::Options::command(), - #[cfg(not(windows))] + #[cfg(all(not(windows), feature = "fuse"))] "mount" => mount::Options::command(), _ => return Ok(Cli::command().print_help()?), }; @@ -114,7 +114,7 @@ fn run() -> Result<()> { Commands::List(options) => Ok(list::list(options)?), Commands::Dump(options) => Ok(dump::dump(options)?), Commands::Extract(options) => Ok(extract::extract(options)?), - #[cfg(not(windows))] + #[cfg(all(not(windows), feature = "fuse"))] Commands::Mount(options) => Ok(mount::mount(options)?), }, } diff --git a/arx/tests/create.rs b/arx/tests/create.rs new file mode 100644 index 0000000..41a9622 --- /dev/null +++ b/arx/tests/create.rs @@ -0,0 +1,60 @@ +#[cfg(all(unix, not(feature = "in_ci")))] +mod inner { + pub use std::path::{Path, PathBuf}; + pub use std::process::Command; + + // Generate a fake directory with fake content. + pub fn spawn_mount() -> std::io::Result<(arx_test_dir::BackgroundSession, PathBuf)> { + let mount_path = tempfile::TempDir::new_in(env!("CARGO_TARGET_TMPDIR")).unwrap(); + let builder = arx_test_dir::ContextBuilder::new(); + let context = builder.create(); + let dir = arx_test_dir::DirEntry::new_root(context); + let mount_dir = arx_test_dir::TreeFs::new(dir); + Ok(( + mount_dir.spawn(mount_path.path())?, + mount_path.path().into(), + )) + } +} + +#[cfg(all(unix, not(feature = "in_ci")))] +#[test] +fn test_create() { + use inner::*; + + let (_source_mount_handle, source_mount_point) = spawn_mount().unwrap(); + let bin_path = env!("CARGO_BIN_EXE_arx"); + let arx_file = Path::new(env!("CARGO_TARGET_TMPDIR")).join("test.arx"); + let output = Command::new(bin_path) + .arg("--verbose") + .arg("create") + .arg("--outfile") + .arg(&arx_file) + .arg("-C") + .arg(&source_mount_point.parent().unwrap()) + .arg("--strip-prefix") + .arg(&source_mount_point.file_name().unwrap()) + .arg(&source_mount_point.file_name().unwrap()) + .output() + .expect("foo"); + println!("Out : {}", String::from_utf8(output.stdout).unwrap()); + println!("Err : {}", String::from_utf8(output.stderr).unwrap()); + assert!(output.status.success()); + assert!(arx_file.is_file()); + + let mount_point = tempfile::TempDir::new_in(env!("CARGO_TARGET_TMPDIR")).unwrap(); + let arx = arx::Arx::new(arx_file).unwrap(); + let arxfs = arx::ArxFs::new(arx).unwrap(); + let _mount_handle = arxfs + .spawn_mount("Test mounted arx".into(), mount_point.path()) + .unwrap(); + let output = Command::new("diff") + .arg("-r") + .arg(&source_mount_point) + .arg(&mount_point.path()) + .output() + .unwrap(); + println!("Out : {}", String::from_utf8(output.stdout).unwrap()); + println!("Err: {}", String::from_utf8(output.stderr).unwrap()); + assert!(output.status.success()); +} diff --git a/libarx/Cargo.toml b/libarx/Cargo.toml index c1cdffc..d0a5517 100644 --- a/libarx/Cargo.toml +++ b/libarx/Cargo.toml @@ -12,7 +12,7 @@ license.workspace = true [dependencies] jbk.workspace = true -clap = { workspace=true, optional =true } +clap = { workspace=true, optional = true } libc = "0.2.148" lru = "0.11.1" fxhash = "0.2.1" @@ -25,10 +25,11 @@ rayon = "1.10.0" bstr = "1.9.1" [target.'cfg(not(windows))'.dependencies] -fuser = "0.13.0" +fuser = { version = "0.13.0", optional = true } [features] cmd_utils = [ "dep:clap"] lz4 = ["jbk/lz4"] zstd = ["jbk/zstd"] lzma = ["jbk/lzma"] +fuse = ["dep:fuser"] diff --git a/libarx/src/common/entry_type.rs b/libarx/src/common/entry_type.rs index a4ac397..d6e8140 100644 --- a/libarx/src/common/entry_type.rs +++ b/libarx/src/common/entry_type.rs @@ -30,7 +30,7 @@ impl ToString for EntryType { impl jbk::creator::VariantName for EntryType {} -#[cfg(not(windows))] +#[cfg(all(not(windows), feature = "fuse"))] impl From for fuser::FileType { fn from(t: EntryType) -> Self { match t { diff --git a/libarx/src/lib.rs b/libarx/src/lib.rs index bd8daff..c69eec0 100644 --- a/libarx/src/lib.rs +++ b/libarx/src/lib.rs @@ -1,7 +1,7 @@ //#![feature(get_mut_unchecked)] mod arx; -#[cfg(not(windows))] +#[cfg(all(not(windows), feature = "fuse"))] mod arx_fs; #[cfg(feature = "cmd_utils")] pub mod cmd_utils; @@ -12,7 +12,7 @@ mod tools; pub mod walk; pub use arx::Arx; -#[cfg(not(windows))] +#[cfg(all(not(windows), feature = "fuse"))] pub use arx_fs::{ArxFs, Stats}; pub use common::{AllProperties, Builder, Entry, FullBuilderTrait, Path, PathBuf, VENDOR_ID}; pub use entry::*; diff --git a/tests/create.rs b/tests/create.rs deleted file mode 100644 index 5b3f4f2..0000000 --- a/tests/create.rs +++ /dev/null @@ -1,52 +0,0 @@ -use std::path::{Path, PathBuf}; -use std::process::Command; - -// Generate a fake directory with fake content. -fn spawn_mount() -> std::io::Result<(arx_test_dir::BackgroundSession, PathBuf)> { - let mount_path = tempfile::TempDir::new_in(env!("CARGO_TARGET_TMPDIR")).unwrap(); - let builder = arx_test_dir::ContextBuilder::new(); - let context = builder.create(); - let dir = arx_test_dir::DirEntry::new_root(context); - let mount_dir = arx_test_dir::TreeFs::new(dir); - Ok(( - mount_dir.spawn(mount_path.path())?, - mount_path.path().into(), - )) -} - -#[test] -#[cfg_attr(feature = "in_ci", ignore)] -fn test_create() { - let (_source_mount_handle, source_mount_point) = spawn_mount().unwrap(); - let bin_path = env!("CARGO_BIN_EXE_arx"); - let arx_file = Path::new(env!("CARGO_TARGET_TMPDIR")).join("test.arx"); - let output = Command::new(bin_path) - .arg("--verbose") - .arg("create") - .arg("--file") - .arg(&arx_file) - .arg("-r1") - .arg("--strip-prefix") - .arg(&source_mount_point) - .arg(&source_mount_point) - .output() - .expect("foo"); - println!("Out : {}", String::from_utf8(output.stdout).unwrap()); - println!("Err : {}", String::from_utf8(output.stderr).unwrap()); - assert!(output.status.success()); - assert!(arx_file.is_file()); - - let mount_point = tempfile::TempDir::new_in(env!("CARGO_TARGET_TMPDIR")).unwrap(); - let arx = libarx::Arx::new(arx_file).unwrap(); - let arxfs = libarx::ArxFs::new(arx).unwrap(); - let _mount_handle = arxfs.spawn_mount(mount_point.path()).unwrap(); - let output = Command::new("diff") - .arg("-r") - .arg(&source_mount_point) - .arg(&mount_point.path()) - .output() - .unwrap(); - println!("Out : {}", String::from_utf8(output.stdout).unwrap()); - println!("Err: {}", String::from_utf8(output.stderr).unwrap()); - assert!(output.status.success()); -}