diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7701fb74..8ad3d426 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,20 +21,11 @@ jobs: - name: Install Rust uses: dtolnay/rust-toolchain@stable - with: - toolchain: nightly # nightly is required for fmt - components: rustfmt, clippy - - - name: Check - run: cargo check - - name: Format - run: | - cargo fmt --all -- --check - cargo clippy --workspace --bins -- -D warnings - - - name: Build Debug - run: cargo build --verbose + - name: Set up Cargo Cache + uses: Swatinem/rust-cache@v2 + with: + save-if: false - name: Run tests run: cargo test --verbose @@ -54,6 +45,15 @@ jobs: - name: Set up Gradle uses: gradle/actions/setup-gradle@v3 + - name: Set up Android SDK + uses: android-actions/setup-android@v3 + + - name: Set up Android NDK + uses: nttld/setup-ndk@v1 + with: + link-to-sdk: true + ndk-version: r28-beta1 + - name: Java tests run: gradle test working-directory: ./java @@ -68,12 +68,17 @@ jobs: - name: Install Rust uses: dtolnay/rust-toolchain@stable - - name: Build Release - run: cargo build --verbose --release + - name: Set up Cargo Cache + uses: Swatinem/rust-cache@v2 + with: + save-if: false - name: Run tests run: cargo test --workspace --verbose + - name: Build Release + run: cargo build --verbose --release + - name: Run `ark-cli watch` test run: ./integration/ark-cli-watch.sh @@ -86,6 +91,15 @@ jobs: - name: Set up Gradle uses: gradle/actions/setup-gradle@v3 + - name: Set up Android SDK + uses: android-actions/setup-android@v3 + + - name: Set up Android NDK + uses: nttld/setup-ndk@v1 + with: + link-to-sdk: true + ndk-version: r28-beta1 + - name: Java tests run: gradle test working-directory: ./java @@ -100,12 +114,17 @@ jobs: - name: Install Rust uses: dtolnay/rust-toolchain@stable - - name: Build Release - run: cargo build --verbose --release + - name: Set up Cargo Cache + uses: Swatinem/rust-cache@v2 + with: + save-if: false - name: Run tests run: cargo test --workspace --verbose + - name: Build Release + run: cargo build --verbose --release + - name: Run `ark-cli watch` test run: ./integration/ark-cli-watch.sh @@ -118,6 +137,15 @@ jobs: - name: Set up Gradle uses: gradle/actions/setup-gradle@v3 + - name: Set up Android SDK + uses: android-actions/setup-android@v3 + + - name: Set up Android NDK + uses: nttld/setup-ndk@v1 + with: + link-to-sdk: true + ndk-version: r28-beta1 + - name: Java tests run: gradle test working-directory: ./java diff --git a/.github/workflows/cache.yml b/.github/workflows/cache.yml new file mode 100644 index 00000000..c30d5675 --- /dev/null +++ b/.github/workflows/cache.yml @@ -0,0 +1,82 @@ +name: Cache build + +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + linux: + name: Linux + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + + - name: Set up Cargo Cache + uses: Swatinem/rust-cache@v2 + with: + save-if: true + + - name: Run tests + run: cargo test --workspace --verbose --release + + windows: + name: Windows + runs-on: windows-latest + + steps: + - uses: actions/checkout@v4 + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + + - name: Set up Cargo Cache + uses: Swatinem/rust-cache@v2 + with: + save-if: true + + - name: Run tests + run: cargo test --workspace --verbose --release + + mac-intel: + name: MacOS Intel + runs-on: macos-14 + + steps: + - uses: actions/checkout@v4 + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + + - name: Set up Cargo Cache + uses: Swatinem/rust-cache@v2 + with: + save-if: true + + - name: Run tests + run: cargo test --workspace --verbose --release + + mac-arm: + name: MacOS ARM + runs-on: macos-13-xlarge + + steps: + - uses: actions/checkout@v4 + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + + - name: Set up Cargo Cache + uses: Swatinem/rust-cache@v2 + with: + save-if: true + + - name: Run tests + run: cargo test --workspace --verbose --release diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..0ebcb24e --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,57 @@ +name: Release + +on: + push: + tags: + - "*" + +jobs: + release: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - uses: actions/checkout@v4 + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + with: + targets: aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android + + - name: Set up Cargo Cache + uses: Swatinem/rust-cache@v2 + with: + save-if: false + + - name: Run tests + run: cargo test --workspace --verbose + + - name: Install JDK + uses: actions/setup-java@v4.2.1 + with: + distribution: "temurin" + java-version: "22" + + - name: Set up Gradle + uses: gradle/actions/setup-gradle@v3 + + - name: Set up Android SDK + uses: android-actions/setup-android@v3 + + - name: Set up Android NDK + uses: nttld/setup-ndk@v1 + with: + link-to-sdk: true + ndk-version: r28-beta1 + + - name: Java tests + run: gradle test + working-directory: ./java + + - name: Publish Java release + run: gradle publish + working-directory: ./java + env: + RELEASE_VERSION: ${{ github.ref_name }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/weekly.yml b/.github/workflows/weekly.yml index 572b131d..308ea6fa 100644 --- a/.github/workflows/weekly.yml +++ b/.github/workflows/weekly.yml @@ -19,6 +19,11 @@ jobs: - name: Install Rust uses: dtolnay/rust-toolchain@stable + - name: Set up Cargo Cache + uses: Swatinem/rust-cache@v2 + with: + save-if: true + - name: Run tests run: cargo test --workspace --verbose --release @@ -32,6 +37,11 @@ jobs: - name: Install Rust uses: dtolnay/rust-toolchain@stable + - name: Set up Cargo Cache + uses: Swatinem/rust-cache@v2 + with: + save-if: true + - name: Run tests run: cargo test --workspace --verbose --release @@ -45,6 +55,11 @@ jobs: - name: Install Rust uses: dtolnay/rust-toolchain@stable + - name: Set up Cargo Cache + uses: Swatinem/rust-cache@v2 + with: + save-if: true + - name: Run tests run: cargo test --workspace --verbose --release @@ -58,5 +73,10 @@ jobs: - name: Install Rust uses: dtolnay/rust-toolchain@stable + - name: Set up Cargo Cache + uses: Swatinem/rust-cache@v2 + with: + save-if: true + - name: Run tests run: cargo test --workspace --verbose --release diff --git a/ark-cli/README.md b/ark-cli/README.md index 033aac80..58932874 100644 --- a/ark-cli/README.md +++ b/ark-cli/README.md @@ -1,32 +1,5 @@ # Ark-CLI -### Installation - -To compile you will need openssl libraries and headers: - -```shell -# macOS (Homebrew) -$ brew install openssl@3 - -# macOS (MacPorts) -$ sudo port install openssl - -# macOS (pkgsrc) -$ sudo pkgin install openssl - -# Arch Linux -$ sudo pacman -S pkg-config openssl - -# Debian and Ubuntu -$ sudo apt-get install pkg-config libssl-dev - -# Fedora -$ sudo dnf install pkg-config perl-FindBin openssl-devel - -# Alpine Linux -$ apk add pkgconfig openssl-dev -``` - ### Usage ```shell diff --git a/data-error/Cargo.toml b/data-error/Cargo.toml index 63ac295d..5ad9127d 100644 --- a/data-error/Cargo.toml +++ b/data-error/Cargo.toml @@ -10,7 +10,7 @@ bench = false [dependencies] thiserror = "1" -reqwest = "0.11.11" +reqwest = { version = "0.11.11", features = [ "json", "rustls-tls" ], default-features = false } serde_json = "1.0.82" anyhow = "1" url = { version = "2.2.2", features = ["serde"] } diff --git a/data-link/Cargo.toml b/data-link/Cargo.toml index 6821ceda..4cae70ce 100644 --- a/data-link/Cargo.toml +++ b/data-link/Cargo.toml @@ -13,7 +13,7 @@ log = { version = "0.4.17", features = ["release_max_level_off"] } serde_json = "1.0.82" serde = { version = "1.0.138", features = ["derive"] } url = { version = "2.2.2", features = ["serde"] } -reqwest = "0.11.11" +reqwest = { version = "0.11.11", features = [ "json", "rustls-tls" ], default-features = false } scraper = "0.13.0" tokio = { version = "1", features = ["full"] } diff --git a/java/.gitignore b/java/.gitignore index f6d64d1f..730cf68f 100644 --- a/java/.gitignore +++ b/java/.gitignore @@ -1,6 +1,7 @@ # Ignore Gradle project-specific cache directory .gradle +.local.properties # Ignore Gradle build output directory build -*.log \ No newline at end of file +*.log diff --git a/java/build.gradle b/java/build.gradle new file mode 100644 index 00000000..448748b2 --- /dev/null +++ b/java/build.gradle @@ -0,0 +1,20 @@ +buildscript { + repositories { + google() + gradlePluginPortal() + maven { url "https://plugins.gradle.org/m2/" } + } + dependencies { + classpath libs.gradle + classpath libs.rust.android + } +} + +allprojects { + repositories { + google() + gradlePluginPortal() + maven { url "https://jitpack.io" } + maven { url "https://plugins.gradle.org/m2/" } + } +} diff --git a/java/gradle/libs.versions.toml b/java/gradle/libs.versions.toml index 8f20ed0b..d41e224a 100644 --- a/java/gradle/libs.versions.toml +++ b/java/gradle/libs.versions.toml @@ -1,12 +1,10 @@ -# This file was generated by the Gradle 'init' task. -# https://docs.gradle.org/current/userguide/platforms.html#sub::toml-dependencies-format - [versions] -commons-math3 = "3.6.1" -guava = "33.0.0-jre" -junit-jupiter = "5.10.2" +gradle = "8.7.3" +rustAndroid = "0.9.4" +junitJupiterApi = "5.11.3" [libraries] -commons-math3 = { module = "org.apache.commons:commons-math3", version.ref = "commons-math3" } -guava = { module = "com.google.guava:guava", version.ref = "guava" } -junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit-jupiter" } +gradle = { module = "com.android.tools.build:gradle", version.ref = "gradle" } +rust-android = { module = "org.mozilla.rust-android-gradle:plugin", version.ref = "rustAndroid" } +junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junitJupiterApi" } +junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junitJupiterApi" } diff --git a/java/gradle/wrapper/gradle-wrapper.properties b/java/gradle/wrapper/gradle-wrapper.properties index a4413138..adddce53 100644 --- a/java/gradle/wrapper/gradle-wrapper.properties +++ b/java/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ +#Tue Dec 10 11:20:11 BRT 2024 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/java/lib/build.gradle b/java/lib/build.gradle new file mode 100644 index 00000000..2753e99b --- /dev/null +++ b/java/lib/build.gradle @@ -0,0 +1,85 @@ +apply plugin: 'maven-publish' +apply plugin: 'com.android.library' +apply plugin: 'org.mozilla.rust-android-gradle.rust-android' + +android { + ndkVersion '28.0.12433566' + namespace 'dev.arkbuilders.core' + defaultConfig { + compileSdk 35 + minSdkVersion 26 + targetSdkVersion 35 + } + publishing { + singleVariant('release') { + withSourcesJar() + } + singleVariant('debug') { + withSourcesJar() + } + } +} + +cargo { + libname = 'fs_storage' + module = '../../fs-storage' + prebuiltToolchains = true + targetDirectory = '../../target' + targets = ['arm64', 'x86', 'x86_64', 'arm'] + profile = gradle.startParameter.taskNames.any { it.containsIgnoreCase('debug') } ? 'debug' : 'release' +} + +dependencies { + testImplementation(libs.junit.jupiter.api) + testImplementation(libs.junit.jupiter.engine) +} + +tasks.register('buildRustDebug', Exec) { + workingDir '../../fs-storage' + commandLine 'cargo', 'build' +} + +tasks.register('buildRustRelease', Exec) { + workingDir '../../fs-storage' + commandLine 'cargo', 'build', '--release' +} + +tasks.withType(Test).configureEach { it -> + useJUnitPlatform() + if (it.name.containsIgnoreCase('debug')) { + it.dependsOn 'buildRustDebug' + systemProperty('java.library.path', projectDir.toPath().resolve('../../target/debug').toString()) + } else if (it.name.containsIgnoreCase('release')) { + it.dependsOn 'buildRustRelease' + systemProperty('java.library.path', projectDir.toPath().resolve('../../target/release').toString()) + } +} + +tasks.configureEach { task -> + if (task.name == 'mergeDebugJniLibFolders' || task.name == 'mergeReleaseJniLibFolders') { + task.dependsOn 'cargoBuild' + } +} + +publishing { + publications { + release(MavenPublication) { + artifactId = 'core' + groupId = 'dev.arkbuilders' + version = System.getenv('RELEASE_VERSION') + afterEvaluate { + from components.release + } + } + } + repositories { + maven { + name = 'GithubPackages' + url = uri('https://maven.pkg.github.com/ARK-Builders/ark-core') + credentials { + username = System.getenv('GITHUB_ACTOR') + password = System.getenv('GITHUB_TOKEN') + } + } + } +} diff --git a/java/lib/build.gradle.kts b/java/lib/build.gradle.kts deleted file mode 100644 index 96541a60..00000000 --- a/java/lib/build.gradle.kts +++ /dev/null @@ -1,42 +0,0 @@ -plugins { - // Apply the java-library plugin for API and implementation separation. - `java-library` -} - -repositories { - // Use Maven Central for resolving dependencies. - mavenCentral() -} - -dependencies { - // Use JUnit Jupiter for testing. - testImplementation(libs.junit.jupiter) - - testRuntimeOnly("org.junit.platform:junit-platform-launcher") - - // This dependency is exported to consumers, that is to say found on their compile classpath. - api(libs.commons.math3) - - // This dependency is used internally, and not exposed to consumers on their own compile classpath. - implementation(libs.guava) -} - -// Apply a specific Java toolchain to ease working on different environments. -java { - toolchain { - languageVersion = JavaLanguageVersion.of(21) - } -} - -tasks.named("test") { - // Use JUnit Platform for unit tests. - useJUnitPlatform() - // Set the JVM argument for the java.library.path (To import rust compiled library) - val rustLibPath = projectDir.resolve("../../target/release").absolutePath - jvmArgs = listOf("-Djava.library.path=$rustLibPath") -} - -tasks.named("javadoc") { - options.encoding = "UTF-8" - options.memberLevel = JavadocMemberLevel.PUBLIC -} diff --git a/java/lib/src/test/java/dev/arkbuilders/core/FileStorageTest.java b/java/lib/src/test/java/dev/arkbuilders/core/FileStorageTest.java index 7b9cc284..bf386d11 100644 --- a/java/lib/src/test/java/dev/arkbuilders/core/FileStorageTest.java +++ b/java/lib/src/test/java/dev/arkbuilders/core/FileStorageTest.java @@ -1,5 +1,10 @@ package dev.arkbuilders.core; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; @@ -7,13 +12,9 @@ import java.nio.file.Path; import java.util.LinkedHashMap; import java.util.Map; - -import static org.junit.jupiter.api.Assertions.*; -import static org.junit.jupiter.api.Assertions.assertThrows; +import java.util.Objects; public class FileStorageTest { - FileStorage fileStorage = new FileStorage("test", "test.txt"); - @TempDir Path tempDir; @@ -129,7 +130,7 @@ public void testFileStorageGet() { } @Test - public void testBTreeMapIterator(){ + public void testBTreeMapIterator() { Path storagePath = tempDir.resolve("test.txt"); FileStorage fileStorage = new FileStorage("test", storagePath.toString()); @@ -144,7 +145,7 @@ public void testBTreeMapIterator(){ BTreeMapIterator bTreeMapIterator = fileStorage.iterator(); Map iteratorData = new LinkedHashMap<>(); - while(bTreeMapIterator.hasNext()){ + while (bTreeMapIterator.hasNext()) { Map.Entry entry = bTreeMapIterator.next(); iteratorData.put(entry.getKey(), entry.getValue()); } @@ -156,37 +157,37 @@ public void testRemoveException() { Path storagePath = tempDir.resolve("test.txt"); FileStorage fileStorage = new FileStorage("test", storagePath.toString()); Exception exception = assertThrows(RuntimeException.class, () -> fileStorage.remove("invalid_id")); - assertTrue(exception.getMessage().matches("Storage error.*")); + assertTrue(Objects.requireNonNull(exception.getMessage()).matches("Storage error.*")); } @Test public void testSyncException() { Path storagePath = tempDir.resolve("test.txt"); FileStorage fileStorage = new FileStorage("test", storagePath.toString()); - Exception exception = assertThrows(RuntimeException.class, () -> fileStorage.sync()); - assertTrue(exception.getMessage().matches("IO error.*")); + Exception exception = assertThrows(RuntimeException.class, fileStorage::sync); + assertTrue(Objects.requireNonNull(exception.getMessage()).matches("IO error.*")); } @Test public void testCreateException() { Path storagePath = tempDir.resolve(""); Exception exception = assertThrows(RuntimeException.class, () -> new FileStorage("", storagePath.toString())); - assertTrue(exception.getMessage().matches("IO error.*")); + assertTrue(Objects.requireNonNull(exception.getMessage()).matches("IO error.*")); } @Test public void testEraseException() { Path storagePath = tempDir.resolve("test.txt"); FileStorage fileStorage = new FileStorage("test", storagePath.toString()); - Exception exception = assertThrows(RuntimeException.class, () -> fileStorage.erase()); - assertTrue(exception.getMessage().matches("Storage error.*")); + Exception exception = assertThrows(RuntimeException.class, fileStorage::erase); + assertTrue(Objects.requireNonNull(exception.getMessage()).matches("Storage error.*")); } @Test public void testReadException() { Path storagePath = tempDir.resolve("test.txt"); FileStorage fileStorage = new FileStorage("test", storagePath.toString()); - Exception exception = assertThrows(RuntimeException.class, () -> fileStorage.readFS()); - assertTrue(exception.getMessage().matches("Storage error.*")); + Exception exception = assertThrows(RuntimeException.class, fileStorage::readFS); + assertTrue(Objects.requireNonNull(exception.getMessage()).matches("Storage error.*")); } } \ No newline at end of file diff --git a/java/settings.gradle b/java/settings.gradle new file mode 100644 index 00000000..d60eb739 --- /dev/null +++ b/java/settings.gradle @@ -0,0 +1,5 @@ +plugins { + id 'org.gradle.toolchains.foojay-resolver-convention' version '0.8.0' +} +rootProject.name = "ark" +include("lib") diff --git a/java/settings.gradle.kts b/java/settings.gradle.kts deleted file mode 100644 index 2a9d8c0c..00000000 --- a/java/settings.gradle.kts +++ /dev/null @@ -1,14 +0,0 @@ -/* - * This file was generated by the Gradle 'init' task. - * - * The settings file is used to specify which projects to include in your build. - * For more detailed information on multi-project builds, please refer to https://docs.gradle.org/8.8/userguide/multi_project_builds.html in the Gradle documentation. - */ - -plugins { - // Apply the foojay-resolver plugin to allow automatic download of JDKs - id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" -} - -rootProject.name = "ark" -include("lib")