Preference setting for white-listing recipes
This commit is contained in:
@@ -33,6 +33,8 @@ public class Constants {
|
||||
|
||||
public static final String PREF_REWRITE_RECONCILE = "boot-java.rewrite.reconcile";
|
||||
|
||||
public static final String PREF_REWRITE_RECIPE_FILTERS = "boot-java.rewrite.recipe-filters";
|
||||
|
||||
public static final String PREF_REWRITE_RECIPES_SCAN_FILES = "boot-java.rewrite.scan-files";
|
||||
|
||||
public static final String PREF_REWRITE_RECIPES_SCAN_DIRS = "boot-java.rewrite.scan-directories";
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.springframework.tooling.boot.ls.prefs.CategoryProblemsSeverityPrefsPa
|
||||
import org.springframework.tooling.boot.ls.prefs.FileListEditor;
|
||||
import org.springframework.tooling.boot.ls.prefs.ProblemCategoryData;
|
||||
import org.springframework.tooling.boot.ls.prefs.ProblemCategoryData.CategoryToggleData;
|
||||
import org.springframework.tooling.boot.ls.prefs.StringListEditor;
|
||||
import org.springsource.ide.eclipse.commons.boot.ls.remoteapps.RemoteBootAppsDataHolder;
|
||||
import org.springsource.ide.eclipse.commons.boot.ls.remoteapps.RemoteBootAppsDataHolder.RemoteAppData;
|
||||
import org.springsource.ide.eclipse.commons.livexp.core.ValueListener;
|
||||
@@ -191,6 +192,7 @@ public class DelegatingStreamConnectionProvider implements StreamConnectionProvi
|
||||
|
||||
bootJavaObj.put("rewrite", Map.of(
|
||||
"reconcile", preferenceStore.getBoolean(Constants.PREF_REWRITE_RECONCILE),
|
||||
"recipe-filters", StringListEditor.decode(preferenceStore.getString(Constants.PREF_REWRITE_RECIPE_FILTERS)),
|
||||
"scan-directories", FileListEditor.getValuesFromPreference(preferenceStore.getString(Constants.PREF_REWRITE_RECIPES_SCAN_DIRS)),
|
||||
"scan-files", FileListEditor.getValuesFromPreference(preferenceStore.getString(Constants.PREF_REWRITE_RECIPES_SCAN_FILES))
|
||||
));
|
||||
|
||||
@@ -12,6 +12,7 @@ package org.springframework.tooling.boot.ls;
|
||||
|
||||
import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
|
||||
import org.eclipse.jface.preference.IPreferenceStore;
|
||||
import org.springframework.tooling.boot.ls.prefs.StringListEditor;
|
||||
|
||||
/**
|
||||
* Preferences initializer for Boot-Java LS extension
|
||||
@@ -42,6 +43,19 @@ public class PrefsInitializer extends AbstractPreferenceInitializer {
|
||||
preferenceStore.setDefault(Constants.PREF_SCAN_JAVA_TEST_SOURCES, false);
|
||||
|
||||
preferenceStore.setDefault(Constants.PREF_REWRITE_RECONCILE, false);
|
||||
|
||||
preferenceStore.setDefault(Constants.PREF_REWRITE_RECIPE_FILTERS, StringListEditor.encode(new String[] {
|
||||
"org.openrewrite.java.spring.boot2.SpringBoot2JUnit4to5Migration",
|
||||
"org.openrewrite.java.spring.boot2.SpringBoot2BestPractices",
|
||||
"org.openrewrite.java.spring.boot2.SpringBoot1To2Migration",
|
||||
"org.openrewrite.java.testing.junit5.JUnit5BestPractices",
|
||||
"org.openrewrite.java.testing.junit5.JUnit4to5Migration",
|
||||
"org.openrewrite.java.spring.boot2.UpgradeSpringBoot_2_6",
|
||||
"org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_0",
|
||||
"org.rewrite.java.security.*",
|
||||
"org.springframework.rewrite.test.*",
|
||||
"rewrite.test.*"
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.ui.IWorkbench;
|
||||
import org.eclipse.ui.IWorkbenchPreferencePage;
|
||||
import org.springframework.tooling.boot.ls.prefs.FileListEditor;
|
||||
import org.springframework.tooling.boot.ls.prefs.StringListEditor;
|
||||
|
||||
public class RewritePreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage {
|
||||
|
||||
@@ -21,11 +22,18 @@ public class RewritePreferencePage extends FieldEditorPreferencePage implements
|
||||
protected void createFieldEditors() {
|
||||
Composite fieldEditorParent = getFieldEditorParent();
|
||||
|
||||
addField(new BooleanFieldEditor(Constants.PREF_REWRITE_RECONCILE, "Experimental reconciling for Java source based on Rewrite project", fieldEditorParent));
|
||||
addField(new BooleanFieldEditor(Constants.PREF_REWRITE_RECONCILE,
|
||||
"Experimental reconciling for Java source based on Rewrite project", fieldEditorParent));
|
||||
|
||||
addField(new FileListEditor(Constants.PREF_REWRITE_RECIPES_SCAN_FILES, "JAR and YAML files to scan for Recipes", "Select JARs and YAML files:", fieldEditorParent, List.of("jar", "yml", "yaml")));
|
||||
addField(new StringListEditor(fieldEditorParent, Constants.PREF_REWRITE_RECIPE_FILTERS,
|
||||
"Recipe filter IDs and patterns", "Filter Value",
|
||||
"Either exact ID or pattern with '*' as the wild-card:", text -> text.isBlank() ? "Cannot be blank" : null));
|
||||
|
||||
addField(new PathEditor(Constants.PREF_REWRITE_RECIPES_SCAN_DIRS, "Directories to scan for Recipes", "Select directory to scan for Recipes", fieldEditorParent));
|
||||
addField(new FileListEditor(Constants.PREF_REWRITE_RECIPES_SCAN_FILES, "JAR and YAML files to scan for Recipes",
|
||||
"Select JARs and YAML files:", fieldEditorParent, List.of("jar", "yml", "yaml")));
|
||||
|
||||
addField(new PathEditor(Constants.PREF_REWRITE_RECIPES_SCAN_DIRS, "Directories to scan for Recipes",
|
||||
"Select directory to scan for Recipes", fieldEditorParent));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2022 VMware, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* VMware, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.tooling.boot.ls.prefs;
|
||||
|
||||
import org.eclipse.jface.dialogs.IDialogConstants;
|
||||
import org.eclipse.jface.dialogs.IInputValidator;
|
||||
import org.eclipse.jface.dialogs.InputDialog;
|
||||
import org.eclipse.jface.preference.ListEditor;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
|
||||
public class StringListEditor extends ListEditor {
|
||||
|
||||
private static final String DELIMITER = "---";
|
||||
|
||||
private String promptTitle;
|
||||
private String promptMessage;
|
||||
private IInputValidator validator;
|
||||
|
||||
public static String encode(String[] items) {
|
||||
return String.join(DELIMITER, items);
|
||||
}
|
||||
|
||||
public static String[] decode(String value) {
|
||||
return value.split(DELIMITER);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String createList(String[] items) {
|
||||
return encode(items);
|
||||
}
|
||||
|
||||
public StringListEditor(Composite parent, String name, String label, String promptTitle, String promptMessage, IInputValidator validator) {
|
||||
super(name, label, parent);
|
||||
this.promptTitle = promptTitle;
|
||||
this.promptMessage = promptMessage;
|
||||
this.validator = validator;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getNewInputObject() {
|
||||
InputDialog dialog = new InputDialog(getShell(), promptTitle, promptMessage, "", validator);
|
||||
if (dialog.open() == IDialogConstants.OK_ID) {
|
||||
return dialog.getValue();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] parseString(String stringList) {
|
||||
return decode(stringList);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -167,6 +167,10 @@ public class BootJavaConfig implements InitializingBean {
|
||||
public Set<String> getRecipeDirectories() {
|
||||
return settings.getStringSet("boot-java", "rewrite", "scan-directories");
|
||||
}
|
||||
|
||||
public Set<String> getRecipesFilters() {
|
||||
return settings.getStringSet("boot-java", "rewrite", "recipe-filters");
|
||||
}
|
||||
|
||||
public Set<String> getRecipeFiles() {
|
||||
return settings.getStringSet("boot-java", "rewrite", "scan-files");
|
||||
|
||||
@@ -16,6 +16,7 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.openrewrite.config.Environment;
|
||||
@@ -23,10 +24,21 @@ import org.openrewrite.config.OptionDescriptor;
|
||||
import org.openrewrite.config.RecipeDescriptor;
|
||||
|
||||
public class RecipesDescriptionGenerator {
|
||||
|
||||
private static final Set<String> TOP_LEVEL_RECIPES = Set.of(
|
||||
"org.openrewrite.java.spring.boot2.SpringBoot2JUnit4to5Migration",
|
||||
"org.openrewrite.java.spring.boot2.SpringBoot2BestPractices",
|
||||
"org.openrewrite.java.spring.boot2.SpringBoot1To2Migration",
|
||||
"org.openrewrite.java.testing.junit5.JUnit5BestPractices",
|
||||
"org.openrewrite.java.testing.junit5.JUnit4to5Migration",
|
||||
"org.openrewrite.java.spring.boot2.UpgradeSpringBoot_2_6",
|
||||
"org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_0"
|
||||
);
|
||||
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
String s = Environment.builder().scanRuntimeClasspath().build().listRecipeDescriptors().stream()
|
||||
.filter(d -> RewriteRecipeRepository.TOP_LEVEL_RECIPES.contains(d.getName()))
|
||||
.filter(d -> TOP_LEVEL_RECIPES.contains(d.getName()))
|
||||
.map(d -> convertToMarkdown(d, 1))
|
||||
.collect(Collectors.joining("\n\n"));
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@@ -107,17 +108,8 @@ public class RewriteRecipeRepository implements ApplicationContextAware {
|
||||
|
||||
private Set<String> scanFiles = Collections.emptySet();
|
||||
private Set<String> scanDirs = Collections.emptySet();
|
||||
|
||||
static final Set<String> TOP_LEVEL_RECIPES = Set.of(
|
||||
"org.openrewrite.java.spring.boot2.SpringBoot2JUnit4to5Migration",
|
||||
"org.openrewrite.java.spring.boot2.SpringBoot2BestPractices",
|
||||
"org.openrewrite.java.spring.boot2.SpringBoot1To2Migration",
|
||||
"org.openrewrite.java.testing.junit5.JUnit5BestPractices",
|
||||
"org.openrewrite.java.testing.junit5.JUnit4to5Migration",
|
||||
"org.openrewrite.java.spring.boot2.UpgradeSpringBoot_2_6",
|
||||
"org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_0"
|
||||
);
|
||||
|
||||
private Set<String> recipeFilters = Collections.emptySet();
|
||||
|
||||
private static Gson serializationGson = new GsonBuilder()
|
||||
.registerTypeAdapter(Duration.class, new DurationTypeConverter())
|
||||
.create();
|
||||
@@ -134,6 +126,7 @@ public class RewriteRecipeRepository implements ApplicationContextAware {
|
||||
server.doOnInitialized(() -> {
|
||||
this.scanDirs = config.getRecipeDirectories();
|
||||
this.scanFiles = config.getRecipeFiles();
|
||||
this.recipeFilters = config.getRecipesFilters();
|
||||
load().thenAccept(v -> registerCommands());
|
||||
config.addListener(l -> {
|
||||
if (!scanDirs.equals(config.getRecipeDirectories())
|
||||
@@ -144,6 +137,11 @@ public class RewriteRecipeRepository implements ApplicationContextAware {
|
||||
scanFiles = config.getRecipeFiles();
|
||||
load();
|
||||
}
|
||||
Set<String> recipeFilterFromConfig = config.getRecipesFilters();
|
||||
if (!recipeFilters.equals(recipeFilterFromConfig)) {
|
||||
recipeFilters = recipeFilterFromConfig;
|
||||
updateGlobalCommandRecipes();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -176,19 +174,9 @@ public class RewriteRecipeRepository implements ApplicationContextAware {
|
||||
}
|
||||
recipes.put(r.getName(), r);
|
||||
|
||||
if (TOP_LEVEL_RECIPES.contains(r.getName()) || r.getName().startsWith("rewrite.test.")
|
||||
|| r.getName().startsWith("org.rewrite.java.security")
|
||||
|| r.getName().startsWith("org.springframework.rewrite.test")) {
|
||||
Validated validation = Validated.invalid(null, null, null);
|
||||
try {
|
||||
validation = r.validate();
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
if (validation.isValid()) {
|
||||
globalCommandRecipes.add(r);
|
||||
}
|
||||
}
|
||||
if (isAcceptableGlobalCommandRecipe(r)) {
|
||||
globalCommandRecipes.add(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
javaProblemDescriptors.addAll(env.listProblemDescriptors());
|
||||
@@ -201,6 +189,45 @@ public class RewriteRecipeRepository implements ApplicationContextAware {
|
||||
}
|
||||
}
|
||||
|
||||
private void updateGlobalCommandRecipes() {
|
||||
globalCommandRecipes.clear();
|
||||
for (Recipe r : recipes.values()) {
|
||||
if (isAcceptableGlobalCommandRecipe(r)) {
|
||||
globalCommandRecipes.add(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isAcceptableGlobalCommandRecipe(Recipe r) {
|
||||
for (String filter : recipeFilters) {
|
||||
if (!filter.isBlank()) {
|
||||
// Check if wild-card character present
|
||||
if (filter.indexOf('*') < 0) {
|
||||
// No wild-card - direct equality
|
||||
if (filter.equals(r.getName())) {
|
||||
return isRecipeValid(r);
|
||||
}
|
||||
} else {
|
||||
// Wild-card present - convert to regular expression
|
||||
if (Pattern.matches(filter.replaceAll("\\*", "\\.*"), r.getName())) {
|
||||
return isRecipeValid(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isRecipeValid(Recipe r) {
|
||||
Validated validation = Validated.invalid(null, null, null);
|
||||
try {
|
||||
validation = r.validate();
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
return validation.isValid();
|
||||
}
|
||||
|
||||
private StsEnvironment createRewriteEnvironment() {
|
||||
StsEnvironment.Builder builder = (StsEnvironment.Builder) StsEnvironment.builder().scanRuntimeClasspath();
|
||||
for (String p : scanFiles) {
|
||||
|
||||
@@ -198,6 +198,25 @@
|
||||
"default": false,
|
||||
"description": "Experimental reconciling for Java source based on Rewrite project"
|
||||
},
|
||||
"boot-java.rewrite.recipe-filters": {
|
||||
"type": "array",
|
||||
"default": [
|
||||
"org.openrewrite.java.spring.boot2.SpringBoot2JUnit4to5Migration",
|
||||
"org.openrewrite.java.spring.boot2.SpringBoot2BestPractices",
|
||||
"org.openrewrite.java.spring.boot2.SpringBoot1To2Migration",
|
||||
"org.openrewrite.java.testing.junit5.JUnit5BestPractices",
|
||||
"org.openrewrite.java.testing.junit5.JUnit4to5Migration",
|
||||
"org.openrewrite.java.spring.boot2.UpgradeSpringBoot_2_6",
|
||||
"org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_0",
|
||||
"org.rewrite.java.security.*",
|
||||
"org.springframework.rewrite.test.*",
|
||||
"rewrite.test.*"
|
||||
],
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Recipe ID filter patterns. Either exact ids or patterns with '*' as the wild-card"
|
||||
},
|
||||
"boot-java.rewrite.scan-files": {
|
||||
"type": "array",
|
||||
"default": [],
|
||||
|
||||
Reference in New Issue
Block a user