diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 4f1a4eb7f6..90665b6037 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -10,7 +10,8 @@ on: jobs: test: env: - HTSJDK_SAMTOOLS_BIN: /usr/bin/samtools + HTSJDK_SAMTOOLS_BIN: /usr/local/bin/samtools + SAMTOOLS_VERSION: 1.23.1 runs-on: ubuntu-latest strategy: matrix: @@ -20,20 +21,28 @@ jobs: continue-on-error: ${{ matrix.experimental }} name: Java ${{ matrix.Java }} build and test steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # full history + tags so palantir/git-version sees the latest release tag - name: Set up java ${{ matrix.Java }} - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: ${{ matrix.Java }} - distribution: 'adopt' - cache: gradle + distribution: 'temurin' + - name: Set up Gradle + uses: gradle/actions/setup-gradle@v4 - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Compile with Gradle run: ./gradlew compileJava + - name: Cache samtools + id: cache-samtools + uses: actions/cache@v4 + with: + path: /usr/local/bin/samtools + key: samtools-${{ env.SAMTOOLS_VERSION }}-${{ runner.os }} - name: Install Samtools + if: steps.cache-samtools.outputs.cache-hit != 'true' run: scripts/install-samtools.sh - name: Start the htsget server run: scripts/htsget-scripts/start-htsget-test-server.sh @@ -50,15 +59,16 @@ jobs: runs-on: ubuntu-latest name: Tests that require external APIs steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # full history + tags so palantir/git-version sees the latest release tag - name: Set up java 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '17' - distribution: 'adopt' - cache: gradle + distribution: 'temurin' + - name: Set up Gradle + uses: gradle/actions/setup-gradle@v4 - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Compile with Gradle @@ -75,15 +85,16 @@ jobs: runs-on: ubuntu-latest name: Java Format Check steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # full history + tags so palantir/git-version sees the latest release tag - name: Set up java 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '17' - distribution: 'adopt' - cache: gradle + distribution: 'temurin' + - name: Set up Gradle + uses: gradle/actions/setup-gradle@v4 - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Verify formatting @@ -92,15 +103,16 @@ jobs: runs-on: ubuntu-latest name: SpotBugs steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # full history + tags so palantir/git-version sees the latest release tag - name: Set up java 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '17' - distribution: 'adopt' - cache: gradle + distribution: 'temurin' + - name: Set up Gradle + uses: gradle/actions/setup-gradle@v4 - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Compile with Gradle @@ -111,6 +123,3 @@ jobs: with: name: spotBugs-Report path: build/reports/spotbugs - - - diff --git a/README.md b/README.md index 4310b5498e..096745fa4e 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ [![Build and Test](https://github.com/samtools/htsjdk/actions/workflows/tests.yml/badge.svg?branch=master&event=push)](https://github.com/samtools/htsjdk/actions/workflows/tests.yml) -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.samtools/htsjdk/badge.svg)](http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.github.samtools%22%20AND%20a%3A%22htsjdk%22) +[![Maven Central](https://img.shields.io/maven-central/v/com.github.samtools/htsjdk.svg?label=Maven%20Central)](https://central.sonatype.com/artifact/com.github.samtools/htsjdk) [![License](http://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/samtools/htsjdk) [![Language](http://img.shields.io/badge/language-java-brightgreen.svg)](https://www.java.com/) ## A Java API for high-throughput sequencing data (HTS) formats. diff --git a/build.gradle b/build.gradle index 969ff850c4..bac4f1bee6 100644 --- a/build.gradle +++ b/build.gradle @@ -102,7 +102,7 @@ java { // // To change the planned bump (e.g. after a release lands), update nextVersionBump // below and commit. -final nextVersionBump = "x" +final nextVersionBump = "x.x.x" final isRelease = Boolean.getBoolean("release") final details = versionDetails() @@ -189,7 +189,7 @@ tasks.withType(Test).configureEach { task -> // set heap size for the test JVM(s) task.minHeapSize = "1G" - task.maxHeapSize = "12G" + task.maxHeapSize = "14G" task.jvmArgs '-Djava.awt.headless=true' //this prevents awt from displaying a java icon while the tests are running @@ -352,9 +352,9 @@ publishing { signing { useGpgCmd() sign(publishing.publications.htsjdk) - required = { isRelease && gradle.taskGraph.hasTask("publishAllPublicationsToCentralPortal") } + required = { isRelease } tasks.withType(Sign).configureEach { - onlyIf { isRelease && gradle.taskGraph.hasTask("publishAllPublicationsToCentralPortal") } + onlyIf { isRelease } } } diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000000..9ac097894c --- /dev/null +++ b/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx512m -XX:MaxMetaspaceSize=256m diff --git a/scripts/install-samtools.sh b/scripts/install-samtools.sh index b2bde8b987..ccf23f20c3 100755 --- a/scripts/install-samtools.sh +++ b/scripts/install-samtools.sh @@ -1,12 +1,11 @@ #!/bin/sh set -ex -#ubuntu specific +# ubuntu specific sudo apt-get update -sudo apt-get upgrade sudo apt-get install -y libncurses-dev libbz2-dev liblzma-dev -#install from the github tar -export SAMTOOLS_VERSION=1.21 +# install from the github tar +export SAMTOOLS_VERSION=1.23.1 wget https://github.com/samtools/samtools/releases/download/${SAMTOOLS_VERSION}/samtools-${SAMTOOLS_VERSION}.tar.bz2 tar -xjvf samtools-${SAMTOOLS_VERSION}.tar.bz2 -cd samtools-${SAMTOOLS_VERSION} && ./configure --prefix=/usr && make && sudo make install +cd samtools-${SAMTOOLS_VERSION} && ./configure --prefix=/usr/local && make && sudo make install diff --git a/src/test/java/htsjdk/utils/SamtoolsTestUtils.java b/src/test/java/htsjdk/utils/SamtoolsTestUtils.java index 81b19af88b..1b59605e92 100644 --- a/src/test/java/htsjdk/utils/SamtoolsTestUtils.java +++ b/src/test/java/htsjdk/utils/SamtoolsTestUtils.java @@ -8,13 +8,46 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Test utilities for running samtools from htsjdk tests. */ public class SamtoolsTestUtils { private static final String SAMTOOLS_BINARY_ENV_VARIABLE = "HTSJDK_SAMTOOLS_BIN"; - public static final String expectedSamtoolsVersion = "1.21"; + public static final String minimumSamtoolsVersion = "1.23.1"; + + private static final Pattern SAMTOOLS_VERSION_PATTERN = Pattern.compile("(?m)^samtools\\s+(\\d+(?:\\.\\d+)*)"); + + /** + * Extracts the version string (e.g. "1.23.1") from the output of `samtools --version`, + * which begins with a line of the form {@code samtools }. + * + * @return the version string, or null if no version line was found. + */ + static String parseSamtoolsVersion(final String samtoolsVersionOutput) { + final Matcher m = SAMTOOLS_VERSION_PATTERN.matcher(samtoolsVersionOutput); + return m.find() ? m.group(1) : null; + } + + /** + * Compares two dotted-numeric version strings (e.g. "1.23.1") component-by-component. + * Missing trailing components are treated as zero, so "1.23" is equal to "1.23.0". + */ + static int compareVersions(final String a, final String b) { + final String[] aParts = a.split("\\."); + final String[] bParts = b.split("\\."); + final int len = Math.max(aParts.length, bParts.length); + for (int i = 0; i < len; i++) { + final int av = i < aParts.length ? Integer.parseInt(aParts[i]) : 0; + final int bv = i < bParts.length ? Integer.parseInt(bParts[i]) : 0; + if (av != bv) { + return Integer.compare(av, bv); + } + } + return 0; + } /** * @return true if samtools is available, otherwise false diff --git a/src/test/java/htsjdk/utils/SamtoolsTestUtilsTest.java b/src/test/java/htsjdk/utils/SamtoolsTestUtilsTest.java index cdf95dd596..3db9ded230 100644 --- a/src/test/java/htsjdk/utils/SamtoolsTestUtilsTest.java +++ b/src/test/java/htsjdk/utils/SamtoolsTestUtilsTest.java @@ -27,10 +27,52 @@ public void testSamtoolsVersion() { if (!SamtoolsTestUtils.isSamtoolsAvailable()) { throw new SkipException("Samtools not available on local device"); } - // If this test runs, but fails because version validation fails, then the local samtools version is - // not the one expected by the htsjdk tests final ProcessExecutor.ExitStatusAndOutput processStatus = SamtoolsTestUtils.executeSamToolsCommand("--version"); - Assert.assertTrue(processStatus.stdout.contains(SamtoolsTestUtils.expectedSamtoolsVersion)); + final String localVersion = SamtoolsTestUtils.parseSamtoolsVersion(processStatus.stdout); + Assert.assertNotNull( + localVersion, + "Could not parse samtools version from `samtools --version` output: " + processStatus.stdout); + Assert.assertTrue( + SamtoolsTestUtils.compareVersions(localVersion, SamtoolsTestUtils.minimumSamtoolsVersion) >= 0, + "Local samtools version " + localVersion + " is older than the minimum required by htsjdk tests (" + + SamtoolsTestUtils.minimumSamtoolsVersion + ")"); + } + + @Test + public void testParseSamtoolsVersionFromTypicalOutput() { + final String stdout = "samtools 1.23.1\nUsing htslib 1.23.1\nCopyright (C) 2024 Genome Research Ltd.\n"; + Assert.assertEquals(SamtoolsTestUtils.parseSamtoolsVersion(stdout), "1.23.1"); + } + + @Test + public void testParseSamtoolsVersionTwoComponent() { + Assert.assertEquals(SamtoolsTestUtils.parseSamtoolsVersion("samtools 1.21\n"), "1.21"); + } + + @Test + public void testParseSamtoolsVersionReturnsNullWhenAbsent() { + Assert.assertNull(SamtoolsTestUtils.parseSamtoolsVersion("nothing recognizable here\n")); + } + + @Test + public void testCompareVersionsEqualWithImplicitZero() { + Assert.assertEquals(SamtoolsTestUtils.compareVersions("1.23", "1.23.0"), 0); + } + + @Test + public void testCompareVersionsPatchGreater() { + Assert.assertTrue(SamtoolsTestUtils.compareVersions("1.23.1", "1.23") > 0); + } + + @Test + public void testCompareVersionsMajorLess() { + Assert.assertTrue(SamtoolsTestUtils.compareVersions("1.21", "1.23.1") < 0); + } + + @Test + public void testCompareVersionsNumericNotLexical() { + // 1.10 is greater than 1.9 numerically, even though "1.10" sorts before "1.9" lexically. + Assert.assertTrue(SamtoolsTestUtils.compareVersions("1.10", "1.9") > 0); } @Test(expectedExceptions = RuntimeException.class)