eclipse.platform icon indicating copy to clipboard operation
eclipse.platform copied to clipboard

Add support for creating workspace private project descriptions

Open laeubi opened this issue 9 months ago • 9 comments

Currently importing a project into eclipse requires the creation of a physical file name .project in the root of the project. this has several drawbacks for tools that automatically discover projects and import them for the user as it creates new files and possibly dirty their working tree. Other tools use a single folder for this purpose or don't require any permanent files in the working-tree itself. Even Eclipse has already such concept that is used when a project is located outside the workspace.

This now adds a new feature called "workspace private project" that only holds the basic information in the location file in the workspace directory, any additional information might be needed to restore by a tool that uses workspace private projects.

This is currently a draft what already works is that if one creates such a project is is open and can be used in eclipse, but there are some places that want to create / read the .project file (e.g. shutdown / restart).

laeubi avatar Mar 22 '25 06:03 laeubi

I now added some more checks and it is now possible to create a private project and restart eclipse without a problem, the .project file is not created.

laeubi avatar Mar 22 '25 07:03 laeubi

Test Results

  428 files   -   762    428 suites   - 762   17m 41s ⏱️ - 39m 23s 1 216 tests  - 2 957  1 142 ✅  - 2 984   9 💤  - 38   7 ❌ + 7   58 🔥 + 58  3 041 runs   - 5 914  2 887 ✅  - 5 948  24 💤  - 96  16 ❌ +16  114 🔥 +114 

For more details on these failures and errors, see this check.

Results for commit 345db752. ± Comparison against base commit a791b17e.

This pull request removes 2957 tests.
AllCompareTests AsyncExecTests ‑ testCancelOnRequeue
AllCompareTests AsyncExecTests ‑ testQueueAdd
AllCompareTests AsyncExecTests ‑ testWorker
AllCompareTests CompareFileRevisionEditorInputTest ‑ testPrepareCompareInputWithNonLocalResourceTypedElements
AllCompareTests CompareUIPluginTest ‑ testFindContentViewerDescriptorForTextType_StreamAccessor
AllCompareTests CompareUIPluginTest ‑ testFindContentViewerDescriptor_TextType_NotStreamAccessor
AllCompareTests CompareUIPluginTest ‑ testFindContentViewerDescriptor_UnknownType
AllCompareTests ContentMergeViewerTest ‑ testFFFX
AllCompareTests ContentMergeViewerTest ‑ testFFTX
AllCompareTests ContentMergeViewerTest ‑ testFFXF
…

:recycle: This comment has been updated with latest results.

github-actions[bot] avatar Mar 22 '25 08:03 github-actions[bot]

Thank you for looking at this interesting topic.

It looks like as per javadoc in IProjectDescription, project.getFile(IProjectDescription.DESCRIPTION_FILE) is always expected to return such a file; that's one reason in JDT-LS hacks we've seen hacks about overriding the filesystem, and that later we changed (did we? but at least I remember I made it possible in Platorm) to be able to use a linked resource for .project.

I think we should aim to get the very minimal new API one can think of. Basically in this proposal, I'm not convinced that setWorkspacePrivate and equivalent are a necessary public API. Concretely, I'm wondering what is best between getters/setters here and there and a new IProject.create(...) method with an extra flag instructing to create the .project in a workspace metadata rather than under the project. For a newly created project, then isWorkspacePrivate just becomes IPath.fromOSString(IProjectDescriptionFileName).equals(project.getFile(DESCRIPTION_FILE_NAME).getLocation().makeRelativeTo(project.getLocation)); so we could deal with less getters.

mickaelistria avatar Mar 23 '25 16:03 mickaelistria

Concretely, I'm wondering what is best between getters/setters here and there and a new IProject.create(...) method with an extra flag instructing to create the .project in a workspace metadata rather than under the project.

The flags are actually only flags passed to the creation of the Project resource itself and looking at org.eclipse.core.internal.resources.Workspace.createResource(IResource, int) only a few flags are actually supported here.

On the other hand the data in ProjectDescription are used to actually store the information about the project itself and we need access to these data on several places (e.g. ProjectDescription are cloned on some places) and we need to persist / restore that nature.

Also as you mentioned, there might be code that wants to access the project.getFile(IProjectDescription.DESCRIPTION_FILE) and would need to get a chance to know that the project itself is only workspace private.

That's the reason why I made this fact "public" and it was quite less changes than initially thought. This also includes to store basically the data currently in the .project file in the workspace area and allows recovery of deleted project files completely, currently Eclipse just creates an almost empty one.

For a newly created project, then isWorkspacePrivate just becomes IPath.fromOSString(IProjectDescriptionFileName).equals(project.getFile(DESCRIPTION_FILE_NAME).getLocation().makeRelativeTo(project.getLocation)); so we could deal with less getters.

I'm not completely sure about the intend here, this looks rather complicated and cumbersome to use as it requires knowledge of internal implementation details compared to a well defined getter.

Another approach would be to make the actual project file "virtual" and e.g. store it in the metadata area next to the location file, but for some reasons the Virtaul flag is currently completely disabled in 51c2f06bfe93a14437166d200be5cb67611689b2

laeubi avatar Mar 23 '25 17:03 laeubi

I'm not completely sure about the intend here, this looks rather complicated and cumbersome to use as it requires knowledge of internal implementation details compared to a well defined getter.

Most users really won't need to make the difference about whether the file is project-local or workspace-local once the project is created. So the flag would be usually useless. The internal consumers can keep an internal private or package visible isWorkspacePrivate method to shortcut IPath.fromOSString(IProjectDescriptionFileName).equals(project.getFile(DESCRIPTION_FILE_NAME).getLocation().makeRelativeTo(project.getLocation)), that would be fine, but I just don't think we need extra project settings, and even less that we need it as API. Most users would indeed not need it as they would keep using the usual strategies to edit the project. People who want to access the .project file can still do it the usual way, using the handle project.getFile(DESCRIPTION_FILE_NAME) or going through filesystem with project.getName(DESCRIPTION_FILE_NAME); that would still work anyway.

mickaelistria avatar Mar 23 '25 17:03 mickaelistria

If you look at ProjectDescription you would see that each configurable property has a getter and setter. This is because one can even update the description later on, so it is not only for create a project itself.

laeubi avatar Mar 23 '25 17:03 laeubi

If you look at ProjectDescription you would see that each configurable property has a getter and setter. This is because one can even update the description later on, so it is not only for create a project itself.

Indeed, but what I mean here is that how the project description is stored is not really a property of the project description. IMO, this property shouldn't be part of the description, creating a new Project.create(...) method would result in simpler code both for users and maintainers.

mickaelistria avatar Mar 23 '25 19:03 mickaelistria

I have now extracted some of the more generic changes that seems like missing before here:

  • https://github.com/eclipse-platform/eclipse.platform/pull/2033

that would make this changes smaller an easier to review / discuss.

laeubi avatar Jul 13 '25 06:07 laeubi

you would see that each configurable property has a getter and setter

Although I don't like the "mutable struct" style of getter and setter in general, here it looks consistent with the surrounding API.

But, it implies that one can convert existing projects to be workspace private and back to "public". Do we consider such a scenario? If so, we need to add a bit more code to handle this scenario. Otherwise, setter is not the perfect choice to activate this new capability.

ruspl-afed avatar Jul 13 '25 07:07 ruspl-afed