diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 0000000..efcdf4f --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,19 @@ +{ + "permissions": { + "allow": [ + "Bash(git checkout:*)", + "Bash(./gradlew clean:*)", + "Bash(git add:*)", + "Bash(./gradlew publishToMavenLocal:*)", + "Bash(gradle build:*)", + "Bash(unzip:*)", + "Bash(gradle clean:*)", + "Bash(git:*)", + "Bash(GIT_SEQUENCE_EDITOR=\"/tmp/reword_all.sh\" GIT_EDITOR=\"/tmp/strip_coauthor.sh\" git:*)", + "Bash(gh pr:*)", + "Bash(gh issue:*)", + "Bash(ls:*)", + "WebFetch(domain:github.com)" + ] + } +} diff --git a/README.adoc b/README.adoc index b38c4a5..139bdf6 100644 --- a/README.adoc +++ b/README.adoc @@ -23,7 +23,7 @@ toc::[] [source,gradle] ---- plugins { - id 'io.github.reqstool' version '0.2.0' + id 'io.github.reqstool.gradle-plugin' version '0.1.0' } ---- @@ -104,7 +104,7 @@ When the `maven-publish` plugin is applied, the reqstool ZIP is automatically re [source,gradle] ---- plugins { - id 'io.github.reqstool' version '0.2.0' + id 'io.github.reqstool.gradle-plugin' version '0.1.0' id 'maven-publish' } diff --git a/build.gradle b/build.gradle index d9b0e4f..78ee4a2 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ plugins { } group = 'io.github.reqstool' -version = '0.2.0' +version = '0.1.0' java { sourceCompatibility = JavaVersion.VERSION_17 @@ -24,7 +24,7 @@ gradlePlugin { plugins { reqstoolPlugin { - id = 'io.github.reqstool' + id = 'io.github.reqstool.gradle-plugin' implementationClass = 'io.github.reqstool.gradle.RequirementsToolPlugin' displayName = 'Reqstool Gradle Plugin' description = 'Gradle plugin for assembling and attaching reqstool ZIP artifacts' @@ -50,7 +50,7 @@ dependencies { } javadoc { - options.addStringOption('Xdoclint:none', '-quiet') + options.addBooleanOption('Xdoclint:all', true) } test { diff --git a/src/main/java/io/github/reqstool/gradle/RequirementsToolExtension.java b/src/main/java/io/github/reqstool/gradle/RequirementsToolExtension.java index 922152a..eff2679 100644 --- a/src/main/java/io/github/reqstool/gradle/RequirementsToolExtension.java +++ b/src/main/java/io/github/reqstool/gradle/RequirementsToolExtension.java @@ -59,34 +59,71 @@ public RequirementsToolExtension(Project project) { this.skipAttachZipArtifact.convention(false); } + /** + * Returns the path to the requirements annotations YAML file generated by the + * annotation processor. + * @return file property for requirements annotations + */ public RegularFileProperty getRequirementsAnnotationsFile() { return requirementsAnnotationsFile; } + /** + * Returns the path to the SVCs (Software Verification Cases) annotations YAML file + * generated by the test annotation processor. + * @return file property for SVCs annotations + */ public RegularFileProperty getSvcsAnnotationsFile() { return svcsAnnotationsFile; } + /** + * Returns the output directory where the ZIP artifact and combined annotations are + * written. + * @return file property for the output directory + */ public RegularFileProperty getOutputDirectory() { return outputDirectory; } + /** + * Returns the dataset directory containing {@code requirements.yml} and optional + * supporting files. + * @return file property for the dataset directory + */ public RegularFileProperty getDatasetPath() { return datasetPath; } + /** + * Returns the list of Ant-style glob patterns used to locate test result XML files. + * @return list property of test result patterns + */ public ListProperty getTestResults() { return testResults; } + /** + * Returns whether the entire plugin execution should be skipped. + * @return boolean property; {@code true} skips all plugin tasks + */ public Property getSkip() { return skip; } + /** + * Returns whether ZIP artifact assembly should be skipped while still combining + * annotations. + * @return boolean property; {@code true} skips ZIP assembly + */ public Property getSkipAssembleZipArtifact() { return skipAssembleZipArtifact; } + /** + * Returns whether attaching the ZIP artifact for Maven publishing should be skipped. + * @return boolean property; {@code true} skips artifact attachment + */ public Property getSkipAttachZipArtifact() { return skipAttachZipArtifact; } diff --git a/src/main/java/io/github/reqstool/gradle/RequirementsToolPlugin.java b/src/main/java/io/github/reqstool/gradle/RequirementsToolPlugin.java index 2808ab4..7bd0217 100644 --- a/src/main/java/io/github/reqstool/gradle/RequirementsToolPlugin.java +++ b/src/main/java/io/github/reqstool/gradle/RequirementsToolPlugin.java @@ -13,6 +13,12 @@ */ public class RequirementsToolPlugin implements Plugin { + /** + * Applies the plugin to a Gradle project. Registers the {@code assembleRequirements} + * task and automatically configures Maven publishing if the {@code maven-publish} + * plugin is applied. + * @param project the Gradle project + */ @Override public void apply(Project project) { // Create extension for configuration @@ -55,6 +61,12 @@ public void apply(Project project) { }); } + /** + * Configures Maven publishing to automatically attach the reqstool ZIP artifact to + * the publication. + * @param project the Gradle project + * @param assembleTask provider for the assembleRequirements task + */ private void configureMavenPublishing(Project project, TaskProvider assembleTask) { PublishingExtension publishing = project.getExtensions().getByType(PublishingExtension.class); diff --git a/src/main/java/io/github/reqstool/gradle/RequirementsToolTask.java b/src/main/java/io/github/reqstool/gradle/RequirementsToolTask.java index d480d90..68c131c 100644 --- a/src/main/java/io/github/reqstool/gradle/RequirementsToolTask.java +++ b/src/main/java/io/github/reqstool/gradle/RequirementsToolTask.java @@ -109,75 +109,132 @@ public class RequirementsToolTask extends DefaultTask { private final RegularFileProperty zipFile = getProject().getObjects().fileProperty(); + /** + * Returns the path to the requirements annotations YAML file. + * @return file property for requirements annotations + */ @Optional @InputFile public RegularFileProperty getRequirementsAnnotationsFile() { return requirementsAnnotationsFile; } + /** + * Returns the path to the SVCs (Software Verification Cases) annotations YAML file. + * @return file property for SVCs annotations + */ @Optional @InputFile public RegularFileProperty getSvcsAnnotationsFile() { return svcsAnnotationsFile; } + /** + * Returns the absolute path to the output directory. + * @return output directory path as a string + */ @Input public String getOutputDirectoryPath() { File outDir = outputDirectory.getAsFile().getOrNull(); return outDir != null ? outDir.getAbsolutePath() : ""; } + /** + * Returns the output directory file property. + * @return file property for the output directory + */ @Internal public RegularFileProperty getOutputDirectory() { return outputDirectory; } + /** + * Returns the dataset directory containing requirements and supporting files. + * @return file property for the dataset directory + */ @InputDirectory @Optional public RegularFileProperty getDatasetPath() { return datasetPath; } + /** + * Returns the list of test result file glob patterns. + * @return list property of test result patterns + */ @Input public ListProperty getTestResults() { return testResults; } + /** + * Returns whether this task execution should be skipped. + * @return boolean property + */ @Input public Property getSkip() { return skip; } + /** + * Returns whether ZIP artifact assembly should be skipped. + * @return boolean property + */ @Input public Property getSkipAssembleZipArtifact() { return skipAssembleZipArtifact; } + /** + * Returns whether artifact attachment should be skipped. + * @return boolean property + */ @Input public Property getSkipAttachZipArtifact() { return skipAttachZipArtifact; } + /** + * Returns the name of the project being built. + * @return project name property + */ @Input public Property getProjectName() { return projectName; } + /** + * Returns the version of the project being built. + * @return project version property + */ @Input public Property getProjectVersion() { return projectVersion; } + /** + * Returns the base directory of the project. + * @return project base directory property + */ @Input public Property getProjectBasedir() { return projectBasedir; } + /** + * Returns the path where the reqstool ZIP artifact will be written. + * @return file property for the ZIP artifact + */ @OutputFile public RegularFileProperty getZipFile() { return zipFile; } + /** + * Executes the task. Combines requirements and test annotations into a single + * annotations file, and optionally assembles a ZIP artifact containing requirements, + * annotations, and test results. + */ @TaskAction public void execute() { if (skip.get()) { @@ -226,6 +283,13 @@ public void execute() { } } + /** + * Combines implementations and tests nodes into a single requirement annotations + * node. + * @param implementationsNode node containing requirement implementations + * @param testsNode node containing test cases + * @return combined requirement annotations node + */ static JsonNode combineOutput(JsonNode implementationsNode, JsonNode testsNode) { ObjectNode requirementAnnotationsNode = yamlMapper.createObjectNode(); if (!implementationsNode.isEmpty()) { @@ -241,6 +305,12 @@ static JsonNode combineOutput(JsonNode implementationsNode, JsonNode testsNode) return newNode; } + /** + * Writes the combined annotations to a YAML file with language server schema hints. + * @param outputFile the file to write to + * @param combinedOutputNode the combined annotations node + * @throws IOException if writing fails + */ private void writeCombinedOutputToFile(File outputFile, JsonNode combinedOutputNode) throws IOException { File reqAnnotFile = requirementsAnnotationsFile.getAsFile().getOrNull(); File svcsAnnotFile = svcsAnnotationsFile.getAsFile().getOrNull(); @@ -255,6 +325,11 @@ private void writeCombinedOutputToFile(File outputFile, JsonNode combinedOutputN } } + /** + * Assembles the reqstool ZIP artifact containing requirements, annotations, and test + * results. + * @throws IOException if ZIP creation or file reading fails + */ private void assembleZipArtifact() throws IOException { String zipArtifactFilename = projectName.get() + "-" + projectVersion.get() + "-reqstool.zip"; String topLevelDir = projectName.get() + "-" + projectVersion.get() + "-reqstool"; @@ -340,6 +415,13 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO getLogger().info("Assembled zip artifact: " + zipFileOutput.getAbsolutePath()); } + /** + * Adds a file to the ZIP artifact at the specified target directory. + * @param zipOut the ZIP output stream + * @param file the file to add + * @param targetDirectory the target directory within the ZIP + * @throws IOException if reading the file or writing to ZIP fails + */ private void addFileToZipArtifact(ZipOutputStream zipOut, File file, File targetDirectory) throws IOException { if (file.exists()) { File entryName; @@ -362,6 +444,13 @@ private void addFileToZipArtifact(ZipOutputStream zipOut, File file, File target } } + /** + * Creates and adds the reqstool_config.yml file to the ZIP artifact. + * @param zipOut the ZIP output stream + * @param topLevelDir the top-level directory within the ZIP + * @param reqstoolConfigResources map of resource files included in the artifact + * @throws IOException if writing to ZIP fails + */ private void addReqstoolConfigYamlToZip(ZipOutputStream zipOut, File topLevelDir, Map reqstoolConfigResources) throws IOException { DumperOptions options = new DumperOptions();