tawasuyu

sergio/takana

> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…

⎇ 8bf1623044075274682e4351a0f8e120047c2bed crates/hammer-core/src/recipe.rs Rust · 109 líneas · 3.0 KB Historia Quién tocó qué crudo

Scaffold inicial: workspace Rust + SDDs completos 8bf162304 · sergio ·

1//! La `Recipe`: descripción pura de un build. Ver `docs/02-build-lab.md` §1.
2
3use serde::{Deserialize, Serialize};
4
5use crate::hash::ArtifactHash;
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct Recipe {
9    pub name: String,
10    pub version: String,
11    pub source: Source,
12    pub build: Build,
13    #[serde(default)]
14    pub deps: Deps,
15}
16
17#[derive(Debug, Clone, Serialize, Deserialize)]
18pub struct Source {
19    pub repo: String,
20    /// Commit FIJADO. Nunca "HEAD". Ver ADR 0006.
21    pub commit: String,
22    #[serde(default)]
23    pub patches: Vec<String>,
24}
25
26#[derive(Debug, Clone, Serialize, Deserialize)]
27pub struct Build {
28    #[serde(default)]
29    pub compiler: Compiler,
30    #[serde(default = "default_target")]
31    pub target: String,
32    #[serde(default)]
33    pub link: LinkMode,
34    #[serde(default)]
35    pub flags: Vec<String>,
36}
37
38#[derive(Debug, Clone, Default, Serialize, Deserialize)]
39pub struct Deps {
40    #[serde(default)]
41    pub build: Vec<String>,
42    #[serde(default)]
43    pub runtime: Vec<String>,
44}
45
46/// Compilador del lab, POR RECETA (no global). `zig-cc` por defecto; escotilla a clang/gcc
47/// para paquetes con gcc-ismos. Ver ADR 0003.
48#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
49#[serde(rename_all = "kebab-case")]
50pub enum Compiler {
51    #[default]
52    ZigCc,
53    Clang,
54    Gcc,
55}
56
57impl Compiler {
58    pub fn as_str(&self) -> &'static str {
59        match self {
60            Compiler::ZigCc => "zig-cc",
61            Compiler::Clang => "clang",
62            Compiler::Gcc => "gcc",
63        }
64    }
65}
66
67#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
68#[serde(rename_all = "lowercase")]
69pub enum LinkMode {
70    #[default]
71    Static,
72    Dynamic,
73}
74
75fn default_target() -> String {
76    "x86_64-linux-musl".to_string()
77}
78
79impl Recipe {
80    pub fn from_toml(_s: &str) -> crate::Result<Recipe> {
81        // TODO(fase-0): parsear TOML. Por ahora el parsing real lo añadiremos al implementar
82        // `hammer build`; el contrato (esta struct) ya está fijado.
83        Err(crate::Error::Recipe(
84            "parsing de receta TOML pendiente (Fase 0)".into(),
85        ))
86    }
87
88    /// Las entradas canónicas que alimentan el `ArtifactHash` de esta receta.
89    /// NOTA: el hash final también incorpora los hashes de las deps de build (recursivo),
90    /// que el lab resuelve antes de llamar aquí. Ver `docs/02-build-lab.md` §2 y §5.
91    pub fn hash_inputs(&self, dep_hashes: &[ArtifactHash]) -> Vec<Vec<u8>> {
92        let mut v: Vec<Vec<u8>> = vec![
93            self.source.commit.as_bytes().to_vec(),
94            self.build.compiler.as_str().as_bytes().to_vec(),
95            self.build.target.as_bytes().to_vec(),
96            format!("{:?}", self.build.link).into_bytes(),
97        ];
98        for p in &self.source.patches {
99            v.push(p.as_bytes().to_vec());
100        }
101        for f in &self.build.flags {
102            v.push(f.as_bytes().to_vec());
103        }
104        for d in dep_hashes {
105            v.push(d.as_str().as_bytes().to_vec());
106        }
107        v
108    }
109}