Skip to content

Commit 4ba22c3

Browse files
brunoborgesCopilot
andcommitted
Update copilot-instructions.md with current conventions
Reflect YAML content format, 14 locales, proof files, JDK filter ranges, and practical i18n rules. Remove outdated examples. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent af36774 commit 4ba22c3

File tree

1 file changed

+83
-169
lines changed

1 file changed

+83
-169
lines changed

.github/copilot-instructions.md

Lines changed: 83 additions & 169 deletions
Original file line numberDiff line numberDiff line change
@@ -1,192 +1,106 @@
11
# Copilot Instructions for java.evolved
22

3-
## Project Overview
3+
## Build & Serve
44

5-
This is a static site showcasing modern Java patterns vs legacy approaches.
6-
It is hosted on GitHub Pages at https://javaevolved.github.io.
5+
```bash
6+
jbang html-generators/generate.java # Rebuild all locales
7+
jbang html-generators/generate.java --locale es # Rebuild single locale
8+
jwebserver -b 0.0.0.0 -d site -p 8090 # Serve locally
9+
```
10+
11+
Requires **Java 25+** and **JBang**. No npm, Maven, or Gradle.
12+
13+
**Validation:** There is no test suite. Validate changes by running the generator and confirming it completes without errors. The `proof/` directory contains one JBang script per pattern that proves the modern code compiles:
14+
15+
```bash
16+
jbang proof/language/TypeInferenceWithVar.java # Run single proof
17+
```
718

819
## Architecture
920

10-
### Source of Truth: JSON Files
21+
Static site generator: YAML content → JBang generator → HTML pages.
1122

12-
Each pattern is defined as a JSON file under **`content/category/`**:
23+
- **`content/`** — Source of truth. One YAML/JSON file per pattern, organized by category.
24+
- **`templates/`** — HTML templates with `{{placeholder}}` tokens. The generator replaces tokens with content fields and UI strings.
25+
- **`html-generators/generate.java`** — JBang script that reads content + translations + templates and produces all HTML under `site/`.
26+
- **`site/app.js`** and **`site/styles.css`** — Manually maintained client-side code (vanilla JS, no frameworks).
27+
- **`translations/strings/{locale}.yaml`** — UI string translations (labels, nav, footer). Tokens use dotted keys: `{{nav.allPatterns}}`.
28+
- **`translations/content/{locale}/`** — Partial content translations (only translatable fields; structural data always comes from English source).
29+
- **`proof/{category}/{PascalCaseSlug}.java`** — JBang scripts proving each pattern's modern code compiles on Java 25.
1330

14-
```
15-
content/language/type-inference-with-var.json
16-
content/collections/immutable-list-creation.json
17-
content/streams/stream-tolist.json
18-
...
19-
```
31+
### Generated files — DO NOT EDIT directly
2032

21-
**Categories:** `language`, `collections`, `strings`, `streams`, `concurrency`, `io`, `errors`, `datetime`, `security`, `tooling`, `enterprise`
33+
Everything under `site/` except `app.js` and `styles.css` is generated:
34+
- `site/index.html`, `site/{category}/*.html`, `site/data/snippets.json`
35+
- `site/{locale}/index.html`, `site/{locale}/{category}/*.html`, `site/{locale}/data/snippets.json`
2236

23-
### Generated Files (DO NOT EDIT)
37+
Run the generator to rebuild after any content, template, or translation change.
2438

25-
The following are **generated by `html-generators/generate.java`** and must not be edited directly:
39+
## Content Schema
2640

27-
- `site/index.html` — English homepage with preview cards (generated from `templates/index.html`)
28-
- `site/language/*.html`, `site/collections/*.html`, etc. — English detail pages
29-
- `site/data/snippets.json` — English aggregated search index
30-
- `site/{locale}/index.html` — localized homepage (e.g., `site/es/index.html`)
31-
- `site/{locale}/language/*.html`, etc. — localized detail pages
32-
- `site/{locale}/data/snippets.json` — localized search index
41+
Content files are YAML (preferred) or JSON under `content/{category}/{slug}.yaml`. The generator auto-detects format by extension (`.yaml`, `.yml`, `.json`).
3342

