Skip to content
Open
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
64 changes: 36 additions & 28 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -113,38 +113,46 @@ jobs:
run: bash tools/check-deps.sh

# ─────────────────────────────────────────────
# Phase 1: cargo-deny — license and crate policy
# Uncomment when Cargo workspace has members
# cargo-deny — license and crate policy
# ─────────────────────────────────────────────
# cargo-deny:
# name: Cargo deny
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v4
# - uses: EmbarkStudios/cargo-deny-action@v1
# with:
# command: check
# arguments: --all-features
cargo-deny:
name: Cargo deny
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: EmbarkStudios/cargo-deny-action@v2
with:
command: check licenses bans sources

# ─────────────────────────────────────────────
# Phase 1: Rust shell build and lint
# Uncomment when shell/ contains a Cargo.toml
# Rust workspace build and lint
# ─────────────────────────────────────────────
# build-shell:
# name: Build shell (Rust)
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v4
# - uses: dtolnay/rust-toolchain@stable
# with:
# components: clippy, rustfmt
# - uses: Swatinem/rust-cache@v2
# with:
# workspaces: shell
# - run: cargo fmt --manifest-path shell/Cargo.toml --check
# - run: cargo clippy --manifest-path shell/Cargo.toml --all-targets -- -D warnings
# - run: cargo build --manifest-path shell/Cargo.toml
# - run: cargo test --manifest-path shell/Cargo.toml
build-rust:
name: Build Rust workspace
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install GTK4 and libadwaita system dependencies
run: |
sudo apt-get update -q
sudo apt-get install -y --no-install-recommends \
libgtk-4-dev \
libadwaita-1-dev \
libglib2.0-dev \
pkg-config
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy, rustfmt
- uses: Swatinem/rust-cache@v2
- name: Check formatting
run: cargo fmt --all -- --check
- name: Clippy
run: cargo clippy --workspace --all-targets -- -D warnings
- name: Build
run: cargo build --workspace
- name: Test
run: cargo test --workspace

# ─────────────────────────────────────────────
# Phase 1: Validate PKGBUILDs with namcap
Expand Down
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ __pycache__/
.venv/
venv/

# Arch Linux packaging artifacts
src/
# Arch Linux packaging artifacts (makepkg build dirs — scoped to packaging/)
packaging/**/src/
packaging/**/pkg/
pkg/
*.pkg.tar.zst
*.pkg.tar.xz
Expand Down
10 changes: 7 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ Branch: `feature/workspace-scaffold`

Create the Cargo workspace structure. No implementation code yet — just the crate skeletons that make the workspace valid and compilable.

```
```text
Cargo.toml ← uncomment members one by one as crates are created
shared/
Cargo.toml ← [package] name = "minecrarch-shared", version = "0.1.0"
Expand Down Expand Up @@ -339,7 +339,8 @@ Branch: `feature/gamescope-session`
Create the systemd user unit files that boot the platform session. These are configuration files, not Rust code.

Files to create:
```

```text
iso/airootfs/etc/systemd/user/
gamescope-session.service ← ExecStart=gamescope --fullscreen ... %h/.minecrarch-shell
minecrarch-shell.service ← stub (ExecStart=/usr/bin/minecrarch-shell)
Expand All @@ -357,7 +358,8 @@ iso/airootfs/etc/systemd/system/
```

Key Gamescope flags for the session unit:
```

```bash
gamescope --fullscreen --nested --output-width 1920 --output-height 1080 \
--xwayland-count 1 -- /usr/bin/minecrarch-shell
```
Expand All @@ -371,6 +373,7 @@ Branch: `feature/shell-skeleton`
Minimal GTK4 + libadwaita application. Must compile, launch, and be gamepad-navigable.

`shell/Cargo.toml` dependencies:

```toml
gtk4 = { version = "0.9", features = ["v4_12"] }
libadwaita = { version = "0.7", features = ["v1_5"] }
Expand All @@ -382,6 +385,7 @@ tracing-subscriber = { workspace = true }
```

