mirror of
https://github.com/denoland/deno.git
synced 2024-11-25 15:29:32 -05:00
refactor: use globbing from deno_config (#21925)
This commit is contained in:
parent
3ff80eb152
commit
4e72ca313a
18 changed files with 294 additions and 789 deletions
5
Cargo.lock
generated
5
Cargo.lock
generated
|
@ -1128,11 +1128,12 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_config"
|
name = "deno_config"
|
||||||
version = "0.6.5"
|
version = "0.7.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "97979f94af93f388822233278ede930414efa273d6eb495de7680f2a6862a4d3"
|
checksum = "62edb1811b076bf29670385098bc6e1cfee37dae70b71a665e7a1534098ba805"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"glob",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"jsonc-parser",
|
"jsonc-parser",
|
||||||
"log",
|
"log",
|
||||||
|
|
|
@ -55,7 +55,7 @@ winres.workspace = true
|
||||||
[dependencies]
|
[dependencies]
|
||||||
deno_ast = { workspace = true, features = ["bundler", "cjs", "codegen", "dep_graph", "module_specifier", "proposal", "react", "sourcemap", "transforms", "typescript", "view", "visit"] }
|
deno_ast = { workspace = true, features = ["bundler", "cjs", "codegen", "dep_graph", "module_specifier", "proposal", "react", "sourcemap", "transforms", "typescript", "view", "visit"] }
|
||||||
deno_cache_dir = "=0.6.1"
|
deno_cache_dir = "=0.6.1"
|
||||||
deno_config = "=0.6.5"
|
deno_config = "=0.7.1"
|
||||||
deno_core = { workspace = true, features = ["include_js_files_for_snapshotting"] }
|
deno_core = { workspace = true, features = ["include_js_files_for_snapshotting"] }
|
||||||
deno_doc = { version = "=0.89.1", features = ["html"] }
|
deno_doc = { version = "=0.89.1", features = ["html"] }
|
||||||
deno_emit = "=0.33.0"
|
deno_emit = "=0.33.0"
|
||||||
|
|
|
@ -30,37 +30,8 @@ use super::flags_net;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Eq, PartialEq)]
|
#[derive(Clone, Debug, Default, Eq, PartialEq)]
|
||||||
pub struct FileFlags {
|
pub struct FileFlags {
|
||||||
pub ignore: Vec<PathBuf>,
|
pub ignore: Vec<String>,
|
||||||
pub include: Vec<PathBuf>,
|
pub include: Vec<String>,
|
||||||
}
|
|
||||||
|
|
||||||
impl FileFlags {
|
|
||||||
pub fn with_absolute_paths(self, base: &Path) -> Self {
|
|
||||||
fn to_absolute_path(path: PathBuf, base: &Path) -> PathBuf {
|
|
||||||
// todo(dsherret): don't store URLs in PathBufs
|
|
||||||
if path.starts_with("http:")
|
|
||||||
|| path.starts_with("https:")
|
|
||||||
|| path.starts_with("file:")
|
|
||||||
{
|
|
||||||
path
|
|
||||||
} else {
|
|
||||||
base.join(path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Self {
|
|
||||||
include: self
|
|
||||||
.include
|
|
||||||
.into_iter()
|
|
||||||
.map(|p| to_absolute_path(p, base))
|
|
||||||
.collect(),
|
|
||||||
ignore: self
|
|
||||||
.ignore
|
|
||||||
.into_iter()
|
|
||||||
.map(|p| to_absolute_path(p, base))
|
|
||||||
.collect(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Eq, PartialEq)]
|
#[derive(Clone, Debug, Default, Eq, PartialEq)]
|
||||||
|
@ -75,7 +46,7 @@ pub struct BenchFlags {
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub struct BundleFlags {
|
pub struct BundleFlags {
|
||||||
pub source_file: String,
|
pub source_file: String,
|
||||||
pub out_file: Option<PathBuf>,
|
pub out_file: Option<String>,
|
||||||
pub watch: Option<WatchFlags>,
|
pub watch: Option<WatchFlags>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,7 +152,7 @@ pub struct FmtFlags {
|
||||||
impl FmtFlags {
|
impl FmtFlags {
|
||||||
pub fn is_stdin(&self) -> bool {
|
pub fn is_stdin(&self) -> bool {
|
||||||
let args = &self.files.include;
|
let args = &self.files.include;
|
||||||
args.len() == 1 && args[0].to_string_lossy() == "-"
|
args.len() == 1 && args[0] == "-"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,7 +204,7 @@ pub struct LintFlags {
|
||||||
impl LintFlags {
|
impl LintFlags {
|
||||||
pub fn is_stdin(&self) -> bool {
|
pub fn is_stdin(&self) -> bool {
|
||||||
let args = &self.files.include;
|
let args = &self.files.include;
|
||||||
args.len() == 1 && args[0].to_string_lossy() == "-"
|
args.len() == 1 && args[0] == "-"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -706,8 +677,12 @@ impl Flags {
|
||||||
use DenoSubcommand::*;
|
use DenoSubcommand::*;
|
||||||
|
|
||||||
match &self.subcommand {
|
match &self.subcommand {
|
||||||
Fmt(FmtFlags { files, .. }) => Some(files.include.clone()),
|
Fmt(FmtFlags { files, .. }) => {
|
||||||
Lint(LintFlags { files, .. }) => Some(files.include.clone()),
|
Some(files.include.iter().map(|p| current_dir.join(p)).collect())
|
||||||
|
}
|
||||||
|
Lint(LintFlags { files, .. }) => {
|
||||||
|
Some(files.include.iter().map(|p| current_dir.join(p)).collect())
|
||||||
|
}
|
||||||
Run(RunFlags { script, .. }) => {
|
Run(RunFlags { script, .. }) => {
|
||||||
if let Ok(module_specifier) = resolve_url_or_path(script, current_dir) {
|
if let Ok(module_specifier) = resolve_url_or_path(script, current_dir) {
|
||||||
if module_specifier.scheme() == "file"
|
if module_specifier.scheme() == "file"
|
||||||
|
@ -730,6 +705,7 @@ impl Flags {
|
||||||
Task(TaskFlags {
|
Task(TaskFlags {
|
||||||
cwd: Some(path), ..
|
cwd: Some(path), ..
|
||||||
}) => {
|
}) => {
|
||||||
|
// todo(dsherret): Why is this canonicalized? Document why.
|
||||||
// attempt to resolve the config file from the task subcommand's
|
// attempt to resolve the config file from the task subcommand's
|
||||||
// `--cwd` when specified
|
// `--cwd` when specified
|
||||||
match canonicalize_path(&PathBuf::from(path)) {
|
match canonicalize_path(&PathBuf::from(path)) {
|
||||||
|
@ -1124,8 +1100,7 @@ glob {*_,*.,}bench.{js,mjs,ts,mts,jsx,tsx}:
|
||||||
.num_args(1..)
|
.num_args(1..)
|
||||||
.use_value_delimiter(true)
|
.use_value_delimiter(true)
|
||||||
.require_equals(true)
|
.require_equals(true)
|
||||||
.help("Ignore files")
|
.help("Ignore files"),
|
||||||
.value_parser(value_parser!(PathBuf)),
|
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("filter")
|
Arg::new("filter")
|
||||||
|
@ -1139,7 +1114,6 @@ glob {*_,*.,}bench.{js,mjs,ts,mts,jsx,tsx}:
|
||||||
Arg::new("files")
|
Arg::new("files")
|
||||||
.help("List of file names to run")
|
.help("List of file names to run")
|
||||||
.num_args(..)
|
.num_args(..)
|
||||||
.value_parser(value_parser!(PathBuf))
|
|
||||||
.action(ArgAction::Append),
|
.action(ArgAction::Append),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
|
@ -1176,11 +1150,7 @@ If no output file is given, the output is written to standard output:
|
||||||
.required(true)
|
.required(true)
|
||||||
.value_hint(ValueHint::FilePath),
|
.value_hint(ValueHint::FilePath),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(Arg::new("out_file").value_hint(ValueHint::FilePath))
|
||||||
Arg::new("out_file")
|
|
||||||
.value_parser(value_parser!(PathBuf))
|
|
||||||
.value_hint(ValueHint::FilePath),
|
|
||||||
)
|
|
||||||
.arg(watch_arg(false))
|
.arg(watch_arg(false))
|
||||||
.arg(no_clear_screen_arg())
|
.arg(no_clear_screen_arg())
|
||||||
.arg(executable_ext_arg())
|
.arg(executable_ext_arg())
|
||||||
|
@ -1291,6 +1261,7 @@ supported in canary.
|
||||||
Arg::new("output")
|
Arg::new("output")
|
||||||
.long("output")
|
.long("output")
|
||||||
.short('o')
|
.short('o')
|
||||||
|
// todo(dsherret): remove value_parser!(PathBuf) and instead parse as string
|
||||||
.value_parser(value_parser!(PathBuf))
|
.value_parser(value_parser!(PathBuf))
|
||||||
.help("Output file (defaults to $PWD/<inferred-name>)")
|
.help("Output file (defaults to $PWD/<inferred-name>)")
|
||||||
.value_hint(ValueHint::FilePath),
|
.value_hint(ValueHint::FilePath),
|
||||||
|
@ -1414,6 +1385,7 @@ Generate html reports from lcov:
|
||||||
Arg::new("output")
|
Arg::new("output")
|
||||||
.requires("lcov")
|
.requires("lcov")
|
||||||
.long("output")
|
.long("output")
|
||||||
|
// todo(dsherret): remove value_parser!(PathBuf) and instead parse as string
|
||||||
.value_parser(value_parser!(PathBuf))
|
.value_parser(value_parser!(PathBuf))
|
||||||
.help("Output file (defaults to stdout) for lcov")
|
.help("Output file (defaults to stdout) for lcov")
|
||||||
.long_help(
|
.long_help(
|
||||||
|
@ -1441,7 +1413,6 @@ Generate html reports from lcov:
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("files")
|
Arg::new("files")
|
||||||
.num_args(0..)
|
.num_args(0..)
|
||||||
.value_parser(value_parser!(PathBuf))
|
|
||||||
.action(ArgAction::Append)
|
.action(ArgAction::Append)
|
||||||
.value_hint(ValueHint::AnyPath),
|
.value_hint(ValueHint::AnyPath),
|
||||||
)
|
)
|
||||||
|
@ -1521,6 +1492,7 @@ Show documentation for runtime built-ins:
|
||||||
.action(ArgAction::Set)
|
.action(ArgAction::Set)
|
||||||
.require_equals(true)
|
.require_equals(true)
|
||||||
.value_hint(ValueHint::DirPath)
|
.value_hint(ValueHint::DirPath)
|
||||||
|
// todo(dsherret): remove value_parser!(PathBuf) and instead parse as string
|
||||||
.value_parser(value_parser!(PathBuf))
|
.value_parser(value_parser!(PathBuf))
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
|
@ -1651,7 +1623,6 @@ Ignore formatting a file by adding an ignore comment at the top of the file:
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("ignore")
|
Arg::new("ignore")
|
||||||
.long("ignore")
|
.long("ignore")
|
||||||
.value_parser(value_parser!(PathBuf))
|
|
||||||
.num_args(1..)
|
.num_args(1..)
|
||||||
.use_value_delimiter(true)
|
.use_value_delimiter(true)
|
||||||
.require_equals(true)
|
.require_equals(true)
|
||||||
|
@ -1660,7 +1631,6 @@ Ignore formatting a file by adding an ignore comment at the top of the file:
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("files")
|
Arg::new("files")
|
||||||
.value_parser(value_parser!(PathBuf))
|
|
||||||
.num_args(1..)
|
.num_args(1..)
|
||||||
.action(ArgAction::Append)
|
.action(ArgAction::Append)
|
||||||
.required(false)
|
.required(false)
|
||||||
|
@ -1863,6 +1833,7 @@ fn jupyter_subcommand() -> Command {
|
||||||
Arg::new("conn")
|
Arg::new("conn")
|
||||||
.long("conn")
|
.long("conn")
|
||||||
.help("Path to JSON file describing connection parameters, provided by Jupyter")
|
.help("Path to JSON file describing connection parameters, provided by Jupyter")
|
||||||
|
// todo(dsherret): remove value_parser!(PathBuf) and instead parse as string
|
||||||
.value_parser(value_parser!(PathBuf))
|
.value_parser(value_parser!(PathBuf))
|
||||||
.value_hint(ValueHint::FilePath)
|
.value_hint(ValueHint::FilePath)
|
||||||
.conflicts_with("install"))
|
.conflicts_with("install"))
|
||||||
|
@ -1988,7 +1959,6 @@ Ignore linting a file by adding an ignore comment at the top of the file:
|
||||||
Arg::new("ignore")
|
Arg::new("ignore")
|
||||||
.long("ignore")
|
.long("ignore")
|
||||||
.num_args(1..)
|
.num_args(1..)
|
||||||
.value_parser(value_parser!(PathBuf))
|
|
||||||
.use_value_delimiter(true)
|
.use_value_delimiter(true)
|
||||||
.require_equals(true)
|
.require_equals(true)
|
||||||
.help("Ignore linting particular source files")
|
.help("Ignore linting particular source files")
|
||||||
|
@ -2009,7 +1979,6 @@ Ignore linting a file by adding an ignore comment at the top of the file:
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new("files")
|
Arg::new("files")
|
||||||
.value_parser(value_parser!(PathBuf))
|
|
||||||
.num_args(1..)
|
.num_args(1..)
|
||||||
.action(ArgAction::Append)
|
.action(ArgAction::Append)
|
||||||
.required(false)
|
.required(false)
|
||||||
|
@ -2128,7 +2097,6 @@ Directory arguments are expanded to all contained files matching the glob
|
||||||
Arg::new("ignore")
|
Arg::new("ignore")
|
||||||
.long("ignore")
|
.long("ignore")
|
||||||
.num_args(1..)
|
.num_args(1..)
|
||||||
.value_parser(value_parser!(PathBuf))
|
|
||||||
.use_value_delimiter(true)
|
.use_value_delimiter(true)
|
||||||
.require_equals(true)
|
.require_equals(true)
|
||||||
.help("Ignore files")
|
.help("Ignore files")
|
||||||
|
@ -2216,7 +2184,6 @@ Directory arguments are expanded to all contained files matching the glob
|
||||||
.help("List of file names to run")
|
.help("List of file names to run")
|
||||||
.num_args(0..)
|
.num_args(0..)
|
||||||
.action(ArgAction::Append)
|
.action(ArgAction::Append)
|
||||||
.value_parser(value_parser!(PathBuf))
|
|
||||||
.value_hint(ValueHint::AnyPath),
|
.value_hint(ValueHint::AnyPath),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
|
@ -2283,6 +2250,7 @@ update to a different location, use the --output flag
|
||||||
Arg::new("output")
|
Arg::new("output")
|
||||||
.long("output")
|
.long("output")
|
||||||
.help("The path to output the updated version to")
|
.help("The path to output the updated version to")
|
||||||
|
// todo(dsherret): remove value_parser!(PathBuf) and instead parse as string
|
||||||
.value_parser(value_parser!(PathBuf))
|
.value_parser(value_parser!(PathBuf))
|
||||||
.value_hint(ValueHint::FilePath),
|
.value_hint(ValueHint::FilePath),
|
||||||
)
|
)
|
||||||
|
@ -2337,6 +2305,7 @@ Remote modules and multiple modules may also be specified:
|
||||||
Arg::new("output")
|
Arg::new("output")
|
||||||
.long("output")
|
.long("output")
|
||||||
.help("The directory to output the vendored modules to")
|
.help("The directory to output the vendored modules to")
|
||||||
|
// todo(dsherret): remove value_parser!(PathBuf) and instead parse as string
|
||||||
.value_parser(value_parser!(PathBuf))
|
.value_parser(value_parser!(PathBuf))
|
||||||
.value_hint(ValueHint::DirPath),
|
.value_hint(ValueHint::DirPath),
|
||||||
)
|
)
|
||||||
|
@ -2570,6 +2539,7 @@ fn permission_args(app: Command) -> Command {
|
||||||
.require_equals(true)
|
.require_equals(true)
|
||||||
.value_name("PATH")
|
.value_name("PATH")
|
||||||
.help(ALLOW_READ_HELP)
|
.help(ALLOW_READ_HELP)
|
||||||
|
// todo(dsherret): remove value_parser!(PathBuf) and instead parse as string
|
||||||
.value_parser(value_parser!(PathBuf))
|
.value_parser(value_parser!(PathBuf))
|
||||||
.value_hint(ValueHint::AnyPath),
|
.value_hint(ValueHint::AnyPath),
|
||||||
)
|
)
|
||||||
|
@ -2581,6 +2551,7 @@ fn permission_args(app: Command) -> Command {
|
||||||
.require_equals(true)
|
.require_equals(true)
|
||||||
.value_name("PATH")
|
.value_name("PATH")
|
||||||
.help(DENY_READ_HELP)
|
.help(DENY_READ_HELP)
|
||||||
|
// todo(dsherret): remove value_parser!(PathBuf) and instead parse as string
|
||||||
.value_parser(value_parser!(PathBuf))
|
.value_parser(value_parser!(PathBuf))
|
||||||
.value_hint(ValueHint::AnyPath),
|
.value_hint(ValueHint::AnyPath),
|
||||||
)
|
)
|
||||||
|
@ -2592,6 +2563,7 @@ fn permission_args(app: Command) -> Command {
|
||||||
.require_equals(true)
|
.require_equals(true)
|
||||||
.value_name("PATH")
|
.value_name("PATH")
|
||||||
.help(ALLOW_WRITE_HELP)
|
.help(ALLOW_WRITE_HELP)
|
||||||
|
// todo(dsherret): remove value_parser!(PathBuf) and instead parse as string
|
||||||
.value_parser(value_parser!(PathBuf))
|
.value_parser(value_parser!(PathBuf))
|
||||||
.value_hint(ValueHint::AnyPath),
|
.value_hint(ValueHint::AnyPath),
|
||||||
)
|
)
|
||||||
|
@ -2603,6 +2575,7 @@ fn permission_args(app: Command) -> Command {
|
||||||
.require_equals(true)
|
.require_equals(true)
|
||||||
.value_name("PATH")
|
.value_name("PATH")
|
||||||
.help(DENY_WRITE_HELP)
|
.help(DENY_WRITE_HELP)
|
||||||
|
// todo(dsherret): remove value_parser!(PathBuf) and instead parse as string
|
||||||
.value_parser(value_parser!(PathBuf))
|
.value_parser(value_parser!(PathBuf))
|
||||||
.value_hint(ValueHint::AnyPath),
|
.value_hint(ValueHint::AnyPath),
|
||||||
)
|
)
|
||||||
|
@ -2713,6 +2686,7 @@ fn permission_args(app: Command) -> Command {
|
||||||
.require_equals(true)
|
.require_equals(true)
|
||||||
.value_name("PATH")
|
.value_name("PATH")
|
||||||
.help(ALLOW_FFI_HELP)
|
.help(ALLOW_FFI_HELP)
|
||||||
|
// todo(dsherret): remove value_parser!(PathBuf) and instead parse as string
|
||||||
.value_parser(value_parser!(PathBuf))
|
.value_parser(value_parser!(PathBuf))
|
||||||
.value_hint(ValueHint::AnyPath),
|
.value_hint(ValueHint::AnyPath),
|
||||||
)
|
)
|
||||||
|
@ -2724,6 +2698,7 @@ fn permission_args(app: Command) -> Command {
|
||||||
.require_equals(true)
|
.require_equals(true)
|
||||||
.value_name("PATH")
|
.value_name("PATH")
|
||||||
.help(DENY_FFI_HELP)
|
.help(DENY_FFI_HELP)
|
||||||
|
// todo(dsherret): remove value_parser!(PathBuf) and instead parse as string
|
||||||
.value_parser(value_parser!(PathBuf))
|
.value_parser(value_parser!(PathBuf))
|
||||||
.value_hint(ValueHint::AnyPath),
|
.value_hint(ValueHint::AnyPath),
|
||||||
)
|
)
|
||||||
|
@ -2973,6 +2948,7 @@ fn hmr_arg(takes_files: bool) -> Arg {
|
||||||
arg
|
arg
|
||||||
.value_name("FILES")
|
.value_name("FILES")
|
||||||
.num_args(0..)
|
.num_args(0..)
|
||||||
|
// todo(dsherret): remove value_parser!(PathBuf) and instead parse as string
|
||||||
.value_parser(value_parser!(PathBuf))
|
.value_parser(value_parser!(PathBuf))
|
||||||
.use_value_delimiter(true)
|
.use_value_delimiter(true)
|
||||||
.require_equals(true)
|
.require_equals(true)
|
||||||
|
@ -2999,6 +2975,7 @@ fn watch_arg(takes_files: bool) -> Arg {
|
||||||
arg
|
arg
|
||||||
.value_name("FILES")
|
.value_name("FILES")
|
||||||
.num_args(0..)
|
.num_args(0..)
|
||||||
|
// todo(dsherret): remove value_parser!(PathBuf) and instead parse as string
|
||||||
.value_parser(value_parser!(PathBuf))
|
.value_parser(value_parser!(PathBuf))
|
||||||
.use_value_delimiter(true)
|
.use_value_delimiter(true)
|
||||||
.require_equals(true)
|
.require_equals(true)
|
||||||
|
@ -3090,6 +3067,7 @@ fn lock_arg() -> Arg {
|
||||||
|
|
||||||
If value is not provided, defaults to \"deno.lock\" in the current working directory.")
|
If value is not provided, defaults to \"deno.lock\" in the current working directory.")
|
||||||
.num_args(0..=1)
|
.num_args(0..=1)
|
||||||
|
// todo(dsherret): remove value_parser!(PathBuf) and instead parse as string
|
||||||
.value_parser(value_parser!(PathBuf))
|
.value_parser(value_parser!(PathBuf))
|
||||||
.value_hint(ValueHint::FilePath)
|
.value_hint(ValueHint::FilePath)
|
||||||
}
|
}
|
||||||
|
@ -3194,7 +3172,7 @@ fn bench_parse(flags: &mut Flags, matches: &mut ArgMatches) {
|
||||||
|
|
||||||
let json = matches.get_flag("json");
|
let json = matches.get_flag("json");
|
||||||
|
|
||||||
let ignore = match matches.remove_many::<PathBuf>("ignore") {
|
let ignore = match matches.remove_many::<String>("ignore") {
|
||||||
Some(f) => f.collect(),
|
Some(f) => f.collect(),
|
||||||
None => vec![],
|
None => vec![],
|
||||||
};
|
};
|
||||||
|
@ -3207,7 +3185,7 @@ fn bench_parse(flags: &mut Flags, matches: &mut ArgMatches) {
|
||||||
.extend(matches.remove_many::<String>("script_arg").unwrap());
|
.extend(matches.remove_many::<String>("script_arg").unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
let include = if let Some(files) = matches.remove_many::<PathBuf>("files") {
|
let include = if let Some(files) = matches.remove_many::<String>("files") {
|
||||||
files.collect()
|
files.collect()
|
||||||
} else {
|
} else {
|
||||||
Vec::new()
|
Vec::new()
|
||||||
|
@ -3232,7 +3210,7 @@ fn bundle_parse(flags: &mut Flags, matches: &mut ArgMatches) {
|
||||||
let source_file = matches.remove_one::<String>("source_file").unwrap();
|
let source_file = matches.remove_one::<String>("source_file").unwrap();
|
||||||
|
|
||||||
let out_file =
|
let out_file =
|
||||||
if let Some(out_file) = matches.remove_one::<PathBuf>("out_file") {
|
if let Some(out_file) = matches.remove_one::<String>("out_file") {
|
||||||
flags.allow_write = Some(vec![]);
|
flags.allow_write = Some(vec![]);
|
||||||
Some(out_file)
|
Some(out_file)
|
||||||
} else {
|
} else {
|
||||||
|
@ -3320,12 +3298,11 @@ fn completions_parse(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn coverage_parse(flags: &mut Flags, matches: &mut ArgMatches) {
|
fn coverage_parse(flags: &mut Flags, matches: &mut ArgMatches) {
|
||||||
let default_files = vec![PathBuf::from("coverage")];
|
let files = match matches.remove_many::<String>("files") {
|
||||||
let files = match matches.remove_many::<PathBuf>("files") {
|
|
||||||
Some(f) => f.collect(),
|
Some(f) => f.collect(),
|
||||||
None => default_files,
|
None => vec!["coverage".to_string()], // default
|
||||||
};
|
};
|
||||||
let ignore = match matches.remove_many::<PathBuf>("ignore") {
|
let ignore = match matches.remove_many::<String>("ignore") {
|
||||||
Some(f) => f.collect(),
|
Some(f) => f.collect(),
|
||||||
None => vec![],
|
None => vec![],
|
||||||
};
|
};
|
||||||
|
@ -3448,11 +3425,11 @@ fn fmt_parse(flags: &mut Flags, matches: &mut ArgMatches) {
|
||||||
config_args_parse(flags, matches);
|
config_args_parse(flags, matches);
|
||||||
ext_arg_parse(flags, matches);
|
ext_arg_parse(flags, matches);
|
||||||
|
|
||||||
let include = match matches.remove_many::<PathBuf>("files") {
|
let include = match matches.remove_many::<String>("files") {
|
||||||
Some(f) => f.collect(),
|
Some(f) => f.collect(),
|
||||||
None => vec![],
|
None => vec![],
|
||||||
};
|
};
|
||||||
let ignore = match matches.remove_many::<PathBuf>("ignore") {
|
let ignore = match matches.remove_many::<String>("ignore") {
|
||||||
Some(f) => f.collect(),
|
Some(f) => f.collect(),
|
||||||
None => vec![],
|
None => vec![],
|
||||||
};
|
};
|
||||||
|
@ -3547,11 +3524,11 @@ fn lsp_parse(flags: &mut Flags, _matches: &mut ArgMatches) {
|
||||||
|
|
||||||
fn lint_parse(flags: &mut Flags, matches: &mut ArgMatches) {
|
fn lint_parse(flags: &mut Flags, matches: &mut ArgMatches) {
|
||||||
config_args_parse(flags, matches);
|
config_args_parse(flags, matches);
|
||||||
let files = match matches.remove_many::<PathBuf>("files") {
|
let files = match matches.remove_many::<String>("files") {
|
||||||
Some(f) => f.collect(),
|
Some(f) => f.collect(),
|
||||||
None => vec![],
|
None => vec![],
|
||||||
};
|
};
|
||||||
let ignore = match matches.remove_many::<PathBuf>("ignore") {
|
let ignore = match matches.remove_many::<String>("ignore") {
|
||||||
Some(f) => f.collect(),
|
Some(f) => f.collect(),
|
||||||
None => vec![],
|
None => vec![],
|
||||||
};
|
};
|
||||||
|
@ -3666,7 +3643,7 @@ fn test_parse(flags: &mut Flags, matches: &mut ArgMatches) {
|
||||||
// interactive prompts, unless done by user code
|
// interactive prompts, unless done by user code
|
||||||
flags.no_prompt = true;
|
flags.no_prompt = true;
|
||||||
|
|
||||||
let ignore = match matches.remove_many::<PathBuf>("ignore") {
|
let ignore = match matches.remove_many::<String>("ignore") {
|
||||||
Some(f) => f.collect(),
|
Some(f) => f.collect(),
|
||||||
None => vec![],
|
None => vec![],
|
||||||
};
|
};
|
||||||
|
@ -3725,7 +3702,7 @@ fn test_parse(flags: &mut Flags, matches: &mut ArgMatches) {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let include = if let Some(files) = matches.remove_many::<PathBuf>("files") {
|
let include = if let Some(files) = matches.remove_many::<String>("files") {
|
||||||
files.collect()
|
files.collect()
|
||||||
} else {
|
} else {
|
||||||
Vec::new()
|
Vec::new()
|
||||||
|
@ -4642,10 +4619,7 @@ mod tests {
|
||||||
subcommand: DenoSubcommand::Fmt(FmtFlags {
|
subcommand: DenoSubcommand::Fmt(FmtFlags {
|
||||||
check: false,
|
check: false,
|
||||||
files: FileFlags {
|
files: FileFlags {
|
||||||
include: vec![
|
include: vec!["script_1.ts".to_string(), "script_2.ts".to_string()],
|
||||||
PathBuf::from("script_1.ts"),
|
|
||||||
PathBuf::from("script_2.ts")
|
|
||||||
],
|
|
||||||
ignore: vec![],
|
ignore: vec![],
|
||||||
},
|
},
|
||||||
use_tabs: None,
|
use_tabs: None,
|
||||||
|
@ -4771,8 +4745,8 @@ mod tests {
|
||||||
subcommand: DenoSubcommand::Fmt(FmtFlags {
|
subcommand: DenoSubcommand::Fmt(FmtFlags {
|
||||||
check: true,
|
check: true,
|
||||||
files: FileFlags {
|
files: FileFlags {
|
||||||
include: vec![PathBuf::from("foo.ts")],
|
include: vec!["foo.ts".to_string()],
|
||||||
ignore: vec![PathBuf::from("bar.js")],
|
ignore: vec!["bar.js".to_string()],
|
||||||
},
|
},
|
||||||
use_tabs: None,
|
use_tabs: None,
|
||||||
line_width: None,
|
line_width: None,
|
||||||
|
@ -4825,7 +4799,7 @@ mod tests {
|
||||||
subcommand: DenoSubcommand::Fmt(FmtFlags {
|
subcommand: DenoSubcommand::Fmt(FmtFlags {
|
||||||
check: false,
|
check: false,
|
||||||
files: FileFlags {
|
files: FileFlags {
|
||||||
include: vec![PathBuf::from("foo.ts")],
|
include: vec!["foo.ts".to_string()],
|
||||||
ignore: vec![],
|
ignore: vec![],
|
||||||
},
|
},
|
||||||
use_tabs: None,
|
use_tabs: None,
|
||||||
|
@ -4916,10 +4890,7 @@ mod tests {
|
||||||
Flags {
|
Flags {
|
||||||
subcommand: DenoSubcommand::Lint(LintFlags {
|
subcommand: DenoSubcommand::Lint(LintFlags {
|
||||||
files: FileFlags {
|
files: FileFlags {
|
||||||
include: vec![
|
include: vec!["script_1.ts".to_string(), "script_2.ts".to_string(),],
|
||||||
PathBuf::from("script_1.ts"),
|
|
||||||
PathBuf::from("script_2.ts")
|
|
||||||
],
|
|
||||||
ignore: vec![],
|
ignore: vec![],
|
||||||
},
|
},
|
||||||
rules: false,
|
rules: false,
|
||||||
|
@ -4946,10 +4917,7 @@ mod tests {
|
||||||
Flags {
|
Flags {
|
||||||
subcommand: DenoSubcommand::Lint(LintFlags {
|
subcommand: DenoSubcommand::Lint(LintFlags {
|
||||||
files: FileFlags {
|
files: FileFlags {
|
||||||
include: vec![
|
include: vec!["script_1.ts".to_string(), "script_2.ts".to_string()],
|
||||||
PathBuf::from("script_1.ts"),
|
|
||||||
PathBuf::from("script_2.ts")
|
|
||||||
],
|
|
||||||
ignore: vec![],
|
ignore: vec![],
|
||||||
},
|
},
|
||||||
rules: false,
|
rules: false,
|
||||||
|
@ -4977,10 +4945,7 @@ mod tests {
|
||||||
Flags {
|
Flags {
|
||||||
subcommand: DenoSubcommand::Lint(LintFlags {
|
subcommand: DenoSubcommand::Lint(LintFlags {
|
||||||
files: FileFlags {
|
files: FileFlags {
|
||||||
include: vec![
|
include: vec!["script_1.ts".to_string(), "script_2.ts".to_string()],
|
||||||
PathBuf::from("script_1.ts"),
|
|
||||||
PathBuf::from("script_2.ts")
|
|
||||||
],
|
|
||||||
ignore: vec![],
|
ignore: vec![],
|
||||||
},
|
},
|
||||||
rules: false,
|
rules: false,
|
||||||
|
@ -5006,10 +4971,7 @@ mod tests {
|
||||||
subcommand: DenoSubcommand::Lint(LintFlags {
|
subcommand: DenoSubcommand::Lint(LintFlags {
|
||||||
files: FileFlags {
|
files: FileFlags {
|
||||||
include: vec![],
|
include: vec![],
|
||||||
ignore: vec![
|
ignore: vec!["script_1.ts".to_string(), "script_2.ts".to_string()],
|
||||||
PathBuf::from("script_1.ts"),
|
|
||||||
PathBuf::from("script_2.ts")
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
rules: false,
|
rules: false,
|
||||||
maybe_rules_tags: None,
|
maybe_rules_tags: None,
|
||||||
|
@ -5103,7 +5065,7 @@ mod tests {
|
||||||
Flags {
|
Flags {
|
||||||
subcommand: DenoSubcommand::Lint(LintFlags {
|
subcommand: DenoSubcommand::Lint(LintFlags {
|
||||||
files: FileFlags {
|
files: FileFlags {
|
||||||
include: vec![PathBuf::from("script_1.ts")],
|
include: vec!["script_1.ts".to_string()],
|
||||||
ignore: vec![],
|
ignore: vec![],
|
||||||
},
|
},
|
||||||
rules: false,
|
rules: false,
|
||||||
|
@ -5131,7 +5093,7 @@ mod tests {
|
||||||
Flags {
|
Flags {
|
||||||
subcommand: DenoSubcommand::Lint(LintFlags {
|
subcommand: DenoSubcommand::Lint(LintFlags {
|
||||||
files: FileFlags {
|
files: FileFlags {
|
||||||
include: vec![PathBuf::from("script_1.ts")],
|
include: vec!["script_1.ts".to_string()],
|
||||||
ignore: vec![],
|
ignore: vec![],
|
||||||
},
|
},
|
||||||
rules: false,
|
rules: false,
|
||||||
|
@ -5160,7 +5122,7 @@ mod tests {
|
||||||
Flags {
|
Flags {
|
||||||
subcommand: DenoSubcommand::Lint(LintFlags {
|
subcommand: DenoSubcommand::Lint(LintFlags {
|
||||||
files: FileFlags {
|
files: FileFlags {
|
||||||
include: vec![PathBuf::from("script_1.ts")],
|
include: vec!["script_1.ts".to_string()],
|
||||||
ignore: vec![],
|
ignore: vec![],
|
||||||
},
|
},
|
||||||
rules: false,
|
rules: false,
|
||||||
|
@ -6091,7 +6053,7 @@ mod tests {
|
||||||
Flags {
|
Flags {
|
||||||
subcommand: DenoSubcommand::Bundle(BundleFlags {
|
subcommand: DenoSubcommand::Bundle(BundleFlags {
|
||||||
source_file: "source.ts".to_string(),
|
source_file: "source.ts".to_string(),
|
||||||
out_file: Some(PathBuf::from("bundle.js")),
|
out_file: Some("bundle.js".to_string()),
|
||||||
watch: Default::default(),
|
watch: Default::default(),
|
||||||
}),
|
}),
|
||||||
allow_write: Some(vec![]),
|
allow_write: Some(vec![]),
|
||||||
|
@ -6111,7 +6073,7 @@ mod tests {
|
||||||
Flags {
|
Flags {
|
||||||
subcommand: DenoSubcommand::Bundle(BundleFlags {
|
subcommand: DenoSubcommand::Bundle(BundleFlags {
|
||||||
source_file: "source.ts".to_string(),
|
source_file: "source.ts".to_string(),
|
||||||
out_file: Some(PathBuf::from("bundle.js")),
|
out_file: Some("bundle.js".to_string()),
|
||||||
watch: Default::default(),
|
watch: Default::default(),
|
||||||
}),
|
}),
|
||||||
type_check_mode: TypeCheckMode::Local,
|
type_check_mode: TypeCheckMode::Local,
|
||||||
|
@ -7081,7 +7043,7 @@ mod tests {
|
||||||
filter: Some("- foo".to_string()),
|
filter: Some("- foo".to_string()),
|
||||||
allow_none: true,
|
allow_none: true,
|
||||||
files: FileFlags {
|
files: FileFlags {
|
||||||
include: vec![PathBuf::from("dir1/"), PathBuf::from("dir2/")],
|
include: vec!["dir1/".to_string(), "dir2/".to_string()],
|
||||||
ignore: vec![],
|
ignore: vec![],
|
||||||
},
|
},
|
||||||
shuffle: None,
|
shuffle: None,
|
||||||
|
@ -7410,7 +7372,7 @@ mod tests {
|
||||||
allow_none: false,
|
allow_none: false,
|
||||||
shuffle: None,
|
shuffle: None,
|
||||||
files: FileFlags {
|
files: FileFlags {
|
||||||
include: vec![PathBuf::from("./")],
|
include: vec!["./".to_string()],
|
||||||
ignore: vec![],
|
ignore: vec![],
|
||||||
},
|
},
|
||||||
concurrent_jobs: None,
|
concurrent_jobs: None,
|
||||||
|
@ -7925,7 +7887,7 @@ mod tests {
|
||||||
Flags {
|
Flags {
|
||||||
subcommand: DenoSubcommand::Coverage(CoverageFlags {
|
subcommand: DenoSubcommand::Coverage(CoverageFlags {
|
||||||
files: FileFlags {
|
files: FileFlags {
|
||||||
include: vec![PathBuf::from("foo.json")],
|
include: vec!["foo.json".to_string()],
|
||||||
ignore: vec![],
|
ignore: vec![],
|
||||||
},
|
},
|
||||||
include: vec![r"^file:".to_string()],
|
include: vec![r"^file:".to_string()],
|
||||||
|
@ -7951,7 +7913,7 @@ mod tests {
|
||||||
Flags {
|
Flags {
|
||||||
subcommand: DenoSubcommand::Coverage(CoverageFlags {
|
subcommand: DenoSubcommand::Coverage(CoverageFlags {
|
||||||
files: FileFlags {
|
files: FileFlags {
|
||||||
include: vec![PathBuf::from("foo.json")],
|
include: vec!["foo.json".to_string()],
|
||||||
ignore: vec![],
|
ignore: vec![],
|
||||||
},
|
},
|
||||||
include: vec![r"^file:".to_string()],
|
include: vec![r"^file:".to_string()],
|
||||||
|
@ -7972,7 +7934,7 @@ mod tests {
|
||||||
Flags {
|
Flags {
|
||||||
subcommand: DenoSubcommand::Coverage(CoverageFlags {
|
subcommand: DenoSubcommand::Coverage(CoverageFlags {
|
||||||
files: FileFlags {
|
files: FileFlags {
|
||||||
include: vec![PathBuf::from("coverage")],
|
include: vec!["coverage".to_string()],
|
||||||
ignore: vec![],
|
ignore: vec![],
|
||||||
},
|
},
|
||||||
include: vec![r"^file:".to_string()],
|
include: vec![r"^file:".to_string()],
|
||||||
|
@ -8010,7 +7972,7 @@ mod tests {
|
||||||
flags_from_vec(svec!["deno", "lint", "dir/a.js", "dir/b.js"]).unwrap();
|
flags_from_vec(svec!["deno", "lint", "dir/a.js", "dir/b.js"]).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
flags.config_path_args(&cwd),
|
flags.config_path_args(&cwd),
|
||||||
Some(vec![PathBuf::from("dir/a.js"), PathBuf::from("dir/b.js")])
|
Some(vec![cwd.join("dir/a.js"), cwd.join("dir/b.js")])
|
||||||
);
|
);
|
||||||
|
|
||||||
let flags = flags_from_vec(svec!["deno", "lint"]).unwrap();
|
let flags = flags_from_vec(svec!["deno", "lint"]).unwrap();
|
||||||
|
@ -8020,7 +7982,7 @@ mod tests {
|
||||||
flags_from_vec(svec!["deno", "fmt", "dir/a.js", "dir/b.js"]).unwrap();
|
flags_from_vec(svec!["deno", "fmt", "dir/a.js", "dir/b.js"]).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
flags.config_path_args(&cwd),
|
flags.config_path_args(&cwd),
|
||||||
Some(vec![PathBuf::from("dir/a.js"), PathBuf::from("dir/b.js")])
|
Some(vec![cwd.join("dir/a.js"), cwd.join("dir/b.js")])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8319,7 +8281,7 @@ mod tests {
|
||||||
json: true,
|
json: true,
|
||||||
no_run: true,
|
no_run: true,
|
||||||
files: FileFlags {
|
files: FileFlags {
|
||||||
include: vec![PathBuf::from("dir1/"), PathBuf::from("dir2/")],
|
include: vec!["dir1/".to_string(), "dir2/".to_string()],
|
||||||
ignore: vec![],
|
ignore: vec![],
|
||||||
},
|
},
|
||||||
watch: Default::default(),
|
watch: Default::default(),
|
||||||
|
|
|
@ -9,6 +9,7 @@ pub mod package_json;
|
||||||
pub use self::import_map::resolve_import_map_from_specifier;
|
pub use self::import_map::resolve_import_map_from_specifier;
|
||||||
use self::package_json::PackageJsonDeps;
|
use self::package_json::PackageJsonDeps;
|
||||||
use ::import_map::ImportMap;
|
use ::import_map::ImportMap;
|
||||||
|
use deno_config::glob::PathOrPattern;
|
||||||
use deno_core::resolve_url_or_path;
|
use deno_core::resolve_url_or_path;
|
||||||
use deno_npm::resolution::ValidSerializedNpmResolutionSnapshot;
|
use deno_npm::resolution::ValidSerializedNpmResolutionSnapshot;
|
||||||
use deno_npm::NpmSystemInfo;
|
use deno_npm::NpmSystemInfo;
|
||||||
|
@ -16,9 +17,9 @@ use deno_runtime::deno_tls::RootCertStoreProvider;
|
||||||
use deno_semver::npm::NpmPackageReqReference;
|
use deno_semver::npm::NpmPackageReqReference;
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
|
|
||||||
|
pub use deno_config::glob::FilePatterns;
|
||||||
pub use deno_config::BenchConfig;
|
pub use deno_config::BenchConfig;
|
||||||
pub use deno_config::ConfigFile;
|
pub use deno_config::ConfigFile;
|
||||||
pub use deno_config::FilesConfig;
|
|
||||||
pub use deno_config::FmtOptionsConfig;
|
pub use deno_config::FmtOptionsConfig;
|
||||||
pub use deno_config::JsxImportSourceConfig;
|
pub use deno_config::JsxImportSourceConfig;
|
||||||
pub use deno_config::LintRulesConfig;
|
pub use deno_config::LintRulesConfig;
|
||||||
|
@ -69,10 +70,9 @@ use thiserror::Error;
|
||||||
|
|
||||||
use crate::file_fetcher::FileFetcher;
|
use crate::file_fetcher::FileFetcher;
|
||||||
use crate::util::fs::canonicalize_path_maybe_not_exists;
|
use crate::util::fs::canonicalize_path_maybe_not_exists;
|
||||||
use crate::util::glob::FilePatterns;
|
|
||||||
use crate::util::glob::PathOrPatternSet;
|
|
||||||
use crate::version;
|
use crate::version;
|
||||||
|
|
||||||
|
use deno_config::glob::PathOrPatternSet;
|
||||||
use deno_config::FmtConfig;
|
use deno_config::FmtConfig;
|
||||||
use deno_config::LintConfig;
|
use deno_config::LintConfig;
|
||||||
use deno_config::TestConfig;
|
use deno_config::TestConfig;
|
||||||
|
@ -1187,16 +1187,13 @@ impl CliOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve_config_excludes(&self) -> Result<PathOrPatternSet, AnyError> {
|
pub fn resolve_config_excludes(&self) -> Result<PathOrPatternSet, AnyError> {
|
||||||
let maybe_files_config = if let Some(config_file) = &self.maybe_config_file
|
let maybe_config_files = if let Some(config_file) = &self.maybe_config_file
|
||||||
{
|
{
|
||||||
config_file.to_files_config()?
|
config_file.to_files_config()?
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
PathOrPatternSet::from_absolute_paths(
|
Ok(maybe_config_files.map(|f| f.exclude).unwrap_or_default())
|
||||||
maybe_files_config.map(|c| c.exclude).unwrap_or_default(),
|
|
||||||
)
|
|
||||||
.context("Invalid config file exclude pattern.")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve_test_options(
|
pub fn resolve_test_options(
|
||||||
|
@ -1647,30 +1644,38 @@ impl StorageKeyResolver {
|
||||||
/// over config file, i.e. if there's `files.ignore` in config file
|
/// over config file, i.e. if there's `files.ignore` in config file
|
||||||
/// and `--ignore` CLI flag, only the flag value is taken into account.
|
/// and `--ignore` CLI flag, only the flag value is taken into account.
|
||||||
fn resolve_files(
|
fn resolve_files(
|
||||||
maybe_files_config: Option<FilesConfig>,
|
maybe_files_config: Option<FilePatterns>,
|
||||||
maybe_file_flags: Option<FileFlags>,
|
maybe_file_flags: Option<FileFlags>,
|
||||||
initial_cwd: &Path,
|
initial_cwd: &Path,
|
||||||
) -> Result<FilePatterns, AnyError> {
|
) -> Result<FilePatterns, AnyError> {
|
||||||
let mut maybe_files_config = maybe_files_config.unwrap_or_default();
|
let mut maybe_files_config = maybe_files_config.unwrap_or_default();
|
||||||
if let Some(file_flags) = maybe_file_flags {
|
if let Some(file_flags) = maybe_file_flags {
|
||||||
let file_flags = file_flags.with_absolute_paths(initial_cwd);
|
|
||||||
if !file_flags.include.is_empty() {
|
if !file_flags.include.is_empty() {
|
||||||
maybe_files_config.include = Some(file_flags.include);
|
maybe_files_config.include =
|
||||||
|
Some(PathOrPatternSet::from_relative_path_or_patterns(
|
||||||
|
initial_cwd,
|
||||||
|
&file_flags.include,
|
||||||
|
)?);
|
||||||
}
|
}
|
||||||
if !file_flags.ignore.is_empty() {
|
if !file_flags.ignore.is_empty() {
|
||||||
maybe_files_config.exclude = file_flags.ignore
|
maybe_files_config.exclude =
|
||||||
|
PathOrPatternSet::from_relative_path_or_patterns(
|
||||||
|
initial_cwd,
|
||||||
|
&file_flags.ignore,
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(FilePatterns {
|
Ok(FilePatterns {
|
||||||
include: {
|
include: {
|
||||||
let files = match maybe_files_config.include {
|
let files = match maybe_files_config.include {
|
||||||
Some(include) => include,
|
Some(include) => include,
|
||||||
None => vec![initial_cwd.to_path_buf()],
|
None => PathOrPatternSet::new(vec![PathOrPattern::Path(
|
||||||
|
initial_cwd.to_path_buf(),
|
||||||
|
)]),
|
||||||
};
|
};
|
||||||
Some(PathOrPatternSet::from_absolute_paths(files)?)
|
Some(files)
|
||||||
},
|
},
|
||||||
exclude: PathOrPatternSet::from_absolute_paths(maybe_files_config.exclude)
|
exclude: maybe_files_config.exclude,
|
||||||
.context("Invalid exclude.")?,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1882,26 +1887,32 @@ mod test {
|
||||||
temp_dir.write("pages/[id].ts", "");
|
temp_dir.write("pages/[id].ts", "");
|
||||||
|
|
||||||
let temp_dir_path = temp_dir.path().as_path();
|
let temp_dir_path = temp_dir.path().as_path();
|
||||||
let error = resolve_files(
|
let error = PathOrPatternSet::from_relative_path_or_patterns(
|
||||||
Some(FilesConfig {
|
|
||||||
include: Some(vec![temp_dir_path.join("data/**********.ts")]),
|
|
||||||
exclude: vec![],
|
|
||||||
}),
|
|
||||||
None,
|
|
||||||
temp_dir_path,
|
temp_dir_path,
|
||||||
|
&["data/**********.ts".to_string()],
|
||||||
)
|
)
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
assert!(error.to_string().starts_with("Failed to expand glob"));
|
assert!(error.to_string().starts_with("Failed to expand glob"));
|
||||||
|
|
||||||
let resolved_files = resolve_files(
|
let resolved_files = resolve_files(
|
||||||
Some(FilesConfig {
|
Some(FilePatterns {
|
||||||
include: Some(vec![
|
include: Some(
|
||||||
temp_dir_path.join("data/test1.?s"),
|
PathOrPatternSet::from_relative_path_or_patterns(
|
||||||
temp_dir_path.join("nested/foo/*.ts"),
|
temp_dir_path,
|
||||||
temp_dir_path.join("nested/fizz/*.ts"),
|
&[
|
||||||
temp_dir_path.join("pages/[id].ts"),
|
"data/test1.?s".to_string(),
|
||||||
]),
|
"nested/foo/*.ts".to_string(),
|
||||||
exclude: vec![temp_dir_path.join("nested/**/*bazz.ts")],
|
"nested/fizz/*.ts".to_string(),
|
||||||
|
"pages/[id].ts".to_string(),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
),
|
||||||
|
exclude: PathOrPatternSet::from_relative_path_or_patterns(
|
||||||
|
temp_dir_path,
|
||||||
|
&["nested/**/*bazz.ts".to_string()],
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
}),
|
}),
|
||||||
None,
|
None,
|
||||||
temp_dir_path,
|
temp_dir_path,
|
||||||
|
|
|
@ -6,6 +6,8 @@ use crate::lsp::logging::lsp_warn;
|
||||||
use crate::util::fs::canonicalize_path_maybe_not_exists;
|
use crate::util::fs::canonicalize_path_maybe_not_exists;
|
||||||
use crate::util::path::specifier_to_file_path;
|
use crate::util::path::specifier_to_file_path;
|
||||||
use deno_ast::MediaType;
|
use deno_ast::MediaType;
|
||||||
|
use deno_config::glob::PathOrPattern;
|
||||||
|
use deno_config::glob::PathOrPatternSet;
|
||||||
use deno_config::FmtOptionsConfig;
|
use deno_config::FmtOptionsConfig;
|
||||||
use deno_core::parking_lot::Mutex;
|
use deno_core::parking_lot::Mutex;
|
||||||
use deno_core::serde::de::DeserializeOwned;
|
use deno_core::serde::de::DeserializeOwned;
|
||||||
|
@ -750,10 +752,7 @@ impl ConfigSnapshot {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !self.specifier_enabled(specifier) {
|
self.specifier_enabled(specifier)
|
||||||
return false;
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1055,7 +1054,7 @@ impl Config {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_enabled_paths(&self) -> Vec<PathBuf> {
|
pub fn get_enabled_paths(&self) -> PathOrPatternSet {
|
||||||
let mut paths = vec![];
|
let mut paths = vec![];
|
||||||
for (workspace_uri, _) in &self.workspace_folders {
|
for (workspace_uri, _) in &self.workspace_folders {
|
||||||
let Ok(workspace_path) = specifier_to_file_path(workspace_uri) else {
|
let Ok(workspace_path) = specifier_to_file_path(workspace_uri) else {
|
||||||
|
@ -1065,23 +1064,28 @@ impl Config {
|
||||||
let settings = self.workspace_settings_for_specifier(workspace_uri);
|
let settings = self.workspace_settings_for_specifier(workspace_uri);
|
||||||
if let Some(enable_paths) = &settings.enable_paths {
|
if let Some(enable_paths) = &settings.enable_paths {
|
||||||
for path in enable_paths {
|
for path in enable_paths {
|
||||||
paths.push(workspace_path.join(path));
|
match PathOrPattern::from_relative(&workspace_path, path) {
|
||||||
|
Ok(path_or_pattern) => paths.push(path_or_pattern),
|
||||||
|
Err(err) => {
|
||||||
|
lsp_log!("Invalid enable path '{}': {:#}", path, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
paths.push(workspace_path);
|
paths.push(PathOrPattern::Path(workspace_path));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
paths.sort();
|
paths.sort();
|
||||||
paths.dedup();
|
paths.dedup();
|
||||||
paths
|
PathOrPatternSet::new(paths)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_disabled_paths(&self) -> Vec<PathBuf> {
|
pub fn get_disabled_paths(&self) -> PathOrPatternSet {
|
||||||
let mut paths = vec![];
|
let mut path_or_patterns = vec![];
|
||||||
if let Some(cf) = self.maybe_config_file() {
|
if let Some(cf) = self.maybe_config_file() {
|
||||||
if let Some(files) = cf.to_files_config().ok().flatten() {
|
if let Some(files) = cf.to_files_config().ok().flatten() {
|
||||||
for path in files.exclude {
|
for path in files.exclude.into_path_or_patterns() {
|
||||||
paths.push(path);
|
path_or_patterns.push(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1093,15 +1097,15 @@ impl Config {
|
||||||
let settings = self.workspace_settings_for_specifier(workspace_uri);
|
let settings = self.workspace_settings_for_specifier(workspace_uri);
|
||||||
if settings.enable.unwrap_or_else(|| self.has_config_file()) {
|
if settings.enable.unwrap_or_else(|| self.has_config_file()) {
|
||||||
for path in &settings.disable_paths {
|
for path in &settings.disable_paths {
|
||||||
paths.push(workspace_path.join(path));
|
path_or_patterns.push(PathOrPattern::Path(workspace_path.join(path)));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
paths.push(workspace_path);
|
path_or_patterns.push(PathOrPattern::Path(workspace_path));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
paths.sort();
|
path_or_patterns.sort();
|
||||||
paths.dedup();
|
path_or_patterns.dedup();
|
||||||
paths
|
PathOrPatternSet::new(path_or_patterns)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn log_file(&self) -> bool {
|
pub fn log_file(&self) -> bool {
|
||||||
|
@ -1587,13 +1591,13 @@ mod tests {
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
config.get_enabled_paths(),
|
config.get_enabled_paths(),
|
||||||
vec![
|
PathOrPatternSet::new(vec![
|
||||||
PathBuf::from("/root1/sub_dir"),
|
PathOrPattern::Path(PathBuf::from("/root1/sub_dir")),
|
||||||
PathBuf::from("/root1/sub_dir/other"),
|
PathOrPattern::Path(PathBuf::from("/root1/sub_dir/other")),
|
||||||
PathBuf::from("/root1/test.ts"),
|
PathOrPattern::Path(PathBuf::from("/root1/test.ts")),
|
||||||
PathBuf::from("/root2/other.ts"),
|
PathOrPattern::Path(PathBuf::from("/root2/other.ts")),
|
||||||
PathBuf::from("/root3/"),
|
PathOrPattern::Path(PathBuf::from("/root3/")),
|
||||||
]
|
])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,14 +23,15 @@ use crate::resolver::CliGraphResolverOptions;
|
||||||
use crate::resolver::SloppyImportsFsEntry;
|
use crate::resolver::SloppyImportsFsEntry;
|
||||||
use crate::resolver::SloppyImportsResolution;
|
use crate::resolver::SloppyImportsResolution;
|
||||||
use crate::resolver::SloppyImportsResolver;
|
use crate::resolver::SloppyImportsResolver;
|
||||||
use crate::util::glob;
|
|
||||||
use crate::util::glob::FilePatterns;
|
|
||||||
use crate::util::path::specifier_to_file_path;
|
use crate::util::path::specifier_to_file_path;
|
||||||
use crate::util::text_encoding;
|
use crate::util::text_encoding;
|
||||||
|
|
||||||
use deno_ast::MediaType;
|
use deno_ast::MediaType;
|
||||||
use deno_ast::ParsedSource;
|
use deno_ast::ParsedSource;
|
||||||
use deno_ast::SourceTextInfo;
|
use deno_ast::SourceTextInfo;
|
||||||
|
use deno_config::glob::FilePatterns;
|
||||||
|
use deno_config::glob::PathOrPattern;
|
||||||
|
use deno_config::glob::PathOrPatternSet;
|
||||||
use deno_core::error::custom_error;
|
use deno_core::error::custom_error;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::futures::future;
|
use deno_core::futures::future;
|
||||||
|
@ -843,8 +844,8 @@ impl FileSystemDocuments {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct UpdateDocumentConfigOptions<'a> {
|
pub struct UpdateDocumentConfigOptions<'a> {
|
||||||
pub enabled_paths: Vec<PathBuf>,
|
pub enabled_paths: PathOrPatternSet,
|
||||||
pub disabled_paths: Vec<PathBuf>,
|
pub disabled_paths: PathOrPatternSet,
|
||||||
pub document_preload_limit: usize,
|
pub document_preload_limit: usize,
|
||||||
pub maybe_import_map: Option<Arc<import_map::ImportMap>>,
|
pub maybe_import_map: Option<Arc<import_map::ImportMap>>,
|
||||||
pub maybe_config_file: Option<&'a ConfigFile>,
|
pub maybe_config_file: Option<&'a ConfigFile>,
|
||||||
|
@ -1318,8 +1319,10 @@ impl Documents {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_config(&mut self, options: UpdateDocumentConfigOptions) {
|
pub fn update_config(&mut self, options: UpdateDocumentConfigOptions) {
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn calculate_resolver_config_hash(
|
fn calculate_resolver_config_hash(
|
||||||
enabled_paths: &[PathBuf],
|
enabled_paths: &PathOrPatternSet,
|
||||||
|
disabled_paths: &PathOrPatternSet,
|
||||||
document_preload_limit: usize,
|
document_preload_limit: usize,
|
||||||
maybe_import_map: Option<&import_map::ImportMap>,
|
maybe_import_map: Option<&import_map::ImportMap>,
|
||||||
maybe_jsx_config: Option<&JsxImportSourceConfig>,
|
maybe_jsx_config: Option<&JsxImportSourceConfig>,
|
||||||
|
@ -1327,14 +1330,27 @@ impl Documents {
|
||||||
maybe_package_json_deps: Option<&PackageJsonDeps>,
|
maybe_package_json_deps: Option<&PackageJsonDeps>,
|
||||||
maybe_unstable_flags: Option<&Vec<String>>,
|
maybe_unstable_flags: Option<&Vec<String>>,
|
||||||
) -> u64 {
|
) -> u64 {
|
||||||
|
fn get_pattern_set_vec(set: &PathOrPatternSet) -> Vec<Cow<'_, str>> {
|
||||||
|
let mut paths = set
|
||||||
|
.inner()
|
||||||
|
.iter()
|
||||||
|
.map(|p| match p {
|
||||||
|
PathOrPattern::Path(p) => {
|
||||||
|
Cow::Owned(p.to_string_lossy().to_string())
|
||||||
|
}
|
||||||
|
PathOrPattern::RemoteUrl(p) => Cow::Borrowed(p.as_str()),
|
||||||
|
PathOrPattern::Pattern(p) => Cow::Borrowed(p.as_str()),
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
// ensure these are sorted so the hashing is deterministic
|
||||||
|
paths.sort_unstable();
|
||||||
|
paths
|
||||||
|
}
|
||||||
|
|
||||||
let mut hasher = FastInsecureHasher::default();
|
let mut hasher = FastInsecureHasher::default();
|
||||||
hasher.write_hashable(document_preload_limit);
|
hasher.write_hashable(document_preload_limit);
|
||||||
hasher.write_hashable(&{
|
hasher.write_hashable(&get_pattern_set_vec(enabled_paths));
|
||||||
// ensure these are sorted so the hashing is deterministic
|
hasher.write_hashable(&get_pattern_set_vec(disabled_paths));
|
||||||
let mut enabled_paths = enabled_paths.to_vec();
|
|
||||||
enabled_paths.sort_unstable();
|
|
||||||
enabled_paths
|
|
||||||
});
|
|
||||||
if let Some(import_map) = maybe_import_map {
|
if let Some(import_map) = maybe_import_map {
|
||||||
hasher.write_str(&import_map.to_json());
|
hasher.write_str(&import_map.to_json());
|
||||||
hasher.write_str(import_map.base_url().as_str());
|
hasher.write_str(import_map.base_url().as_str());
|
||||||
|
@ -1372,6 +1388,7 @@ impl Documents {
|
||||||
.and_then(|cf| cf.to_maybe_jsx_import_source_config().ok().flatten());
|
.and_then(|cf| cf.to_maybe_jsx_import_source_config().ok().flatten());
|
||||||
let new_resolver_config_hash = calculate_resolver_config_hash(
|
let new_resolver_config_hash = calculate_resolver_config_hash(
|
||||||
&options.enabled_paths,
|
&options.enabled_paths,
|
||||||
|
&options.disabled_paths,
|
||||||
options.document_preload_limit,
|
options.document_preload_limit,
|
||||||
options.maybe_import_map.as_deref(),
|
options.maybe_import_map.as_deref(),
|
||||||
maybe_jsx_config.as_ref(),
|
maybe_jsx_config.as_ref(),
|
||||||
|
@ -1447,8 +1464,8 @@ impl Documents {
|
||||||
|
|
||||||
fn refresh_dependencies(
|
fn refresh_dependencies(
|
||||||
&mut self,
|
&mut self,
|
||||||
enabled_paths: Vec<PathBuf>,
|
enabled_paths: PathOrPatternSet,
|
||||||
disabled_paths: Vec<PathBuf>,
|
disabled_paths: PathOrPatternSet,
|
||||||
document_preload_limit: usize,
|
document_preload_limit: usize,
|
||||||
) {
|
) {
|
||||||
let resolver = self.resolver.as_graph_resolver();
|
let resolver = self.resolver.as_graph_resolver();
|
||||||
|
@ -1883,8 +1900,8 @@ enum PendingEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PreloadDocumentFinderOptions {
|
struct PreloadDocumentFinderOptions {
|
||||||
enabled_paths: Vec<PathBuf>,
|
enabled_paths: PathOrPatternSet,
|
||||||
disabled_paths: Vec<PathBuf>,
|
disabled_paths: PathOrPatternSet,
|
||||||
limit: usize,
|
limit: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1900,18 +1917,6 @@ struct PreloadDocumentFinder {
|
||||||
|
|
||||||
impl PreloadDocumentFinder {
|
impl PreloadDocumentFinder {
|
||||||
pub fn new(options: PreloadDocumentFinderOptions) -> Self {
|
pub fn new(options: PreloadDocumentFinderOptions) -> Self {
|
||||||
fn paths_into_globs_and_paths(
|
|
||||||
input_paths: Vec<PathBuf>,
|
|
||||||
) -> glob::PathOrPatternSet {
|
|
||||||
let mut result = Vec::with_capacity(input_paths.len());
|
|
||||||
for path in input_paths {
|
|
||||||
if let Ok(path_or_pattern) = glob::PathOrPattern::new(path) {
|
|
||||||
result.push(path_or_pattern);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
glob::PathOrPatternSet::new(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_allowed_root_dir(dir_path: &Path) -> bool {
|
fn is_allowed_root_dir(dir_path: &Path) -> bool {
|
||||||
if dir_path.parent().is_none() {
|
if dir_path.parent().is_none() {
|
||||||
// never search the root directory of a drive
|
// never search the root directory of a drive
|
||||||
|
@ -1929,8 +1934,8 @@ impl PreloadDocumentFinder {
|
||||||
};
|
};
|
||||||
|
|
||||||
let file_patterns = FilePatterns {
|
let file_patterns = FilePatterns {
|
||||||
include: Some(paths_into_globs_and_paths(options.enabled_paths)),
|
include: Some(options.enabled_paths),
|
||||||
exclude: paths_into_globs_and_paths(options.disabled_paths),
|
exclude: options.disabled_paths,
|
||||||
};
|
};
|
||||||
let file_patterns_by_base = file_patterns.split_by_base();
|
let file_patterns_by_base = file_patterns.split_by_base();
|
||||||
|
|
||||||
|
@ -2242,8 +2247,8 @@ console.log(b, "hello deno");
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
documents.update_config(UpdateDocumentConfigOptions {
|
documents.update_config(UpdateDocumentConfigOptions {
|
||||||
enabled_paths: vec![],
|
enabled_paths: Default::default(),
|
||||||
disabled_paths: vec![],
|
disabled_paths: Default::default(),
|
||||||
document_preload_limit: 1_000,
|
document_preload_limit: 1_000,
|
||||||
maybe_import_map: Some(Arc::new(import_map)),
|
maybe_import_map: Some(Arc::new(import_map)),
|
||||||
maybe_config_file: None,
|
maybe_config_file: None,
|
||||||
|
@ -2284,8 +2289,8 @@ console.log(b, "hello deno");
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
documents.update_config(UpdateDocumentConfigOptions {
|
documents.update_config(UpdateDocumentConfigOptions {
|
||||||
enabled_paths: vec![],
|
enabled_paths: Default::default(),
|
||||||
disabled_paths: vec![],
|
disabled_paths: Default::default(),
|
||||||
document_preload_limit: 1_000,
|
document_preload_limit: 1_000,
|
||||||
maybe_import_map: Some(Arc::new(import_map)),
|
maybe_import_map: Some(Arc::new(import_map)),
|
||||||
maybe_config_file: None,
|
maybe_config_file: None,
|
||||||
|
@ -2352,17 +2357,17 @@ console.log(b, "hello deno");
|
||||||
temp_dir.write("root3/mod.ts", ""); // no, not provided
|
temp_dir.write("root3/mod.ts", ""); // no, not provided
|
||||||
|
|
||||||
let mut urls = PreloadDocumentFinder::new(PreloadDocumentFinderOptions {
|
let mut urls = PreloadDocumentFinder::new(PreloadDocumentFinderOptions {
|
||||||
enabled_paths: vec![
|
enabled_paths: PathOrPatternSet::from_relative_path_or_patterns(
|
||||||
temp_dir.path().to_path_buf().join("root1"),
|
temp_dir.path().as_path(),
|
||||||
temp_dir.path().to_path_buf().join("root2").join("file1.ts"),
|
&[
|
||||||
temp_dir
|
"root1".to_string(),
|
||||||
.path()
|
"root2/file1.ts".to_string(),
|
||||||
.to_path_buf()
|
"root2/main.min.ts".to_string(),
|
||||||
.join("root2")
|
"root2/folder".to_string(),
|
||||||
.join("main.min.ts"),
|
],
|
||||||
temp_dir.path().to_path_buf().join("root2").join("folder"),
|
)
|
||||||
],
|
.unwrap(),
|
||||||
disabled_paths: Vec::new(),
|
disabled_paths: Default::default(),
|
||||||
limit: 1_000,
|
limit: 1_000,
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
@ -2392,8 +2397,10 @@ console.log(b, "hello deno");
|
||||||
|
|
||||||
// now try iterating with a low limit
|
// now try iterating with a low limit
|
||||||
let urls = PreloadDocumentFinder::new(PreloadDocumentFinderOptions {
|
let urls = PreloadDocumentFinder::new(PreloadDocumentFinderOptions {
|
||||||
enabled_paths: vec![temp_dir.path().to_path_buf()],
|
enabled_paths: PathOrPatternSet::new(vec![PathOrPattern::Path(
|
||||||
disabled_paths: Vec::new(),
|
temp_dir.path().to_path_buf(),
|
||||||
|
)]),
|
||||||
|
disabled_paths: Default::default(),
|
||||||
limit: 10, // entries and not results
|
limit: 10, // entries and not results
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
@ -2405,12 +2412,18 @@ console.log(b, "hello deno");
|
||||||
|
|
||||||
// now try with certain directories and files disabled
|
// now try with certain directories and files disabled
|
||||||
let mut urls = PreloadDocumentFinder::new(PreloadDocumentFinderOptions {
|
let mut urls = PreloadDocumentFinder::new(PreloadDocumentFinderOptions {
|
||||||
enabled_paths: vec![temp_dir.path().to_path_buf()],
|
enabled_paths: PathOrPatternSet::new(vec![PathOrPattern::Path(
|
||||||
disabled_paths: vec![
|
temp_dir.path().to_path_buf(),
|
||||||
temp_dir.path().to_path_buf().join("root1"),
|
)]),
|
||||||
temp_dir.path().to_path_buf().join("root2").join("file1.ts"),
|
disabled_paths: PathOrPatternSet::from_relative_path_or_patterns(
|
||||||
temp_dir.path().to_path_buf().join("**/*.js"), // ignore js files
|
temp_dir.path().as_path(),
|
||||||
],
|
&[
|
||||||
|
"root1".to_string(),
|
||||||
|
"root2/file1.ts".to_string(),
|
||||||
|
"**/*.js".to_string(), // ignore js files
|
||||||
|
],
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
limit: 1_000,
|
limit: 1_000,
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
@ -2430,16 +2443,20 @@ console.log(b, "hello deno");
|
||||||
pub fn test_pre_load_document_finder_disallowed_dirs() {
|
pub fn test_pre_load_document_finder_disallowed_dirs() {
|
||||||
if cfg!(windows) {
|
if cfg!(windows) {
|
||||||
let paths = PreloadDocumentFinder::new(PreloadDocumentFinderOptions {
|
let paths = PreloadDocumentFinder::new(PreloadDocumentFinderOptions {
|
||||||
enabled_paths: vec![PathBuf::from("C:\\")],
|
enabled_paths: PathOrPatternSet::new(vec![PathOrPattern::Path(
|
||||||
disabled_paths: Vec::new(),
|
PathBuf::from("C:\\"),
|
||||||
|
)]),
|
||||||
|
disabled_paths: Default::default(),
|
||||||
limit: 1_000,
|
limit: 1_000,
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
assert_eq!(paths, vec![]);
|
assert_eq!(paths, vec![]);
|
||||||
} else {
|
} else {
|
||||||
let paths = PreloadDocumentFinder::new(PreloadDocumentFinderOptions {
|
let paths = PreloadDocumentFinder::new(PreloadDocumentFinderOptions {
|
||||||
enabled_paths: vec![PathBuf::from("/")],
|
enabled_paths: PathOrPatternSet::new(vec![PathOrPattern::Path(
|
||||||
disabled_paths: Vec::new(),
|
PathBuf::from("/"),
|
||||||
|
)]),
|
||||||
|
disabled_paths: Default::default(),
|
||||||
limit: 1_000,
|
limit: 1_000,
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
|
@ -15,12 +15,12 @@ use crate::tools::test::format_test_error;
|
||||||
use crate::tools::test::TestFilter;
|
use crate::tools::test::TestFilter;
|
||||||
use crate::util::file_watcher;
|
use crate::util::file_watcher;
|
||||||
use crate::util::fs::collect_specifiers;
|
use crate::util::fs::collect_specifiers;
|
||||||
use crate::util::glob::FilePatterns;
|
|
||||||
use crate::util::glob::PathOrPattern;
|
|
||||||
use crate::util::path::is_script_ext;
|
use crate::util::path::is_script_ext;
|
||||||
use crate::version::get_user_agent;
|
use crate::version::get_user_agent;
|
||||||
use crate::worker::CliMainWorkerFactory;
|
use crate::worker::CliMainWorkerFactory;
|
||||||
|
|
||||||
|
use deno_config::glob::FilePatterns;
|
||||||
|
use deno_config::glob::PathOrPattern;
|
||||||
use deno_core::error::generic_error;
|
use deno_core::error::generic_error;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::error::JsError;
|
use deno_core::error::JsError;
|
||||||
|
@ -408,6 +408,7 @@ fn is_supported_bench_path(path: &Path, patterns: &FilePatterns) -> bool {
|
||||||
.map(|p| {
|
.map(|p| {
|
||||||
p.inner().iter().any(|p| match p {
|
p.inner().iter().any(|p| match p {
|
||||||
PathOrPattern::Path(p) => p == path,
|
PathOrPattern::Path(p) => p == path,
|
||||||
|
PathOrPattern::RemoteUrl(_) => true,
|
||||||
PathOrPattern::Pattern(p) => p.matches_path(path),
|
PathOrPattern::Pattern(p) => p.matches_path(path),
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -99,9 +99,10 @@ async fn bundle_action(
|
||||||
let out_file = &bundle_flags.out_file;
|
let out_file = &bundle_flags.out_file;
|
||||||
|
|
||||||
if let Some(out_file) = out_file {
|
if let Some(out_file) = out_file {
|
||||||
|
let out_file = cli_options.initial_cwd().join(out_file);
|
||||||
let output_bytes = bundle_output.code.as_bytes();
|
let output_bytes = bundle_output.code.as_bytes();
|
||||||
let output_len = output_bytes.len();
|
let output_len = output_bytes.len();
|
||||||
util::fs::write_file(out_file, output_bytes, 0o644)?;
|
util::fs::write_file(&out_file, output_bytes, 0o644)?;
|
||||||
log::info!(
|
log::info!(
|
||||||
"{} {:?} ({})",
|
"{} {:?} ({})",
|
||||||
colors::green("Emit"),
|
colors::green("Emit"),
|
||||||
|
|
|
@ -9,12 +9,13 @@ use crate::npm::CliNpmResolver;
|
||||||
use crate::tools::fmt::format_json;
|
use crate::tools::fmt::format_json;
|
||||||
use crate::tools::test::is_supported_test_path;
|
use crate::tools::test::is_supported_test_path;
|
||||||
use crate::util::fs::FileCollector;
|
use crate::util::fs::FileCollector;
|
||||||
use crate::util::glob::FilePatterns;
|
|
||||||
use crate::util::glob::PathOrPatternSet;
|
|
||||||
use crate::util::text_encoding::source_map_from_code;
|
use crate::util::text_encoding::source_map_from_code;
|
||||||
|
|
||||||
use deno_ast::MediaType;
|
use deno_ast::MediaType;
|
||||||
use deno_ast::ModuleSpecifier;
|
use deno_ast::ModuleSpecifier;
|
||||||
|
use deno_config::glob::FilePatterns;
|
||||||
|
use deno_config::glob::PathOrPattern;
|
||||||
|
use deno_config::glob::PathOrPatternSet;
|
||||||
use deno_core::anyhow::anyhow;
|
use deno_core::anyhow::anyhow;
|
||||||
use deno_core::anyhow::Context;
|
use deno_core::anyhow::Context;
|
||||||
use deno_core::error::generic_error;
|
use deno_core::error::generic_error;
|
||||||
|
@ -375,19 +376,25 @@ fn collect_coverages(
|
||||||
files: FileFlags,
|
files: FileFlags,
|
||||||
initial_cwd: &Path,
|
initial_cwd: &Path,
|
||||||
) -> Result<Vec<cdp::ScriptCoverage>, AnyError> {
|
) -> Result<Vec<cdp::ScriptCoverage>, AnyError> {
|
||||||
let files = files.with_absolute_paths(initial_cwd);
|
|
||||||
let mut coverages: Vec<cdp::ScriptCoverage> = Vec::new();
|
let mut coverages: Vec<cdp::ScriptCoverage> = Vec::new();
|
||||||
let file_patterns = FilePatterns {
|
let file_patterns = FilePatterns {
|
||||||
include: Some({
|
include: Some({
|
||||||
let files = if files.include.is_empty() {
|
if files.include.is_empty() {
|
||||||
vec![initial_cwd.to_path_buf()]
|
PathOrPatternSet::new(vec![PathOrPattern::Path(
|
||||||
|
initial_cwd.to_path_buf(),
|
||||||
|
)])
|
||||||
} else {
|
} else {
|
||||||
files.include
|
PathOrPatternSet::from_relative_path_or_patterns(
|
||||||
};
|
initial_cwd,
|
||||||
PathOrPatternSet::from_absolute_paths(files)?
|
&files.include,
|
||||||
|
)?
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
exclude: PathOrPatternSet::from_absolute_paths(files.ignore)
|
exclude: PathOrPatternSet::from_relative_path_or_patterns(
|
||||||
.context("Invalid ignore pattern.")?,
|
initial_cwd,
|
||||||
|
&files.ignore,
|
||||||
|
)
|
||||||
|
.context("Invalid ignore pattern.")?,
|
||||||
};
|
};
|
||||||
let file_paths = FileCollector::new(|file_path, _| {
|
let file_paths = FileCollector::new(|file_path, _| {
|
||||||
file_path
|
file_path
|
||||||
|
@ -463,7 +470,9 @@ pub async fn cover_files(
|
||||||
assert!(!coverage_flags.files.include.is_empty());
|
assert!(!coverage_flags.files.include.is_empty());
|
||||||
|
|
||||||
// Use the first include path as the default output path.
|
// Use the first include path as the default output path.
|
||||||
let coverage_root = coverage_flags.files.include[0].clone();
|
let coverage_root = cli_options
|
||||||
|
.initial_cwd()
|
||||||
|
.join(&coverage_flags.files.include[0]);
|
||||||
let script_coverages =
|
let script_coverages =
|
||||||
collect_coverages(coverage_flags.files, cli_options.initial_cwd())?;
|
collect_coverages(coverage_flags.files, cli_options.initial_cwd())?;
|
||||||
if script_coverages.is_empty() {
|
if script_coverages.is_empty() {
|
||||||
|
|
|
@ -11,8 +11,8 @@ use crate::factory::CliFactory;
|
||||||
use crate::graph_util::graph_lock_or_exit;
|
use crate::graph_util::graph_lock_or_exit;
|
||||||
use crate::tsc::get_types_declaration_file_text;
|
use crate::tsc::get_types_declaration_file_text;
|
||||||
use crate::util::fs::collect_specifiers;
|
use crate::util::fs::collect_specifiers;
|
||||||
use crate::util::glob::FilePatterns;
|
use deno_config::glob::FilePatterns;
|
||||||
use crate::util::glob::PathOrPatternSet;
|
use deno_config::glob::PathOrPatternSet;
|
||||||
use deno_core::anyhow::bail;
|
use deno_core::anyhow::bail;
|
||||||
use deno_core::anyhow::Context;
|
use deno_core::anyhow::Context;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
|
@ -25,7 +25,6 @@ use deno_graph::ModuleSpecifier;
|
||||||
use doc::DocDiagnostic;
|
use doc::DocDiagnostic;
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::path::PathBuf;
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
async fn generate_doc_nodes_for_builtin_types(
|
async fn generate_doc_nodes_for_builtin_types(
|
||||||
|
@ -94,21 +93,9 @@ pub async fn doc(flags: Flags, doc_flags: DocFlags) -> Result<(), AnyError> {
|
||||||
|
|
||||||
let module_specifiers = collect_specifiers(
|
let module_specifiers = collect_specifiers(
|
||||||
FilePatterns {
|
FilePatterns {
|
||||||
include: Some(PathOrPatternSet::from_absolute_paths(
|
include: Some(PathOrPatternSet::from_relative_path_or_patterns(
|
||||||
source_files
|
cli_options.initial_cwd(),
|
||||||
.iter()
|
source_files,
|
||||||
.map(|p| {
|
|
||||||
if p.starts_with("https:")
|
|
||||||
|| p.starts_with("http:")
|
|
||||||
|| p.starts_with("file:")
|
|
||||||
{
|
|
||||||
// todo(dsherret): don't store URLs in PathBufs
|
|
||||||
PathBuf::from(p)
|
|
||||||
} else {
|
|
||||||
cli_options.initial_cwd().join(p)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect(),
|
|
||||||
)?),
|
)?),
|
||||||
exclude: Default::default(),
|
exclude: Default::default(),
|
||||||
},
|
},
|
||||||
|
|
|
@ -19,10 +19,10 @@ use crate::util::diff::diff;
|
||||||
use crate::util::file_watcher;
|
use crate::util::file_watcher;
|
||||||
use crate::util::fs::canonicalize_path;
|
use crate::util::fs::canonicalize_path;
|
||||||
use crate::util::fs::FileCollector;
|
use crate::util::fs::FileCollector;
|
||||||
use crate::util::glob::FilePatterns;
|
|
||||||
use crate::util::path::get_extension;
|
use crate::util::path::get_extension;
|
||||||
use crate::util::text_encoding;
|
use crate::util::text_encoding;
|
||||||
use deno_ast::ParsedSource;
|
use deno_ast::ParsedSource;
|
||||||
|
use deno_config::glob::FilePatterns;
|
||||||
use deno_core::anyhow::anyhow;
|
use deno_core::anyhow::anyhow;
|
||||||
use deno_core::anyhow::bail;
|
use deno_core::anyhow::bail;
|
||||||
use deno_core::anyhow::Context;
|
use deno_core::anyhow::Context;
|
||||||
|
|
|
@ -13,10 +13,10 @@ use crate::tools::fmt::run_parallelized;
|
||||||
use crate::util::file_watcher;
|
use crate::util::file_watcher;
|
||||||
use crate::util::fs::canonicalize_path;
|
use crate::util::fs::canonicalize_path;
|
||||||
use crate::util::fs::FileCollector;
|
use crate::util::fs::FileCollector;
|
||||||
use crate::util::glob::FilePatterns;
|
|
||||||
use crate::util::path::is_script_ext;
|
use crate::util::path::is_script_ext;
|
||||||
use crate::util::sync::AtomicFlag;
|
use crate::util::sync::AtomicFlag;
|
||||||
use deno_ast::MediaType;
|
use deno_ast::MediaType;
|
||||||
|
use deno_config::glob::FilePatterns;
|
||||||
use deno_core::anyhow::bail;
|
use deno_core::anyhow::bail;
|
||||||
use deno_core::error::generic_error;
|
use deno_core::error::generic_error;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
|
|
|
@ -36,7 +36,6 @@ use crate::tools::registry::graph::resolve_config_file_roots_from_exports;
|
||||||
use crate::tools::registry::graph::surface_fast_check_type_graph_errors;
|
use crate::tools::registry::graph::surface_fast_check_type_graph_errors;
|
||||||
use crate::tools::registry::graph::MemberRoots;
|
use crate::tools::registry::graph::MemberRoots;
|
||||||
use crate::util::display::human_size;
|
use crate::util::display::human_size;
|
||||||
use crate::util::glob::PathOrPatternSet;
|
|
||||||
use crate::util::import_map::ImportMapUnfurler;
|
use crate::util::import_map::ImportMapUnfurler;
|
||||||
|
|
||||||
mod api;
|
mod api;
|
||||||
|
@ -127,10 +126,9 @@ async fn prepare_publish(
|
||||||
let Some((scope, package_name)) = name.split_once('/') else {
|
let Some((scope, package_name)) = name.split_once('/') else {
|
||||||
bail!("Invalid package name, use '@<scope_name>/<package_name> format");
|
bail!("Invalid package name, use '@<scope_name>/<package_name> format");
|
||||||
};
|
};
|
||||||
let exclude_patterns = deno_json.to_files_config().and_then(|files| {
|
let exclude_patterns = deno_json
|
||||||
PathOrPatternSet::from_absolute_paths(files.unwrap_or_default().exclude)
|
.to_files_config()
|
||||||
.context("Invalid config file exclude pattern.")
|
.map(|files| files.unwrap_or_default().exclude)?;
|
||||||
})?;
|
|
||||||
|
|
||||||
let tarball = deno_core::unsync::spawn_blocking(move || {
|
let tarball = deno_core::unsync::spawn_blocking(move || {
|
||||||
let unfurler = ImportMapUnfurler::new(&import_map);
|
let unfurler = ImportMapUnfurler::new(&import_map);
|
||||||
|
|
|
@ -12,8 +12,8 @@ use std::path::Path;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use tar::Header;
|
use tar::Header;
|
||||||
|
|
||||||
use crate::util::glob::PathOrPatternSet;
|
|
||||||
use crate::util::import_map::ImportMapUnfurler;
|
use crate::util::import_map::ImportMapUnfurler;
|
||||||
|
use deno_config::glob::PathOrPatternSet;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct PublishableTarballFile {
|
pub struct PublishableTarballFile {
|
||||||
|
|
|
@ -16,8 +16,6 @@ use crate::module_loader::ModuleLoadPreparer;
|
||||||
use crate::ops;
|
use crate::ops;
|
||||||
use crate::util::file_watcher;
|
use crate::util::file_watcher;
|
||||||
use crate::util::fs::collect_specifiers;
|
use crate::util::fs::collect_specifiers;
|
||||||
use crate::util::glob::FilePatterns;
|
|
||||||
use crate::util::glob::PathOrPattern;
|
|
||||||
use crate::util::path::get_extension;
|
use crate::util::path::get_extension;
|
||||||
use crate::util::path::is_script_ext;
|
use crate::util::path::is_script_ext;
|
||||||
use crate::util::path::mapped_specifier_for_tsc;
|
use crate::util::path::mapped_specifier_for_tsc;
|
||||||
|
@ -26,6 +24,8 @@ use crate::worker::CliMainWorkerFactory;
|
||||||
use deno_ast::swc::common::comments::CommentKind;
|
use deno_ast::swc::common::comments::CommentKind;
|
||||||
use deno_ast::MediaType;
|
use deno_ast::MediaType;
|
||||||
use deno_ast::SourceRangedForSpanned;
|
use deno_ast::SourceRangedForSpanned;
|
||||||
|
use deno_config::glob::FilePatterns;
|
||||||
|
use deno_config::glob::PathOrPattern;
|
||||||
use deno_core::anyhow;
|
use deno_core::anyhow;
|
||||||
use deno_core::anyhow::bail;
|
use deno_core::anyhow::bail;
|
||||||
use deno_core::anyhow::Context as _;
|
use deno_core::anyhow::Context as _;
|
||||||
|
@ -1065,6 +1065,7 @@ fn is_supported_test_path_predicate(
|
||||||
.map(|p| {
|
.map(|p| {
|
||||||
p.inner().iter().any(|p| match p {
|
p.inner().iter().any(|p| match p {
|
||||||
PathOrPattern::Path(p) => p == path,
|
PathOrPattern::Path(p) => p == path,
|
||||||
|
PathOrPattern::RemoteUrl(_) => true,
|
||||||
PathOrPattern::Pattern(p) => p.matches_path(path),
|
PathOrPattern::Pattern(p) => p.matches_path(path),
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
115
cli/util/fs.rs
115
cli/util/fs.rs
|
@ -1,14 +1,5 @@
|
||||||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
use deno_core::anyhow::anyhow;
|
|
||||||
use deno_core::anyhow::Context;
|
|
||||||
use deno_core::error::AnyError;
|
|
||||||
pub use deno_core::normalize_path;
|
|
||||||
use deno_core::unsync::spawn_blocking;
|
|
||||||
use deno_core::ModuleSpecifier;
|
|
||||||
use deno_runtime::deno_crypto::rand;
|
|
||||||
use deno_runtime::deno_fs::FileSystem;
|
|
||||||
use deno_runtime::deno_node::PathClean;
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::env::current_dir;
|
use std::env::current_dir;
|
||||||
use std::fmt::Write as FmtWrite;
|
use std::fmt::Write as FmtWrite;
|
||||||
|
@ -22,15 +13,23 @@ use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use walkdir::WalkDir;
|
use walkdir::WalkDir;
|
||||||
|
|
||||||
|
use deno_config::glob::FilePatterns;
|
||||||
|
use deno_config::glob::PathOrPattern;
|
||||||
|
use deno_config::glob::PathOrPatternSet;
|
||||||
|
use deno_core::anyhow::anyhow;
|
||||||
|
use deno_core::anyhow::Context;
|
||||||
|
use deno_core::error::AnyError;
|
||||||
|
pub use deno_core::normalize_path;
|
||||||
|
use deno_core::unsync::spawn_blocking;
|
||||||
|
use deno_core::ModuleSpecifier;
|
||||||
|
use deno_runtime::deno_crypto::rand;
|
||||||
|
use deno_runtime::deno_fs::FileSystem;
|
||||||
|
use deno_runtime::deno_node::PathClean;
|
||||||
|
|
||||||
use crate::util::progress_bar::ProgressBar;
|
use crate::util::progress_bar::ProgressBar;
|
||||||
use crate::util::progress_bar::ProgressBarStyle;
|
use crate::util::progress_bar::ProgressBarStyle;
|
||||||
use crate::util::progress_bar::ProgressMessagePrompt;
|
use crate::util::progress_bar::ProgressMessagePrompt;
|
||||||
|
|
||||||
use super::glob::FilePatterns;
|
|
||||||
use super::glob::PathOrPattern;
|
|
||||||
use super::glob::PathOrPatternSet;
|
|
||||||
use super::path::specifier_to_file_path;
|
|
||||||
|
|
||||||
/// Writes the file to the file system at a temporary path, then
|
/// Writes the file to the file system at a temporary path, then
|
||||||
/// renames it to the destination in a single sys call in order
|
/// renames it to the destination in a single sys call in order
|
||||||
/// to never leave the file system in a corrupted state.
|
/// to never leave the file system in a corrupted state.
|
||||||
|
@ -359,26 +358,7 @@ pub fn collect_specifiers(
|
||||||
for path_or_pattern in path_or_patterns {
|
for path_or_pattern in path_or_patterns {
|
||||||
match path_or_pattern {
|
match path_or_pattern {
|
||||||
PathOrPattern::Path(path) => {
|
PathOrPattern::Path(path) => {
|
||||||
// todo(dsherret): we should improve this to not store URLs in a PathBuf
|
if path.is_dir() {
|
||||||
let path_str = path.to_string_lossy();
|
|
||||||
let lowercase_path = path_str.to_lowercase();
|
|
||||||
if lowercase_path.starts_with("http://")
|
|
||||||
|| lowercase_path.starts_with("https://")
|
|
||||||
{
|
|
||||||
// take out the url
|
|
||||||
let url = ModuleSpecifier::parse(&path_str)
|
|
||||||
.with_context(|| format!("Invalid URL '{}'", path_str))?;
|
|
||||||
prepared.push(url);
|
|
||||||
} else if lowercase_path.starts_with("file://") {
|
|
||||||
let url = ModuleSpecifier::parse(&path_str)
|
|
||||||
.with_context(|| format!("Invalid URL '{}'", path_str))?;
|
|
||||||
let p = specifier_to_file_path(&url)?;
|
|
||||||
if p.is_dir() {
|
|
||||||
result.push(PathOrPattern::Path(p));
|
|
||||||
} else {
|
|
||||||
prepared.push(url)
|
|
||||||
}
|
|
||||||
} else if path.is_dir() {
|
|
||||||
result.push(PathOrPattern::Path(path));
|
result.push(PathOrPattern::Path(path));
|
||||||
} else if !files.exclude.matches_path(&path) {
|
} else if !files.exclude.matches_path(&path) {
|
||||||
let url = ModuleSpecifier::from_file_path(&path)
|
let url = ModuleSpecifier::from_file_path(&path)
|
||||||
|
@ -386,6 +366,9 @@ pub fn collect_specifiers(
|
||||||
prepared.push(url);
|
prepared.push(url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
PathOrPattern::RemoteUrl(remote_url) => {
|
||||||
|
prepared.push(remote_url);
|
||||||
|
}
|
||||||
PathOrPattern::Pattern(pattern) => {
|
PathOrPattern::Pattern(pattern) => {
|
||||||
// add it back
|
// add it back
|
||||||
result.push(PathOrPattern::Pattern(pattern));
|
result.push(PathOrPattern::Pattern(pattern));
|
||||||
|
@ -824,16 +807,12 @@ mod tests {
|
||||||
create_files(&ignore_dir_path, &ignore_dir_files);
|
create_files(&ignore_dir_path, &ignore_dir_files);
|
||||||
|
|
||||||
let file_patterns = FilePatterns {
|
let file_patterns = FilePatterns {
|
||||||
include: Some(
|
include: Some(PathOrPatternSet::new(vec![PathOrPattern::Path(
|
||||||
PathOrPatternSet::from_absolute_paths(
|
root_dir_path.to_path_buf(),
|
||||||
vec![root_dir_path.to_path_buf()],
|
)])),
|
||||||
)
|
exclude: PathOrPatternSet::new(vec![PathOrPattern::Path(
|
||||||
.unwrap(),
|
ignore_dir_path.to_path_buf(),
|
||||||
),
|
)]),
|
||||||
exclude: PathOrPatternSet::from_absolute_paths(vec![
|
|
||||||
ignore_dir_path.to_path_buf()
|
|
||||||
])
|
|
||||||
.unwrap(),
|
|
||||||
};
|
};
|
||||||
let file_collector = FileCollector::new(|path, _| {
|
let file_collector = FileCollector::new(|path, _| {
|
||||||
// exclude dotfiles
|
// exclude dotfiles
|
||||||
|
@ -892,17 +871,15 @@ mod tests {
|
||||||
|
|
||||||
// test opting out of ignoring by specifying the dir
|
// test opting out of ignoring by specifying the dir
|
||||||
let file_patterns = FilePatterns {
|
let file_patterns = FilePatterns {
|
||||||
include: Some(
|
include: Some(PathOrPatternSet::new(vec![
|
||||||
PathOrPatternSet::from_absolute_paths(vec![
|
PathOrPattern::Path(root_dir_path.to_path_buf()),
|
||||||
root_dir_path.to_path_buf(),
|
PathOrPattern::Path(
|
||||||
root_dir_path.to_path_buf().join("child/node_modules/"),
|
root_dir_path.to_path_buf().join("child/node_modules/"),
|
||||||
])
|
),
|
||||||
.unwrap(),
|
])),
|
||||||
),
|
exclude: PathOrPatternSet::new(vec![PathOrPattern::Path(
|
||||||
exclude: PathOrPatternSet::from_absolute_paths(vec![
|
ignore_dir_path.to_path_buf(),
|
||||||
ignore_dir_path.to_path_buf()
|
)]),
|
||||||
])
|
|
||||||
.unwrap(),
|
|
||||||
};
|
};
|
||||||
let result = file_collector.collect_file_patterns(file_patterns).unwrap();
|
let result = file_collector.collect_file_patterns(file_patterns).unwrap();
|
||||||
let expected = [
|
let expected = [
|
||||||
|
@ -972,17 +949,19 @@ mod tests {
|
||||||
let result = collect_specifiers(
|
let result = collect_specifiers(
|
||||||
FilePatterns {
|
FilePatterns {
|
||||||
include: Some(
|
include: Some(
|
||||||
PathOrPatternSet::from_absolute_paths(vec![
|
PathOrPatternSet::from_relative_path_or_patterns(
|
||||||
PathBuf::from("http://localhost:8080"),
|
root_dir_path.as_path(),
|
||||||
root_dir_path.to_path_buf(),
|
&[
|
||||||
PathBuf::from("https://localhost:8080".to_string()),
|
"http://localhost:8080".to_string(),
|
||||||
])
|
"./".to_string(),
|
||||||
|
"https://localhost:8080".to_string(),
|
||||||
|
],
|
||||||
|
)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
),
|
),
|
||||||
exclude: PathOrPatternSet::from_absolute_paths(vec![
|
exclude: PathOrPatternSet::new(vec![PathOrPattern::Path(
|
||||||
ignore_dir_path.to_path_buf()
|
ignore_dir_path.to_path_buf(),
|
||||||
])
|
)]),
|
||||||
.unwrap(),
|
|
||||||
},
|
},
|
||||||
predicate,
|
predicate,
|
||||||
)
|
)
|
||||||
|
@ -1018,14 +997,14 @@ mod tests {
|
||||||
};
|
};
|
||||||
let result = collect_specifiers(
|
let result = collect_specifiers(
|
||||||
FilePatterns {
|
FilePatterns {
|
||||||
include: Some(
|
include: Some(PathOrPatternSet::new(vec![PathOrPattern::new(
|
||||||
PathOrPatternSet::from_absolute_paths(vec![PathBuf::from(format!(
|
&format!(
|
||||||
"{}{}",
|
"{}{}",
|
||||||
scheme,
|
scheme,
|
||||||
root_dir_path.join("child").to_string().replace('\\', "/")
|
root_dir_path.join("child").to_string().replace('\\', "/")
|
||||||
))])
|
),
|
||||||
.unwrap(),
|
)
|
||||||
),
|
.unwrap()])),
|
||||||
exclude: Default::default(),
|
exclude: Default::default(),
|
||||||
},
|
},
|
||||||
predicate,
|
predicate,
|
||||||
|
|
465
cli/util/glob.rs
465
cli/util/glob.rs
|
@ -1,465 +0,0 @@
|
||||||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
|
||||||
|
|
||||||
use std::path::Path;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
use deno_core::anyhow::Context;
|
|
||||||
use deno_core::error::AnyError;
|
|
||||||
use deno_core::normalize_path;
|
|
||||||
use deno_core::url::Url;
|
|
||||||
use indexmap::IndexMap;
|
|
||||||
|
|
||||||
use super::path::specifier_to_file_path;
|
|
||||||
|
|
||||||
#[derive(Clone, Default, Debug, Eq, PartialEq)]
|
|
||||||
pub struct FilePatterns {
|
|
||||||
pub include: Option<PathOrPatternSet>,
|
|
||||||
pub exclude: PathOrPatternSet,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FilePatterns {
|
|
||||||
pub fn matches_specifier(&self, specifier: &Url) -> bool {
|
|
||||||
let path = match specifier_to_file_path(specifier) {
|
|
||||||
Ok(path) => path,
|
|
||||||
Err(_) => return true,
|
|
||||||
};
|
|
||||||
self.matches_path(&path)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn matches_path(&self, path: &Path) -> bool {
|
|
||||||
// Skip files in the exclude list.
|
|
||||||
if self.exclude.matches_path(path) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ignore files not in the include list if it's present.
|
|
||||||
self
|
|
||||||
.include
|
|
||||||
.as_ref()
|
|
||||||
.map(|m| m.matches_path(path))
|
|
||||||
.unwrap_or(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a collection of `FilePatterns` by base where the containing patterns
|
|
||||||
/// are only the ones applicable to the base.
|
|
||||||
///
|
|
||||||
/// The order these are returned in is the order that the directory traversal
|
|
||||||
/// should occur in.
|
|
||||||
pub fn split_by_base(&self) -> Vec<(PathBuf, Self)> {
|
|
||||||
let Some(include) = &self.include else {
|
|
||||||
return Vec::new();
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut include_paths = Vec::new();
|
|
||||||
let mut include_patterns = Vec::new();
|
|
||||||
for path_or_pattern in &include.0 {
|
|
||||||
match path_or_pattern {
|
|
||||||
PathOrPattern::Path(path) => include_paths.push((path.is_file(), path)),
|
|
||||||
PathOrPattern::Pattern(pattern) => include_patterns.push(pattern),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let include_patterns_by_base_path = include_patterns.into_iter().fold(
|
|
||||||
IndexMap::new(),
|
|
||||||
|mut map: IndexMap<_, Vec<_>>, p| {
|
|
||||||
map.entry(p.base_path()).or_default().push(p);
|
|
||||||
map
|
|
||||||
},
|
|
||||||
);
|
|
||||||
let exclude_by_base_path = self
|
|
||||||
.exclude
|
|
||||||
.0
|
|
||||||
.iter()
|
|
||||||
.map(|s| (s.base_path(), s))
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
let get_applicable_excludes =
|
|
||||||
|is_file_path: bool, base_path: &PathBuf| -> Vec<PathOrPattern> {
|
|
||||||
exclude_by_base_path
|
|
||||||
.iter()
|
|
||||||
.filter_map(|(exclude_base_path, exclude)| {
|
|
||||||
match exclude {
|
|
||||||
PathOrPattern::Path(exclude_path) => {
|
|
||||||
// For explicitly specified files, ignore when the exclude path starts
|
|
||||||
// with it. Regardless, include excludes that are on a sub path of the dir.
|
|
||||||
if is_file_path && base_path.starts_with(exclude_path)
|
|
||||||
|| exclude_path.starts_with(base_path)
|
|
||||||
{
|
|
||||||
Some((*exclude).clone())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PathOrPattern::Pattern(_) => {
|
|
||||||
// include globs that's are sub paths or a parent path
|
|
||||||
if exclude_base_path.starts_with(base_path)
|
|
||||||
|| base_path.starts_with(exclude_base_path)
|
|
||||||
{
|
|
||||||
Some((*exclude).clone())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut result = Vec::with_capacity(
|
|
||||||
include_paths.len() + include_patterns_by_base_path.len(),
|
|
||||||
);
|
|
||||||
for (is_file, path) in include_paths {
|
|
||||||
let applicable_excludes = get_applicable_excludes(is_file, path);
|
|
||||||
result.push((
|
|
||||||
path.clone(),
|
|
||||||
Self {
|
|
||||||
include: Some(PathOrPatternSet::new(vec![PathOrPattern::Path(
|
|
||||||
path.clone(),
|
|
||||||
)])),
|
|
||||||
exclude: PathOrPatternSet::new(applicable_excludes),
|
|
||||||
},
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo(dsherret): This could be further optimized by not including
|
|
||||||
// patterns that will only ever match another base.
|
|
||||||
for base_path in include_patterns_by_base_path.keys() {
|
|
||||||
let applicable_excludes = get_applicable_excludes(false, base_path);
|
|
||||||
let mut applicable_includes = Vec::new();
|
|
||||||
// get all patterns that apply to the current or ancestor directories
|
|
||||||
for path in base_path.ancestors() {
|
|
||||||
if let Some(patterns) = include_patterns_by_base_path.get(path) {
|
|
||||||
applicable_includes.extend(
|
|
||||||
patterns
|
|
||||||
.iter()
|
|
||||||
.map(|p| PathOrPattern::Pattern((*p).clone())),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result.push((
|
|
||||||
base_path.clone(),
|
|
||||||
Self {
|
|
||||||
include: Some(PathOrPatternSet::new(applicable_includes)),
|
|
||||||
exclude: PathOrPatternSet::new(applicable_excludes),
|
|
||||||
},
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort by the longest base path first. This ensures that we visit opted into
|
|
||||||
// nested directories first before visiting the parent directory. The directory
|
|
||||||
// traverser will handle not going into directories it's already been in.
|
|
||||||
result.sort_by(|a, b| b.0.as_os_str().len().cmp(&a.0.as_os_str().len()));
|
|
||||||
|
|
||||||
result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Default, Debug, Eq, PartialEq)]
|
|
||||||
pub struct PathOrPatternSet(Vec<PathOrPattern>);
|
|
||||||
|
|
||||||
impl PathOrPatternSet {
|
|
||||||
pub fn new(elements: Vec<PathOrPattern>) -> Self {
|
|
||||||
Self(elements)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_absolute_paths(path: Vec<PathBuf>) -> Result<Self, AnyError> {
|
|
||||||
Ok(Self(
|
|
||||||
path
|
|
||||||
.into_iter()
|
|
||||||
.map(PathOrPattern::new)
|
|
||||||
.collect::<Result<Vec<_>, _>>()?,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn inner(&self) -> &Vec<PathOrPattern> {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn into_path_or_patterns(self) -> Vec<PathOrPattern> {
|
|
||||||
self.0
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn matches_path(&self, path: &Path) -> bool {
|
|
||||||
self.0.iter().any(|p| p.matches_path(path))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn base_paths(&self) -> Vec<PathBuf> {
|
|
||||||
let mut result = Vec::with_capacity(self.0.len());
|
|
||||||
for element in &self.0 {
|
|
||||||
match element {
|
|
||||||
PathOrPattern::Path(path) => {
|
|
||||||
result.push(path.to_path_buf());
|
|
||||||
}
|
|
||||||
PathOrPattern::Pattern(pattern) => {
|
|
||||||
result.push(pattern.base_path());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
||||||
pub enum PathOrPattern {
|
|
||||||
Path(PathBuf),
|
|
||||||
Pattern(GlobPattern),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PathOrPattern {
|
|
||||||
pub fn new(path: PathBuf) -> Result<Self, AnyError> {
|
|
||||||
let path_str = path.to_string_lossy();
|
|
||||||
// todo(dsherret): don't store URLs in PathBufs
|
|
||||||
if path_str.starts_with("http:")
|
|
||||||
|| path_str.starts_with("https:")
|
|
||||||
|| path_str.starts_with("file:")
|
|
||||||
{
|
|
||||||
return Ok(Self::Path(path));
|
|
||||||
}
|
|
||||||
|
|
||||||
GlobPattern::new_if_pattern(&path_str).map(|maybe_pattern| {
|
|
||||||
maybe_pattern
|
|
||||||
.map(PathOrPattern::Pattern)
|
|
||||||
.unwrap_or_else(|| PathOrPattern::Path(normalize_path(path)))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn matches_path(&self, path: &Path) -> bool {
|
|
||||||
match self {
|
|
||||||
PathOrPattern::Path(p) => path.starts_with(p),
|
|
||||||
PathOrPattern::Pattern(p) => p.matches_path(path),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn base_path(&self) -> PathBuf {
|
|
||||||
match self {
|
|
||||||
PathOrPattern::Path(p) => p.clone(),
|
|
||||||
PathOrPattern::Pattern(p) => p.base_path(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
|
||||||
pub struct GlobPattern(glob::Pattern);
|
|
||||||
|
|
||||||
impl GlobPattern {
|
|
||||||
pub fn new_if_pattern(pattern: &str) -> Result<Option<Self>, AnyError> {
|
|
||||||
if !is_glob_pattern(pattern) {
|
|
||||||
return Ok(None);
|
|
||||||
}
|
|
||||||
Self::new(pattern).map(Some)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new(pattern: &str) -> Result<Self, AnyError> {
|
|
||||||
let pattern = escape_brackets(pattern)
|
|
||||||
.replace('\\', "/")
|
|
||||||
.replace("/./", "/");
|
|
||||||
let pattern = glob::Pattern::new(&pattern)
|
|
||||||
.with_context(|| format!("Failed to expand glob: \"{}\"", pattern))?;
|
|
||||||
Ok(Self(pattern))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn matches_path(&self, path: &Path) -> bool {
|
|
||||||
self.0.matches_path_with(path, match_options())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn base_path(&self) -> PathBuf {
|
|
||||||
let base_path = self
|
|
||||||
.0
|
|
||||||
.as_str()
|
|
||||||
.split('/')
|
|
||||||
.take_while(|c| !has_glob_chars(c))
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.join(std::path::MAIN_SEPARATOR_STR);
|
|
||||||
PathBuf::from(base_path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_glob_pattern(path: &str) -> bool {
|
|
||||||
!path.starts_with("http:")
|
|
||||||
&& !path.starts_with("https:")
|
|
||||||
&& !path.starts_with("file:")
|
|
||||||
&& has_glob_chars(path)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn has_glob_chars(pattern: &str) -> bool {
|
|
||||||
// we don't support [ and ]
|
|
||||||
pattern.chars().any(|c| matches!(c, '*' | '?'))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn escape_brackets(pattern: &str) -> String {
|
|
||||||
// Escape brackets - we currently don't support them, because with introduction
|
|
||||||
// of glob expansion paths like "pages/[id].ts" would suddenly start giving
|
|
||||||
// wrong results. We might want to revisit that in the future.
|
|
||||||
pattern.replace('[', "[[]").replace(']', "[]]")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn match_options() -> glob::MatchOptions {
|
|
||||||
// Matches what `deno_task_shell` does
|
|
||||||
glob::MatchOptions {
|
|
||||||
// false because it should work the same way on case insensitive file systems
|
|
||||||
case_sensitive: false,
|
|
||||||
// true because it copies what sh does
|
|
||||||
require_literal_separator: true,
|
|
||||||
// true because it copies with sh does—these files are considered "hidden"
|
|
||||||
require_literal_leading_dot: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod test {
|
|
||||||
use pretty_assertions::assert_eq;
|
|
||||||
use test_util::TempDir;
|
|
||||||
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
// For easier comparisons in tests.
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
|
||||||
struct ComparableFilePatterns {
|
|
||||||
include: Option<Vec<String>>,
|
|
||||||
exclude: Vec<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ComparableFilePatterns {
|
|
||||||
pub fn new(root: &Path, file_patterns: &FilePatterns) -> Self {
|
|
||||||
fn path_or_pattern_to_string(root: &Path, p: &PathOrPattern) -> String {
|
|
||||||
match p {
|
|
||||||
PathOrPattern::Path(p) => p
|
|
||||||
.strip_prefix(root)
|
|
||||||
.unwrap()
|
|
||||||
.to_string_lossy()
|
|
||||||
.replace('\\', "/"),
|
|
||||||
PathOrPattern::Pattern(p) => p
|
|
||||||
.0
|
|
||||||
.as_str()
|
|
||||||
.strip_prefix(&format!(
|
|
||||||
"{}/",
|
|
||||||
root.to_string_lossy().replace('\\', "/")
|
|
||||||
))
|
|
||||||
.unwrap()
|
|
||||||
.to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Self {
|
|
||||||
include: file_patterns.include.as_ref().map(|p| {
|
|
||||||
p.0
|
|
||||||
.iter()
|
|
||||||
.map(|p| path_or_pattern_to_string(root, p))
|
|
||||||
.collect()
|
|
||||||
}),
|
|
||||||
exclude: file_patterns
|
|
||||||
.exclude
|
|
||||||
.0
|
|
||||||
.iter()
|
|
||||||
.map(|p| path_or_pattern_to_string(root, p))
|
|
||||||
.collect(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_split(
|
|
||||||
root: &Path,
|
|
||||||
patterns_by_base: &[(PathBuf, FilePatterns)],
|
|
||||||
) -> Vec<(String, ComparableFilePatterns)> {
|
|
||||||
patterns_by_base
|
|
||||||
.iter()
|
|
||||||
.map(|(base_path, file_patterns)| {
|
|
||||||
(
|
|
||||||
base_path
|
|
||||||
.strip_prefix(root)
|
|
||||||
.unwrap()
|
|
||||||
.to_string_lossy()
|
|
||||||
.replace('\\', "/"),
|
|
||||||
ComparableFilePatterns::new(root, file_patterns),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn should_split_globs_by_base_dir() {
|
|
||||||
let temp_dir = TempDir::new();
|
|
||||||
let patterns = FilePatterns {
|
|
||||||
include: Some(PathOrPatternSet::new(vec![
|
|
||||||
PathOrPattern::Pattern(
|
|
||||||
GlobPattern::new(&format!(
|
|
||||||
"{}/inner/**/*.ts",
|
|
||||||
temp_dir.path().to_string_lossy().replace('\\', "/")
|
|
||||||
))
|
|
||||||
.unwrap(),
|
|
||||||
),
|
|
||||||
PathOrPattern::Pattern(
|
|
||||||
GlobPattern::new(&format!(
|
|
||||||
"{}/inner/sub/deeper/**/*.js",
|
|
||||||
temp_dir.path().to_string_lossy().replace('\\', "/")
|
|
||||||
))
|
|
||||||
.unwrap(),
|
|
||||||
),
|
|
||||||
PathOrPattern::Pattern(
|
|
||||||
GlobPattern::new(&format!(
|
|
||||||
"{}/other/**/*.js",
|
|
||||||
temp_dir.path().to_string_lossy().replace('\\', "/")
|
|
||||||
))
|
|
||||||
.unwrap(),
|
|
||||||
),
|
|
||||||
PathOrPattern::Path(temp_dir.path().join("sub/file.ts").to_path_buf()),
|
|
||||||
])),
|
|
||||||
exclude: PathOrPatternSet::new(vec![
|
|
||||||
PathOrPattern::Pattern(
|
|
||||||
GlobPattern::new(&format!(
|
|
||||||
"{}/inner/other/**/*.ts",
|
|
||||||
temp_dir.path().to_string_lossy().replace('\\', "/")
|
|
||||||
))
|
|
||||||
.unwrap(),
|
|
||||||
),
|
|
||||||
PathOrPattern::Path(
|
|
||||||
temp_dir
|
|
||||||
.path()
|
|
||||||
.join("inner/sub/deeper/file.js")
|
|
||||||
.to_path_buf(),
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
};
|
|
||||||
let split = ComparableFilePatterns::from_split(
|
|
||||||
temp_dir.path().as_path(),
|
|
||||||
&patterns.split_by_base(),
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
split,
|
|
||||||
vec![
|
|
||||||
(
|
|
||||||
"inner/sub/deeper".to_string(),
|
|
||||||
ComparableFilePatterns {
|
|
||||||
include: Some(vec![
|
|
||||||
"inner/sub/deeper/**/*.js".to_string(),
|
|
||||||
"inner/**/*.ts".to_string(),
|
|
||||||
]),
|
|
||||||
exclude: vec!["inner/sub/deeper/file.js".to_string()],
|
|
||||||
}
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"sub/file.ts".to_string(),
|
|
||||||
ComparableFilePatterns {
|
|
||||||
include: Some(vec!["sub/file.ts".to_string()]),
|
|
||||||
exclude: vec![],
|
|
||||||
}
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"inner".to_string(),
|
|
||||||
ComparableFilePatterns {
|
|
||||||
include: Some(vec!["inner/**/*.ts".to_string()]),
|
|
||||||
exclude: vec![
|
|
||||||
"inner/other/**/*.ts".to_string(),
|
|
||||||
"inner/sub/deeper/file.js".to_string(),
|
|
||||||
],
|
|
||||||
}
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"other".to_string(),
|
|
||||||
ComparableFilePatterns {
|
|
||||||
include: Some(vec!["other/**/*.js".to_string()]),
|
|
||||||
exclude: vec![],
|
|
||||||
}
|
|
||||||
)
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -8,7 +8,6 @@ pub mod display;
|
||||||
pub mod draw_thread;
|
pub mod draw_thread;
|
||||||
pub mod file_watcher;
|
pub mod file_watcher;
|
||||||
pub mod fs;
|
pub mod fs;
|
||||||
pub mod glob;
|
|
||||||
pub mod import_map;
|
pub mod import_map;
|
||||||
pub mod logger;
|
pub mod logger;
|
||||||
pub mod path;
|
pub mod path;
|
||||||
|
|
Loading…
Reference in a new issue