Skip to content

Commit

Permalink
Merge pull request #70 from adamcin/expose-run-modes-to-tools
Browse files Browse the repository at this point in the history
initial code to add run mode support to maven plugin and cli
  • Loading branch information
adamcin committed Sep 4, 2020
2 parents a82c706 + 82d9370 commit 026c364
Show file tree
Hide file tree
Showing 14 changed files with 246 additions and 23 deletions.
51 changes: 33 additions & 18 deletions cli/src/main/java/net/adamcin/oakpal/cli/Command.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
package net.adamcin.oakpal.cli;

import static net.adamcin.oakpal.api.Fun.compose1;
import static net.adamcin.oakpal.api.Fun.result0;
import static net.adamcin.oakpal.api.Fun.result1;
import static net.adamcin.oakpal.api.Fun.uncheck0;
import net.adamcin.oakpal.api.Nothing;
import net.adamcin.oakpal.api.Result;
import net.adamcin.oakpal.api.Severity;
import net.adamcin.oakpal.api.Violation;
import net.adamcin.oakpal.core.CheckReport;
import net.adamcin.oakpal.core.DefaultErrorListener;
import net.adamcin.oakpal.core.FileBlobMemoryNodeStore;
import net.adamcin.oakpal.core.OakMachine;
import net.adamcin.oakpal.core.OakpalPlan;
import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeStore;
import org.apache.jackrabbit.oak.spi.state.NodeStore;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.File;
Expand All @@ -18,21 +28,14 @@
import java.util.Properties;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import net.adamcin.oakpal.api.Severity;
import net.adamcin.oakpal.core.CheckReport;
import net.adamcin.oakpal.core.DefaultErrorListener;
import net.adamcin.oakpal.core.FileBlobMemoryNodeStore;
import net.adamcin.oakpal.api.Nothing;
import net.adamcin.oakpal.core.OakMachine;
import net.adamcin.oakpal.core.OakpalPlan;
import net.adamcin.oakpal.api.Result;
import net.adamcin.oakpal.api.Violation;
import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeStore;
import org.apache.jackrabbit.oak.spi.state.NodeStore;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static net.adamcin.oakpal.api.Fun.compose1;
import static net.adamcin.oakpal.api.Fun.inferTest1;
import static net.adamcin.oakpal.api.Fun.result0;
import static net.adamcin.oakpal.api.Fun.result1;
import static net.adamcin.oakpal.api.Fun.uncheck0;

