Skip to content

Commit

Permalink
Builder patter refactoring.
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexandrouR committed Jan 22, 2020
1 parent 26e2eec commit 37755cd
Show file tree
Hide file tree
Showing 35 changed files with 852 additions and 675 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ gradle-app.setting
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar

# Cache of project
# Cache of baseProject
.gradletasknamecache

# Work around https://youtrack.jetbrains.com/issue/IDEA-116898
Expand All @@ -45,6 +45,6 @@ docs/build
.DS_Store

.settings
.project
.baseProject
.classpath
bin
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ About
=====
The Web3j command line tools enable developers to interact with blockchains more easily. The Web3j command line tools allow allow you to use some of the key functionality of web3j from your terminal, including:

* New project creation
* New baseProject creation
* Project creation from existing Solidity code
* Wallet creation
* Wallet password management
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ apply {
download {
src "https://raw.githubusercontent.com/web3j/build-tools/master/gradle/$buildScript/build.gradle"
dest "$rootDir/gradle/$buildScript/build.gradle"
overwrite true
overwrite false
quiet true
onlyIfModified true
}
Expand Down
1 change: 1 addition & 0 deletions gradle/repositories/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
repositories {
mavenCentral()
jcenter()
mavenLocal()
maven { url 'https://oss.sonatype.org/content/repositories/releases/' }
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
}
2 changes: 1 addition & 1 deletion gradlew
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"

# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
# by default we should be in the correct baseProject dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
Expand Down
12 changes: 6 additions & 6 deletions src/main/java/org/web3j/console/Runner.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@
import org.web3j.codegen.SolidityFunctionWrapperGenerator;
import org.web3j.codegen.TruffleJsonFunctionWrapperGenerator;
import org.web3j.console.config.CliConfig;
import org.web3j.console.project.ProjectCreator;
import org.web3j.console.project.ProjectImporter;
import org.web3j.console.project.UnitTestCreator;
import org.web3j.console.project.java.ProjectCreator;
import org.web3j.console.project.java.ProjectImporter;
import org.web3j.console.project.java.UnitTestCreator;
import org.web3j.console.update.Updater;
import org.web3j.utils.Version;

import static org.web3j.codegen.SolidityFunctionWrapperGenerator.COMMAND_SOLIDITY;
import static org.web3j.console.project.ProjectCreator.COMMAND_NEW;
import static org.web3j.console.project.ProjectImporter.COMMAND_IMPORT;
import static org.web3j.console.project.UnitTestCreator.COMMAND_GENERATE_TESTS;
import static org.web3j.console.project.java.ProjectCreator.COMMAND_NEW;
import static org.web3j.console.project.java.ProjectImporter.COMMAND_IMPORT;
import static org.web3j.console.project.java.UnitTestCreator.COMMAND_GENERATE_TESTS;
import static org.web3j.utils.Collection.tail;

/** Main entry point for running command line utilities. */
Expand Down
86 changes: 86 additions & 0 deletions src/main/java/org/web3j/console/project/BaseBuilder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* Copyright 2020 Web3 Labs Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package org.web3j.console.project;

import org.web3j.console.project.java.JavaProjectStructure;

public class BaseBuilder {

private String solidityImportPath;
private boolean withWallet;
private boolean withTests;
private String projectName;
private String packageName;
private String rootDirectory;
private boolean withSampleCode;
private boolean withFatJar;
private String command = "new";

public BaseBuilder withSolidityFile(final String solidityImportPath) {
this.solidityImportPath = solidityImportPath;
return this;
}

public BaseBuilder withWalletProvider(boolean withWalletProvider) {
this.withWallet = withWalletProvider;
return this;
}

public BaseBuilder withSampleCode(boolean withSampleCode) {
this.withSampleCode = withSampleCode;
return this;
}

public BaseBuilder withTests(boolean withTests) {
this.withTests = withTests;
return this;
}

public BaseBuilder withFatJar(boolean withFatJar) {
this.withFatJar = withFatJar;
return this;
}

public BaseBuilder withCommand(String command) {
this.command = command;
return this;
}

public BaseBuilder withProjectName(String projectName) {
this.projectName = projectName;
return this;
}

public BaseBuilder withPackageName(String packageName) {
this.packageName = packageName;
return this;
}

public BaseBuilder withRootDirectory(String rootDirectory) {
this.rootDirectory = rootDirectory;
return this;
}

public BaseProject build() throws Exception {
final ProjectStructure projectStructure =
new JavaProjectStructure(rootDirectory, packageName, projectName);
return new BaseProject(
withTests,
withFatJar,
withWallet,
withSampleCode,
command,
solidityImportPath,
projectStructure);
}
}
225 changes: 225 additions & 0 deletions src/main/java/org/web3j/console/project/BaseProject.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
/*
* Copyright 2019 Web3 Labs Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package org.web3j.console.project;

import java.io.File;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;

import org.web3j.codegen.Console;
import org.web3j.commons.JavaVersion;
import org.web3j.console.project.java.UnitTestCreator;
import org.web3j.console.project.templates.TemplateBuilder;
import org.web3j.console.project.templates.TemplateProvider;
import org.web3j.console.project.utils.ProgressCounter;
import org.web3j.console.project.utils.ProjectUtils;
import org.web3j.crypto.CipherException;

import static java.io.File.separator;

public class BaseProject {
private final boolean withTests;
private final boolean withFatJar;
private final boolean withWallet;
private final boolean withSampleCode;
private final String command;
private final String solidityImportPath;
private final ProjectStructure projectStructure;
private ProjectWallet projectWallet;
private ProgressCounter progressCounter = new ProgressCounter(true);

protected BaseProject(
boolean withTests,
boolean withFatJar,
boolean withWallet,
boolean withSampleCode,
String command,
String solidityImportPath,
ProjectStructure projectStructure) {
this.withTests = withTests;
this.withFatJar = withFatJar;
this.withWallet = withWallet;
this.withSampleCode = withSampleCode;
this.command = command;
this.solidityImportPath = solidityImportPath;
this.projectStructure = projectStructure;
}

public ProjectStructure getProjectStructure() {
return this.projectStructure;
}

public ProjectWallet getProjectWallet() {
return this.projectWallet;
}

private void buildGradleProject(final String pathToDirectory)
throws IOException, InterruptedException {
if (!isWindows()) {
setExecutable(pathToDirectory, "gradlew");
executeBuild(
new File(pathToDirectory), new String[] {"bash", "-c", "./gradlew build -q"});
} else {
setExecutable(pathToDirectory, "gradlew.bat");
executeBuild(
new File(pathToDirectory),
new String[] {"cmd.exe", "/c", "gradlew.bat build -q"});
}
}

private boolean isWindows() {
return System.getProperty("os.name").toLowerCase().startsWith("windows");
}

private void setExecutable(final String pathToDirectory, final String gradlew) {
final File f = new File(pathToDirectory + File.separator + gradlew);
final boolean isExecutable = f.setExecutable(true);
}

private void executeBuild(final File workingDir, final String[] command)
throws InterruptedException, IOException {
executeProcess(workingDir, command);
}

private void executeProcess(File workingDir, String[] command)
throws InterruptedException, IOException {
int exitCode =
new ProcessBuilder(command)
.directory(workingDir)
.redirectOutput(ProcessBuilder.Redirect.INHERIT)
.redirectError(ProcessBuilder.Redirect.INHERIT)
.start()
.waitFor();
if (exitCode != 0) {
Console.exitError("Could not build project.");
}
}

private void createFatJar(String pathToDirectory) throws IOException, InterruptedException {
if (!isWindows()) {
executeProcess(
new File(pathToDirectory),
new String[] {"bash", "./gradlew", "shadowJar", "-q"});
} else {
executeProcess(
new File(pathToDirectory),
new String[] {"cmd.exe", "/c", "./gradlew.bat shadowJar", "-q"});
}
}

private void generateTopLevelDirectories(ProjectStructure projectStructure) {
projectStructure.createMainDirectory();
projectStructure.createTestDirectory();
projectStructure.createSolidityDirectory();
projectStructure.createWrapperDirectory();
}

private void generateTests(ProjectStructure projectStructure) throws IOException {
String wrapperPath =
String.join(
separator,
projectStructure.getRootDirectory(),
projectStructure.projectName,
"build",
"generated",
"source",
"web3j",
"main",
"java");
String writePath =
String.join(
separator,
projectStructure.getRootDirectory(),
projectStructure.projectName,
"src",
"test",
"java");
new UnitTestCreator(wrapperPath, writePath).generate();
}

private void generateWallet()
throws CipherException, InvalidAlgorithmParameterException, NoSuchAlgorithmException,
NoSuchProviderException, IOException {
projectStructure.createWalletDirectory();
projectWallet =
new ProjectWallet(
ProjectUtils.generateWalletPassword(), projectStructure.getWalletPath());
ProjectWriter.writeResourceFile(
projectWallet.getWalletPassword(),
projectWallet.getPasswordFileName(),
projectStructure.getWalletPath());
}

private TemplateProvider getTemplateProvider() {
TemplateBuilder templateBuilder =
new TemplateBuilder()
.withProjectNameReplacement(projectStructure.projectName)
.withPackageNameReplacement(projectStructure.packageName)
.withGradleBatScript("gradlew.bat.template")
.withGradleScript("gradlew.template");
if (projectWallet != null) {

templateBuilder.withWalletNameReplacement(projectWallet.getWalletName());
templateBuilder.withPasswordFileName(projectWallet.getPasswordFileName());
}
if (command.equals("new")) {
templateBuilder
.withGradleBuild(
JavaVersion.getJavaVersionAsDouble() < 11
? "build.gradle.template"
: "build.gradleJava11.template")
.withSolidityProject("HelloWorld.sol");

} else if (command.equals("import")) {
templateBuilder
.withGradleBuild(
JavaVersion.getJavaVersionAsDouble() < 11
? "build.gradleImport.template"
: "build.gradleImportJava11.template")
.withPathToSolidityFolder(solidityImportPath);
}
templateBuilder
.withGradleSettings("settings.gradle.template")
.withWrapperGradleSettings("gradlew-wrapper.properties.template")
.withGradlewWrapperJar("gradle-wrapper.jar");
if (withSampleCode) {
templateBuilder.withMainJavaClass("Template.java");
} else {
templateBuilder.withMainJavaClass("EmptyTemplate.java");
}

return templateBuilder.build();
}

public void createProject()
throws IOException, InterruptedException, NoSuchAlgorithmException,
NoSuchProviderException, InvalidAlgorithmParameterException, CipherException {
generateTopLevelDirectories(projectStructure);
if (withWallet) {
generateWallet();
}
getTemplateProvider().generateFiles(projectStructure);
progressCounter.processing("Creating " + projectStructure.projectName);
buildGradleProject(projectStructure.getProjectRoot());

if (withTests) {
generateTests(projectStructure);
}
if (withFatJar) {
createFatJar(projectStructure.getProjectRoot());
}
progressCounter.setLoading(false);
}
}
Loading

0 comments on commit 37755cd

Please sign in to comment.