Skip to content
This repository has been archived by the owner on May 13, 2023. It is now read-only.

Commit

Permalink
Interactive project creation
Browse files Browse the repository at this point in the history
Also fixed a crash that would occur if the buildscript project was package-private
  • Loading branch information
Geolykt committed May 4, 2022
1 parent f9069d8 commit 726380e
Show file tree
Hide file tree
Showing 9 changed files with 253 additions and 63 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package io.github.coolcrabs.brachyura.bootstrap;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.invoke.MethodHandles;
Expand All @@ -27,10 +26,6 @@ public class Main {
public static void main(String[] args) throws Throwable {
System.out.println("Using brachyura bootstrap " + VERSION);

if (args.length != 0 && args[0].equalsIgnoreCase("createTemplate")) {
createTemplate(args);
}

// https://stackoverflow.com/a/2837287
Path projectPath = Paths.get(Main.class.getProtectionDomain().getCodeSource().getLocation().toURI()).getParent();
if (projectPath == null) {
Expand Down Expand Up @@ -72,34 +67,6 @@ public static void main(String[] args) throws Throwable {
).invokeExact(args, projectPath, classpath);
}

private static void createTemplate(String[] args) throws IOException {
Path javaSourceFolder = Paths.get("src", "main", "java");
if (Files.exists(javaSourceFolder)) {
System.out.println("Cannot create template: The source folder (" + javaSourceFolder.toAbsolutePath().toString() + ") already exists. Consider deleting it if you are sure of your actions.");
return;
}
Path buildscriptSourceFolder = Paths.get("buildscript").resolve(javaSourceFolder);
if (Files.exists(buildscriptSourceFolder)) {
System.out.println("Cannot create template: Buildscript folder already exists. Consider deleting it if you are sure of your actions.");
return;
}
Path mainResourceFolder = Paths.get("src", "main", "resources");
if (Files.exists(mainResourceFolder)) {
System.out.println("Cannot create template: The resources folder (" + mainResourceFolder.toAbsolutePath().toString() + ") already exists. Consider deleting it if you are sure of your actions.");
return;
}

Files.createDirectories(javaSourceFolder);
Files.createDirectories(buildscriptSourceFolder);
Files.createDirectories(mainResourceFolder);

Path buildscriptFile = buildscriptSourceFolder.resolve("Buildscript.java");
Path exampleApplicationFile = javaSourceFolder.resolve("ExampleApplication.java");

Files.copy(Main.class.getClassLoader().getResourceAsStream("Buildscript.java"), buildscriptFile);
Files.copy(Main.class.getClassLoader().getResourceAsStream("ExampleApplication.java"), exampleApplicationFile);
}

private static Collection<? extends Path> getBuildscriptDependencies(Path projectPath) throws Exception {
Path buildscriptDir = projectPath.resolve("buildscript");
if (!Files.isDirectory(buildscriptDir)) {
Expand Down
19 changes: 0 additions & 19 deletions bootstrap/src/main/resources/Buildscript.java

This file was deleted.

6 changes: 0 additions & 6 deletions bootstrap/src/main/resources/ExampleApplication.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
Expand Down Expand Up @@ -50,7 +49,6 @@ static TinyTree read(BufferedReader reader) throws IOException {
start = end;
}
parts = strictlySplit.toArray(new String[0]);
System.out.println(Arrays.toString(parts));
if (parts.length - 1 < r.namespaces.length) {
throw new ArrayIndexOutOfBoundsException("Invalid line (parts length is " + parts.length
+ ", namespaces length is " + r.namespaces.length + "): " + line);
Expand Down
12 changes: 11 additions & 1 deletion brachyura/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>io.github.coolcrabs</groupId>
<artifactId>brachyura</artifactId>
<version>0.82.0</version>
<version>0.82.1</version>

<properties>
<java.version>1.8</java.version>
Expand Down Expand Up @@ -87,13 +87,23 @@
<artifactId>access-widener</artifactId>
<version>2.1.0</version>
</dependency>

<!-- Slbrachyura: Custom maven resolver -->
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>

<!-- Slbrachyura: Interactive project creation -->
<!-- https://mvnrepository.com/artifact/com.squareup/javapoet -->
<dependency>
<groupId>com.squareup</groupId>
<artifactId>javapoet</artifactId>
<version>1.13.0</version>
</dependency>

<!-- junit 5 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,129 @@
package io.github.coolcrabs.brachyura.project;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

import org.jetbrains.annotations.NotNull;
import org.tinylog.Logger;

import io.github.coolcrabs.brachyura.maven.MavenId;
import io.github.coolcrabs.brachyura.plugins.Plugin;
import io.github.coolcrabs.brachyura.plugins.Plugins;

public class BrachyuraEntry {
private BrachyuraEntry() { }

private static final boolean isBlank(@NotNull String string) {
int length = string.length();
for (int i = 0; i < length; i++) {
if (!Character.isWhitespace(string.codePointAt(i))) {
return false;
}
}
return true;
}

// Slbrachyura: Interactive project creation
private static void interactiveSetup(String[] args, Path projectDir, List<Path> classpath) {
Path relJavaSourceFolder = Paths.get("src", "main", "java");
Path javaSourceFolder = projectDir.resolve(relJavaSourceFolder);
if (Files.exists(javaSourceFolder)) {
System.err.println("Cannot create template: The source folder (" + javaSourceFolder.toAbsolutePath().toString() + ") already exists. Consider deleting it if you are sure of your actions.");
return;
}
Path buildscriptSourceFolder = projectDir.resolve("buildscript").resolve(relJavaSourceFolder);
if (Files.exists(buildscriptSourceFolder)) {
System.err.println("Cannot create template: Buildscript folder already exists. Consider deleting it if you are sure of your actions.");
return;
}
Path mainResourceFolder = projectDir.resolve("src").resolve("main").resolve("resources");
if (Files.exists(mainResourceFolder)) {
System.err.println("Cannot create template: The resources folder (" + mainResourceFolder.toAbsolutePath().toString() + ") already exists. Consider deleting it if you are sure of your actions.");
return;
}

try {
Files.createDirectories(javaSourceFolder);
Files.createDirectories(buildscriptSourceFolder);
Files.createDirectories(mainResourceFolder);
} catch (IOException e) {
e.printStackTrace();
}

Path buildscriptFile = buildscriptSourceFolder.resolve("Buildscript.java");
Path exampleApplicationFile = javaSourceFolder.resolve("ExampleApplication.java");

BuildscriptCreator bsCreator = new BuildscriptCreator();

try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
while (true) {
System.out.println("Choose java version [8]: ");
String javaVer = br.readLine();
if (javaVer == null || isBlank(javaVer)) {
javaVer = "8";
}
try {
bsCreator.withJavaVersion(Integer.parseInt(javaVer.trim()));
break;
} catch (NumberFormatException nfe) {
System.err.println("Unparseable java version: \"" + javaVer + "\". Note: it must be an integer");
}
}
System.out.println("Choose project name [ExampleBuildscript]: ");
String buildscriptProjectName = br.readLine();
if (buildscriptProjectName == null || isBlank(buildscriptProjectName)) {
buildscriptProjectName = "ExampleBuildscript";
}
bsCreator.withProjectName(buildscriptProjectName);

System.out.println("Choose maven group id [org.example]: ");
String groupId = br.readLine();
if (groupId == null || isBlank(groupId)) {
groupId = "org.example";
}
System.out.println("Choose maven artifact id [example]: ");
String artifactId = br.readLine();
if (artifactId == null || isBlank(artifactId)) {
artifactId = "example";
}
System.out.println("Choose maven artifact version [0.0.1-SNAPSHOT]: ");
String version = br.readLine();
if (version == null || isBlank(version)) {
version = "0.0.1-SNAPSHOT";
}
bsCreator.withId(new MavenId(groupId, artifactId, version));
} catch (IOException e) {
e.printStackTrace();
return;
}

try {
Files.write(buildscriptFile, bsCreator.getBuildscriptSource().getBytes(StandardCharsets.UTF_8));
Files.write(exampleApplicationFile,
("public class ExampleApplication {\n"
+ "\n"
+ " public static void main(String[] args) {\n"
+ " System.out.println(\"Hello, World!\");\n"
+ " }\n"
+ "}\n").getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE_NEW);
} catch (IOException e) {
e.printStackTrace();
}
}

// Called via reflection by bootstrap
public static void main(String[] args, Path projectDir, List<Path> classpath) {
if (args.length != 0 && args[0].equalsIgnoreCase("createTemplate")) {
interactiveSetup(args, projectDir, classpath);
return;
}
int exitcode = 0;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package io.github.coolcrabs.brachyura.project;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

import javax.lang.model.element.Modifier;

import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;

import com.squareup.javapoet.AnnotationSpec;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeSpec;

import io.github.coolcrabs.brachyura.maven.MavenId;
import io.github.coolcrabs.brachyura.project.java.SimpleJavaProject;

// Slbrachyura: Interactive project creation
public class BuildscriptCreator {

private String buildscriptName = "Buildscript";
private String buildscriptProjectName = "ExampleBuildscript";
private Type buildscriptSuperclass = SimpleJavaProject.class;
private int javaVersion = 8;
private MavenId projectId = new MavenId("com.example", "example", "0.0.1-SNAPSHOT");

@NotNull
@Contract(pure = true, value = "-> new")
public String getBuildscriptSource() {
final String className;
final String packageName;
{
int lastDot = buildscriptName.lastIndexOf('.');
if (lastDot == -1) {
packageName = "";
} else {
packageName = buildscriptName.substring(0, lastDot);
}
className = buildscriptName.substring(lastDot + 1);
}

List<MethodSpec> methods = new ArrayList<>();

methods.add(MethodSpec.methodBuilder("getId")
.returns(MavenId.class)
.addAnnotation(Override.class)
.addAnnotation(NotNull.class)
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addStatement("return new $T($S, $S, $S)", MavenId.class, projectId.groupId, projectId.artifactId, projectId.version)
.build());

methods.add(MethodSpec.methodBuilder("getJavaVersion")
.returns(int.class)
.addAnnotation(Override.class)
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addStatement("return $L", javaVersion)
.build());

methods.add(MethodSpec.methodBuilder("getBuildscriptName")
.returns(String.class)
.addAnnotation(Override.class)
.addAnnotation(NotNull.class)
.addAnnotation(AnnotationSpec.builder(Contract.class).addMember("pure", CodeBlock.of("true")).build())
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addStatement(CodeBlock.of("return $S", buildscriptProjectName))
.build());

TypeSpec type = TypeSpec.classBuilder(className)
.addSuperinterface(DescriptiveBuildscriptName.class)
.superclass(buildscriptSuperclass)
.addMethods(methods)
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.build();

JavaFile buildscriptFile = JavaFile.builder(packageName, type)
.build();

StringBuilder builder = new StringBuilder();
try {
buildscriptFile.writeTo(builder);
} catch (IOException e) {
throw new RuntimeException(e);
}
builder.append('\n');
return builder.toString();
}

@NotNull
@Contract(mutates = "this", pure = false, value = "_ -> this")
public BuildscriptCreator withClassName(@NotNull String name) {
this.buildscriptName = name;
return this;
}

@NotNull
@Contract(mutates = "this", pure = false, value = "_ -> this")
public BuildscriptCreator withId(@NotNull MavenId id) {
this.projectId = id;
return this;
}

@NotNull
@Contract(mutates = "this", pure = false, value = "_ -> this")
public BuildscriptCreator withJavaVersion(int version) {
this.javaVersion = version;
return this;
}


@NotNull
@Contract(mutates = "this", pure = false, value = "_ -> this")
public BuildscriptCreator withProjectName(@NotNull String name) {
this.buildscriptProjectName = name;
return this;
}

@NotNull
@Contract(mutates = "this", pure = false, value = "_ -> this")
public BuildscriptCreator withSuperclass(@NotNull Type superClass) {
this.buildscriptSuperclass = superClass;
return this;
}
}
Loading

0 comments on commit 726380e

Please sign in to comment.