update tor resource library and switch to resource-filterjar plugin

This commit is contained in:
Craig Raw
2025-05-14 11:38:17 +02:00
parent b1ab157ee3
commit af4c68a09c
8 changed files with 4 additions and 286 deletions

View File

@@ -3,7 +3,7 @@ plugins {
id 'org-openjfx-javafxplugin'
id 'org.beryx.jlink' version '3.1.1'
id 'org.gradlex.extra-java-module-info' version '1.9'
id 'com.sparrowwallet.filterjar'
id 'io.matthewnelson.kmp.tor.resource-filterjar' version '408.16.2'
}
def sparrowVersion = '2.1.4'
@@ -77,7 +77,7 @@ dependencies {
implementation('co.nstant.in:cbor:0.9')
implementation('org.openpnp:openpnp-capture-java:0.0.28-5')
implementation("io.matthewnelson.kmp-tor:runtime:2.2.1")
implementation("io.matthewnelson.kmp-tor:resource-exec-tor-gpl:408.16.0")
implementation("io.matthewnelson.kmp-tor:resource-exec-tor-gpl:408.16.2")
implementation('org.jetbrains.kotlinx:kotlinx-coroutines-javafx:1.10.1') {
exclude group: 'org.jetbrains.kotlin', module: 'kotlin-stdlib-common'
}
@@ -460,10 +460,6 @@ extraJavaModuleInfo {
}
}
String torOs = os.macOsX ? "macos" : (os.windows ? "mingw" : "linux-libc")
filterInfo {
filter('io.matthewnelson.kmp-tor', 'resource-lib-tor-gpl-jvm') {
include("io/matthewnelson/kmp/tor/resource/lib/tor/native/${torOs}/${releaseArch}")
exclude('io/matthewnelson/kmp/tor/resource/lib/tor/native/')
}
kmpTorResourceFilterJar {
keepTorCompilation("current","current")
}

View File

@@ -20,9 +20,5 @@ gradlePlugin {
id = "org-openjfx-javafxplugin"
implementationClass = "org.openjfx.gradle.JavaFXPlugin"
}
register("com.sparrowwallet.filterjar") {
id = "com.sparrowwallet.filterjar"
implementationClass = "com.sparrowwallet.filterjar.FilterJarPlugin"
}
}
}

View File

@@ -1,69 +0,0 @@
package com.sparrowwallet.filterjar;
import org.gradle.api.Action;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.ConfigurationContainer;
import org.gradle.api.attributes.Attribute;
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.provider.MapProperty;
import org.gradle.api.tasks.SourceSet;
import javax.inject.Inject;
public abstract class FilterJarExtension {
static Attribute<Boolean> FILTERED_ATTRIBUTE = Attribute.of("filtered", Boolean.class);
public abstract MapProperty<String, JarFilterConfigImpl> getFilterConfigs();
@Inject
protected abstract ObjectFactory getObjects();
@Inject
protected abstract ConfigurationContainer getConfigurations();
public void filter(String group, String artifact, Action<? super JarFilterConfigImpl> action) {
String name = group + ":" + artifact;
JarFilterConfigImpl config = new JarFilterConfigImpl(name, getObjects());
config.setGroup(group);
config.setArtifact(artifact);
action.execute(config);
getFilterConfigs().put(name, config);
}
/**
* Activate the plugin's functionality for dependencies of all scopes of the given source set
* (runtimeClasspath, compileClasspath, annotationProcessor).
* Note that the plugin activates the functionality for all source sets by default.
* Therefore, this method only has an effect for source sets for which a {@link #deactivate(Configuration)}
* has been performed.
*
* @param sourceSet the Source Set to activate (e.g. sourceSets.test)
*/
public void activate(SourceSet sourceSet) {
Configuration runtimeClasspath = getConfigurations().getByName(sourceSet.getRuntimeClasspathConfigurationName());
Configuration compileClasspath = getConfigurations().getByName(sourceSet.getCompileClasspathConfigurationName());
Configuration annotationProcessor = getConfigurations().getByName(sourceSet.getAnnotationProcessorConfigurationName());
activate(runtimeClasspath);
activate(compileClasspath);
activate(annotationProcessor);
}
/**
* Activate the plugin's functionality for a single resolvable Configuration.
*
* @param resolvable a resolvable Configuration (e.g. configurations["customClasspath"])
*/
public void activate(Configuration resolvable) {
resolvable.getAttributes().attribute(FILTERED_ATTRIBUTE, true);
}
/**
* Deactivate the plugin's functionality for a single resolvable Configuration.
*
* @param resolvable a resolvable Configuration (e.g. configurations.annotationProcessor)
*/
public void deactivate(Configuration resolvable) {
resolvable.getAttributes().attribute(FILTERED_ATTRIBUTE, false);
}
}

View File

@@ -1,10 +0,0 @@
package com.sparrowwallet.filterjar;
import org.gradle.api.artifacts.transform.TransformParameters;
import org.gradle.api.provider.MapProperty;
import org.gradle.api.tasks.Input;
public interface FilterJarParameters extends TransformParameters {
@Input
MapProperty<String, JarFilterConfig> getFilterConfigs();
}

View File

