diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000..493b5c8
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,160 @@
+name: Build AppleSingle 'asu' CLI and API
+
+on:
+ push:
+ branches: [ "main" ]
+ tags:
+ - '*'
+ pull_request:
+ branches: [ "main" ]
+ workflow_dispatch:
+
+permissions:
+ contents: read
+
+jobs:
+ build-java:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v7
+ - name: Set up JDK 25
+ uses: actions/setup-java@v6.0.1
+ with:
+ java-version: '25'
+ distribution: 'temurin'
+ - name: Setup Gradle
+ uses: gradle/actions/setup-gradle@v6
+ - name: Build with Gradle
+ run: ./gradlew build
+ - name: Upload artifacts
+ uses: actions/upload-artifact@v7
+ with:
+ name: build-artifacts
+ path: |
+ tools/asu/build/libs/applesingle-tools-asu-*.jar
+ !tools/asu/build/libs/applesingle-tools-asu-*-plain.jar
+ archive: false
+ if-no-files-found: error
+
+ # This is a crude license header check. The ones I tested were susceptible to whitespace differences
+ # and I never got them to work. My primary goal is to ensure the headers exist, so this suffices.
+ license-check:
+ name: License check
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v7
+ - name: Look for license phrase
+ run: |
+ outfile=$(mktemp)
+ find . -name "*.java" -not -name module-info.java | xargs grep -L "GNU General Public License" > ${outfile}
+ if [ -s "${outfile}" ]
+ then
+ echo "License headers missing on the following files:"
+ cat ${outfile}
+ exit 1
+ else
+ echo "License headers appear to be valid!"
+ fi
+
+ build-native:
+ name: asu on ${{ matrix.os }}-${{ matrix.arch }}
+ needs: [build-java, license-check]
+ runs-on: ${{ matrix.label }}
+ strategy:
+ matrix:
+ # See: https://docs.github.com/en/actions/concepts/runners/about-github-hosted-runners#overview-of-github-hosted-runners
+ # ... and follow the links to the related Github repositories
+ include:
+ - label: ubuntu-latest
+ os: linux
+ arch: x86_64
+ - label: ubuntu-24.04-arm
+ os: linux
+ arch: aarch64
+ - label: windows-latest
+ os: windows
+ arch: x86_64
+ - label: macos-15-intel
+ os: darwin
+ arch: x86_64
+ - label: macos-15
+ os: darwin
+ arch: arm64
+ steps:
+ - uses: actions/checkout@v7
+ - uses: graalvm/setup-graalvm@v1
+ with:
+ java-version: '25'
+ distribution: 'graalvm-community'
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ native-image-job-reports: 'true'
+ - name: Build 'asu'
+ run: ./gradlew nativeCompile
+ env:
+ # Needed for Windows; not an issue for other OSes
+ GRADLE_OPTS: -Djava.io.tmpdir=${{ runner.temp }}
+ - name: Run UPX
+ uses: crazy-max/ghaction-upx@v4
+ if: runner.os == 'Linux'
+ with:
+ files: |
+ tools/asu/build/native/nativeCompile/asu*
+ - name: Upload binary
+ uses: actions/upload-artifact@v7
+ with:
+ name: asu-${{ matrix.os }}-${{ matrix.arch }}
+ path: tools/asu/build/native/nativeCompile/asu*
+
+ release:
+ name: Create draft release
+ if: github.ref_type == 'tag'
+ needs: [build-java, build-native]
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write
+ steps:
+ - uses: actions/download-artifact@v8
+ with:
+ merge-multiple: true
+ - uses: softprops/action-gh-release@v3
+ with:
+ draft: true
+ generate_release_notes: true
+ files: |
+ asu-*
+ applesingle-tools-asu-*.jar
+
+ publish:
+ name: Publish to Maven Central
+ if: github.ref_type == 'tag'
+ needs: [build-java, build-native]
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v7
+ - name: Set up JDK 25
+ uses: actions/setup-java@v6.0.1
+ with:
+ java-version: '25'
+ distribution: 'temurin'
+ - name: Setup Gradle
+ uses: gradle/actions/setup-gradle@v6
+ - name: Publish with Gradle
+ run: |
+ export ORG_GRADLE_PROJECT_signingKey=$(echo "$GPG_SIGNING_KEY_BASE64" | base64 -d)
+ ./gradlew build publish -x test
+ env:
+ ORG_GRADLE_PROJECT_ossrhUsername: ${{ secrets.OSSRH_USERNAME }}
+ ORG_GRADLE_PROJECT_ossrhPassword: ${{ secrets.OSSRH_TOKEN }}
+ ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.GPG_SIGNING_PASSPHRASE }}
+ GPG_SIGNING_KEY_BASE64: ${{ secrets.GPG_SIGNING_KEY_BASE64 }}
+ ORG_GRADLE_PROJECT_signingKeyId: ${{ secrets.GPG_SIGNING_KEY_ID }}
+ - name: Setup .netrc file
+ uses: extractions/netrc@v3
+ with:
+ machine: ossrh-staging-api.central.sonatype.com
+ username: ${{ secrets.OSSRH_USERNAME }}
+ password: ${{ secrets.OSSRH_TOKEN }}
+ - name: Finish publishing
+ run: ./scripts/finish-publishing.sh
diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml
deleted file mode 100644
index 02a9246..0000000
--- a/.github/workflows/gradle.yml
+++ /dev/null
@@ -1,40 +0,0 @@
-# This workflow uses actions that are not certified by GitHub.
-# They are provided by a third-party and are governed by
-# separate terms of service, privacy policy, and support
-# documentation.
-# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
-# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle
-
-name: Build AppleSingle 'asu' CLI and API
-
-on:
- push:
- branches: [ "main" ]
- pull_request:
- branches: [ "main" ]
-
-permissions:
- contents: read
-
-jobs:
- build:
-
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@v7
- - name: Set up JDK 21
- uses: actions/setup-java@v6.0.1
- with:
- java-version: '21'
- distribution: 'temurin'
- - name: Setup Gradle
- uses: gradle/actions/setup-gradle@v6
- - name: Build with Gradle
- run: ./gradlew build
- - name: Upload artifacts
- uses: actions/upload-artifact@v7
- with:
- name: build-artifacts
- path: tools/asu/build/libs/applesingle-tools-asu-*.jar
- if-no-files-found: error
diff --git a/.github/workflows/nativeCompile.yml b/.github/workflows/nativeCompile.yml
deleted file mode 100644
index de70cf5..0000000
--- a/.github/workflows/nativeCompile.yml
+++ /dev/null
@@ -1,58 +0,0 @@
-name: GraalVM Native Image builds
-
-on:
- push:
- branches: [ "main" ]
- pull_request:
- branches: [ "main" ]
-
-permissions:
- contents: read
-
-jobs:
- build:
- name: asu on ${{ matrix.os }}-${{ matrix.arch }}
- runs-on: ${{ matrix.label }}
- strategy:
- matrix:
- # See: https://docs.github.com/en/actions/concepts/runners/about-github-hosted-runners#overview-of-github-hosted-runners
- # ... and follow the links to the related Github repositories
- include:
- - label: ubuntu-latest
- os: linux
- arch: x86_64
- - label: ubuntu-24.04-arm
- os: linux
- arch: aarch64
- - label: windows-latest
- os: windows
- arch: x86_64
- - label: macos-15-intel
- os: darwin
- arch: x86_64
- - label: macos-15
- os: darwin
- arch: arm64
- steps:
- - uses: actions/checkout@v7
-
- - uses: graalvm/setup-graalvm@v1
- with:
- java-version: '21'
- distribution: 'graalvm-community'
- github-token: ${{ secrets.GITHUB_TOKEN }}
- native-image-job-reports: 'true'
-
- # Note that Graal v21 builds to the current architecture, and "--target" is not functional.
- # Therefore, we try to find runners that fit our targets (see above).
- - name: Build 'asu'
- run: ./gradlew nativeCompile
- env:
- # Needed for Windows; not an issue for other OSes
- GRADLE_OPTS: -Djava.io.tmpdir=${{ runner.temp }}
-
- - name: Upload binary
- uses: actions/upload-artifact@v7
- with:
- name: asu-${{ matrix.os }}-${{ matrix.arch }}
- path: tools/asu/build/native/nativeCompile/asu*
diff --git a/HEADER b/HEADER
new file mode 100644
index 0000000..54e04cc
--- /dev/null
+++ b/HEADER
@@ -0,0 +1,17 @@
+/*
+ * AppleSingle - A Java library and command-line tool for AppleSingle support.
+ * Copyright (C) 2026 Robert Greene
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
diff --git a/api/build.gradle b/api/build.gradle
index 0809e2a..8562fc4 100644
--- a/api/build.gradle
+++ b/api/build.gradle
@@ -44,19 +44,21 @@ artifacts {
publishing {
publications {
mavenJava(MavenPublication) {
+ groupId = "org.applecommander"
+ artifactId = "applesingle-api"
+
from components.java
+
artifact sourcesJar
artifact javadocJar
pom {
- groupId = "net.sf.applecommander"
- artifactId = "applesingle-api"
name = 'applesingle-api'
description = 'A Java library for managing AppleSingle files.'
url = 'https://applecommander.github.io/'
licenses {
license {
- name = 'The GNU General Public License (GPL) Version 2, June 1991'
- url = 'https://www.gnu.org/licenses/gpl-2.0.html'
+ name = 'The GNU General Public License (GPL) Version 3, June 2007'
+ url = 'https://www.gnu.org/licenses/gpl-3.0.html'
}
}
developers {
@@ -74,8 +76,8 @@ publishing {
}
repositories {
maven {
- def releasesRepoUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2"
- def snapshotsRepoUrl = "https://oss.sonatype.org/content/repositories/snapshots/"
+ def releasesRepoUrl = "https://ossrh-staging-api.central.sonatype.com/service/local/staging/deploy/maven2"
+ def snapshotsRepoUrl = "https://ossrh-staging-api.central.sonatype.com/content/repositories/snapshots/"
url = isSnapshotVersion ? snapshotsRepoUrl : releasesRepoUrl
credentials {
username = findProperty('ossrhUsername')
@@ -88,5 +90,9 @@ publishing {
}
signing {
+ def signingKey = findProperty("signingKey")
+ def signingPassword = findProperty("signingPassword")
+ def signingKeyId = findProperty("signingKeyId")
+ useInMemoryPgpKeys(signingKeyId, signingKey, signingPassword)
sign publishing.publications.mavenJava
}
diff --git a/api/src/main/java/module-info.java b/api/src/main/java/module-info.java
new file mode 100644
index 0000000..29a128f
--- /dev/null
+++ b/api/src/main/java/module-info.java
@@ -0,0 +1,3 @@
+module org.applecommander.applesingle {
+ exports org.applecommander.applesingle;
+}
\ No newline at end of file
diff --git a/api/src/main/java/io/github/applecommander/applesingle/AppleSingle.java b/api/src/main/java/org/applecommander/applesingle/AppleSingle.java
similarity index 93%
rename from api/src/main/java/io/github/applecommander/applesingle/AppleSingle.java
rename to api/src/main/java/org/applecommander/applesingle/AppleSingle.java
index 643f333..258859f 100644
--- a/api/src/main/java/io/github/applecommander/applesingle/AppleSingle.java
+++ b/api/src/main/java/org/applecommander/applesingle/AppleSingle.java
@@ -1,4 +1,21 @@
-package io.github.applecommander.applesingle;
+/*
+ * AppleSingle - A Java library and command-line tool for AppleSingle support.
+ * Copyright (C) 2026 Robert Greene
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.applecommander.applesingle;
import java.io.File;
import java.io.FileOutputStream;
diff --git a/api/src/main/java/io/github/applecommander/applesingle/AppleSingleReader.java b/api/src/main/java/org/applecommander/applesingle/AppleSingleReader.java
similarity index 84%
rename from api/src/main/java/io/github/applecommander/applesingle/AppleSingleReader.java
rename to api/src/main/java/org/applecommander/applesingle/AppleSingleReader.java
index e348c20..d3795fd 100644
--- a/api/src/main/java/io/github/applecommander/applesingle/AppleSingleReader.java
+++ b/api/src/main/java/org/applecommander/applesingle/AppleSingleReader.java
@@ -1,4 +1,21 @@
-package io.github.applecommander.applesingle;
+/*
+ * AppleSingle - A Java library and command-line tool for AppleSingle support.
+ * Copyright (C) 2026 Robert Greene
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.applecommander.applesingle;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
diff --git a/api/src/main/java/io/github/applecommander/applesingle/Entry.java b/api/src/main/java/org/applecommander/applesingle/Entry.java
similarity index 73%
rename from api/src/main/java/io/github/applecommander/applesingle/Entry.java
rename to api/src/main/java/org/applecommander/applesingle/Entry.java
index 66bad8e..a6a2f57 100644
--- a/api/src/main/java/io/github/applecommander/applesingle/Entry.java
+++ b/api/src/main/java/org/applecommander/applesingle/Entry.java
@@ -1,4 +1,21 @@
-package io.github.applecommander.applesingle;
+/*
+ * AppleSingle - A Java library and command-line tool for AppleSingle support.
+ * Copyright (C) 2026 Robert Greene
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.applecommander.applesingle;
import java.io.IOException;
import java.io.OutputStream;
diff --git a/api/src/main/java/io/github/applecommander/applesingle/EntryType.java b/api/src/main/java/org/applecommander/applesingle/EntryType.java
similarity index 57%
rename from api/src/main/java/io/github/applecommander/applesingle/EntryType.java
rename to api/src/main/java/org/applecommander/applesingle/EntryType.java
index 4bcff70..ff6899a 100644
--- a/api/src/main/java/io/github/applecommander/applesingle/EntryType.java
+++ b/api/src/main/java/org/applecommander/applesingle/EntryType.java
@@ -1,4 +1,21 @@
-package io.github.applecommander.applesingle;
+/*
+ * AppleSingle - A Java library and command-line tool for AppleSingle support.
+ * Copyright (C) 2026 Robert Greene
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.applecommander.applesingle;
public enum EntryType {
DATA_FORK(1, "Data Fork"),
diff --git a/api/src/main/java/io/github/applecommander/applesingle/FileDatesInfo.java b/api/src/main/java/org/applecommander/applesingle/FileDatesInfo.java
similarity index 75%
rename from api/src/main/java/io/github/applecommander/applesingle/FileDatesInfo.java
rename to api/src/main/java/org/applecommander/applesingle/FileDatesInfo.java
index b977556..31ab2b2 100644
--- a/api/src/main/java/io/github/applecommander/applesingle/FileDatesInfo.java
+++ b/api/src/main/java/org/applecommander/applesingle/FileDatesInfo.java
@@ -1,4 +1,21 @@
-package io.github.applecommander.applesingle;
+/*
+ * AppleSingle - A Java library and command-line tool for AppleSingle support.
+ * Copyright (C) 2026 Robert Greene
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.applecommander.applesingle;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
diff --git a/api/src/main/java/io/github/applecommander/applesingle/ProdosFileInfo.java b/api/src/main/java/org/applecommander/applesingle/ProdosFileInfo.java
similarity index 62%
rename from api/src/main/java/io/github/applecommander/applesingle/ProdosFileInfo.java
rename to api/src/main/java/org/applecommander/applesingle/ProdosFileInfo.java
index d0482e4..9813f60 100644
--- a/api/src/main/java/io/github/applecommander/applesingle/ProdosFileInfo.java
+++ b/api/src/main/java/org/applecommander/applesingle/ProdosFileInfo.java
@@ -1,9 +1,26 @@
-package io.github.applecommander.applesingle;
+/*
+ * AppleSingle - A Java library and command-line tool for AppleSingle support.
+ * Copyright (C) 2026 Robert Greene
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.applecommander.applesingle;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
-import io.github.applecommander.applesingle.AppleSingle.Builder;
+import org.applecommander.applesingle.AppleSingle.Builder;
/**
* A simple ProDOS File Info wrapper class.
diff --git a/api/src/main/java/io/github/applecommander/applesingle/Utilities.java b/api/src/main/java/org/applecommander/applesingle/Utilities.java
similarity index 53%
rename from api/src/main/java/io/github/applecommander/applesingle/Utilities.java
rename to api/src/main/java/org/applecommander/applesingle/Utilities.java
index 8e9f898..4b4b907 100644
--- a/api/src/main/java/io/github/applecommander/applesingle/Utilities.java
+++ b/api/src/main/java/org/applecommander/applesingle/Utilities.java
@@ -1,4 +1,21 @@
-package io.github.applecommander.applesingle;
+/*
+ * AppleSingle - A Java library and command-line tool for AppleSingle support.
+ * Copyright (C) 2026 Robert Greene
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.applecommander.applesingle;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
diff --git a/api/src/test/java/io/github/applecommander/applesingle/AppleSingleReaderTest.java b/api/src/test/java/org/applecommander/applesingle/AppleSingleReaderTest.java
similarity index 76%
rename from api/src/test/java/io/github/applecommander/applesingle/AppleSingleReaderTest.java
rename to api/src/test/java/org/applecommander/applesingle/AppleSingleReaderTest.java
index 4efe52b..0b7db47 100644
--- a/api/src/test/java/io/github/applecommander/applesingle/AppleSingleReaderTest.java
+++ b/api/src/test/java/org/applecommander/applesingle/AppleSingleReaderTest.java
@@ -1,4 +1,21 @@
-package io.github.applecommander.applesingle;
+/*
+ * AppleSingle - A Java library and command-line tool for AppleSingle support.
+ * Copyright (C) 2026 Robert Greene
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.applecommander.applesingle;
import org.junit.Test;
import static org.junit.Assert.*;
diff --git a/api/src/test/java/io/github/applecommander/applesingle/AppleSingleTest.java b/api/src/test/java/org/applecommander/applesingle/AppleSingleTest.java
similarity index 81%
rename from api/src/test/java/io/github/applecommander/applesingle/AppleSingleTest.java
rename to api/src/test/java/org/applecommander/applesingle/AppleSingleTest.java
index 4481fad..43f4a78 100644
--- a/api/src/test/java/io/github/applecommander/applesingle/AppleSingleTest.java
+++ b/api/src/test/java/org/applecommander/applesingle/AppleSingleTest.java
@@ -1,4 +1,21 @@
-package io.github.applecommander.applesingle;
+/*
+ * AppleSingle - A Java library and command-line tool for AppleSingle support.
+ * Copyright (C) 2026 Robert Greene
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.applecommander.applesingle;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
diff --git a/build.gradle b/build.gradle
index 6ecfb0c..d91d283 100644
--- a/build.gradle
+++ b/build.gradle
@@ -2,14 +2,11 @@ plugins {
id 'java'
}
-ext {
- // Dependency versions
- // ???
-}
-
subprojects {
- sourceCompatibility = '21'
- targetCompatibility = '21'
+ java {
+ sourceCompatibility = 25
+ targetCompatibility = 25
+ }
}
if (JavaVersion.current().isJava8Compatible()) {
diff --git a/gradle.properties b/gradle.properties
index fdee160..e1373c0 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,8 +1,4 @@
# Universal applesingle version number. Used for:
# - Naming JAR file.
# - The build will insert this into a file that is read at run time as well.
-version=1.4.0-DEV
-
-# Maven Central Repository G and A of GAV coordinate. :-)
-group=net.sf.applecommander
-archivesBaseName=AppleCommander
+version=2.0
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 1b33c55..eddabd2 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index ff23a68..69dd0d0 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,7 +1,9 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-9.7.0-bin.zip
networkTimeout=10000
+retries=0
+retryBackOffMs=500
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
index 23d15a9..249efbb 100755
--- a/gradlew
+++ b/gradlew
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# Copyright © 2015-2021 the original authors.
+# Copyright © 2015 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -20,7 +20,7 @@
##############################################################################
#
-# Gradle start up script for POSIX generated by Gradle.
+# gradlew start up script for POSIX generated by Gradle.
#
# Important for running:
#
@@ -29,7 +29,7 @@
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
-# ksh Gradle
+# ksh gradlew
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
@@ -57,7 +57,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
-# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# https://github.com/gradle/gradle/blob/3d91ce3b8caaf77ad09f381f43615b715b53f72c/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
@@ -114,7 +114,6 @@ case "$( uname )" in #(
NONSTOP* ) nonstop=true ;;
esac
-CLASSPATH="\\\"\\\""
# Determine the Java command to use to start the JVM.
@@ -172,7 +171,6 @@ fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
- CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
@@ -212,7 +210,6 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
- -classpath "$CLASSPATH" \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"
diff --git a/gradlew.bat b/gradlew.bat
index 5eed7ee..8508ef6 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -19,12 +19,12 @@
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
-@rem Gradle startup script for Windows
+@rem gradlew startup script for Windows
@rem
@rem ##########################################################################
-@rem Set local scope for the variables with windows NT shell
-if "%OS%"=="Windows_NT" setlocal
+@rem Set local scope for the variables, and ensure extensions are enabled
+setlocal EnableExtensions
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@@ -51,7 +51,7 @@ echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
-goto fail
+"%COMSPEC%" /c exit 1
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
@@ -65,30 +65,18 @@ echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
-goto fail
+"%COMSPEC%" /c exit 1
:execute
@rem Setup the command line
-set CLASSPATH=
-@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
+@rem Execute gradlew
+@rem endlocal doesn't take effect until after the line is parsed and variables are expanded
+@rem which allows us to clear the local environment before executing the java command
+endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel
-:end
-@rem End local scope for the variables with windows NT shell
-if %ERRORLEVEL% equ 0 goto mainEnd
-
-:fail
-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
-rem the _cmd.exe /c_ return code!
-set EXIT_CODE=%ERRORLEVEL%
-if %EXIT_CODE% equ 0 set EXIT_CODE=1
-if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
-exit /b %EXIT_CODE%
-
-:mainEnd
-if "%OS%"=="Windows_NT" endlocal
-
-:omega
+:exitWithErrorLevel
+@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts
+"%COMSPEC%" /c exit %ERRORLEVEL%
diff --git a/scripts/finish-publishing.sh b/scripts/finish-publishing.sh
new file mode 100755
index 0000000..3e09341
--- /dev/null
+++ b/scripts/finish-publishing.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+# Note: Credentials are in the netrc file
+curl --netrc -v -X POST https://ossrh-staging-api.central.sonatype.com/manual/upload/defaultRepository/org.applecommander
diff --git a/tools/asu/build.gradle b/tools/asu/build.gradle
index fc8dde2..37374ec 100644
--- a/tools/asu/build.gradle
+++ b/tools/asu/build.gradle
@@ -24,7 +24,7 @@ jar {
}
application {
- mainClass = "io.github.applecommander.applesingle.tools.asu.Main"
+ mainClass = "org.applecommander.applesingle.tools.asu.Main"
}
// Disable all Spring AOT processing
diff --git a/tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/ForkType.java b/tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/ForkType.java
deleted file mode 100644
index 058f3fa..0000000
--- a/tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/ForkType.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package io.github.applecommander.applesingle.tools.asu;
-
-/**
- * Basic listing of fork types used in the command line tools.
- */
-public enum ForkType {
- data, resource, both
-}
diff --git a/tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/IntegerTypeConverter.java b/tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/IntegerTypeConverter.java
deleted file mode 100644
index 66d6d11..0000000
--- a/tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/IntegerTypeConverter.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package io.github.applecommander.applesingle.tools.asu;
-
-import picocli.CommandLine.ITypeConverter;
-
-/** Add support for "$801" and "0x801" instead of just decimal like 2049. */
-public class IntegerTypeConverter implements ITypeConverter {
- @Override
- public Integer convert(String value) {
- if (value == null) {
- return null;
- } else if (value.startsWith("$")) {
- return Integer.valueOf(value.substring(1), 16);
- } else if (value.startsWith("0x") || value.startsWith("0X")) {
- return Integer.valueOf(value.substring(2), 16);
- } else {
- return Integer.valueOf(value);
- }
- }
-}
diff --git a/tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/NullOutputStream.java b/tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/NullOutputStream.java
deleted file mode 100644
index 44f544e..0000000
--- a/tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/NullOutputStream.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package io.github.applecommander.applesingle.tools.asu;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/** An OutputStream that doesn't do output. */
-public class NullOutputStream extends OutputStream {
- public static final NullOutputStream INSTANCE = new NullOutputStream();
-
- private NullOutputStream() { /* Prevent construction */ }
-
- @Override
- public void write(int b) throws IOException {
- // Do Nothing
- }
-}
diff --git a/tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/VersionProvider.java b/tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/VersionProvider.java
deleted file mode 100644
index 47091ef..0000000
--- a/tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/VersionProvider.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package io.github.applecommander.applesingle.tools.asu;
-
-import io.github.applecommander.applesingle.AppleSingle;
-import picocli.CommandLine.IVersionProvider;
-
-/** Display version information. Note that this is dependent on the Spring Boot Gradle plugin configuration. */
-public class VersionProvider implements IVersionProvider {
- public String[] getVersion() {
- return new String[] {
- String.format("CLI: %s", Main.class.getPackage().getImplementationVersion()),
- String.format("API: %s", AppleSingle.VERSION)
- };
- }
-}
\ No newline at end of file
diff --git a/tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/AnalyzeCommand.java b/tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/AnalyzeCommand.java
similarity index 81%
rename from tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/AnalyzeCommand.java
rename to tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/AnalyzeCommand.java
index 3770344..652605a 100644
--- a/tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/AnalyzeCommand.java
+++ b/tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/AnalyzeCommand.java
@@ -1,4 +1,21 @@
-package io.github.applecommander.applesingle.tools.asu;
+/*
+ * AppleSingle - A Java library and command-line tool for AppleSingle support.
+ * Copyright (C) 2026 Robert Greene
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.applecommander.applesingle.tools.asu;
import java.io.IOException;
import java.io.PrintStream;
@@ -12,13 +29,13 @@
import java.util.concurrent.Callable;
import java.util.function.BiConsumer;
-import io.github.applecommander.applesingle.AppleSingle;
-import io.github.applecommander.applesingle.AppleSingleReader;
-import io.github.applecommander.applesingle.Entry;
-import io.github.applecommander.applesingle.EntryType;
-import io.github.applecommander.applesingle.FileDatesInfo;
-import io.github.applecommander.applesingle.ProdosFileInfo;
-import io.github.applecommander.applesingle.Utilities;
+import org.applecommander.applesingle.AppleSingle;
+import org.applecommander.applesingle.AppleSingleReader;
+import org.applecommander.applesingle.Entry;
+import org.applecommander.applesingle.EntryType;
+import org.applecommander.applesingle.FileDatesInfo;
+import org.applecommander.applesingle.ProdosFileInfo;
+import org.applecommander.applesingle.Utilities;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;
diff --git a/tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/CreateCommand.java b/tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/CreateCommand.java
similarity index 86%
rename from tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/CreateCommand.java
rename to tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/CreateCommand.java
index 8990a1e..1e2ef71 100644
--- a/tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/CreateCommand.java
+++ b/tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/CreateCommand.java
@@ -1,4 +1,21 @@
-package io.github.applecommander.applesingle.tools.asu;
+/*
+ * AppleSingle - A Java library and command-line tool for AppleSingle support.
+ * Copyright (C) 2026 Robert Greene
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.applecommander.applesingle.tools.asu;
import java.io.IOException;
import java.nio.file.Files;
@@ -8,8 +25,8 @@
import java.util.Optional;
import java.util.concurrent.Callable;
-import io.github.applecommander.applesingle.AppleSingle;
-import io.github.applecommander.applesingle.Utilities;
+import org.applecommander.applesingle.AppleSingle;
+import org.applecommander.applesingle.Utilities;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;
diff --git a/tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/EditCommand.java b/tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/EditCommand.java
similarity index 86%
rename from tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/EditCommand.java
rename to tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/EditCommand.java
index 172a177..1e07693 100644
--- a/tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/EditCommand.java
+++ b/tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/EditCommand.java
@@ -1,7 +1,24 @@
-package io.github.applecommander.applesingle.tools.asu;
+/*
+ * AppleSingle - A Java library and command-line tool for AppleSingle support.
+ * Copyright (C) 2026 Robert Greene
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.applecommander.applesingle.tools.asu;
-import io.github.applecommander.applesingle.AppleSingle;
-import io.github.applecommander.applesingle.Utilities;
+import org.applecommander.applesingle.AppleSingle;
+import org.applecommander.applesingle.Utilities;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;
diff --git a/tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/ExtractCommand.java b/tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/ExtractCommand.java
similarity index 79%
rename from tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/ExtractCommand.java
rename to tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/ExtractCommand.java
index 2e7d3c2..b4d15a8 100644
--- a/tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/ExtractCommand.java
+++ b/tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/ExtractCommand.java
@@ -1,4 +1,21 @@
-package io.github.applecommander.applesingle.tools.asu;
+/*
+ * AppleSingle - A Java library and command-line tool for AppleSingle support.
+ * Copyright (C) 2026 Robert Greene
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.applecommander.applesingle.tools.asu;
import java.io.IOException;
import java.nio.file.Files;
@@ -6,7 +23,7 @@
import java.nio.file.Paths;
import java.util.concurrent.Callable;
-import io.github.applecommander.applesingle.AppleSingle;
+import org.applecommander.applesingle.AppleSingle;
import picocli.CommandLine.Command;
import picocli.CommandLine.Help.Visibility;
import picocli.CommandLine.Option;
diff --git a/tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/FilterCommand.java b/tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/FilterCommand.java
similarity index 84%
rename from tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/FilterCommand.java
rename to tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/FilterCommand.java
index b80a0d2..30abb54 100644
--- a/tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/FilterCommand.java
+++ b/tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/FilterCommand.java
@@ -1,4 +1,21 @@
-package io.github.applecommander.applesingle.tools.asu;
+/*
+ * AppleSingle - A Java library and command-line tool for AppleSingle support.
+ * Copyright (C) 2026 Robert Greene
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.applecommander.applesingle.tools.asu;
import java.io.IOException;
import java.io.OutputStream;
@@ -15,9 +32,9 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;
-import io.github.applecommander.applesingle.AppleSingle;
-import io.github.applecommander.applesingle.Entry;
-import io.github.applecommander.applesingle.EntryType;
+import org.applecommander.applesingle.AppleSingle;
+import org.applecommander.applesingle.Entry;
+import org.applecommander.applesingle.EntryType;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;
diff --git a/tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/ForkType.java b/tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/ForkType.java
new file mode 100644
index 0000000..0ed6e82
--- /dev/null
+++ b/tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/ForkType.java
@@ -0,0 +1,25 @@
+/*
+ * AppleSingle - A Java library and command-line tool for AppleSingle support.
+ * Copyright (C) 2026 Robert Greene
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.applecommander.applesingle.tools.asu;
+
+/**
+ * Basic listing of fork types used in the command line tools.
+ */
+public enum ForkType {
+ data, resource, both
+}
diff --git a/tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/HexDumper.java b/tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/HexDumper.java
similarity index 66%
rename from tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/HexDumper.java
rename to tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/HexDumper.java
index ee7c8cb..1713fd6 100644
--- a/tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/HexDumper.java
+++ b/tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/HexDumper.java
@@ -1,4 +1,21 @@
-package io.github.applecommander.applesingle.tools.asu;
+/*
+ * AppleSingle - A Java library and command-line tool for AppleSingle support.
+ * Copyright (C) 2026 Robert Greene
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.applecommander.applesingle.tools.asu;
import java.io.PrintStream;
import java.util.Arrays;
diff --git a/tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/InfoCommand.java b/tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/InfoCommand.java
similarity index 71%
rename from tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/InfoCommand.java
rename to tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/InfoCommand.java
index f2f76c1..7f42e61 100644
--- a/tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/InfoCommand.java
+++ b/tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/InfoCommand.java
@@ -1,13 +1,30 @@
-package io.github.applecommander.applesingle.tools.asu;
+/*
+ * AppleSingle - A Java library and command-line tool for AppleSingle support.
+ * Copyright (C) 2026 Robert Greene
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.applecommander.applesingle.tools.asu;
import java.io.File;
import java.io.IOException;
import java.util.Optional;
import java.util.concurrent.Callable;
-import io.github.applecommander.applesingle.AppleSingle;
-import io.github.applecommander.applesingle.FileDatesInfo;
-import io.github.applecommander.applesingle.ProdosFileInfo;
+import org.applecommander.applesingle.AppleSingle;
+import org.applecommander.applesingle.FileDatesInfo;
+import org.applecommander.applesingle.ProdosFileInfo;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;
diff --git a/tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/IntRange.java b/tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/IntRange.java
similarity index 66%
rename from tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/IntRange.java
rename to tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/IntRange.java
index ea2a488..7dd67d9 100644
--- a/tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/IntRange.java
+++ b/tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/IntRange.java
@@ -1,4 +1,21 @@
-package io.github.applecommander.applesingle.tools.asu;
+/*
+ * AppleSingle - A Java library and command-line tool for AppleSingle support.
+ * Copyright (C) 2026 Robert Greene
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.applecommander.applesingle.tools.asu;
import java.util.List;
import java.util.Optional;
diff --git a/tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/IntegerTypeConverter.java b/tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/IntegerTypeConverter.java
new file mode 100644
index 0000000..c30b363
--- /dev/null
+++ b/tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/IntegerTypeConverter.java
@@ -0,0 +1,36 @@
+/*
+ * AppleSingle - A Java library and command-line tool for AppleSingle support.
+ * Copyright (C) 2026 Robert Greene
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.applecommander.applesingle.tools.asu;
+
+import picocli.CommandLine.ITypeConverter;
+
+/** Add support for "$801" and "0x801" instead of just decimal like 2049. */
+public class IntegerTypeConverter implements ITypeConverter {
+ @Override
+ public Integer convert(String value) {
+ if (value == null) {
+ return null;
+ } else if (value.startsWith("$")) {
+ return Integer.valueOf(value.substring(1), 16);
+ } else if (value.startsWith("0x") || value.startsWith("0X")) {
+ return Integer.valueOf(value.substring(2), 16);
+ } else {
+ return Integer.valueOf(value);
+ }
+ }
+}
diff --git a/tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/Main.java b/tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/Main.java
similarity index 62%
rename from tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/Main.java
rename to tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/Main.java
index da70f4f..2d71119 100644
--- a/tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/Main.java
+++ b/tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/Main.java
@@ -1,4 +1,21 @@
-package io.github.applecommander.applesingle.tools.asu;
+/*
+ * AppleSingle - A Java library and command-line tool for AppleSingle support.
+ * Copyright (C) 2026 Robert Greene
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.applecommander.applesingle.tools.asu;
import java.util.Optional;
diff --git a/tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/NullOutputStream.java b/tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/NullOutputStream.java
new file mode 100644
index 0000000..327bda2
--- /dev/null
+++ b/tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/NullOutputStream.java
@@ -0,0 +1,33 @@
+/*
+ * AppleSingle - A Java library and command-line tool for AppleSingle support.
+ * Copyright (C) 2026 Robert Greene
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.applecommander.applesingle.tools.asu;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/** An OutputStream that doesn't do output. */
+public class NullOutputStream extends OutputStream {
+ public static final NullOutputStream INSTANCE = new NullOutputStream();
+
+ private NullOutputStream() { /* Prevent construction */ }
+
+ @Override
+ public void write(int b) throws IOException {
+ // Do Nothing
+ }
+}
diff --git a/tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/ProdosFileTypeConverter.java b/tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/ProdosFileTypeConverter.java
similarity index 50%
rename from tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/ProdosFileTypeConverter.java
rename to tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/ProdosFileTypeConverter.java
index 44ccd84..6559943 100644
--- a/tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/ProdosFileTypeConverter.java
+++ b/tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/ProdosFileTypeConverter.java
@@ -1,4 +1,21 @@
-package io.github.applecommander.applesingle.tools.asu;
+/*
+ * AppleSingle - A Java library and command-line tool for AppleSingle support.
+ * Copyright (C) 2026 Robert Greene
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.applecommander.applesingle.tools.asu;
import java.util.HashMap;
import java.util.Map;
diff --git a/tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/VersionProvider.java b/tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/VersionProvider.java
new file mode 100644
index 0000000..f069594
--- /dev/null
+++ b/tools/asu/src/main/java/org/applecommander/applesingle/tools/asu/VersionProvider.java
@@ -0,0 +1,31 @@
+/*
+ * AppleSingle - A Java library and command-line tool for AppleSingle support.
+ * Copyright (C) 2026 Robert Greene
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.applecommander.applesingle.tools.asu;
+
+import org.applecommander.applesingle.AppleSingle;
+import picocli.CommandLine.IVersionProvider;
+
+/** Display version information. Note that this is dependent on the Spring Boot Gradle plugin configuration. */
+public class VersionProvider implements IVersionProvider {
+ public String[] getVersion() {
+ return new String[] {
+ String.format("CLI: %s", Main.class.getPackage().getImplementationVersion()),
+ String.format("API: %s", AppleSingle.VERSION)
+ };
+ }
+}
\ No newline at end of file
diff --git a/tools/asu/src/main/resources/META-INF/native-image/reflect-config.json b/tools/asu/src/main/resources/META-INF/native-image/reflect-config.json
index e037f39..afef808 100644
--- a/tools/asu/src/main/resources/META-INF/native-image/reflect-config.json
+++ b/tools/asu/src/main/resources/META-INF/native-image/reflect-config.json
@@ -6,7 +6,7 @@
"name": "groovy.lang.Closure"
},
{
- "name": "io.github.applecommander.applesingle.tools.asu.AnalyzeCommand",
+ "name": "org.applecommander.applesingle.tools.asu.AnalyzeCommand",
"allDeclaredFields": true,
"queryAllDeclaredMethods": true,
"methods": [
@@ -17,7 +17,7 @@
]
},
{
- "name": "io.github.applecommander.applesingle.tools.asu.CreateCommand",
+ "name": "org.applecommander.applesingle.tools.asu.CreateCommand",
"allDeclaredFields": true,
"queryAllDeclaredMethods": true,
"methods": [
@@ -28,7 +28,7 @@
]
},
{
- "name": "io.github.applecommander.applesingle.tools.asu.EditCommand",
+ "name": "org.applecommander.applesingle.tools.asu.EditCommand",
"allDeclaredFields": true,
"queryAllDeclaredMethods": true,
"methods": [
@@ -39,7 +39,7 @@
]
},
{
- "name": "io.github.applecommander.applesingle.tools.asu.ExtractCommand",
+ "name": "org.applecommander.applesingle.tools.asu.ExtractCommand",
"allDeclaredFields": true,
"queryAllDeclaredMethods": true,
"methods": [
@@ -50,7 +50,7 @@
]
},
{
- "name": "io.github.applecommander.applesingle.tools.asu.FilterCommand",
+ "name": "org.applecommander.applesingle.tools.asu.FilterCommand",
"allDeclaredFields": true,
"queryAllDeclaredMethods": true,
"methods": [
@@ -61,7 +61,7 @@
]
},
{
- "name": "io.github.applecommander.applesingle.tools.asu.InfoCommand",
+ "name": "org.applecommander.applesingle.tools.asu.InfoCommand",
"allDeclaredFields": true,
"queryAllDeclaredMethods": true,
"methods": [
@@ -72,7 +72,7 @@
]
},
{
- "name": "io.github.applecommander.applesingle.tools.asu.IntegerTypeConverter",
+ "name": "org.applecommander.applesingle.tools.asu.IntegerTypeConverter",
"methods": [
{
"name": "",
@@ -81,7 +81,7 @@
]
},
{
- "name": "io.github.applecommander.applesingle.tools.asu.Main",
+ "name": "org.applecommander.applesingle.tools.asu.Main",
"allDeclaredFields": true,
"queryAllDeclaredMethods": true,
"methods": [
@@ -94,7 +94,7 @@
]
},
{
- "name": "io.github.applecommander.applesingle.tools.asu.ProdosFileTypeConverter",
+ "name": "org.applecommander.applesingle.tools.asu.ProdosFileTypeConverter",
"methods": [
{
"name": "",
@@ -103,7 +103,7 @@
]
},
{
- "name": "io.github.applecommander.applesingle.tools.asu.VersionProvider",
+ "name": "org.applecommander.applesingle.tools.asu.VersionProvider",
"allDeclaredFields": true,
"queryAllDeclaredMethods": true,
"methods": [