Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:

strategy:
matrix:
version: [ 24 ]
version: [ 25 ]
vector-length: [ 256, 512 ]

steps:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ jobs:

- uses: gradle/actions/wrapper-validation@v4

- name: Set up JDK 24
- name: Set up JDK 25
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 24
java-version: 25

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3
Expand Down
63 changes: 58 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,59 @@
build/
target/
!.mvn/wrapper/maven-wrapper.jar
.DS_Store
out/
generated/
generated_tests/
generated-resources-dir/
bin/
*.swp

# python
__pycache__
venv
.pyc

# Compiled class file
*.class

# Log file
*.log
*.log*

# BlueJ files
*.ctxt

# Mobile Tools for Java (J2ME)
.mtj.tmp/

# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar

### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.gradle/*

### IntelliJ IDEA ###
.idea
.gradle
build
profilers
testdata
hotspot_*.log
*.iws
*.iml
*.ipr
#### Intellij run configuration
.run/

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
replay_pid*
*/.gradle/*
165 changes: 117 additions & 48 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import me.champeau.jmh.JmhBytecodeGeneratorTask
import org.ajoberstar.grgit.Grgit
import org.gradle.internal.os.OperatingSystem

import java.time.Duration
Expand All @@ -8,17 +7,16 @@ plugins {
id 'java'
id 'scala'
id 'me.champeau.jmh' version '0.7.1'
id 'org.ajoberstar.grgit' version '5.2.0'
id 'pl.allegro.tech.build.axion-release' version '1.15.5'
id 'io.github.gradle-nexus.publish-plugin' version '1.3.0'
id 'pl.allegro.tech.build.axion-release' version '1.21.1'
id 'io.github.gradle-nexus.publish-plugin' version '2.0.0'
id 'maven-publish'
id 'signing'
}

scmVersion {
versionCreator('versionWithBranch')
tag {
prefix = ''
prefix.set('')
}
}

Expand All @@ -29,17 +27,46 @@ repositories {
mavenCentral()
}

// --- Java Version Resolution ---
static int resolveBuildJavaVersion() {
String v = System.getenv('BUILD_JAVA_VERSION') ?: JavaVersion.current().majorVersion

int dot = v.indexOf('.')
if (dot >= 0) {
v = v.substring(0, dot)
}

int dash = v.indexOf('-')
if (dash >= 0) {
v = v.substring(0, dash)
}

try {
return Integer.parseInt(v)
} catch (Exception e) {
throw new GradleException("Invalid BUILD_JAVA_VERSION '${System.getenv('BUILD_JAVA_VERSION')}'. " +
"Expected a Java major version like '24' (optionally with suffixes like '24.0.1' or '24-ea').", e)
}
}

def buildJavaVersion = resolveBuildJavaVersion()

if (buildJavaVersion < 24) {
throw new GradleException(
"This build requires Java 24+.\n" +
"Detected buildJavaVersion=${buildJavaVersion}.\n" +
"Either run Gradle with JDK 24+ (JAVA_HOME / PATH), or set BUILD_JAVA_VERSION=24 (or higher)."
)
}

java {
// It seems that specifying the minimum supported Java version while allowing the use of newer
// ones isn't possible in Gradle. To test the library against multiple Java versions, the
// workaround proposed in https://github.com/gradle/gradle/issues/16256 has been applied:
if (!JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_24)) {
toolchain {
languageVersion = JavaLanguageVersion.of(24)
}
toolchain {
languageVersion = JavaLanguageVersion.of(buildJavaVersion)
}
withJavadocJar()
withSourcesJar()
sourceCompatibility = JavaVersion.toVersion(buildJavaVersion)
targetCompatibility = JavaVersion.toVersion(buildJavaVersion)
}

ext {
Expand All @@ -62,49 +89,86 @@ dependencies {
testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: junitVersion
}

tasks.register('downloadTestData') {
doFirst {
def testDataDir = new File("${project.projectDir.getAbsolutePath()}/testdata")
if (!testDataDir.exists()) {
testDataDir.mkdir()
}
def numbersTestDataDir = new File("${testDataDir}/parse-number-fxx-test-data")
if (!numbersTestDataDir.exists()) {
def grgit = Grgit.clone(dir: numbersTestDataDir, uri: 'https://github.com/nigeltao/parse-number-fxx-test-data.git')
grgit.close()
// --- Test Data Preparation ---
def testdataParent = layout.projectDirectory.dir("testdata")
def repoDir = testdataParent.dir("parse-number-fxx-test-data")

tasks.register('prepareTestDataDir') {
description = 'Create testdata/ directory if missing'
doLast {
def parent = testdataParent.asFile
if (!parent.exists()) {
logger.lifecycle("Creating ${parent}")
parent.mkdirs()
}
}
}

tasks.register('test256', Test) {
dependsOn downloadTestData
useJUnitPlatform()
jvmArgs += [
'--add-modules', 'jdk.incubator.vector',
'-Xmx2g',
'-Dorg.simdjson.species=256'
]
tasks.register('downloadTestData', Exec) {
description = 'Clone parse-number-fxx-test-data into testdata/ if missing'
group = 'verification'
dependsOn tasks.named('prepareTestDataDir')

// Run if repo dir missing OR empty (handles half-created directories)
onlyIf {
def d = repoDir.asFile
!d.exists() || (d.isDirectory() && (d.listFiles() == null || d.listFiles().length == 0))
}

workingDir testdataParent.asFile
commandLine 'git', 'clone', 'https://github.com/nigeltao/parse-number-fxx-test-data.git', 'parse-number-fxx-test-data'

doFirst {
logger.lifecycle("Cloning parse-number-fxx-test-data into ${repoDir.asFile}")
}
}

// Configuration common to ALL Test tasks (including 'test', 'test256', 'test512')
tasks.withType(Test).configureEach {
dependsOn tasks.named('downloadTestData')

// Fix: Ensure logging is visible in the console
testLogging {
showStandardStreams = true
events 'PASSED', 'SKIPPED', 'FAILED', 'STANDARD_OUT', 'STANDARD_ERROR'
exceptionFormat = 'full'
showExceptions = true
showCauses = true
showStackTraces = true
}
}

tasks.register('test512', Test) {
dependsOn downloadTestData
// --- Test Variants (256/512) ---
test {
useJUnitPlatform()
jvmArgs += [
'--add-modules', 'jdk.incubator.vector',
'-Xmx2g',
'-Dorg.simdjson.species=512'
'--add-modules', 'jdk.incubator.vector', '-Xmx2g'
]
testLogging {
events 'PASSED', 'SKIPPED', 'FAILED', 'STANDARD_OUT', 'STANDARD_ERROR'
failOnNoDiscoveredTests = false
}

// Generate test tasks for specific species (256, 512)
[256, 512].each { species ->
tasks.register("test${species}", Test) {
group = 'verification'
description = "Runs tests with org.simdjson.species=${species}"

// Fix: Removed 'dependsOn test'. This allows test256 to run independently.
// We use mustRunAfter so they don't interleave output if run together via 'check'.
dependsOn tasks.named('test')

useJUnitPlatform()
jvmArgs += [
'--add-modules', 'jdk.incubator.vector',
'-Xmx2g',
"-Dorg.simdjson.species=${species}"
]
}
}

test {
dependsOn 'test256'
dependsOn 'test512'
tasks.named('check') {
dependsOn tasks.named('test256')
dependsOn tasks.named('test512')
}

tasks.withType(JmhBytecodeGeneratorTask).configureEach {
Expand All @@ -116,7 +180,6 @@ tasks.withType(JavaCompile).configureEach {
}

tasks.compileJmhScala.classpath = sourceSets.main.compileClasspath

tasks.compileJmhJava.classpath += files(sourceSets.jmh.scala.classesDirectory)

compileTestJava {
Expand Down Expand Up @@ -206,15 +269,21 @@ if (System.getenv('GPG_KEY_ID')) {
nexusPublishing {
repositories {
sonatype {
nexusUrl = uri("https://ossrh-staging-api.central.sonatype.com/service/local/")
snapshotRepositoryUrl = uri("https://central.sonatype.com/repository/maven-snapshots/")
stagingProfileId = '3c0bbfe420699e'
username = System.getenv('SONATYPE_USERNAME')
password = System.getenv('SONATYPE_PASSWORD')
nexusUrl.set(uri("https://ossrh-staging-api.central.sonatype.com/service/local/"))
snapshotRepositoryUrl.set(uri("https://central.sonatype.com/repository/maven-snapshots/"))

if (System.getenv('SONATYPE_USERNAME')) {
username.set(System.getenv('SONATYPE_USERNAME'))
}
if (System.getenv('SONATYPE_PASSWORD')) {
password.set(System.getenv('SONATYPE_PASSWORD'))
}

stagingProfileId.set('3c0bbfe420699e')
}
}
connectTimeout = Duration.ofMinutes(3)
clientTimeout = Duration.ofMinutes(3)
connectTimeout.set(Duration.ofMinutes(3))
clientTimeout.set(Duration.ofMinutes(3))
}

def getBooleanProperty(String name, boolean defaultValue) {
Expand Down
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
5 changes: 1 addition & 4 deletions gradlew

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

3 changes: 1 addition & 2 deletions gradlew.bat

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

4 changes: 4 additions & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "0.10.0"
}

rootProject.name = 'simdjson-java'