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
98 changes: 98 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# The gate AGENTS.md already documents — format, lint, test, doc — enforced.
# Until now nothing ran `cargo clippy -D warnings` or `cargo test --workspace`
# in CI, so lint regressions landed on `main` unnoticed (14 of them in the
# cockpit alone). The wasm render is checked separately by cockpit-web-test.
#
# `fuzz/` is a nightly, non-member crate (ADR-0010), so `--workspace` never
# reaches it; the fuzz gate stays its own concern.
name: ci
on:
pull_request:
push:
branches: [main]

permissions:
contents: read

env:
CARGO_TERM_COLOR: always

jobs:
check:
runs-on: ubuntu-latest
steps:
# persist-credentials: false — later steps compile and run PR-authored
# code (build scripts, tests), so don't leave the token in .git/config
# for them to read (zizmor: artipacked).
- uses: actions/checkout@v4
with:
persist-credentials: false

# rust-toolchain.toml pins the channel and pulls in rustfmt + clippy.
- name: Show toolchain
run: rustc --version && cargo clippy --version && cargo fmt --version

- name: Cache cargo
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ci-${{ hashFiles('Cargo.lock', '**/Cargo.toml') }}

# eframe needs a windowing/GL stack to *link* the cockpit's native target.
- name: Install native deps
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libxcb-render0-dev libxcb-shape0-dev \
libxcb-xfixes0-dev libxkbcommon-dev libssl-dev

- name: Format
run: cargo fmt --all --check
- name: Lint
run: cargo clippy --workspace --all-targets -- -D warnings
- name: Test
run: cargo test --workspace
# Not yet `-D warnings`: rustdoc flags five pre-existing findings in
# griff-core (an unresolved `AtomRest` link, public docs linking to
# private items). Deny once those are cleared.
- name: Doc
run: cargo doc --no-deps --workspace

# The MSRV is a promise; build on it or it rots. It sat at 1.74 for a year
# while egui/eframe 0.34 already demanded 1.92 — nobody on 1.74 could have
# built the cockpit.
msrv:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false

- name: Read the MSRV from the workspace manifest
id: msrv
run: |
v=$(grep -m1 -E '^rust-version' Cargo.toml | grep -oE '[0-9]+\.[0-9]+(\.[0-9]+)?')
echo "version=$v" >> "$GITHUB_OUTPUT"
echo "workspace MSRV: $v"
- name: Install the MSRV toolchain
run: rustup toolchain install ${{ steps.msrv.outputs.version }} --profile minimal

- name: Cache cargo
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: msrv-${{ steps.msrv.outputs.version }}-${{ hashFiles('Cargo.lock') }}

- name: Install native deps
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libxcb-render0-dev libxcb-shape0-dev \
libxcb-xfixes0-dev libxkbcommon-dev libssl-dev

- name: Build on the MSRV
run: cargo +${{ steps.msrv.outputs.version }} check --workspace --all-targets
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ resolver = "2"
[workspace.package]
version = "0.1.0"
edition = "2021"
rust-version = "1.74"
rust-version = "1.92"
license = "MIT"
repository = "https://github.com/physshell/griff"
homepage = "https://github.com/physshell/griff"
Expand Down
29 changes: 17 additions & 12 deletions cockpit/src/generation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@
//! I/O the native app owns (the web app reads the same records out of OPFS), and
//! the provenance a kept candidate is stamped with.

#[cfg(not(target_arch = "wasm32"))]
use std::path::Path;

#[cfg(not(target_arch = "wasm32"))]
use griff_core::corpus::ChunkMeta;
#[cfg(not(target_arch = "wasm32"))]
use griff_core::generation_input::CorpusMaterial;
use griff_core::generation_input::GenerationAsk;
use griff_ui_core::generate::CandidateSet;

Expand Down Expand Up @@ -53,7 +60,7 @@ impl GeneratePanel {
/// A panel with the CLI's defaults (`griff generate`: seed 0, 8 bars,
/// 2 variants per strategy, gesture on).
#[must_use]
pub fn new() -> Self {
pub const fn new() -> Self {
Self {
open: false,
sources: Vec::new(),
Expand Down Expand Up @@ -92,14 +99,16 @@ impl GeneratePanel {
#[derive(Debug)]
pub struct LoadedCorpus {
/// The rhythm/novelty/gesture material.
pub material: griff_core::generation_input::CorpusMaterial,
pub material: CorpusMaterial,
/// The distinct source tabs the records point at, by first-seen order.
pub sources: Vec<SourceTab>,
}

/// Reads a corpus *directory* — the native app's I/O half, mirroring what the
/// CLI's `load_corpus_material` does and what the web app does over OPFS. Every
/// musical decision (slicing, rhythm extraction, gesture aggregation) is core's.
/// Reads a corpus *directory* — the native app's I/O half.
///
/// Mirrors what the CLI's `load_corpus_material` does and what the web app does
/// over OPFS. Every musical decision (slicing, rhythm extraction, gesture
/// aggregation) is core's.
///
/// Records are visited in sorted order, so the rhythm-template palette is
/// deterministic. A record whose source is missing, unreadable, unimportable, or
Expand All @@ -108,7 +117,7 @@ pub struct LoadedCorpus {
/// # Errors
/// A message when `dir` cannot be read.
#[cfg(not(target_arch = "wasm32"))]
pub fn load_corpus_dir(dir: &std::path::Path) -> Result<LoadedCorpus, String> {
pub fn load_corpus_dir(dir: &Path) -> Result<LoadedCorpus, String> {
use std::fs;

use griff_core::generation_input::{corpus_material, prepare_chunk};
Expand Down Expand Up @@ -159,14 +168,10 @@ pub fn load_corpus_dir(dir: &std::path::Path) -> Result<LoadedCorpus, String> {
/// Reads one record and the bytes of the tab it names. `None` when either is
/// missing or unparseable.
#[cfg(not(target_arch = "wasm32"))]
fn read_record(
dir: &std::path::Path,
record: &str,
) -> Option<(griff_core::corpus::ChunkMeta, Vec<u8>)> {
fn read_record(dir: &Path, record: &str) -> Option<(ChunkMeta, Vec<u8>)> {
use std::fs;

let meta: griff_core::corpus::ChunkMeta =
serde_json::from_str(&fs::read_to_string(dir.join(record)).ok()?).ok()?;
let meta: ChunkMeta = serde_json::from_str(&fs::read_to_string(dir.join(record)).ok()?).ok()?;
let bytes = fs::read(dir.join(&meta.source.filename)).ok()?;
Some((meta, bytes))
}
Expand Down
Loading
Loading