archlinux_inputs_fsck/
makepkg.rs1use crate::errors::*;
2use std::path::Path;
3use std::process::Stdio;
4use tokio::process::Command;
5
6pub const SUPPORTED_ALGS: &[&str] = &["sha256sums", "sha512sums", "b2sums", "md5sums", "sha1sums"];
7
8#[derive(Debug, PartialEq)]
9pub enum Source {
10 Url(String),
11 UrlWithFilename((String, String)),
12}
13
14impl Source {
15 pub fn filename(&self) -> Option<&str> {
16 match self {
17 Source::Url(_) => None,
18 Source::UrlWithFilename((_, filename)) => Some(filename),
19 }
20 }
21
22 pub fn url(&self) -> &str {
23 match self {
24 Source::Url(url) => url,
25 Source::UrlWithFilename((url, _file)) => url,
26 }
27 }
28
29 pub fn scheme(&self) -> Option<&str> {
30 self.url().split_once("://").map(|x| x.0)
31 }
32}
33
34async fn exec_sh(folder: &Path, cmd: &str) -> Result<Vec<String>> {
35 let child = Command::new("bash")
36 .arg("-c")
37 .arg(format!("source ./PKGBUILD;{}", cmd))
38 .stdout(Stdio::piped())
39 .current_dir(folder)
40 .spawn()
41 .context("Failed to run bash")?;
42
43 let out = child.wait_with_output().await?;
44 if !out.status.success() {
45 bail!(
46 "Process (bash, {:?}) exited with error: {:?}",
47 cmd,
48 out.status
49 );
50 }
51
52 let buf = String::from_utf8(out.stdout).context("Shell output contains invalid utf8")?;
53 Ok(buf.lines().map(String::from).collect())
54}
55
56pub async fn list_variable(folder: &Path, var: &str) -> Result<Vec<String>> {
57 exec_sh(
58 folder,
59 &format!("for x in ${{{}[@]}}; do echo \"$x\"; done", var),
60 )
61 .await
62}
63
64pub async fn list_sources(folder: &Path) -> Result<Vec<Source>> {
65 let sources = list_variable(folder, "source").await?;
66 let sources = sources
67 .into_iter()
68 .map(|line| {
69 if let Some((file, url)) = line.split_once("::") {
70 Source::UrlWithFilename((url.to_string(), file.to_string()))
71 } else {
72 Source::Url(line)
73 }
74 })
75 .collect();
76 Ok(sources)
77}