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
2 changes: 2 additions & 0 deletions .github/workflows/check-examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,6 @@ jobs:
chmod +x scripts/check-examples.sh

- name: Check Fe code examples
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npm run check:examples:verbose
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# build output
dist/
bin/
# generated types
.astro/

Expand All @@ -21,4 +22,4 @@ pnpm-debug.log*
.DS_Store

# Open Spec
openspec/changes/
openspec/changes/
26 changes: 18 additions & 8 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,17 +157,27 @@ For language behavior not covered in docs, consult the [Fe compiler source](http

## Updating the Fe Binary

The Fe binary is stored in `bin/`. A platform-detecting wrapper is at `scripts/fe`.
The Fe compiler is resolved dynamically via `scripts/fe`.

To update the compiler:
Behavior:
- On first use, `scripts/fe` fetches the latest release from `argotorg/fe` and caches it in `bin/`.
- It stores cache metadata in `bin/.fe-version` and `bin/.fe-last-check`.
- By default it only re-checks for latest releases every 6 hours.

1. Build Fe from source or obtain a new binary
2. Copy to `bin/fe-linux-x86_64` (or appropriate platform)
3. Ensure it's executable: `chmod +x bin/fe-linux-x86_64`
4. Run `bash scripts/check-examples.sh` to verify compatibility
5. Commit the updated binary
Useful commands:

Note: Only Linux x86_64 is currently supported for local checking. CI runs on Linux.
```bash
# Validate all docs code examples using the wrapper
bash scripts/check-examples.sh

# Force an immediate latest-release check
FE_FORCE_LATEST_CHECK=1 ./scripts/fe check path/to/file.fe
```

Environment variables:
- `GITHUB_TOKEN`: used for authenticated GitHub API requests (recommended in CI)
- `FE_LATEST_TTL_SECONDS`: override metadata freshness window (default: `21600`)
- `FE_FORCE_LATEST_CHECK=1`: bypass freshness and force an API latest check

## Site Customization

Expand Down
Binary file removed bin/fe-linux-x86_64
Binary file not shown.
15 changes: 10 additions & 5 deletions openspec/project.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,25 @@

## Fe Compiler

The Fe compiler binary is located in the `bin/` directory. A platform-detecting wrapper script is available at `scripts/fe`:
Use the wrapper script at `scripts/fe` for all compiler invocations. The wrapper downloads the latest Fe release on demand, caches it in `bin/`, and reuses cached metadata to avoid repeated GitHub API calls.

```bash
# Type-check a Fe file using the wrapper (recommended)
./scripts/fe check path/to/file.fe

# Or use the binary directly (Linux x86_64 only)
./bin/fe-linux-x86_64 check path/to/file.fe

# Validate all documentation code snippets
bash scripts/check-examples.sh

# Optional: force a latest-release check immediately
FE_FORCE_LATEST_CHECK=1 ./scripts/fe check path/to/file.fe
```

This local compiler should be used instead of any system-installed version to ensure consistency with the documented language features.
Environment variables:
- `GITHUB_TOKEN`: used for authenticated GitHub API requests (recommended in CI to avoid low unauthenticated rate limits)
- `FE_LATEST_TTL_SECONDS`: freshness window for latest-release checks (default: `21600`)
- `FE_FORCE_LATEST_CHECK=1`: bypass freshness window and force a latest check

This local compiler wrapper should be used instead of any system-installed version to ensure consistency with the documented language features.

## Project Conventions

Expand Down
29 changes: 22 additions & 7 deletions scripts/boilerplate.fe
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
// Snippets can import what they need with: use _boilerplate::Map

mod _boilerplate {
// Re-export StorageMap from core
pub use core::StorageMap

// Re-export intrinsics from core
pub use core::{caller, revert, keccak, sload, sstore}
// Intrinsic compatibility shims for docs snippets.
pub fn caller() -> u256 { todo() }
pub fn revert(_ offset: u256, _ size: u256) { todo() }
pub fn keccak<T>(_ data: T) -> u256 { todo() }
pub fn sload(_ slot: u256) -> u256 { todo() }
pub fn sstore(_ slot: u256, _ value: u256) { todo() }

// Map type stub (for non-storage contexts)
pub struct Map<K, V> {}
Expand Down Expand Up @@ -68,10 +69,24 @@ mod _boilerplate {
pub fn block_hash(_ number: u256) -> u256 { todo() }

// Address type stub
pub struct Address {}
pub struct Address { inner: u256 }
impl Address {
pub fn zero() -> Self { Address {} }
pub fn zero() -> Self { Address { inner: 0 } }
pub fn encode<E>(own self, _ e: mut E) { todo() }
pub fn decode<D>(_ d: mut D) -> Self { todo() }
pub fn as_topic(self) -> u256 { self.inner }
}
impl core::abi::Encode<std::abi::Sol> for Address {
fn encode<E: core::abi::AbiEncoder<std::abi::Sol>>(own self, _ e: mut E) { todo() }
}
impl core::abi::Decode<std::abi::Sol> for Address {
fn decode<D: core::abi::AbiDecoder<std::abi::Sol>>(_ d: mut D) -> Self { todo() }
}
impl std::abi::SolCompat for Address {
type S = String<7>
const SOL_TYPE: Self::S = "address"
}
impl Copy for Address {}
impl core::ops::Eq for Address {
fn eq(self, _ other: Self) -> bool { todo() }
}
Expand Down
23 changes: 22 additions & 1 deletion scripts/check-examples.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$SCRIPT_DIR/.."
BOILERPLATE_FILE="$SCRIPT_DIR/boilerplate.fe"

# Configuration
VERBOSE=false
Expand Down Expand Up @@ -84,6 +85,8 @@ TOTAL_BLOCKS=$(wc -l < "$MAPPINGS_FILE")
if [[ "$VERBOSE" == true ]]; then
echo "Found $TOTAL_BLOCKS Fe code blocks to check"
echo ""
else
echo "Checking $TOTAL_BLOCKS Fe code blocks (use --verbose for live progress)..."
fi

# Track errors
Expand All @@ -92,6 +95,22 @@ CHECKED=0
PASSED=0
FAILED=0

prepare_standalone_check_file() {
local source_file="$1"
local output_file="$2"

if [[ -f "$BOILERPLATE_FILE" ]]; then
cat "$BOILERPLATE_FILE" > "$output_file"
echo "" >> "$output_file"
echo "// --- standalone source below ---" >> "$output_file"
echo "" >> "$output_file"
cat "$source_file" >> "$output_file"
else
cp "$source_file" "$output_file"
fi

}

# Check each extracted file
while IFS=: read -r fe_file md_file block_start_line; do
: $((CHECKED++))
Expand Down Expand Up @@ -154,7 +173,9 @@ if [[ -d "$EXAMPLES_DIR" ]] && [[ ${#FILES[@]} -eq 0 ]]; then
echo -n "Checking $rel_fe... "
fi

FE_OUTPUT=$("$SCRIPT_DIR/fe" check "$fe_file" 2>&1) || true
temp_check_file="$TEMP_DIR/standalone_$(basename "$fe_file")"
prepare_standalone_check_file "$fe_file" "$temp_check_file"
FE_OUTPUT=$("$SCRIPT_DIR/fe" check "$temp_check_file" 2>&1) || true
Comment on lines +176 to +178

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Report standalone example errors against original file lines

Standalone examples are now checked through a generated temp file with boilerplate prepended, so any compiler diagnostics reference shifted line numbers in that synthetic file instead of the original src/examples/*.fe source. When a standalone example fails, the reported location is therefore misleading, which makes CI failures harder to triage and fix; this path should either check the original file directly or remap diagnostics back to original line numbers.

Useful? React with 👍 / 👎.


if [[ -z "$FE_OUTPUT" ]]; then
: $((PASSED++))
Expand Down
Loading