34-
Run `jbang html-generators/generate.java` to rebuild all generated files from the JSON sources and translations.
43+
### Required fields
3544

36-
### Manually Maintained Files
45+
| Field | Constraint |
46+
|-------|-----------|
47+
| `slug` | Must match filename (without extension) |
48+
| `category` | Must match parent folder name |
49+
| `whyModernWins` | Exactly **3** entries, each with `icon`, `title`, `desc` |
50+
| `related` | Exactly **3** entries as `category/slug` paths (cross-category OK) |
51+
| `docs` | At least **1** entry with `title` and `href` |
52+
| `prev` / `next` | `category/slug` path or `null` for first/last in the global chain |
53+
| `jdkVersion` | The JDK version where the feature became **final** (not preview) |
54+
| `difficulty` | One of: `beginner`, `intermediate`, `advanced` |
55+
| `support.state` | One of: `available`, `preview`, `experimental` |
3756

38-
- `site/app.js` — client-side search, filtering, code highlighting, locale detection
39-
- `site/styles.css` — all styling
40-
- `templates/slug-template.html` — HTML template with `{{placeholder}}` tokens (content + UI strings) used by the generator
41-
- `templates/index.html` — homepage template with `{{tipCards}}`, `{{snippetCount}}`, and UI string placeholders
42-
- `templates/index-card.html` — preview card template for the homepage grid
43-
- `html-generators/categories.properties` — category ID → display name mapping
44-
- `html-generators/locales.properties` — supported locales registry (locale=Display name)
45-
- `translations/strings/{locale}.yaml` — UI strings per locale (labels, nav, footer, etc.)
46-
- `translations/content/{locale}/` — translated pattern JSON files (partial, translatable fields only)
57+
### Adding a new pattern
4758

48-
### Project Structure
59+
1. Create `content/{category}/new-slug.yaml` with all required fields (use `content/template.json` as reference).
60+
2. Update `prev`/`next` in the adjacent patterns to maintain the navigation chain.
61+
3. Create `proof/{category}/{PascalCaseSlug}.java` — JBang script wrapping the modern code.
62+
4. Run `jbang html-generators/generate.java` and verify it completes.
63+
5. Translations are optional — the AI translation workflow handles them, or create partial files under `translations/content/{locale}/`.
4964

50-
```
51-
content/ # English content JSON files (source of truth, one per pattern)
52-
translations/ # All i18n artifacts
53-
strings/ # UI strings per locale (en.yaml, es.yaml, pt-BR.yaml)
54-
content/ # Translated pattern files per locale (partial, translatable fields only)
55-
es/ # Spanish translations (mirrors content/ folder structure)
56-
pt-BR/ # Brazilian Portuguese translations
57-
site/ # Deployable site (static assets + generated HTML)
58-
es/ # Generated Spanish pages
59-
pt-BR/ # Generated Portuguese pages
60-
templates/ # HTML templates with {{…}} tokens for content + UI strings
61-
html-generators/ # Build scripts, categories.properties, locales.properties
62-
specs/ # Feature specifications (e.g., i18n-spec.md)
63-
```
65+
### Removing or reordering a pattern
6466

