mirror of
https://github.com/storytold/lightcraft.git
synced 2026-10-24 10:09:01 -06:00
Merge PR #1211
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
# Evaluates the Nix flake (no build, about a minute): `nix build` / `nix develop` stop at evaluation
|
||||
# when Cargo.lock gains something nix/package.nix can't vendor, and nothing else would notice.
|
||||
name: Nix
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths: ["flake.nix", "flake.lock", "nix/**", "Cargo.lock", ".github/workflows/nix.yml"]
|
||||
pull_request:
|
||||
paths: ["flake.nix", "flake.lock", "nix/**", "Cargo.lock", ".github/workflows/nix.yml"]
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: nix-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
eval:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
- uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1
|
||||
- name: nix flake check --no-build
|
||||
run: nix flake check --no-build --all-systems
|
||||
@@ -131,8 +131,8 @@ of it. Full standard: `../craftrules/standards/never-crash.md`
|
||||
→ `ui-egui`, `mcp` (L5) → apps `lightcraft` (desktop), `lightcraft-cli` (render/commands/MCP). `scenes` generates demo
|
||||
photos. `xtask` = tooling (`ci`, `layers`, `assets`, `parity`, `wasm`, `corpus`, `stats`). `flake.nix` +
|
||||
`nix/package.nix` = the Nix package (`nix build` builds both binaries with the craft-fonts input, installs the
|
||||
desktop file/icons/AppStream metadata and runs `cargo test --workspace`; `nix develop` = dev shell). Community-maintained and not
|
||||
in CI: it may lag behind the workspace; see README → Quick start.
|
||||
desktop file/icons/AppStream metadata and runs `cargo test --workspace`; `nix develop` = dev shell). Community-maintained; CI only
|
||||
evaluates it (`.github/workflows/nix.yml`), so the build may lag behind the workspace; see README → Quick start.
|
||||
|
||||
## Contributor credits (About window)
|
||||
|
||||
|
||||
@@ -139,5 +139,5 @@ of it. Full standard: `../craftrules/standards/never-crash.md`
|
||||
→ `ui-egui`, `mcp` (L5) → apps `lightcraft` (desktop), `lightcraft-cli` (render/commands/MCP). `scenes` generates demo
|
||||
photos. `xtask` = tooling (`ci`, `layers`, `assets`, `parity`, `wasm`, `corpus`, `stats`). `flake.nix` +
|
||||
`nix/package.nix` = the Nix package (`nix build` builds both binaries with the craft-fonts input, installs the
|
||||
desktop file/icons/AppStream metadata and runs `cargo test --workspace`; `nix develop` = dev shell). Community-maintained and not
|
||||
in CI: it may lag behind the workspace; see README → Quick start.
|
||||
desktop file/icons/AppStream metadata and runs `cargo test --workspace`; `nix develop` = dev shell). Community-maintained; CI only
|
||||
evaluates it (`.github/workflows/nix.yml`), so the build may lag behind the workspace; see README → Quick start.
|
||||
|
||||
@@ -51,7 +51,7 @@ fn decode(code: u32) -> Option<egui::Theme> {
|
||||
/// absolute path, and is never repeated.
|
||||
#[cfg(target_os = "linux")]
|
||||
fn gtk_theme() -> Option<egui::Theme> {
|
||||
let exe = ["/usr/bin/gsettings", "/bin/gsettings", "/usr/local/bin/gsettings"].into_iter().find(|p| std::path::Path::new(p).is_file())?;
|
||||
let exe = gsettings_exe(std::env::var_os("PATH").as_deref())?;
|
||||
let output = std::process::Command::new(exe).args(["get", "org.gnome.desktop.interface", "color-scheme"]).output().ok()?;
|
||||
if !output.status.success() {
|
||||
return None;
|
||||
@@ -59,6 +59,15 @@ fn gtk_theme() -> Option<egui::Theme> {
|
||||
parse_gtk_scheme(std::str::from_utf8(&output.stdout).ok()?)
|
||||
}
|
||||
|
||||
/// `gsettings` by absolute path: the absolute `PATH` entries first (NixOS has no /usr/bin/gsettings),
|
||||
/// then the usual places for a sparse `PATH`. Relative entries are skipped, so nothing runs from
|
||||
/// the working folder.
|
||||
#[cfg(target_os = "linux")]
|
||||
fn gsettings_exe(path: Option<&std::ffi::OsStr>) -> Option<std::path::PathBuf> {
|
||||
let listed = path.map(std::env::split_paths).into_iter().flatten().filter(|dir| dir.is_absolute());
|
||||
listed.chain(["/usr/bin", "/bin", "/usr/local/bin"].map(std::path::PathBuf::from)).map(|dir| dir.join("gsettings")).find(|exe| exe.is_file())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn parse_gtk_scheme(s: &str) -> Option<egui::Theme> {
|
||||
match s.trim().trim_matches('\'') {
|
||||
@@ -174,6 +183,24 @@ mod tests {
|
||||
assert_eq!(calls.load(Ordering::Relaxed), after_settle);
|
||||
}
|
||||
|
||||
/// NixOS keeps `gsettings` in /run/current-system/sw/bin or the per-user profile: it is found
|
||||
/// on `PATH`, but never through a relative entry, even one that leads to a real file.
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn gsettings_is_found_on_absolute_path_entries_only() {
|
||||
let dir = std::env::temp_dir().join(format!("lightcraft-gsettings-{}", std::process::id()));
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
std::fs::write(dir.join("gsettings"), "").unwrap();
|
||||
let path = std::env::join_paths([std::path::Path::new("relative/bin"), &dir]).unwrap();
|
||||
assert_eq!(super::gsettings_exe(Some(&path)), Some(dir.join("gsettings")));
|
||||
let cwd = std::env::current_dir().unwrap();
|
||||
let relative = std::path::PathBuf::from("../".repeat(cwd.components().count() - 1)).join(dir.strip_prefix("/").unwrap());
|
||||
assert!(relative.join("gsettings").is_file());
|
||||
let found = super::gsettings_exe(Some(relative.as_os_str()));
|
||||
assert!(found.as_ref().is_none_or(|p| p.is_absolute()), "{found:?}");
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn portal_values_and_gsettings_output_decode() {
|
||||
|
||||
Reference in New Issue
Block a user