Skip to content

Commit 2dce22b

Browse files
committed
Fix DevCenter validation, add ordinal position to SecurityIssues
1 parent 9e9c0cd commit 2dce22b

7 files changed

Lines changed: 101 additions & 23 deletions

File tree

src/main/java/io/moderne/devcenter/DevCenter.java

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,16 @@ public void validate() throws DevCenterValidationException {
4444
validationErrors.add("Only one security recipe can be included.");
4545
}
4646
for (UpgradeOrMigration upgradesAndMigration : upgradesAndMigrations) {
47-
//noinspection ConstantValue
48-
if (upgradesAndMigration.getFixRecipeId() == null) {
49-
validationErrors.add("Recipe " + upgradesAndMigration.getRecipeName() +
50-
" is missing a fix recipe. Please add a tag `DevCenter:fix:<RECIPE_ID>` to the recipe.");
47+
if (upgradesAndMigration.getRecipesContributingMeasures().isEmpty()) {
48+
validationErrors.add("Recipe `" + upgradesAndMigration.getRecipeId() + "` " +
49+
"with a `DevCenter:fix:<RECIPE_ID>` tag should either directly or have " +
50+
"a subrecipe contributing rows to the `UpgradesAndMigrations` data table.");
5151
}
5252
}
5353

54-
throw new DevCenterValidationException(validationErrors);
54+
if (!validationErrors.isEmpty()) {
55+
throw new DevCenterValidationException(validationErrors);
56+
}
5557
}
5658

