From 2e81b3e74f03f9de03f3b68a37bd82fc3120442d Mon Sep 17 00:00:00 2001 From: Aesen Vismea Date: Mon, 10 Jul 2017 00:11:31 -0400 Subject: [PATCH] Add automatic defaults downloading --- README.md | 5 +- build.gradle | 9 +++ .../java/com/surgeplay/visage/Visage.java | 64 ++++++++++++++++++- .../visage/renderer/RenderConfiguration.java | 24 +++++++ 4 files changed, 98 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e3989c8..ed9c0d9 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,8 @@ headers. You should open the file and tweak the parameters to your particular use-case. You can download a ready-to-run Visage distribution at [the GitHub releases page][2]. -Extract it wherever, `cd` to the directory, and run `./bin/Visage --distributor`. +Extract it wherever, `cd` to the directory, and run +`java -jar Visage--capsule.jar --distributor`. **Windows is unsupported. Use it at your own peril.** Renderers just need to be pointed at your RabbitMQ server, which brings us to... @@ -48,7 +49,7 @@ editing the `conf/renderer.conf` file to point to the RabbitMQ server the sysadmin gives you. You can download a ready-to-run Visage distribution at [the GitHub releases page][2]. -Extract it wherever, `cd` to the directory, and run `./bin/Visage`. +Extract it wherever, `cd` to the directory, and run `java -jar Visage--capsule.jar`. Renderer mode is the default. **Windows is unsupported. Use it at your own peril.** diff --git a/build.gradle b/build.gradle index 4472f6a..37e4e79 100644 --- a/build.gradle +++ b/build.gradle @@ -14,6 +14,11 @@ def dirty = !'git diff-index HEAD'.execute().in.text.trim().isEmpty(); version = '2.0.'+commits+(dirty ? '-dirty' : ''); archivesBaseName = 'Visage' +def commitHash = 'git rev-parse HEAD'.execute().in.text.trim(); +if (commitHash.length() != 40) { + commitHash = 'master'; +} + sourceCompatibility = 1.8 targetCompatibility = 1.8 @@ -71,6 +76,10 @@ tasks.withType(JavaCompile) { task capsule(type: MavenCapsule) { applicationClass 'com.surgeplay.visage.Visage' + capsuleManifest { + systemProperties['com.surgeplay.visage.internal.builtFrom'] = commitHash; + systemProperties['com.surgeplay.visage.internal.version'] = project.version; + } } license { diff --git a/src/main/java/com/surgeplay/visage/Visage.java b/src/main/java/com/surgeplay/visage/Visage.java index 76fee1f..b09dfd6 100644 --- a/src/main/java/com/surgeplay/visage/Visage.java +++ b/src/main/java/com/surgeplay/visage/Visage.java @@ -25,6 +25,10 @@ package com.surgeplay.visage; import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; import java.util.Arrays; import java.util.logging.ConsoleHandler; import java.util.logging.Formatter; @@ -37,13 +41,15 @@ import joptsimple.OptionSet; import joptsimple.OptionSpec; +import com.google.common.io.Files; +import com.google.common.io.Resources; import com.surgeplay.visage.distributor.VisageDistributor; import com.surgeplay.visage.renderer.VisageRenderer; import com.typesafe.config.Config; import com.typesafe.config.ConfigFactory; public class Visage { - public static final String VERSION = "2.0.0"; + public static final String VERSION = System.getProperty("com.surgeplay.visage.internal.version", "2.0.0"); public static final Formatter logFormat = new VisageFormatter(); public static final Logger log = Logger.getLogger("com.surgeplay.visage"); @@ -74,11 +80,59 @@ public static void main(String[] args) throws Exception { } OptionParser parser = new OptionParser(); // master/slave terminology kept for compatibility + OptionSpec help = parser.acceptsAll(Arrays.asList("h", "help", "?"), "Show this help").forHelp(); parser.acceptsAll(Arrays.asList("distributor", "d", "master", "m"), "Start Visage as a distributor"); parser.acceptsAll(Arrays.asList("renderer", "r", "slave", "s"), "Start Visage as a renderer"); + parser.accepts("pollute-my-directory", "Bypass directory checks when downloading defaults"); OptionSpec fileSwitch; - fileSwitch = parser.acceptsAll(Arrays.asList("config", "c"), "Load the given config file instead of the default conf/[mode].conf").withRequiredArg().ofType(File.class); + fileSwitch = parser.acceptsAll(Arrays.asList("config", "c"), "Load the given config file instead of the default conf/[mode].conf, and don't download defaults").withRequiredArg().ofType(File.class); OptionSet set = parser.parse(args); + + if (set.has(help)) { + System.err.println("Visage v"+VERSION); + parser.printHelpOn(System.err); + System.exit(0); + } + + if (!set.has(fileSwitch)) { + File conf = new File("conf"); + if (!conf.isDirectory()) { + ansi = true; + log.info("Looks like you're starting Visage for the first time."); + log.info("We'll download some defaults to get you started."); + File wd = new File("."); + if (wd.list().length > 1) { + if (set.has("pollute-my-directory")) { + log.warning("This directory doesn't seem to be empty, but continuing anyway, as you requested."); + } else { + log.severe("This directory doesn't seem to be empty."); + log.severe("To prevent a frustrating experience akin to a zip bomb, Visage will exit."); + log.severe("If you want to download the defaults into this directory anyway, run Visage again with the option --pollute-my-directory."); + log.severe("Alternatively, specify a config file with --config and Visage will not attempt to download defaults."); + System.exit(4); + return; + } + } else { + log.fine("Directory seems to be empty."); + } + log.info("Creating conf directory"); + conf.mkdirs(); + if (!conf.isDirectory()) throw new FileNotFoundException("Failed to create conf directory"); + File www = new File("www"); + log.info("Creating www directory"); + www.mkdirs(); + if (!www.isDirectory()) throw new FileNotFoundException("Failed to create www directory"); + + String builtFrom = System.getProperty("com.surgeplay.visage.internal.builtFrom", "master"); + log.info("Pulling files from ref "+builtFrom); + + download("conf/renderer.conf", builtFrom); + download("conf/distributor.conf", builtFrom); + + download("www/index.html", builtFrom); + } + } + File confFile = fileSwitch.value(set); if (set.has("distributor")) { if (confFile == null) { @@ -116,4 +170,10 @@ public void run() { } }); } + + private static void download(String path, String commit) throws MalformedURLException, IOException { + log.info("Downloading "+path); + Resources.asByteSource(new URL("https://raw.githubusercontent.com/surgeplay/Visage/"+commit+"/"+path)) + .copyTo(Files.asByteSink(new File(path))); + } } diff --git a/src/main/java/com/surgeplay/visage/renderer/RenderConfiguration.java b/src/main/java/com/surgeplay/visage/renderer/RenderConfiguration.java index f9f9465..371f9e3 100644 --- a/src/main/java/com/surgeplay/visage/renderer/RenderConfiguration.java +++ b/src/main/java/com/surgeplay/visage/renderer/RenderConfiguration.java @@ -1,3 +1,27 @@ +/* + * The MIT License + * + * Copyright (c) 2015-2017, William Thompson (unascribed) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + package com.surgeplay.visage.renderer; import com.surgeplay.visage.RenderMode;