Add beta install layout tooling
This commit is contained in:
parent
ee2b8e0930
commit
5180f69c4c
@ -17,6 +17,11 @@ complete and the full release gate passes near publication.
|
|||||||
- `glagol new --template binary|library|workspace` supports the existing
|
- `glagol new --template binary|library|workspace` supports the existing
|
||||||
binary scaffold plus checkable/testable library and local workspace
|
binary scaffold plus checkable/testable library and local workspace
|
||||||
scaffolds.
|
scaffolds.
|
||||||
|
- `scripts/install.sh` installs `bin/glagol`, `share/slovo/std/*.slo`, and
|
||||||
|
`share/slovo/runtime/runtime.c` under a configurable prefix.
|
||||||
|
- Installed `glagol` discovers both standard-library source modules and the
|
||||||
|
runtime C input relative to the executable, with `SLOVO_STD_PATH`,
|
||||||
|
`SLOVO_RUNTIME_C`, `GLAGOL_RUNTIME_C`, and `GLAGOL_CLANG` override paths.
|
||||||
- The release gate prints a concise success line after docs, formatting, tests,
|
- The release gate prints a concise success line after docs, formatting, tests,
|
||||||
promotion, binary, and LLVM smoke checks pass.
|
promotion, binary, and LLVM smoke checks pass.
|
||||||
|
|
||||||
@ -26,15 +31,11 @@ complete and the full release gate passes near publication.
|
|||||||
- no networking or runtime resource model
|
- no networking or runtime resource model
|
||||||
- no package registry behavior
|
- no package registry behavior
|
||||||
- no stable ABI/layout promise
|
- no stable ABI/layout promise
|
||||||
- no stable install layout promise until the install-path portion of this
|
- no operating-system package-manager integration
|
||||||
tooling bundle is finished
|
- no stable install layout promise beyond this beta toolchain layout
|
||||||
|
|
||||||
## Remaining Before Tagging `1.0.0-beta.1`
|
## Remaining Before Tagging `1.0.0-beta.1`
|
||||||
|
|
||||||
- document and gate public install layout for `glagol`, `runtime/`, and
|
|
||||||
`lib/std`
|
|
||||||
- add a minimal install or packaging command/script if the existing build flow
|
|
||||||
is not enough
|
|
||||||
- rerender publication PDFs only if documentation release text changes
|
- rerender publication PDFs only if documentation release text changes
|
||||||
- run the full release gate from a clean checkout state
|
- run the full release gate from a clean checkout state
|
||||||
|
- decide whether this tooling bundle is sufficient for the `1.0.0-beta.1` tag
|
||||||
|
|||||||
20
README.md
20
README.md
@ -91,6 +91,26 @@ Create alternate project shapes:
|
|||||||
./compiler/target/debug/glagol new workspace-demo --template workspace
|
./compiler/target/debug/glagol new workspace-demo --template workspace
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Install the current checkout:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
PREFIX="$HOME/.local" ./scripts/install.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
The installed layout is:
|
||||||
|
|
||||||
|
```text
|
||||||
|
<prefix>/bin/glagol
|
||||||
|
<prefix>/share/slovo/std/*.slo
|
||||||
|
<prefix>/share/slovo/runtime/runtime.c
|
||||||
|
```
|
||||||
|
|
||||||
|
Installed `glagol` discovers `share/slovo/std` and
|
||||||
|
`share/slovo/runtime/runtime.c` relative to its executable. `SLOVO_STD_PATH`
|
||||||
|
can still override standard-library search, `SLOVO_RUNTIME_C` or
|
||||||
|
`GLAGOL_RUNTIME_C` can override the runtime C input, and `GLAGOL_CLANG` can
|
||||||
|
select the Clang-compatible compiler.
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
- [Language Manifest](docs/language/MANIFEST.md)
|
- [Language Manifest](docs/language/MANIFEST.md)
|
||||||
|
|||||||
@ -2222,6 +2222,32 @@ fn parse_test_count(output: &str, suffix: &str) -> Option<usize> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn runtime_path() -> PathBuf {
|
fn runtime_path() -> PathBuf {
|
||||||
|
runtime_path_candidates()
|
||||||
|
.into_iter()
|
||||||
|
.find(|path| path.is_file())
|
||||||
|
.unwrap_or_else(checkout_runtime_path)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn runtime_path_candidates() -> Vec<PathBuf> {
|
||||||
|
let mut candidates = Vec::new();
|
||||||
|
if let Some(path) = env::var_os("SLOVO_RUNTIME_C") {
|
||||||
|
candidates.push(PathBuf::from(path));
|
||||||
|
}
|
||||||
|
if let Some(path) = env::var_os("GLAGOL_RUNTIME_C") {
|
||||||
|
candidates.push(PathBuf::from(path));
|
||||||
|
}
|
||||||
|
if let Ok(exe) = env::current_exe() {
|
||||||
|
if let Some(bin_dir) = exe.parent() {
|
||||||
|
candidates.push(bin_dir.join("runtime/runtime.c"));
|
||||||
|
candidates.push(bin_dir.join("../runtime/runtime.c"));
|
||||||
|
candidates.push(bin_dir.join("../share/slovo/runtime/runtime.c"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
candidates.push(checkout_runtime_path());
|
||||||
|
candidates
|
||||||
|
}
|
||||||
|
|
||||||
|
fn checkout_runtime_path() -> PathBuf {
|
||||||
Path::new(env!("CARGO_MANIFEST_DIR")).join("../runtime/runtime.c")
|
Path::new(env!("CARGO_MANIFEST_DIR")).join("../runtime/runtime.c")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -125,6 +125,64 @@ fn run_forwards_program_arguments_when_host_toolchain_is_available() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn installed_layout_discovers_std_and_runtime_without_checkout_paths() {
|
||||||
|
let prefix = unique_path("installed-layout");
|
||||||
|
let bin_dir = prefix.join("bin");
|
||||||
|
let std_dir = prefix.join("share/slovo/std");
|
||||||
|
let runtime_dir = prefix.join("share/slovo/runtime");
|
||||||
|
fs::create_dir_all(&bin_dir).expect("create installed bin dir");
|
||||||
|
fs::create_dir_all(&std_dir).expect("create installed std dir");
|
||||||
|
fs::create_dir_all(&runtime_dir).expect("create installed runtime dir");
|
||||||
|
|
||||||
|
let installed_glagol = bin_dir.join(format!("glagol{}", std::env::consts::EXE_SUFFIX));
|
||||||
|
fs::copy(env!("CARGO_BIN_EXE_glagol"), &installed_glagol).expect("copy glagol");
|
||||||
|
make_executable(&installed_glagol);
|
||||||
|
|
||||||
|
let repo_root = Path::new(env!("CARGO_MANIFEST_DIR"))
|
||||||
|
.parent()
|
||||||
|
.expect("compiler has repo parent");
|
||||||
|
fs::copy(
|
||||||
|
repo_root.join("runtime/runtime.c"),
|
||||||
|
runtime_dir.join("runtime.c"),
|
||||||
|
)
|
||||||
|
.expect("copy runtime");
|
||||||
|
for entry in fs::read_dir(repo_root.join("lib/std")).expect("read std dir") {
|
||||||
|
let entry = entry.expect("read std entry");
|
||||||
|
let path = entry.path();
|
||||||
|
if path.extension().and_then(|ext| ext.to_str()) == Some("slo") {
|
||||||
|
fs::copy(
|
||||||
|
&path,
|
||||||
|
std_dir.join(path.file_name().expect("std file name")),
|
||||||
|
)
|
||||||
|
.expect("copy std module");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let project = write_project(
|
||||||
|
"installed-layout-project",
|
||||||
|
&[],
|
||||||
|
"(module main)\n\n(import std.io (print_string_zero))\n(import std.string (concat))\n\n(fn main () -> i32\n (print_string_zero (concat \"installed\" \"-ok\")))\n",
|
||||||
|
);
|
||||||
|
|
||||||
|
let check = run_installed_glagol(&installed_glagol, ["check".as_ref(), project.as_os_str()]);
|
||||||
|
assert_success("installed layout check", &check);
|
||||||
|
|
||||||
|
let run = run_installed_glagol(&installed_glagol, ["run".as_ref(), project.as_os_str()]);
|
||||||
|
if host_clang_available() {
|
||||||
|
assert_success("installed layout run", &run);
|
||||||
|
assert_eq!(String::from_utf8_lossy(&run.stdout), "installed-ok\n");
|
||||||
|
assert!(run.stderr.is_empty(), "installed run wrote stderr");
|
||||||
|
} else {
|
||||||
|
assert_exit_code("installed layout run without clang", &run, 3);
|
||||||
|
assert_stderr_contains(
|
||||||
|
"installed layout run without clang",
|
||||||
|
&run,
|
||||||
|
"ToolchainUnavailable",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn new_library_template_creates_checkable_testable_library_project() {
|
fn new_library_template_creates_checkable_testable_library_project() {
|
||||||
let project = unique_path("library-template");
|
let project = unique_path("library-template");
|
||||||
@ -329,6 +387,7 @@ fn release_gate_script_exists_and_names_required_commands() {
|
|||||||
let script = Path::new("../scripts/release-gate.sh");
|
let script = Path::new("../scripts/release-gate.sh");
|
||||||
let text = fs::read_to_string(script).expect("read release gate script");
|
let text = fs::read_to_string(script).expect("read release gate script");
|
||||||
assert!(text.contains("git diff --check"));
|
assert!(text.contains("git diff --check"));
|
||||||
|
assert!(text.contains("scripts/install.sh"));
|
||||||
assert!(text.contains("cargo fmt --check"));
|
assert!(text.contains("cargo fmt --check"));
|
||||||
assert!(text.contains("cargo test"));
|
assert!(text.contains("cargo test"));
|
||||||
assert!(text.contains("dx_v1_7"));
|
assert!(text.contains("dx_v1_7"));
|
||||||
@ -390,6 +449,39 @@ where
|
|||||||
.expect("run glagol")
|
.expect("run glagol")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn run_installed_glagol<I, S>(binary: &Path, args: I) -> Output
|
||||||
|
where
|
||||||
|
I: IntoIterator<Item = S>,
|
||||||
|
S: AsRef<std::ffi::OsStr>,
|
||||||
|
{
|
||||||
|
Command::new(binary)
|
||||||
|
.env_remove("SLOVO_STD_PATH")
|
||||||
|
.env_remove("SLOVO_RUNTIME_C")
|
||||||
|
.env_remove("GLAGOL_RUNTIME_C")
|
||||||
|
.args(args)
|
||||||
|
.output()
|
||||||
|
.expect("run installed glagol")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn host_clang_available() -> bool {
|
||||||
|
let clang = std::env::var("GLAGOL_CLANG").unwrap_or_else(|_| "clang".to_string());
|
||||||
|
Command::new(clang)
|
||||||
|
.arg("--version")
|
||||||
|
.output()
|
||||||
|
.map(|output| output.status.success())
|
||||||
|
.unwrap_or(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_executable(path: &Path) {
|
||||||
|
#[cfg(unix)]
|
||||||
|
{
|
||||||
|
use std::os::unix::fs::PermissionsExt;
|
||||||
|
let mut permissions = fs::metadata(path).expect("stat executable").permissions();
|
||||||
|
permissions.set_mode(0o755);
|
||||||
|
fs::set_permissions(path, permissions).expect("chmod executable");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn assert_success(context: &str, output: &Output) {
|
fn assert_success(context: &str, output: &Output) {
|
||||||
assert!(
|
assert!(
|
||||||
output.status.success(),
|
output.status.success(),
|
||||||
|
|||||||
@ -37,10 +37,9 @@ Work:
|
|||||||
- keep PDF rendering explicit and non-mutating by default
|
- keep PDF rendering explicit and non-mutating by default
|
||||||
|
|
||||||
Current main-branch progress after `1.0.0-beta`: `glagol run`,
|
Current main-branch progress after `1.0.0-beta`: `glagol run`,
|
||||||
`glagol clean`, `glagol new --template binary|library|workspace`, README
|
`glagol clean`, `glagol new --template binary|library|workspace`,
|
||||||
coverage, focused DX tests, and a concise release-gate success line are
|
`scripts/install.sh`, installed std/runtime discovery, README coverage,
|
||||||
implemented. Install-path polish remains in this tooling bundle before a
|
focused DX tests, and a concise release-gate success line are implemented.
|
||||||
`1.0.0-beta.1` tag.
|
|
||||||
|
|
||||||
Why first: it reduces friction for every later feature and gives users a better
|
Why first: it reduces friction for every later feature and gives users a better
|
||||||
way to exercise the beta.
|
way to exercise the beta.
|
||||||
|
|||||||
@ -19,6 +19,10 @@ future `1.0.0-beta.1` bundle:
|
|||||||
- `glagol clean <file.slo|project>` removes generated `.slovo/build` artifacts
|
- `glagol clean <file.slo|project>` removes generated `.slovo/build` artifacts
|
||||||
- `glagol new --template binary|library|workspace` adds library and local
|
- `glagol new --template binary|library|workspace` adds library and local
|
||||||
workspace scaffolds beside the existing binary default
|
workspace scaffolds beside the existing binary default
|
||||||
|
- `scripts/install.sh` installs `bin/glagol`, `share/slovo/std`, and
|
||||||
|
`share/slovo/runtime/runtime.c`
|
||||||
|
- installed native builds discover the runtime C input relative to the
|
||||||
|
executable, with `SLOVO_RUNTIME_C` and `GLAGOL_RUNTIME_C` overrides
|
||||||
- the release gate prints a concise final success summary
|
- the release gate prints a concise final success summary
|
||||||
|
|
||||||
This is a toolchain workflow slice only. It does not claim a new stable ABI,
|
This is a toolchain workflow slice only. It does not claim a new stable ABI,
|
||||||
|
|||||||
@ -23,6 +23,11 @@ Post-beta main currently contains tooling hardening intended for a future
|
|||||||
- `glagol clean <file.slo|project>` removes generated `.slovo/build` artifacts
|
- `glagol clean <file.slo|project>` removes generated `.slovo/build` artifacts
|
||||||
- `glagol new --template binary|library|workspace` scaffolds binary projects,
|
- `glagol new --template binary|library|workspace` scaffolds binary projects,
|
||||||
library projects, and local package workspaces using existing manifest rules
|
library projects, and local package workspaces using existing manifest rules
|
||||||
|
- `scripts/install.sh` installs the compiler, `lib/std`, and runtime C input
|
||||||
|
under a configurable prefix
|
||||||
|
- installed `glagol` discovers `share/slovo/std` and
|
||||||
|
`share/slovo/runtime/runtime.c` relative to its executable, with environment
|
||||||
|
overrides still available
|
||||||
- the release gate prints a concise final success line after all checks pass
|
- the release gate prints a concise final success line after all checks pass
|
||||||
|
|
||||||
This unreleased slice does not add source-language syntax, stable ABI/layout
|
This unreleased slice does not add source-language syntax, stable ABI/layout
|
||||||
|
|||||||
@ -953,6 +953,20 @@ scaffold shapes. `binary` is the default project with `src/main.slo`.
|
|||||||
creates a local two-package workspace using the existing `[workspace]`,
|
creates a local two-package workspace using the existing `[workspace]`,
|
||||||
`[package]`, and local path dependency rules.
|
`[package]`, and local path dependency rules.
|
||||||
|
|
||||||
|
`scripts/install.sh` installs the beta toolchain layout under a configurable
|
||||||
|
prefix:
|
||||||
|
|
||||||
|
```text
|
||||||
|
<prefix>/bin/glagol
|
||||||
|
<prefix>/share/slovo/std/*.slo
|
||||||
|
<prefix>/share/slovo/runtime/runtime.c
|
||||||
|
```
|
||||||
|
|
||||||
|
Installed `glagol` must discover the standard-library sources and runtime C
|
||||||
|
input relative to its executable. `SLOVO_STD_PATH` remains the standard-library
|
||||||
|
source override. `SLOVO_RUNTIME_C` and `GLAGOL_RUNTIME_C` may override the
|
||||||
|
runtime C input for native builds.
|
||||||
|
|
||||||
## 4.5 v2.0.0-beta.1 Experimental Integration Readiness
|
## 4.5 v2.0.0-beta.1 Experimental Integration Readiness
|
||||||
|
|
||||||
Status: current experimental Slovo-side release contract, released 2026-05-17.
|
Status: current experimental Slovo-side release contract, released 2026-05-17.
|
||||||
|
|||||||
88
scripts/install.sh
Executable file
88
scripts/install.sh
Executable file
@ -0,0 +1,88 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
repo_root="$(cd -- "${script_dir}/.." && pwd)"
|
||||||
|
prefix="${PREFIX:-${HOME}/.local}"
|
||||||
|
profile="release"
|
||||||
|
build=1
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'USAGE'
|
||||||
|
usage: scripts/install.sh [--prefix <dir>] [--debug] [--no-build]
|
||||||
|
|
||||||
|
Installs the Slovo toolchain layout:
|
||||||
|
|
||||||
|
<prefix>/bin/glagol
|
||||||
|
<prefix>/share/slovo/std/*.slo
|
||||||
|
<prefix>/share/slovo/runtime/runtime.c
|
||||||
|
|
||||||
|
Set PREFIX instead of --prefix if preferred.
|
||||||
|
USAGE
|
||||||
|
}
|
||||||
|
|
||||||
|
while [ "$#" -gt 0 ]; do
|
||||||
|
case "$1" in
|
||||||
|
--prefix)
|
||||||
|
if [ "$#" -lt 2 ]; then
|
||||||
|
echo "--prefix requires a directory" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
prefix="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--debug)
|
||||||
|
profile="debug"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--no-build)
|
||||||
|
build=0
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-h|--help)
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "unexpected argument: $1" >&2
|
||||||
|
usage >&2
|
||||||
|
exit 2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "${build}" -eq 1 ]; then
|
||||||
|
cargo build --manifest-path "${repo_root}/compiler/Cargo.toml" --profile "${profile}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
binary="${repo_root}/compiler/target/${profile}/glagol"
|
||||||
|
if [ ! -x "${binary}" ]; then
|
||||||
|
echo "missing built compiler binary: ${binary}" >&2
|
||||||
|
echo "run cargo build --manifest-path compiler/Cargo.toml --profile ${profile}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
bin_dir="${prefix}/bin"
|
||||||
|
std_dir="${prefix}/share/slovo/std"
|
||||||
|
runtime_dir="${prefix}/share/slovo/runtime"
|
||||||
|
doc_dir="${prefix}/share/doc/slovo"
|
||||||
|
|
||||||
|
install -d "${bin_dir}" "${std_dir}" "${runtime_dir}" "${doc_dir}"
|
||||||
|
install -m 755 "${binary}" "${bin_dir}/glagol"
|
||||||
|
install -m 644 "${repo_root}/runtime/runtime.c" "${runtime_dir}/runtime.c"
|
||||||
|
|
||||||
|
find "${repo_root}/lib/std" -maxdepth 1 -type f -name '*.slo' -print0 |
|
||||||
|
while IFS= read -r -d '' module; do
|
||||||
|
install -m 644 "${module}" "${std_dir}/$(basename "${module}")"
|
||||||
|
done
|
||||||
|
|
||||||
|
install -m 644 "${repo_root}/README.md" "${doc_dir}/README.md"
|
||||||
|
install -m 644 "${repo_root}/LICENSE-MIT" "${doc_dir}/LICENSE-MIT"
|
||||||
|
install -m 644 "${repo_root}/LICENSE-APACHE" "${doc_dir}/LICENSE-APACHE"
|
||||||
|
|
||||||
|
cat <<EOF
|
||||||
|
installed Slovo toolchain to ${prefix}
|
||||||
|
${bin_dir}/glagol
|
||||||
|
${std_dir}
|
||||||
|
${runtime_dir}/runtime.c
|
||||||
|
EOF
|
||||||
@ -7,6 +7,7 @@ compiler_dir="${repo_root}/compiler"
|
|||||||
|
|
||||||
cd "${repo_root}"
|
cd "${repo_root}"
|
||||||
git diff --check
|
git diff --check
|
||||||
|
bash -n scripts/install.sh
|
||||||
|
|
||||||
required_pdfs=(
|
required_pdfs=(
|
||||||
"docs/papers/SLOVO_WHITEPAPER.pdf"
|
"docs/papers/SLOVO_WHITEPAPER.pdf"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user