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
24 changes: 24 additions & 0 deletions .github/workflows/check-examples.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Check Fe Examples

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
check-examples:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Make scripts executable
run: |
chmod +x scripts/fe
chmod +x scripts/extract-fe-blocks.sh
chmod +x scripts/check-examples.sh

- name: Check Fe code examples
run: npm run check:examples:verbose
72 changes: 72 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Contributing to The Fe Guide

## Code Examples

The documentation includes Fe code examples that are type-checked to ensure they remain valid as the language evolves.

### Code Block Conventions

Use the following markdown annotations for Fe code blocks:

**Complete examples** (type-checked):
```markdown
```fe
// This code must pass `fe check`
pub contract Example {
// ...
}
```(end)
```

**Snippets** (not type-checked):
```markdown
```fe ignore
// This is illustrative, may be incomplete
store.balances[from] -= amount
```(end)
```

### Running the Type Checker

Check all documentation examples:
```bash
npm run check:examples
```

Check with verbose output:
```bash
npm run check:examples:verbose
```

Check a specific file:
```bash
npm run check:examples -- src/content/docs/examples/erc20.md
```

### Adding New Examples

1. **Complete examples** in `src/content/docs/examples/` should use ` ```fe ` and include all necessary type definitions (see ERC20 example for reference)

2. **Illustrative snippets** throughout the documentation should use ` ```fe ignore ` since they are not complete programs

3. Run `npm run check:examples` before committing to verify all examples pass

### Updating the Fe Binary

The Fe binary is stored at `bin/fe-linux-x86_64`. To update it:

1. Build Fe from source or obtain a new binary
2. Copy to `bin/fe-linux-x86_64`
3. Ensure it's executable: `chmod +x bin/fe-linux-x86_64`
4. Run `npm run check:examples` to verify compatibility
5. Commit the updated binary

Note: Only Linux x86_64 is currently supported for local checking. CI runs on Linux.

### CI Integration

The type checker runs automatically on:
- Pull requests to `main`
- Pushes to `main`

If the check fails, the PR/build will be marked as failed with error details showing the file and line number.
Binary file added bin/fe-linux-x86_64
Binary file not shown.
157 changes: 157 additions & 0 deletions openspec/changes/add-fe-type-checking/design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
## Context

The Fe Guide documentation contains numerous code examples that should be valid Fe code. Without automated checking, examples can become stale or contain errors as the language evolves. Since Fe is not yet released, there's no official binary distribution to download.

**Stakeholders:**
- Documentation authors (need fast feedback)
- Learners (need working examples)
- Fe language maintainers (need to know when language changes break docs)

**Constraints:**
- Fe has no official releases yet (no downloadable binaries)
- Multi-platform support is desirable but not critical initially
- Some code blocks are intentional snippets, not complete programs

## Goals / Non-Goals

**Goals:**
- Catch broken code examples before they reach readers
- Provide fast local feedback for documentation authors
- Automate checking in CI to prevent regressions
- Support both complete examples and intentional snippets

**Non-Goals:**
- Multi-platform binary support (Linux-first is acceptable)
- Runtime testing of examples (type checking only)
- Automatic fixing of broken examples

## Decisions

### Decision: Commit Linux binary to repository
**What:** Store a pre-built `fe` binary for Linux x86_64 directly in the repository.

**Source:** Copy from local Fe build at `~/Documents/hacking/ef/fe/target/release/fe`

**Why:**
- Simplest approach given no official Fe releases
- Works immediately for CI (Linux runners)
- Works for Linux developers locally
- No external dependencies or network requirements

**Alternatives considered:**
- Build from source: Requires Rust toolchain, slower
- Docker: Additional dependency, more complex
- Download from CI artifacts: Requires fe repo changes, fragile

### Decision: Use `ignore` annotation for snippets
**What:** Code blocks marked ` ```fe ignore ` are skipped during type checking.

**Why:**
- Simple, explicit opt-out
- Visible in source (documentation intent is clear)
- Compatible with existing markdown tooling
- No complex heuristics needed

**Alternatives considered:**
- Wrapper templates: More complex, deferred to Phase 3
- Separate file extension (`.fe-snippet`): Doesn't work in markdown
- Automatic detection: Too fragile, false positives/negatives

### Decision: Shell script for extraction and checking
**What:** Use bash scripts for the core tooling.

**Why:**
- No additional dependencies beyond standard Unix tools
- Simple to understand and modify
- Works in CI without setup
- `grep`, `sed`, `awk` are sufficient for markdown parsing

**Alternatives considered:**
- Node.js script: More dependencies, but better parsing
- Dedicated tool (mdbook-like): Over-engineered for this use case

### Decision: Error output maps to markdown source
**What:** Errors reference the original markdown file and line, not the extracted temp file.

**Why:**
- Authors can immediately find and fix issues
- Integrates well with IDE "click to navigate"
- CI annotations can point to correct location

## Directory Structure

```
the-guide/
├── bin/
│ └── fe-linux-x86_64 # Pre-built Fe binary
├── scripts/
│ ├── fe # Wrapper script (platform detection)
│ ├── extract-fe-blocks.sh # Extract code blocks from markdown
│ └── check-examples.sh # Main entry point
├── .github/
│ └── workflows/
│ └── check-examples.yml
└── package.json # npm scripts: check:examples
```

## Code Block Extraction Algorithm

```
1. Find all .md files in src/content/docs/
2. For each file:
a. Scan for lines matching ```fe (but not ```fe ignore)
b. Record start line number
c. Capture content until closing ```
d. Write to temp file: {hash}_{file}_{line}.fe
3. Return list of temp files with source mappings
```

