diff --git a/.github/workflows/pr_build_jdk11_dependents.yml b/.github/workflows/pr_build_jdk11_dependents.yml
index efc358086c..81ec441dc2 100644
--- a/.github/workflows/pr_build_jdk11_dependents.yml
+++ b/.github/workflows/pr_build_jdk11_dependents.yml
@@ -35,7 +35,42 @@ jobs:
matrix:
jdk-distribution: [ temurin ]
java-version: [ 11, 17 ]
- ruleset-test: [ WindupRulesTest, WindupRulesLinksTest]
+ ruleset-test: [ WindupRulesTest ]
+ tests-pattern: [ 'rules-reviewed/[a-d]',
+ 'rules-reviewed/e',
+ 'rules-reviewed/[f-z]',
+ 'rules-generated/' ]
+ steps:
+ - name: Checkout repo
+ uses: actions/checkout@v3
+ with:
+ repository: windup/windup-rulesets
+ ref: ${{ github.base_ref }}
+ - name: Set up JDK
+ uses: actions/setup-java@v3
+ with:
+ java-version: ${{ matrix.java-version }}
+ distribution: ${{ matrix.jdk-distribution }}
+ java-package: jdk
+ - name: Cache local Maven repository
+ uses: actions/cache@v3
+ with:
+ path: ~/.m2/repository
+ key: ${{ runner.os }}-maven-windup-rulesets-build-${{ github.sha }}
+ restore-keys: |
+ ${{ runner.os }}-maven-windup-build-${{ github.sha }}
+ - name: Test
+ run: mvn clean test -nsu -f rules -DrunTestsMatching=${{ matrix.tests-pattern }} -Dtest=${{ matrix.ruleset-test }}
+
+ windup-rulesets-links-build:
+ runs-on: ubuntu-latest
+ needs: [windup-build]
+ strategy:
+ fail-fast: false
+ matrix:
+ jdk-distribution: [ temurin ]
+ java-version: [ 11, 17 ]
+ ruleset-test: [ WindupRulesLinksTest ]
steps:
- name: Checkout repo
uses: actions/checkout@v3
@@ -62,7 +97,7 @@ jobs:
windup-maven-plugin-build:
runs-on: ubuntu-latest
- needs: [windup-rulesets-build]
+ needs: [windup-rulesets-links-build]
strategy:
fail-fast: false
matrix:
diff --git a/bom/pom.xml b/bom/pom.xml
index e08620419a..26610b4cdc 100644
--- a/bom/pom.xml
+++ b/bom/pom.xml
@@ -404,12 +404,12 @@
org.eclipse.platform
org.eclipse.core.runtime
- [3.13.0,4.0.0)
+ [3.13.0,3.27.0)
org.eclipse.platform
org.eclipse.core.resources
- [3.14.0,4.0.0)
+ [3.14.0,3.19.0)
io.netty
@@ -419,7 +419,7 @@
org.jsoup
jsoup
- 1.14.3
+ 1.15.3
com.google.guava
diff --git a/config/api/src/main/java/org/jboss/windup/config/projecttraversal/ProjectTraversalCache.java b/config/api/src/main/java/org/jboss/windup/config/projecttraversal/ProjectTraversalCache.java
index 765f75478b..6a7ce3460c 100644
--- a/config/api/src/main/java/org/jboss/windup/config/projecttraversal/ProjectTraversalCache.java
+++ b/config/api/src/main/java/org/jboss/windup/config/projecttraversal/ProjectTraversalCache.java
@@ -71,6 +71,11 @@ public static Set getApplicationsForProject(GraphContext context,
return results;
}
+ public static void clear() {
+ moduleToApplicationCache.clear();
+ applicationToProjectCache.clear();
+ }
+
private static Set getFromCache(ProjectModel project) {
if (project == null)
return null;
diff --git a/config/impl/src/main/java/org/jboss/windup/config/loader/RuleLoaderImpl.java b/config/impl/src/main/java/org/jboss/windup/config/loader/RuleLoaderImpl.java
index daedf05d82..65f00cfd47 100644
--- a/config/impl/src/main/java/org/jboss/windup/config/loader/RuleLoaderImpl.java
+++ b/config/impl/src/main/java/org/jboss/windup/config/loader/RuleLoaderImpl.java
@@ -57,7 +57,7 @@ private RuleProviderRegistry buildRegistry(RuleLoaderContext ruleLoaderContext)
registry.setProviders(providers);
// Get override rules from override providers (if any)
- Map overrideRules = extractOverrideRules(providers);
+ Map overrideRules = extractOverrideRules(providers, ruleLoaderContext);
// Add provider->rules mappings to the registry and, for each rule, inject parameters if applicable
for (RuleProvider provider : providers) {
@@ -166,10 +166,11 @@ private void printRulePhases(List allProviders) {
LOG.info("Rule Phases: [\n" + rulePhaseSB.toString() + "]");
}
- private Map extractOverrideRules(List providers) {
+ private Map extractOverrideRules(List providers, RuleLoaderContext ruleLoaderContext) {
Map overrideRules = new HashMap<>();
providers.stream()
.filter(provider -> provider.getMetadata().isOverrideProvider())
+ .filter(provider -> ruleLoaderContext.getRuleProviderFilter() == null || ruleLoaderContext.getRuleProviderFilter().accept(provider))
.forEach(provider -> {
provider.getConfiguration(null).getRules().forEach(rule -> {
RuleKey ruleKey = new RuleKey(provider.getMetadata().getID(), rule.getId());
diff --git a/config/tests/src/test/java/org/jboss/windup/config/RuleProviderOverrideTest.java b/config/tests/src/test/java/org/jboss/windup/config/RuleProviderOverrideTest.java
index f33980079b..d6bb5ca8c1 100644
--- a/config/tests/src/test/java/org/jboss/windup/config/RuleProviderOverrideTest.java
+++ b/config/tests/src/test/java/org/jboss/windup/config/RuleProviderOverrideTest.java
@@ -1,6 +1,7 @@
package org.jboss.windup.config;
-import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -14,7 +15,9 @@
import org.jboss.windup.config.loader.RuleLoader;
import org.jboss.windup.config.loader.RuleLoaderContext;
import org.jboss.windup.config.metadata.MetadataBuilder;
-import org.jboss.windup.graph.GraphContextFactory;
+import org.jboss.windup.config.metadata.RuleMetadata;
+import org.jboss.windup.config.metadata.Technology;
+import org.jboss.windup.exec.rulefilters.SourceAndTargetPredicate;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -27,14 +30,13 @@
@RunWith(Arquillian.class)
public class RuleProviderOverrideTest {
- @Inject
- private GraphContextFactory factory;
@Inject
private RuleLoader loader;
@Deployment
@AddonDependencies({
@AddonDependency(name = "org.jboss.windup.config:windup-config"),
+ @AddonDependency(name = "org.jboss.windup.exec:windup-exec"),
@AddonDependency(name = "org.jboss.windup.graph:windup-graph"),
@AddonDependency(name = "org.jboss.forge.furnace.container:cdi")
})
@@ -43,15 +45,56 @@ public static AddonArchive getDeployment() {
}
@Test
- public void testOverride() throws IOException {
+ public void testOverride() {
RuleLoaderContext ruleLoaderContext = new RuleLoaderContext();
Configuration configuration = loader.loadConfiguration(ruleLoaderContext).getConfiguration();
int count = 0;
+ boolean foundTestOverrideProvider = false;
+ boolean foundTestOriginalWithTargetProvider = false;
+ for (Rule rule : configuration.getRules()) {
+ count++;
+ if (rule.toString().contains("(RuleOverride)")) foundTestOverrideProvider = true;
+ if (rule.toString().contains("(RuleOverrideWithTarget)")) foundTestOriginalWithTargetProvider = true;
+ }
+ Assert.assertTrue("RuleOverride", foundTestOverrideProvider);
+ Assert.assertTrue("RuleOverrideWithTarget", foundTestOriginalWithTargetProvider);
+ Assert.assertEquals(2, count);
+ }
+
+ @Test
+ public void testOverrideWithTarget() {
+ final SourceAndTargetPredicate targetPredicate = new SourceAndTargetPredicate(Collections.emptyList(), List.of("test-target"));
+ RuleLoaderContext ruleLoaderContext = new RuleLoaderContext(Collections.emptyList(), targetPredicate);
+ Configuration configuration = loader.loadConfiguration(ruleLoaderContext).getConfiguration();
+ int count = 0;
+ boolean foundTestOverrideProvider = false;
+ boolean foundTestOverrideWithTargetProvider = false;
for (Rule rule : configuration.getRules()) {
count++;
- Assert.assertTrue("Override", rule.toString().contains("RuleOverride"));
+ if (rule.toString().contains("(RuleOverride)")) foundTestOverrideProvider = true;
+ if (rule.toString().contains("(RuleOverrideWithTarget)")) foundTestOverrideWithTargetProvider = true;
}
- Assert.assertEquals(1, count);
+ Assert.assertTrue("RuleOverride", foundTestOverrideProvider);
+ Assert.assertTrue("RuleOverrideWithTarget", foundTestOverrideWithTargetProvider);
+ Assert.assertEquals(2, count);
+ }
+
+ @Test
+ public void testOverrideWithAnotherTarget() {
+ final SourceAndTargetPredicate targetPredicate = new SourceAndTargetPredicate(Collections.emptyList(), List.of("another-target"));
+ RuleLoaderContext ruleLoaderContext = new RuleLoaderContext(Collections.emptyList(), targetPredicate);
+ Configuration configuration = loader.loadConfiguration(ruleLoaderContext).getConfiguration();
+ int count = 0;
+ boolean foundTestOverrideProvider = false;
+ boolean foundTestOverrideWithTargetProvider = false;
+ for (Rule rule : configuration.getRules()) {
+ count++;
+ if (rule.toString().contains("(RuleOverride)")) foundTestOverrideProvider = true;
+ if (rule.toString().contains("(OriginalRuleWithTarget)")) foundTestOverrideWithTargetProvider = true;
+ }
+ Assert.assertTrue("RuleOverride", foundTestOverrideProvider);
+ Assert.assertTrue("OriginalRuleWithTarget", foundTestOverrideWithTargetProvider);
+ Assert.assertEquals(2, count);
}
@Singleton
@@ -116,5 +159,70 @@ public String toString() {
});
}
}
+
+ @Singleton
+ public static class TestOriginalWithTargetProvider extends AbstractRuleProvider {
+ public TestOriginalWithTargetProvider() {
+ super(MetadataBuilder.forProvider(TestOriginalProvider.class, "TestRuleProviderWithTarget"));
+ }
+
+ @Override
+ public Configuration getConfiguration(RuleLoaderContext ruleLoaderContext) {
+ return ConfigurationBuilder.begin()
+ .addRule(new Rule() {
+ @Override
+ public void perform(Rewrite event, EvaluationContext context) {
+ }
+
+ @Override
+ public boolean evaluate(Rewrite event, EvaluationContext context) {
+ return true;
+ }
+
+ @Override
+ public String getId() {
+ return TestOriginalProvider.class.getSimpleName();
+ }
+
+ @Override
+ public String toString() {
+ return "OriginalRuleWithTarget";
+ }
+ });
+ }
+ }
+
+ @Singleton
+ @RuleMetadata(targetTechnologies = {@Technology(id = "test-target")})
+ public static class TestOverrideWithTargetProvider extends AbstractRuleProvider {
+ public TestOverrideWithTargetProvider() {
+ super(MetadataBuilder.forProvider(TestOverrideWithTargetProvider.class, "TestRuleProviderWithTarget").setOverrideProvider(true));
+ }
+
+ @Override
+ public Configuration getConfiguration(RuleLoaderContext ruleLoaderContext) {
+ return ConfigurationBuilder.begin()
+ .addRule(new Rule() {
+ @Override
+ public void perform(Rewrite event, EvaluationContext context) {
+ }
+
+ @Override
+ public boolean evaluate(Rewrite event, EvaluationContext context) {
+ return true;
+ }
+
+ @Override
+ public String getId() {
+ return TestOriginalProvider.class.getSimpleName();
+ }
+
+ @Override
+ public String toString() {
+ return "RuleOverrideWithTarget";
+ }
+ });
+ }
+ }
}
}
diff --git a/pf-ui/src/main/webapp/src/pages/application-edit/pages/dashboard/components/efforts-section.tsx b/pf-ui/src/main/webapp/src/pages/application-edit/pages/dashboard/components/efforts-section.tsx
index e8b4eab418..a82877910b 100644
--- a/pf-ui/src/main/webapp/src/pages/application-edit/pages/dashboard/components/efforts-section.tsx
+++ b/pf-ui/src/main/webapp/src/pages/application-edit/pages/dashboard/components/efforts-section.tsx
@@ -172,6 +172,14 @@ export const EffortsSection: React.FC = ({
{
+ return e.totalIncidents === 0 && e.totalStoryPoints === 0;
+ })
+ ? { y: [0, 9] }
+ : undefined
+ }
domainPadding={{ x: 35 }}
padding={{
bottom: 40,
diff --git a/reporting-data/addon/src/main/java/org/jboss/windup/reporting/data/rules/DataGatheringRuleProvider.java b/reporting-data/addon/src/main/java/org/jboss/windup/reporting/data/rules/DataGatheringRuleProvider.java
index 4e1d03b018..eaf0fa0a35 100644
--- a/reporting-data/addon/src/main/java/org/jboss/windup/reporting/data/rules/DataGatheringRuleProvider.java
+++ b/reporting-data/addon/src/main/java/org/jboss/windup/reporting/data/rules/DataGatheringRuleProvider.java
@@ -33,6 +33,8 @@ public void perform(GraphRewrite event, EvaluationContext context) {
executorService.awaitTermination(2, TimeUnit.DAYS);
} catch (InterruptedException e) {
throw new WindupException("Failed to render reports due to a timeout: " + e.getMessage(), e);
+ } finally {
+ AbstractApiRuleProvider.executorServiceMap.remove(event.getGraphContext());
}
}
});
diff --git a/reporting/tests/src/test/java/org/jboss/windup/reporting/CSVExportingTest.java b/reporting/tests/src/test/java/org/jboss/windup/reporting/CSVExportingTest.java
index 65223535a9..6379aad349 100644
--- a/reporting/tests/src/test/java/org/jboss/windup/reporting/CSVExportingTest.java
+++ b/reporting/tests/src/test/java/org/jboss/windup/reporting/CSVExportingTest.java
@@ -97,14 +97,14 @@ private void csvTest(boolean exportCSV) throws Exception {
configuration.setExportingCSV(true);
}
processor.execute(configuration);
- Assert.assertEquals(exportCSV, new File(outputPath + "/" + FILE1_NAME + ".csv").exists());
- Assert.assertEquals(exportCSV, new File(outputPath + "/" + FILE2_NAME + ".csv").exists());
+ Assert.assertEquals(exportCSV, outputPath.resolve(FILE1_NAME + ".csv").toFile().exists());
+ Assert.assertEquals(exportCSV, outputPath.resolve(FILE2_NAME + ".csv").toFile().exists());
if (exportCSV) {
- Path resource = Paths.get("src/test/resources/test-exports/" + FILE1_NAME + ".csv");
- Path resource2 = Paths.get("src/test/resources/test-exports/" + FILE2_NAME + ".csv");
+ Path resource = Paths.get("src", "test", "resources", "test-exports", FILE1_NAME + ".csv");
+ Path resource2 = Paths.get("src", "test", "resources", "test-exports", FILE2_NAME + ".csv");
try {
- Assert.assertTrue(checkFileAreSame(resource.toString(), outputPath + "/" + FILE1_NAME + ".csv"));
- Assert.assertTrue(checkFileAreSame(resource2.toString(), outputPath + "/" + FILE2_NAME + ".csv"));
+ Assert.assertTrue(checkFileAreSame(resource.toString(), outputPath.resolve(FILE1_NAME + ".csv").toString()));
+ Assert.assertTrue(checkFileAreSame(resource2.toString(), outputPath.resolve(FILE2_NAME + ".csv").toString()));
} catch (IOException ex) {
Assert.fail("Exception was thrown while checking if the exported CSV file looks like expected. Exception: " + ex);
}
@@ -182,9 +182,39 @@ private boolean checkFileAreSame(String filePath1, String filePath2) throws IOEx
if (linesFile1.size() != linesFile2.size())
return false;
- for (String line1 : linesFile1) {
- if (!linesFile2.contains(line1))
- return false;
+ final String csvColumnRegex = ",(?=([^\"]*\"[^\"]*\")*[^\"]*$)";
+
+ String[][] file1RowsAndColumns = linesFile1.stream()
+ .map(row -> row.split(csvColumnRegex))
+ .toArray(String[][]::new);
+ String[][] file2RowsAndColumns = linesFile2.stream()
+ .map(row -> row.split(csvColumnRegex))
+ .toArray(String[][]::new);
+
+ // Verify that each cell from file1 exists in file2
+ for (int i = 0; i < file1RowsAndColumns.length; i++) {
+ for (int j = 0; j < file1RowsAndColumns[i].length; j++) {
+ // Skip 'File Path' column since its value is not deterministic
+ // and depends on the OS.
+ if (j == 7) {
+ continue;
+ }
+
+ String cellFile1 = file1RowsAndColumns[i][j];
+ boolean cellMatches = false;
+
+ for (int x = 0; x < file2RowsAndColumns.length; x++) {
+ String cellFile2 = file2RowsAndColumns[x][j];
+ if (cellFile1.equals(cellFile2)) {
+ cellMatches = true;
+ break;
+ }
+ }
+
+ if (!cellMatches) {
+ return false;
+ }
+ }
}
return true;
diff --git a/rules-java/api/src/main/java/org/jboss/windup/rules/apps/java/scan/provider/ClearProjectTraversalCacheRuleProvider.java b/rules-java/api/src/main/java/org/jboss/windup/rules/apps/java/scan/provider/ClearProjectTraversalCacheRuleProvider.java
new file mode 100644
index 0000000000..1bd39efe70
--- /dev/null
+++ b/rules-java/api/src/main/java/org/jboss/windup/rules/apps/java/scan/provider/ClearProjectTraversalCacheRuleProvider.java
@@ -0,0 +1,30 @@
+package org.jboss.windup.rules.apps.java.scan.provider;
+
+import org.jboss.windup.config.AbstractRuleProvider;
+import org.jboss.windup.config.GraphRewrite;
+import org.jboss.windup.config.loader.RuleLoaderContext;
+import org.jboss.windup.config.metadata.RuleMetadata;
+import org.jboss.windup.config.operation.GraphOperation;
+import org.jboss.windup.config.phase.FinalizePhase;
+import org.jboss.windup.config.projecttraversal.ProjectTraversalCache;
+import org.ocpsoft.rewrite.config.Configuration;
+import org.ocpsoft.rewrite.config.ConfigurationBuilder;
+import org.ocpsoft.rewrite.context.EvaluationContext;
+
+/**
+ * Clear the caches used in the {@link ProjectTraversalCache}
+ */
+@RuleMetadata(phase = FinalizePhase.class)
+public class ClearProjectTraversalCacheRuleProvider extends AbstractRuleProvider {
+ @Override
+ public Configuration getConfiguration(RuleLoaderContext ruleLoaderContext) {
+ return ConfigurationBuilder.begin()
+ .addRule()
+ .perform(new GraphOperation() {
+ @Override
+ public void perform(GraphRewrite event, EvaluationContext context) {
+ ProjectTraversalCache.clear();
+ }
+ });
+ }
+}