Skip to content

Commit

Permalink
Make automatic configuration updates configurable per project
Browse files Browse the repository at this point in the history
And degrade problems about out-dated project configuration to severity
'info', if automatic updates are disabled for a project.

Fixes #1661
  • Loading branch information
HannesWell committed Feb 4, 2024
1 parent 086955c commit 2688bc9
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 33 deletions.
7 changes: 7 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
8 changes: 7 additions & 1 deletion org.eclipse.m2e.core.ui/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: org.eclipse.m2e.core.ui;singleton:=true
Bundle-Version: 2.0.8.qualifier
Bundle-Version: 2.0.800.qualifier
Bundle-RequiredExecutionEnvironment: JavaSE-17
Bundle-Name: %Bundle-Name
Bundle-Vendor: %Bundle-Vendor
Expand Down Expand Up @@ -56,3 +56,9 @@ Service-Component: OSGI-INF/component.xml,
OSGI-INF/org.eclipse.m2e.core.ui.internal.archetype.ArchetypeGenerator.xml,
OSGI-INF/org.eclipse.m2e.core.ui.internal.archetype.ArchetypePlugin.xml
Automatic-Module-Name: org.eclipse.m2e.core.ui
Service-Component: OSGI-INF/org.eclipse.m2e.core.ui.internal.archetype.ArchetypeGenerator.xml,
OSGI-INF/org.eclipse.m2e.core.ui.internal.archetype.ArchetypePlugin.xml
Bundle-ActivationPolicy: lazy
Service-Component: OSGI-INF/org.eclipse.m2e.core.ui.internal.archetype.ArchetypeGenerator.xml,
OSGI-INF/org.eclipse.m2e.core.ui.internal.archetype.ArchetypePlugin.xml
Bundle-ActivationPolicy: lazy
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,12 @@

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.internal.preferences.MavenPreferenceInitializer;
import org.eclipse.m2e.core.internal.project.ResolverConfigurationIO;
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;


