Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat: compiler options from workspace member #143

Open
wants to merge 22 commits into
base: main
Choose a base branch
from
Open
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
271 changes: 183 additions & 88 deletions src/workspace/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ use crate::deno_json::LintOptionsConfig;
use crate::deno_json::LintRulesConfig;
use crate::deno_json::NodeModulesDirMode;
use crate::deno_json::NodeModulesDirParseError;
use crate::deno_json::ParsedTsConfigOptions;
use crate::deno_json::PatchConfigParseError;
use crate::deno_json::PublishConfig;
pub use crate::deno_json::TaskDefinition;
Expand Down Expand Up @@ -609,12 +608,6 @@ impl Workspace {
member_config: &ConfigFile,
diagnostics: &mut Vec<WorkspaceDiagnostic>,
) {
if member_config.json.compiler_options.is_some() {
diagnostics.push(WorkspaceDiagnostic {
config_url: member_config.specifier.clone(),
kind: WorkspaceDiagnosticKind::RootOnlyOption("compilerOptions"),
});
}
if member_config.json.import_map.is_some() {
diagnostics.push(WorkspaceDiagnostic {
config_url: member_config.specifier.clone(),
Expand Down Expand Up @@ -762,25 +755,10 @@ impl Workspace {
diagnostics
}

pub fn check_js(&self) -> bool {
self
.with_root_config_only(|root_config| root_config.get_check_js())
.unwrap_or(false)
}

pub fn vendor_dir_path(&self) -> Option<&PathBuf> {
self.vendor_dir.as_ref()
}

pub fn to_compiler_options(
&self,
) -> Result<Option<ParsedTsConfigOptions>, AnyError> {
self
.with_root_config_only(|root_config| root_config.to_compiler_options())
.map(|o| o.map(Some))
.unwrap_or(Ok(None))
}

pub fn to_lint_config(&self) -> Result<WorkspaceLintConfig, AnyError> {
self
.with_root_config_only(|root_config| {
Expand Down Expand Up @@ -808,16 +786,6 @@ impl Workspace {
.unwrap_or(Ok(Default::default()))
}

pub fn resolve_ts_config_for_emit(
&self,
config_type: TsConfigType,
) -> Result<TsConfigForEmit, AnyError> {
get_ts_config_for_emit(
config_type,
self.root_deno_json().map(|c| c.as_ref()),
)
}

pub fn to_import_map_path(&self) -> Result<Option<PathBuf>, AnyError> {
self
.with_root_config_only(|root_config| root_config.to_import_map_path())
Expand All @@ -834,24 +802,13 @@ impl Workspace {
}
}

pub fn to_compiler_option_types(
pub fn resolve_file_patterns_for_members(
self: &WorkspaceRc,
) -> Result<Vec<(Url, Vec<String>)>, AnyError> {
self
.with_root_config_only(|root_config| {
root_config.to_compiler_option_types()
})
.unwrap_or(Ok(Vec::new()))
}

pub fn to_maybe_jsx_import_source_config(
self: &WorkspaceRc,
) -> Result<Option<JsxImportSourceConfig>, AnyError> {
self
.with_root_config_only(|root_config| {
root_config.to_maybe_jsx_import_source_config()
})
.unwrap_or(Ok(None))
cli_args: &FilePatterns,
) -> Result<Vec<(WorkspaceDirectory, FilePatterns)>, AnyError> {
self.resolve_config_for_members(cli_args, |dir, patterns| {
dir.to_resolved_file_patterns(patterns)
})
}

pub fn resolve_bench_config_for_members(
Expand Down Expand Up @@ -1369,6 +1326,47 @@ impl WorkspaceDirectory {
})
}

fn deno_json_for_compiler_options(&self) -> Option<&ConfigFileRc> {
self
.maybe_deno_json()
.filter(|c| c.json.compiler_options.is_some())
.or_else(|| self.workspace.root_deno_json())
.filter(|c| c.json.compiler_options.is_some())
}

pub fn check_js(&self) -> bool {
self
.deno_json_for_compiler_options()
.map(|c| c.get_check_js())
.unwrap_or(false)
}

pub fn to_ts_config_for_emit(
&self,
config_type: TsConfigType,
) -> Result<TsConfigForEmit, AnyError> {
let deno_json = self.deno_json_for_compiler_options();
get_ts_config_for_emit(config_type, deno_json.map(|c| c.as_ref()))
}

pub fn to_compiler_option_types(
&self,
) -> Result<Vec<(Url, Vec<String>)>, AnyError> {
self
.deno_json_for_compiler_options()
.map(|c| c.to_compiler_option_types())
.unwrap_or(Ok(Vec::new()))
}

pub fn to_maybe_jsx_import_source_config(
&self,
) -> Result<Option<JsxImportSourceConfig>, AnyError> {
self
.deno_json_for_compiler_options()
.map(|c| c.to_maybe_jsx_import_source_config())
.unwrap_or(Ok(None))
}

pub fn to_lint_config(
&self,
cli_args: FilePatterns,
Expand Down Expand Up @@ -1483,6 +1481,28 @@ impl WorkspaceDirectory {
})
}

pub fn to_resolved_file_patterns(
&self,
cli_args: FilePatterns,
) -> Result<FilePatterns, AnyError> {
let Some(deno_json) = self.deno_json.as_ref() else {
return Ok(FilePatterns::new_with_base(
url_to_file_path(&self.dir_url).unwrap(),
));
};
let member_patterns = deno_json.member.to_exclude_files_config()?;
let mut patterns = match &deno_json.root {
Some(root) => {
combine_patterns(root.to_exclude_files_config()?, member_patterns)
}
None => member_patterns,
};
self.exclude_includes_with_member_for_base_for_root(&mut patterns);
combine_files_config_with_cli_args(&mut patterns, cli_args);
self.append_workspace_members_to_exclude(&mut patterns);
Ok(patterns)
}

pub fn to_bench_config(
&self,
cli_args: FilePatterns,
Expand Down Expand Up @@ -2303,62 +2323,45 @@ mod test {
#[test]
fn test_root_member_compiler_options() {
let workspace_dir = workspace_for_root_and_member(
json!({
"compilerOptions": {
"checkJs": false
},
}),
json!({
"compilerOptions": {
"checkJs": true,
"types": ["./types.d.ts"],
"jsx": "react-jsx",
"jsxImportSource": "npm:react",
"jsxImportSourceTypes": "npm:@types/react",
}
}),
json!({
"compilerOptions": {
"checkJs": false
}
},
}),
);
assert_eq!(
workspace_dir
.workspace
.to_compiler_options()
.unwrap()
.unwrap()
.options,
*json!({
// ignores member config
"checkJs": true,
"jsx": "react-jsx",
"jsxImportSource": "npm:react",
})
.as_object()
.unwrap()
);
assert_eq!(
workspace_dir.workspace.to_compiler_option_types().unwrap(),
workspace_dir.to_compiler_option_types().unwrap(),
vec![(
Url::from_file_path(root_dir().join("deno.json")).unwrap(),
Url::from_file_path(root_dir().join("member/deno.json")).unwrap(),
vec!["./types.d.ts".to_string()]
)]
)],
);
assert_eq!(
workspace_dir
.workspace
.to_maybe_jsx_import_source_config()
.unwrap()
.unwrap(),
JsxImportSourceConfig {
default_specifier: Some("npm:react".to_string()),
default_types_specifier: Some("npm:@types/react".to_string()),
module: "jsx-runtime".to_string(),
base_url: Url::from_file_path(root_dir().join("deno.json")).unwrap(),
}
base_url: Url::from_file_path(root_dir().join("member/deno.json"))
.unwrap(),
},
);
assert_eq!(workspace_dir.workspace.check_js(), true);
assert_eq!(workspace_dir.check_js(), true);
assert_eq!(
workspace_dir
.workspace
.resolve_ts_config_for_emit(TsConfigType::Emit)
.to_ts_config_for_emit(TsConfigType::Emit)
.unwrap(),
TsConfigForEmit {
ts_config: TsConfig(json!({
Expand All @@ -2381,14 +2384,7 @@ mod test {
maybe_ignored_options: None,
}
);
assert_eq!(
workspace_dir.workspace.diagnostics(),
vec![WorkspaceDiagnostic {
kind: WorkspaceDiagnosticKind::RootOnlyOption("compilerOptions"),
config_url: Url::from_file_path(root_dir().join("member/deno.json"))
.unwrap(),
}]
);
assert_eq!(workspace_dir.workspace.diagnostics(), vec![]);
}

#[test]
Expand Down Expand Up @@ -4789,6 +4785,105 @@ mod test {
}
}

#[test]
fn test_resolve_file_patterns_for_members() {
let mut fs = TestFileSystem::default();
fs.insert_json(
root_dir().join("deno.json"),
json!({
"workspace": ["./member-a", "./member-b", "member-c"],
"exclude": ["./excluded.ts", "./member-b/excluded.ts", "./member-c/excluded"],
}),
);
fs.insert_json(
root_dir().join("member-a/deno.json"),
json!({
"exclude": ["./excluded.ts"],
}),
);
fs.insert_json(root_dir().join("member-b/deno.json"), json!({}));
fs.insert_json(root_dir().join("member-c/deno.json"), json!({}));
let workspace_dir = workspace_at_start_dir(&fs, &root_dir());
let mut patterns_by_dir = workspace_dir
.workspace
.resolve_file_patterns_for_members(&FilePatterns {
base: root_dir(),
include: Some(
PathOrPatternSet::from_include_relative_path_or_patterns(
&root_dir(),
&[
"file.ts".to_string(),
"excluded.ts".to_string(),
"member-a/file.ts".to_string(),
"member-a/excluded.ts".to_string(),
"member-b/file.ts".to_string(),
"member-b/excluded.ts".to_string(),
"member-c/folder/file.ts".to_string(),
"member-c/excluded/file.ts".to_string(),
],
)
.unwrap(),
),
exclude: Default::default(),
})
.unwrap();
patterns_by_dir.sort_by_cached_key(|(d, _)| d.dir_url().clone());
let patterns = patterns_by_dir
.into_iter()
.map(|(_, p)| p)
.collect::<Vec<_>>();
assert_eq!(
patterns,
vec![
FilePatterns {
base: root_dir(),
include: Some(PathOrPatternSet::new(vec![
PathOrPattern::Path(root_dir().join("file.ts")),
PathOrPattern::Path(root_dir().join("excluded.ts")),
])),
exclude: PathOrPatternSet::new(vec![
PathOrPattern::Path(root_dir().join("excluded.ts")),
PathOrPattern::Path(root_dir().join("member-b/excluded.ts")),
PathOrPattern::Path(root_dir().join("member-c/excluded")),
PathOrPattern::Path(root_dir().join("member-a")),
PathOrPattern::Path(root_dir().join("member-b")),
PathOrPattern::Path(root_dir().join("member-c")),
]),
},
FilePatterns {
base: root_dir().join("member-a"),
include: Some(PathOrPatternSet::new(vec![
PathOrPattern::Path(root_dir().join("member-a/file.ts")),
PathOrPattern::Path(root_dir().join("member-a/excluded.ts")),
])),
exclude: PathOrPatternSet::new(vec![PathOrPattern::Path(
root_dir().join("member-a/excluded.ts")
),]),
},
FilePatterns {
base: root_dir().join("member-b"),
include: Some(PathOrPatternSet::new(vec![
PathOrPattern::Path(root_dir().join("member-b/file.ts")),
PathOrPattern::Path(root_dir().join("member-b/excluded.ts")),
])),
exclude: PathOrPatternSet::new(vec![PathOrPattern::Path(
root_dir().join("member-b/excluded.ts")
),]),
},
FilePatterns {
base: root_dir().join("member-c"),
include: Some(PathOrPatternSet::new(vec![
PathOrPattern::Path(root_dir().join("member-c/excluded/file.ts")),
PathOrPattern::Path(root_dir().join("member-c/folder/file.ts")),
])),
exclude: PathOrPatternSet::new(vec![PathOrPattern::Path(
root_dir().join("member-c/excluded")
),]),
},
]
);
}

#[test]
fn test_resolve_config_for_members_include_root_and_sub_member() {
fn run_test(
Expand Down