@@ -1,33 +0,0 @@
package com.sparrowwallet.filterjar;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.tasks.SourceSetContainer;
import static com.sparrowwallet.filterjar.FilterJarExtension.FILTERED_ATTRIBUTE;
public class FilterJarPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
// Register the extension
FilterJarExtension extension = project.getExtensions().create("filterInfo", FilterJarExtension.class);
project.getPlugins().withType(JavaPlugin.class).configureEach(_ -> {
// By default, activate plugin for all source sets
project.getExtensions().getByType(SourceSetContainer.class).all(extension::activate);
// All jars have a filtered=false attribute by default
project.getDependencies().getArtifactTypes().maybeCreate("jar").getAttributes().attribute(FILTERED_ATTRIBUTE, false);
// Register the transform
project.getDependencies().registerTransform(FilterJarTransform.class, transform -> {
transform.getFrom().attribute(FILTERED_ATTRIBUTE, false);
transform.getTo().attribute(FILTERED_ATTRIBUTE, true);
transform.parameters(params -> {
params.getFilterConfigs().putAll(extension.getFilterConfigs());
});
});
});
}
}

View File

@@ -1,79 +0,0 @@
package com.sparrowwallet.filterjar;
import org.gradle.api.artifacts.transform.InputArtifact;
import org.gradle.api.artifacts.transform.TransformAction;
import org.gradle.api.artifacts.transform.TransformOutputs;
import org.gradle.api.file.FileSystemLocation;
import org.gradle.api.provider.Provider;
import org.gradle.api.tasks.PathSensitive;
import org.gradle.api.tasks.PathSensitivity;
import java.io.File;
import java.util.Map;
import java.util.Set;
import java.util.HashSet;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import java.nio.file.Files;
public abstract class FilterJarTransform implements TransformAction<FilterJarParameters> {
@InputArtifact
@PathSensitive(PathSensitivity.NAME_ONLY)
public abstract Provider<FileSystemLocation> getInputArtifact();
@Override
public void transform(TransformOutputs outputs) {
File originalJar = getInputArtifact().get().getAsFile();
String jarName = originalJar.getName();
// Get filter configurations from parameters
Map<String, JarFilterConfig> filterConfigs = getParameters().getFilterConfigs().get();
//Inclusions are prioritised ahead of exclusions
Set<String> inclusions = new HashSet<>();
Set<String> exclusions = new HashSet<>();
// Check if this JAR matches any configured filters (simplified matching based on artifact name)
filterConfigs.forEach((key, config) -> {
if(jarName.contains(config.getArtifact())) {
inclusions.addAll(config.getInclusions());
exclusions.addAll(config.getExclusions());
}
});
try {
if(!exclusions.isEmpty()) {
filterJar(originalJar, getFilterJar(outputs, originalJar), inclusions, exclusions);
} else {
outputs.file(originalJar);
}
} catch(Exception e) {
throw new RuntimeException("Failed to transform jar: " + jarName, e);
}
}
private void filterJar(File inputFile, File outputFile, Set<String> inclusions, Set<String> exclusions) throws Exception {
try(JarFile jarFile = new JarFile(inputFile); JarOutputStream jarOut = new JarOutputStream(Files.newOutputStream(outputFile.toPath()))) {
jarFile.entries().asIterator().forEachRemaining(entry -> {
String entryName = entry.getName();
boolean shouldInclude = inclusions.stream().anyMatch(entryName::startsWith);
boolean shouldExclude = exclusions.stream().anyMatch(entryName::startsWith);
if(shouldInclude || !shouldExclude) {
try {
jarOut.putNextEntry(new JarEntry(entryName));
jarFile.getInputStream(entry).transferTo(jarOut);
jarOut.closeEntry();
} catch(Exception e) {
throw new RuntimeException("Error processing entry: " + entryName, e);
}
}
});
}
}
private File getFilterJar(TransformOutputs outputs, File originalJar) {
return outputs.file(originalJar.getName().substring(0, originalJar.getName().lastIndexOf('.')) + "-filtered.jar");
}
}

View File

@@ -1,19 +0,0 @@
package com.sparrowwallet.filterjar;
import org.gradle.api.tasks.Input;
import java.util.List;
public interface JarFilterConfig {
@Input
String getGroup();
@Input
String getArtifact();
@Input
List<String> getInclusions();
@Input
List<String> getExclusions();
}

View File

@@ -1,64 +0,0 @@
package com.sparrowwallet.filterjar;
import org.gradle.api.Named;
import org.gradle.api.model.ObjectFactory;
import javax.inject.Inject;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class JarFilterConfigImpl implements Named, JarFilterConfig, Serializable {
private final String name;
private String group;
private String artifact;
private final List<String> inclusions;
private final List<String> exclusions;
@Inject
public JarFilterConfigImpl(String name, ObjectFactory objectFactory) {
this.name = name;
this.inclusions = new ArrayList<>();
this.exclusions = new ArrayList<>();
}
@Override
public String getName() {
return name;
}
@Override
public String getGroup() {
return group;
}
public void setGroup(String group) {
this.group = group;
}
@Override
public String getArtifact() {
return artifact;
}
public void setArtifact(String artifact) {
this.artifact = artifact;
}
@Override
public List<String> getInclusions() {
return inclusions;
}
public void include(String path) {
inclusions.add(path);
}
@Override
public List<String> getExclusions() {
return exclusions;
}
public void exclude(String path) {
exclusions.add(path);
}
}