/**
Expand All @@ -52,6 +54,8 @@ public class MavenProjectPreferencePage extends PropertyPage {

private Button resolveWorspaceProjectsButton;

private Button autoUpdateConfigurationButton;

// private Button includeModulesButton;

private Text selectedProfilesText;
Expand All @@ -74,10 +78,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;
Expand All @@ -100,16 +112,19 @@ protected Control createContents(Composite parent) {

init(getResolverConfiguration());

boolean isAutoUpdate = ResolverConfigurationIO.isAutomaticallyUpdateConfiguration(getProject());
autoUpdateConfigurationButton.setSelection(isAutoUpdate);

return composite;
}

@Override
protected void performDefaults() {
init(new ResolverConfiguration());
autoUpdateConfigurationButton.setSelection(MavenPreferenceInitializer.P_AUTO_UPDATE_CONFIGURATION_DEFAULT);
}

private void init(IProjectConfiguration configuration) {

private void init(ResolverConfiguration configuration) {
resolveWorspaceProjectsButton.setSelection(configuration.isResolveWorkspaceProjects());
// includeModulesButton.setSelection(configuration.shouldIncludeModules());
selectedProfilesText.setText(configuration.getSelectedProfiles());
Expand All @@ -130,11 +145,14 @@ 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()
&& ResolverConfigurationIO.isAutomaticallyUpdateConfiguration(project) == autoUpdateConfigurationButton
.getSelection()) {
return true;
}

configuration.setResolveWorkspaceProjects(resolveWorspaceProjectsButton.getSelection());
ResolverConfigurationIO.setAutomaticallyUpdateConfiguration(project, autoUpdateConfigurationButton.getSelection());
// configuration.setIncludeModules(includeModulesButton.getSelection());
configuration.setSelectedProfiles(selectedProfilesText.getText());

Expand Down Expand Up @@ -165,9 +183,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() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.eclipse.core.runtime.CoreException;

import org.eclipse.m2e.core.MavenPlugin;
import org.eclipse.m2e.core.internal.project.ResolverConfigurationIO;
import org.eclipse.m2e.core.ui.internal.UpdateMavenProjectJob;


Expand All @@ -40,10 +41,10 @@ public class MavenUpdateConfigurationChangeListener implements IResourceChangeLi

@Override
public void resourceChanged(IResourceChangeEvent event) {
if(isDisabled()) {
if(isAutoConfigurationUpdateDisabled()) {
return;
}
List<IProject> outOfDateProjects = null;
List<IProject> outOfDateProjects;
try {
OutOfDateConfigurationDeltaVisitor visitor = new OutOfDateConfigurationDeltaVisitor();
event.getDelta().accept(visitor);
Expand All @@ -52,10 +53,12 @@ public void resourceChanged(IResourceChangeEvent event) {
LOG.error("An error occurred while checking for out-of-date configuration markers", e);
return;
}
outOfDateProjects = outOfDateProjects.stream() //
.filter(ResolverConfigurationIO::isAutomaticallyUpdateConfiguration).toList();
updateProjectConfiguration(outOfDateProjects);
}

private boolean isDisabled() {
public static boolean isAutoConfigurationUpdateDisabled() {
return !MavenPlugin.getMavenConfiguration().isAutomaticallyUpdateConfiguration();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
*/
public class OutOfDateConfigurationDeltaVisitor implements IResourceDeltaVisitor {

List<IProject> outOfDateProjects = new ArrayList<>();
final List<IProject> outOfDateProjects = new ArrayList<>();

@Override
public boolean visit(IResourceDelta delta) throws CoreException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
*/
public class MavenPreferenceInitializer extends AbstractPreferenceInitializer {

public static final boolean P_AUTO_UPDATE_CONFIGURATION_DEFAULT = true;

@Override
public void initializeDefaultPreferences() {
IEclipsePreferences store = DefaultScope.INSTANCE.getNode(IMavenConstants.PLUGIN_ID);
Expand Down Expand Up @@ -63,7 +65,7 @@ public void initializeDefaultPreferences() {
// set to null since the plugin state location is not available by the time execution reaches here
store.remove(MavenPreferenceConstants.P_WORKSPACE_MAPPINGS_LOCATION);

store.putBoolean(MavenPreferenceConstants.P_AUTO_UPDATE_CONFIGURATION, true);
store.putBoolean(MavenPreferenceConstants.P_AUTO_UPDATE_CONFIGURATION, P_AUTO_UPDATE_CONFIGURATION_DEFAULT);

store.putBoolean(MavenPreferenceConstants.P_ENABLE_SNAPSHOT_ARCHETYPES, false);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -885,12 +885,16 @@ public void mavenProjectChanged(List<MavenProjectChangedEvent> 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(!ResolverConfigurationIO.isAutomaticallyUpdateConfiguration(project)) {
outOfDateSeverity = ProblemSeverity.info;
}
mavenMarkerManager.addMarker(project, IMavenConstants.MARKER_CONFIGURATION_ID,
Messages.ProjectConfigurationUpdateRequired, -1, outOfDateSeverity.getSeverity());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,11 @@
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.IScopeContext;

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.internal.preferences.MavenPreferenceInitializer;
import org.eclipse.m2e.core.project.IProjectConfiguration;
import org.eclipse.m2e.core.project.ResolverConfiguration;

Expand All @@ -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.
*/
Expand Down Expand Up @@ -82,13 +85,11 @@ public class ResolverConfigurationIO {
private static final String VERSION = "1"; //$NON-NLS-1$

public static boolean saveResolverConfiguration(IProject project, IProjectConfiguration configuration) {
IScopeContext projectScope = new ProjectScope(project);
IEclipsePreferences projectNode = projectScope.getNode(IMavenConstants.PLUGIN_ID);
IEclipsePreferences projectNode = getMavenProjectPreferences(project);
if(projectNode != null) {
projectNode.put(P_VERSION, VERSION);

projectNode.putBoolean(P_RESOLVE_WORKSPACE_PROJECTS, configuration.isResolveWorkspaceProjects());

projectNode.put(P_SELECTED_PROFILES, configuration.getSelectedProfiles());

if(configuration.getLifecycleMappingId() != null) {
Expand All @@ -101,21 +102,13 @@ public static boolean saveResolverConfiguration(IProject project, IProjectConfig
} else {
projectNode.remove(P_PROPERTIES);
}

try {
projectNode.flush();
return true;
} catch(BackingStoreException ex) {
log.error("Failed to save resolver configuration", ex);
}
return savePreferences(projectNode);
}

return false;
}

public static IProjectConfiguration readResolverConfiguration(IProject project) {
IScopeContext projectScope = new ProjectScope(project);
IEclipsePreferences projectNode = projectScope.getNode(IMavenConstants.PLUGIN_ID);
IEclipsePreferences projectNode = getMavenProjectPreferences(project);
if(projectNode == null) {
return new ResolverConfiguration(project);
}
Expand All @@ -132,6 +125,34 @@ public static IProjectConfiguration readResolverConfiguration(IProject project)
return configuration;
}

public static boolean isAutomaticallyUpdateConfiguration(IProject project) {
IEclipsePreferences preferences = getMavenProjectPreferences(project);
boolean defaultValue = MavenPreferenceInitializer.P_AUTO_UPDATE_CONFIGURATION_DEFAULT;
return preferences != null ? preferences.getBoolean(P_AUTO_UPDATE_CONFIGURATION, defaultValue) : defaultValue;
}

public static void setAutomaticallyUpdateConfiguration(IProject project, boolean isAutomaticallyUpdateConfiguration) {
IEclipsePreferences preferences = getMavenProjectPreferences(project);
if(preferences != null) {
preferences.putBoolean(P_AUTO_UPDATE_CONFIGURATION, isAutomaticallyUpdateConfiguration);
savePreferences(preferences);
}
}

private static IEclipsePreferences getMavenProjectPreferences(IProject project) {
return new ProjectScope(project).getNode(IMavenConstants.PLUGIN_ID);
}

private static boolean savePreferences(IEclipsePreferences node) {
try {
node.flush();
return true;
} catch(BackingStoreException ex) {
log.error("Failed to save resolver configuration", ex);
}
return false;
}

private static File getBasedir(IEclipsePreferences projectNode, IProject project) {
String basedirSetting = projectNode.get(P_BASEDIR, null);
if(basedirSetting != null) {
Expand All @@ -144,9 +165,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) {
Expand Down

0 comments on commit 2688bc9

Please sign in to comment.