Skip to content

Commit 0ec2a1b

Browse files
zrr1999Copilot
andauthored
πŸ› fix: restore package-backed basic-cli canon (#7)
* πŸ”§ fix: restore package-backed basic-cli canon Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * πŸ”§ fix: realign package-backed basic-cli docs and CI Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 91e188c commit 0ec2a1b

5 files changed

Lines changed: 125 additions & 32 deletions

File tree

β€Ž.github/workflows/ci-tests.ymlβ€Ž

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ jobs:
4242
- uses: actions/checkout@v6
4343
with:
4444
repository: spore-lang/spore
45-
ref: ef627c785e355a70551af5e4f4d85230996ce8d9
45+
ref: d96212aa5a4cfe24759c21d8690642adfd357018
4646
path: _spore
4747

4848
- uses: dtolnay/rust-toolchain@stable
@@ -58,38 +58,68 @@ jobs:
5858

5959
- name: Format Spore files
6060
run: |
61-
# `src/host.sp` is the package host entry; validate it via package/example flows,
62-
# not standalone file-mode formatting.
63-
paths=(examples src/basic_cli)
61+
# `src/host.sp` is a legacy compatibility shim; validate package-backed behavior
62+
# via the example and platform modules rather than standalone file-mode checks.
63+
# Standalone file examples
64+
find examples -maxdepth 1 -name '*.sp' -type f | sort | xargs _spore/target/release/spore format
65+
# Project-mode examples (format their src files)
66+
if [ -d examples/hello-app/src ]; then
67+
find examples/hello-app/src -name '*.sp' -type f | sort | xargs _spore/target/release/spore format
68+
fi
69+
# Platform API modules
70+
find src/basic_cli -name '*.sp' -type f | sort | xargs _spore/target/release/spore format
71+
# Check tests if they exist
6472
if [ -d tests ]; then
65-
paths+=(tests)
73+
find tests -name '*.sp' -type f | sort | xargs _spore/target/release/spore format
6674
fi
67-
find "${paths[@]}" -name '*.sp' -type f | sort | xargs _spore/target/release/spore format
68-
git diff --exit-code -- "${paths[@]}"
75+
git diff --exit-code
6976
7077
- name: Check Spore files
7178
run: |
72-
# `src/host.sp` is the package host entry; validate it via package/example flows,
73-
# not standalone file-mode checks.
74-
paths=(examples src/basic_cli)
79+
# `src/host.sp` is a legacy compatibility shim; validate package-backed behavior
80+
# via the example and platform modules rather than standalone file-mode checks.
81+
# Standalone file examples
82+
find examples -maxdepth 1 -name '*.sp' -type f | sort | xargs -n 1 _spore/target/release/spore check
83+
# Platform API modules
84+
find src/basic_cli -name '*.sp' -type f | sort | xargs -n 1 _spore/target/release/spore check
85+
# Project-mode examples: validate with spore check
86+
if [ -d examples/hello-app ]; then
87+
echo "βœ“ Checking project-mode example examples/hello-app/src/main.sp"
88+
_spore/target/release/spore check examples/hello-app/src/main.sp
89+
fi
90+
# Check tests if they exist
7591
if [ -d tests ]; then
76-
paths+=(tests)
92+
find tests -name '*.sp' -type f | sort | xargs -n 1 _spore/target/release/spore check
7793
fi
78-
find "${paths[@]}" -name '*.sp' -type f | sort | xargs -n 1 _spore/target/release/spore check
7994
8095
- name: Build Spore files
8196
run: |
82-
# `src/host.sp` is the package host entry; validate it via package/example flows,
83-
# not standalone file-mode builds.
84-
paths=(examples src/basic_cli)
97+
# `src/host.sp` is a legacy compatibility shim; validate package-backed behavior
98+
# via the example and platform modules rather than standalone file-mode builds.
99+
# Standalone file examples
100+
find examples -maxdepth 1 -name '*.sp' -type f | sort | xargs -n 1 _spore/target/release/spore build
101+
# Platform API modules
102+
find src/basic_cli -name '*.sp' -type f | sort | xargs -n 1 _spore/target/release/spore build
103+
# Project-mode examples: validate with spore build
104+
if [ -d examples/hello-app ]; then
105+
echo "βœ“ Building project-mode example examples/hello-app/src/main.sp"
106+
_spore/target/release/spore build examples/hello-app/src/main.sp
107+
fi
108+
# Check tests if they exist
85109
if [ -d tests ]; then
86-
paths+=(tests)
110+
find tests -name '*.sp' -type f | sort | xargs -n 1 _spore/target/release/spore build
87111
fi
88-
find "${paths[@]}" -name '*.sp' -type f | sort | xargs -n 1 _spore/target/release/spore build
89112
90-
- name: Run hello example
113+
- name: Run standalone hello example
91114
run: _spore/target/release/spore run examples/hello.sp
92115

116+
- name: Run project-mode hello-app example
117+
run: |
118+
if [ -d examples/hello-app ]; then
119+
echo "βœ“ Running project-mode example examples/hello-app/src/main.sp"
120+
_spore/target/release/spore run examples/hello-app/src/main.sp
121+
fi
122+
93123
- name: Run Spore spec tests
94124
run: |
95125
if [ ! -d tests ]; then

β€ŽREADME.mdβ€Ž

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,28 +29,58 @@ Operating System
2929

3030
## Quick Start
3131

32+
The canonical project-mode structure is demonstrated in `examples/hello-app/`:
33+
34+
**examples/hello-app/spore.toml:**
35+
```toml
36+
[package]
37+
name = "hello-app"
38+
version = "0.1.0"
39+
type = "application"
40+
spore-version = ">=0.1.0"
41+
42+
[project]
43+
platform = "basic-cli"
44+
default-entry = "app"
45+
46+
[entries.app]
47+
path = "main.sp"
48+
49+
[capabilities]
50+
allow = ["Compute"]
51+
52+
[dependencies]
53+
basic-cli = { path = "../.." }
54+
```
55+
56+
**examples/hello-app/src/main.sp:**
3257
```spore
33-
/// A simple "Hello World" using the basic-cli platform.
58+
import basic_cli.stdout as stdout
59+
3460
fn main() -> () uses [Console] {
35-
println("Hello from Spore basic-cli!")
61+
println("Hello from a project-mode Spore application!")
62+
return
3663
}
3764
```
3865

66+
**Run the project:**
3967
```bash
40-
spore check examples/hello.sp
41-
spore build examples/hello.sp
42-
spore run examples/hello.sp
68+
cd examples/hello-app
69+
spore check src/main.sp
70+
spore run src/main.sp
4371
```
4472

45-
This repository currently keeps `examples/` limited to files that PR CI validates today.
73+
This is a real package-backed application. The in-repo example points `basic-cli` at `../..`; projects generated by `spore new` vendor the package and use `vendor/basic-cli` instead. The formatter currently normalizes the import to `import basic_cli.stdout as stdout`, while `println` still resolves directly in scope.
74+
75+
For quick experiments, you can also run standalone `.sp` files (see `examples/hello.sp`), but production applications should use the project-mode structure above.
4676

4777
## Project Structure
4878

4979
```
5080
basic-cli/
5181
β”œβ”€β”€ spore.toml # Platform manifest
5282
β”œβ”€β”€ src/
53-
β”‚ β”œβ”€β”€ host.sp # Compatibility runtime entry point
83+
β”‚ β”œβ”€β”€ host.sp # Legacy compatibility shim
5484
β”‚ β”œβ”€β”€ platform_contract.sp
5585
β”‚ └── basic_cli/ # Spore API modules, checked and built in CI
5686
β”‚ β”œβ”€β”€ stdout.sp # Standard output operations
@@ -75,13 +105,14 @@ The current Platform contract MVP is intentionally split across two artifacts:
75105
- a hole-backed `main` function carries the authoritative startup signature
76106
- `main_for_host` is the Platform-owned adapter that receives the application startup function
77107

78-
Applications targeting `basic-cli` must implement the same startup function name/signature in their entry module. When the compiler starts reading Platform contracts from packages, `spec` items attached to the Platform contract and the application implementation will both have to hold.
108+
Applications targeting `basic-cli` must implement the same startup function name/signature in their entry module. The current compiler already resolves the package's `[platform]` metadata and `src/platform_contract.sp` to validate that startup shape. Runtime support is currently specialized to package-backed `basic-cli`: imported `basic_cli.*` foreign functions route through the built-in basic-cli host profile, while generic `handles` enforcement and startup `spec` stacking are still follow-up work.
79109

80-
`src/host.sp` remains as a compatibility copy of the adapter while the compiler still hardcodes platform startup behavior.
110+
`src/host.sp` remains as a compatibility copy of the adapter for older references; current manifest-backed projects use `src/platform_contract.sp`.
81111

82112
## Tutorial Contract
83113

84-
- `examples/` is for truthful, CI-validated examples only.
114+
- `examples/hello-app/` is the **canonical project-mode example** β€” it is formatted, checked, built, and run in CI.
115+
- `examples/hello.sp` is a minimal standalone file for quick experiments (also validated in CI).
85116
- `src/basic_cli/` is the API surface for the platform modules themselves.
86117
- `src/platform_contract.sp` is the package-owned startup contract surface.
87118
- Only add `tests/` when the repo has real Spore-side regression coverage worth running with `spore test`.
@@ -105,7 +136,9 @@ Following Spore's [SEP-0003 (Effect Capability System)](https://github.com/spore
105136

106137
🚧 **Early development** β€” API is unstable and subject to change.
107138

108-
At the moment, the validated example is `examples/hello.sp`. More ambitious host-backed demos such as environment/file workflows should stay out of `examples/` until the current platform import/runtime architecture supports them honestly.
139+
The canonical example is the **package-backed project-mode** `examples/hello-app/` application. It already validates and runs with `[project].platform = "basic-cli"`, an in-repo path dependency, and `import basic_cli.stdout`.
140+
141+
The standalone file example (`examples/hello.sp`) stays around for quick experiments. The main remaining platform gaps are generic `handles` enforcement, startup `spec` stacking, and lifting the runtime from its current explicit `basic-cli` host profile to a more general package-backed mechanism.
109142

110143
## License
111144

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
[package]
2+
name = "hello-app"
3+
version = "0.1.0"
4+
type = "application"
5+
spore-version = ">=0.1.0"
6+
7+
[project]
8+
platform = "basic-cli"
9+
default-entry = "app"
10+
11+
[entries.app]
12+
path = "main.sp"
13+
14+
[capabilities]
15+
allow = ["Compute"]
16+
17+
[dependencies]
18+
basic-cli = { path = "../.." }
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/// Canonical package-backed application example for basic-cli.
2+
///
3+
/// This mirrors the formatted `spore new` scaffold: import the
4+
/// platform module explicitly and call `println` directly from the
5+
/// imported basic-cli surface.
6+
/// Application entry point matching the platform contract.
7+
import basic_cli.stdout as stdout
8+
9+
fn main() -> () uses [Console] {
10+
println("Hello from a project-mode Spore application!")
11+
return
12+
}

β€Žsrc/host.spβ€Ž

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
/// Compatibility startup adapter.
2-
/// Keep this entry in sync with `platform_contract.sp` until the compiler reads
3-
/// `[platform].contract-module` directly.
1+
/// Legacy compatibility adapter.
2+
/// Manifest-backed projects resolve `main_for_host` from `platform_contract.sp`;
3+
/// keep this shim in sync for older references.
44
pub fn main_for_host(app_main: () -> ()) -> () {
55
app_main()
66
return

0 commit comments

Comments
Β (0)