`shell/src/main.rs` structure:

```rust
// 1. Initialize tracing (structured JSON logging to journald)
// 2. Create AdwApplication
Expand Down
6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ resolver = "2"
# "services/logging" minecrarch-logging
# "services/updater" minecrarch-updater

members = []
members = [
"shared",
"shell",
"services/modpack-manager",
]

# Workspace-wide dependency versions — pin here, reference with { workspace = true } in members
[workspace.dependencies]
Expand Down
34 changes: 14 additions & 20 deletions deny.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@ targets = []

# ── License policy ────────────────────────────────────────────────────────────
[licenses]
# Only allow GPL-compatible licenses (MinecrarchOS targets GPLv3/MIT/Apache-2.0)
version = 2
# Only allow GPL-compatible licenses (MinecrarchOS targets GPLv3/MIT/Apache-2.0).
# Any crate with a license not in this list — including unlicensed crates — is denied.
allow = [
"MIT",
"Apache-2.0",
"Apache-2.0 WITH LLVM-exception",
"MPL-2.0",
"Unicode-DFS-2016",
"Unicode-3.0",
"ISC",
"BSD-2-Clause",
"BSD-3-Clause",
Expand All @@ -26,43 +29,34 @@ allow = [
"LGPL-3.0",
"LGPL-2.1",
]
deny = [
# Proprietary or non-distributable
"SSPL-1.0",
"BUSL-1.1",
]
unlicensed = "deny"
copyleft = "warn"

# ── Banned external crates ────────────────────────────────────────────────────
[bans]
multiple-versions = "warn"
wildcards = "deny"
# Path dependencies within the workspace don't carry version constraints by design.
# Crates.io wildcards (foo = "*") are still denied via the deny list below.
wildcards = "warn"
highlight = "all"

deny = [
# No OpenSSL — use rustls for TLS
{ name = "openssl" },
{ name = "openssl-sys" },

# No Tokio in shared/ — shared must be runtime-agnostic
# (enforced per-crate rather than globally — see layers.md)

# No direct GUI frameworks in services — services are headless
{ name = "gtk4", wrappers = ["minecrarch-modpack-manager", "minecrarch-overlay", "minecrarch-logging", "minecrarch-updater", "minecrarch-runtime"] },
]

# gtk4 is legitimately used by minecrarch-shell (ADR-0013).
# Enforcement that services don't pull in gtk4 is handled by tools/check-deps.sh,
# not by cargo-deny (which cannot scope bans per workspace member).

skip = []
skip-tree = []

# ── Security advisories ───────────────────────────────────────────────────────
# Advisories not checked in CI (requires network + advisory DB fetch).
# Run locally: cargo deny check advisories
[advisories]
db-path = "~/.cargo/advisory-db"
db-urls = ["https://github.com/rustsec/advisory-db"]
vulnerability = "deny"
unmaintained = "warn"
version = 2
yanked = "deny"
notice = "warn"

# ── Source policy ─────────────────────────────────────────────────────────────
[sources]
Expand Down
16 changes: 16 additions & 0 deletions services/modpack-manager/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "minecrarch-modpack-manager"
version = "0.1.0"
edition = "2021"
license = "MIT OR Apache-2.0"

[[bin]]
name = "minecrarch-modpack-manager"
path = "src/main.rs"

[dependencies]
zbus = { workspace = true }
tokio = { workspace = true }
tracing = { workspace = true }
tracing-subscriber = { workspace = true, features = ["env-filter", "json"] }
minecrarch-shared = { path = "../../shared", version = "0.1" }
3 changes: 3 additions & 0 deletions services/modpack-manager/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
println!("minecrarch-modpack-manager stub — Phase 1 D5 will replace this");
}
8 changes: 8 additions & 0 deletions shared/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "minecrarch-shared"
version = "0.1.0"
edition = "2021"
license = "MIT OR Apache-2.0"

[dependencies]
thiserror = { workspace = true }
40 changes: 40 additions & 0 deletions shared/src/dbus_types.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//! D-Bus type aliases and constants for MinecrarchOS IPC.
//! Full interface contracts are defined in docs/ipc.md.
//! Instance and snapshot data are passed as D-Bus dicts (a{sv}) per the IPC spec.

/// Field keys for an instance dict (`ListInstances` return type). D-Bus type: `a{sv}`.
pub mod instance_fields {
pub const ID: &str = "id";
pub const NAME: &str = "name";
pub const EDITION: &str = "edition";
pub const VERSION: &str = "version";
pub const STATUS: &str = "status";
}

/// Field keys for a snapshot dict (ListSnapshots return type).
/// D-Bus type: a{sv} with these keys.
pub mod snapshot_fields {
pub const ID: &str = "id";
pub const TIMESTAMP: &str = "timestamp";
pub const VERSION: &str = "version";
pub const SIZE_BYTES: &str = "size_bytes";
}

/// D-Bus error name prefix for all MinecrarchOS errors.
pub const ERROR_NAMESPACE: &str = "org.minecrarch.Error";

/// D-Bus bus names for all platform services.
pub mod bus_names {
pub const MODPACK_MANAGER: &str = "org.minecrarch.ModpackManager";
pub const OVERLAY: &str = "org.minecrarch.Overlay";
pub const UPDATER: &str = "org.minecrarch.Updater";
pub const LOGGING: &str = "org.minecrarch.Logging";
}

/// D-Bus object paths for all platform services.
pub mod object_paths {
pub const MODPACK_MANAGER: &str = "/org/minecrarch/ModpackManager";
pub const OVERLAY: &str = "/org/minecrarch/Overlay";
pub const UPDATER: &str = "/org/minecrarch/Updater";
pub const LOGGING: &str = "/org/minecrarch/Logging";
}
19 changes: 19 additions & 0 deletions shared/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use thiserror::Error;

#[derive(Debug, Error)]
pub enum MinecrarchError {
#[error("IPC error: {0}")]
Ipc(String),

#[error("Launch failed: {0}")]
Launch(String),

#[error("Install failed: {0}")]
Install(String),

#[error("Instance not found: {0}")]
InstanceNotFound(String),

#[error("IO error: {0}")]
Io(#[from] std::io::Error),
}
4 changes: 4 additions & 0 deletions shared/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/// Shared types, constants, and error definitions for MinecrarchOS components.
/// All IPC contracts are defined in docs/ipc.md.
pub mod dbus_types;
pub mod error;
19 changes: 19 additions & 0 deletions shell/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[package]
name = "minecrarch-shell"
version = "0.1.0"
edition = "2021"
license = "MIT OR Apache-2.0"

[[bin]]
name = "minecrarch-shell"
path = "src/main.rs"

[dependencies]
gtk4 = { version = "0.9", features = ["v4_12"] }
libadwaita = { version = "0.7", features = ["v1_5"] }
zbus = { workspace = true }
tokio = { workspace = true }
async-channel = "2"
tracing = { workspace = true }
tracing-subscriber = { workspace = true, features = ["env-filter", "json"] }
minecrarch-shared = { path = "../shared", version = "0.1" }
3 changes: 3 additions & 0 deletions shell/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
println!("minecrarch-shell stub — Phase 1 D4 will replace this");
}
4 changes: 3 additions & 1 deletion tools/check-deps.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ check_cargo_toml() {
fi

for dep in "${forbidden[@]}"; do
if grep -q "\"${dep}\"" "$file" || grep -q "'${dep}'" "$file"; then
# Match only dependency declarations (lines like `crate-name = ...` or `crate-name = { ... }`)
# Excludes [package] name = "..." lines by requiring the crate name at line start
if grep -qE "^[[:space:]]*${dep}[[:space:]]*(=|\\.)" "$file"; then
fail "${component} (${file}) must not depend on ${dep}"
fi
done
Expand Down
Loading