Skip to content

Commit

Permalink
Added compression back
Browse files Browse the repository at this point in the history
  • Loading branch information
juanmuscaria committed Aug 26, 2024
1 parent e395d75 commit 14437af
Show file tree
Hide file tree
Showing 9 changed files with 441 additions and 3 deletions.
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform

plugins {
id 'application'
//id 'org.jetbrains.gradle.upx' version '1.6.0-RC.5'
id 'de.undercouch.download' version '5.4.0'
id 'com.github.johnrengelman.shadow' version '8.1.1'
id 'io.micronaut.application' version '4.2.1'
id 'com.juanmuscaria.tooling.dmm' /* because sometimes we need to make our own tools */
id 'de.undercouch.download' /* version set in the plugin above */
}

ext.gitInfoCached = null
Expand Down
31 changes: 31 additions & 0 deletions buildSrc/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
plugins {
id 'groovy-gradle-plugin'
}

repositories {
gradlePluginPortal()
mavenCentral()
}

configurations {
compileOnly {
extendsFrom annotationProcessor
}
}

dependencies {
annotationProcessor("org.projectlombok:lombok:1.18.28")
implementation("de.undercouch:gradle-download-task:5.6.0")
implementation("org.tukaani:xz:1.9")
implementation("commons-io:commons-io:2.16.1")
}