65-
## JSON Snippet Schema
66-
67-
Each `content/category/slug.json` file has this structure:
68-
69-
```json
70-
{
71-
"id": 1,
72-
"slug": "type-inference-with-var",
73-
"title": "Type inference with var",
74-
"category": "language",
75-
"difficulty": "beginner|intermediate|advanced",
76-
"jdkVersion": "10",
77-
"oldLabel": "Java 8",
78-
"modernLabel": "Java 10+",
79-
"oldApproach": "Explicit Types",
80-
"modernApproach": "var keyword",
81-
"oldCode": "// old way...",
82-
"modernCode": "// modern way...",
83-
"summary": "One-line description.",
84-
"explanation": "How it works paragraph.",
85-
"whyModernWins": [
86-
{ "icon": "", "title": "Short title", "desc": "One sentence." },
87-
{ "icon": "👁", "title": "Short title", "desc": "One sentence." },
88-
{ "icon": "🔒", "title": "Short title", "desc": "One sentence." }
89-
],
90-
"support": {
91-
"state": "available",
92-
"description": "Widely available since JDK 10 (March 2018)"
93-
},
94-
"prev": "category/slug-of-previous",
95-
"next": "category/slug-of-next",
96-
"related": [
97-
"category/slug-1",
98-
"category/slug-2",
99-
"category/slug-3"
100-
],
101-
"docs": [
102-
{ "title": "Javadoc or Guide Title", "href": "https://docs.oracle.com/..." }
103-
]
104-
}
105-
```
67+
Update `prev`/`next` in adjacent patterns. Search for the slug in other patterns' `related` arrays and replace with an appropriate alternative.
68+
69+
## Internationalization
70+
71+
Full spec: `specs/i18n/i18n-spec.md`. Key rules:
72+
73+
- All locales (including English) go through the same build pipeline.
74+
- UI strings: `translations/strings/{locale}.yaml`. Missing keys fall back to English with a build-time warning.
75+
- Content translations contain **only** translatable fields: `title`, `summary`, `explanation`, `oldApproach`, `modernApproach`, `whyModernWins`, `support.description`. Code, slugs, navigation, and docs are never translated.
76+
- `oldCode`/`modernCode` in translation files are **always overwritten** with English values at build time to prevent hallucinated code.
77+
- Locale registry: `html-generators/locales.properties` (format: `locale=Display Name`).
78+
- When adding a new UI string key, add it to `en.yaml` first, then to all other locale files. The generator warns on missing keys but doesn't fail.
79+
- YAML colons in string values must be quoted (Jackson parser is stricter than PyYAML).
80+
81+
## Proof Files
10682