## Error Mapping Strategy

When `fe check` reports an error like:
```
/tmp/examples/abc123_erc20_42.fe:5:10: error: unknown type `u257`
```

Transform to:
```
src/content/docs/examples/erc20.md:46:10: error: unknown type `u257`
```

(Line 46 = code block start line 42 + error line 5 - 1)

## Risks / Trade-offs

| Risk | Mitigation |
|------|------------|
| Binary becomes stale | Document update process, consider automation |
| Git repo bloat from binary | Use Git LFS if binary > 10MB |
| Non-Linux developers can't check locally | Clear skip message, CI catches issues |
| Snippets incorrectly marked as complete | Phase 2 audit, contributor guidelines |
| Fe language changes break many examples | Run checker before Fe releases, batch fix |

## Migration Plan

1. **Phase 1**: Infrastructure + Examples directory only
- Add binary, scripts, CI
- Verify against known-good ERC20 example
- Fix any issues in examples/

2. **Phase 2**: Full documentation coverage
- Run against all docs
- Add `ignore` to intentional snippets
- Fix broken complete examples

3. **Phase 3** (optional): Wrapper templates
- Add support for `wrap=function` etc.
- Convert applicable snippets to checked

## Resolved Questions

1. **Binary updates**: Manual process for now. No automation needed initially.

2. **Git LFS**: Not needed. Binary will be committed directly to the repository.

3. **Partial checking**: Yes, support checking individual files for faster iteration:
- `npm run check:examples -- path/to/file.md`
- Useful during documentation writing
88 changes: 88 additions & 0 deletions openspec/changes/add-fe-type-checking/proposal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Change: Add Fe Type Checking for Documentation Examples

## Why

Code examples in documentation can drift out of sync with the actual Fe language as it evolves. Currently, there's no automated verification that code examples compile correctly. This leads to:
- Broken examples frustrating learners
- Outdated syntax going unnoticed
- No confidence that documentation reflects working code

## What Changes

### 1. Fe Binary Distribution
- Commit a pre-built `fe` binary for Linux x86_64 to the repository
- Store in `bin/fe-linux-x86_64` (or use Git LFS for cleaner history)
- Add wrapper script `scripts/fe` that selects the appropriate binary (future-proofed for multi-platform)

### 2. Code Block Extraction System
- Script to extract code blocks from markdown files
- Support two types of code blocks:
- ` ```fe ` - Complete, self-contained examples (must compile)
- ` ```fe ignore ` - Snippets for illustration only (skipped)
- Extract to temporary `.fe` files preserving source location for error reporting

### 3. Type Checking Infrastructure
- `scripts/check-examples.sh` - Main entry point for checking all examples
- Extracts code blocks, runs `fe check`, reports errors with source locations
- Exit code indicates pass/fail for CI integration

### 4. CI Integration
- GitHub Action runs on PRs and pushes to main
- Fails PR if any ` ```fe ` block doesn't compile
- Clear error messages pointing to the markdown file and line

### 5. Local Developer Workflow
- `npm run check:examples` - Run type checking locally
- Works on Linux directly, other platforms show helpful skip message
- Fast feedback during documentation writing

## Code Block Strategy

### Self-Contained Examples (checked)
```fe
// This compiles as-is
struct Point {
x: u256,
y: u256,
}
```

### Snippets (not checked)
```fe ignore
// This is illustrative, missing context
store.balances[from] -= amount
```

### Wrapper Templates (future enhancement)
For snippets that should be checked but need context, we could support:
```fe wrap=function
// Wrapped in: fn example() { ... }
let x = 10
let y = x + 5
```

## Impact

- Affected specs: New tooling capability
- Affected code:
- New `bin/` directory with fe binary
- New `scripts/` directory with checking scripts
- New GitHub Action workflow
- Markdown files may need `ignore` annotations on snippets
- **BREAKING**: Existing broken examples will be surfaced and need fixing

## Rollout Strategy

### Phase 1: Self-Contained Examples Only
- Start with `src/content/docs/examples/` directory
- These are complete, working programs (ERC20, etc.)
- Establishes the infrastructure

### Phase 2: Expand to All Documentation
- Audit all ` ```fe ` blocks across documentation
- Add `ignore` annotation to intentional snippets
- Fix any broken complete examples

### Phase 3: Snippet Wrapper Templates (Optional)
- Add wrapper template support for common patterns
- Allows more snippets to be type-checked with minimal boilerplate
Loading