final class Command {
private static final Logger LOGGER = LoggerFactory.getLogger(Command.class);
Expand Down Expand Up @@ -223,6 +226,18 @@ Optional<String> flipOpt(final @NotNull String wholeOpt) {
builder.addRepoInitFile(console.getCwd().toPath().resolve(args[++i]).toFile());
}
break;
case "-r":
case "--run-modes":
builder.setNoRunModes(isNoOpt);
if (isNoOpt) {
builder.setRunModes(Collections.emptyList());
} else {
builder.setRunModes(Stream.of(args[++i].split(","))
.map(String::trim)
.filter(inferTest1(String::isEmpty).negate())
.collect(Collectors.toList()));
}
break;
case "-xp":
case "--extend-classpath":
if (isNoOpt) {
Expand Down
42 changes: 38 additions & 4 deletions cli/src/main/java/net/adamcin/oakpal/cli/Options.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ final class Options {
private final File planFileBaseDir;
private final List<File> preInstallFiles;
private final List<File> repoInitFiles;
private final List<String> runModes;
private final boolean noRunModes;
private final List<File> extendedClassPathFiles;
private final boolean noHooks;
private final List<File> scanFiles;
Expand All @@ -64,6 +66,7 @@ final class Options {
Collections.emptyList(),
Collections.emptyList(),
Collections.emptyList(), false,
Collections.emptyList(), false,
Collections.emptyList(),
EMPTY_PRINTER,
Severity.MAJOR);
Expand All @@ -81,6 +84,8 @@ final class Options {
final @Nullable File planFileBaseDir,
final @NotNull List<File> preInstallFiles,
final @NotNull List<File> repoInitFiles,
final @NotNull List<String> runModes,
final boolean noRunModes,
final @NotNull List<File> extendedClassPathFiles,
final boolean noHooks,
final @NotNull List<File> scanFiles,
Expand All @@ -98,6 +103,8 @@ final class Options {
this.planFileBaseDir = planFileBaseDir;
this.preInstallFiles = preInstallFiles;
this.repoInitFiles = repoInitFiles;
this.runModes = runModes;
this.noRunModes = noRunModes;
this.extendedClassPathFiles = extendedClassPathFiles;
this.noHooks = noHooks;
this.scanFiles = scanFiles;
Expand Down Expand Up @@ -157,6 +164,14 @@ public File getCacheDir() {
return repoInitFiles;
}

public @NotNull List<String> getRunModes() {
return runModes;
}

public boolean isNoRunModes() {
return noRunModes;
}

public @NotNull List<File> getExtendedClassPathFiles() {
return extendedClassPathFiles;
}
Expand All @@ -174,7 +189,8 @@ public Severity getFailOnSeverity() {
}

boolean hasOverrides() {
return noHooks || !getPreInstallFiles().isEmpty() || !getRepoInitFiles().isEmpty();
return noHooks || !getPreInstallFiles().isEmpty() || !getRepoInitFiles().isEmpty()
|| !getRunModes().isEmpty() || noRunModes;
}

public OakpalPlan applyOverrides(final @NotNull OakpalPlan basePlan) {
Expand All @@ -199,6 +215,11 @@ public OakpalPlan applyOverrides(final @NotNull OakpalPlan basePlan) {
.collect(Result.tryCollect(Collectors.toList())).forEach(allUrls::addAll);
overridePlan.withRepoInitUrls(allUrls);
}
if (noRunModes) {
overridePlan.withRunModes(Collections.emptyList());
} else if (!getRunModes().isEmpty()) {
overridePlan.withRunModes(getRunModes());
}
if (isNoHooks()) {
overridePlan.withInstallHookPolicy(InstallHookPolicy.SKIP);
overridePlan.withEnablePreInstallHooks(false);
Expand Down Expand Up @@ -262,6 +283,8 @@ static final class Builder {
private File planFileBaseDir;
private List<File> preInstallFiles = new ArrayList<>();
private List<File> repoInitFiles = new ArrayList<>();
private List<String> runModes = new ArrayList<>();
private boolean noRunModes;
private List<File> extendedClassPathFiles = new ArrayList<>();
private File outFile;
private File cacheDir;
Expand Down Expand Up @@ -334,6 +357,16 @@ public Builder addRepoInitFile(final @NotNull File repoInitFile) {
return this;
}

public Builder setRunModes(final @NotNull List<String> runModes) {
this.runModes = runModes;
return this;
}

public Builder setNoRunModes(final boolean noRunModes) {
this.noRunModes = noRunModes;
return this;
}

public Builder setExtendedClassPathFiles(final @NotNull List<File> extendedClassPathFiles) {
this.extendedClassPathFiles = new ArrayList<>(extendedClassPathFiles);
return this;
Expand Down Expand Up @@ -432,9 +465,10 @@ Result<Options> build(final @NotNull Console console) {
.flatMap(classLoader -> messageWriter(console, outputJson, outFile).map(writer ->
new Options(justHelp, justVersion, storeBlobs, planUrl,
classLoader, realCacheDir, opearFile, planName, planFile,
planFileBaseDir, preInstallFiles, repoInitFiles, extendedClassPathFiles,
noHooks, scanFiles, writer, Optional.ofNullable(failOnSeverity)
.orElse(DEFAULT_OPTIONS.failOnSeverity))))));
planFileBaseDir, preInstallFiles, repoInitFiles, runModes, noRunModes,
extendedClassPathFiles, noHooks, scanFiles, writer,
Optional.ofNullable(failOnSeverity)
.orElse(DEFAULT_OPTIONS.failOnSeverity))))));
}
}

Expand Down
4 changes: 4 additions & 0 deletions cli/src/main/resources/net/adamcin/oakpal/cli/help.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ oakpal [ <options> ] <scanFile> ...
--no-hooks : Disable preinstall and scan install hooks for all packages, otherwise, rely on
install hook policies configured in the selected plan.
-pi | --pre-install-file <file> : Add a preinstall package to the list specified in the plan, if any.
-r | --run-modes <mode,...> : Override the simulated sling run modes specified in the plan (json key: "runModes")
with the provided comma-delimited list of run modes.
+r | --no-run-modes : Override the simulated sling run modes specified in the plan (json key: "runModes")
to set no active run modes.
-ri | --repoinit-file <file> : Add a repoinit file to the list specified in the plan, if any.
-xp | --extend-classpath <file> : Extend the opear classpath with the specified jar file or directory.
-s | --severity-fail <severity> : Exit with a non-zero code if any violations are
Expand Down
48 changes: 48 additions & 0 deletions cli/src/test/java/net/adamcin/oakpal/cli/CommandTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,54 @@ public void testParseArgs_simpleOnes() {
options -> assertFalse("expect no isNoHooks", options.isNoHooks()));
validator.expectSuccess(args("--hooks", "--no-hooks"),
options -> assertTrue("expect isNoHooks", options.isNoHooks()));

validator.expectSuccess(args(),
options -> {
assertFalse("expect no isNoRunModes", options.isNoRunModes());
assertTrue("expect empty runModes", options.getRunModes().isEmpty());
});
validator.expectSuccess(args("--run-modes", ""),
options -> {
assertFalse("expect no isNoRunModes", options.isNoRunModes());
assertTrue("expect empty runModes", options.getRunModes().isEmpty());
});
validator.expectSuccess(args("--no-run-modes"),
options -> {
assertTrue("expect isNoRunModes", options.isNoRunModes());
assertTrue("expect empty runModes", options.getRunModes().isEmpty());
});
validator.expectSuccess(args("+r"),
options -> {
assertTrue("expect isNoRunModes", options.isNoRunModes());
assertTrue("expect empty runModes", options.getRunModes().isEmpty());
});
validator.expectSuccess(args("--no-run-modes", "--run-modes", ""),
options -> {
assertFalse("expect no isNoRunModes", options.isNoRunModes());
assertTrue("expect empty runModes", options.getRunModes().isEmpty());
});
validator.expectSuccess(args("--run-modes", "", "--no-run-modes"),
options -> {
assertTrue("expect isNoRunModes", options.isNoRunModes());
assertTrue("expect empty runModes", options.getRunModes().isEmpty());
});
validator.expectSuccess(args("-r", "author,publish"),
options -> {
assertFalse("expect no isNoRunModes", options.isNoRunModes());
assertEquals("expect runModes",
Arrays.asList("author", "publish"), options.getRunModes());
});
validator.expectSuccess(args("-r", "author,publish", "--no-run-modes"),
options -> {
assertTrue("expect isNoRunModes", options.isNoRunModes());
assertTrue("expect empty runModes", options.getRunModes().isEmpty());
});
validator.expectSuccess(args("--no-run-modes", "-r", "author,publish"),
options -> {
assertFalse("expect no isNoRunModes", options.isNoRunModes());
assertEquals("expect runModes",
Arrays.asList("author", "publish"), options.getRunModes());
});
}

