Skip to content

Commit

Permalink
Merge branch 'release/1.1.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
overheadhunter committed Apr 27, 2022
2 parents a4908c6 + 878bccb commit a21e678
Show file tree
Hide file tree
Showing 28 changed files with 991 additions and 45 deletions.
12 changes: 4 additions & 8 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,11 @@ jobs:
if: "!contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.head_commit.message, '[skip ci]')"
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
- uses: actions/setup-java@v2
with:
java-version: 11
- uses: actions/cache@v2
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-
distribution: 'temurin'
java-version: 17
cache: 'maven'
- name: Ensure to use tagged version
if: startsWith(github.ref, 'refs/tags/')
run: mvn versions:set --file ./pom.xml -DnewVersion=${GITHUB_REF##*/}
Expand Down
12 changes: 4 additions & 8 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,11 @@ jobs:
- uses: actions/checkout@v2
with:
fetch-depth: 2
- uses: actions/setup-java@v1
- uses: actions/setup-java@v2
with:
java-version: 11
- uses: actions/cache@v2
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-
distribution: 'temurin'
java-version: 17
cache: 'maven'
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
Expand Down
17 changes: 9 additions & 8 deletions .github/workflows/publish-central.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,26 @@ jobs:
- uses: actions/checkout@v2
with:
ref: "refs/tags/${{ github.event.inputs.tag }}"
- uses: actions/setup-java@v1
- uses: actions/setup-java@v2
with:
java-version: 11
distribution: 'temurin'
java-version: 17
cache: 'maven'
server-id: ossrh # Value of the distributionManagement/repository/id field of the pom.xml
server-username: MAVEN_USERNAME # env variable for username in deploy
server-password: MAVEN_PASSWORD # env variable for token in deploy
gpg-private-key: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }} # Value of the GPG private key to import
gpg-passphrase: MAVEN_GPG_PASSPHRASE # env variable for GPG private key passphrase
- uses: actions/cache@v2
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-
- name: Enforce project version ${{ github.event.inputs.tag }}
run: mvn versions:set -B -DnewVersion=${{ github.event.inputs.tag }}
- name: Deploy
run: mvn deploy -B -DskipTests -Psign,deploy-central --no-transfer-progress
env:
MAVEN_OPTS: >
--add-opens=java.base/java.util=ALL-UNNAMED
--add-opens=java.base/java.lang.reflect=ALL-UNNAMED
--add-opens=java.base/java.text=ALL-UNNAMED
--add-opens=java.desktop/java.awt.font=ALL-UNNAMED
MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }}
MAVEN_PASSWORD: ${{ secrets.OSSRH_PASSWORD }}
MAVEN_GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }}
12 changes: 4 additions & 8 deletions .github/workflows/publish-github.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,13 @@ jobs:
if: startsWith(github.ref, 'refs/tags/') # only allow publishing tagged versions
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v1
- uses: actions/setup-java@v2
with:
java-version: 11
distribution: 'temurin'
java-version: 17
cache: 'maven'
gpg-private-key: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }} # Value of the GPG private key to import
gpg-passphrase: MAVEN_GPG_PASSPHRASE # env variable for GPG private key passphrase
- uses: actions/cache@v2
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-
- name: Enforce project version ${{ github.event.release.tag_name }}
run: mvn versions:set -B -DnewVersion=${{ github.event.release.tag_name }}
- name: Deploy
Expand Down
1 change: 1 addition & 0 deletions .idea/codeStyles/Project.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

47 changes: 40 additions & 7 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.cryptomator</groupId>
<artifactId>integrations-api</artifactId>
<version>1.0.0</version>
<version>1.1.0</version>

<name>Cryptomator Integrations API</name>
<description>Defines optional service interfaces that may be used by Cryptomator</description>
Expand Down Expand Up @@ -37,14 +37,47 @@
</license>
</licenses>

<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.36</version>
</dependency>

<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>23.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.36</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>4.3.1</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<version>3.9.0</version>
<configuration>
<release>11</release>
<release>17</release>
</configuration>
</plugin>
<plugin>
Expand Down Expand Up @@ -72,7 +105,7 @@
</executions>
<configuration>
<quiet>true</quiet>
<release>11</release>
<release>17</release>
<tags>
<!-- workaround for "unknown tag: implNote", see https://blog.codefx.org/java/new-javadoc-tags/#Maven -->
<tag>
Expand Down Expand Up @@ -110,7 +143,7 @@
<plugins>
<plugin>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.6</version>
<version>3.0.1</version>
<executions>
<execution>
<id>sign-artifacts</id>
Expand All @@ -137,7 +170,7 @@
<repository>
<id>ossrh</id>
<name>Maven Central</name>
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
<url>https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
</distributionManagement>
<build>
Expand All @@ -149,7 +182,7 @@
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
<nexusUrl>https://s01.oss.sonatype.org/</nexusUrl>
<autoReleaseAfterClose>true</autoReleaseAfterClose>
</configuration>
</plugin>
Expand Down
17 changes: 17 additions & 0 deletions src/main/java/module-info.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,23 @@
import org.cryptomator.integrations.tray.TrayMenuController;
import org.cryptomator.integrations.autostart.AutoStartProvider;
import org.cryptomator.integrations.keychain.KeychainAccessProvider;
import org.cryptomator.integrations.tray.TrayIntegrationProvider;
import org.cryptomator.integrations.uiappearance.UiAppearanceProvider;


