diff --git a/.gitignore b/.gitignore index a3ac56a..ccabaea 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ release/deployment-dev/* release/deployment-pub/ release/Scelight/ build-release.xml +*.snap # Ignore IntelliJ files: # https://intellij-support.jetbrains.com/hc/en-us/articles/206544839-How-to-manage-projects-under-Version-Control-Systems diff --git a/.idea/compiler.xml b/.idea/compiler.xml index e576cd0..9f609d0 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -10,6 +10,8 @@ + + diff --git a/.idea/modules.xml b/.idea/modules.xml index ab78fef..af2a9b5 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -2,7 +2,7 @@ - + diff --git a/build.gradle b/build.gradle index eb650b7..db2bfb9 100644 --- a/build.gradle +++ b/build.gradle @@ -54,12 +54,4 @@ distributions { } } -task copyIcon(type: Copy) { - from './src-launcher/hu/sllauncher/r/icon/my/app-icon-1.png' - into './snap/icon' - rename { String filename -> 'scelight.png' } -} - -buildDir = new File(rootProject.projectDir, "snap/build") mainClassName = 'hu.sllauncher.ScelightLauncher' -assemble.dependsOn copyIcon diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..2e20e0c --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'scelight' diff --git a/snap/.gitignore b/snap/.gitignore deleted file mode 100644 index e9c68d6..0000000 --- a/snap/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -*.snap -.gradle -.snapcraft -build -stage -parts -prime -icon diff --git a/snap/Dockerfile b/snap/Dockerfile deleted file mode 100644 index 6db61ef..0000000 --- a/snap/Dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -FROM ubuntu:18.04 - -# Update and install common dependencies. -RUN apt-get update -y -RUN apt-get upgrade -y -RUN apt-get install -y build-essential curl gosu sudo ruby snapcraft -RUN echo "%sudo ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/snapbuild - -# Set up the entry point script -COPY docker-entrypoint.sh /usr/local/bin/entrypoint.sh - -ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] - -CMD ["bash"] - diff --git a/snap/docker-entrypoint.sh b/snap/docker-entrypoint.sh deleted file mode 100755 index 0f7905e..0000000 --- a/snap/docker-entrypoint.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -# Add local user -# Either use the LOCAL_USER_ID if passed in at runtime or fallback - -USER_ID=${LOCAL_USER_ID:-9001} -GROUP_ID=${LOCAL_GROUP_ID:-$USER_ID} - - -echo "Starting with UID : $USER_ID, GID: $GROUP_ID" -groupadd -g ${GROUP_ID} snapbuild -useradd --shell /bin/bash -u ${USER_ID} -g snapbuild -G sudo -o -c "" -m snapbuild -export HOME=/home/snapbuild -chown -R snapbuild /home/snapbuild/work -chown snapbuild:snapbuild /home/snapbuild - -exec gosu snapbuild "$@" diff --git a/snap/plugins/gradle_application.py b/snap/plugins/gradle_application.py new file mode 100644 index 0000000..454e4b9 --- /dev/null +++ b/snap/plugins/gradle_application.py @@ -0,0 +1,230 @@ +# This module is adapted from Canonical's gradle Snapcraft plugin: +# https://github.com/snapcore/snapcraft/blob/master/snapcraft/plugins/gradle.py +# +# Canonical's gradle plugin only produces a .jar or .war file. +# This plugin is for producing a gradle java application distribution. + +import logging +import os +import tarfile +import urllib.parse +from glob import glob +from typing import Sequence + +import snapcraft +from snapcraft import file_utils, formatting_utils +from snapcraft.internal import errors, sources + +logger = logging.getLogger(__name__) + +_DEFAULT_GRADLE_VERSION = "4.10.2" +_DEFAULT_GRADLE_CHECKSUM = ( + "sha256/b49c6da1b2cb67a0caf6c7480630b51c70a11ca2016ff2f555eaeda863143a29" +) +_GRADLE_URL = "https://services.gradle.org/distributions/gradle-{version}-bin.zip" + + +class UnsupportedJDKVersionError(errors.SnapcraftError): + fmt = ( + "The gradle-openjdk-version plugin property was set to {version!r}.\n" + "Valid values for the {base!r} base are: {valid_versions}." + ) + + def __init__( + self, *, base: str, version: str, valid_versions: Sequence[str] + ) -> None: + super().__init__( + base=base, + version=version, + valid_versions=formatting_utils.humanize_list( + valid_versions, conjunction="or" + ), + ) + + +class GradlePlugin(snapcraft.BasePlugin): + @classmethod + def schema(cls): + schema = super().schema() + schema["properties"]["gradle-options"] = { + "type": "array", + "minitems": 1, + "uniqueItems": True, + "items": {"type": "string"}, + "default": [], + } + schema["properties"]["gradle-output-dir"] = { + "type": "string", + "default": "build/distributions", + } + + schema["properties"]["gradle-version"] = {"type": "string"} + + schema["properties"]["gradle-version-checksum"] = {"type": "string"} + + schema["properties"]["gradle-openjdk-version"] = { + "type": "string", + "default": "", + } + + schema["required"] = ["source"] + + return schema + + @classmethod + def get_pull_properties(cls): + # Inform Snapcraft of the properties associated with pulling. If these + # change in the YAML Snapcraft will consider the pull step dirty. + return ["gradle-version", "gradle-version-checksum", "gradle-openjdk-version"] + + @classmethod + def get_build_properties(cls): + # Inform Snapcraft of the properties associated with building. If these + # change in the YAML Snapcraft will consider the build step dirty. + return super().get_build_properties() + ["gradle-options", "gradle-output-dir"] + + @property + def _gradle_tar(self): + if self._gradle_tar_handle is None: + gradle_uri = _GRADLE_URL.format(version=self._gradle_version) + self._gradle_tar_handle = sources.Zip( + gradle_uri, self._gradle_dir, source_checksum=self._gradle_checksum + ) + return self._gradle_tar_handle + + def __init__(self, name, options, project): + super().__init__(name, options, project) + + self._setup_gradle() + self._setup_base_tools(project.info.base) + + def _get_openjdk_version(self, base): + if base not in ("core16", "core18"): + raise errors.PluginBaseError( + part_name=self.name, base=self.project.info.base + ) + + if base == "core16": + valid_versions = ["8", "9"] + elif base == "core18": + valid_versions = ["8", "11"] + + version = self.options.gradle_openjdk_version + if version and version not in valid_versions: + raise UnsupportedJDKVersionError( + version=version, base=base, valid_versions=valid_versions + ) + elif not version: + # Get the latest version from the slice + version = valid_versions[-1] + + return version + + def _setup_base_tools(self, base): + version = self._get_openjdk_version(base) + self.stage_packages.append("openjdk-{}-jre-headless".format(version)) + self.build_packages.append("openjdk-{}-jdk-headless".format(version)) + self.build_packages.append("ca-certificates-java") + + def _using_gradlew(self) -> bool: + return os.path.isfile(os.path.join(self.sourcedir, "gradlew")) + + def _setup_gradle(self): + self._gradle_tar_handle = None + self._gradle_dir = os.path.join(self.partdir, "gradle") + if self.options.gradle_version: + self._gradle_version = self.options.gradle_version + self._gradle_checksum = self.options.gradle_version_checksum + else: + self._gradle_version = _DEFAULT_GRADLE_VERSION + self._gradle_checksum = _DEFAULT_GRADLE_CHECKSUM + + def pull(self): + super().pull() + + if self._using_gradlew(): + logger.info("Found gradlew, skipping gradle setup.") + return + + os.makedirs(self._gradle_dir, exist_ok=True) + self._gradle_tar.download() + + def build(self): + super().build() + + if self._using_gradlew(): + gradle_cmd = ["./gradlew"] + else: + self._gradle_tar.provision(self._gradle_dir, keep_zip=True) + gradle_cmd = ["gradle"] + self.run( + gradle_cmd + + self._get_proxy_options() + + self.options.gradle_options + + ["build"], + rootdir=self.builddir, + ) + + src = os.path.join(self.builddir, self.options.gradle_output_dir) + tarFiles = glob(os.path.join(src, "*.tar")) + + if len(tarFiles) >= 1: + tarFile = tarFiles[0] + else: + raise RuntimeError("Could not find any built tar or zip files for part") + + tarFile = tarFiles[0] + tar = tarfile.open(tarFile) + distribution_dir = os.path.join(self.builddir, "distribution") + tar.extractall(path=distribution_dir) + tar.close() + + file_utils.link_or_copy_tree( + os.path.join(distribution_dir, self.project.info.name), + os.path.join(self.installdir + "/"), + ) + + def run(self, cmd, rootdir): + super().run(cmd, cwd=rootdir, env=self._build_environment()) + + def _build_environment(self): + if self._using_gradlew(): + return + + env = os.environ.copy() + gradle_bin = os.path.join( + self._gradle_dir, "gradle-{}".format(self._gradle_version), "bin" + ) + print("gradle_bin") + print(gradle_bin) + + if env.get("PATH"): + new_path = "{}:{}".format(gradle_bin, env.get("PATH")) + else: + new_path = gradle_bin + + env["PATH"] = new_path + return env + + def _get_proxy_options(self): + proxy_options = [] + for var in ("http", "https"): + proxy = os.environ.get("{}_proxy".format(var), False) + if proxy: + parsed_url = urllib.parse.urlparse(proxy) + proxy_options.append( + "-D{}.proxyHost={}".format(var, parsed_url.hostname) + ) + if parsed_url.port: + proxy_options.append( + "-D{}.proxyPort={}".format(var, parsed_url.port) + ) + if parsed_url.username: + proxy_options.append( + "-D{}.proxyUser={}".format(var, parsed_url.username) + ) + if parsed_url.password: + proxy_options.append( + "-D{}.proxyPassword={}".format(var, parsed_url.password) + ) + return proxy_options diff --git a/snap/run-docker.sh b/snap/run-docker.sh deleted file mode 100755 index 1f12cb1..0000000 --- a/snap/run-docker.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -docker run \ - --interactive \ - --tty \ - -e LOCAL_USER_ID=$(id -u $USER) \ - -e LOCAL_GROUP_ID=$(id -g $USER) \ - -v $PWD:/home/snapbuild/work \ - -w=/home/snapbuild/work \ - snapbuild bash \ - --rm \ - diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 1415a00..715adb6 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -7,17 +7,22 @@ description: | a developer, team manager, league organizer, commentator or just a game analyzer). Its main features are replay management and replay analysis. +architectures: + - build-on: amd64 + run-on: amd64 + - build-on: i386 + run-on: i386 base: core18 -grade: devel # must be 'stable' to release into candidate/stable channels +grade: stable # must be 'stable' to release into candidate/stable channels confinement: strict # use 'strict' once you have the right plugs and slots -icon: ./icon/scelight.png +icon: ./src-launcher/hu/sllauncher/r/icon/my/app-icon-1.png apps: scelight: command: sh $SNAP/bin/scelight desktop: usr/share/applications/scelight.desktop environment: - JAVA_HOME: $SNAP/usr/lib/jvm/java-11-openjdk-amd64 + JAVA_HOME: $SNAP/usr/lib/jvm/java-11-openjdk-$SNAP_ARCH plugs: - desktop - home @@ -27,14 +32,17 @@ apps: parts: scelight: - plugin: dump - source: build/distributions/scelight.tar - build-packages: - - ca-certificates-java - stage-packages: - - ca-certificates-java - - openjdk-11-jre - - fontconfig + plugin: gradle-application + source: . +# scelight: +# plugin: dump +# source: build/distributions/scelight.tar +# build-packages: +# - ca-certificates-java +# stage-packages: +# - ca-certificates-java +# - openjdk-11-jre +# - fontconfig # Useful commands for snapping: # gradle build && ( rm -rf ~/test/scelight tar; tar -x -f snap/build/distributions/scelight.tar -C ~/test/ )