Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add NpmCacheDir #60

Merged
merged 6 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ on:
workflow_dispatch:
inputs:
releaseKind:
description: 'Kind of release'
default: 'minor'
description: "Kind of release"
default: "minor"
type: choice
options:
- patch
Expand Down Expand Up @@ -36,4 +36,4 @@ jobs:
run: |
git config user.email "denobot@users.noreply.github.com"
git config user.name "denobot"
deno run -A https://raw.githubusercontent.com/denoland/automation/0.14.2/tasks/publish_release.ts --${{github.event.inputs.releaseKind}} deno_cache_dir
deno run -A https://raw.githubusercontent.com/denoland/automation/0.20.0/tasks/publish_release.ts --${{github.event.inputs.releaseKind}} deno_cache_dir
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions rs_lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ crate-type = ["cdylib", "lib"]
wasm = ["console_error_panic_hook", "js-sys", "serde-wasm-bindgen", "wasm-bindgen"]

[dependencies]
base32 = "=0.5.1"
deno_media_type = "0.1.1"
indexmap = { version = "2.0.0", features = ["serde"] }
log = "0.4.19"
Expand Down
16 changes: 16 additions & 0 deletions rs_lib/fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,22 @@ export function read_file_bytes(path) {
}
}

export function canonicalize_path(path) {
try {
return Deno.realPathSync(path);
} catch (err) {
if (err instanceof Deno.errors.NotFound) {
return undefined;
} else {
throw err;
}
}
}

export function create_dir_all(path) {
Deno.mkdirSync(path, { recursive: true });
}

export function remove_file(path) {
Deno.removeSync(path);
}
Expand Down
2 changes: 1 addition & 1 deletion rs_lib/src/cache.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
// Copyright 2018-2024 the Deno authors. MIT license.

use serde::Deserialize;
use serde::Serialize;
Expand Down
127 changes: 126 additions & 1 deletion rs_lib/src/common.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
// Copyright 2018-2024 the Deno authors. MIT license.

use std::borrow::Cow;
use std::collections::HashMap;
use std::path::Path;

use url::Url;

Expand Down Expand Up @@ -48,6 +49,79 @@ pub fn checksum(v: &[u8]) -> String {
format!("{:x}", hasher.finalize())
}

pub fn url_from_directory_path(path: &Path) -> Result<Url, ()> {
#[cfg(any(unix, windows, target_os = "redox", target_os = "wasi"))]
return Url::from_directory_path(path);
#[cfg(not(any(unix, windows, target_os = "redox", target_os = "wasi")))]
url_from_directory_path_wasm(path)
}

#[cfg(any(
test,
not(any(unix, windows, target_os = "redox", target_os = "wasi"))
))]
fn url_from_directory_path_wasm(path: &Path) -> Result<Url, ()> {
let mut url = url_from_file_path_wasm(path)?;
url.path_segments_mut().unwrap().push("");
Ok(url)
}

