Skip to content

Commit

Permalink
Fixed lib building for wasi
Browse files Browse the repository at this point in the history
This is adapting the FS apis in `lib` for wasi (excluding git support).

The compilation command for building this is:
`cargo +nightly build --no-default-features --target wasm32-wasip1`

* Nightly is needed for `std::os::wasi::fs::symlink_path`, if symlink support isn't needed then this can be non-nightly.
* No default features is needed to not compile gitoxide, as that doesn't yet support wasi.

This does not adapt the CLI, just lib.
  • Loading branch information
Earthmark committed Sep 21, 2024
1 parent 0f5c553 commit 805ae84
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 10 deletions.
16 changes: 16 additions & 0 deletions lib/src/file_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,22 @@ pub fn persist_content_addressed_temp_file<P: AsRef<Path>>(
}
}

#[cfg(target_os = "wasi")]
mod platform {
use std::io;
use std::os::wasi::fs::symlink_path;
use std::path::Path;

/// Symlinks are available on wasi.
pub fn check_symlink_support() -> io::Result<bool> {
Ok(true)
}

pub fn try_symlink<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) -> io::Result<()> {
symlink_path(original, link)
}
}

#[cfg(unix)]
mod platform {
use std::io;
Expand Down
2 changes: 2 additions & 0 deletions lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#![warn(missing_docs)]
#![deny(unused_must_use)]
#![forbid(unsafe_code)]
// Required for wasi symlink support.
#![cfg_attr(target_os = "wasi", feature(wasi_ext))]

// Needed so that proc macros can be used inside jj_lib and by external crates
// that depend on it.
Expand Down
20 changes: 10 additions & 10 deletions lib/src/local_working_copy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ use crate::working_copy::WorkingCopyStateError;

#[cfg(unix)]
type FileExecutableFlag = bool;
#[cfg(windows)]
#[cfg(any(windows, target_os = "wasi"))]
type FileExecutableFlag = ();

#[derive(Debug, PartialEq, Eq, Clone)]
Expand All @@ -132,7 +132,7 @@ impl FileState {
fn placeholder() -> Self {
#[cfg(unix)]
let executable = false;
#[cfg(windows)]
#[cfg(any(windows, target_os = "wasi"))]
let executable = ();
FileState {
file_type: FileType::Normal { executable },
Expand All @@ -142,7 +142,7 @@ impl FileState {
}

fn for_file(executable: bool, size: u64, metadata: &Metadata) -> Self {
#[cfg(windows)]
#[cfg(any(windows, target_os = "wasi"))]
let executable = {
// Windows doesn't support executable bit.
let _ = executable;
Expand Down Expand Up @@ -349,7 +349,7 @@ fn file_state_from_proto(proto: &crate::protos::working_copy::FileState) -> File
#[cfg(unix)]
crate::protos::working_copy::FileType::Executable => FileType::Normal { executable: true },
// can exist in files written by older versions of jj
#[cfg(windows)]
#[cfg(any(windows, target_os = "wasi"))]
crate::protos::working_copy::FileType::Executable => FileType::Normal { executable: () },
crate::protos::working_copy::FileType::Symlink => FileType::Symlink,
crate::protos::working_copy::FileType::Conflict => FileType::Normal {
Expand All @@ -371,7 +371,7 @@ fn file_state_to_proto(file_state: &FileState) -> crate::protos::working_copy::F
FileType::Normal { executable: false } => crate::protos::working_copy::FileType::Normal,
#[cfg(unix)]
FileType::Normal { executable: true } => crate::protos::working_copy::FileType::Executable,
#[cfg(windows)]
#[cfg(any(windows, target_os = "wasi"))]
FileType::Normal { executable: () } => crate::protos::working_copy::FileType::Normal,
FileType::Symlink => crate::protos::working_copy::FileType::Symlink,
FileType::GitSubmodule => crate::protos::working_copy::FileType::GitSubmodule,
Expand Down Expand Up @@ -492,7 +492,7 @@ fn file_state(metadata: &Metadata) -> Option<FileState> {
} else {
Some(FileType::Normal { executable: false })
}
#[cfg(windows)]
#[cfg(any(windows, target_os = "wasi"))]
Some(FileType::Normal { executable: () })
} else {
None
Expand Down Expand Up @@ -1199,7 +1199,7 @@ impl TreeState {
let _ = current_tree_value; // use the variable
let id = self.write_file_to_store(repo_path, disk_path).await?;
// On Windows, we preserve the executable bit from the current tree.
#[cfg(windows)]
#[cfg(any(windows, target_os = "wasi"))]
let executable = {
let () = executable; // use the variable
if let Some(TreeValue::File { id: _, executable }) = current_tree_value {
Expand All @@ -1224,7 +1224,7 @@ impl TreeState {
match new_file_ids.into_resolved() {
Ok(file_id) => {
// On Windows, we preserve the executable bit from the merged trees.
#[cfg(windows)]
#[cfg(any(windows, target_os = "wasi"))]
let executable = {
let () = executable; // use the variable
if let Some(merge) = current_tree_values.to_executable_merge() {
Expand Down Expand Up @@ -1323,7 +1323,7 @@ impl TreeState {
Ok(FileState::for_file(executable, size, &metadata))
}

#[cfg_attr(windows, allow(unused_variables))]
#[cfg_attr(any(windows, target_os = "wasi"), allow(unused_variables))]
fn set_executable(&self, disk_path: &Path, executable: bool) -> Result<(), CheckoutError> {
#[cfg(unix)]
{
Expand Down Expand Up @@ -1515,7 +1515,7 @@ impl TreeState {
Ok(value) => match value.unwrap() {
#[cfg(unix)]
TreeValue::File { id: _, executable } => FileType::Normal { executable },
#[cfg(windows)]
#[cfg(any(windows, target_os = "wasi"))]
TreeValue::File { .. } => FileType::Normal { executable: () },
TreeValue::Symlink(_id) => FileType::Symlink,
TreeValue::Conflict(_id) => {
Expand Down

0 comments on commit 805ae84

Please sign in to comment.