From fd317d51c13d5e8b1c969e9511fc4b69c628eeb7 Mon Sep 17 00:00:00 2001 From: David Perl Date: Tue, 7 Jul 2026 15:30:33 +0200 Subject: [PATCH 1/2] ci: copy basic CI from bec log ingestor --- .gitea/workflows/check-and-lint.yaml | 56 +++++++++++++++++++++++++ .gitea/workflows/release.yaml | 39 +++++++++++++++++ .gitea/workflows/test-and-coverage.yaml | 29 +++++++++++++ Cargo.toml | 17 ++++++++ README.md | 20 ++++++++- src/main.rs | 2 +- 6 files changed, 161 insertions(+), 2 deletions(-) create mode 100644 .gitea/workflows/check-and-lint.yaml create mode 100644 .gitea/workflows/release.yaml create mode 100644 .gitea/workflows/test-and-coverage.yaml diff --git a/.gitea/workflows/check-and-lint.yaml b/.gitea/workflows/check-and-lint.yaml new file mode 100644 index 0000000..c153a10 --- /dev/null +++ b/.gitea/workflows/check-and-lint.yaml @@ -0,0 +1,56 @@ +name: Check and Lint + +on: + pull_request: + push: + branches: + - main + +jobs: + check: + name: Check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: https://github.com/dtolnay/rust-toolchain@stable + - uses: https://github.com/Swatinem/rust-cache@v2 + - run: cargo check --all-targets + + fmt: + name: Rustfmt + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: https://github.com/dtolnay/rust-toolchain@stable + with: + components: rustfmt + - run: cargo fmt --all -- --check + + clippy: + name: Clippy + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: https://github.com/dtolnay/rust-toolchain@stable + with: + components: clippy + - uses: https://github.com/Swatinem/rust-cache@v2 + - run: cargo clippy --all-targets --all-features -- -D warnings + + build-rpm: + name: Build RPM + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: https://github.com/dtolnay/rust-toolchain@stable + - uses: https://github.com/Swatinem/rust-cache@v2 + - name: Build RPM + run: | + cargo build --release + strip -s target/release/aarel + cargo install cargo-generate-rpm + cargo generate-rpm + - uses: https://github.com/actions/upload-artifact@v3 + with: + name: rpm + path: target/generate-rpm/*.rpm diff --git a/.gitea/workflows/release.yaml b/.gitea/workflows/release.yaml new file mode 100644 index 0000000..6f5eae9 --- /dev/null +++ b/.gitea/workflows/release.yaml @@ -0,0 +1,39 @@ +name: Release + +on: + push: + tags: + - "v*" + +env: + RUST_BACKTRACE: 1 + +jobs: + build-rpm: + name: Build and push RPM + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: https://github.com/dtolnay/rust-toolchain@stable + - uses: https://github.com/Swatinem/rust-cache@v2 + + - name: Build RPM + run: | + cargo build --release + strip -s target/release/aarel + cargo install cargo-generate-rpm + cargo generate-rpm + + - uses: actions/upload-artifact@v3 + with: + name: rpm + path: target/generate-rpm/*.rpm + + - name: Push to Gitea RPM registry + run: | + for pkg in target/generate-rpm/*.rpm; do + curl -f -X PUT \ + --user "${{ secrets.GITEA_REGISTRY_TOKEN }}" \ + --upload-file "$pkg" \ + "https://gitea.psi.ch/api/packages/${{ github.repository_owner }}/rpm/upload" + done diff --git a/.gitea/workflows/test-and-coverage.yaml b/.gitea/workflows/test-and-coverage.yaml new file mode 100644 index 0000000..9f376e2 --- /dev/null +++ b/.gitea/workflows/test-and-coverage.yaml @@ -0,0 +1,29 @@ +name: Test and Coverage + +on: [push, pull_request] + +jobs: + test: + name: Test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: https://github.com/dtolnay/rust-toolchain@stable + - uses: https://github.com/Swatinem/rust-cache@v2 + - run: cargo test --all-features + + coverage: + name: Coverage + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: https://github.com/dtolnay/rust-toolchain@stable + - uses: https://github.com/Swatinem/rust-cache@v2 + - name: Install cargo-tarpaulin + run: cargo install cargo-tarpaulin + - name: Generate code coverage + run: cargo tarpaulin --verbose --all-features --workspace --timeout 120 --out xml + - uses: https://github.com/actions/upload-artifact@v3 + with: + name: coverage + path: cobertura.xml diff --git a/Cargo.toml b/Cargo.toml index 44e4c1a..839e9d4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,25 @@ [package] name = "aare_launcher" +description = "Launcher for AareDAQ applications on MX beamline consoles at PSI" +readme = "README.md" +repository = "https://gitea.psi.ch/perl_d/aare_launcher" +keywords = ["mx", "beamline", "launcher", "tui"] +categories = ["science", "command-line-utilities"] +license = "GPL-3.0-only" version = "0.1.0" edition = "2024" +# The installed command is `aarel`. +[[bin]] +name = "aarel" +path = "src/main.rs" + +[package.metadata.generate-rpm] +assets = [ + { source = "target/release/aarel", dest = "/usr/local/bin/aarel", mode = "755" }, + { source = "data/defaults.json", dest = "/etc/aarel/defaults.json", mode = "644", config = true }, +] + [dependencies] anyhow = "1.0.103" clap = { version = "4.6.1", features = ["derive"] } diff --git a/README.md b/README.md index e89613c..ccb6956 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,21 @@ # aare_launcher -cli/tui launcher for aare daq+gui \ No newline at end of file +[![Check and Lint](https://gitea.psi.ch/perl_d/aare_launcher/actions/workflows/check-and-lint.yaml/badge.svg)](https://gitea.psi.ch/perl_d/aare_launcher/actions?workflow=check-and-lint.yaml) +[![Test and Coverage](https://gitea.psi.ch/perl_d/aare_launcher/actions/workflows/test-and-coverage.yaml/badge.svg)](https://gitea.psi.ch/perl_d/aare_launcher/actions?workflow=test-and-coverage.yaml) +[![License: GPL-3.0](https://img.shields.io/badge/license-GPL--3.0-blue.svg)](LICENSE) + +CLI/TUI launcher for the AareDAQ server and GUI on MX beamline consoles at PSI. + +Installed as the `aarel` command. It detects the current beamline and launches the +matching application, or opens a TUI to pick one. + +## Usage + +``` +aarel pick # open the TUI to choose what to launch +aarel gui # launch the GUI for the detected beamline +aarel server # launch the server for the detected beamline +``` + +Use `--entry ` with `gui`/`server` to override detection, and `--config +` to use a different config file. diff --git a/src/main.rs b/src/main.rs index 9f74231..7569ed1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,7 +11,7 @@ use config::{Config, LauncherEntry, load_config}; use detect::detect_beamline; #[derive(Parser)] -#[command(name = "aare_launcher")] +#[command(name = "aarel")] struct Cli { /// Path to the launcher config file. #[arg(long, default_value = "data/defaults.json")] -- 2.54.0 From f4fe88995610be6219ec7d6741af5de5fa294930 Mon Sep 17 00:00:00 2001 From: David Perl Date: Tue, 7 Jul 2026 15:40:21 +0200 Subject: [PATCH 2/2] style: cargo fmt --- .gitea/workflows/check-and-lint.yaml | 4 ++++ .gitea/workflows/release.yaml | 6 +++++- .gitea/workflows/test-and-coverage.yaml | 8 +++++++- src/config.rs | 14 ++++++++++---- src/tui/entries.rs | 6 +++++- src/tui/mod.rs | 8 ++------ 6 files changed, 33 insertions(+), 13 deletions(-) diff --git a/.gitea/workflows/check-and-lint.yaml b/.gitea/workflows/check-and-lint.yaml index c153a10..554579b 100644 --- a/.gitea/workflows/check-and-lint.yaml +++ b/.gitea/workflows/check-and-lint.yaml @@ -6,6 +6,10 @@ on: branches: - main +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: check: name: Check diff --git a/.gitea/workflows/release.yaml b/.gitea/workflows/release.yaml index 6f5eae9..d274d0e 100644 --- a/.gitea/workflows/release.yaml +++ b/.gitea/workflows/release.yaml @@ -8,6 +8,10 @@ on: env: RUST_BACKTRACE: 1 +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: build-rpm: name: Build and push RPM @@ -33,7 +37,7 @@ jobs: run: | for pkg in target/generate-rpm/*.rpm; do curl -f -X PUT \ - --user "${{ secrets.GITEA_REGISTRY_TOKEN }}" \ + --user "${{ secrets.GITEA_TOKEN }}" \ --upload-file "$pkg" \ "https://gitea.psi.ch/api/packages/${{ github.repository_owner }}/rpm/upload" done diff --git a/.gitea/workflows/test-and-coverage.yaml b/.gitea/workflows/test-and-coverage.yaml index 9f376e2..56db6b9 100644 --- a/.gitea/workflows/test-and-coverage.yaml +++ b/.gitea/workflows/test-and-coverage.yaml @@ -2,6 +2,10 @@ name: Test and Coverage on: [push, pull_request] +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: test: name: Test @@ -20,7 +24,9 @@ jobs: - uses: https://github.com/dtolnay/rust-toolchain@stable - uses: https://github.com/Swatinem/rust-cache@v2 - name: Install cargo-tarpaulin - run: cargo install cargo-tarpaulin + run: | + cargo install cargo-binstall + cargo binstall cargo-tarpaulin - name: Generate code coverage run: cargo tarpaulin --verbose --all-features --workspace --timeout 120 --out xml - uses: https://github.com/actions/upload-artifact@v3 diff --git a/src/config.rs b/src/config.rs index ca4ed23..453c856 100644 --- a/src/config.rs +++ b/src/config.rs @@ -81,8 +81,8 @@ impl RawLauncherEntry { /// Parse a `defaults.json` document into a resolved [`Config`]. pub fn load_config(json: &str) -> Result { let deserializer = &mut serde_json::Deserializer::from_str(json); - let raw: RawConfig = serde_path_to_error::deserialize(deserializer) - .context("failed to parse config JSON")?; + let raw: RawConfig = + serde_path_to_error::deserialize(deserializer).context("failed to parse config JSON")?; let entries = raw .map @@ -134,7 +134,10 @@ mod tests { let entry = &config.entries["x10sa"]; assert_eq!(entry.python, PathBuf::from("/venvs/pxii/bin/python")); - assert_eq!(entry.gui_file, PathBuf::from("/apps/aaredaq-pxii/custom/gui.py")); + assert_eq!( + entry.gui_file, + PathBuf::from("/apps/aaredaq-pxii/custom/gui.py") + ); assert_eq!( entry.server_file, PathBuf::from("/apps/aaredaq-pxii/custom/server.py") @@ -147,7 +150,10 @@ mod tests { let entry = &config.entries["x06da"]; assert_eq!(entry.python, PathBuf::from("/venvs/pxiii/bin/python")); - assert_eq!(entry.gui_file, PathBuf::from("/apps/aaredaq-pxiii/src/gui.py")); + assert_eq!( + entry.gui_file, + PathBuf::from("/apps/aaredaq-pxiii/src/gui.py") + ); assert_eq!( entry.server_file, PathBuf::from("/apps/aaredaq-pxiii/src/server.py") diff --git a/src/tui/entries.rs b/src/tui/entries.rs index fe21514..37c203a 100644 --- a/src/tui/entries.rs +++ b/src/tui/entries.rs @@ -117,7 +117,11 @@ impl<'a> EntriesTab<'a> { let [list_area, detail_area] = Layout::horizontal([Constraint::Percentage(30), Constraint::Min(0)]).areas(area); - let items: Vec = self.keys.iter().map(|k| ListItem::new(k.as_str())).collect(); + let items: Vec = self + .keys + .iter() + .map(|k| ListItem::new(k.as_str())) + .collect(); let list = List::new(items) .block(Block::default().borders(Borders::ALL).title("Entries")) .highlight_style(Style::default().add_modifier(Modifier::BOLD | Modifier::REVERSED)) diff --git a/src/tui/mod.rs b/src/tui/mod.rs index d993dee..dc8fe36 100644 --- a/src/tui/mod.rs +++ b/src/tui/mod.rs @@ -50,10 +50,7 @@ pub fn run(config: &Config) -> Result> { result } -fn run_app( - terminal: &mut DefaultTerminal, - config: &Config, -) -> Result> { +fn run_app(terminal: &mut DefaultTerminal, config: &Config) -> Result> { let mut app = App::new(config); loop { @@ -129,8 +126,7 @@ fn draw(frame: &mut Frame, app: &mut App) { _ => app.custom.draw(frame, content_area), } - let footer = Paragraph::new(help_text(app)) - .style(Style::default().add_modifier(Modifier::DIM)); + let footer = Paragraph::new(help_text(app)).style(Style::default().add_modifier(Modifier::DIM)); frame.render_widget(footer, footer_area); } -- 2.54.0