5759
public List<UpgradeOrMigration> getUpgradesAndMigrations() {
@@ -67,13 +69,12 @@ public Security getSecurity() {
6769
private List<UpgradeOrMigration> getUpgradesAndMigrationsRecursive(RecipeDescriptor recipeDescriptor,
6870
List<UpgradeOrMigration> upgradesAndMigrations) {
6971
for (RecipeDescriptor recipe : recipeDescriptor.getRecipeList()) {
70-
for (DataTableDescriptor dataTable : recipe.getDataTables()) {
71-
if (dataTable.getName().equals(new UpgradesAndMigrations(Recipe.noop()).getDisplayName())) {
72-
//noinspection DataFlowIssue
73-
upgradesAndMigrations.add(new UpgradeOrMigration(
74-
recipe.getInstanceName(), recipe.getName(), fixRecipe(recipeDescriptor)
75-
));
76-
}
72+
String fixRecipe = fixRecipe(recipe);
73+
if (fixRecipe != null) {
74+
upgradesAndMigrations.add(new UpgradeOrMigration(recipe.getDisplayName(),
75+
recipe.getName(),
76+
fixRecipe,
77+
getRecipesContributingMeasures(recipe, new ArrayList<>())));
7778
}
7879
for (RecipeDescriptor subRecipe : recipe.getRecipeList()) {
7980
getUpgradesAndMigrationsRecursive(subRecipe, upgradesAndMigrations);
@@ -82,6 +83,18 @@ private List<UpgradeOrMigration> getUpgradesAndMigrationsRecursive(RecipeDescrip
8283
return upgradesAndMigrations;
8384
}
8485

86+
private List<RecipeDescriptor> getRecipesContributingMeasures(RecipeDescriptor recipe, List<RecipeDescriptor> contributors) {
87+
for (DataTableDescriptor dataTable : recipe.getDataTables()) {
88+
if (dataTable.getName().equals(new UpgradesAndMigrations(Recipe.noop()).getName())) {
89+
contributors.add(recipe);
90+
}
91+
}
92+
for (RecipeDescriptor subRecipe : recipe.getRecipeList()) {
93+
getRecipesContributingMeasures(subRecipe, contributors);
94+
}
95+
return contributors;
96+
}
97+
8598
@Nullable
8699
private String fixRecipe(RecipeDescriptor recipeDescriptor) {
87100
for (String tag : recipeDescriptor.getTags()) {
@@ -109,8 +122,10 @@ private List<Security> getSecurityRecursive(RecipeDescriptor recipeDescriptor, L
109122
@Value
110123
public static class UpgradeOrMigration {
111124
String displayName;
112-
String recipeName;
125+
String recipeId;
113126
String fixRecipeId;
127+
128+
List<RecipeDescriptor> recipesContributingMeasures;
114129
}
115130

116131
@Value

src/main/java/io/moderne/devcenter/ReportAsSecurityIssues.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,17 @@ public Tree preVisit(Tree tree, ExecutionContext ctx) {
5353
tree.getMarkers().findFirst(RecipesThatMadeChanges.class).ifPresent(changes -> {
5454
for (List<Recipe> recipeStack : changes.getRecipes()) {
5555
for (int i = 0; i < recipeStack.size(); i++) {
56-
if (recipeStack.get(i).getTags().contains("DevCenter:security")) {
57-
securityIssues.insertRow(ctx, new SecurityIssues.Row(
58-
recipeStack.get(i + 1).getInstanceName()
59-
));
56+
Recipe recipe = recipeStack.get(i);
57+
if (recipe.getTags().contains("DevCenter:security")) {
58+
Recipe measure = recipeStack.get(i + 1);
59+
List<Recipe> recipeList = recipe.getRecipeList();
60+
for (int j = 0; j < recipeList.size(); j++) {
61+
if (recipeList.get(j).getName().equals(measure.getName())) {
62+
securityIssues.insertRow(ctx, new SecurityIssues.Row(
63+
j, measure.getInstanceName()));
64+
break;
65+
}
66+
}
6067
}
6168
}
6269
}

src/main/java/io/moderne/devcenter/table/SecurityIssues.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,17 @@
2323
public class SecurityIssues extends DataTable<SecurityIssues.Row> {
2424

2525
public SecurityIssues(Recipe recipe) {
26-
super(recipe,
27-
"Security issues",
28-
"Security issues in the repository."
29-
);
26+
super(recipe, "Security issues", "Security issues in the repository.");
3027
}
3128

3229
@Value
3330
public static class Row {
31+
@Column(
32+
displayName = "Ordinal",
33+
description = "The ordinal position of this issue relative to other issues."
34+
)
35+
int ordinal;
36+
3437
@Column(
3538
displayName = "Issue name",
3639
description = "The name of the security issue."

src/main/resources/META-INF/rewrite/default.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ tags:
4040
- DevCenter:fix:org.openrewrite.java.migrate.UpgradeToJava21
4141
recipeList:
4242
- io.moderne.devcenter.JavaVersionUpgrade:
43-
targetVersion: 21
43+
majorVersion: 21
4444
---
4545
type: specs.openrewrite.org/v1beta/recipe
4646
name: io.moderne.devcenter.SpringBootUpgradeStarter
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#
2+
# Copyright 2021 the original author or authors.
3+
# <p>
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
# <p>
8+
# https://www.apache.org/licenses/LICENSE-2.0
9+
# <p>
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
#
16+
17+
type: specs.openrewrite.org/v1beta/category
18+
name: Moderne DevCenter
19+
packageName: io.moderne.DevCenter
20+

src/test/java/io/moderne/devcenter/DevCenterTest.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,38 @@
1515
*/
1616
package io.moderne.devcenter;
1717

18+
import org.junit.jupiter.api.Test;
19+
import org.openrewrite.Recipe;
20+
import org.openrewrite.config.Environment;
21+
22+
import static org.assertj.core.api.Assertions.assertThat;
23+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
24+
1825
public class DevCenterTest {
26+
27+
@SuppressWarnings("DataFlowIssue")
28+
@Test
29+
void valid() throws DevCenterValidationException {
30+
Recipe starterDevCenter = Environment.builder()
31+
.scanRuntimeClasspath("org.openrewrite")
32+
.scanYamlResources()
33+
.build()
34+
.activateRecipes("io.moderne.devcenter.DevCenterStarter");
35+
36+
DevCenter devCenter = new DevCenter(starterDevCenter.getDescriptor());
37+
devCenter.validate();
38+
assertThat(devCenter.getUpgradesAndMigrations()).hasSize(3);
39+
assertThat(devCenter.getSecurity()).isNotNull();
40+
}
41+
42+
@Test
43+
void noCards() {
44+
DevCenter devCenter = new DevCenter(Recipe.builder("No cards", "A DevCenter with no cards.")
45+
.build("io.moderne.devcenter.DevCenterNoCards")
46+
.getDescriptor());
47+
48+
assertThatThrownBy(devCenter::validate)
49+
.isInstanceOf(DevCenterValidationException.class)
50+
.hasMessageContaining("No recipes included that provide upgrades and migrations or security advice.");
51+
}
1952
}

src/test/java/io/moderne/devcenter/ReportAsSecurityIssuesTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public void defaults(RecipeSpec spec) {
4040
void reportSecret() {
4141
rewriteRun(spec -> spec.dataTable(SecurityIssues.Row.class, rows ->
4242
assertThat(rows).containsExactly(
43-
new SecurityIssues.Row("Find secrets")
43+
new SecurityIssues.Row(7, "Find secrets")
4444
)),
4545
//language=java
4646
java(

0 commit comments

Comments
 (0)