use of org.revapi.Revapi in project revapi by revapi.
the class ConvertToXmlConfigMojo method updateAllConfigurationFiles.
private void updateAllConfigurationFiles(MavenProject project, Map<String, ModelNode> extensionSchemas, int indentationSize) throws Exception {
VTDGen gen = new VTDGen();
gen.enableIgnoredWhiteSpace(true);
gen.parseFile(project.getFile().getAbsolutePath(), true);
VTDNav nav = gen.getNav();
XMLModifier mod = new XMLModifier(nav);
AutoPilot ap = new AutoPilot(nav);
ThrowingConsumer<String> update = xpath -> {
ap.resetXPath();
ap.selectXPath(xpath);
while (ap.evalXPath() != -1) {
int textPos = nav.getText();
String configFile = nav.toString(textPos);
File newFile = updateConfigurationFile(new File(configFile), extensionSchemas, indentationSize);
if (newFile == null) {
continue;
}
mod.updateToken(textPos, newFile.getPath());
}
};
update.accept("//plugin[groupId = 'org.revapi' and artifactId = 'revapi-maven-plugin']" + "/configuration/analysisConfigurationFiles/*[not(self::configurationFile)]");
update.accept("//plugin[groupId = 'org.revapi' and artifactId = 'revapi-maven-plugin']" + "/configuration/analysisConfigurationFiles/configurationFile[not(roots)]/path");
update.accept("//plugin[groupId = 'org.revapi' and artifactId = 'revapi-maven-plugin']" + "/executions/execution/configuration/analysisConfigurationFiles/*[not(self::configurationFile)]");
update.accept("//plugin[groupId = 'org.revapi' and artifactId = 'revapi-maven-plugin']" + "/executions/execution/configuration/analysisConfigurationFiles/configurationFile[not(roots)]/path");
try (OutputStream out = new FileOutputStream(project.getFile())) {
mod.output(out);
}
}
use of org.revapi.Revapi in project revapi by revapi.
the class ReportAggregateMojo method executeReport.
@Override
protected void executeReport(Locale locale) throws MavenReportException {
if (skip) {
return;
}
if (!canGenerateReport()) {
return;
}
List<MavenProject> dependents = mavenSession.getProjectDependencyGraph().getDownstreamProjects(project, true);
Collections.sort(dependents, (a, b) -> {
String as = a.getArtifact().toString();
String bs = b.getArtifact().toString();
return as.compareTo(bs);
});
Map<MavenProject, ProjectVersions> projectVersions = dependents.stream().collect(Collectors.toMap(Function.identity(), this::getRunConfig));
projectVersions.put(project, getRunConfig(project));
ResourceBundle messages = getBundle(locale);
Sink sink = getSink();
if (generateSiteReport) {
startReport(sink, messages);
}
try {
Analyzer topAnalyzer = prepareAnalyzer(null, project, locale, projectVersions.get(project));
Revapi sharedRevapi = topAnalyzer == null ? null : topAnalyzer.getRevapi();
for (MavenProject p : dependents) {
Analyzer projectAnalyzer = prepareAnalyzer(sharedRevapi, p, locale, projectVersions.get(p));
if (projectAnalyzer != null) {
try (AnalysisResult res = projectAnalyzer.analyze()) {
res.throwIfFailed();
ReportTimeReporter reporter = res.getExtensions().getFirstExtension(ReportTimeReporter.class, null);
if (generateSiteReport && reporter != null) {
reportBody(reporter, projectAnalyzer.getResolvedOldApi(), projectAnalyzer.getResolvedNewApi(), sink, messages);
}
}
}
}
if (generateSiteReport) {
endReport(sink);
}
} catch (Exception e) {
throw new MavenReportException("Failed to generate the report.", e);
}
}
use of org.revapi.Revapi in project revapi by revapi.
the class Main method run.
@SuppressWarnings("ConstantConditions")
private static void run(File cacheDir, String[] extensionGAVs, List<FileArchive> oldArchives, List<FileArchive> oldSupplementaryArchives, List<FileArchive> newArchives, List<FileArchive> newSupplementaryArchives, String[] configFiles, Map<String, String> additionalConfig) throws Exception {
ProjectModule.Builder bld = ProjectModule.build();
bld.localRepository(cacheDir);
if (extensionGAVs != null) {
for (String gav : extensionGAVs) {
bld.addDependency(gav);
}
}
Properties libraryVersionsProps = new Properties();
libraryVersionsProps.load(Main.class.getResourceAsStream("/library.versions"));
Set<Artifact> globalArtifacts = libraryVersionsProps.stringPropertyNames().stream().map(p -> {
String gav = p + ':' + libraryVersionsProps.get(p);
return new DefaultArtifact(gav);
}).collect(toSet());
bld.moduleSpecController(new ModuleSpecController() {
private boolean override;
private String currentModuleName;
@Override
public void start(String moduleName) {
currentModuleName = moduleName;
}
// TODO add warnings when the deps depend on another revapi version than the one bundled...
@Override
public DependencySpec modifyDependency(String dependencyName, DependencySpec original) {
boolean overrideThis = false;
Artifact a = new DefaultArtifact(dependencyName);
for (Artifact ga : globalArtifacts) {
if (ga.getGroupId().equals(a.getGroupId()) && ga.getArtifactId().equals(a.getArtifactId()) && !ga.getVersion().equals(a.getVersion())) {
LOG.warn("Detected version conflict in dependencies of extension " + currentModuleName + ". The extension depends on " + a + " while the CLI has " + ga + " on global" + " classpath. This will likely cause problems.");
}
}
override = override || overrideThis;
return overrideThis ? null : original;
}
@Override
public void modify(ModuleSpec.Builder bld) {
if (override) {
Set<String> revapiPaths = new HashSet<>(Arrays.asList("org/revapi", "org/revapi/configuration", "org/revapi/query", "org/revapi/simple"));
bld.addDependency(DependencySpec.createSystemDependencySpec(revapiPaths));
override = false;
}
}
@Override
public void end(String moduleName) {
currentModuleName = null;
}
});
LOG.info("Downloading extensions");
Module project = bld.create();
Revapi revapi = Revapi.builder().withAllExtensionsFrom(project.getClassLoader()).withAllExtensionsFromThreadContextClassLoader().build();
AnalysisContext.Builder ctxBld = AnalysisContext.builder(revapi).withOldAPI(API.of(oldArchives).supportedBy(oldSupplementaryArchives).build()).withNewAPI(API.of(newArchives).supportedBy(newSupplementaryArchives).build());
if (configFiles != null) {
for (String cf : configFiles) {
File f = new File(cf);
checkCanRead(f, "Configuration file");
try (FileInputStream is = new FileInputStream(f)) {
ctxBld.mergeConfigurationFromJSONStream(is);
}
}
}
for (Map.Entry<String, String> e : additionalConfig.entrySet()) {
String[] keyPath = e.getKey().split("\\.");
ModelNode additionalNode = new ModelNode();
ModelNode key = additionalNode.get(keyPath);
String value = e.getValue();
if (value.startsWith("[") && value.endsWith("]")) {
String[] values = value.substring(1, value.length() - 1).split("\\s*,\\s*");
for (String v : values) {
key.add(v);
}
} else {
key.set(value);
}
ctxBld.mergeConfiguration(additionalNode);
}
LOG.info("Starting analysis");
try (AnalysisResult result = revapi.analyze(ctxBld.build())) {
if (!result.isSuccess()) {
throw result.getFailure();
}
}
}
use of org.revapi.Revapi in project revapi by revapi.
the class ConfigurationValidatorTest method testRevapiValidation.
@Test
public void testRevapiValidation() throws Exception {
String config = "[" + "{\"extension\": \"my-config\", \"configuration\": {\"id\": 3, \"kachna\": \"duck\"}}," + "{\"extension\": \"my-config\", \"configuration\": {\"id\": 4, \"kachna\": \"no duck\"}}," + "{\"extension\": \"other-config\", \"configuration\": 1}" + "]";
Revapi revapi = Revapi.builder().withFilters(TestFilter.class).withReporters(TestReporter.class).withAnalyzers(DummyApiAnalyzer.class).build();
AnalysisContext ctx = AnalysisContext.builder(revapi).withConfigurationFromJSON(config).build();
ValidationResult res = revapi.validateConfiguration(ctx);
Assert.assertFalse(res.isSuccessful());
Assert.assertNotNull(res.getErrors());
Assert.assertEquals(1, res.getErrors().length);
Assert.assertEquals("/[2]/configuration", res.getErrors()[0].dataPath);
}
use of org.revapi.Revapi in project revapi by revapi.
the class ConfigurationValidatorTest method testRevapiValidation_mergeWithoutIds.
@Test
public void testRevapiValidation_mergeWithoutIds() throws Exception {
// partial config of the extension
String config1 = "[" + "{\"extension\": \"my-config\", \"configuration\": {\"id\": 3,}}" + "]";
// complete the config of the extension and add another config for another extension
String config2 = "[" + "{\"extension\": \"my-config\", \"configuration\": {\"kachna\": \"no duck\"}}," + "{\"extension\": \"other-config\", \"configuration\": 1}" + "]";
Revapi revapi = Revapi.builder().withFilters(TestFilter.class).withReporters(TestReporter.class).withAnalyzers(DummyApiAnalyzer.class).build();
AnalysisContext ctx = AnalysisContext.builder(revapi).withConfigurationFromJSON(config1).mergeConfigurationFromJSON(config2).build();
ValidationResult res = revapi.validateConfiguration(ctx);
Assert.assertFalse(res.isSuccessful());
Assert.assertNotNull(res.getErrors());
// we merged "my-config" from the second config into the first, so that should be ok. Only other-config should error out.
Assert.assertEquals(1, res.getErrors().length);
Assert.assertEquals("/[1]/configuration", res.getErrors()[0].dataPath);
}
Aggregations