summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormd_5 <git@md-5.net>2014-11-26 16:56:48 +1100
committermd_5 <git@md-5.net>2014-11-28 17:10:15 +1100
commit032e8ca0a3a2fd6059308ca43083df986467b99e (patch)
tree29a154dcfab98c5390ef6502c604509b884ea2d8
downloadbuildtools-032e8ca0a3a2fd6059308ca43083df986467b99e.tar
buildtools-032e8ca0a3a2fd6059308ca43083df986467b99e.tar.gz
buildtools-032e8ca0a3a2fd6059308ca43083df986467b99e.tar.lz
buildtools-032e8ca0a3a2fd6059308ca43083df986467b99e.tar.xz
buildtools-032e8ca0a3a2fd6059308ca43083df986467b99e.zip
Initial Commit
For more information please see http://www.spigotmc.org/
-rw-r--r--.gitignore35
-rw-r--r--LICENSE26
-rw-r--r--nb-configuration.xml31
-rw-r--r--pom.xml107
-rw-r--r--src/main/java/org/spigotmc/builder/Builder.java411
5 files changed, 610 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..2ae51bc
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,35 @@
+# Eclipse stuff
+.classpath
+.project
+.settings/
+
+# netbeans
+nbproject/
+nbactions.xml
+
+# we use maven!
+build.xml
+
+# maven
+target/
+dependency-reduced-pom.xml
+
+# vim
+.*.sw[a-p]
+
+# various other potential build files
+build/
+bin/
+dist/
+manifest.mf
+
+# Mac filesystem dust
+.DS_Store/
+
+# intellij
+*.iml
+*.ipr
+*.iws
+.idea/
+
+out \ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..cc27cd7
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,26 @@
+Copyright (c) 2014, SpigotMC. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer.
+
+Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+
+The name of the author may not be used to endorse or promote products derived
+from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/nb-configuration.xml b/nb-configuration.xml
new file mode 100644
index 0000000..7e46592
--- /dev/null
+++ b/nb-configuration.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project-shared-configuration>
+ <!--
+ This file contains additional configuration written by modules in the NetBeans IDE.
+ The configuration is intended to be shared among all the users of project and
+ therefore it is assumed to be part of version control checkout.
+ Without this configuration present, some functionality in the IDE may be limited or fail altogether.
+ -->
+ <properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">
+ <!--
+ Properties that influence various parts of the IDE, especially code formatting and the like.
+ You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
+ That way multiple projects can share the same settings (useful for formatting rules for example).
+ Any value defined here will override the pom.xml file value but is only applicable to the current project.
+ -->
+ <org-netbeans-modules-editor-indent.CodeStyle.usedProfile>project</org-netbeans-modules-editor-indent.CodeStyle.usedProfile>
+ <org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.classDeclBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.classDeclBracePlacement>
+ <org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.otherBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.otherBracePlacement>
+ <org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.methodDeclBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.methodDeclBracePlacement>
+ <org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinMethodCallParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinMethodCallParens>
+ <org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSwitchParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSwitchParens>
+ <org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinCatchParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinCatchParens>
+ <org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinTryParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinTryParens>
+ <org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSynchronizedParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSynchronizedParens>
+ <org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinArrayInitBrackets>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinArrayInitBrackets>
+ <org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinParens>
+ <org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinWhileParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinWhileParens>
+ <org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinIfParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinIfParens>
+ <org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinForParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinForParens>
+ </properties>
+</project-shared-configuration>
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..ec5e6e0
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,107 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.spigotmc</groupId>
+ <artifactId>builder</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0-SNAPSHOT</version>
+
+ <name>BuildTools</name>
+ <description></description>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.custardsource.dybdob</groupId>
+ <artifactId>java-diff-utils-copy</artifactId>
+ <version>1.0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <version>18.0</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>net.sf.jopt-simple</groupId>
+ <artifactId>jopt-simple</artifactId>
+ <version>4.7</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jgit</groupId>
+ <artifactId>org.eclipse.jgit</artifactId>
+ <version>3.3.2.201404171909-r</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.projectlombok</groupId>
+ <artifactId>lombok</artifactId>
+ <version>1.14.8</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>2.4</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <finalName>${project.name}</finalName>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.1</version>
+ <configuration>
+ <source>1.6</source>
+ <target>1.6</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.5</version>
+ <configuration>
+ <archive>
+ <manifestEntries>
+ <Main-Class>org.spigotmc.builder.Builder</Main-Class>
+ </manifestEntries>
+ </archive>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <version>2.3</version>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <filters>
+ <filter>
+ <artifact>*:*</artifact>
+ <excludes>
+ <exclude>**/*.java</exclude>
+ <exclude>**/*.SF</exclude>
+ <exclude>**/*.DSA</exclude>
+ </excludes>
+ </filter>
+ </filters>
+ <minimizeJar>true</minimizeJar>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/src/main/java/org/spigotmc/builder/Builder.java b/src/main/java/org/spigotmc/builder/Builder.java
new file mode 100644
index 0000000..c8248b4
--- /dev/null
+++ b/src/main/java/org/spigotmc/builder/Builder.java
@@ -0,0 +1,411 @@
+package org.spigotmc.builder;
+
+import com.google.common.base.Charsets;
+import com.google.common.base.Predicate;
+import com.google.common.base.Throwables;
+import com.google.common.collect.Iterables;
+import com.google.common.hash.Hasher;
+import com.google.common.hash.Hashing;
+import com.google.common.io.ByteStreams;
+import com.google.common.io.Files;
+import com.google.common.io.Resources;
+import difflib.DiffUtils;
+import difflib.Patch;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.net.URL;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import lombok.RequiredArgsConstructor;
+import org.apache.commons.io.FileUtils;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.ResetCommand;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.revwalk.RevCommit;
+
+public class Builder
+{
+
+ public static final boolean IS_WINDOWS = System.getProperty( "os.name" ).startsWith( "Windows" );
+ public static final boolean IS_MAC = System.getProperty( "os.name" ).startsWith( "Mac" );
+ public static final File CWD = new File( "." );
+ public static final String MC_VERSION = "1.8";
+
+ public static void main(String[] args) throws Exception
+ {
+ if ( IS_MAC )
+ {
+ System.out.println( "Sorry, but Macintosh is not currently a supported platform for compilation at this time." );
+ System.out.println( "Please run this script on a Windows or Linux PC and then copy the jars to this computer." );
+ return;
+ }
+
+ try
+ {
+ runProcess( "bash -c exit", CWD );
+ } catch ( Exception ex )
+ {
+ System.out.println( "You must run this jar through bash (msysgit)" );
+ return;
+ }
+
+ try
+ {
+ runProcess( "git config --global user.name", CWD );
+ } catch ( Exception ex )
+ {
+ System.out.println( "Git name not set, setting it to default value." );
+ runProcess( "git config --global user.name BuildTools", CWD );
+ }
+ try
+ {
+ runProcess( "git config --global user.email", CWD );
+ } catch ( Exception ex )
+ {
+ System.out.println( "Git email not set, setting it to default value." );
+ runProcess( "git config --global user.email unconfigured@null.spigotmc.org", CWD );
+ }
+
+ File workDir = new File( "work" );
+ workDir.mkdir();
+
+ File bukkit = new File( "Bukkit" );
+ if ( !bukkit.exists() )
+ {
+ clone( "https://hub.spigotmc.org/stash/scm/spigot/bukkit.git", bukkit );
+ }
+
+ File craftBukkit = new File( "CraftBukkit" );
+ if ( !craftBukkit.exists() )
+ {
+ clone( "https://hub.spigotmc.org/stash/scm/spigot/craftbukkit.git", craftBukkit );
+ }
+
+ File spigot = new File( "Spigot" );
+ if ( !spigot.exists() )
+ {
+ clone( "https://hub.spigotmc.org/stash/scm/spigot/spigot.git", spigot );
+ }
+
+ File buildData = new File( "BuildData" );
+ if ( !buildData.exists() )
+ {
+ clone( "https://hub.spigotmc.org/stash/scm/spigot/builddata.git", buildData );
+ }
+
+ File maven = new File( "apache-maven-3.2.3" );
+ if ( !maven.exists() )
+ {
+ System.out.println( "Maven does not exist, downloading. Please wait." );
+
+ File mvnTemp = new File( "mvn.zip" );
+ mvnTemp.deleteOnExit();
+
+ download( "http://static.spigotmc.org/maven/apache-maven-3.2.3-bin.zip", mvnTemp );
+ unzip( mvnTemp, new File( "." ) );
+ }
+
+ String mvnCmd = maven.getAbsolutePath() + "/bin/mvn";
+ if ( IS_WINDOWS )
+ {
+ mvnCmd += ".bat";
+ } else
+ {
+ mvnCmd = "/bin/sh " + mvnCmd;
+ }
+
+ Git bukkitGit = Git.open( bukkit );
+ Git craftBukkitGit = Git.open( craftBukkit );
+ Git spigotGit = Git.open( spigot );
+ Git buildGit = Git.open( buildData );
+
+ pull( bukkitGit );
+ pull( craftBukkitGit );
+ pull( spigotGit );
+ pull( buildGit );
+
+ File vanillaJar = new File( workDir, "minecraft_server." + MC_VERSION + ".jar" );
+ if ( !vanillaJar.exists() )
+ {
+ download( String.format( "https://s3.amazonaws.com/Minecraft.Download/versions/%1$s/minecraft_server.%1$s.jar", MC_VERSION ), vanillaJar );
+ }
+
+ Iterable<RevCommit> mappings = buildGit.log()
+ .addPath( "mappings/bukkit-1.8.at" )
+ .addPath( "mappings/bukkit-1.8-cl.csrg" )
+ .addPath( "mappings/bukkit-1.8-members.csrg" )
+ .addPath( "mappings/package.srg" )
+ .setMaxCount( 1 ).call();
+
+ Hasher mappingsHash = Hashing.md5().newHasher();
+ for ( RevCommit rev : mappings )
+ {
+ mappingsHash.putString( rev.getName(), Charsets.UTF_8 );
+ }
+ String mappingsVersion = mappingsHash.hash().toString().substring( 24 ); // Last 8 chars
+
+ File finalMappedJar = new File( workDir, "mapped." + mappingsVersion + ".jar" );
+ if ( !finalMappedJar.exists() )
+ {
+ System.out.println( "Final mapped jar: " + finalMappedJar + " does not exist, creating!" );
+
+ File clMappedJar = new File( finalMappedJar + "-cl" );
+ File mMappedJar = new File( finalMappedJar + "-m" );
+
+ runProcess( "java -jar BuildData/bin/SpecialSource.jar -i " + vanillaJar + " -m BuildData/mappings/bukkit-1.8-cl.csrg -o " + clMappedJar, CWD );
+ runProcess( "java -jar BuildData/bin/SpecialSource-2.jar map -i " + clMappedJar + " -m " + "BuildData/mappings/bukkit-1.8-members.csrg -o " + mMappedJar, CWD );
+ runProcess( "java -jar BuildData/bin/SpecialSource.jar -i " + mMappedJar + " --access-transformer BuildData/mappings/bukkit-1.8.at "
+ + "-m BuildData/mappings/package.srg -o " + finalMappedJar, CWD );
+ }
+
+ runProcess( mvnCmd + " install:install-file -Dfile=" + finalMappedJar + " -Dpackaging=jar -DgroupId=org.spigotmc -DartifactId=minecraft-server -Dversion=1.8-SNAPSHOT", CWD );
+
+ File decompileDir = new File( workDir, "decompile-" + mappingsVersion );
+ if ( !decompileDir.exists() )
+ {
+ decompileDir.mkdir();
+
+ File clazzDir = new File( decompileDir, "classes" );
+ unzip( finalMappedJar, clazzDir, new Predicate<String>()
+ {
+
+ @Override
+ public boolean apply(String input)
+ {
+ return input.startsWith( "net/minecraft/server" );
+ }
+ } );
+
+ runProcess( "java -jar BuildData/bin/fernflower.jar -dgs=1 -hdc=0 -rbr=0 -asc=1 " + clazzDir + " " + decompileDir, CWD );
+
+ String jacobePath = "BuildData/bin/jacobe";
+ if ( IS_WINDOWS )
+ {
+ jacobePath += ".exe";
+ }
+ runProcess( jacobePath + " -cfg=BuildData/bin/jacobe.cfg -nobackup -overwrite -outext=java " + decompileDir + "/net/minecraft/server", CWD );
+ }
+
+ System.out.println( "Applying CraftBukkit Patches" );
+ File nmsDir = new File( craftBukkit, "src/main/java/net" );
+ if ( nmsDir.exists() )
+ {
+ System.out.println( "Backing up NMS dir" );
+ FileUtils.moveDirectory( nmsDir, new File( workDir, "nms.old." + System.currentTimeMillis() ) );
+ }
+ File patchDir = new File( craftBukkit, "nms-patches" );
+ for ( File file : patchDir.listFiles() )
+ {
+ String targetFile = "net/minecraft/server/" + file.getName().replaceAll( ".patch", ".java" );
+
+ File clean = new File( decompileDir, targetFile );
+ File t = new File( nmsDir.getParentFile(), targetFile );
+ t.getParentFile().mkdirs();
+
+ System.out.println( "Patching with " + file.getName() );
+
+ Patch parsedPatch = DiffUtils.parseUnifiedDiff( Files.readLines( file, Charsets.UTF_8 ) );
+ List<?> modifiedLines = DiffUtils.patch( Files.readLines( clean, Charsets.UTF_8 ), parsedPatch );
+
+ BufferedWriter bw = new BufferedWriter( new FileWriter( t ) );
+ for ( String line : (List<String>) modifiedLines )
+ {
+ bw.write( line );
+ bw.newLine();
+ }
+ bw.close();
+ }
+ File tmpNms = new File( craftBukkit, "tmp-nms" );
+ FileUtils.copyDirectory( nmsDir, tmpNms );
+
+ craftBukkitGit.branchDelete().setBranchNames( "patched" ).setForce( true ).call();
+ craftBukkitGit.checkout().setCreateBranch( true ).setForce( true ).setName( "patched" ).call();
+ craftBukkitGit.add().addFilepattern( "src/main/java/net/" ).call();
+ craftBukkitGit.commit().setMessage( "CraftBukkit $ " + new Date() ).call();
+ craftBukkitGit.checkout().setName( "master" ).call();
+
+ FileUtils.moveDirectory( tmpNms, nmsDir );
+
+ File spigotApi = new File( spigot, "Bukkit" );
+ if ( !spigotApi.exists() )
+ {
+ clone( "file://" + bukkit.getAbsolutePath(), spigotApi );
+ }
+ File spigotServer = new File( spigot, "CraftBukkit" );
+ if ( !spigotServer.exists() )
+ {
+ clone( "file://" + craftBukkit.getAbsolutePath(), spigotServer );
+ }
+
+ // Git spigotApiGit = Git.open( spigotApi );
+ // Git spigotServerGit = Git.open( spigotServer );
+ System.out.println( "Compiling Bukkit" );
+ runProcess( mvnCmd + " clean install", bukkit );
+
+ System.out.println( "Compiling CraftBukkit" );
+ runProcess( mvnCmd + " clean install", craftBukkit );
+
+ try
+ {
+ runProcess( "bash applyPatches.sh", spigot );
+ System.out.println( "*** Spigot patches applied!" );
+ System.out.println( "Compiling Spigot & Spigot-API" );
+ runProcess( mvnCmd + " clean install", spigot );
+ } catch ( Exception ex )
+ {
+ System.err.println( "Error compiling Spigot, are you running this jar via msysgit?" );
+ ex.printStackTrace();
+ }
+ }
+
+ public static void pull(Git repo) throws Exception
+ {
+ System.out.println( "Pulling updates for " + repo.getRepository().getDirectory() );
+
+ repo.reset().setRef( "origin/master" ).setMode( ResetCommand.ResetType.HARD ).call();
+ boolean result = repo.pull().call().isSuccessful();
+
+ if ( !result )
+ {
+ throw new RuntimeException( "Could not pull updates!" );
+ }
+
+ System.out.println( "Successfully pulled updates!" );
+ }
+
+ public static int runProcess(String command, File workDir) throws Exception
+ {
+ final Process ps = new ProcessBuilder( command.split( " " ) ).directory( workDir ).start();
+
+ new Thread( new StreamRedirector( ps.getInputStream(), System.out ) ).start();
+ new Thread( new StreamRedirector( ps.getErrorStream(), System.err ) ).start();
+
+ int status = ps.waitFor();
+
+ if ( status != 0 )
+ {
+ throw new RuntimeException( "Error running command, return status !=0: " + command );
+ }
+
+ return status;
+ }
+
+ @RequiredArgsConstructor
+ private static class StreamRedirector implements Runnable
+ {
+
+ private final InputStream in;
+ private final PrintStream out;
+
+ @Override
+ public void run()
+ {
+ BufferedReader br = new BufferedReader( new InputStreamReader( in ) );
+ try
+ {
+ String line;
+ while ( ( line = br.readLine() ) != null )
+ {
+ out.println( line );
+ }
+ } catch ( IOException ex )
+ {
+ throw Throwables.propagate( ex );
+ }
+ }
+ }
+
+ public static void unzip(File zipFile, File targetFolder) throws IOException
+ {
+ unzip( zipFile, targetFolder, null );
+ }
+
+ public static void unzip(File zipFile, File targetFolder, Predicate<String> filter) throws IOException
+ {
+ targetFolder.mkdir();
+ ZipFile zip = new ZipFile( zipFile );
+
+ for ( Enumeration<? extends ZipEntry> entries = zip.entries(); entries.hasMoreElements(); )
+ {
+ ZipEntry entry = entries.nextElement();
+
+ if ( filter != null )
+ {
+ if ( !filter.apply( entry.getName() ) )
+ {
+ continue;
+ }
+ }
+
+ File outFile = new File( targetFolder, entry.getName() );
+
+ if ( entry.isDirectory() )
+ {
+ outFile.mkdirs();
+ continue;
+ }
+ if ( outFile.getParentFile() != null )
+ {
+ outFile.getParentFile().mkdirs();
+ }
+
+ InputStream is = zip.getInputStream( entry );
+ OutputStream os = new FileOutputStream( outFile );
+ try
+ {
+ ByteStreams.copy( is, os );
+ } finally
+ {
+ is.close();
+ os.close();
+ }
+
+ System.out.println( "Extracted: " + outFile );
+ }
+ }
+
+ public static void clone(String url, File target) throws GitAPIException
+ {
+ System.out.println( "Starting clone of " + url + " to " + target );
+
+ Git result = Git.cloneRepository().setURI( url ).setDirectory( target ).call();
+
+ try
+ {
+ System.out.println( "Cloned git repository " + url + " to " + url + ". Current HEAD: " + commitHash( result ) );
+
+ } finally
+ {
+ result.close();
+ }
+ }
+
+ public static String commitHash(Git repo) throws GitAPIException
+ {
+ return Iterables.getOnlyElement( repo.log().setMaxCount( 1 ).call() ).getName();
+ }
+
+ public static File download(String url, File target) throws IOException
+ {
+ System.out.println( "Starting download of " + url );
+
+ byte[] bytes = Resources.toByteArray( new URL( url ) );
+
+ System.out.println( "Downloaded file: " + target + " with md5: " + Hashing.md5().hashBytes( bytes ).toString() );
+
+ Files.write( bytes, target );
+
+ return target;
+ }
+}