@Test
Expand Down
70 changes: 70 additions & 0 deletions cli/src/test/java/net/adamcin/oakpal/cli/OptionsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -364,4 +364,74 @@ public void testNoHooks() {
});

}

@Test
public void testWithNoRunModes() throws Exception {
final Console console = getMockConsole();
when(console.getCwd()).thenReturn(tempDir);
final Options.Builder builder = new Options.Builder()
.setOpearFile(new File("src/test/resources/opears/runModesPlan"));
final Result<Options> defaultOptionsResult = builder.build(console);
assertFalse("options build is successful", defaultOptionsResult.getError().isPresent());
defaultOptionsResult.forEach(options -> {
assertFalse("isNoRunModes is disabled by default", options.isNoRunModes());
assertFalse("false hasOverrides", options.hasOverrides());
final OakpalPlan originalPlan = new OakpalPlan.Builder(null, null)
.withRunModes(Arrays.asList("author", "publish"))
.build();
final OakpalPlan overriddenPlan = options.applyOverrides(originalPlan);
assertSame("same plan with no overrides", originalPlan, overriddenPlan);
assertEquals("enabled runModes",
Arrays.asList("author", "publish"), overriddenPlan.getRunModes());
});
final Result<Options> noRunModesOptionsResult = builder.setNoRunModes(true).build(console);
assertFalse("options build is successful", noRunModesOptionsResult.getError().isPresent());
noRunModesOptionsResult.forEach(options -> {
assertTrue("isNoRunModes is enabled by builder", options.isNoRunModes());
assertTrue("true hasOverrides", options.hasOverrides());
final OakpalPlan originalPlan = new OakpalPlan.Builder(null, null)
.withRunModes(Arrays.asList("author", "publish"))
.build();
final OakpalPlan overriddenPlan = options.applyOverrides(originalPlan);
assertNotSame("not same plan with overrides", originalPlan, overriddenPlan);
assertEquals("enabled runModes",
Collections.emptyList(), overriddenPlan.getRunModes());
});
}

