From 8f80e1ecfd5cc29cbfc20483e08da63d975e0ca4 Mon Sep 17 00:00:00 2001 From: Hannes Wellmann Date: Fri, 2 Feb 2024 17:39:55 +0100 Subject: [PATCH] Make automatic configuration updates configurable per project And degrade problems about out-dated project configuration to severity 'info', if automatic updates are disabled for a project. Fixes https://github.com/eclipse-m2e/m2e-core/issues/1661 --- RELEASE_NOTES.md | 7 +++++ org.eclipse.m2e.core.ui/META-INF/MANIFEST.MF | 2 +- .../MavenProjectPreferencePage.java | 27 ++++++++++++++----- ...avenUpdateConfigurationChangeListener.java | 13 ++++++--- .../OutOfDateConfigurationDeltaVisitor.java | 2 +- .../project/ProjectConfigurationManager.java | 10 ++++--- .../project/ResolverConfigurationIO.java | 14 ++++++---- .../core/project/ResolverConfiguration.java | 16 ++++++++++- 8 files changed, 70 insertions(+), 21 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 2b373270d3..66e3aaf740 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -8,6 +8,13 @@ Updated the embedded Maven from version 3.9.5 to 3.9.6; [Maven 3.9.6 Release Notes](https://maven.apache.org/docs/3.9.6/release-notes.html). +### New project preference for automated Maven project configuration updates + +Automatic configuration updates for Maven projects can now be disabled the in the project preferences. +This allows to disable these updates individually per project and to store the setting in a preference-file under version control, +which is useful for projects that require special workspace configuration that doesn't exactly match the configuration in the `pom.xml`. + +![grafik](https://github.com/eclipse-m2e/m2e-core/assets/44067969/7d27ceda-5d13-4f0e-97f0-ff34c94d7493) ## 2.5.0 diff --git a/org.eclipse.m2e.core.ui/META-INF/MANIFEST.MF b/org.eclipse.m2e.core.ui/META-INF/MANIFEST.MF index c3aef70e28..8eb3e9a8b6 100644 --- a/org.eclipse.m2e.core.ui/META-INF/MANIFEST.MF +++ b/org.eclipse.m2e.core.ui/META-INF/MANIFEST.MF @@ -1,7 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.eclipse.m2e.core.ui;singleton:=true -Bundle-Version: 2.0.7.qualifier +Bundle-Version: 2.0.800.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-17 Bundle-Name: %Bundle-Name Bundle-Vendor: %Bundle-Vendor diff --git a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/preferences/MavenProjectPreferencePage.java b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/preferences/MavenProjectPreferencePage.java index ff4fbbfd8b..d761d8d485 100644 --- a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/preferences/MavenProjectPreferencePage.java +++ b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/preferences/MavenProjectPreferencePage.java @@ -36,10 +36,10 @@ import org.eclipse.m2e.core.MavenPlugin; import org.eclipse.m2e.core.internal.IMavenConstants; -import org.eclipse.m2e.core.project.IProjectConfiguration; import org.eclipse.m2e.core.project.IProjectConfigurationManager; import org.eclipse.m2e.core.project.ResolverConfiguration; import org.eclipse.m2e.core.ui.internal.Messages; +import org.eclipse.m2e.core.ui.internal.project.MavenUpdateConfigurationChangeListener; /** @@ -52,6 +52,8 @@ public class MavenProjectPreferencePage extends PropertyPage { private Button resolveWorspaceProjectsButton; + private Button autoUpdateConfigurationButton; + // private Button includeModulesButton; private Text selectedProfilesText; @@ -74,10 +76,18 @@ protected Control createContents(Composite parent) { selectedProfilesText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); resolveWorspaceProjectsButton = new Button(composite, SWT.CHECK); - GridData resolveWorspaceProjectsButtonData = new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1); - resolveWorspaceProjectsButton.setLayoutData(resolveWorspaceProjectsButtonData); + resolveWorspaceProjectsButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); resolveWorspaceProjectsButton.setText(Messages.MavenProjectPreferencePage_btnResolve); + autoUpdateConfigurationButton = new Button(composite, SWT.CHECK); + autoUpdateConfigurationButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); + autoUpdateConfigurationButton.setText(Messages.MavenPreferencePage_autoUpdateProjectConfiguration); + if(MavenUpdateConfigurationChangeListener.isAutoConfigurationUpdateDisabled()) { + autoUpdateConfigurationButton.setEnabled(false); + String text = autoUpdateConfigurationButton.getText() + " (disabled in workspace preferences)"; + autoUpdateConfigurationButton.setText(text); + } + // includeModulesButton = new Button(composite, SWT.CHECK); // GridData gd = new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1); // gd.verticalIndent = 15; @@ -108,9 +118,10 @@ protected void performDefaults() { init(new ResolverConfiguration()); } - private void init(IProjectConfiguration configuration) { + private void init(ResolverConfiguration configuration) { resolveWorspaceProjectsButton.setSelection(configuration.isResolveWorkspaceProjects()); + autoUpdateConfigurationButton.setSelection(configuration.isAutomaticallyUpdateConfiguration()); // includeModulesButton.setSelection(configuration.shouldIncludeModules()); selectedProfilesText.setText(configuration.getSelectedProfiles()); } @@ -130,11 +141,13 @@ public boolean performOk() { final ResolverConfiguration configuration = new ResolverConfiguration(getResolverConfiguration()); if(configuration.getSelectedProfiles().equals(selectedProfilesText.getText()) && // configuration.shouldIncludeModules()==includeModulesButton.getSelection() && - configuration.isResolveWorkspaceProjects() == resolveWorspaceProjectsButton.getSelection()) { + configuration.isResolveWorkspaceProjects() == resolveWorspaceProjectsButton.getSelection() + && configuration.isAutomaticallyUpdateConfiguration() == autoUpdateConfigurationButton.getSelection()) { return true; } configuration.setResolveWorkspaceProjects(resolveWorspaceProjectsButton.getSelection()); + configuration.setAutomaticallyUpdateConfiguration(autoUpdateConfigurationButton.getSelection()); // configuration.setIncludeModules(includeModulesButton.getSelection()); configuration.setSelectedProfiles(selectedProfilesText.getText()); @@ -165,9 +178,9 @@ public IStatus runInWorkspace(IProgressMonitor monitor) { return isSet; } - private IProjectConfiguration getResolverConfiguration() { + private ResolverConfiguration getResolverConfiguration() { IProjectConfigurationManager projectManager = MavenPlugin.getProjectConfigurationManager(); - return projectManager.getProjectConfiguration(getProject()); + return (ResolverConfiguration) projectManager.getProjectConfiguration(getProject()); } private IProject getProject() { diff --git a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/project/MavenUpdateConfigurationChangeListener.java b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/project/MavenUpdateConfigurationChangeListener.java index 28ee8d7088..30c362361a 100644 --- a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/project/MavenUpdateConfigurationChangeListener.java +++ b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/project/MavenUpdateConfigurationChangeListener.java @@ -25,6 +25,8 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.m2e.core.MavenPlugin; +import org.eclipse.m2e.core.project.IProjectConfigurationManager; +import org.eclipse.m2e.core.project.ResolverConfiguration; import org.eclipse.m2e.core.ui.internal.UpdateMavenProjectJob; @@ -40,10 +42,10 @@ public class MavenUpdateConfigurationChangeListener implements IResourceChangeLi @Override public void resourceChanged(IResourceChangeEvent event) { - if(isDisabled()) { + if(isAutoConfigurationUpdateDisabled()) { return; } - List outOfDateProjects = null; + List outOfDateProjects; try { OutOfDateConfigurationDeltaVisitor visitor = new OutOfDateConfigurationDeltaVisitor(); event.getDelta().accept(visitor); @@ -52,10 +54,15 @@ public void resourceChanged(IResourceChangeEvent event) { LOG.error("An error occurred while checking for out-of-date configuration markers", e); return; } + IProjectConfigurationManager configManager = MavenPlugin.getProjectConfigurationManager(); + outOfDateProjects = outOfDateProjects.stream().filter(p -> { + ResolverConfiguration configuration = (ResolverConfiguration) configManager.getProjectConfiguration(p); + return configuration.isAutomaticallyUpdateConfiguration(); + }).toList(); updateProjectConfiguration(outOfDateProjects); } - private boolean isDisabled() { + public static boolean isAutoConfigurationUpdateDisabled() { return !MavenPlugin.getMavenConfiguration().isAutomaticallyUpdateConfiguration(); } diff --git a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/project/OutOfDateConfigurationDeltaVisitor.java b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/project/OutOfDateConfigurationDeltaVisitor.java index e9707aee85..a49cdfe843 100644 --- a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/project/OutOfDateConfigurationDeltaVisitor.java +++ b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/project/OutOfDateConfigurationDeltaVisitor.java @@ -35,7 +35,7 @@ */ public class OutOfDateConfigurationDeltaVisitor implements IResourceDeltaVisitor { - List outOfDateProjects = new ArrayList<>(); + final List outOfDateProjects = new ArrayList<>(); @Override public boolean visit(IResourceDelta delta) throws CoreException { diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/ProjectConfigurationManager.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/ProjectConfigurationManager.java index caf9d732b0..817b2a31a6 100644 --- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/ProjectConfigurationManager.java +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/ProjectConfigurationManager.java @@ -885,12 +885,16 @@ public void mavenProjectChanged(List events, IProgress if(facade != null) { ProblemSeverity outOfDateSeverity = ProblemSeverity.get(mavenConfiguration.getOutOfDateProjectSeverity()); - mavenMarkerManager.deleteMarkers(facade.getProject(), IMavenConstants.MARKER_CONFIGURATION_ID); + IProject project = facade.getProject(); + mavenMarkerManager.deleteMarkers(project, IMavenConstants.MARKER_CONFIGURATION_ID); if(!ProblemSeverity.ignore.equals(outOfDateSeverity)) { LifecycleMappingConfiguration oldConfiguration = LifecycleMappingConfiguration.restore(facade, monitor); if(oldConfiguration != null && LifecycleMappingFactory.isLifecycleMappingChanged(facade, oldConfiguration, monitor)) { - mavenMarkerManager.addMarker(facade.getProject(), IMavenConstants.MARKER_CONFIGURATION_ID, + if(!getProjectConfiguration(project).isAutomaticallyUpdateConfiguration()) { + outOfDateSeverity = ProblemSeverity.info; + } + mavenMarkerManager.addMarker(project, IMavenConstants.MARKER_CONFIGURATION_ID, Messages.ProjectConfigurationUpdateRequired, -1, outOfDateSeverity.getSeverity()); } } @@ -936,7 +940,7 @@ public ResolverConfiguration getResolverConfiguration(IProject project) { * @see org.eclipse.m2e.core.project.IProjectConfigurationManager#getProjectConfiguration(org.eclipse.core.resources.IProject) */ @Override - public IProjectConfiguration getProjectConfiguration(IProject project) { + public ResolverConfiguration getProjectConfiguration(IProject project) { return ResolverConfigurationIO.readResolverConfiguration(project); } diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/ResolverConfigurationIO.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/ResolverConfigurationIO.java index b3e2d6976b..a8c52bd317 100644 --- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/ResolverConfigurationIO.java +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/project/ResolverConfigurationIO.java @@ -34,6 +34,7 @@ import org.eclipse.m2e.core.internal.IMavenConstants; import org.eclipse.m2e.core.internal.embedder.MavenProperties; +import org.eclipse.m2e.core.internal.preferences.MavenPreferenceConstants; import org.eclipse.m2e.core.project.IProjectConfiguration; import org.eclipse.m2e.core.project.ResolverConfiguration; @@ -55,6 +56,8 @@ public class ResolverConfigurationIO { */ private static final String P_RESOLVE_WORKSPACE_PROJECTS = "resolveWorkspaceProjects"; //$NON-NLS-1$ + private static final String P_AUTO_UPDATE_CONFIGURATION = MavenPreferenceConstants.P_AUTO_UPDATE_CONFIGURATION; + /** * Active profiles project preference key. Value is comma-separated list of enabled profiles. */ @@ -88,7 +91,9 @@ public static boolean saveResolverConfiguration(IProject project, IProjectConfig projectNode.put(P_VERSION, VERSION); projectNode.putBoolean(P_RESOLVE_WORKSPACE_PROJECTS, configuration.isResolveWorkspaceProjects()); - + if(configuration instanceof ResolverConfiguration resolverConfiguration) { + projectNode.putBoolean(P_AUTO_UPDATE_CONFIGURATION, resolverConfiguration.isAutomaticallyUpdateConfiguration()); + } projectNode.put(P_SELECTED_PROFILES, configuration.getSelectedProfiles()); if(configuration.getLifecycleMappingId() != null) { @@ -113,7 +118,7 @@ public static boolean saveResolverConfiguration(IProject project, IProjectConfig return false; } - public static IProjectConfiguration readResolverConfiguration(IProject project) { + public static ResolverConfiguration readResolverConfiguration(IProject project) { IScopeContext projectScope = new ProjectScope(project); IEclipsePreferences projectNode = projectScope.getNode(IMavenConstants.PLUGIN_ID); if(projectNode == null) { @@ -125,6 +130,7 @@ public static IProjectConfiguration readResolverConfiguration(IProject project) } ResolverConfiguration configuration = new ResolverConfiguration(); configuration.setResolveWorkspaceProjects(projectNode.getBoolean(P_RESOLVE_WORKSPACE_PROJECTS, false)); + configuration.setAutomaticallyUpdateConfiguration(projectNode.getBoolean(P_AUTO_UPDATE_CONFIGURATION, true)); configuration.setSelectedProfiles(projectNode.get(P_SELECTED_PROFILES, "")); //$NON-NLS-1$ configuration.setLifecycleMappingId(projectNode.get(P_LIFECYCLE_MAPPING_ID, (String) null)); configuration.setProperties(stringAsProperties(projectNode.get(P_PROPERTIES, null))); @@ -144,9 +150,7 @@ private static File getBasedir(IEclipsePreferences projectNode, IProject project } private static String propertiesAsString(Map properties) { - String propAsString = properties.entrySet().stream().map(e -> encodeEntry(e)) - .collect(Collectors.joining(PROPERTIES_SEPARATOR)); - return propAsString; + return properties.entrySet().stream().map(e -> encodeEntry(e)).collect(Collectors.joining(PROPERTIES_SEPARATOR)); } private static Properties stringAsProperties(String properties) { diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/ResolverConfiguration.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/ResolverConfiguration.java index 3a325938cb..0ba7307555 100644 --- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/ResolverConfiguration.java +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/project/ResolverConfiguration.java @@ -48,6 +48,8 @@ public class ResolverConfiguration implements Serializable, IProjectConfiguratio private boolean resolveWorkspaceProjects = true; + private boolean automaticallyUpdateConfiguration = true; + private String selectedProfiles = ""; //$NON-NLS-1$ private String lifecycleMappingId; @@ -83,6 +85,9 @@ public ResolverConfiguration(IProjectConfiguration resolverConfiguration) { properties2.putAll(resolverConfiguration.getConfigurationProperties()); setProperties(properties2); setResolveWorkspaceProjects(resolverConfiguration.isResolveWorkspaceProjects()); + if(resolverConfiguration instanceof ResolverConfiguration resolverConfig) { + setAutomaticallyUpdateConfiguration(resolverConfig.isAutomaticallyUpdateConfiguration()); + } setSelectedProfiles(resolverConfiguration.getSelectedProfiles()); } @@ -134,6 +139,11 @@ public boolean isResolveWorkspaceProjects() { return this.resolveWorkspaceProjects; } + /** @noreference this method is not intended to be called by the clients may be changed or removed at any time. */ + public boolean isAutomaticallyUpdateConfiguration() { + return this.automaticallyUpdateConfiguration; + } + /* (non-Javadoc) * @see org.eclipse.m2e.core.project.IProjectConfiguration#getSelectedProfiles() */ @@ -146,13 +156,17 @@ public void setResolveWorkspaceProjects(boolean resolveWorkspaceProjects) { this.resolveWorkspaceProjects = resolveWorkspaceProjects; } + /** @noreference this method is not intended to be called by the clients may be changed or removed at any time. */ + public void setAutomaticallyUpdateConfiguration(boolean automaticallyUpdateConfiguration) { + this.automaticallyUpdateConfiguration = automaticallyUpdateConfiguration; + } + public void setSelectedProfiles(String profiles) { this.selectedProfiles = profiles; this.activeProfiles = parseProfiles(profiles, true); this.inactiveProfiles = parseProfiles(profiles, false); } - /* (non-Javadoc) * @see org.eclipse.m2e.core.project.IProjectConfiguration#getLifecycleMappingId() */