107-
### Key Rules
108-
109-
- `slug` must match the filename (without `.json`)
110-
- `category` must match the parent folder name
111-
- `whyModernWins` must have exactly **3** entries
112-
- `related` must have exactly **3** entries (as `category/slug` paths)
113-
- `docs` must have at least **1** entry linking to Javadoc or Oracle documentation
114-
- `prev`/`next` are `category/slug` paths or `null` for first/last
115-
- Code in `oldCode`/`modernCode` uses `\n` for newlines
116-
117-
## Category Display Names
118-
119-
Categories and their display names are defined in `html-generators/categories.properties`:
120-
121-
| ID | Display |
122-
|----|---------|
123-
| `language` | Language |
124-
| `collections` | Collections |
125-
| `strings` | Strings |
126-
| `streams` | Streams |
127-
| `concurrency` | Concurrency |
128-
| `io` | I/O |
129-
| `errors` | Errors |
130-
| `datetime` | Date/Time |
131-
| `security` | Security |
132-
| `tooling` | Tooling |
133-
| `enterprise` | Enterprise |
134-
135-
## Adding a New Pattern
136-
137-
1. Create `content/category/new-slug.json` with all required fields
138-
2. Update `prev`/`next` in the adjacent patterns' JSON files
139-
3. Run `jbang html-generators/generate.java`
140-
4. (Optional) Create translated content files under `translations/content/{locale}/category/new-slug.json` with only translatable fields — or let the AI translation workflow handle it
141-
142-
## Internationalization (i18n)
143-
144-
The site supports multiple languages. See `specs/i18n/i18n-spec.md` for the full specification.
145-
146-
### Key Concepts
147-
148-
- **UI strings:** Hard-coded template text (labels, nav, footer) is extracted into `translations/strings/{locale}.yaml`. Templates use `{{dotted.key}}` tokens (e.g., `{{nav.allPatterns}}`, `{{sections.codeComparison}}`). Missing keys fall back to the English value with a build-time warning.
149-
- **Content translations:** Translated pattern files under `translations/content/{locale}/` contain **only** translatable fields (`title`, `summary`, `explanation`, `oldApproach`, `modernApproach`, `whyModernWins`, `support.description`). All other fields (`oldCode`, `modernCode`, `slug`, `id`, `prev`, `next`, `related`, `docs`, etc.) are always taken from the English source.
150-
- **Locale registry:** `html-generators/locales.properties` lists supported locales (format: `locale=Display name`). The first entry is the default.
151-
- **English is a first-class locale:** All locales — including English — go through the same build pipeline.
152-
- **Fallback:** If a pattern has no translation file for a locale, the English content is used and an "untranslated" banner is shown.
153-
154-
### Supported Locales
155-
156-
Defined in `html-generators/locales.properties`:
157-
158-
| Locale | Display Name |
159-
|--------|-------------|
160-
| `en` | English |
161-
| `es` | Español |
162-
| `pt-BR` | Português (Brasil) |
163-
164-
### Content Translation File Example
165-
166-
Translation files contain **only** translatable fields — no structural data:
167-
168-
```json
169-
// translations/content/pt-BR/language/type-inference-with-var.json
170-
{
171-
"title": "Inferência de tipo com var",
172-
"oldApproach": "Tipos explícitos",
173-
"modernApproach": "Palavra-chave var",
174-
"summary": "Use var para deixar o compilador inferir o tipo local.",
175-
"explanation": "...",
176-
"whyModernWins": [
177-
{ "icon": "", "title": "Menos ruído", "desc": "..." },
178-
{ "icon": "👁", "title": "Mais legível", "desc": "..." },
179-
{ "icon": "🔒", "title": "Seguro", "desc": "..." }
180-
],
181-
"support": {
182-
"description": "Amplamente disponível desde o JDK 10 (março de 2018)"
183-
}
83+
Each pattern has a corresponding proof file: `proof/{category}/{PascalCaseSlug}.java`.
84+
85+
```java
86+
///usr/bin/env jbang "$0" "$@" ; exit $?
87+
//JAVA 25+
88+
89+
/// Proof: slug-name
90+
/// Source: content/category/slug-name.yaml
91+
void main() {
92+
// modern code only — no old code, no assertions
18493
}
18594
```
18695

187-
## Local Development
96+
Uses Java 25 implicit classes (`void main()`, not `static void main`). Add minimal scaffolding (imports, dummy variables) to make the modern code compile.
18897

189-
```bash
190-
jbang html-generators/generate.java # Build HTML pages + snippets.json
191-
jwebserver -d site -p 8090 # Serve locally
192-
```
98+
## Key Conventions
99+
100+
- **Vanilla JS only**`site/app.js` uses no frameworks or build tools.
101+
- **Category display names** are defined in `html-generators/categories.properties`, not hardcoded.
102+
- **JDK filter ranges** in `app.js` map LTS versions to ranges: `11→[9-11]`, `17→[12-17]`, `21→[18-21]`, `25→[22-25]`.
103+
- **JetBrains Mono ligatures** are disabled on `.code-text` elements to prevent operators like `->` from rendering as special characters.
104+
- **Dark theme** uses CSS custom properties (`--modern-bg`, `--old-bg`). Theme state is in `localStorage.theme` and `data-theme` on `<html>`.
105+
- **RTL support** — Arabic (`ar`) locale sets `dir="rtl"` on the page.
106+
- When both old and modern approaches are from the same JDK version, use descriptive labels (e.g., "Full syntax" / "Compact") instead of version numbers.

0 commit comments

Comments
 (0)