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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.9.1] - 2026-08-01

### Changed

- Bumped dependencies: `readingbat-core` / `readingbat-kotest` 3.3.0 → 3.3.1, `core-utils` 3.2.1 → 3.2.2, and the ben-manes versions plugin 0.54.0 → 0.57.0.
- Moved the ben-manes versions plugin to its current published coordinate: `com.github.ben-manes.versions` → `io.github.ben-manes.versions`. The catalog alias stays `ben-manes-versions`, so the `alias(libs.plugins.ben.manes.versions)` call site in `build.gradle.kts` and the `./gradlew dependencyUpdates` / `make versions` commands are unchanged.
- Trimmed `CLAUDE.md` from 89 lines to 31, removing guidance a session can reconstruct from the repo itself: the build-command list (mirrored by the self-documenting `make help`), the architecture tour, the dependency inventory, and the step-by-step CI description. The runtime gotchas (`initTestProperties()`, suspend `correctAnswers()`), build-configuration constraints (`gradle.properties` metadata, `FAIL_ON_PROJECT_REPOS`, configuration cache), pre-push lint etiquette, and DSL conventions remain.

## [1.9.0] - 2026-07-26

### Added
Expand Down Expand Up @@ -98,6 +106,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Upgrades to Kotlin 2.1.0 / Ktor 3.0.1, `readingbat-core` 2.0.0, and various jar refreshes.

[1.9.1]: https://github.com/readingbat/readingbat-template/compare/1.9.0...1.9.1
[1.9.0]: https://github.com/readingbat/readingbat-template/compare/1.8.0...1.9.0
[1.8.0]: https://github.com/readingbat/readingbat-template/compare/1.7.0...1.8.0
[1.7.0]: https://github.com/readingbat/readingbat-template/compare/1.6.0...1.7.0
Expand Down
66 changes: 4 additions & 62 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,86 +1,28 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

ReadingBat Template — a Kotlin/Ktor-based template for teachers to author ReadingBat.com content. ReadingBat is a code-reading practice site (inspired by CodingBat) where students read and trace code rather than write it. Content is defined via a Kotlin DSL supporting Python, Java, and Kotlin challenges.

## Build & Run Commands

- **Build (no tests):** `./gradlew build -xtest` or `make build`
- **Run server:** `./gradlew run` or `make run`
- **Run all tests:** `./gradlew --rerun-tasks check` or `make tests`
- **Run a single test class:** `./gradlew test --tests "ContentTests"`
- **Run a single test:** `./gradlew test --tests "ContentTests.Test all challenges"`
- **Build fat JAR:** `./gradlew buildFatJar` or `make uberjar` (outputs `build/libs/server.jar`)
- **Lint (kotlinter + detekt):** `make lint`
- **Auto-format (ktlint):** `make format`
- **Run detekt only:** `make detekt`
- **Regenerate detekt baseline:** `make detekt-baseline`
- **Check dependency updates:** `./gradlew dependencyUpdates` (default Make target)
- **Continuous compile:** `make cc` (rebuilds on file changes, skips tests)
- **Discover Makefile targets:** `make help` (renders self-documented `## …` descriptions)

## Architecture

### Content Definition (DSL)

`src/main/kotlin/Content.kt` — the central file defining all challenge content using the `readingBatContent` DSL. The DSL hierarchy is:
- `readingBatContent` → `python {}` / `java {}` / `kotlin {}` (LanguageGroup)
- → `group("Name") {}` (ChallengeGroup)
- → `challenge("Name") {}` (individual Challenge)
- → `includeFiles` / `includeFilesWithType` (glob-based bulk import)

The `repo` property switches between `GitHubRepo` (production) and `FileSystemSource` (local dev) based on `isProduction()`.

### Challenge Source Files

Challenge code lives outside the Kotlin source tree in language-specific directories:
- **Python:** `python/<packageName>/` (e.g., `python/group1/find_it.py`)
- **Java:** `src/main/java/<packageName>/` (e.g., `src/main/java/group1/JoinEnds.java`)
- **Kotlin:** `src/main/kotlin/<packageName>/` (e.g., `src/main/kotlin/kgroup/StringLambda1.kt`)

### Server

