-
Notifications
You must be signed in to change notification settings - Fork 5.2k
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: auto-discover config file #13313
Conversation
cli/config_file.rs
Outdated
for f in flags.config_path_args() { | ||
if let Some(cf) = discover_inner(&f, &mut checked)? { | ||
return Ok(Some(cf)); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a bit unexpected - IIRC the algorithm we agreed upon was supposed to find a config file for each of the passed arguments, not a config file that was found first. Could you clarify this @ry?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've been thinking about this more just now and I think this goes beyond what we've discussed in the past. I'm wondering if when running deno fmt
or deno lint
should we have deno.json
files in sub directories be resepected when there's a deno.json
in an ancestor directory.
For example, say you have:
sub_dir
- deno.json
- file.ts
deno.json
- Should running
deno fmt
have the same behaviour onfile.ts
as runningdeno fmt sub_dir/file.ts
? - Should running
deno fmt sub_dir/file.ts
have the same behaviour as running(cd sub_dir && deno fmt file.ts)
?
I can think of a few options:
Option 1: Resolve based on closest deno.json from file path
This option would mean for deno fmt
and deno lint
along with deno fmt <file-path>
, it would always resolve a config file based on the closest deno.json. So includes/excludes in parent deno.json
s would be ignored.
- Fmt/lint option resolution: Each config file resolves from the default options
- Includes/excludes: Each config file resolves from the default options
- Run options: Resolved from closest ancestor deno.json (Same as Option 3)
Personally, I think this is the best option and is the least complex for users to understand. It answers yes to both the questions I asked above.
Option 2: Resolve using resolution from all deno.json files in ancestor directories from file path
This would require resolving all deno.json files in all ancestor directories, then use that information to figure out the fmt/lint options and includes/excludes for a folder based on the combined result of all config files.
- Fmt/lint option resolution: Each config file resolves from the ancestor directory's options
- Includes/excludes: Each config file resolves from the ancestor directory's includes/excludes and overrides it.
- Run options: Requires resolution of each ancestor config and then a resolution to the final options by combining configs.
This would be complex to implement. It answers yes to both the questions I asked above.
Option 3: Use config file resolved for root of each disjointed tree
By "disjointed tree" I mean, directory sub trees that share no common directories from the root with other directory trees. Maybe there is a better word?
This would resolve the config file for each disjointed tree. So deno fmt
would resolve based on the cwd and use that, but deno fmt ./child/mod.ts ../sibling/mod.ts ../sibling/other.ts
would resolve the config file for ./child
and ../sibling
to use for their respective files.
- Fmt/lint option resolution: Each config file resolves from the root of each disjointed tree
- Includes/excludes: Each config file resolves from the root of each disjointed tree
- Run options: Resolved from closest ancestor deno.json (same as Option 1)
I think this is the solution we agreed upon before? It answers no to both of the questions I asked above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Option 1 and Option 3 are the same except applying to multiple arguments. I agree with this approach.
Or we can just find the deno.json based on the first argument and if other files have a different config, erroniously ignore it for the time being. These are corner cases that we should have tests for anyway - we can move to option 1/3 in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe Option 3 was exactly what we discussed previously.
Is this shippable without addressing the language server? Feels like it should be included in this PR. |
What needs to be addressed in the language server? |
Currently the lsp requires an explicit option of Lines 157 to 159 in c487b7e
And when there is something impacted in the environment, like when the client configuration or the configuration file iteself changes, then the language server processes an update: deno/cli/lsp/language_server.rs Line 524 in c487b7e
If we have automatic behaviour to identify the file when Generally this should be fairly straight forward with just a "workspace" and looking in the "workspace root", but when you have "workspace folders" (multi-root workspaces), I suspect it could get a bit convoluted. Side note, I just realised we are only watching JSON files in the workspace (and not JSONC): deno/cli/lsp/language_server.rs Lines 722 to 728 in c487b7e
And not watching for changes in Another discussion at one point, which could be delivered later, is that if we automatically detect a |
Could we just rip out the LSP config option? Seems like if we have auto-discover then maybe this option isn't necessary |
Will the CLI still allow |
@kitsonk I put up a little test case but it doesn't seem to be working. I'm seeing this error message from the LSP
Any advice would be appreciated |
Ah, OK, I will have to trace it through, but what is happening, versus the other tests like this, is that it is triggering the workspace folder logic which request from the client the specific configuration for a file, and for some reason it is causing this test to fail. |
Tried this PR on |
) | ||
.unwrap(); | ||
|
||
let workspace_root = temp_dir.path().canonicalize().unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was the fix, in that auto-discovery automatically canonicalizes the discovered path.
An open question though is how do clients behave? Do they canonicalize files? There isn't an easy way to determine. We may need to fix exclude
and include
properties for things like format and lint to canoncilize files... 😕
Looks like something is hanging with |
Found the problem, will push a fix after I check the rest of the tests... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM too.
There are some unrelated changes in this PR, but I'm not gonna nitpick.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM too!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tried it out locally, and it is working great. LGTM!
I don't see anything in the release notes about how to disable this feature. How can I prevent deno from walking the directory hierarchy and discovering configs? |
No description provided.