diff --git a/core/src/it/java/com/threerings/getdown/tests/DigesterIT.java b/core/src/it/java/com/threerings/getdown/tests/DigesterIT.java index 52b4b5e..d2ddaf2 100644 --- a/core/src/it/java/com/threerings/getdown/tests/DigesterIT.java +++ b/core/src/it/java/com/threerings/getdown/tests/DigesterIT.java @@ -5,16 +5,16 @@ package com.threerings.getdown.tests; -import java.io.File; import java.nio.charset.StandardCharsets; -import java.nio.file.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Arrays; import java.util.List; -import org.junit.*; -import static org.junit.Assert.*; - import com.threerings.getdown.tools.Digester; +import org.junit.Test; +import static org.junit.Assert.assertEquals; public class DigesterIT { @@ -32,23 +32,23 @@ public class DigesterIT { Files.delete(digest2); assertEquals(Arrays.asList( - "getdown.txt = 779c74fb4b251e18faf6e240a0667964", + "getdown.txt = 9c9b2494929c99d44ae51034d59e1a1b", "testapp.jar = 404dafa55e78b25ec0e3a936357b1883", "funny%test dir/some=file.txt = d8e8fca2dc0f896fd7cb4cb0031ba249", "crazyhashfile#txt = f29d23fd5ab1781bd8d0760b3a516f16", "foo.jar = 46ca4cc9079d9d019bb30cd21ebbc1ec", "script.sh = f66e8ea25598e67e99c47d9b0b2a2cdf", - "digest.txt = f5561d85e4d80cc85883963897e58ff6" + "digest.txt = 11f9ba349cf9edacac4d72a3158447e5" ), digestLines); assertEquals(Arrays.asList( - "getdown.txt = 4f0c657895c3c3a35fa55bf5951c64fa9b0694f8fc685af3f1d8635c639e066b", + "getdown.txt = 1efecfae2a189002a6658f17d162b1922c7bde978944949276dc038a0df2461f", "testapp.jar = c9cb1906afbf48f8654b416c3f831046bd3752a76137e5bf0a9af2f790bf48e0", "funny%test dir/some=file.txt = f2ca1bb6c7e907d06dafe4687e579fce76b37e4e93b7605022da52e6ccc26fd2", "crazyhashfile#txt = 6816889f922de38f145db215a28ad7c5e1badf7354b5cdab225a27486789fa3b", "foo.jar = ea188b872e0496debcbe00aaadccccb12a8aa9b025bb62c130cd3d9b8540b062", "script.sh = cca1c5c7628d9bf7533f655a9cfa6573d64afb8375f81960d1d832dc5135c988", - "digest2.txt = 70b442c9f56660561921da3368e1a206f05c379182fab3062750b7ddcf303407" + "digest2.txt = 41eacdabda8909bdbbf61e4f980867f4003c16a12f6770e6fc619b6af100e05b" ), digest2Lines); } } diff --git a/core/src/it/resources/testapp/getdown.txt b/core/src/it/resources/testapp/getdown.txt index 3e0e538..ab0e473 100644 --- a/core/src/it/resources/testapp/getdown.txt +++ b/core/src/it/resources/testapp/getdown.txt @@ -13,6 +13,18 @@ apparg = %APPDIR% # test the %env% mechanism jvmarg = -Dusername=\%ENV.USER% +# test various java_*** configs, they are not interesting for digester +java_local_dir = jre +java_max_version = 1089999 +java_min_version = [windows] 1080111 +java_min_version = [!windows] 1080192 +java_exact_version_required = [linux] true +java_location = [linux-amd64] /files/java/java_linux_64.zip +java_location = [linux-i386] /files/java/java_linux_32.zip +java_location = [mac] /files/java/java_mac_64.zip +java_location = [windows-amd64] /files/java/java_windows_64.zip +java_location = [windows-x86] /files/java/java_windows_32.zip + strict_comments = true resource = funny%test dir/some=file.txt resource = crazyhashfile#txt diff --git a/core/src/main/java/com/threerings/getdown/data/Application.java b/core/src/main/java/com/threerings/getdown/data/Application.java index 1412d8a..e4d0987 100644 --- a/core/src/main/java/com/threerings/getdown/data/Application.java +++ b/core/src/main/java/com/threerings/getdown/data/Application.java @@ -547,6 +547,36 @@ public class Application public Config init (boolean checkPlatform) throws IOException { + Config config = initConfig(checkPlatform); + initConfigJava(config); + initConfigTracking(config); + initConfigResources(config); + initConfigArgs(config); + + // determine whether we want to allow offline operation (defaults to false) + _allowOffline = config.getBoolean("allow_offline"); + + // look for a debug.txt file which causes us to run in java.exe on Windows so that we can + // obtain a thread dump of the running JVM + _windebug = getLocalPath("debug.txt").exists(); + + // whether to cache code resources and launch from cache + _useCodeCache = config.getBoolean("use_code_cache"); + _codeCacheRetentionDays = config.getInt("code_cache_retention_days", 7); + + // maximum simultaneous downloads + _maxConcDownloads = Math.max(1, config.getInt("max_concurrent_downloads", + SysProps.threadPoolSize())); + + // extract some info used to configure our child process on macOS + _dockName = config.getString("ui.name"); + _dockIconPath = config.getString("ui.mac_dock_icon", "../desktop.icns"); + + _verifyTimeout = config.getInt("verify_timeout", 60); + return config; + } + + public Config initConfig (boolean checkPlatform) throws IOException { Config config = null; File cfgfile = _config; Config.ParseOpts opts = Config.createOpts(checkPlatform); @@ -591,7 +621,7 @@ public class Application // make sure there's a trailing slash if (!_appbase.endsWith("/")) { - _appbase = _appbase + "/"; + _appbase += "/"; } // extract our version information @@ -602,17 +632,15 @@ public class Application _vappbase = createVAppBase(_version); } catch (MalformedURLException mue) { String err = MessageUtil.tcompose("m.invalid_appbase", _appbase); - throw (IOException) new IOException(err).initCause(mue); + throw new IOException(err, mue); } // check for a latest config URL String latest = config.getString("latest"); if (latest != null) { - if (latest.startsWith(_appbase)) { - latest = _appbase + latest.substring(_appbase.length()); - } else { - latest = SysProps.replaceDomain(latest); - } + latest = latest.startsWith(_appbase) + ? _appbase + latest.substring(_appbase.length()) + : SysProps.replaceDomain(latest); try { _latest = HostWhitelist.verify(new URL(latest)); } catch (MalformedURLException mue) { @@ -620,20 +648,12 @@ public class Application } } - String appPrefix = _envc.appId == null ? "" : (_envc.appId + "."); - - // determine our application class name (use app-specific class _if_ one is provided) - _class = config.getString("class"); - if (appPrefix.length() > 0) { - _class = config.getString(appPrefix + "class", _class); - } - if (_class == null) { - throw new IOException("m.missing_class"); - } - // determine whether we want strict comments _strictComments = config.getBoolean("strict_comments"); + return config; + } + public void initConfigJava (Config config) { // check to see if we're using a custom java.version property and regex _javaVersionProp = config.getString("java_version_prop", _javaVersionProp); _javaVersionRegex = config.getString("java_version_regex", _javaVersionRegex); @@ -651,14 +671,13 @@ public class Application // this is a little weird, but when we're run from the digester, we see a String[] which // contains java locations for all platforms which we can't grok, but the digester doesn't // need to know about that; when we're run in a real application there will be only one! - Object javaloc = config.getRaw("java_location"); - if (javaloc instanceof String) { - _javaLocation = (String)javaloc; - } + _javaLocation = config.getString("java_location"); // used only in conjunction with java_location _javaLocalDir = getLocalPath(config.getString("java_local_dir", LaunchUtil.LOCAL_JAVA_DIR)); + } + public void initConfigTracking (Config config) { // determine whether we have any tracking configuration _trackingURL = config.getString("tracking_url"); @@ -683,7 +702,9 @@ public class Application // Some app may need to generate google analytics code _trackingGAHash = config.getString("tracking_ga_hash"); + } + public void initConfigResources (Config config) throws IOException { // clear our arrays as we may be reinitializing _codes.clear(); _resources.clear(); @@ -709,10 +730,10 @@ public class Application // parse our auxiliary resource groups for (String auxgroup : config.getList("auxgroups")) { - ArrayList codes = new ArrayList<>(); + List codes = new ArrayList<>(); parseResources(config, auxgroup + ".code", Resource.NORMAL, codes); parseResources(config, auxgroup + ".ucode", Resource.UNPACK, codes); - ArrayList rsrcs = new ArrayList<>(); + List rsrcs = new ArrayList<>(); parseResources(config, auxgroup + ".resource", Resource.NORMAL, rsrcs); parseResources(config, auxgroup + ".xresource", Resource.EXEC, rsrcs); parseResources(config, auxgroup + ".uresource", Resource.UNPACK, rsrcs); @@ -720,6 +741,19 @@ public class Application parseResources(config, auxgroup + ".nresource", Resource.NATIVE, rsrcs); _auxgroups.put(auxgroup, new AuxGroup(auxgroup, codes, rsrcs)); } + } + + private void initConfigArgs (Config config) throws IOException { + String appPrefix = _envc.appId == null ? "" : (_envc.appId + "."); + + // determine our application class name (use app-specific class _if_ one is provided) + _class = config.getString("class"); + if (appPrefix.length() > 0) { + _class = config.getString(appPrefix + "class", _class); + } + if (_class == null) { + throw new IOException("m.missing_class"); + } // transfer our JVM arguments (we include both "global" args and app_id-prefixed args) String[] jvmargs = config.getMultiValue("jvmarg"); @@ -741,28 +775,6 @@ public class Application // look for custom arguments fillAssignmentListFromPairs("extra.txt", _txtJvmArgs); - - // determine whether we want to allow offline operation (defaults to false) - _allowOffline = config.getBoolean("allow_offline"); - - // look for a debug.txt file which causes us to run in java.exe on Windows so that we can - // obtain a thread dump of the running JVM - _windebug = getLocalPath("debug.txt").exists(); - - // whether to cache code resources and launch from cache - _useCodeCache = config.getBoolean("use_code_cache"); - _codeCacheRetentionDays = config.getInt("code_cache_retention_days", 7); - - // maximum simultaneous downloads - _maxConcDownloads = Math.max(1, config.getInt("max_concurrent_downloads", - SysProps.threadPoolSize())); - - // extract some info used to configure our child process on macOS - _dockName = config.getString("ui.name"); - _dockIconPath = config.getString("ui.mac_dock_icon", "../desktop.icns"); - - _verifyTimeout = config.getInt("verify_timeout", 60); - return config; } /** diff --git a/core/src/main/java/com/threerings/getdown/tools/Digester.java b/core/src/main/java/com/threerings/getdown/tools/Digester.java index b04a653..8e97f80 100644 --- a/core/src/main/java/com/threerings/getdown/tools/Digester.java +++ b/core/src/main/java/com/threerings/getdown/tools/Digester.java @@ -23,6 +23,7 @@ import com.threerings.getdown.data.Digest; import com.threerings.getdown.data.EnvConfig; import com.threerings.getdown.data.Resource; import com.threerings.getdown.util.Base64; +import com.threerings.getdown.util.Config; import static java.nio.charset.StandardCharsets.UTF_8; @@ -75,7 +76,8 @@ public class Digester // create our application and instruct it to parse its business Application app = new Application(new EnvConfig(appdir)); - app.init(false); + Config config = app.initConfig(false); + app.initConfigResources(config); List rsrcs = new ArrayList<>(); rsrcs.add(app.getConfigResource()); @@ -86,6 +88,9 @@ public class Digester rsrcs.addAll(ag.rsrcs); } + // reinit app just to verify that getdown.txt has valid format + app.init(true); + // now generate the digest file Digest.createDigest(version, rsrcs, target); }