1use extism_pdk::*;
2use fluentci_types::{cache::Cache, nix::NixArgs, pipeline as types, service::Service};
3use serde::{Deserialize, Serialize};
4
5use super::{
6 devbox::Devbox, devenv::Devenv, envhub::Envhub, file::File, flox::Flox, git::Git,
7 hermit::Hermit, mise::Mise, nix::Nix, pixi::Pixi, pkgx::Pkgx,
8};
9
10#[host_fn]
11extern "ExtismHost" {
12 fn set_runner(runner: String);
13 fn devbox() -> Json<Devbox>;
14 fn devenv() -> Json<Devenv>;
15 fn flox() -> Json<Flox>;
16 fn nix(args: Json<NixArgs>) -> Json<Nix>;
17 fn pkgx() -> Json<Pkgx>;
18 fn pixi() -> Json<Pixi>;
19 fn hermit() -> Json<Hermit>;
20 fn git(url: String) -> Json<Git>;
21 fn http(url: String) -> Json<File>;
22 fn mise() -> Json<Mise>;
23 fn envhub() -> Json<Envhub>;
24 fn with_exec(args: Json<Vec<String>>);
25 fn with_workdir(path: String);
26 fn with_cache(cache: Json<Cache>);
27 fn with_file(file: Json<File>);
28 fn stdout() -> String;
29 fn stderr() -> String;
30 fn as_service(name: String) -> Json<Service>;
31 fn with_service(service_id: String);
32 fn set_envs(envs: Json<Vec<(String, String)>>);
33 fn wait_on(args: Json<Vec<u32>>);
34 fn with_secret_variable(params: Json<Vec<String>>);
35}
36
37#[derive(Serialize, Deserialize)]
38pub struct Pipeline {
39 pub id: String,
40}
41
42impl From<types::Pipeline> for Pipeline {
43 fn from(pipeline: types::Pipeline) -> Self {
44 Pipeline { id: pipeline.id }
45 }
46}
47
48impl Pipeline {
49 pub fn devbox(&self) -> Result<Devbox, Error> {
50 unsafe { set_runner("devbox".into()) }?;
51 let devbox = unsafe { devbox() }?;
52 Ok(devbox.into_inner())
53 }
54
55 pub fn devenv(&self) -> Result<Devenv, Error> {
56 unsafe { set_runner("devenv".into()) }?;
57 let devenv = unsafe { devenv() }?;
58 Ok(devenv.into_inner())
59 }
60
61 pub fn flox(&self) -> Result<Flox, Error> {
62 unsafe { set_runner("flox".into()) }?;
63 let flox = unsafe { flox() }?;
64 Ok(flox.into_inner())
65 }
66
67 pub fn nix(&self, args: NixArgs) -> Result<Nix, Error> {
68 unsafe { set_runner("nix".into()) }?;
69 let nix = unsafe { nix(Json(args)) }?;
70 Ok(nix.into_inner())
71 }
72
73 pub fn pkgx(&self) -> Result<Pkgx, Error> {
74 unsafe { set_runner("pkgx".into()) }?;
75 let pkgx = unsafe { pkgx() }?;
76 Ok(pkgx.into_inner())
77 }
78
79 pub fn pixi(&self) -> Result<Pixi, Error> {
80 unsafe { set_runner("pixi".into()) }?;
81 let pixi = unsafe { pixi() }?;
82 Ok(pixi.into_inner())
83 }
84
85 pub fn hermit(&self) -> Result<Hermit, Error> {
86 unsafe { set_runner("hermit".into()) }?;
87 let hermit = unsafe { hermit() }?;
88 Ok(hermit.into_inner())
89 }
90
91 pub fn git(&self, url: &str) -> Result<Git, Error> {
92 unsafe { set_runner("git".into()) }?;
93 let git = unsafe { git(url.into()) }?;
94 Ok(git.into_inner())
95 }
96
97 pub fn http(&self, url: &str) -> Result<File, Error> {
98 unsafe { set_runner("http".into()) }?;
99 let file = unsafe { http(url.into()) }?;
100 Ok(file.into_inner())
101 }
102
103 pub fn mise(&self) -> Result<Mise, Error> {
104 unsafe { set_runner("mise".into()) }?;
105 let mise = unsafe { mise() }?;
106 Ok(mise.into_inner())
107 }
108
109 pub fn envhub(&self) -> Result<Envhub, Error> {
110 unsafe { set_runner("envhub".into()) }?;
111 let envhub = unsafe { envhub() }?;
112 Ok(envhub.into_inner())
113 }
114
115 pub fn with_exec(&self, args: Vec<&str>) -> Result<Pipeline, Error> {
116 unsafe {
117 with_exec(Json::from(
118 args.into_iter()
119 .map(|x| x.to_string())
120 .collect::<Vec<String>>(),
121 ))
122 }?;
123 Ok(Pipeline {
124 id: self.id.clone(),
125 })
126 }
127
128 pub fn with_workdir(&self, path: &str) -> Result<Pipeline, Error> {
129 unsafe { with_workdir(path.into()) }?;
130 Ok(Pipeline {
131 id: self.id.clone(),
132 })
133 }
134
135 pub fn with_cache(&self, path: &str, cache_id: &str) -> Result<Pipeline, Error> {
136 unsafe {
137 with_cache(Json(Cache {
138 id: cache_id.into(),
139 path: path.into(),
140 ..Default::default()
141 }))
142 }?;
143 Ok(Pipeline {
144 id: self.id.clone(),
145 })
146 }
147
148 pub fn with_file(&self, path: &str, file_id: &str) -> Result<Pipeline, Error> {
149 unsafe {
150 with_file(Json(File {
151 id: file_id.into(),
152 path: path.into(),
153 }))
154 }?;
155 Ok(Pipeline {
156 id: self.id.clone(),
157 })
158 }
159
160 pub fn stdout(&self) -> Result<String, Error> {
161 unsafe { stdout() }
162 }
163
164 pub fn stderr(&self) -> Result<String, Error> {
165 unsafe { stderr() }
166 }
167
168 pub fn as_service(&self, name: &str) -> Result<String, Error> {
169 let service = unsafe { as_service(name.into())? };
170 Ok(service.into_inner().id)
171 }
172
173 pub fn with_service(&self, service_id: &str) -> Result<Pipeline, Error> {
174 unsafe { with_service(service_id.into())? }
175 Ok(Pipeline {
176 id: self.id.clone(),
177 })
178 }
179
180 pub fn with_env_variable(&self, name: &str, value: &str) -> Result<Pipeline, Error> {
181 unsafe { set_envs(Json(vec![(name.into(), value.into())]))? };
182 Ok(Pipeline {
183 id: self.id.clone(),
184 })
185 }
186
187 pub fn wait_on(&self, port: u32, timeout: Option<u32>) -> Result<Pipeline, Error> {
188 unsafe {
189 wait_on(Json(vec![port, timeout.unwrap_or(60)]))?;
190 }
191 Ok(Pipeline {
192 id: self.id.clone(),
193 })
194 }
195
196 pub fn with_secret_variable(&self, name: &str, secret_id: &str) -> Result<Pipeline, Error> {
197 unsafe {
198 with_secret_variable(Json(vec![name.into(), secret_id.into()]))?;
199 }
200 Ok(Pipeline {
201 id: self.id.clone(),
202 })
203 }
204}