Support hierarchical project preferences
Currently project preferences are stored in a folder named .settings this has the drawback that if one want to configure an aspect for a set of projects (e.g. formatter settings, compiler preferences, ...) one need to duplicate this (and keep them up to date) for each project. Also wen VCS comes into account the same files need to be versioned multiple times.
To mitigate this and given that most projects have some hierarchical nature (e.g the usual <projectroot>/plugins/<myproject>) I'd like to propose the following enhancement (using org.eclipse.jdt.core.prefs as an example):
- Given there is a file
.settings/org.eclipse.jdt.core.prefsnothing changes - Given there is no file
.settings/org.eclipse.jdt.core.prefsthen first a file.eclipse/org.eclipse.jdt.core.prefsis searched and if found that is used, if that file is not found, the parent folder is checked for this until the root is reached - If still no file is found
<workspace-root>/.eclipse/<project-name>/org.eclipse.jdt.core.prefsis searched as a last resort
This would allow to have a variety of different use cases:
- In cases where a user chooses to "enable project specific settings" for certain settings, one could add a new option to not store it in the project but in the workspace, e.g. if I want to prevent the noise if I open a project that normally do not store eclipse preferences.
- I might use this to enable some project specific settings for a set of projects e.g. by placing it in the
<projectroot>/plugins/.eclipsefolder. - I even configure some things on the root of the project e.g. placing a
<projectroot>/.eclipse/org.eclipse.core.resources.prefsto force UTF-8 for the usual source folders. - ...
IIRC @merks started to prototype something related in the context of Oomph a (long) while ago?
Yes, long ago I started implementing something that would automatically copy/propagate project-specific preferences between projects where one could specify which project is the "prototype" from which the preferences should be copied. But I never completed this work such that it's actually in use by any project...
Are there some comment on how this works? It has been a while since I wrote this down, but now I think my initial proposal could even be adjusted by instead of
Given there is a file .settings/org.eclipse.jdt.core.prefs nothing changes
to simply delegate e.g. overwrite anything from the lower levels so we have:
- workspace values
- parent project values
- project specific values
and the highest value wins.
My goal here would clearly be that one do not need to copy anything ... so once we might be able to have what @mickaelistria likes from intelij/vscode that there is only one single folder in the workspace storing all ide specific configurations.
if that file is not found, the parent folder is checked for this until the root is reached
Are we talking here about parent from IFileSystem perspective or about IContainer?
Is it supposed to work with Remote File Systems?
Are we talking here about
parentfrom IFileSystem perspective or about IContainer?
I think the "parent" of a project is always the workspace so this seems not useful, not sure how IFileSystem handles this, but for a local filesystem it should match the expectation of the user that sees a tree-hierarchy in its file browser.
Is it supposed to work with Remote File Systems?
Why not? But I'm wondering if there are really people using a rmfs for their project to work on entirely?
So, for each IProject it will go up from its "Location URI" through the local file system, looking for .eclipse folder until the very root of the drive, and then will try to look into workspace? Or what?
So, for each IProject it will go up from its "Location URI" through the local file system, looking for
.eclipsefolder until the very root of the drive, and then will try to look into workspace? Or what?
yes, this is for example how maven works with the .mvn folder, I think one can have one exception when the project is inside the workspace folder then stop there.
I believe that Eclipse (at least with m2e) already has a notion of hierarchical project structures (see the project explorer), which might be used to know how far to go "up", because when working with Git, the projects might not reside inside the workspace folder (for example /git/my.project/base/plugins/my.plugin vs. ~/workspaces/MyProjectWorkspace/), because workspace settings are not committed to git.
While working on https://github.com/eclipse-equinox/equinox/pull/446, I also thought about this and how to implement this.
In general I think this a good approach, but it should only be implemented in the Project-preference scope so that the project-scope in itself is hierarchical, while being the most specific scope of the project, instance/workspace, configuration/installation and hopefully soon user scope (plus the default scopes) hierarchy.
I think this makes sense since the proposed project preferences are tied to the location of the project in the file-system, while the location of the project, workspace and installation (and user) are in general absolutely independent and can all have their own location.
If a value is search in the project scope, the closest preference file should be searched first and if the key is not found the further parents should be searched until a value for a key is found.
From an UI point of view, the shared preferences stored in an .eclipse folders could be modified like the project specific preferences that are stored inside the project-folder, simply by opening the Properties of the .eclipse folder via the (context) menu, just like it is done project specific preference now.
There could then also be a clean up to remove preference entries stored in a project that are duplicates from a parent directory preference (not considering from other scopes).
To mitigate this and given that most projects have some hierarchical nature (e.g the usual
<projectroot>/plugins/<myproject>) I'd like to propose the following enhancement (usingorg.eclipse.jdt.core.prefsas an example):* Given there is a file `.settings/org.eclipse.jdt.core.prefs` nothing changes
I would propose that nothing changes only if the requested key is not present in the existing preference file. If the requested key is missing it should be search in the parent directories .eclipse/.settings/*.prefs.
* Given there is no file `.settings/org.eclipse.jdt.core.prefs` then first a file `.eclipse/org.eclipse.jdt.core.prefs` is searched and if found that is used, if that file is not found, the parent folder is checked for this until the root is reached
I don't think we should have .eclipse as an alternative to the .settings folder within a project.
Furthermore the current implementation in EclipsePreferences assume that all *.prefs files are located in a .settings folder within the scope location, be it the project's location, the instance location in .metadata\.plugins\org.eclipse.core.runtime\.settings (i.e. the state location of the o.e.core.runtime in the current runtime instance or the configuration location.
In order to keep this consistent I think it an .eclipse folder in a parent directory should be considered as parent (within the project scope), which has the effect that the preference files are saved in .eclipse/.settings/*.prefs.
Only if we think that there will never be a reason to have other files/folders stored there we could think about changing EclipsePreferences to look in the preference scope directory directly.
Thinking about it, at least for projects, it could be an interesting to place all Eclipse specific files in the .eclipse folder, like the .project, .classpath, META-INF/MANIFEST.MF, build.properties, etc. But that's another story.
Furthermore by default only the parent directory should be considered in order to prevent potential confused if https://github.com/eclipse-equinox/equinox/pull/446 is implemented as suggested and a workspace is located within the user home plus to improve the performance (if performance is a problem depends on the exact implementation). Nevertheless it should be possible to configure the number of considered parent directories easily respectively to configure that the parent
* If still no file is found `<workspace-root>/.eclipse/<project-name>/org.eclipse.jdt.core.prefs` is searched as a last resort
I think the workspace (scope) should not be considered here. This should only be done as part of the project scope. Of course it might happen that coincidentally the workspace root is equal to a parent directory containing a .eclipse preference folder.
I believe that Eclipse (at least with m2e) already has a notion of hierarchical project structures (see the project explorer
Not really, the project explorer is just showing the project hierarchically, it's a UI trick to hide some content from a project a show a project in place of a folder, not something that is directly taken from the underlying resource model.
But there are utility to resolve the "deepest parent project" or things of that sort. Those could be used to build a kind of ProjectPreferenceStore that would delegate to parent project if requesting a particular value that's missing in project settings.