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

support multi-root for 'Add Configuration' #8066

Closed
wants to merge 1 commit into from
Closed

Conversation

elaihau
Copy link
Contributor

@elaihau elaihau commented Jun 20, 2020

  • If a user is using a multi-root workspace, the command "Debug: Add Configuration" adds a configuration directly in the first workspace root instead of prompting users to select the correct root. With this change the command prompts users with a quick-pick which allows them to select their desired workspace root.

  • resolves [debug] support multi-root for 'Add Configuration' #5166

Signed-off-by: Liang Huang [email protected]

How to test

  • in a workspace that has only one root folder, the command "Debug: Add Configuration" should work the way it used ot

  • in a multi root workspace, we should see a prompt that asks users to select which root folder the configuration should be added to.

Peek 2020-06-20 15-58

Review checklist

Reminder for reviewers

@akosyakov akosyakov added the tasks issues related to the task system label Jun 22, 2020
let model: DebugConfigurationModel | undefined;
if (this.models.size > 1) {
model = await this.quickPick.show(Array.from(this.models.entries()).map(entry => {
const [rootFolder, modelValue] = entry;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice if the list of roots would be ordered like what the user sees in the explorer: I guess if we iterate over the root folders array and 'get' from the map that would be the case. Iteration order over a map is not defined.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the feedback !
With my most recent update, I am using workspaceService.roots to ensure the order of the workspace folders.

value: modelValue
};
}), {
placeholder: 'Select for which root folder to add the configuration to'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think "workspace folder" would be the VS Code terminology here: I suggest:

Select the workspace folder to add the configuration to

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@elaihau elaihau force-pushed the Liang/addConfig branch 2 times, most recently from bb20598 to 7aacc6f Compare June 22, 2020 22:42
Copy link
Member

@vince-fugnitto vince-fugnitto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@elaihau I had issues with adding configurations when I had multiple roots and my roots were simple folders without .theia or .vscode present. In these cases, when selecting a root with the quick-pick, the launch.json was not created in their respective root and instead the workspace file was opened instead, is this the expected behavior?

{
   "folders": [
      {
         "path": "file:///Users/vincentfugnitto/Desktop/a"
      },
      {
         "path": "file:///Users/vincentfugnitto/workspace/theia"
      }
   ],
"settings": {
    "launch": {}
}
}

model = await this.quickPick.show(rootUris.map(rootUri => {
const modelValue = this.models.get(rootUri);
return {
label: this.labelProvider.getName(new URI(rootUri)),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can align with the 'new terminal' and also display the path to the workspace (helps when there are multiple roots with the same name):

return this.quickPick.show(roots.map(
({ uri }) => ({ label: this.labelProvider.getName(new URI(uri)), description: this.labelProvider.getLongName(new URI(uri)), value: uri })
), { placeholder: 'Select current working directory for new terminal' });
}

Copy link
Contributor Author

@elaihau elaihau Jun 23, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your feedback should have been resolved in the lastest patch.
I tested the multi root workspace

  • that has more than one folders
  • that has only one folder, and
  • with & without the .theia or .vscode folders

Thank you !

@vince-fugnitto vince-fugnitto added debug issues that related to debug functionality multi-root issues related to multi-root support labels Jun 22, 2020
@tsmaeder
Copy link
Contributor

I found a problem with the following scenario:

  1. Create a multiroot-workspace looking like this:
Third
  .vscode
    launch.json
Second
  untitled.txt

Where launch.json contains:

{
  // Use IntelliSense to learn about possible attributes.
  // Hover to view descriptions of existing attributes.
  "version": "0.2.0",
  "configurations": []
}
  1. Run "Debug: Add Configuration"
  2. Observe: the content of Third/.vscode/launch.json is replaced with:
{}

const { model } = this;
let model: DebugConfigurationModel | undefined;
if (this.models.size > 1) {
const rootUris = (await this.workspaceService.roots).map(r => r.uri);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't this first map is needed: why not just use r.uri inside the quick pick?

@@ -254,21 +274,28 @@ export class DebugConfigurationManager {

protected async doOpen(model: DebugConfigurationModel): Promise<EditorWidget> {
let uri = model.uri;
if (!uri) {
const configFileUri = this.getFolderConfigurationUri(model);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this sequence is ignoring the case where there is a launch.json but it's in the .vscode folder instead of .theia

@@ -254,21 +274,28 @@ export class DebugConfigurationManager {

protected async doOpen(model: DebugConfigurationModel): Promise<EditorWidget> {
let uri = model.uri;
if (!uri) {
const configFileUri = this.getFolderConfigurationUri(model);
const fileStat = await this.filesystem.getFileStat(configFileUri.toString());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line throws an error when the the parent folder of the file does not exist. Maybe exists does the trick? But the documentation is really not very precise on this.

- If a user is using a multi-root workspace, the command "Debug: Add Configuration" adds a configuration directly in the first workspace root instead of prompting users to select the correct root. With this change the command prompts users with a quick-pick which allows them to select their desired workspace root.

- resolves #5166

Signed-off-by: Liang Huang <[email protected]>
@elaihau
Copy link
Contributor Author

elaihau commented Jun 25, 2020

Thank you for your time @tsmaeder !
You are right. I totally forgot the scenarios where .vscode/launch.json is used by Theia.
The bugs you found should have been fixed in my lastest patch. Could you please take a look when you get the chance? Thanks !

Copy link
Contributor

@tsmaeder tsmaeder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm very good at finding subtle problems, I guess 🤷 Otherwise, looks good.

console.log(thismodel);
}
let model: DebugConfigurationModel | undefined;
if (this.models.size > 1) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this check is not reliable: I was able to construct a case where I'm not asked which folder I would like to configure:

  1. Open an unrelated folder
  2. Select "Open Workspace" and open a folder looking like this:
   Third
     .vscode
       launch.json
  1. Add a second folder to the workspace looking like this (don't save to a file)
   Second
     untitled.txt
  1. Hit F1->Debug: Add Configuration
  2. Observe: I'm not asked which workspace folder to use: the config goes to Third

I've been able to trace the problem to the fact that the listener for preference changes is never called when a new workspace root is added: theia/packages/debug/src/browser/debug-configuration-manager.ts#88

I am not really sure what the right fix is, though: should we listen to workspace folder changes or should the preferences system send a change?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@akosyakov I'd like your opinion on that one.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It sounds fine to listen to workspace root changes, since they are input to updateModels function and seems to be easy fix.

But that we don't fire preference events when roots are changed bother me too. We should check what VS Code extensions will expect. Could you file an issue to investigate?

const paths = this.preferenceConfigurations.getPaths();
for (const configPath of paths) {
const configUri = new URI(model.workspaceFolderUri).resolve(`${configPath}/launch.json`);
if (await this.filesystem.exists(configUri.toString())) {
Copy link
Member

@akosyakov akosyakov Jun 29, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need it? if something exist already we should not override it at all, previous fallback was fine to me

doCreate method should assume that it is called when nothing exists

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The previous version of the PR did not work in the cases where a launch.json existed, but was under .vscode instead of .theia

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that sounds like a bug in the preference service, DebugConfigurationModel.uri used to point to a config from which data was loaded or nothing

@@ -254,21 +277,27 @@ export class DebugConfigurationManager {

protected async doOpen(model: DebugConfigurationModel): Promise<EditorWidget> {
let uri = model.uri;
if (!uri) {
const configFileUri = await this.getFolderConfigurationUri(model);
if (!await this.filesystem.exists(configFileUri.toString())) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why previous check was not good? if uri is missing, that already means that model does not exist.

uri = await this.doCreate(model);
}
return this.editorManager.open(uri, {
return this.editorManager.open(uri!, {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

! why is it needed?, if branch should ensure that uri exists

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i agree with you while the linter doesn't.

without ! it gives me this error

Argument of type 'URI | undefined' is not assignable to parameter of type 'URI'.
  Type 'undefined' is not assignable to type 'URI'.ts(2345)

and

   'Exit with failure status (1): concurrently -n compile,lint -c blue,green "theiaext compile" "theiaext lint"\nerror Command failed with exit code 1.\n',

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should sort out other comments, I don't think that so many changes to doCreate function are required. It seems there are regressions with PreferenceService.

@marcdumais-work
Copy link
Contributor

Liang's contract is over and he has moved-on from Theia.

@tsmaeder I have not followed closely this PR - how close DYT it is to be merged? Is there someone on your side who could take-over and address remaining comments?

@tsmaeder
Copy link
Contributor

tsmaeder commented Jul 6, 2020

@marcdumais there is a corner case when adding a workspace folder that needs to be addressed, should be pretty straight-forward, though.

@JonasHelming JonasHelming added the decision_needed issues that require decisions on ways forward (ex: if they should be updated or closed) label Feb 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
debug issues that related to debug functionality decision_needed issues that require decisions on ways forward (ex: if they should be updated or closed) multi-root issues related to multi-root support tasks issues related to the task system
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[debug] support multi-root for 'Add Configuration'
6 participants