S101Plugin.java 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /*
  2. * Copyright 2002-2024 the original author or authors.
  3. *
  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. *
  8. * https://www.apache.org/licenses/LICENSE-2.0
  9. *
  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. package s101;
  17. import java.io.ByteArrayInputStream;
  18. import java.io.File;
  19. import java.io.FileInputStream;
  20. import java.io.IOException;
  21. import java.io.InputStream;
  22. import java.nio.charset.StandardCharsets;
  23. import java.nio.file.Files;
  24. import java.nio.file.Path;
  25. import java.nio.file.StandardCopyOption;
  26. import org.gradle.api.Plugin;
  27. import org.gradle.api.Project;
  28. import org.gradle.api.provider.Property;
  29. import org.gradle.api.tasks.JavaExec;
  30. public class S101Plugin implements Plugin<Project> {
  31. @Override
  32. public void apply(Project project) {
  33. project.getExtensions().add("s101", new S101PluginExtension(project));
  34. project.getTasks().register("s101Install", S101Install.class, this::configure);
  35. project.getTasks().register("s101Configure", S101Configure.class, this::configure);
  36. project.getTasks().register("s101", JavaExec.class, this::configure);
  37. }
  38. private void configure(S101Install install) {
  39. install.setDescription("Installs Structure101 to your filesystem");
  40. }
  41. private void configure(S101Configure configure) {
  42. configure.setDescription("Applies a default Structure101 configuration to the project");
  43. }
  44. private void configure(JavaExec exec) {
  45. exec.setDescription("Runs Structure101 headless analysis, installing and configuring if necessary");
  46. exec.dependsOn("assemble");
  47. Project project = exec.getProject();
  48. S101PluginExtension extension = project.getExtensions().getByType(S101PluginExtension.class);
  49. exec
  50. .workingDir(extension.getInstallationDirectory())
  51. .classpath(new File(extension.getInstallationDirectory().get(), "structure101-java-build.jar"))
  52. .args(new File(new File(project.getBuildDir(), "s101"), "config.xml"))
  53. .systemProperty("s101.label", computeLabel(extension).get())
  54. .doFirst((task) -> {
  55. installAndConfigureIfNeeded(project);
  56. copyConfigurationToBuildDirectory(extension, project);
  57. })
  58. .doLast((task) -> {
  59. copyResultsBackToConfigurationDirectory(extension, project);
  60. });
  61. }
  62. private Property<String> computeLabel(S101PluginExtension extension) {
  63. boolean hasBaseline = extension.getConfigurationDirectory().get().toPath()
  64. .resolve("repository").resolve("snapshots").resolve("baseline").toFile().exists();
  65. if (!hasBaseline) {
  66. return extension.getLabel().convention("baseline");
  67. }
  68. return extension.getLabel().convention("recent");
  69. }
  70. private void installAndConfigureIfNeeded(Project project) {
  71. S101Configurer configurer = new S101Configurer(project);
  72. S101PluginExtension extension = project.getExtensions().getByType(S101PluginExtension.class);
  73. String licenseId = extension.getLicenseId().getOrNull();
  74. if (licenseId != null) {
  75. configurer.license(licenseId);
  76. }
  77. File installationDirectory = extension.getInstallationDirectory().get();
  78. File configurationDirectory = extension.getConfigurationDirectory().get();
  79. if (!installationDirectory.exists()) {
  80. configurer.install(installationDirectory, configurationDirectory);
  81. }
  82. if (!configurationDirectory.exists()) {
  83. configurer.configure(installationDirectory, configurationDirectory);
  84. }
  85. }
  86. private void copyConfigurationToBuildDirectory(S101PluginExtension extension, Project project) {
  87. Path configurationDirectory = extension.getConfigurationDirectory().get().toPath();
  88. Path buildDirectory = project.getBuildDir().toPath();
  89. copyDirectory(project, configurationDirectory, buildDirectory);
  90. }
  91. private void copyResultsBackToConfigurationDirectory(S101PluginExtension extension, Project project) {
  92. Path buildConfigurationDirectory = project.getBuildDir().toPath().resolve("s101");
  93. String label = extension.getLabel().get();
  94. if ("baseline".equals(label)) { // a new baseline was created
  95. copyDirectory(project, buildConfigurationDirectory.resolve("repository").resolve("snapshots"),
  96. extension.getConfigurationDirectory().get().toPath().resolve("repository"));
  97. copyDirectory(project, buildConfigurationDirectory.resolve("repository"),
  98. extension.getConfigurationDirectory().get().toPath());
  99. }
  100. }
  101. private void copyDirectory(Project project, Path source, Path destination) {
  102. try {
  103. Files.walk(source)
  104. .forEach(each -> {
  105. Path relativeToSource = source.getParent().relativize(each);
  106. Path resolvedDestination = destination.resolve(relativeToSource);
  107. if (each.toFile().isDirectory()) {
  108. resolvedDestination.toFile().mkdirs();
  109. return;
  110. }
  111. InputStream input;
  112. if ("project.java.hsp".equals(each.toFile().getName())) {
  113. Path relativeTo = project.getBuildDir().toPath().resolve("s101").relativize(project.getProjectDir().toPath());
  114. String value = "const(THIS_FILE)/" + relativeTo;
  115. input = replace(each, "<property name=\"relative-to\" value=\"(.*)\" />", "<property name=\"relative-to\" value=\"" + value + "\" />");
  116. } else if (each.toFile().toString().endsWith(".xml")) {
  117. input = replace(each, "\\r\\n", "\n");
  118. } else {
  119. input = input(each);
  120. }
  121. try {
  122. Files.copy(input, resolvedDestination, StandardCopyOption.REPLACE_EXISTING);
  123. } catch (IOException e) {
  124. throw new RuntimeException(e);
  125. }
  126. });
  127. } catch (IOException e) {
  128. throw new RuntimeException(e);
  129. }
  130. }
  131. private InputStream replace(Path file, String search, String replace) {
  132. try {
  133. byte[] b = Files.readAllBytes(file);
  134. String contents = new String(b).replaceAll(search, replace);
  135. return new ByteArrayInputStream(contents.getBytes(StandardCharsets.UTF_8));
  136. } catch (IOException e) {
  137. throw new RuntimeException(e);
  138. }
  139. }
  140. private InputStream input(Path file) {
  141. try {
  142. return new FileInputStream(file.toFile());
  143. } catch (IOException e) {
  144. throw new RuntimeException(e);
  145. }
  146. }
  147. }