Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add autodocBom task to generate Autodoc manifests for BOMs #282

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

package org.eclipse.edc.plugins.autodoc;

import org.eclipse.edc.plugins.autodoc.tasks.AutodocBomTask;
import org.eclipse.edc.plugins.autodoc.tasks.DownloadManifestTask;
import org.eclipse.edc.plugins.autodoc.tasks.MarkdownRendererTask.ToHtml;
import org.eclipse.edc.plugins.autodoc.tasks.MarkdownRendererTask.ToMarkdown;
Expand Down Expand Up @@ -47,6 +48,15 @@ public void apply(Project project) {
project.getTasks().register(ToHtml.NAME, ToHtml.class, t -> t.setGroup(GROUP_NAME));
project.getTasks().register(DownloadManifestTask.NAME, DownloadManifestTask.class, t -> t.setGroup(GROUP_NAME));
// resolving manifests requires the Autodoc manifests of all dependencies to exist already
project.getTasks().register(ResolveManifestTask.NAME, ResolveManifestTask.class, t -> t.dependsOn(AUTODOC_TASK_NAME).setGroup(GROUP_NAME));
project.getTasks().register(ResolveManifestTask.NAME, ResolveManifestTask.class, t -> {
t.dependsOn(AUTODOC_TASK_NAME);
t.setGroup(GROUP_NAME);
t.setDescription(ResolveManifestTask.DESCRIPTION);
});
project.getTasks().register(AutodocBomTask.NAME, AutodocBomTask.class, t -> {
t.dependsOn(ResolveManifestTask.NAME);
t.setDescription(AutodocBomTask.DESCRIPTION);
t.setGroup(GROUP_NAME);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import java.util.Set;

import static java.util.Objects.requireNonNull;
import static org.eclipse.edc.plugins.autodoc.tasks.Constants.DEFAULT_AUTODOC_FOLDER;

/**
* Abstract gradle task, that "resolves" an already-existing autodoc manifest from a URI and transfers (=copies, downloads,...)
Expand All @@ -45,7 +46,7 @@ public abstract class AbstractManifestResolveTask extends DefaultTask {
private File outputDirectoryOverride;

public AbstractManifestResolveTask() {
downloadDirectory = getProject().getLayout().getBuildDirectory().getAsFile().get().toPath().resolve("autodoc");
downloadDirectory = getProject().getLayout().getBuildDirectory().getAsFile().get().toPath().resolve(DEFAULT_AUTODOC_FOLDER);
}

@TaskAction
Expand Down Expand Up @@ -92,10 +93,12 @@ protected Set<String> getExclusions() {
private void transferDependencyFile(DependencySource dependencySource, Path downloadDirectory) {
var targetFilePath = downloadDirectory.resolve(dependencySource.filename());
try (var inputStream = resolveManifest(dependencySource)) {
downloadDirectory.toFile().mkdirs();
getLogger().debug("Downloading {} into {}", dependencySource, downloadDirectory);
try (var fos = new FileOutputStream(targetFilePath.toFile())) {
inputStream.transferTo(fos);
if (inputStream != null) {
downloadDirectory.toFile().mkdirs();
getLogger().debug("Downloading {} into {}", dependencySource, downloadDirectory);
try (var fos = new FileOutputStream(targetFilePath.toFile())) {
inputStream.transferTo(fos);
}
}
} catch (IOException e) {
throw new RuntimeException(e);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation
*
*/

package org.eclipse.edc.plugins.autodoc.tasks;

import org.gradle.api.DefaultTask;
import org.gradle.api.tasks.OutputFile;
import org.gradle.api.tasks.TaskAction;
import org.gradle.util.internal.GFileUtils;

import java.io.File;

public class AutodocBomTask extends DefaultTask {

public static final String NAME = "autodocBom";
public static final String DESCRIPTION = """
This task is intended for BOM modules. It resolves all autodoc manifests of modules that the BOM depends on
and generates a merged manifest file. By default, this merged file is stored at {project}/build/edc.json.
""";
private final JsonFileAppender appender;
private File outputFile;

public AutodocBomTask() {
appender = new JsonFileAppender(getLogger());
outputFile = getProject().getLayout().getBuildDirectory().file(outputFileName()).get().getAsFile();
}

@TaskAction
public void mergeManifests() {
if (!getProject().getName().endsWith("-bom")) {
getLogger().warn("Project name does not end with '-bom'. Is this really a BOM module?");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe this functionality shouldn't be limited to bom modules, e.g. an EDC distribution (like Tractus-X) could be interested in generating a comprehensive autodoc out of a set of dependencies.
the warning wouldn't be needed then

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this would require a bit of refactoring, because then, the autodocBom task would not depend on the resolveManifest task anymore, but on either resolveManifest or downloadManifests.

alternatively, resolveManifest and downloadManifest could be merged into one, and artifact resolution (of the manifest file) happens dynamically based on its URI.

Definitely worth exploring, though in a different PR, IMO.

}

var inputDirectory = getProject().getLayout().getBuildDirectory().dir(Constants.DEFAULT_AUTODOC_FOLDER).get();
if (!inputDirectory.getAsFile().exists()) {
getLogger().info("Input directory does not exist: {}, Skipping", inputDirectory);
return;
}

var destinationFile = outputFile;

var files = GFileUtils.listFiles(inputDirectory.getAsFile(), new String[]{ "json" }, false);
getLogger().debug("Appending [{}] additional JSON files to the merged manifest", files.size());
files.forEach(f -> appender.append(destinationFile, f));

}

@OutputFile
public File getOutputFile() {
return outputFile;
}

public void setOutputFile(File outputFile) {
this.outputFile = outputFile;
}

private String outputFileName() {
return "edc.json";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation
*
*/

package org.eclipse.edc.plugins.autodoc.tasks;

public interface Constants {
String DEFAULT_AUTODOC_FOLDER = "autodoc";
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ protected InputStream resolveManifest(DependencySource autodocManifest) {
}
if (response.statusCode() != 200) {
getLogger().warn("Could not download {}, HTTP response: {}", autodocManifest.dependency(), response);
return InputStream.nullInputStream();
return null;
}
return response.body();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
import java.nio.file.Path;
import java.util.Objects;

import static org.eclipse.edc.plugins.autodoc.tasks.Constants.DEFAULT_AUTODOC_FOLDER;

/**
* Task that takes an input file (JSON) and appends its contents to a destination file. This task is intended to be called per-project.
*/
Expand All @@ -43,7 +45,7 @@ public MergeManifestsTask() {
appender = new JsonFileAppender(getProject().getLogger());
projectBuildDirectory = getProject().getLayout().getBuildDirectory().getAsFile().get();
destinationFile = getProject().getRootProject().getLayout().getBuildDirectory().get().getAsFile().toPath().resolve(MERGED_MANIFEST_FILENAME).toFile();
inputDirectory = projectBuildDirectory.toPath().resolve("autodoc").toFile();
inputDirectory = projectBuildDirectory.toPath().resolve(DEFAULT_AUTODOC_FOLDER).toFile();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,10 @@
import java.io.InputStream;
import java.util.Optional;

import static java.io.InputStream.nullInputStream;

public class ResolveManifestTask extends AbstractManifestResolveTask {

public static final String NAME = "resolveManifests";

public static final String DESCRIPTION = "This task is intended for BOM modules and resolves the autodoc manifests of all modules that the project depends on. By default, all manifests are stored in {project}/build/autodoc.";

@Override
protected InputStream resolveManifest(DependencySource autodocManifest) {
Expand All @@ -40,7 +38,7 @@ protected InputStream resolveManifest(DependencySource autodocManifest) {
}

getLogger().info("File {} does not exist", file);
return nullInputStream();
return null;
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
Expand All @@ -62,5 +60,4 @@ protected Optional<DependencySource> createSource(Dependency dependency) {

return Optional.empty();
}

}
Loading