diff --git a/CHANGELOG.md b/CHANGELOG.md index 311f22f..9c83980 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,30 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). Nothing yet. +## [1.2.0] - 2026-10-13 + +Dependency and toolchain refresh, a quieter dependency-update report, and the +Gradle configuration cache turned on. No runtime behavior, challenge content, +or public DSL has changed. + +### Added +- Makefile `versions-all` target: the dependency-updates plugin's full plain report, up-to-date dependencies included. +- `org.gradle.jvmargs` in `gradle.properties`: a 4 GB heap for the Gradle and Kotlin daemons, a heap dump on out-of-memory, and UTF-8 file encoding. + +### Changed +- `make versions` now prints only the dependencies with newer versions, those that could not be checked, and any Gradle update, via a custom `outputFormatter` in `build.gradle.kts`. Its help text no longer calls it the default target (`help` is). +- Turned on the Gradle configuration cache (`org.gradle.configuration-cache=true`). `dependencyUpdates` stays marked incompatible, and `make versions` / `make versions-all` skip the cache for that one task. +- Upgraded the Gradle wrapper from 9.7.1 to 9.8.1. +- Bumped dependencies: Kotlin → 2.4.21, `readingbat-core` → 3.5.0, `common-utils` → 5.1.1. +- Bumped build plugins: versions plugin → 0.66.0. +- The Gradle wrapper jar and `gradlew.bat` were regenerated as part of the wrapper upgrade. + +### Documentation +- Listed `make versions` and `make versions-all` in `README.md` and `llms.txt`. + +### Upgrade notes +- `common-utils` crossed two major versions (3.2.2 → 5.1.1) during this cycle. The project uses only `GitHubRepo`, `FileSystemSource`, and `OwnerType` from it; the build and full test suite pass against the new version, but treat it as the highest-risk item if you pin transitively. + ## [1.1.0] - 2026-09-21 Dependency and toolchain refresh, plus line-ending normalization. No runtime @@ -94,7 +118,8 @@ are less complete than later ones. Structured changelog tracking begins with - `andor7` function name mismatch, and the unregistered `front_back` challenge. - Several incorrect challenge return types. -[Unreleased]: https://github.com/readingbat/readingbat-python-content/compare/1.1.0...master +[Unreleased]: https://github.com/readingbat/readingbat-python-content/compare/1.2.0...master +[1.2.0]: https://github.com/readingbat/readingbat-python-content/compare/1.1.0...1.2.0 [1.1.0]: https://github.com/readingbat/readingbat-python-content/compare/1.0.1...1.1.0 [1.0.1]: https://github.com/readingbat/readingbat-python-content/compare/1.0.0...1.0.1 [1.0.0]: https://github.com/readingbat/readingbat-python-content/commits/1.0.0 diff --git a/Makefile b/Makefile index 3bc01f7..8056830 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ .PHONY: default help clean build lint format detekt detekt-baseline tests uberjar uber \ - cc run versions upgrade-wrapper _require-gradle-version + cc run versions versions-all upgrade-wrapper _require-gradle-version GRADLE_VERSION := $(shell sed -n 's/^gradle-wrapper = "\(.*\)"/\1/p' gradle/libs.versions.toml) @@ -42,9 +42,16 @@ cc: ## Continuous compilation (no tests) run: ## Start the server on port 8080 ./gradlew run -versions: ## Check for dependency updates (default target) +# dependencyUpdates is marked incompatible with the configuration cache (build.gradle.kts), so a run with the cache on +# builds an entry only to discard it, and says so. --no-configuration-cache skips the cache for this run instead. +# build.gradle.kts gives the task a formatter that lists only what is behind; versions-all names the plugin's own plain +# report, which also lists everything up to date. +versions: ## List the dependencies with newer versions, and any that could not be checked ./gradlew dependencyUpdates --no-configuration-cache --no-parallel +versions-all: ## The plugin's full dependency report, up-to-date dependencies included + ./gradlew dependencyUpdates --no-configuration-cache --no-parallel --output-formatter=plain + upgrade-wrapper: _require-gradle-version ## Upgrade the Gradle wrapper to the catalog version # Gradle's documented upgrade procedure: the first run rewrites # gradle-wrapper.properties using the *old* wrapper jar; the second run diff --git a/README.md b/README.md index 40d47e3..2a51575 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ make lint # Run kotlinter + detekt make format # Format Kotlin sources make cc # Continuous compilation while you edit make uber # Build and run the fat jar +make versions # List dependencies with newer versions (versions-all: full report) ``` ## Adding a Challenge diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index ee67873..66d1ce3 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,5 +1,55 @@ # Release Notes +## 1.2.0 — dependency refresh and a quieter update report + +A maintenance release: current versions of the build toolchain and runtime +dependencies, a dependency-update report that lists only what is behind, and +the Gradle configuration cache turned on. No runtime behavior, challenge +content, or public DSL has changed. + +### Highlights + +- **`make versions` lists only what is behind.** A custom `outputFormatter` in + `build.gradle.kts` prints one line per dependency with a newer version, a `?` + line for any that could not be checked, and a line for a newer Gradle. When + nothing is behind it prints `All dependencies are up to date`. +- **`make versions-all`.** The plugin's full plain report, which also lists + every dependency that is already up to date. +- **Gradle configuration cache on.** `gradle.properties` now sets + `org.gradle.configuration-cache=true`, and adds `org.gradle.jvmargs` with a + 4 GB heap for the Gradle and Kotlin daemons, a heap dump on out-of-memory, + and UTF-8 file encoding. +- **Gradle wrapper → 9.8.1.** Up from 9.7.1. +- **Dependency upgrades.** Kotlin → 2.4.21, `readingbat-core` → 3.5.0, + `common-utils` → 5.1.1. Ktor (3.6.0), Kotest (6.2.5), and `kotlin-logging` + (8.0.4) are unchanged from 1.1.0. +- **Build plugin upgrades.** versions plugin → 0.66.0. kotlinter (5.7.0) and + detekt (2.0.0-alpha.6) are unchanged. + +### Documentation + +- `README.md` and `llms.txt` list `make versions` and `make versions-all`. + +### Upgrade notes + +- `common-utils` crossed two major versions (3.2.2 → 5.1.1). The project uses + only `GitHubRepo`, `FileSystemSource`, and `OwnerType` from it, and the build + and full test suite pass against the new version. +- The daemons now ask for a 4 GB heap. On a machine with little memory, lower + `-Xmx4g` in `gradle.properties`. +- `dependencyUpdates` is not compatible with the configuration cache, and the + task says so. Run it through `make versions` or `make versions-all`, which + pass `--no-configuration-cache`. +- Run `./gradlew --refresh-dependencies` (or `make build`) once after pulling so + the new plugin and dependency versions resolve. +- The Java 25 toolchain requirement is unchanged. + +### Full diff + +See the [compare view on +GitHub](https://github.com/readingbat/readingbat-python-content/compare/1.1.0...1.2.0) +for the complete set of changes in this release. + ## 1.1.0 — dependency refresh and line-ending normalization A maintenance release: current versions of the build toolchain and runtime diff --git a/build.gradle.kts b/build.gradle.kts index 3d1ba48..aa763d0 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -124,5 +124,23 @@ fun Project.configureVersions() { rejectVersionIf { isNonStable(candidate.version) && !isNonStable(currentVersion) } + + // Prints only what is behind, and what could not be checked. The plugin's own report, + // which `make versions-all` asks for with --output-formatter=plain, also lists every + // dependency that is already up to date. + outputFormatter { + val behind = outdated.dependencies.sortedBy { "${it.group}:${it.name}" } + if (behind.isEmpty()) println("All dependencies are up to date") + behind.forEach { d -> + val latest = with(d.available) { release ?: milestone ?: integration } + println(" - ${d.group}:${d.name} ${d.version} -> $latest") + } + unresolved.dependencies.sortedBy { "${it.group}:${it.name}" }.forEach { + println(" ? ${it.group}:${it.name}:${it.version} could not be checked") + } + if (gradle.current.isUpdateAvailable) { + println(" - Gradle ${gradle.running.version} -> ${gradle.current.version}") + } + } } } diff --git a/gradle.properties b/gradle.properties index ef1db44..07c8afd 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,8 @@ group=com.readingbat -version=1.1.0 +version=1.2.0 kotlin.code.style=official -org.gradle.caching=true -org.gradle.configuration-cache=false org.gradle.daemon=true +org.gradle.caching=true +org.gradle.configuration-cache=true +org.gradle.jvmargs=-Xmx4g -Dkotlin.daemon.jvm.options=-Xmx4g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index faccb44..1254f6d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,15 +1,15 @@ [versions] detekt = "2.0.0-alpha.6" -gradle-wrapper = "9.7.1" +gradle-wrapper = "9.8.1" jvm = "25" kotest = "6.2.5" -kotlin = "2.4.10" +kotlin = "2.4.21" kotlinter = "5.7.0" ktor = "3.6.0" logging = "8.0.4" -readingbat = "3.4.0" -utils = "3.2.2" -versions = "0.64.0" +readingbat = "3.5.0" +utils = "5.1.1" +versions = "0.66.0" [libraries] core-utils = { module = "com.pambrose.common-utils:core-utils", version.ref = "utils" } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index eddabd2..9fa7f28 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 ad7845b..2e7bb9f 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.7.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.8.1-bin.zip networkTimeout=10000 retries=0 retryBackOffMs=500 diff --git a/gradlew.bat b/gradlew.bat index a51ec4f..3185a43 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -26,6 +26,33 @@ @rem Set local scope for the variables, and ensure extensions are enabled setlocal EnableExtensions +@rem Catch executions from older scripts and ensure they exit cleanly. +@rem This can be removed once we can be reasonably confident that few people +@rem will be migrating directly to this new wrapper. +goto afterSafetyNet +:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +goto exitWithErrorLevel +:afterSafetyNet + set DIRNAME=%~dp0 if "%DIRNAME%"=="" set DIRNAME=. @rem This is normally unused @@ -45,13 +72,14 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. 1>&2 -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 -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 +1>&2 echo. +1>&2 echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +1>&2 echo. +1>&2 echo Please set the JAVA_HOME variable in your environment to match the +1>&2 echo location of your Java installation. "%COMSPEC%" /c exit 1 +goto exitWithErrorLevel :findJavaFromJavaHome set JAVA_HOME=%JAVA_HOME:"=% @@ -59,13 +87,14 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. 1>&2 -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 -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 +1>&2 echo. +1>&2 echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +1>&2 echo. +1>&2 echo Please set the JAVA_HOME variable in your environment to match the +1>&2 echo location of your Java installation. "%COMSPEC%" /c exit 1 +goto exitWithErrorLevel :execute @rem Setup the command line @@ -75,8 +104,9 @@ echo location of your Java installation. 1>&2 @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 +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 & goto exitWithErrorLevel +@rem This label must not be changed. We rely on old scripts being able to jump to this point. :exitWithErrorLevel @rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts "%COMSPEC%" /c exit %ERRORLEVEL% diff --git a/llms.txt b/llms.txt index bf8f454..fc963ed 100644 --- a/llms.txt +++ b/llms.txt @@ -38,6 +38,7 @@ Each .py file has: a `# @desc` comment, a function implementing the challenge, a - Continuous build: `make cc` - Lint (kotlinter + detekt): `make lint` - Format Kotlin sources: `make format` +- Dependency updates: `make versions` (only what is behind), `make versions-all` (full report) - JVM toolchain: Java 25 - Testing: Kotest with JUnit5 - Lint/format: kotlinter + detekt, configured via `.editorconfig` and `build.gradle.kts`