`src/main/kotlin/ContentServer.kt` — minimal entry point that delegates to `ReadingBatServer.start()` from the `readingbat-core` library. Server configuration is in `src/main/resources/application.conf` (HOCON format) — controls port (default 8080), production mode, DBMS, content caching, script pool sizes, and Ktor watch mode for hot reload during development.

### Testing

`src/test/kotlin/ContentTests.kt` — uses Kotest (StringSpec style with `init {}` block) and Ktor's `testApplication`. Tests use the `readingbat-kotest` library's `TestSupport` helpers to verify challenges accept correct answers and reject incorrect ones. The test framework iterates over all languages/groups/challenges automatically.
## Testing

**Important:** Tests must call `initTestProperties()` before accessing `content` (e.g., via `beforeEach`). This sets `IS_PRODUCTION=false` and `IS_TESTING=true` in the `KtorProperty` config store — without it, `isProduction()` in `Content.kt` will throw `Property IS_PRODUCTION not initialized`.

As of readingbat-core 3.2.0, `correctAnswers` is a suspend function — call it as `correctAnswers()` and wrap answer assertions in `runBlocking { … }` (see `ContentTests.kt`).

## Key Dependencies

Managed in `gradle/libs.versions.toml`:
- `readingbat-core` / `readingbat-kotest` — core DSL, server, and test framework (Maven Central)
- Ktor — web server framework
- Kotest — test framework (JUnit5 runner)
- `jvm` and `gradle-wrapper` versions are also tracked in the catalog. `build.gradle.kts` reads `libs.versions.jvm.get().toInt()` for the toolchain; the `Makefile` reads `gradle-wrapper` from the catalog for `upgrade-wrapper`.

Test dependencies are exposed as a `[bundles] testing` entry and consumed in `build.gradle.kts` via `libs.bundles.testing`.
## Build Configuration

`group` and `version` live in `gradle.properties` (not `build.gradle.kts`). Repository configuration lives in `settings.gradle.kts` with `FAIL_ON_PROJECT_REPOS` enforcement — do not add per-project repositories to `build.gradle.kts`.

Fat-jar output (`build/libs/server.jar`) is configured via the `ktor { fatJar { archiveFileName = ... } }` block; `tasks.shadowJar` only carries signature excludes (`META-INF/*.SF`, `*.DSA`, `*.RSA`) and uses `DuplicatesStrategy.WARN` so duplicate-resource collisions surface in build output. Build it with `./gradlew buildFatJar` (or `make uberjar`).

## Code Style & Linting

- `.editorconfig` defines project-wide formatting (UTF-8, LF, 2-space indent, 120-char max, final newline) and disables a curated set of ktlint rules that conflict with this codebase's style.
- Kotlinter (ktlint) and detekt are wired in via Gradle plugins (`org.jmailen.kotlinter` and `dev.detekt`). Run them together with `make lint`; auto-fix ktlint with `make format`.
- Gradle's configuration cache is enabled (`org.gradle.configuration-cache=true` in `gradle.properties`) — keep new build logic configuration-cache-compatible.
Gradle's configuration cache is enabled (`org.gradle.configuration-cache=true` in `gradle.properties`) — keep new build logic configuration-cache-compatible.

## Continuous Integration

`.github/workflows/ci.yml` runs on pushes and pull requests targeting `master`. It installs Temurin JDK 25, sets up Gradle, then runs two steps:

1. `./gradlew --rerun-tasks check`
2. `./gradlew lintKotlin detekt`

Both must pass, so run `make tests` and `make lint` locally before pushing — a formatting violation fails CI just as a test failure does.
Run `make tests` and `make lint` locally before pushing — a formatting violation fails CI just as a test failure does.

## DSL Conventions

Expand Down
44 changes: 44 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,49 @@
# Release Notes

## v1.9.1 — 2026-08-01

A patch release on top of 1.9.0: a dependency refresh, a build-plugin coordinate fix, and a `CLAUDE.md` trim. There are no DSL, content, or runtime source changes — existing `Content.kt` definitions compile and run unchanged, and the build still targets **JDK 25**.

### Highlights

