From 636af2850c90f6bf7005a270d95b68bc9718de75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Mon, 16 Nov 2020 20:48:50 +0100 Subject: refactor(cli): rename fs module to fs_util (#8380) This commit renames "fs" module in "cli/" to "fs_util". This is purely cosmetic change; there were a few places which aliased "crate::fs" to "deno_fs" which was very confusing with "fs" module in ops. --- cli/disk_cache.rs | 4 +- cli/fmt.rs | 2 +- cli/fs.rs | 258 ----------------------------------------------------- cli/fs_util.rs | 258 +++++++++++++++++++++++++++++++++++++++++++++++++++++ cli/http_cache.rs | 6 +- cli/installer.rs | 2 +- cli/lint.rs | 2 +- cli/main.rs | 10 +-- cli/ops/fs.rs | 2 +- cli/permissions.rs | 2 +- cli/test_runner.rs | 6 +- cli/tsc_config.rs | 2 +- 12 files changed, 277 insertions(+), 277 deletions(-) delete mode 100644 cli/fs.rs create mode 100644 cli/fs_util.rs (limited to 'cli') diff --git a/cli/disk_cache.rs b/cli/disk_cache.rs index 398085cc2..96a4ff41a 100644 --- a/cli/disk_cache.rs +++ b/cli/disk_cache.rs @@ -1,6 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use crate::fs as deno_fs; +use crate::fs_util; use crate::http_cache::url_to_filename; use deno_core::url::{Host, Url}; use std::ffi::OsStr; @@ -145,7 +145,7 @@ impl DiskCache { Some(ref parent) => self.ensure_dir_exists(parent), None => Ok(()), }?; - deno_fs::write_file(&path, data, crate::http_cache::CACHE_PERM) + fs_util::write_file(&path, data, crate::http_cache::CACHE_PERM) .map_err(|e| with_io_context(&e, format!("{:#?}", &path))) } } diff --git a/cli/fmt.rs b/cli/fmt.rs index 9bb4dbc82..0036436c1 100644 --- a/cli/fmt.rs +++ b/cli/fmt.rs @@ -9,7 +9,7 @@ use crate::colors; use crate::diff::diff; -use crate::fs::{collect_files, is_supported_ext}; +use crate::fs_util::{collect_files, is_supported_ext}; use crate::text_encoding; use deno_core::error::generic_error; use deno_core::error::AnyError; diff --git a/cli/fs.rs b/cli/fs.rs deleted file mode 100644 index 16f9e1f64..000000000 --- a/cli/fs.rs +++ /dev/null @@ -1,258 +0,0 @@ -// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. - -use deno_core::error::AnyError; -pub use deno_core::normalize_path; -use std::env::current_dir; -use std::fs::OpenOptions; -use std::io::{Error, Write}; -use std::path::{Path, PathBuf}; -use walkdir::WalkDir; - -pub fn write_file>( - filename: &Path, - data: T, - mode: u32, -) -> std::io::Result<()> { - write_file_2(filename, data, true, mode, true, false) -} - -pub fn write_file_2>( - filename: &Path, - data: T, - update_mode: bool, - mode: u32, - is_create: bool, - is_append: bool, -) -> std::io::Result<()> { - let mut file = OpenOptions::new() - .read(false) - .write(true) - .append(is_append) - .truncate(!is_append) - .create(is_create) - .open(filename)?; - - if update_mode { - #[cfg(unix)] - { - use std::os::unix::fs::PermissionsExt; - let mode = mode & 0o777; - let permissions = PermissionsExt::from_mode(mode); - file.set_permissions(permissions)?; - } - #[cfg(not(unix))] - let _ = mode; - } - - file.write_all(data.as_ref()) -} - -/// Similar to `std::fs::canonicalize()` but strips UNC prefixes on Windows. -pub fn canonicalize_path(path: &Path) -> Result { - let mut canonicalized_path = path.canonicalize()?; - if cfg!(windows) { - canonicalized_path = PathBuf::from( - canonicalized_path - .display() - .to_string() - .trim_start_matches("\\\\?\\"), - ); - } - Ok(canonicalized_path) -} - -pub fn resolve_from_cwd(path: &Path) -> Result { - let resolved_path = if path.is_absolute() { - path.to_owned() - } else { - let cwd = current_dir().unwrap(); - cwd.join(path) - }; - - Ok(normalize_path(&resolved_path)) -} - -/// Checks if the path has extension Deno supports. -pub fn is_supported_ext(path: &Path) -> bool { - let lowercase_ext = path - .extension() - .and_then(|e| e.to_str()) - .map(|e| e.to_lowercase()); - if let Some(ext) = lowercase_ext { - ext == "ts" || ext == "tsx" || ext == "js" || ext == "jsx" || ext == "mjs" - } else { - false - } -} - -/// Collects file paths that satisfy the given predicate, by recursively walking `files`. -/// If the walker visits a path that is listed in `ignore`, it skips descending into the directory. -pub fn collect_files

( - files: Vec, - ignore: Vec, - predicate: P, -) -> Result, AnyError> -where - P: Fn(&Path) -> bool, -{ - let mut target_files = Vec::new(); - - // retain only the paths which exist and ignore the rest - let canonicalized_ignore: Vec = ignore - .into_iter() - .filter_map(|i| i.canonicalize().ok()) - .collect(); - - let files = if files.is_empty() { - vec![std::env::current_dir()?] - } else { - files - }; - - for file in files { - for entry in WalkDir::new(file) - .into_iter() - .filter_entry(|e| { - e.path().canonicalize().map_or(false, |c| { - !canonicalized_ignore.iter().any(|i| c.starts_with(i)) - }) - }) - .filter_map(|e| match e { - Ok(e) if !e.file_type().is_dir() && predicate(e.path()) => Some(e), - _ => None, - }) - { - target_files.push(entry.into_path().canonicalize()?) - } - } - - Ok(target_files) -} - -#[cfg(test)] -mod tests { - use super::*; - use tempfile::TempDir; - - #[test] - fn resolve_from_cwd_child() { - let cwd = current_dir().unwrap(); - assert_eq!(resolve_from_cwd(Path::new("a")).unwrap(), cwd.join("a")); - } - - #[test] - fn resolve_from_cwd_dot() { - let cwd = current_dir().unwrap(); - assert_eq!(resolve_from_cwd(Path::new(".")).unwrap(), cwd); - } - - #[test] - fn resolve_from_cwd_parent() { - let cwd = current_dir().unwrap(); - assert_eq!(resolve_from_cwd(Path::new("a/..")).unwrap(), cwd); - } - - #[test] - fn test_normalize_path() { - assert_eq!(normalize_path(Path::new("a/../b")), PathBuf::from("b")); - assert_eq!(normalize_path(Path::new("a/./b/")), PathBuf::from("a/b/")); - assert_eq!( - normalize_path(Path::new("a/./b/../c")), - PathBuf::from("a/c") - ); - - if cfg!(windows) { - assert_eq!( - normalize_path(Path::new("C:\\a\\.\\b\\..\\c")), - PathBuf::from("C:\\a\\c") - ); - } - } - - // TODO: Get a good expected value here for Windows. - #[cfg(not(windows))] - #[test] - fn resolve_from_cwd_absolute() { - let expected = Path::new("/a"); - assert_eq!(resolve_from_cwd(expected).unwrap(), expected); - } - - #[test] - fn test_is_supported_ext() { - assert!(!is_supported_ext(Path::new("tests/subdir/redirects"))); - assert!(!is_supported_ext(Path::new("README.md"))); - assert!(is_supported_ext(Path::new("lib/typescript.d.ts"))); - assert!(is_supported_ext(Path::new("cli/tests/001_hello.js"))); - assert!(is_supported_ext(Path::new("cli/tests/002_hello.ts"))); - assert!(is_supported_ext(Path::new("foo.jsx"))); - assert!(is_supported_ext(Path::new("foo.tsx"))); - assert!(is_supported_ext(Path::new("foo.TS"))); - assert!(is_supported_ext(Path::new("foo.TSX"))); - assert!(is_supported_ext(Path::new("foo.JS"))); - assert!(is_supported_ext(Path::new("foo.JSX"))); - assert!(is_supported_ext(Path::new("foo.mjs"))); - assert!(!is_supported_ext(Path::new("foo.mjsx"))); - } - - #[test] - fn test_collect_files() { - fn create_files(dir_path: &PathBuf, files: &[&str]) { - std::fs::create_dir(dir_path).expect("Failed to create directory"); - for f in files { - let path = dir_path.join(f); - std::fs::write(path, "").expect("Failed to create file"); - } - } - - // dir.ts - // ├── a.ts - // ├── b.js - // ├── child - // │ ├── e.mjs - // │ ├── f.mjsx - // │ ├── .foo.TS - // │ └── README.md - // ├── c.tsx - // ├── d.jsx - // └── ignore - // ├── g.d.ts - // └── .gitignore - - let t = TempDir::new().expect("tempdir fail"); - - let root_dir_path = t.path().join("dir.ts"); - let root_dir_files = ["a.ts", "b.js", "c.tsx", "d.jsx"]; - create_files(&root_dir_path, &root_dir_files); - - let child_dir_path = root_dir_path.join("child"); - let child_dir_files = ["e.mjs", "f.mjsx", ".foo.TS", "README.md"]; - create_files(&child_dir_path, &child_dir_files); - - let ignore_dir_path = root_dir_path.join("ignore"); - let ignore_dir_files = ["g.d.ts", ".gitignore"]; - create_files(&ignore_dir_path, &ignore_dir_files); - - let result = - collect_files(vec![root_dir_path], vec![ignore_dir_path], |path| { - // exclude dotfiles - path - .file_name() - .and_then(|f| f.to_str()) - .map_or(false, |f| !f.starts_with('.')) - }) - .unwrap(); - let expected = [ - "a.ts", - "b.js", - "e.mjs", - "f.mjsx", - "README.md", - "c.tsx", - "d.jsx", - ]; - for e in expected.iter() { - assert!(result.iter().any(|r| r.ends_with(e))); - } - assert_eq!(result.len(), expected.len()); - } -} diff --git a/cli/fs_util.rs b/cli/fs_util.rs new file mode 100644 index 000000000..16f9e1f64 --- /dev/null +++ b/cli/fs_util.rs @@ -0,0 +1,258 @@ +// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. + +use deno_core::error::AnyError; +pub use deno_core::normalize_path; +use std::env::current_dir; +use std::fs::OpenOptions; +use std::io::{Error, Write}; +use std::path::{Path, PathBuf}; +use walkdir::WalkDir; + +pub fn write_file>( + filename: &Path, + data: T, + mode: u32, +) -> std::io::Result<()> { + write_file_2(filename, data, true, mode, true, false) +} + +pub fn write_file_2>( + filename: &Path, + data: T, + update_mode: bool, + mode: u32, + is_create: bool, + is_append: bool, +) -> std::io::Result<()> { + let mut file = OpenOptions::new() + .read(false) + .write(true) + .append(is_append) + .truncate(!is_append) + .create(is_create) + .open(filename)?; + + if update_mode { + #[cfg(unix)] + { + use std::os::unix::fs::PermissionsExt; + let mode = mode & 0o777; + let permissions = PermissionsExt::from_mode(mode); + file.set_permissions(permissions)?; + } + #[cfg(not(unix))] + let _ = mode; + } + + file.write_all(data.as_ref()) +} + +/// Similar to `std::fs::canonicalize()` but strips UNC prefixes on Windows. +pub fn canonicalize_path(path: &Path) -> Result { + let mut canonicalized_path = path.canonicalize()?; + if cfg!(windows) { + canonicalized_path = PathBuf::from( + canonicalized_path + .display() + .to_string() + .trim_start_matches("\\\\?\\"), + ); + } + Ok(canonicalized_path) +} + +pub fn resolve_from_cwd(path: &Path) -> Result { + let resolved_path = if path.is_absolute() { + path.to_owned() + } else { + let cwd = current_dir().unwrap(); + cwd.join(path) + }; + + Ok(normalize_path(&resolved_path)) +} + +/// Checks if the path has extension Deno supports. +pub fn is_supported_ext(path: &Path) -> bool { + let lowercase_ext = path + .extension() + .and_then(|e| e.to_str()) + .map(|e| e.to_lowercase()); + if let Some(ext) = lowercase_ext { + ext == "ts" || ext == "tsx" || ext == "js" || ext == "jsx" || ext == "mjs" + } else { + false + } +} + +/// Collects file paths that satisfy the given predicate, by recursively walking `files`. +/// If the walker visits a path that is listed in `ignore`, it skips descending into the directory. +pub fn collect_files

( + files: Vec, + ignore: Vec, + predicate: P, +) -> Result, AnyError> +where + P: Fn(&Path) -> bool, +{ + let mut target_files = Vec::new(); + + // retain only the paths which exist and ignore the rest + let canonicalized_ignore: Vec = ignore + .into_iter() + .filter_map(|i| i.canonicalize().ok()) + .collect(); + + let files = if files.is_empty() { + vec![std::env::current_dir()?] + } else { + files + }; + + for file in files { + for entry in WalkDir::new(file) + .into_iter() + .filter_entry(|e| { + e.path().canonicalize().map_or(false, |c| { + !canonicalized_ignore.iter().any(|i| c.starts_with(i)) + }) + }) + .filter_map(|e| match e { + Ok(e) if !e.file_type().is_dir() && predicate(e.path()) => Some(e), + _ => None, + }) + { + target_files.push(entry.into_path().canonicalize()?) + } + } + + Ok(target_files) +} + +#[cfg(test)] +mod tests { + use super::*; + use tempfile::TempDir; + + #[test] + fn resolve_from_cwd_child() { + let cwd = current_dir().unwrap(); + assert_eq!(resolve_from_cwd(Path::new("a")).unwrap(), cwd.join("a")); + } + + #[test] + fn resolve_from_cwd_dot() { + let cwd = current_dir().unwrap(); + assert_eq!(resolve_from_cwd(Path::new(".")).unwrap(), cwd); + } + + #[test] + fn resolve_from_cwd_parent() { + let cwd = current_dir().unwrap(); + assert_eq!(resolve_from_cwd(Path::new("a/..")).unwrap(), cwd); + } + + #[test] + fn test_normalize_path() { + assert_eq!(normalize_path(Path::new("a/../b")), PathBuf::from("b")); + assert_eq!(normalize_path(Path::new("a/./b/")), PathBuf::from("a/b/")); + assert_eq!( + normalize_path(Path::new("a/./b/../c")), + PathBuf::from("a/c") + ); + + if cfg!(windows) { + assert_eq!( + normalize_path(Path::new("C:\\a\\.\\b\\..\\c")), + PathBuf::from("C:\\a\\c") + ); + } + } + + // TODO: Get a good expected value here for Windows. + #[cfg(not(windows))] + #[test] + fn resolve_from_cwd_absolute() { + let expected = Path::new("/a"); + assert_eq!(resolve_from_cwd(expected).unwrap(), expected); + } + + #[test] + fn test_is_supported_ext() { + assert!(!is_supported_ext(Path::new("tests/subdir/redirects"))); + assert!(!is_supported_ext(Path::new("README.md"))); + assert!(is_supported_ext(Path::new("lib/typescript.d.ts"))); + assert!(is_supported_ext(Path::new("cli/tests/001_hello.js"))); + assert!(is_supported_ext(Path::new("cli/tests/002_hello.ts"))); + assert!(is_supported_ext(Path::new("foo.jsx"))); + assert!(is_supported_ext(Path::new("foo.tsx"))); + assert!(is_supported_ext(Path::new("foo.TS"))); + assert!(is_supported_ext(Path::new("foo.TSX"))); + assert!(is_supported_ext(Path::new("foo.JS"))); + assert!(is_supported_ext(Path::new("foo.JSX"))); + assert!(is_supported_ext(Path::new("foo.mjs"))); + assert!(!is_supported_ext(Path::new("foo.mjsx"))); + } + + #[test] + fn test_collect_files() { + fn create_files(dir_path: &PathBuf, files: &[&str]) { + std::fs::create_dir(dir_path).expect("Failed to create directory"); + for f in files { + let path = dir_path.join(f); + std::fs::write(path, "").expect("Failed to create file"); + } + } + + // dir.ts + // ├── a.ts + // ├── b.js + // ├── child + // │ ├── e.mjs + // │ ├── f.mjsx + // │ ├── .foo.TS + // │ └── README.md + // ├── c.tsx + // ├── d.jsx + // └── ignore + // ├── g.d.ts + // └── .gitignore + + let t = TempDir::new().expect("tempdir fail"); + + let root_dir_path = t.path().join("dir.ts"); + let root_dir_files = ["a.ts", "b.js", "c.tsx", "d.jsx"]; + create_files(&root_dir_path, &root_dir_files); + + let child_dir_path = root_dir_path.join("child"); + let child_dir_files = ["e.mjs", "f.mjsx", ".foo.TS", "README.md"]; + create_files(&child_dir_path, &child_dir_files); + + let ignore_dir_path = root_dir_path.join("ignore"); + let ignore_dir_files = ["g.d.ts", ".gitignore"]; + create_files(&ignore_dir_path, &ignore_dir_files); + + let result = + collect_files(vec![root_dir_path], vec![ignore_dir_path], |path| { + // exclude dotfiles + path + .file_name() + .and_then(|f| f.to_str()) + .map_or(false, |f| !f.starts_with('.')) + }) + .unwrap(); + let expected = [ + "a.ts", + "b.js", + "e.mjs", + "f.mjsx", + "README.md", + "c.tsx", + "d.jsx", + ]; + for e in expected.iter() { + assert!(result.iter().any(|r| r.ends_with(e))); + } + assert_eq!(result.len(), expected.len()); + } +} diff --git a/cli/http_cache.rs b/cli/http_cache.rs index 7310c9e92..9cf2adc1a 100644 --- a/cli/http_cache.rs +++ b/cli/http_cache.rs @@ -4,7 +4,7 @@ /// as defined in RFC 7234 (https://tools.ietf.org/html/rfc7234). /// Currently it's a very simplified version to fulfill Deno needs /// at hand. -use crate::fs as deno_fs; +use crate::fs_util; use crate::http_util::HeadersMap; use deno_core::error::AnyError; use deno_core::serde_json; @@ -87,7 +87,7 @@ impl Metadata { pub fn write(&self, cache_filename: &Path) -> Result<(), AnyError> { let metadata_filename = Self::filename(cache_filename); let json = serde_json::to_string_pretty(self)?; - deno_fs::write_file(&metadata_filename, json, CACHE_PERM)?; + fs_util::write_file(&metadata_filename, json, CACHE_PERM)?; Ok(()) } @@ -161,7 +161,7 @@ impl HttpCache { .expect("Cache filename should have a parent dir"); self.ensure_dir_exists(parent_filename)?; // Cache content - deno_fs::write_file(&cache_filename, content, CACHE_PERM)?; + fs_util::write_file(&cache_filename, content, CACHE_PERM)?; let metadata = Metadata { url: url.to_string(), diff --git a/cli/installer.rs b/cli/installer.rs index dab81bc8d..e0a99873a 100644 --- a/cli/installer.rs +++ b/cli/installer.rs @@ -1,7 +1,7 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. use crate::flags::Flags; -use crate::fs::canonicalize_path; +use crate::fs_util::canonicalize_path; use deno_core::error::generic_error; use deno_core::error::AnyError; use deno_core::url::Url; diff --git a/cli/lint.rs b/cli/lint.rs index 1ac680bac..e319a7be6 100644 --- a/cli/lint.rs +++ b/cli/lint.rs @@ -10,7 +10,7 @@ use crate::ast; use crate::colors; use crate::fmt::run_parallelized; use crate::fmt_errors; -use crate::fs::{collect_files, is_supported_ext}; +use crate::fs_util::{collect_files, is_supported_ext}; use crate::media_type::MediaType; use deno_core::error::{generic_error, AnyError, JsStackFrame}; use deno_core::serde_json; diff --git a/cli/main.rs b/cli/main.rs index 87e817cf0..11674a8b6 100644 --- a/cli/main.rs +++ b/cli/main.rs @@ -22,7 +22,7 @@ mod flags; mod flags_allow_net; mod fmt; mod fmt_errors; -mod fs; +mod fs_util; mod http_cache; mod http_util; mod import_map; @@ -57,7 +57,6 @@ use crate::coverage::CoverageCollector; use crate::coverage::PrettyCoverageReporter; use crate::file_fetcher::File; use crate::file_fetcher::FileFetcher; -use crate::fs as deno_fs; use crate::media_type::MediaType; use crate::permissions::Permissions; use crate::program_state::ProgramState; @@ -381,7 +380,7 @@ async fn bundle_command( if let Some(out_file_) = out_file.as_ref() { let output_bytes = output.as_bytes(); let output_len = output_bytes.len(); - deno_fs::write_file(out_file_, output_bytes, 0o644)?; + fs_util::write_file(out_file_, output_bytes, 0o644)?; info!( "{} {:?} ({})", colors::green("Emit"), @@ -583,8 +582,9 @@ async fn run_with_watch(flags: Flags, script: String) -> Result<(), AnyError> { .collect(); if let Some(import_map) = program_state.flags.import_map_path.clone() { - paths_to_watch - .push(fs::resolve_from_cwd(std::path::Path::new(&import_map)).unwrap()); + paths_to_watch.push( + fs_util::resolve_from_cwd(std::path::Path::new(&import_map)).unwrap(), + ); } // FIXME(bartlomieju): new file watcher is created on after each restart diff --git a/cli/ops/fs.rs b/cli/ops/fs.rs index 37558ec6b..211404f39 100644 --- a/cli/ops/fs.rs +++ b/cli/ops/fs.rs @@ -2,7 +2,7 @@ // Some deserializer fields are only used on Unix and Windows build fails without it use super::io::std_file_resource; use super::io::{FileMetadata, StreamResource, StreamResourceHolder}; -use crate::fs::canonicalize_path; +use crate::fs_util::canonicalize_path; use crate::permissions::Permissions; use deno_core::error::custom_error; use deno_core::error::type_error; diff --git a/cli/permissions.rs b/cli/permissions.rs index 204176ad3..cc3ce8242 100644 --- a/cli/permissions.rs +++ b/cli/permissions.rs @@ -2,7 +2,7 @@ use crate::colors; use crate::flags::Flags; -use crate::fs::resolve_from_cwd; +use crate::fs_util::resolve_from_cwd; use deno_core::error::custom_error; use deno_core::error::uri_error; use deno_core::error::AnyError; diff --git a/cli/test_runner.rs b/cli/test_runner.rs index 265b514c1..cd8a394c5 100644 --- a/cli/test_runner.rs +++ b/cli/test_runner.rs @@ -1,6 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use crate::fs as deno_fs; +use crate::fs_util; use crate::installer::is_remote_url; use deno_core::error::AnyError; use deno_core::serde_json::json; @@ -42,10 +42,10 @@ pub fn prepare_test_modules_urls( let mut prepared = vec![]; for path in include_paths { - let p = deno_fs::normalize_path(&root_path.join(path)); + let p = fs_util::normalize_path(&root_path.join(path)); if p.is_dir() { let test_files = - crate::fs::collect_files(vec![p], vec![], is_supported).unwrap(); + crate::fs_util::collect_files(vec![p], vec![], is_supported).unwrap(); let test_files_as_urls = test_files .iter() .map(|f| Url::from_file_path(f).unwrap()) diff --git a/cli/tsc_config.rs b/cli/tsc_config.rs index 92332cca6..5012e03a9 100644 --- a/cli/tsc_config.rs +++ b/cli/tsc_config.rs @@ -1,6 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use crate::fs::canonicalize_path; +use crate::fs_util::canonicalize_path; use deno_core::error::AnyError; use deno_core::serde_json; use deno_core::serde_json::json; -- cgit v1.2.3