module org.cryptomator.integrations.api {
requires static org.jetbrains.annotations;
requires org.slf4j;

exports org.cryptomator.integrations.autostart;
exports org.cryptomator.integrations.common;
exports org.cryptomator.integrations.keychain;
exports org.cryptomator.integrations.tray;
exports org.cryptomator.integrations.uiappearance;

uses AutoStartProvider;
uses KeychainAccessProvider;
uses TrayIntegrationProvider;
uses TrayMenuController;
uses UiAppearanceProvider;
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,26 @@
package org.cryptomator.integrations.autostart;

import org.cryptomator.integrations.common.IntegrationsLoader;
import org.jetbrains.annotations.Blocking;

import java.util.Optional;

public interface AutoStartProvider {

/**
* Loads the best-suited AutoStartProvider.
*
* @return preferred AutoStartProvider (if any)
* @since 1.1.0
*/
static Optional<AutoStartProvider> get() {
return IntegrationsLoader.load(AutoStartProvider.class);
}

@Blocking
void enable() throws ToggleAutoStartFailedException;

@Blocking
void disable() throws ToggleAutoStartFailedException;

boolean isEnabled();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.cryptomator.integrations.common;

import org.jetbrains.annotations.ApiStatus;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Identifies 0..n public methods to check preconditions for the integration to work. These are the rules:
*
* <ul>
* <li>Both the type and the method(s) must be annotated with {@code @CheckAvailability}</li>
* <li>Only public no-arg boolean methods are considered</li>
* <li>Methods <em>may</em> be {@code static}, in which case they get invoked before instantiating the service</li>
* <li>Should the method throw an exception, it has the same effect as returning {@code false}</li>
* <li>No specific execution order is guaranteed in case of multiple annotated methods</li>
* <li>Annotations must be present on classes or ancestor classes, not on interfaces</li>
* </ul>
*
* Example:
* <pre>
* {@code
* @CheckAvailability
* public class Foo {
* @CheckAvailability
* public static boolean isSupported() {
* return "enabled".equals(System.getProperty("plugin.status"));
* }
* }
* }
* </pre>
* <p>
* Annotations are discovered at runtime using reflection, so make sure to make relevant classes accessible to this
* module ({@code opens X to org.cryptomator.integrations.api}).
*
* @since 1.1.0
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Inherited
@ApiStatus.Experimental
public @interface CheckAvailability {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package org.cryptomator.integrations.common;

import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.VisibleForTesting;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.stream.Collectors;

class ClassLoaderFactory {

private static final Logger LOG = LoggerFactory.getLogger(ClassLoaderFactory.class);
private static final String USER_HOME = System.getProperty("user.home");
private static final String PLUGIN_DIR_KEY = "cryptomator.pluginDir";
private static final String JAR_SUFFIX = ".jar";

/**
* Attempts to find {@code .jar} files in the path specified in {@value #PLUGIN_DIR_KEY} system property.
* A new class loader instance is returned that loads classes from the given classes.
*
* @return A new URLClassLoader that is aware of all {@code .jar} files in the plugin dir
*/
@Contract(value = "-> new", pure = true)
public static URLClassLoader forPluginDir() {
String val = System.getProperty(PLUGIN_DIR_KEY, "");
final Path p;
if (val.startsWith("~/")) {
p = Path.of(USER_HOME).resolve(val.substring(2));
} else {
p = Path.of(val);
}
return forPluginDirWithPath(p);
}

@VisibleForTesting
@Contract(value = "_ -> new", pure = true)
static URLClassLoader forPluginDirWithPath(Path path) throws UncheckedIOException {
var jars = findJars(path);
if (LOG.isDebugEnabled()) {
String jarList = Arrays.stream(jars).map(URL::getPath).collect(Collectors.joining(", "));
LOG.debug("Found jars in cryptomator.pluginDir: {}", jarList);
}
return URLClassLoader.newInstance(jars);
}

@VisibleForTesting
static URL[] findJars(Path path) {
try (var stream = Files.walk(path)) {
return stream.filter(ClassLoaderFactory::isJarFile).map(ClassLoaderFactory::toUrl).toArray(URL[]::new);
} catch (IOException | UncheckedIOException e) {
// unable to locate any jars // TODO: log a warning?
return new URL[0];
}
}

private static URL toUrl(Path path) throws UncheckedIOException {
try {
return path.toUri().toURL();
} catch (MalformedURLException e) {
throw new UncheckedIOException(e);
}
}

private static boolean isJarFile(Path path) {
return Files.isRegularFile(path) && path.getFileName().toString().toLowerCase().endsWith(JAR_SUFFIX);
}

}
Loading

0 comments on commit a21e678

Please sign in to comment.