- **readingbat-core / readingbat-kotest 3.3.0 → 3.3.1.** A patch bump; no call-site changes were required. `correctAnswers()` remains a suspend function, as it has since 3.2.0.
- **core-utils 3.2.1 → 3.2.2.** A patch bump on the 3.x line adopted in 1.9.0. The template's four call sites — `FileSystemSource`, `GitHubRepo`, and `OwnerType.Organization` in `Content.kt`, plus `toDoubleQuoted` in `ContentTests.kt` — compile unchanged.
- **ben-manes versions plugin 0.54.0 → 0.57.0, with a coordinate move.** The plugin's published ID changed from `com.github.ben-manes.versions` to `io.github.ben-manes.versions`; `gradle/libs.versions.toml` now points at the new ID. The catalog alias stays `ben-manes-versions`, so `alias(libs.plugins.ben.manes.versions)` in `build.gradle.kts` is untouched and `./gradlew dependencyUpdates` / `make versions` behave exactly as before.
- **`CLAUDE.md` trimmed 89 → 31 lines.** Removed the guidance a session can reconstruct from the repo itself — the build-command list (already surfaced by the self-documenting `make help`), the architecture tour, the dependency inventory, and the step-by-step CI description. What stays is the material the code can't teach: the `initTestProperties()` and suspend-`correctAnswers()` runtime gotchas, the `gradle.properties` / `FAIL_ON_PROJECT_REPOS` / configuration-cache build constraints, the pre-push lint etiquette, and the DSL conventions.

### Dependencies

| Library | Version |
|------------------|---------------|
| Kotlin | 2.4.10 |
| Ktor | 3.5.1 |
| Kotest | 6.2.3 |
| readingbat-core | 3.3.1 |
| core-utils | 3.2.2 |
| kotlin-logging | 8.0.4 |
| detekt | 2.0.0-alpha.5 |
| kotlinter | 5.6.0 |
| Gradle | 9.6.1 |
| JDK toolchain | 25 |

### Upgrade Notes

- No source changes are required for forks that track this template — this release touches only `gradle/libs.versions.toml`, `gradle.properties`, `CLAUDE.md`, and the release docs.
- **Forks that declare the ben-manes versions plugin themselves must update the coordinate** from `com.github.ben-manes.versions` to `io.github.ben-manes.versions`. Forks that consume it through this repo's catalog alias need no change.
- JDK 25 remains required, unchanged from 1.8.0.

### Verification

- `./gradlew --rerun-tasks check` — BUILD SUCCESSFUL; all three `ContentTests` specs pass (`Test all challenges`, `Test with correct answers`, `Test individual challenges`), 3 tests, 0 failures, 0 errors.
- `./gradlew buildFatJar` — BUILD SUCCESSFUL; produces `build/libs/server.jar`.
- `./gradlew lintKotlin detekt` — both checks run cleanly.
- `./gradlew dependencyUpdates` — BUILD SUCCESSFUL under the new plugin coordinate, confirming the ID move resolves.
- `build/libs/readingbat-template-1.9.1.jar` confirms the `gradle.properties` version bump took effect.

**Full Changelog:** https://github.com/readingbat/readingbat-template/compare/1.9.0...1.9.1

---

## v1.9.0 — 2026-07-26

A dependency-refresh and CI release on top of 1.8.0. There are no DSL, content, or runtime source changes — existing `Content.kt` definitions compile and run unchanged, and the build still targets **JDK 25**.
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
group=com.readingbat
version=1.9.0
version=1.9.1

kotlin.code.style=official
org.gradle.caching=true
Expand Down
6 changes: 4 additions & 2 deletions llms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,7 @@ The repo property in Content.kt switches between GitHubRepo (production, reads f
- Static analysis: detekt (`dev.detekt`) and Kotlinter / ktlint (`org.jmailen.kotlinter`)
- CI: GitHub Actions (.github/workflows/ci.yml) on pushes and PRs to master
- Deployment: Runnable fat JAR via the Ktor plugin's buildFatJar task (build/libs/server.jar)
- readingbat-core: 3.3.0
- Current version: 1.9.0
- Dependency updates: ben-manes versions plugin (`io.github.ben-manes.versions`), via `./gradlew dependencyUpdates` or `make versions`
- readingbat-core: 3.3.1
- core-utils: 3.2.2
- Current version: 1.9.1
Loading