Projects can save themselves to disk (WIP)

This commit is contained in:
nathan 2017-02-17 21:23:49 +01:00
parent de5fdecd0c
commit 432495213c
4 changed files with 251 additions and 85 deletions

View File

@ -29,7 +29,13 @@ import java.util.Map;
import java.util.Set;
import org.bouncycastle.crypto.digests.MD5Digest;
import org.slf4j.Logger;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.Serializer;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.esotericsoftware.minlog.Log;
import com.esotericsoftware.wildcard.Paths;
import com.twmacinta.util.MD5;
@ -43,6 +49,9 @@ import dorkbox.license.License;
import dorkbox.util.Base64Fast;
import dorkbox.util.FileUtil;
import dorkbox.util.OS;
import dorkbox.util.SerializationManager;
import dorkbox.util.serialization.FileSerializer;
import io.netty.buffer.ByteBuf;
@SuppressWarnings({"unchecked", "unused"})
public abstract
@ -62,15 +71,82 @@ class Project<T extends Project<T>> {
private static boolean alreadyChecked = false;
private static Comparator<Project> dependencyComparator = new ProjectComparator();
// used to suppress certain messages when building deps
protected boolean isBuildingDependencies = false;
// Sometimes we don't want to export the build to maven (ie: when running a test, for example)
protected boolean exportToMaven = false;
public static List<File> builderFiles = new ArrayList<File>();
public static Thread shutdownHook;
static final SerializationManager manager = new SerializationManager() {
Kryo kryo = new Kryo();
{
// we don't want logging from Kryo...
Log.set(Log.LEVEL_ERROR);
register(File.class, new FileSerializer());
}
@Override
public
void register(final Class<?> clazz) {
kryo.register(clazz);
}
@Override
public
void register(final Class<?> clazz, final Serializer<?> serializer) {
kryo.register(clazz, serializer);
}
@Override
public
void register(final Class<?> type, final Serializer<?> serializer, final int id) {
kryo.register(type, serializer, id);
}
@Override
public
void write(final ByteBuf buffer, final Object message) {
final Output output = new Output();
writeFullClassAndObject(null, output, message);
buffer.writeBytes(output.getBuffer());
}
@Override
public
Object read(final ByteBuf buffer, final int length) throws IOException {
final Input input = new Input();
buffer.readBytes(input.getBuffer());
final Object o = readFullClassAndObject(null, input);
buffer.skipBytes(input.position());
return o;
}
@Override
public
void writeFullClassAndObject(final Logger logger, final Output output, final Object value) {
kryo.writeClassAndObject(output, value);
}
@Override
public
Object readFullClassAndObject(final Logger logger, final Input input) throws IOException {
return kryo.readClassAndObject(input);
}
@Override
public
void finishInit() {
}
@Override
public
boolean initialized() {
return false;
}
};
static {
// check to see if our deploy code has changed. if yes, then we have to rebuild everything since
// we don't know what might have changed.
@ -130,7 +206,7 @@ class Project<T extends Project<T>> {
public final String name;
public String name;
protected Version version;
@ -151,7 +227,10 @@ class Project<T extends Project<T>> {
protected List<Project<?>> dependencies = new ArrayList<Project<?>>();
/** ALL related dependencies for this project (ie: recursively searched) */
List<Project<?>> fullDependencyList = null;
transient List<Project<?>> fullDependencyList = null;
// used to make sure licenses are called in the correct spot
private transient boolean calledLicenseBefore = false;
transient Paths checksumPaths = new Paths();
protected List<License> licenses = new ArrayList<License>();
@ -159,14 +238,20 @@ class Project<T extends Project<T>> {
private ArrayList<String> unresolvedDependencies = new ArrayList<String>();
// used to suppress certain messages when building deps
protected transient boolean isBuildingDependencies = false;
// Sometimes we don't want to export the build to maven (ie: when running a test, for example)
protected boolean exportToMaven = false;
MavenExporter mavenExporter;
public MavenInfo mavenInfo;
/** true if we had to build this project */
boolean shouldBuild = false;
transient boolean shouldBuild = false;
/** true if we skipped building this project */
boolean skippedBuild = false;
transient boolean skippedBuild = false;
/**
* Temporary projects are always built, but not always exported to maven (this is controlled by the parent, non-temp project
@ -236,6 +321,10 @@ class Project<T extends Project<T>> {
deps.remove(outputDir);
}
// for serialization
protected
Project() {
}
protected
Project(String projectName) {
@ -243,7 +332,7 @@ class Project<T extends Project<T>> {
this.buildOptions = new BuildOptions();
String lowerCase_outputDir = projectName.toLowerCase();
this.stagingDir = new File(FileUtil.normalizeAsFile(STAGING + File.separator + lowerCase_outputDir));
this.stagingDir = FileUtil.normalize(STAGING + File.separator + lowerCase_outputDir);
// must call this method, because it's not overridden by jar type
outputFile0(new File(this.stagingDir.getParentFile(), this.name + getExtension()).getAbsolutePath(), null);
}
@ -513,7 +602,7 @@ class Project<T extends Project<T>> {
public
T addSrc(String file) {
this.sources.add(new File(FileUtil.normalizeAsFile(file)));
this.sources.add(FileUtil.normalize(file));
return (T) this;
}
@ -525,7 +614,7 @@ class Project<T extends Project<T>> {
public
T dist(String distLocation) {
this.distLocation = FileUtil.normalizeAsFile(distLocation);
this.distLocation = FileUtil.normalize(distLocation).getAbsolutePath();
return (T) this;
}
@ -549,7 +638,6 @@ class Project<T extends Project<T>> {
return this.buildOptions;
}
private boolean calledLicenseBefore = false;
/**
* This call needs to be (at least) before dependencies are added, otherwise the order of licenses might be in the incorrect order.
* Preferably, this should be the very first call.
@ -591,7 +679,7 @@ class Project<T extends Project<T>> {
public
void copyFiles(String targetLocation) throws IOException {
copyFiles(new File(FileUtil.normalizeAsFile(targetLocation)));
copyFiles(FileUtil.normalize(targetLocation));
}
public
@ -657,7 +745,7 @@ class Project<T extends Project<T>> {
public
void copyMainFiles(String targetLocation) throws IOException {
copyMainFiles(new File(FileUtil.normalizeAsFile(targetLocation)));
copyMainFiles(FileUtil.normalize(targetLocation));
}
@ -922,4 +1010,11 @@ class Project<T extends Project<T>> {
// only if we save the build. Test builds don't save, and we shouldn't upload them to maven
}
}
/**
* Saves the project details to the specified location
* @param location
*/
public abstract
void save(final String location);
}

View File

@ -15,14 +15,6 @@
*/
package dorkbox.build;
import com.esotericsoftware.wildcard.Paths;
import dorkbox.Builder;
import dorkbox.build.util.BuildLog;
import dorkbox.build.util.jar.JarUtil;
import dorkbox.util.FileUtil;
import dorkbox.util.gwt.GwtSymbolMapParser;
import dorkbox.util.process.JavaProcessBuilder;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
@ -33,6 +25,15 @@ import java.util.Arrays;
import java.util.List;
import java.util.Map.Entry;
import com.esotericsoftware.wildcard.Paths;
import dorkbox.Builder;
import dorkbox.build.util.BuildLog;
import dorkbox.build.util.jar.JarUtil;
import dorkbox.util.FileUtil;
import dorkbox.util.gwt.GwtSymbolMapParser;
import dorkbox.util.process.JavaProcessBuilder;
public
class ProjectGwt extends Project<ProjectGwt> {
@ -407,4 +408,13 @@ class ProjectGwt extends Project<ProjectGwt> {
return this;
}
/**
* Take all of the parameters of this project, and convert it to a text file.
*/
@Override
public
void save(final String location) {
}
}

View File

@ -6,54 +6,46 @@ import java.io.IOException;
import dorkbox.Version;
import dorkbox.build.util.BuildLog;
import dorkbox.build.util.FileNotFoundRuntimeException;
import dorkbox.util.storage.Storage;
import dorkbox.util.storage.StorageType;
public class ProjectJar extends Project<ProjectJar> {
public static ProjectJar create(String projectName) {
public static
ProjectJar create(String projectName) {
ProjectJar projectJar = new ProjectJar(projectName);
deps.put(projectName, projectJar);
return projectJar;
}
private ProjectJar(String projectName) {
// for serialization
private
ProjectJar() {
}
private
ProjectJar(String projectName) {
super(projectName);
}
@Override
public ProjectJar addSrc(String file) {
public
ProjectJar addSrc(String file) {
BuildLog.title("Error")
.println("Cannot specify a source file in this manner for a jar. Please set the source along with the output file");
throw new FileNotFoundRuntimeException("Invalid file: " + file);
}
@Override
public ProjectJar addSrc(File file) {
BuildLog.title("Error")
.println("Cannot specify a source file in this manner for a jar. Please set the source along with the output file");
throw new FileNotFoundRuntimeException("Invalid file: " + file);
}
@Override
public ProjectJar version(Version version) {
super.version(version);
return this;
}
@Override
public String getExtension() {
return Project.JAR_EXTENSION;
}
@Override
public boolean
build(final int targetJavaVersion) throws IOException {
public
boolean build(final int targetJavaVersion) throws IOException {
return false;
}
@Override
public ProjectJar dist(String distLocation) {
super.dist(distLocation);
return this;
public
String getExtension() {
return Project.JAR_EXTENSION;
}
@Override
@ -72,9 +64,26 @@ public class ProjectJar extends Project<ProjectJar> {
return outputFileNoWarn(outputFile, outputSourceFile);
}
@Override
public
ProjectJar outputFileNoWarn(final String outputFile) {
return outputFileNoWarn(outputFile, null);
ProjectJar addSrc(File file) {
BuildLog.title("Error")
.println("Cannot specify a source file in this manner for a jar. Please set the source along with the output file");
throw new FileNotFoundRuntimeException("Invalid file: " + file);
}
@Override
public
ProjectJar dist(String distLocation) {
super.dist(distLocation);
return this;
}
@Override
public
ProjectJar version(Version version) {
super.version(version);
return this;
}
public
@ -86,4 +95,39 @@ public class ProjectJar extends Project<ProjectJar> {
return super.outputFile(outputFile, outputSourceFile);
}
public
ProjectJar outputFileNoWarn(final String outputFile) {
return outputFileNoWarn(outputFile, null);
}
/**
* Take all of the parameters of this project, and convert it to a text file.
*/
@Override
public
void save(final String location) {
Storage storage = StorageType.Disk()
.file(location)
.serializer(manager)
.make();
storage.put(this.name, this);
storage.save();
}
/**
* Take all of the parameters of this project, and convert it to a text file.
*/
public static
ProjectJar get(final String projectName, final String location) {
Storage storage = StorageType.Disk()
.file(location)
.serializer(manager)
.logger(null)
.make();
ProjectJar proj = storage.get(projectName);
return proj;
}
}

View File

@ -47,6 +47,7 @@ import dorkbox.Version;
import dorkbox.build.util.BuildLog;
import dorkbox.build.util.CrossCompileClass;
import dorkbox.build.util.DependencyWalker;
import dorkbox.build.util.FileNotFoundRuntimeException;
import dorkbox.build.util.classloader.ByteClassloader;
import dorkbox.build.util.classloader.JavaMemFileManager;
import dorkbox.license.License;
@ -62,9 +63,9 @@ class ProjectJava extends Project<ProjectJava> {
protected Paths sourcePaths = new Paths();
public Paths classPaths = new Paths();
private ByteClassloader bytesClassloader = null;
private transient ByteClassloader bytesClassloader = null;
protected Jarable jarable = null;
protected transient Jarable jarable = null;
private boolean suppressSunWarnings = false;
private final List<CrossCompileClass> crossCompileClasses = new ArrayList<CrossCompileClass>(4);
@ -359,7 +360,12 @@ class ProjectJava extends Project<ProjectJava> {
FileUtil.delete(tempProject.stagingDir);
FileUtil.mkdir(tempProject.stagingDir);
tempProject.shouldBuild = true; // always build temp projects
tempProject.build(crossCompileClass.targetJavaVersion);
try {
tempProject.build(crossCompileClass.targetJavaVersion);
} catch (RuntimeException e) {
e.printStackTrace();
}
// now have to save out the source files (that are now converted to .class files)
for (File sourceFile : sourceFiles.getFiles()) {
@ -504,7 +510,14 @@ class ProjectJava extends Project<ProjectJava> {
args.add("1." + targetJavaVersion);
args.add("-bootclasspath");
args.add(this.buildOptions.compiler.crossCompileLibrary.getCrossCompileLibraryLocation(targetJavaVersion));
String location = this.buildOptions.compiler.crossCompileLibrary.getCrossCompileLibraryLocation(targetJavaVersion);
File file = FileUtil.normalize(location);
if (!file.canRead()) {
throw new FileNotFoundRuntimeException("Unable to read cross compile jar: " + location);
}
args.add(file.getAbsolutePath());
}
// suppress sun proprietary warnings
@ -730,44 +743,48 @@ class ProjectJava extends Project<ProjectJava> {
/**
* Take all of the parameters of this project, and convert it to a text file.
*
* @throws IOException
*/
@Override
public
void toBuildFile() throws IOException {
YamlWriter writer = new YamlWriter(new FileWriter("build.oak"));
YamlConfig config = writer.getConfig();
void save(final String location) {
try {
YamlWriter writer = new YamlWriter(new FileWriter(location));
YamlConfig config = writer.getConfig();
config.writeConfig.setWriteRootTags(false);
config.writeConfig.setWriteRootTags(false);
config.setPropertyElementType(ProjectJava.class, "licenses", License.class);
config.setPrivateFields(true);
config.setPropertyElementType(ProjectJava.class, "licenses", License.class);
config.setPrivateFields(true);
config.readConfig.setConstructorParameters(License.class, new Class[] {String.class, LicenseType.class},
new String[] {"licenseName", "licenseType"});
config.readConfig.setConstructorParameters(ProjectJava.class, new Class[] {String.class}, new String[] {"projectName"});
config.readConfig.setConstructorParameters(License.class,
new Class[] {String.class, LicenseType.class},
new String[] {"licenseName", "licenseType"});
config.readConfig.setConstructorParameters(ProjectJava.class, new Class[] {String.class}, new String[] {"projectName"});
config.setScalarSerializer(Paths.class, new ScalarSerializer<Paths>() {
@Override
public
Paths read(String value) throws YamlException {
String[] split = value.split(File.pathSeparator);
Paths paths = new Paths();
for (String s : split) {
paths.addFile(s);
config.setScalarSerializer(Paths.class, new ScalarSerializer<Paths>() {
@Override
public
Paths read(String value) throws YamlException {
String[] split = value.split(File.pathSeparator);
Paths paths = new Paths();
for (String s : split) {
paths.addFile(s);
}
return paths;
}
return paths;
}
@Override
public
String write(Paths paths) throws YamlException {
return paths.toString(File.pathSeparator);
}
});
@Override
public
String write(Paths paths) throws YamlException {
return paths.toString(File.pathSeparator);
}
});
writer.write(this);
writer.close();
writer.write(this);
writer.close();
} catch (IOException e) {
throw new RuntimeException("Unable to save file.", e);
}
}
/**