gradlePlugin {
plugins {
toolingPlugin {
id = "com.juanmuscaria.tooling.dmm"
implementationClass = "com.juanmuscaria.tooling.dmm.DmmPlugin"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package com.juanmuscaria.tooling.dmm

import com.juanmuscaria.tooling.dmm.file.XZArchiver
import com.juanmuscaria.tooling.dmm.task.UpxTask
import de.undercouch.gradle.tasks.download.Download
import org.gradle.api.Named
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.file.RelativePath
import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider
import org.gradle.api.resources.ReadableResource
import org.gradle.api.tasks.Sync
import org.gradle.internal.os.OperatingSystem

import java.nio.file.Path

class DmmPlugin implements Plugin<Project> {
static class Extension implements Named {
Property<String> version
Property<Path> localUpxPath
Provider<Path> upxExecutableProvider

Extension(Property<String> version, Property<Path> localUpxPath, Provider<Path> upxExecutableProvider) {
this.version = version
this.localUpxPath = localUpxPath
this.upxExecutableProvider = upxExecutableProvider
}

@Override
String getName() {
return "dmm"
}
}

@Override
void apply(Project target) {
target.with {
plugins.withId("de.undercouch.download") {
var os = OperatingSystem.current()
var version = objects.property(String).convention("4.0.2")
var localUpxPath = objects.property(Path)

var downloadUpx = tasks.register("downloadUpx", Download) {
group = "upx"
var platform = UpxSupportedOperatingSystems.current()
src("https://github.com/upx/upx/releases/download/v${version.get()}/upx-${version.get()}-${platform.fileSuffix}.${platform.extension}")
dest(layout.buildDirectory.file("upx/downloads/${os.isWindows() ? "upx.zip" : "upx.tar.xz"}"))
overwrite(false)
}

var unzipUpx = tasks.register("unzipUpx", Sync) {
group = "upx"
from(downloadUpx.map {
os.isWindows() ? zipTree(it.dest) : tarTree(XZArchiver.xz(resources, it.dest) as ReadableResource)
})
eachFile {
relativePath(new RelativePath(true, name))
}
into(layout.buildDirectory.dir("upx/exec"))
}

var upxExecutable = localUpxPath.orElse(unzipUpx.map { it.destinationDir.toPath().resolve("upx${os.isWindows() ? ".exe" : ""}") })

var extension = extensions.create("upx", Extension, version, localUpxPath, upxExecutable)
var compress = tasks.register("compress") {
group = "upx"
}

plugins.withId("org.graalvm.buildtools.native") {
tasks.getByName("nativeCompile") { nativeBuild ->
var compressTask = tasks.register("compress${nativeBuild.name.capitalize()}", UpxTask) {
it.dependsOn(nativeBuild)
it.inputExecutable.set(nativeBuild.outputDirectory.flatMap { it.file(nativeBuild.executableName) })
it.upxExecutableFile.set(upxExecutable.get())
}

compress.configure {
it.dependsOn(compressTask)
}
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.juanmuscaria.tooling.dmm;

import java.lang.invoke.MethodHandles;
import java.lang.reflect.Field;

public class UnsafeJvm {
public static final MethodHandles.Lookup theLookup;

static {
try {
var unsafeClass = Class.forName("sun.misc.Unsafe");
Object unsafe = null;
for (Field field : unsafeClass.getDeclaredFields()) {
if (field.getType().equals(unsafeClass)) {
field.setAccessible(true);
unsafe = field.get(null);
}
}
MethodHandles.lookup();
var lookupField = MethodHandles.Lookup.class.getDeclaredField("IMPL_LOOKUP");
var lookupFieldOffset = (long) unsafeClass.getDeclaredMethod("staticFieldOffset", Field.class)
.invoke(unsafe, lookupField);

theLookup = (MethodHandles.Lookup) unsafeClass.getDeclaredMethod("getObject", Object.class, long.class)
.invoke(unsafe, MethodHandles.Lookup.class, lookupFieldOffset);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.juanmuscaria.tooling.dmm


import org.gradle.internal.os.OperatingSystem
import org.jetbrains.annotations.NotNull

enum UpxSupportedOperatingSystems {
WINDOWS_x86("win32", "zip"),
WINDOWS_x64("win64", "zip"),
LINUX_x64("amd64_linux", "tar.xz"),
LINUX_ARM64("arm64_linux", "tar.xz"),
LINUX_ARM("amd_linux", "tar.xz"),
LINUX_x86("i386_linux", "tar.xz");

@NotNull
private final String fileSuffix
@NotNull
private final String extension

private UpxSupportedOperatingSystems(String fileSuffix, String extension) {
this.fileSuffix = fileSuffix
this.extension = extension
}

@NotNull
final String getFileSuffix() {
return this.fileSuffix
}

@NotNull
final String getExtension() {
return this.extension
}

@NotNull
static UpxSupportedOperatingSystems current() {
var os = OperatingSystem.current()
var arch = System.getProperty("os.arch", "")
boolean is64 = arch.contains("64")
if (os.isWindows()) {
return is64 ? WINDOWS_x64 : WINDOWS_x86
} else if (os.isLinux()) {
var isArm = arch.contains("arm") || arch.contains("aarch")
return is64 && isArm ? LINUX_ARM64 : (!is64 && isArm ? LINUX_ARM : (is64 ? LINUX_x64 : LINUX_x86))
} else {
throw new UnsupportedOperationException("Current OS '$os' is not supported.")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright 2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.juanmuscaria.tooling.dmm.file;

import org.gradle.api.internal.file.archive.compression.CompressedReadableResource;
import org.gradle.api.internal.file.archive.compression.URIBuilder;
import org.gradle.api.resources.internal.ReadableResourceInternal;
import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.io.InputStream;
import java.net.URI;

public abstract class AbstractArchiver implements CompressedReadableResource {
protected final ReadableResourceInternal resource;
protected final URI uri;

public AbstractArchiver(ReadableResourceInternal resource) {
assert resource != null;
this.uri = new URIBuilder(resource.getURI()).schemePrefix(getSchemePrefix()).build();
this.resource = resource;
}

abstract protected String getSchemePrefix();

@Override
public abstract @NotNull InputStream read();

@Override
public @NotNull String getDisplayName() {
return resource.getDisplayName();
}

@Override
public @NotNull URI getURI() {
return uri;
}

@Override
public @NotNull String getBaseName() {
return resource.getBaseName();
}

@Override
public File getBackingFile() {
return resource.getBackingFile();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.juanmuscaria.tooling.dmm.file

import com.juanmuscaria.tooling.dmm.UnsafeJvm
import org.gradle.api.internal.resources.DefaultResourceHandler
import org.gradle.api.internal.resources.ResourceResolver
import org.gradle.api.resources.MissingResourceException
import org.gradle.api.resources.ResourceException
import org.gradle.api.resources.ResourceHandler
import org.gradle.api.resources.internal.ReadableResourceInternal
import org.jetbrains.annotations.NotNull
import org.tukaani.xz.SeekableFileInputStream
import org.tukaani.xz.SeekableXZInputStream

import java.lang.invoke.MethodHandle

class XZArchiver extends AbstractArchiver {
static MethodHandle resourceResolver = UnsafeJvm.theLookup
.unreflectGetter(DefaultResourceHandler.class.getDeclaredField("resourceResolver"))

static ReadableResourceInternal xz(ResourceHandler handle, Object path) {
var resolver = resourceResolver.invokeWithArguments(handle) as ResourceResolver
return new XZArchiver(resolver.resolveResource(path))
}

XZArchiver(ReadableResourceInternal resource) {
super(resource)
}

@Override
protected String getSchemePrefix() {
return "xz:"
}

@NotNull
@Override
InputStream read() throws MissingResourceException, ResourceException {
return new SeekableXZInputStream(new SeekableFileInputStream(resource.backingFile))
}
}
Loading

0 comments on commit 14437af

Please sign in to comment.