@Test
public void testWithRunModes() throws Exception {
final Console console = getMockConsole();
when(console.getCwd()).thenReturn(tempDir);
final Options.Builder builder = new Options.Builder()
.setOpearFile(new File("src/test/resources/opears/runModesPlan"));
final Result<Options> defaultOptionsResult = builder.build(console);
assertFalse("options build is successful", defaultOptionsResult.getError().isPresent());
defaultOptionsResult.forEach(options -> {
assertTrue("getRunModes is empty by default", options.getRunModes().isEmpty());
assertFalse("false hasOverrides", options.hasOverrides());
final OakpalPlan originalPlan = new OakpalPlan.Builder(null, null)
.withRunModes(Collections.singletonList("author"))
.build();
final OakpalPlan overriddenPlan = options.applyOverrides(originalPlan);
assertSame("same plan with no overrides", originalPlan, overriddenPlan);
assertEquals("enabled runModes",
Collections.singletonList("author"), overriddenPlan.getRunModes());
});
final Result<Options> newRunModesOptionsResult = builder.setRunModes(Collections.singletonList("publish"))
.build(console);
assertFalse("options build is successful", newRunModesOptionsResult.getError().isPresent());
newRunModesOptionsResult.forEach(options -> {
assertEquals("expect new getRunModes list",
Collections.singletonList("publish"), options.getRunModes());
assertTrue("true hasOverrides", options.hasOverrides());
final OakpalPlan originalPlan = new OakpalPlan.Builder(null, null)
.withRunModes(Arrays.asList("author", "publish"))
.build();
final OakpalPlan overriddenPlan = options.applyOverrides(originalPlan);
assertNotSame("not same plan with overrides", originalPlan, overriddenPlan);
assertEquals("enabled runModes",
Collections.singletonList("publish"), overriddenPlan.getRunModes());
});
}
}
5 changes: 5 additions & 0 deletions cli/src/test/resources/opears/runModesPlan/plan.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"runModes": [
"author"
]
}
2 changes: 2 additions & 0 deletions core/src/main/java/net/adamcin/oakpal/core/OakpalPlan.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import net.adamcin.oakpal.api.ProgressCheck;
import net.adamcin.oakpal.api.Result;
import net.adamcin.oakpal.api.ViolationReporter;
import net.adamcin.oakpal.core.sling.DefaultSlingSimulator;
import org.apache.jackrabbit.spi.PrivilegeDefinition;
import org.apache.jackrabbit.spi.QNodeTypeDefinition;
import org.apache.jackrabbit.spi.commons.namespace.NamespaceMapping;
Expand Down Expand Up @@ -387,6 +388,7 @@ public OakMachine.Builder toOakMachineBuilder(final @Nullable ErrorListener erro
.withInstallHookPolicy(installHookPolicy)
.withInstallHookClassLoader(classLoader)
.withRunModes(new HashSet<>(getRunModes()))
.withSlingSimulator(DefaultSlingSimulator.instance())
.withEnablePreInstallHooks(enablePreInstallHooks);
}

Expand Down
4 changes: 4 additions & 0 deletions core/src/main/resources/OAKPAL-INF/checklists/basic.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@
"name": "composite-store-alignment",
"impl": "net.adamcin.oakpal.core.checks.CompositeStoreAlignment"
},
{
"name": "sling-jcr-installer",
"impl": "net.adamcin.oakpal.core.checks.SlingJcrInstaller"
},
{
"name": "echo",
"impl": "net.adamcin.oakpal.core.checks.Echo",
Expand Down
3 changes: 2 additions & 1 deletion core/src/test/java/net/adamcin/oakpal/it/ChecklistIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ public void testLoadChecklists() throws Exception {
"acHandling",
"filterSets",
"overlaps",
"composite-store-alignment"
"composite-store-alignment",
"sling-jcr-installer"
).map(name -> OAKPAL_MODULE_NAME + "/" + OAKPAL_CHECKLIST_BASIC + "/" + name)
.collect(Collectors.toList());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,18 @@ abstract class AbstractITestWithPlanMojo extends AbstractITestMojo implements Pl
@Parameter(property = "repoInitFiles")
protected List<File> repoInitFiles = new ArrayList<>();

/**
* Specify a list of Sling run modes to simulate for installation of embedded filevault packages and
* RepositoryInitializer factory configs that provide repoinit scripts.
*
* See https://sling.apache.org/documentation/bundles/repository-initialization.html .
* See https://sling.apache.org/documentation/bundles/repository-initialization.html .
*
* @since 2.2.0
*/
@Parameter(property = "runModes")
protected List<String> runModes = new ArrayList<>();

@Override
public final @NotNull PlanBuilderParams getPlanBuilderParams() {
return this;
Expand Down Expand Up @@ -444,6 +456,11 @@ public List<File> getRepoInitFiles() {
return repoInitFiles;
}

@Override
public List<String> getRunModes() {
return runModes;
}

protected void performScan(final @NotNull List<File> scanFiles) throws MojoFailureException {
List<CheckReport> reports;
try {
Expand Down
Loading

0 comments on commit 026c364

Please sign in to comment.