diff --git a/CHANGELOG.md b/CHANGELOG.md index 7215d31..1503420 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # CHANGELOG +## Version 1.2.2 (2023-06-03) + - Build improvements [[#106]][106] + - Removes `kotln-components` submodule + - Composite builds via `gradle-kmp-configuration-plugin` + - Adds a Bill of Materials (BOM) + - Updates dependencies + - Kotlin `1.8.0` -> `1.8.21` + - Fixes dropped decoded bytes not being back-filled on resize [[#112]][112] + - Adds static instances with "reasonable" default configurations [[#122]][122] + - Exposes `LineBreakOutFeed` utility class [[#113]][113] && [[#118]][118] + - Adds ability to `flush` an `EncoderDecoder.Feed` [[#114]][114] + ## Version 1.2.1 (2023-01-31) - Fixes `Base32` encoding - Updates `kotlin-components` submodule @@ -98,3 +110,10 @@ ## Version 1.0.0 (2021-10-30) - Initial Release + +[106]: https://github.com/05nelsonm/encoding/pull/106 +[112]: https://github.com/05nelsonm/encoding/pull/112 +[113]: https://github.com/05nelsonm/encoding/pull/113 +[114]: https://github.com/05nelsonm/encoding/pull/114 +[118]: https://github.com/05nelsonm/encoding/pull/118 +[122]: https://github.com/05nelsonm/encoding/pull/122 diff --git a/README.md b/README.md index 25b6945..4cb7420 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,9 @@ val base16 = Base16 { // Shortcuts val base16StrictSettings = Base16(strict = true) val base16DefaultSettings = Base16() + +// Alternatively, use the static instance with its default settings +Base16 ``` ```kotlin @@ -68,8 +71,16 @@ val base32Crockford = Base32Crockford { // Optional data integrity check unique to the Crockford spec checkSymbol('*') + + // Only apply the checkSymbol & reset hyphen interval counter + // when Encoder.Feed.doFinal is called (see builder docs for + // more info) + finalizeWhenFlushed = false } +// Alternatively, use the static instance with its default settings +Base32.Crockford + val base32Default = Base32Default { isLenient = true lineBreakInterval = 64 @@ -79,12 +90,18 @@ val base32Default = Base32Default { padEncoded = false } +// Alternatively, use the static instance with its default settings +Base32.Default + val base32Hex = Base32Hex { isLenient = true lineBreakInterval = 64 encodeToLowercase = false padEncoded = true } + +// Alternatively, use the static instance with its default settings +Base32.Hex ``` ```kotlin @@ -95,11 +112,17 @@ val base64 = Base64 { padEncoded = true } +// Alternatively, use the static instance with its default settings +Base64.Default + // Inherit settings from another EncoderDecoder's Config val base64UrlSafe = Base64(base64.config) { encodeToUrlSafe = true padEncoded = false } + +// Alternatively, use the static instance with its default settings +Base64.UrlSafe ``` **Encoding/Decoding Extension Functions** @@ -113,19 +136,19 @@ val bytes = text.encodeToByteArray() // transformations (can be useful for security // purposes, too, as you are able to clear Arrays // before they are de-referenced). -val encodedString = bytes.encodeToString(base64) -val encodedChars = bytes.encodeToCharArray(base32Default) -val encodedBytes = bytes.encodeToByteArray(base16) +val encodedString = bytes.encodeToString(Base64.Default) +val encodedChars = bytes.encodeToCharArray(Base32.Default) +val encodedBytes = bytes.encodeToByteArray(Base16) val decodedString = try { - encodedString.decodeToByteArray(base64) + encodedString.decodeToByteArray(Base64.Default) } catch (e: EncodingException) { Log.e("Something went terribly wrong", e) null } // Swallow `EncodingException`s by using the `*OrNull` variants -val decodedChars = encodedChars.decodeToByteArrayOrNull(base32Default) -val decodedBytes = encodedBytes.decodeToByteArrayOrNull(base16) +val decodedChars = encodedChars.decodeToByteArrayOrNull(Base32.Default) +val decodedBytes = encodedBytes.decodeToByteArrayOrNull(Base16) ``` **Encoding/Decoding `Feed`(s) (i.e. Streaming)** @@ -138,13 +161,33 @@ care about `Byte`(s) and `Char`(s)! `Feed`s are currently annotated with `ExperimentalEncodingApi` and require an `OptIn` to use directly. +```kotlin +// e.g. Concatenate multiple encodings +val sb = StringBuilder() + +// Use our own line break out feed in order to add a delimiter between +// encodings and preserve the counter. +val out = LineBreakOutFeed(interval = 64) { char -> sb.append(char) } + +@OptIn(ExperimentalEncodingApi::class) +Base64.Default.newEncoderFeed(out).use { feed -> + "Hello World 1!".forEach { c -> feed.consume(c.code.toByte()) } + feed.flush() + out.output('.') + "Hello World 2!".forEach { c -> feed.consume(c.code.toByte()) } +} + +println(sb.toString()) +// SGVsbG8gV29ybGQgMSE=.SGVsbG8gV29ybGQgMiE= +``` + ```kotlin // e.g. Writing encoded data to a File in Java. // NOTE: try/catch omitted for this example. @OptIn(ExperimentalEncodingApi::class) file.outputStream().use { oStream -> - base64.newEncoderFeed { encodedChar -> + Base64.Default.newEncoderFeed { encodedChar -> // As encoded data comes out of the feed, // write it to the file. oStream.write(encodedChar.code) @@ -179,7 +222,7 @@ FeatureRequests are **always** welcome)! // Pre-calculate the output size for the given encoding // spec; in this case, Base64. -val size = base64.config.decodeOutMaxSize(file.length()) +val size = Base64.Default.config.decodeOutMaxSize(file.length()) // Since we will be storing the data in a StringBuilder, // we need to check if the output size would exceed @@ -196,7 +239,7 @@ val sb = StringBuilder(size.toInt()) @OptIn(ExperimentalEncodingApi::class) file.inputStream().reader().use { iStreamReader -> - base64.newDecoderFeed { decodedByte -> + Base64.Default.newDecoderFeed { decodedByte -> // As decoded data comes out of the feed, // update the StringBuilder. sb.append(decodedByte.toInt().toChar()) @@ -236,7 +279,7 @@ See [sample project](sample/README.md) ```kotlin // build.gradle.kts dependencies { - val encoding = "1.2.1" + val encoding = "1.2.2" implementation("io.matthewnelson.kotlin-components:encoding-base16:$encoding") implementation("io.matthewnelson.kotlin-components:encoding-base32:$encoding") implementation("io.matthewnelson.kotlin-components:encoding-base64:$encoding") @@ -247,14 +290,13 @@ dependencies { ``` - -[badge-latest-release]: https://img.shields.io/badge/latest--release-1.2.1-blue.svg?style=flat +[badge-latest-release]: https://img.shields.io/badge/latest--release-1.2.2-blue.svg?style=flat [badge-license]: https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg?style=flat -[badge-kotlin]: https://img.shields.io/badge/kotlin-1.8.0-blue.svg?logo=kotlin +[badge-kotlin]: https://img.shields.io/badge/kotlin-1.8.21-blue.svg?logo=kotlin [badge-platform-android]: http://img.shields.io/badge/-android-6EDB8D.svg?style=flat diff --git a/RELEASING.md b/RELEASING.md index ac50725..8d0cf9d 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -31,7 +31,7 @@ git checkout -b release_"$VERSION_NAME" ```bash git add --all git commit -S -m "Prepare $VERSION_NAME release" -git tag -s $VersionName -m "Release v$VERSION_NAME" +git tag -s "$VERSION_NAME" -m "Release v$VERSION_NAME" ``` - Make sure you have valid credentials in `~/.gradle/gradle.properties` @@ -75,21 +75,26 @@ ykman openpgp keys set-touch sig off git push -u origin release_"$VERSION_NAME" ``` -### Macos +### macOS - Spin up VM of macOS and ensure USB pass through worked for the YubiKey - - Should ask for PIN to log in + - Should ask for PIN to log in - Sign a random `.txt` file (gpg tty for YubiKey PIN + gradle build don't mix) -```bash +```shell gpg --sign --armor --detach ~/Documents/hello.txt ``` - Ensure java version is greater than or equal to 11 -```bash +```shell java --version ``` +- Ensure you are in a `bash` shell +```shell +bash +``` + - Set version variable in terminal shell ```bash VERSION_NAME="" @@ -131,17 +136,14 @@ PUBLISH_TASKS=$(./gradlew tasks -PKMP_TARGETS="$MACOS_TARGETS" | cut -d ' ' -f 1 | grep -e "publishIos" -e "publishMacos" -e "publishTvos" -e "publishWatchos" ) -./gradlew $PUBLISH_TASKS -PKMP_TARGETS="$MACOS_TARGETS" +./gradlew $PUBLISH_TASKS --no-daemon --no-parallel -PKMP_TARGETS="$MACOS_TARGETS" ``` ### Linux -- Re-enable YubiKey touch for signing -```bash -ykman openpgp keys set-touch sig on -``` - -- Close publications (Don't release yet) +- The [gradle-maven-publish-plugin](https://github.com/vanniktech/gradle-maven-publish-plugin) should have automatically + closed the staged repositories, but if it did not: + - Close publications (Don't release yet) - Login to Sonatype OSS Nexus: [oss.sonatype.org](https://s01.oss.sonatype.org/#stagingRepositories) - Click on **Staging Repositories** - Select all Publications @@ -150,11 +152,43 @@ ykman openpgp keys set-touch sig on - Check Publication ```bash -./gradlew clean -DKMP_TARGETS_ALL +./gradlew clean -PCHECK_PUBLICATION -DKMP_TARGETS_ALL +./gradlew :tools:check-publication:build --refresh-dependencies -PCHECK_PUBLICATION -DKMP_TARGETS_ALL +``` + +### macOS + +- Check Publication +```bash +./gradlew clean -PCHECK_PUBLICATION -DKMP_TARGETS_ALL ./gradlew :tools:check-publication:build --refresh-dependencies -PCHECK_PUBLICATION -DKMP_TARGETS_ALL ``` +### Linux + +- Re-enable YubiKey touch for signing +```bash +ykman openpgp keys set-touch sig on +``` + - **Release** publications from Sonatype OSS Nexus StagingRepositories manager + - Alternatively, can use Curl with the given repository id's that were output + to terminal when publishing, e.g. `iomatthewnelson-1018` + ```shell + curl -v -u "" \ + -H "Content-Type: application/json" \ + -H "Accept: application/json" \ + https://s01.oss.sonatype.org/service/local/staging/bulk/promote --data ' + { + "data": { + "stagedRepositoryIds": [ + "iomatthewnelson-", + "iomatthewnelson-" + ], + "autoDropAfterRelease": true + } + }' + ``` - Merge release branch to `master` ```bash @@ -207,5 +241,5 @@ git branch -D release_"$VERSION_NAME" - Wait for releases to become available on [MavenCentral](https://repo1.maven.org/maven2/io/matthewnelson/kotlin-components/) - Draft new release on GitHub - - Enter the release name as tag and title - - Have the description point to the changelog + - Enter the release name as tag and title + - Have the description point to the changelog diff --git a/encoding-bom/gradle.properties b/encoding-bom/gradle.properties index 7a41666..f167560 100644 --- a/encoding-bom/gradle.properties +++ b/encoding-bom/gradle.properties @@ -13,4 +13,4 @@ # limitations under the License. POM_ARTIFACT_ID=encoding-bom POM_NAME=encoding-bom -POM_DESCRIPTION=Bill of materials for encoding library +POM_DESCRIPTION=Bill of Materials for encoding library artifacts diff --git a/gradle.properties b/gradle.properties index 64272c7..638f66f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -29,7 +29,7 @@ POM_DEVELOPER_ID=05nelsonm POM_DEVELOPER_NAME=Matthew Nelson POM_DEVELOPER_URL=https://github.com/05nelsonm/ -VERSION_NAME=1.2.2-SNAPSHOT +VERSION_NAME=1.2.2 # 0.1.0-alpha01 = 00 01 00 11 # 0.1.0-beta01 = 00 01 00 21 # 0.1.0-rc01 = 00 01 00 31