From 40de99384912f49d0041d6c4935960cb7f09baa2 Mon Sep 17 00:00:00 2001 From: ToBinio Date: Thu, 9 Apr 2026 08:13:54 +0200 Subject: [PATCH] add service parsing --- Cargo.lock | 102 ++++++++++++++++++ Cargo.toml | 3 + src/main.rs | 10 +- src/project.rs | 29 +++++ tests/projects/1/compose.yml | 9 ++ .../projects/another-project-path/compose.yml | 29 +++++ tests/projects/nested/2/compose.yml | 49 +++++++++ 7 files changed, 230 insertions(+), 1 deletion(-) create mode 100644 src/project.rs diff --git a/Cargo.lock b/Cargo.lock index 6cdb8e8..8a601d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -67,6 +67,12 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "anyhow" +version = "1.0.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" + [[package]] name = "backtrace" version = "0.3.76" @@ -191,6 +197,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + [[package]] name = "eyre" version = "0.6.12" @@ -216,6 +228,12 @@ version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + [[package]] name = "heck" version = "0.5.0" @@ -228,6 +246,16 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5" +[[package]] +name = "indexmap" +version = "2.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45a8a2b9cb3e0b0c1803dbb0758ffac5de2f425b23c28f518faabd9d805342ff" +dependencies = [ + "equivalent", + "hashbrown", +] + [[package]] name = "indicatif" version = "0.18.4" @@ -256,6 +284,12 @@ dependencies = [ "either", ] +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + [[package]] name = "js-sys" version = "0.3.94" @@ -278,6 +312,16 @@ version = "0.2.184" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" +[[package]] +name = "libyml" +version = "0.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3302702afa434ffa30847a83305f0a69d6abd74293b6554c18ec85c7ef30c980" +dependencies = [ + "anyhow", + "version_check", +] + [[package]] name = "memchr" version = "2.8.0" @@ -351,6 +395,8 @@ dependencies = [ "fuzzy-matcher", "indicatif", "itertools", + "serde", + "serde_yml", ] [[package]] @@ -374,6 +420,56 @@ version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +[[package]] +name = "ryu" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_yml" +version = "0.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59e2dd588bf1597a252c3b920e0143eb99b0f76e4e082f4c92ce34fbc9e71ddd" +dependencies = [ + "indexmap", + "itoa", + "libyml", + "memchr", + "ryu", + "serde", + "version_check", +] + [[package]] name = "sharded-slab" version = "0.1.7" @@ -480,6 +576,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + [[package]] name = "wasm-bindgen" version = "0.2.117" diff --git a/Cargo.toml b/Cargo.toml index cb56a41..ffc9e60 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,3 +13,6 @@ indicatif = "0.18.4" fuzzy-matcher = "0.3.7" itertools = "0.14.0" + +serde = "1.0.228" +serde_yml = "0.0.12" diff --git a/src/main.rs b/src/main.rs index dd5c04b..586a670 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,6 +12,10 @@ use console::{Key, Term, style}; use fuzzy_matcher::skim::SkimMatcherV2; use itertools::Itertools; +use crate::project::Project; + +mod project; + #[derive(Parser)] #[command(version, about, long_about = None)] #[command(propagate_version = true)] @@ -39,7 +43,11 @@ fn update() -> Result<()> { term.hide_cursor()?; let project = select_project(&mut term)?; - writeln!(term, "Selected: {:?}", project)?; + + let path = current_dir()?.join(project).join("compose.yml"); + let project = Project::new(&path)?; + + writeln!(term, "services: {:?}", project.services()?)?; term.show_cursor()?; diff --git a/src/project.rs b/src/project.rs new file mode 100644 index 0000000..4f2f30d --- /dev/null +++ b/src/project.rs @@ -0,0 +1,29 @@ +use std::{fs, path::Path}; + +use color_eyre::eyre::{ContextCompat, Result}; +use serde_yml::Value; + +pub struct Project { + document: Value, +} + +impl Project { + pub fn new(path: &Path) -> Result { + let file = fs::read_to_string(path)?; + let value: Value = serde_yml::from_str(&file)?; + + Ok(Project { document: value }) + } + + pub fn services(&self) -> Result> { + Ok(self + .document + .get("services") + .context("invalid compose.yml - no 'services'")? + .as_mapping() + .context("invalid compose.yml - no services is not mapping")? + .keys() + .filter_map(|key| key.as_str().map(|text| text.to_string())) + .collect()) + } +} diff --git a/tests/projects/1/compose.yml b/tests/projects/1/compose.yml index e69de29..331309d 100644 --- a/tests/projects/1/compose.yml +++ b/tests/projects/1/compose.yml @@ -0,0 +1,9 @@ +version: "3.9" + +services: + web: + image: nginx:alpine + container_name: simple_web + ports: + - "8080:80" + restart: unless-stopped diff --git a/tests/projects/another-project-path/compose.yml b/tests/projects/another-project-path/compose.yml index e69de29..caae467 100644 --- a/tests/projects/another-project-path/compose.yml +++ b/tests/projects/another-project-path/compose.yml @@ -0,0 +1,29 @@ +version: "3.9" + +services: + app: + image: node:20-alpine + container_name: node_app + working_dir: /app + volumes: + - ./app:/app + command: ["node", "server.js"] + ports: + - "3000:3000" + depends_on: + - db + restart: unless-stopped + + db: + image: postgres:16-alpine + container_name: postgres_db + environment: + POSTGRES_USER: user + POSTGRES_PASSWORD: password + POSTGRES_DB: appdb + volumes: + - db_data:/var/lib/postgresql/data + restart: unless-stopped + +volumes: + db_data: diff --git a/tests/projects/nested/2/compose.yml b/tests/projects/nested/2/compose.yml index e69de29..0cbeee8 100644 --- a/tests/projects/nested/2/compose.yml +++ b/tests/projects/nested/2/compose.yml @@ -0,0 +1,49 @@ +version: "3.9" + +services: + frontend: + image: nginx:alpine + container_name: frontend + ports: + - "8080:80" + volumes: + - ./frontend:/usr/share/nginx/html:ro + depends_on: + - backend + restart: unless-stopped + + backend: + image: python:3.12-alpine + container_name: backend + working_dir: /app + volumes: + - ./backend:/app + command: ["python", "app.py"] + ports: + - "5000:5000" + environment: + DATABASE_URL: postgres://user:password@db:5432/appdb + REDIS_URL: redis://cache:6379 + depends_on: + - db + - cache + restart: unless-stopped + + db: + image: postgres:16-alpine + container_name: db + environment: + POSTGRES_USER: user + POSTGRES_PASSWORD: password + POSTGRES_DB: appdb + volumes: + - db_data:/var/lib/postgresql/data + restart: unless-stopped + + cache: + image: redis:7-alpine + container_name: redis_cache + restart: unless-stopped + +volumes: + db_data: -- 2.51.2