-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Retrieving launch configurations using Plugin API #4743
Conversation
@akurinnoy tests are red |
c28e82b
to
a206590
Compare
@akosyakov tests are green, please have a look |
@akurinnoy i will test tomorrow morning |
@@ -53,6 +54,7 @@ export class PreferenceSchemaProvider extends PreferenceProvider { | |||
|
|||
protected readonly preferences: { [name: string]: any } = {}; | |||
protected readonly combinedSchema: PreferenceDataSchema = { properties: {}, patternProperties: {} }; | |||
private remoteSchemas: IJSONSchema[] = []; |
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.
What is special about remoteSchema
? Why cannot be incorporated in combinedSchema
and should be validated separately?
After reading code it does not seem to affect combined schemas, but just passed here to reuse validate
function for launch folder providers?
PreferenceSchemaProvider
is responsible for providing a schema for settings files, validating it and used for getting default values of settings. It does not have anything to do with launch preferences. I think we should have a separate Ajv validator for launch file not aware of settings schema.
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.
After reading code it does not seem to affect combined schemas, but just passed here to reuse
validate
function for launch folder providers?
You're right, but not only for launch folder provider but for any preference provider. Each time a launch configuration is added, renamed or removed we need new schema which restricts possible names of configuration available for compound sub-section.
PreferenceSchemaProvider
is responsible for providing a schema for settings files, validating it and used for getting default values of settings. It does not have anything to do with launch preferences.
User might have a global or workspace wide launch configuration placed in corresponding settings file, and a project might contain no launch file at all. That is why I treated launch configuration as any other property.
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.
User might have a global or workspace wide launch configuration placed in corresponding settings file
Wow, did not know it, ok, will test how it works. So i should get content assist in settings.json for launch
property and registered debug configurations similar to VS Code?
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.
yes
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.
There is no content assist support for launch
property and launch configurations in 'settings.json` as in VS Code. Looking at the code this property should be provided by https://github.com/akurinnoy/theia/blob/397f360422dae3dc590e58665fd526d04d7810c7/packages/debug/src/browser/debug-schema-updater.ts#L77-L88 not by remote schemas.
I'm still confused why we need remoteSchemas
here? How do they affect settings schema and values?
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.
Thinking of content assist I meant this:
I'm still confused why we need
remoteSchemas
here? How do they affect settings schema and values?
That's the point. Remote schema doesn't affect setting a values. It affects only validation. Remote schema only makes things easier allowing to replace a part of preference schema without calling doSetSchema()
, thus allows to easily update validation function.
The main part of launch preference schema is set only once. Since then only remote part of schema become updated.
https://github.com/theia-ide/theia/pull/4743/files#diff-2dd1a479f035ae6ce8c1517929d4568dR70
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 will try again tomorrow. Tried the same today and did not get any content assist. The problematic part with it that these settings not respected by DebugConfigurationWidget
and we don't have an implementation for compounds
anywhere. We either have to implement it or keep content assist out of scope of this PR.
} | ||
} | ||
|
||
// debug general schema | ||
const defaultCompound = { name: 'Compound', configurations: [] }; | ||
export const defaultCompound = { name: 'Compound', configurations: [] }; |
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.
Does it mean that we support compound configurations now? Does a user can get a false impression via UI that we do?
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.
No, it doesn't mean that. It's only about providing preference schema and validating a launch configuration.
Which UI do you mean?
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.
content assist in launch.json should not provide what is not implemented
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.
If a property is not valid then user can't retrieve it using plugin API.
Could we instead provide a diagnostics for content assist for compounds
property key to warn user that compound configurations are not supported?
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.
When it should be stubbed somehow in the plugin ext for now without leaking anything to UI and adding half-baked code to other extensions.
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.
Could It be done in the following way?
At this point
https://github.com/theia-ide/theia/blob/397f360422dae3dc590e58665fd526d04d7810c7/packages/debug/src/browser/debug-schema-updater.ts#L113
clone the schema. Then one of schemas could go to provide content assist. And the second one could be populated with configuration names and used for validation purpose.
This allows to validate preferences and will not affect UI.
packages/preferences/src/browser/abstract-resource-preference-provider.ts
Outdated
Show resolved
Hide resolved
packages/preferences/src/browser/abstract-resource-preference-provider.ts
Outdated
Show resolved
Hide resolved
this.toDispose.push(this.onDidLaunchChangedEmitter); | ||
this.toDispose.push( | ||
this.preferenceProvider.onDidNotValidPreferencesRead(prefs => { | ||
if (!prefs || !GlobalLaunchConfig.is(prefs.launch)) { |
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.
Why should it go here and cannot happen in launch preference provider? then we don't need a new event onDidNotValidPreferencesRead
and can do GlobalLaunchConfig.is
check in one place.
Also wondering after reading code, looks like if you don't use the validation function aware of setting schema for launch folder preferences maybe you won't get some false possible validation results and getting rid of an event would be easier.
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.
Why should it go here and cannot happen in launch preference provider? then we don't need a new event
onDidNotValidPreferencesRead
and can doGlobalLaunchConfig.is
check in one place.
Event onDidNotValidPreferencesRead
triggers creating new preference schema for launch property, so I don't see how we can't get rid of it.
looks like if you don't use the validation function aware of setting schema for launch folder preferences maybe you won't get some false possible validation results and getting rid of an event would be easier.
I'm not sure I understood what you meant... Could you elaborate on this?
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.
Why do we need to create preferences from invalid data? If it is valid then it should be part of onDidPreferencesChanged
. Could you elaborate on an example when preferences are not valid but we still want to use them?
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.
It's because how launch preference schema is defined.
In order to build this schema I need to get all configuration names to fill the enum
. On the other hand, to get them launch configurations need to be validated against launch preference schema which is not built yet.
Imagine, you have launch configuration
"launch": {
"confugurations": [
{ "name": "Launch Backend", ...},
{ "name": "Launch Frontend", ...}
],
"compounds": [
{
"name": "Compound",
"configurations": [
"Launch Backend", // valid
"Launch Frontend", // valid
"Run Tests" // not valid
]
}
]
}
And you need to restrict possible values of configurations
in compounds
section to only available configuration names.
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.
Do you mean if someone add Run Tests
to compounds.configurations
then the whole launch
preference marked as invalid and not available to a user?
Do you also mean that we reparse launch json twice, once to create a schema and second time to validate data?
How about having custom validation for launch preferences to exclude only bogus compound configuration, break a cycle between schema and data, avoid parsing data twice and introducing a new event? I don't think you need to check each property in this case of each configuration just top-level structure, like here https://github.com/akurinnoy/theia/blob/397f360422dae3dc590e58665fd526d04d7810c7/packages/debug/src/browser/debug-configuration-model.ts#L74
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 wonder whether launch launch configs in user settings makes sense at all? Should not we just stub it with default values? Docs does not say anything about user settings:
Note: Workspace and Workspace Folder configurations contains launch and tasks settings.
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.
Have you seen default settings and explanation near launch
property?
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 think launch config in user settings shouldn't be stabbed, and Theia should use a global launch config if a project doesn't have its own.
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.
Does it mean that it's stubbed with such value and data from user settings json are ignored? Do I read it correctly?
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'm wrong. My user settings already had launch section that's why i got such results. If i try to changes it changes are reflected into expectations, so we should read launch section user settings as well.
I will update tests with expectations that user settings does not contain launch section.
I don't see that |
async getUri(): Promise<URI | undefined> { | ||
this.folderUri = new URI(this.options.folder.uri); | ||
if (await this.fileSystem.exists(this.folderUri.toString())) { | ||
const uri = this.folderUri.resolve('.theia').resolve('launch.json'); |
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.
It should respect launch.json from vscode as well. See logic in DebugConfigurationWidget
, if we move it here it should be properly reimplemented.
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.
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 think this should be separate issue and another pull request because there are some things to discuss. For example, if a project has one launch configurations for Theia
and one for VScode
which names are same but they differ in other fields. Which one should be returned if a user gets configuration by name? How a user should update or delete a concrete launch configuration?
@akosyakov do you mind if I open an issue?
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.
It should work as on master. If a folder has .theia then theia settings is used, if not then VS Code settings.
packages/preferences/src/browser/folders-preferences-provider.ts
Outdated
Show resolved
Hide resolved
Signed-off-by: Oleksii Kurinnyi <okurinny@redhat.com>
This allows to re-validate such properties when a corresponding schema has been set. Signed-off-by: Oleksii Kurinnyi <okurinny@redhat.com>
Signed-off-by: Oleksii Kurinnyi <okurinny@redhat.com>
…schema `UserLaunchProvider`, `WorkspaceLaunchProvider` and `FoldersLaunchProvider` handle changing of 'launch' section of preferences without paying attention whether configuration is valid or not. Once it happens a new preference schema for launch configurations builds. Signed-off-by: Oleksii Kurinnyi <okurinny@redhat.com>
a206590
to
397f360
Compare
With which VS Code extension it's possible to reproduce issues like access compound configurations and so on? |
@@ -3,6 +3,7 @@ | |||
## v0.6.0 | |||
|
|||
- [filesystem] added the menu item `Upload Files...` to easily upload files into a workspace | |||
- [preferences] changed signature for methods `getProvider`, `setProvider` and `createFolderPreferenceProvider` of `FoldersPreferenceProvider`. |
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.
breaking changes should go in its own section, see below for 0.5.0
It would be nice also cover what for they were changed, see examples in breaknig changes for other releases
this.toDispose.push(this.onDidLaunchChangedEmitter); | ||
this.toDispose.push( | ||
this.preferenceProvider.onDidNotValidPreferencesRead(prefs => { | ||
if (!prefs || !GlobalLaunchConfig.is(prefs.launch)) { |
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.
Why do we need to create preferences from invalid data? If it is valid then it should be part of onDidPreferencesChanged
. Could you elaborate on an example when preferences are not valid but we still want to use them?
} | ||
} | ||
|
||
// debug general schema | ||
const defaultCompound = { name: 'Compound', configurations: [] }; | ||
export const defaultCompound = { name: 'Compound', configurations: [] }; |
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.
When it should be stubbed somehow in the plugin ext for now without leaking anything to UI and adding half-baked code to other extensions.
@@ -21,87 +21,113 @@ import { FolderPreferenceProvider, FolderPreferenceProviderFactory } from './fol | |||
import { FileSystem, FileStat } from '@theia/filesystem/lib/common'; | |||
import URI from '@theia/core/lib/common/uri'; | |||
|
|||
export const LAUNCH_PROPERTY_NAME = 'launch'; | |||
export type ResourceKind = 'settings' | 'launch'; |
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.
please use unique naming, see naming conventions
i.e. FolderPreferenceKind
Resource
already has a meaning in Theia, i.e git and file are kind of resources
@@ -53,6 +54,7 @@ export class PreferenceSchemaProvider extends PreferenceProvider { | |||
|
|||
protected readonly preferences: { [name: string]: any } = {}; | |||
protected readonly combinedSchema: PreferenceDataSchema = { properties: {}, patternProperties: {} }; | |||
private remoteSchemas: IJSONSchema[] = []; |
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.
There is no content assist support for launch
property and launch configurations in 'settings.json` as in VS Code. Looking at the code this property should be provided by https://github.com/akurinnoy/theia/blob/397f360422dae3dc590e58665fd526d04d7810c7/packages/debug/src/browser/debug-schema-updater.ts#L77-L88 not by remote schemas.
I'm still confused why we need remoteSchemas
here? How do they affect settings schema and values?
@@ -215,7 +221,11 @@ export class PreferenceRegistryExtImpl implements PreferenceRegistryExt { | |||
const defaultConfiguration = this.getConfigurationModel(data[PreferenceScope.Default]); | |||
const userConfiguration = this.getConfigurationModel(data[PreferenceScope.User]); | |||
const workspaceConfiguration = this.getConfigurationModel(data[PreferenceScope.Workspace]); | |||
return new Configuration(defaultConfiguration, userConfiguration, workspaceConfiguration); | |||
const folderConfigurations = {} as { [resource: string]: ConfigurationModel }; |
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 think it would be better to have a named type if this construction is used in several files.
@@ -113,20 +139,34 @@ export class FoldersPreferencesProvider extends PreferenceProvider { | |||
return provider; | |||
} | |||
|
|||
protected createFolderPreferenceProvider(folder: FileStat): FolderPreferenceProvider { | |||
const provider = this.folderPreferenceProviderFactory({ folder }); | |||
protected setProvider(provider: FolderPreferenceProvider, kind: ResourceKind): void { |
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.
To me addProvider
suits better here
This PR is also required for finishing eclipse-che/che#12446: we cannot enable logging and debugging in jdt.ls right now. |
@tsmaeder I understand and also want to see it merged, but the current state does not look good to me. If you don't mind we can collaborate on this PR, i.e. i will push commits to finish it up. |
@akosyakov as I am not the author of the PR, I don't really have a say in that ;-). I cross-linked the other issue to make the link for planning purposes. |
@akurinnoy let me know if it would be fine with you to work together on this PR |
@akosyakov I'm OK to work on this PR together. How do we split the work? |
I could work on integration with Theia UI, you with VS Code extensions. I can look into hooking I can open a PR against this PR for my changes. |
if (resourceUri && this.providers.length > 0) { | ||
const provider = this.getProvider(resourceUri); | ||
if (resourceUri) { | ||
const resourceKind = preferenceName === LAUNCH_PROPERTY_NAME ? 'launch' : 'settings'; |
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 wonder why do we check both? settings can provide as well, can't they?
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.
AFAIK VS Code doesn't provide launch from folder's settings in multi-root scope
const launchProvider = this.getProvider(resourceUri, 'launch'); | ||
const launch = launchProvider ? launchProvider.getPreferences() : {}; | ||
|
||
const result = Object.assign({}, prefs, launch); |
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.
Should not the last arg be { launch }
and only if launch is defined?
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.
@injectable() | ||
export class FoldersPreferencesProvider extends PreferenceProvider { | ||
|
||
@inject(WorkspaceService) protected readonly workspaceService: WorkspaceService; | ||
@inject(FileSystem) protected readonly fileSystem: FileSystem; | ||
@inject(FolderPreferenceProviderFactory) protected readonly folderPreferenceProviderFactory: FolderPreferenceProviderFactory; | ||
|
||
private providers: FolderPreferenceProvider[] = []; | ||
private providersByKind: Map<ResourceKind, FolderPreferenceProvider[]> = new Map(); | ||
private resourceKinds: ResourceKind[] = ['launch', 'settings']; | ||
|
||
@postConstruct() | ||
protected async init(): Promise<void> { | ||
await this.workspaceService.roots; |
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 started rewriting this code. It's unnecessary complicated.
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 started reworking code as we decided earlier, so it will be much simpler.
hello, any news on when we're able to merge this PR ? |
It cannot be merged. It does not pass any VS Code compatibility test and breaks Theia UI. I've strarted reworking it here: https://github.com/theia-ide/theia/tree/ak/laung_preferences will open a PR then it is finished |
This PR aims to fix #4188. In order to fix the issue following improvements are introduced:
launch.json
to retrieve launch configurationsThis PR also fixes #2290