Commit

Author:

Hash:

Timestamp:

+49 -16 +/-7 browse

Kevin Schoon [me@kevinschoon.com]

68d497f78ad2d99a167af50aea55af6b990ffc99

Wed, 13 May 2026 06:43:13 +0000 (4 weeks ago)

allow specifying collection/repository as an argument to ayllu-build
allow specifying collection/repository as an argument to ayllu-build

Additionally adds the --stdin flag which will allow for systemd
socket activation of builds.
1diff --git a/Cargo.lock b/Cargo.lock
2index fdfc10a..3e41c76 100644
3--- a/Cargo.lock
4+++ b/Cargo.lock
5 @@ -2207,6 +2207,7 @@ dependencies = [
6 "ayllu_api",
7 "ayllu_cmd",
8 "ayllu_config",
9+ "ayllu_git",
10 "reqwest",
11 "serde",
12 "thiserror 2.0.18",
13 diff --git a/Containerfile.build b/Containerfile.build
14index 1442266..0f5012c 100644
15--- a/Containerfile.build
16+++ b/Containerfile.build
17 @@ -1,6 +1,6 @@
18 FROM docker.io/alpine:3.23
19
20- RUN apk add cargo rust pkgconf build-base git
21+ RUN apk add cargo rust rustfmt pkgconf build-base git sqlite sqlite-dev
22 RUN adduser -D -h /src -s /bin/sh ayllu
23 USER ayllu
24 WORKDIR /src
25 diff --git a/ayllu-build/src/config.rs b/ayllu-build/src/config.rs
26index 2147521..0883c1a 100644
27--- a/ayllu-build/src/config.rs
28+++ b/ayllu-build/src/config.rs
29 @@ -1,5 +1,6 @@
30 use std::path::{Path, PathBuf};
31
32+ use ayllu_git::Collection;
33 use serde::{Deserialize, Serialize};
34
35 use ayllu_config::{Configurable, Database, Error, Reader, data_dir};
36 @@ -44,6 +45,8 @@ pub struct Config {
37 pub database: Database,
38 #[serde(default = "Builder::default")]
39 pub builder: Builder,
40+ #[serde(default = "Vec::new")]
41+ pub collections: Vec<Collection>,
42 }
43
44 impl Configurable for Config {}
45 diff --git a/ayllu-build/src/evaluate.rs b/ayllu-build/src/evaluate.rs
46index 2a812a7..e4f7759 100644
47--- a/ayllu-build/src/evaluate.rs
48+++ b/ayllu-build/src/evaluate.rs
49 @@ -55,7 +55,6 @@ impl Source {
50 #[allow(dead_code)]
51 pub(crate) struct Runtime {
52 // parallelism: bool,
53- pub tee_output: bool,
54 pub db: Database,
55 pub source: Source,
56 pub work_dir: PathBuf,
57 @@ -231,7 +230,7 @@ impl Runtime {
58 ) -> Result<i32, Error> {
59 let (manifest_id, graph) = self.allocate()?;
60 let source_dir = match &self.source {
61- Source::Path(path_buf) => path_buf.as_path().parent().unwrap(),
62+ Source::Path(path_buf) => path_buf.as_path(),
63 _ => todo!(),
64 };
65 let package = Package {
66 diff --git a/ayllu-build/src/main.rs b/ayllu-build/src/main.rs
67index 617b902..5570f66 100644
68--- a/ayllu-build/src/main.rs
69+++ b/ayllu-build/src/main.rs
70 @@ -5,7 +5,10 @@ use tracing::Level;
71 use ayllu_cmd::build::{Command, Commands};
72 use ayllu_database::Wrapper as Database;
73
74- use crate::evaluate::{Runtime, Source};
75+ use crate::{
76+ config::Config,
77+ evaluate::{Runtime, Source},
78+ };
79
80 mod config;
81 mod error;
82 @@ -17,6 +20,20 @@ mod package;
83
84 const DEFAULT_BUILD_FILE: &str = ".ayllu-build.json";
85
86+ type Error = Box<dyn std::error::Error>;
87+
88+ fn read_source(cfg: &Config, input: &str) -> Result<Source, Error> {
89+ let (collection, name) = input.split_once("/").unwrap();
90+ match ayllu_git::find(
91+ cfg.collections.as_slice(),
92+ collection,
93+ name.trim_end_matches("\n"),
94+ )? {
95+ Some(repo) => Ok(Source::Path(repo.path.to_path_buf())),
96+ None => Err("Cannot find repository".into()),
97+ }
98+ }
99+
100 #[tokio::main(flavor = "current_thread")]
101 async fn main() -> Result<(), Box<dyn std::error::Error>> {
102 let cli = ayllu_cmd::parse::<Command>();
103 @@ -24,17 +41,27 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
104 ayllu_logging::init(Level::INFO); // FIXME
105 match cli.command {
106 Commands::Evaluate {
107- alternate_path,
108- tee_output,
109+ source,
110+ stdin,
111+ name,
112 } => {
113+ let source = if stdin {
114+ tracing::info!("Reading source from stdin for build {name:?}");
115+ let mut line = String::new();
116+ std::io::stdin().read_line(&mut line).unwrap();
117+ read_source(&cfg, &line)?
118+ } else {
119+ match source {
120+ Some(path) => Source::Path(Path::new(&path).to_path_buf()),
121+ None => Source::Path(std::fs::canonicalize(Path::new("."))?),
122+ }
123+ };
124+
125 let workdir = cfg.builder.work_dir.clone();
126 let db = Database::new(&cfg.database.path)?;
127- let source_path = alternate_path.unwrap_or(Path::new(DEFAULT_BUILD_FILE).to_path_buf());
128- let source_path = std::fs::canonicalize(source_path)?;
129 let mut rt = Runtime {
130 db,
131- source: Source::Path(source_path),
132- tee_output,
133+ source,
134 work_dir: workdir.clone(),
135 init_path: cfg.builder.init_binary.clone(),
136 };
137 diff --git a/ayllu-web/src/main.rs b/ayllu-web/src/main.rs
138index 69e002f..e2b6310 100644
139--- a/ayllu-web/src/main.rs
140+++ b/ayllu-web/src/main.rs
141 @@ -43,7 +43,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
142 name: String::from("Default"),
143 description: Some(format!("Collection @ {}", path.to_string_lossy())),
144 path,
145- ..Default::default()
146+ hidden: Default::default(),
147 })
148 }
149 init_logger(
150 diff --git a/crates/cmd/src/build.rs b/crates/cmd/src/build.rs
151index 659e56f..4eb74b8 100644
152--- a/crates/cmd/src/build.rs
153+++ b/crates/cmd/src/build.rs
154 @@ -44,11 +44,14 @@ pub enum Environment {
155 pub enum Commands {
156 /// evaluate a local build script
157 Evaluate {
158- /// Path to your configuration file
159- #[arg(value_name = "FILE")]
160- alternate_path: Option<PathBuf>,
161- /// "Tee" output from the executor to your local stdout/stderr
162+ /// Read the collection / name from stdin
163 #[arg(short, long, action)]
164- tee_output: bool,
165+ stdin: bool,
166+ /// Unique build name
167+ #[arg(short, long)]
168+ name: Option<String>,
169+ /// Build Source can be PATH or collection/name
170+ #[arg(value_name = "SOURCE")]
171+ source: Option<String>,
172 },
173 }