Add support for remote --in-jar URLs

You can now provide an HTTP URL to --in-jar and
it will be downloaded to a temporary file before
remapping. Example:

java -jar target/SpecialSource-1.3-SNAPSHOT-shaded.jar --in-jar http://assets.minecraft.net/1_4_7/minecraft_server.jar --out-jar /tmp/net.jar --srg-in ../MinecraftForge/mcp/conf/
This commit is contained in:
Agaricus 2013-02-27 21:11:47 -08:00
parent 262ec1b82e
commit 1000ba60cf
2 changed files with 110 additions and 6 deletions

View File

@ -29,11 +29,8 @@
package net.md_5.specialsource;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.google.common.base.Joiner;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import joptsimple.OptionException;
@ -83,7 +80,7 @@ public class SpecialSource {
acceptsAll(asList("i", "in-jar"), "Input jar to remap")
.withRequiredArg()
.ofType(File.class);
.ofType(String.class);
acceptsAll(asList("o", "out-jar"), "Output jar to write")
.withRequiredArg()
@ -211,11 +208,12 @@ public class SpecialSource {
return;
}
log("Remapping final jar");
Jar jar3 = Jar.init((File) options.valueOf("in-jar"));
URLDownloader.verbose = !options.has("quiet");
Jar jar3 = Jar.init(URLDownloader.getLocalFile((String) options.valueOf("in-jar")));
inheritanceProviders.add(new JarInheritanceProvider(jar3));
log("Remapping final jar");
JarRemapper jarRemapper = new JarRemapper(jarMapping);
jarRemapper.remapJar(jar3, (File) options.valueOf("out-jar"));
}

View File

@ -0,0 +1,106 @@
/**
* Copyright (c) 2012, md_5. 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.
*/
package net.md_5.specialsource;
import com.google.common.io.Files;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
public class URLDownloader {
private URL url;
public static boolean verbose = true;
public URLDownloader(String urlString) throws MalformedURLException {
this.url = new URL(urlString);
}
public File download() throws IOException {
if (verbose) {
System.out.println("Downloading "+url);
}
url.openConnection();
InputStream inputStream = url.openStream();
String path = url.getPath();
String baseName = URLDownloader.getNameWithoutExtension(path);
String extension = Files.getFileExtension(path);
File tempFile = File.createTempFile(baseName, "." + extension);
FileOutputStream outputStream = new FileOutputStream(tempFile);
byte[] buffer = new byte[4096];
int n = 0;
while ((n = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, n);
}
inputStream.close();
outputStream.close();
if (verbose) {
System.out.println("Downloaded to "+tempFile.getPath());
}
return tempFile;
}
public static File getLocalFile(String string) throws IOException {
if (new File(string).exists()) {
return new File(string);
}
if (string.startsWith("http://") || string.startsWith("https://")) {
URLDownloader downloader = new URLDownloader(string);
return downloader.download();
} else {
throw new FileNotFoundException(string);
}
}
// Borrowed from Guava 13 (since we're on Guava 12) - TODO: remove and use Guava after https://github.com/MinecraftForge/FML/commit/937e9a016936195e4dc51f33ab9e8dde52621684
/**
* Returns the file name without its
* <a href="http://en.wikipedia.org/wiki/Filename_extension">file extension</a> or path. This is
* similar to the {@code basename} unix command. The result does not include the '{@code .}'.
*
* @param file The name of the file to trim the extension from. This can be either a fully
* qualified file name (including a path) or just a file name.
* @return The file name without its path or extension.
* @since 14.0
*/
public static String getNameWithoutExtension(String file) {
String fileName = new File(file).getName();
int dotIndex = fileName.lastIndexOf('.');
return (dotIndex == -1) ? fileName : fileName.substring(0, dotIndex);
}
}