1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-21 04:52:26 -05:00

remove need for outer factory

This commit is contained in:
Nayeem Rahman 2024-12-16 11:13:23 +00:00
parent 9a6263c1ce
commit 5d76fc9d3e
4 changed files with 258 additions and 282 deletions

View file

@ -93,6 +93,7 @@ use deno_runtime::deno_node::NodeResolver;
use deno_runtime::deno_node::PackageJsonResolver;
use deno_runtime::deno_permissions::Permissions;
use deno_runtime::deno_permissions::PermissionsContainer;
use deno_runtime::deno_permissions::PermissionsOptions;
use deno_runtime::deno_tls::rustls::RootCertStore;
use deno_runtime::deno_tls::RootCertStoreProvider;
use deno_runtime::deno_web::BlobStore;
@ -1075,33 +1076,99 @@ pub struct SpecifierInfo {
pub check_doc: bool,
}
struct WorkspaceFileContainerEntry {
pub struct WorkspaceDirFilesFactory {
specifiers: Vec<(ModuleSpecifier, SpecifierInfo)>,
doc_snippet_specifiers: Vec<ModuleSpecifier>,
factory: CliFactory,
worker_factory: Arc<CliMainWorkerFactory>,
cli_options: Arc<CliOptions>,
cli_factory: CliFactory,
permissions_options: Deferred<PermissionsOptions>,
}
impl WorkspaceFileContainerEntry {
fn checked_specifiers(&self) -> impl Iterator<Item = &ModuleSpecifier> {
impl WorkspaceDirFilesFactory {
pub fn checked_specifiers(&self) -> impl Iterator<Item = &ModuleSpecifier> {
self
.specifiers
.iter()
.filter_map(|(s, i)| i.check.then_some(s))
.chain(self.doc_snippet_specifiers.iter())
}
pub async fn dependent_checked_specifiers(
&self,
canonicalized_dep_paths: &HashSet<PathBuf>,
) -> Result<Vec<&ModuleSpecifier>, AnyError> {
let graph_kind = self
.cli_factory
.cli_options()?
.type_check_mode()
.as_graph_kind();
let module_graph_creator = self.cli_factory.module_graph_creator().await?;
let specifiers = self.checked_specifiers().cloned().collect::<Vec<_>>();
let graph = module_graph_creator
.create_graph(
graph_kind,
specifiers.clone(),
crate::graph_util::NpmCachingStrategy::Eager,
)
.await?;
module_graph_creator.graph_valid(&graph)?;
let dependent_specifiers = self
.checked_specifiers()
.filter(|s| {
let mut dependency_specifiers = graph.walk(
std::iter::once(*s),
deno_graph::WalkOptions {
follow_dynamic: true,
kind: deno_graph::GraphKind::All,
prefer_fast_check_graph: true,
check_js: true,
},
);
while let Some((s, _)) = dependency_specifiers.next() {
if let Ok(path) = url_to_file_path(s) {
if let Ok(path) = canonicalize_path(&path) {
if canonicalized_dep_paths.contains(&path) {
return true;
}
}
} else {
// skip walking this remote module's dependencies
dependency_specifiers.skip_previous_dependencies();
}
}
false
})
.collect();
Ok(dependent_specifiers)
}
pub fn permissions_options(&self) -> &PermissionsOptions {
self
.permissions_options
.get_or_init(|| self.cli_options.permissions_options())
}
pub fn permission_desc_parser(
&self,
) -> Result<&Arc<RuntimePermissionDescriptorParser>, AnyError> {
self.cli_factory.permission_desc_parser()
}
pub async fn create_cli_main_worker_factory(
&self,
) -> Result<CliMainWorkerFactory, AnyError> {
self.cli_factory.create_cli_main_worker_factory().await
}
}
pub struct WorkspaceFileContainer {
entries: Vec<WorkspaceFileContainerEntry>,
pub struct WorkspaceFilesFactory {
dirs: Vec<WorkspaceDirFilesFactory>,
}
impl WorkspaceFileContainer {
impl WorkspaceFilesFactory {
#[allow(clippy::type_complexity)]
pub async fn from_workspace_dirs_with_files<T: Clone>(
mut workspace_dirs_with_files: Vec<(Arc<WorkspaceDirectory>, FilePatterns)>,
factory: &CliFactory,
extract_doc_files: Option<fn(File) -> Result<Vec<File>, AnyError>>,
collect_specifiers: fn(
FilePatterns,
Arc<CliOptions>,
@ -1115,10 +1182,11 @@ impl WorkspaceFileContainer {
>,
>,
args: T,
extract_doc_files: Option<fn(File) -> Result<Vec<File>, AnyError>>,
cli_options: &CliOptions,
watcher_communicator: Option<&Arc<WatcherCommunicator>>,
) -> Result<Self, AnyError> {
workspace_dirs_with_files.sort_by_cached_key(|(d, _)| d.dir_url().clone());
let cli_options = factory.cli_options()?;
let watcher_communicator = &factory.watcher_communicator;
let all_scopes = Arc::new(
workspace_dirs_with_files
.iter()
@ -1127,7 +1195,7 @@ impl WorkspaceFileContainer {
.collect::<BTreeSet<_>>(),
);
let dir_count = workspace_dirs_with_files.len();
let mut entries = Vec::with_capacity(dir_count);
let mut dirs = Vec::with_capacity(dir_count);
for (workspace_dir, files) in workspace_dirs_with_files {
let scope_options = (dir_count > 1).then(|| ScopeOptions {
scope: workspace_dir
@ -1140,11 +1208,11 @@ impl WorkspaceFileContainer {
.with_new_start_dir_and_scope_options(workspace_dir, scope_options)?,
);
let mut factory = CliFactory::from_cli_options(cli_options.clone());
factory.watcher_communicator = watcher_communicator.clone();
factory.watcher_communicator = watcher_communicator.cloned();
let file_fetcher = factory.file_fetcher()?;
let specifiers = collect_specifiers(
files,
cli_options,
cli_options.clone(),
file_fetcher.clone(),
args.clone(),
)
@ -1161,30 +1229,32 @@ impl WorkspaceFileContainer {
}
}
}
let worker_factory =
Arc::new(factory.create_cli_main_worker_factory().await?);
entries.push(WorkspaceFileContainerEntry {
dirs.push(WorkspaceDirFilesFactory {
specifiers,
doc_snippet_specifiers,
factory,
worker_factory,
cli_options,
cli_factory: factory,
permissions_options: Default::default(),
});
}
Ok(Self { entries })
Ok(Self { dirs })
}
pub async fn check(&self) -> Result<(), AnyError> {
let mut diagnostics = vec![];
let mut all_errors = vec![];
for entry in &self.entries {
let main_graph_container =
entry.factory.main_module_graph_container().await?.clone();
for entry in &self.dirs {
let main_graph_container = entry
.cli_factory
.main_module_graph_container()
.await?
.clone();
let specifiers_for_typecheck =
entry.checked_specifiers().cloned().collect::<Vec<_>>();
if specifiers_for_typecheck.is_empty() {
continue;
}
let ext_flag = entry.factory.cli_options()?.ext_flag().as_ref();
let ext_flag = entry.cli_factory.cli_options()?.ext_flag().as_ref();
if let Err(err) = main_graph_container
.check_specifiers(&specifiers_for_typecheck, ext_flag)
.await
@ -1213,78 +1283,11 @@ impl WorkspaceFileContainer {
Ok(())
}
pub fn dirs(&self) -> &Vec<WorkspaceDirFilesFactory> {
&self.dirs
}
pub fn found_specifiers(&self) -> bool {
self.entries.iter().any(|e| !e.specifiers.is_empty())
}
pub fn worker_factories_with_checked_specifiers(
&self,
) -> Vec<(Arc<CliMainWorkerFactory>, Vec<ModuleSpecifier>)> {
self
.entries
.iter()
.map(|e| {
(
e.worker_factory.clone(),
e.checked_specifiers().cloned().collect(),
)
})
.collect()
}
/// Per workspace directory, return a list of included checked specifiers
/// which depend on the modules at the passed paths.
pub async fn worker_factories_with_dependent_checked_specifiers(
&self,
canonicalized_dep_paths: &HashSet<PathBuf>,
) -> Result<Vec<(Arc<CliMainWorkerFactory>, Vec<ModuleSpecifier>)>, AnyError>
{
let mut result = Vec::with_capacity(self.entries.len());
for entry in &self.entries {
let graph_kind = entry
.factory
.cli_options()?
.type_check_mode()
.as_graph_kind();
let module_graph_creator = entry.factory.module_graph_creator().await?;
let specifiers = entry.checked_specifiers().cloned().collect::<Vec<_>>();
let graph = module_graph_creator
.create_graph(
graph_kind,
specifiers.clone(),
crate::graph_util::NpmCachingStrategy::Eager,
)
.await?;
module_graph_creator.graph_valid(&graph)?;
let dependent_specifiers = specifiers
.into_iter()
.filter(|s| {
let mut dependency_specifiers = graph.walk(
std::iter::once(s),
deno_graph::WalkOptions {
follow_dynamic: true,
kind: deno_graph::GraphKind::All,
prefer_fast_check_graph: true,
check_js: true,
},
);
while let Some((s, _)) = dependency_specifiers.next() {
if let Ok(path) = url_to_file_path(s) {
if let Ok(path) = canonicalize_path(&path) {
if canonicalized_dep_paths.contains(&path) {
return true;
}
}
} else {
// skip walking this remote module's dependencies
dependency_specifiers.skip_previous_dependencies();
}
}
false
})
.collect::<Vec<_>>();
result.push((entry.worker_factory.clone(), dependent_specifiers));
}
Ok(result)
self.dirs.iter().any(|e| !e.specifiers.is_empty())
}
}

View file

@ -1,12 +1,12 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use crate::args::BenchFlags;
use crate::args::CliOptions;
use crate::args::Flags;
use crate::colors;
use crate::display::write_json_to_stdout;
use crate::factory::CliFactory;
use crate::factory::SpecifierInfo;
use crate::factory::WorkspaceFileContainer;
use crate::factory::WorkspaceFilesFactory;
use crate::ops;
use crate::tools::test::format_test_error;
use crate::tools::test::TestFilter;
@ -32,7 +32,6 @@ use deno_core::ModuleSpecifier;
use deno_core::PollEventLoopOptions;
use deno_runtime::deno_permissions::Permissions;
use deno_runtime::deno_permissions::PermissionsContainer;
use deno_runtime::permissions::RuntimePermissionDescriptorParser;
use deno_runtime::tokio_util::create_and_run_current_thread;
use deno_runtime::WorkerExecutionMode;
use indexmap::IndexMap;
@ -40,7 +39,9 @@ use indexmap::IndexSet;
use log::Level;
use serde::Deserialize;
use serde::Serialize;
use std::collections::HashSet;
use std::path::Path;
use std::path::PathBuf;
use std::sync::Arc;
use std::time::Duration;
use tokio::sync::mpsc::unbounded_channel;
@ -264,29 +265,42 @@ async fn bench_specifier_inner(
/// Test a collection of specifiers with test modes concurrently.
async fn bench_specifiers(
factories_with_specifiers: Vec<(
Arc<CliMainWorkerFactory>,
Vec<ModuleSpecifier>,
)>,
permissions: &Permissions,
permissions_desc_parser: &Arc<RuntimePermissionDescriptorParser>,
workspace_files_factory: &WorkspaceFilesFactory,
changed_paths: Option<&HashSet<PathBuf>>,
options: BenchSpecifierOptions,
) -> Result<(), AnyError> {
let specifiers_with_factory = factories_with_specifiers
.into_iter()
.flat_map(|(f, s)| {
s.into_iter().map(|s| (s, f.clone())).collect::<Vec<_>>()
})
.collect::<Vec<_>>();
let mut specifiers_with_services = vec![];
for factory in workspace_files_factory.dirs() {
let worker_factory =
Arc::new(factory.create_cli_main_worker_factory().await?);
let permission_desc_parser = factory.permission_desc_parser()?;
let permissions = Arc::new(Permissions::from_options(
permission_desc_parser.as_ref(),
factory.permissions_options(),
)?);
let specifiers = if let Some(changed_paths) = changed_paths {
factory.dependent_checked_specifiers(changed_paths).await?
} else {
factory.checked_specifiers().collect()
};
specifiers_with_services.extend(specifiers.into_iter().map(|s| {
(
s.clone(),
worker_factory.clone(),
permission_desc_parser.clone(),
permissions.clone(),
)
}));
}
let (sender, mut receiver) = unbounded_channel::<BenchEvent>();
let log_level = options.log_level;
let option_for_handles = options.clone();
let join_handles = specifiers_with_factory.into_iter().map(
move |(specifier, worker_factory)| {
let join_handles = specifiers_with_services.into_iter().map(
move |(specifier, worker_factory, permissions_desc_parser, permissions)| {
let permissions_container = PermissionsContainer::new(
permissions_desc_parser.clone(),
permissions.clone(),
permissions.as_ref().clone(),
);
let sender = sender.clone();
let options = option_for_handles.clone();
@ -418,18 +432,9 @@ pub async fn run_benchmarks(
flags: Arc<Flags>,
bench_flags: BenchFlags,
) -> Result<(), AnyError> {
let factory = CliFactory::from_flags(flags);
let cli_options = factory.cli_options()?;
let cli_options = CliOptions::from_flags(flags)?;
let workspace_bench_options =
cli_options.resolve_workspace_bench_options(&bench_flags);
// Various bench files should not share the same permissions in terms of
// `PermissionsContainer` - otherwise granting/revoking permissions in one
// file would have impact on other files, which is undesirable.
let permission_desc_parser = factory.permission_desc_parser()?;
let permissions = Permissions::from_options(
permission_desc_parser.as_ref(),
&cli_options.permissions_options(),
)?;
let log_level = cli_options.log_level();
let workspace_dirs_with_files = cli_options
@ -437,42 +442,43 @@ pub async fn run_benchmarks(
.into_iter()
.map(|(d, o)| (d, o.files))
.collect();
let file_container = WorkspaceFileContainer::from_workspace_dirs_with_files(
workspace_dirs_with_files,
&factory,
None,
|patterns, cli_options, _, _| {
async move {
let info = SpecifierInfo {
check: true,
check_doc: false,
};
collect_specifiers(
patterns,
cli_options.vendor_dir_path().map(ToOwned::to_owned),
is_supported_bench_path,
)
.map(|s| s.into_iter().map(|s| (s, info)).collect())
}
.boxed_local()
},
(),
)
.await?;
if !file_container.found_specifiers() {
let workspace_files_factory =
WorkspaceFilesFactory::from_workspace_dirs_with_files(
workspace_dirs_with_files,
|patterns, cli_options, _, _| {
async move {
let info = SpecifierInfo {
check: true,
check_doc: false,
};
collect_specifiers(
patterns,
cli_options.vendor_dir_path().map(ToOwned::to_owned),
is_supported_bench_path,
)
.map(|s| s.into_iter().map(|s| (s, info)).collect())
}
.boxed_local()
},
(),
None,
&cli_options,
None,
)
.await?;
if !workspace_files_factory.found_specifiers() {
return Err(generic_error("No test modules found"));
}
file_container.check().await?;
workspace_files_factory.check().await?;
if workspace_bench_options.no_run {
return Ok(());
}
bench_specifiers(
file_container.worker_factories_with_checked_specifiers(),
&permissions,
permission_desc_parser,
&workspace_files_factory,
None,
BenchSpecifierOptions {
filter: TestFilter::from_flag(&workspace_bench_options.filter),
json: workspace_bench_options.json,
@ -502,18 +508,9 @@ pub async fn run_benchmarks_with_watch(
let bench_flags = bench_flags.clone();
watcher_communicator.show_path_changed(changed_paths.clone());
Ok(async move {
let factory = CliFactory::from_flags_for_watcher(
flags,
watcher_communicator.clone(),
);
let cli_options = factory.cli_options()?;
let cli_options = CliOptions::from_flags(flags)?;
let workspace_bench_options =
cli_options.resolve_workspace_bench_options(&bench_flags);
let permission_desc_parser = factory.permission_desc_parser()?;
let permissions = Permissions::from_options(
permission_desc_parser.as_ref(),
&cli_options.permissions_options(),
)?;
let log_level = cli_options.log_level();
let _ = watcher_communicator.watch_paths(cli_options.watch_paths());
@ -530,11 +527,9 @@ pub async fn run_benchmarks_with_watch(
.flatten()
.collect::<Vec<_>>();
let _ = watcher_communicator.watch_paths(watch_paths);
let file_container =
WorkspaceFileContainer::from_workspace_dirs_with_files(
let workspace_files_factory =
WorkspaceFilesFactory::from_workspace_dirs_with_files(
workspace_dirs_with_files,
&factory,
None,
|patterns, cli_options, _, _| {
async move {
let info = SpecifierInfo {
@ -551,30 +546,21 @@ pub async fn run_benchmarks_with_watch(
.boxed_local()
},
(),
None,
&cli_options,
Some(&watcher_communicator),
)
.await?;
file_container.check().await?;
workspace_files_factory.check().await?;
if workspace_bench_options.no_run {
return Ok(());
}
let factories_with_specifiers =
if let Some(changed_paths) = changed_paths {
file_container
.worker_factories_with_dependent_checked_specifiers(
&changed_paths.into_iter().collect(),
)
.await?
} else {
file_container.worker_factories_with_checked_specifiers()
};
bench_specifiers(
factories_with_specifiers,
&permissions,
permission_desc_parser,
&workspace_files_factory,
changed_paths.map(|p| p.into_iter().collect()).as_ref(),
BenchSpecifierOptions {
filter: TestFilter::from_flag(&workspace_bench_options.filter),
json: workspace_bench_options.json,

View file

@ -30,9 +30,8 @@ use crate::cache::CacheDBHash;
use crate::cache::Caches;
use crate::cache::FastInsecureHasher;
use crate::cache::TypeCheckCache;
use crate::factory::CliFactory;
use crate::factory::SpecifierInfo;
use crate::factory::WorkspaceFileContainer;
use crate::factory::WorkspaceFilesFactory;
use crate::graph_util::BuildFastCheckGraphOptions;
use crate::graph_util::ModuleGraphBuilder;
use crate::npm::CliNpmResolver;
@ -48,39 +47,40 @@ pub async fn check(
flags: Arc<Flags>,
check_flags: CheckFlags,
) -> Result<(), AnyError> {
let factory = CliFactory::from_flags(flags);
let cli_options = factory.cli_options()?;
let cli_options = CliOptions::from_flags(flags)?;
let workspace_dirs_with_files =
cli_options.resolve_file_flags_for_members(&FileFlags {
ignore: Default::default(),
include: check_flags.files,
})?;
let file_container = WorkspaceFileContainer::from_workspace_dirs_with_files(
workspace_dirs_with_files,
&factory,
Some(extract_snippet_files),
|patterns, cli_options, _, (doc, doc_only)| {
async move {
let info = SpecifierInfo {
check: !doc_only,
check_doc: doc || doc_only,
};
collect_specifiers(
patterns,
cli_options.vendor_dir_path().map(ToOwned::to_owned),
|e| is_script_ext(e.path),
)
.map(|s| s.into_iter().map(|s| (s, info)).collect())
}
.boxed_local()
},
(check_flags.doc, check_flags.doc_only),
)
.await?;
if !file_container.found_specifiers() {
let workspace_files_factory =
WorkspaceFilesFactory::from_workspace_dirs_with_files(
workspace_dirs_with_files,
|patterns, cli_options, _, (doc, doc_only)| {
async move {
let info = SpecifierInfo {
check: !doc_only,
check_doc: doc || doc_only,
};
collect_specifiers(
patterns,
cli_options.vendor_dir_path().map(ToOwned::to_owned),
|e| is_script_ext(e.path),
)
.map(|s| s.into_iter().map(|s| (s, info)).collect())
}
.boxed_local()
},
(check_flags.doc, check_flags.doc_only),
Some(extract_snippet_files),
&cli_options,
None,
)
.await?;
if !workspace_files_factory.found_specifiers() {
log::warn!("{} No matching files found.", colors::yellow("Warning"));
}
file_container.check().await
workspace_files_factory.check().await
}
/// Options for performing a check of a module graph. Note that the decision to

View file

@ -6,9 +6,8 @@ use crate::args::TestFlags;
use crate::args::TestReporterConfig;
use crate::colors;
use crate::display;
use crate::factory::CliFactory;
use crate::factory::SpecifierInfo;
use crate::factory::WorkspaceFileContainer;
use crate::factory::WorkspaceFilesFactory;
use crate::file_fetcher::FileFetcher;
use crate::ops;
use crate::util::extract::extract_doc_tests;
@ -53,7 +52,6 @@ use deno_runtime::deno_io::StdioPipe;
use deno_runtime::deno_permissions::Permissions;
use deno_runtime::deno_permissions::PermissionsContainer;
use deno_runtime::fmt_errors::format_js_error;
use deno_runtime::permissions::RuntimePermissionDescriptorParser;
use deno_runtime::tokio_util::create_and_run_current_thread;
use deno_runtime::worker::MainWorker;
use deno_runtime::WorkerExecutionMode;
@ -77,6 +75,7 @@ use std::future::poll_fn;
use std::io::Write;
use std::num::NonZeroUsize;
use std::path::Path;
use std::path::PathBuf;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering;
@ -1163,24 +1162,37 @@ static HAS_TEST_RUN_SIGINT_HANDLER: AtomicBool = AtomicBool::new(false);
/// Test a collection of specifiers with test modes concurrently.
async fn test_specifiers(
factories_with_specifiers: Vec<(
Arc<CliMainWorkerFactory>,
Vec<ModuleSpecifier>,
)>,
permissions: &Permissions,
permission_desc_parser: &Arc<RuntimePermissionDescriptorParser>,
workspace_files_factory: &WorkspaceFilesFactory,
changed_paths: Option<&HashSet<PathBuf>>,
options: TestSpecifiersOptions,
) -> Result<(), AnyError> {
let mut specifiers_with_factory = factories_with_specifiers
.into_iter()
.flat_map(|(f, s)| {
s.into_iter().map(|s| (s, f.clone())).collect::<Vec<_>>()
})
.collect::<Vec<_>>();
let mut specifiers_with_services = vec![];
for factory in workspace_files_factory.dirs() {
let worker_factory =
Arc::new(factory.create_cli_main_worker_factory().await?);
let permission_desc_parser = factory.permission_desc_parser()?;
let permissions = Arc::new(Permissions::from_options(
permission_desc_parser.as_ref(),
factory.permissions_options(),
)?);
let specifiers = if let Some(changed_paths) = changed_paths {
factory.dependent_checked_specifiers(changed_paths).await?
} else {
factory.checked_specifiers().collect()
};
specifiers_with_services.extend(specifiers.into_iter().map(|s| {
(
s.clone(),
worker_factory.clone(),
permission_desc_parser.clone(),
permissions.clone(),
)
}));
}
if let Some(seed) = options.specifier.shuffle {
let mut rng = SmallRng::seed_from_u64(seed);
specifiers_with_factory.sort_by_cached_key(|(s, _)| s.to_string());
specifiers_with_factory.shuffle(&mut rng);
specifiers_with_services.sort_by_cached_key(|(s, ..)| s.to_string());
specifiers_with_services.shuffle(&mut rng);
}
let (test_event_sender_factory, receiver) = create_test_event_channel();
@ -1195,11 +1207,11 @@ async fn test_specifiers(
let reporter = get_test_reporter(&options);
let fail_fast_tracker = FailFastTracker::new(options.fail_fast);
let join_handles = specifiers_with_factory.into_iter().map(
move |(specifier, worker_factory)| {
let join_handles = specifiers_with_services.into_iter().map(
move |(specifier, worker_factory, permission_desc_parser, permissions)| {
let permissions_container = PermissionsContainer::new(
permission_desc_parser.clone(),
permissions.clone(),
permission_desc_parser,
permissions.as_ref().clone(),
);
let worker_sender = test_event_sender_factory.worker();
let fail_fast_tracker = fail_fast_tracker.clone();
@ -1485,18 +1497,12 @@ pub async fn run_tests(
flags: Arc<Flags>,
test_flags: TestFlags,
) -> Result<(), AnyError> {
let factory = CliFactory::from_flags(flags);
let cli_options = factory.cli_options()?;
let cli_options = CliOptions::from_flags(flags)?;
let workspace_test_options =
cli_options.resolve_workspace_test_options(&test_flags);
// Various test files should not share the same permissions in terms of
// `PermissionsContainer` - otherwise granting/revoking permissions in one
// file would have impact on other files, which is undesirable.
let permission_desc_parser = factory.permission_desc_parser()?;
let permissions = Permissions::from_options(
permission_desc_parser.as_ref(),
&cli_options.permissions_options(),
)?;
let log_level = cli_options.log_level();
let workspace_dirs_with_files = cli_options
@ -1504,33 +1510,34 @@ pub async fn run_tests(
.into_iter()
.map(|(d, o)| (d, o.files))
.collect();
let file_container = WorkspaceFileContainer::from_workspace_dirs_with_files(
workspace_dirs_with_files,
&factory,
Some(extract_doc_tests),
|patterns, cli_options, file_fetcher, doc| {
collect_specifiers_for_tests(patterns, cli_options, file_fetcher, doc)
.boxed_local()
},
workspace_test_options.doc,
)
.await?;
let workspace_files_factory =
WorkspaceFilesFactory::from_workspace_dirs_with_files(
workspace_dirs_with_files,
|patterns, cli_options, file_fetcher, doc| {
collect_specifiers_for_tests(patterns, cli_options, file_fetcher, doc)
.boxed_local()
},
workspace_test_options.doc,
Some(extract_doc_tests),
&cli_options,
None,
)
.await?;
if !workspace_test_options.permit_no_files
&& !file_container.found_specifiers()
&& !workspace_files_factory.found_specifiers()
{
return Err(generic_error("No test modules found"));
}
file_container.check().await?;
workspace_files_factory.check().await?;
if workspace_test_options.no_run {
return Ok(());
}
test_specifiers(
file_container.worker_factories_with_checked_specifiers(),
&permissions,
permission_desc_parser,
&workspace_files_factory,
None,
TestSpecifiersOptions {
cwd: Url::from_directory_path(cli_options.initial_cwd()).map_err(
|_| {
@ -1591,18 +1598,9 @@ pub async fn run_tests_with_watch(
let test_flags = test_flags.clone();
watcher_communicator.show_path_changed(changed_paths.clone());
Ok(async move {
let factory = CliFactory::from_flags_for_watcher(
flags,
watcher_communicator.clone(),
);
let cli_options = factory.cli_options()?;
let cli_options = CliOptions::from_flags(flags)?;
let workspace_test_options =
cli_options.resolve_workspace_test_options(&test_flags);
let permission_desc_parser = factory.permission_desc_parser()?;
let permissions = Permissions::from_options(
permission_desc_parser.as_ref(),
&cli_options.permissions_options(),
)?;
let log_level = cli_options.log_level();
let _ = watcher_communicator.watch_paths(cli_options.watch_paths());
@ -1619,11 +1617,9 @@ pub async fn run_tests_with_watch(
.flatten()
.collect::<Vec<_>>();
let _ = watcher_communicator.watch_paths(watch_paths);
let file_container =
WorkspaceFileContainer::from_workspace_dirs_with_files(
let workspace_files_factory =
WorkspaceFilesFactory::from_workspace_dirs_with_files(
workspace_dirs_with_files,
&factory,
Some(extract_doc_tests),
|patterns, cli_options, file_fetcher, doc| {
collect_specifiers_for_tests(
patterns,
@ -1634,30 +1630,21 @@ pub async fn run_tests_with_watch(
.boxed_local()
},
workspace_test_options.doc,
Some(extract_doc_tests),
&cli_options,
Some(&watcher_communicator),
)
.await?;
file_container.check().await?;
workspace_files_factory.check().await?;
if workspace_test_options.no_run {
return Ok(());
}
let factories_with_specifiers =
if let Some(changed_paths) = changed_paths {
file_container
.worker_factories_with_dependent_checked_specifiers(
&changed_paths.into_iter().collect(),
)
.await?
} else {
file_container.worker_factories_with_checked_specifiers()
};
test_specifiers(
factories_with_specifiers,
&permissions,
permission_desc_parser,
&workspace_files_factory,
changed_paths.map(|p| p.into_iter().collect()).as_ref(),
TestSpecifiersOptions {
cwd: Url::from_directory_path(cli_options.initial_cwd()).map_err(
|_| {