#[cfg(any(
test,
not(any(unix, windows, target_os = "redox", target_os = "wasi"))
))]
fn url_from_file_path_wasm(path: &Path) -> Result<Url, ()> {
use std::path::Component;

let original_path = path.to_string_lossy();
let mut path_str = original_path;
// assume paths containing backslashes are windows paths
if path_str.contains('\\') {
let mut url = Url::parse("file://").unwrap();
if let Some(next) = path_str.strip_prefix(r#"\\?\UNC\"#) {
if let Some((host, rest)) = next.split_once('\\') {
if url.set_host(Some(host)).is_ok() {
path_str = rest.to_string().into();
}
}
} else if let Some(next) = path_str.strip_prefix(r#"\\?\"#) {
path_str = next.to_string().into();
} else if let Some(next) = path_str.strip_prefix(r#"\\"#) {
if let Some((host, rest)) = next.split_once('\\') {
if url.set_host(Some(host)).is_ok() {
path_str = rest.to_string().into();
}
}
}

for component in path_str.split('\\') {
url.path_segments_mut().unwrap().push(component);
}

Ok(url)
} else {
let mut url = Url::parse("file://").unwrap();
for component in path.components() {
match component {
Component::RootDir => {
url.path_segments_mut().unwrap().push("");
}
Component::Normal(segment) => {
url
.path_segments_mut()
.unwrap()
.push(&segment.to_string_lossy());
}
Component::Prefix(_) | Component::CurDir | Component::ParentDir => {
return Err(());
}
}
}

Ok(url)
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand All @@ -60,4 +134,55 @@ mod tests {
"b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"
);
}

#[test]
fn test_url_from_file_path_wasm() {
#[track_caller]
fn convert(path: &str) -> String {
url_from_file_path_wasm(Path::new(path))
.unwrap()
.to_string()
}

assert_eq!(convert("/a/b/c.json"), "file:///a/b/c.json");
assert_eq!(
convert("D:\\test\\other.json"),
"file:///D:/test/other.json"
);
assert_eq!(
convert("/path with spaces/and#special%chars!.json"),
"file:///path%20with%20spaces/and%23special%25chars!.json"
);
assert_eq!(
convert("C:\\My Documents\\file.txt"),
"file:///C:/My%20Documents/file.txt"
);
assert_eq!(
convert("/a/b/пример.txt"),
"file:///a/b/%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80.txt"
);
assert_eq!(
convert("\\\\server\\share\\folder\\file.txt"),
"file://server/share/folder/file.txt"
);
assert_eq!(convert(r#"\\?\UNC\server\share"#), "file://server/share");
assert_eq!(
convert(r"\\?\cat_pics\subfolder\file.jpg"),
"file:///cat_pics/subfolder/file.jpg"
);
assert_eq!(convert(r"\\?\cat_pics"), "file:///cat_pics");
}

#[test]
fn test_url_from_directory_path_wasm() {
#[track_caller]
fn convert(path: &str) -> String {
url_from_directory_path_wasm(Path::new(path))
.unwrap()
.to_string()
}

assert_eq!(convert("/a/b/c"), "file:///a/b/c/");
assert_eq!(convert("D:\\test\\other"), "file:///D:/test/other/");
}
}
13 changes: 12 additions & 1 deletion rs_lib/src/env.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
// Copyright 2018-2024 the Deno authors. MIT license.

use std::path::Path;
use std::path::PathBuf;
use std::time::SystemTime;

pub trait DenoCacheEnv: Send + Sync + std::fmt::Debug + Clone {
fn read_file_bytes(&self, path: &Path) -> std::io::Result<Vec<u8>>;
fn atomic_write_file(&self, path: &Path, bytes: &[u8])
-> std::io::Result<()>;
fn canonicalize_path(&self, path: &Path) -> std::io::Result<PathBuf>;
fn create_dir_all(&self, path: &Path) -> std::io::Result<()>;
fn remove_file(&self, path: &Path) -> std::io::Result<()>;
fn modified(&self, path: &Path) -> std::io::Result<Option<SystemTime>>;
fn is_file(&self, path: &Path) -> bool;
Expand Down Expand Up @@ -49,6 +52,14 @@ mod test_fs {
}
}

fn canonicalize_path(&self, path: &Path) -> std::io::Result<PathBuf> {
path.canonicalize()
}

fn create_dir_all(&self, path: &Path) -> std::io::Result<()> {
std::fs::create_dir_all(path)
}

fn remove_file(&self, path: &Path) -> std::io::Result<()> {
std::fs::remove_file(path)
}
Expand Down
2 changes: 1 addition & 1 deletion rs_lib/src/global/cache_file.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
// Copyright 2018-2024 the Deno authors. MIT license.

use std::io::ErrorKind;
use std::path::Path;
Expand Down
2 changes: 1 addition & 1 deletion rs_lib/src/global/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
// Copyright 2018-2024 the Deno authors. MIT license.

use std::path::Path;
use std::path::PathBuf;
Expand Down
21 changes: 20 additions & 1 deletion rs_lib/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
// Copyright 2018-2024 the Deno authors. MIT license.

mod cache;
mod common;
mod env;
mod global;
mod local;
pub mod npm;

pub use cache::url_to_filename;
pub use cache::CacheEntry;
Expand Down Expand Up @@ -55,6 +56,10 @@ pub mod wasm {
#[wasm_bindgen(catch)]
fn atomic_write_file(path: &str, bytes: &[u8]) -> Result<JsValue, JsValue>;
#[wasm_bindgen(catch)]
fn canonicalize_path(path: &str) -> Result<JsValue, JsValue>;
#[wasm_bindgen(catch)]
fn create_dir_all(path: &str) -> Result<(), JsValue>;
#[wasm_bindgen(catch)]
fn modified_time(path: &str) -> Result<Option<usize>, JsValue>;
fn is_file(path: &str) -> bool;
fn time_now() -> usize;
Expand Down Expand Up @@ -84,6 +89,20 @@ pub mod wasm {
Ok(())
}

fn canonicalize_path(&self, path: &Path) -> std::io::Result<PathBuf> {
let js_value =
canonicalize_path(&path.to_string_lossy()).map_err(js_to_io_error)?;
if js_value.is_null() || js_value.is_undefined() {
Err(std::io::Error::new(ErrorKind::NotFound, ""))
} else {
Ok(PathBuf::from(js_value.as_string().unwrap()))
}
}

fn create_dir_all(&self, path: &Path) -> std::io::Result<()> {
create_dir_all(&path.to_string_lossy()).map_err(js_to_io_error)
}

fn remove_file(&self, path: &Path) -> std::io::Result<()> {
remove_file(&path.to_string_lossy()).map_err(js_to_io_error)
}
Expand Down
2 changes: 1 addition & 1 deletion rs_lib/src/local.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
// Copyright 2018-2024 the Deno authors. MIT license.

use std::borrow::Cow;
use std::collections::BTreeMap;
Expand Down
Loading