|
1 | | -use std::{collections::HashMap, fmt::Display, path::PathBuf, process::Command, str::FromStr}; |
| 1 | +use std::{collections::HashMap, fmt::Display, process::Command, str::FromStr, sync::LazyLock}; |
2 | 2 |
|
3 | | -use anyhow::anyhow; |
| 3 | +use anyhow::{anyhow, Result}; |
| 4 | +use camino::Utf8PathBuf; |
| 5 | +use regex::{Captures, Regex}; |
4 | 6 | use serde::{Deserialize, Serialize}; |
5 | 7 | use serde_with::{serde_as, DisplayFromStr}; |
6 | 8 | use spdx::Expression; |
@@ -60,7 +62,7 @@ pub enum StepVariant { |
60 | 62 | command: String, |
61 | 63 | }, |
62 | 64 | Move { |
63 | | - path: PathBuf, |
| 65 | + path: Utf8PathBuf, |
64 | 66 | }, |
65 | 67 | } |
66 | 68 |
|
@@ -102,3 +104,38 @@ impl Runner { |
102 | 104 | } |
103 | 105 | } |
104 | 106 | } |
| 107 | + |
| 108 | +static VARIABLE_REGEX: LazyLock<Regex> = |
| 109 | + LazyLock::new(|| Regex::new(r"%\{([^}]+)\}").expect("invalid regex")); |
| 110 | + |
| 111 | +impl Package { |
| 112 | + pub fn parse(s: &str) -> Result<Self> { |
| 113 | + let mut package: Package = toml_edit::de::from_str(s)?; |
| 114 | + |
| 115 | + let mut variables = HashMap::new(); |
| 116 | + variables.insert("version", package.info.version.as_str()); |
| 117 | + |
| 118 | + for source in package.sources.iter_mut() { |
| 119 | + source.url = replace_vars(&source.url, &variables) |
| 120 | + } |
| 121 | + |
| 122 | + for step in package.steps.iter_mut() { |
| 123 | + match &mut step.variant { |
| 124 | + StepVariant::Command { .. } => {} |
| 125 | + StepVariant::Move { path } => { |
| 126 | + *path = replace_vars(path.as_str(), &variables).into(); |
| 127 | + } |
| 128 | + } |
| 129 | + } |
| 130 | + |
| 131 | + Ok(package) |
| 132 | + } |
| 133 | +} |
| 134 | + |
| 135 | +fn replace_vars<'h>(haystack: &'h str, variables: &HashMap<&str, &str>) -> String { |
| 136 | + VARIABLE_REGEX |
| 137 | + .replace_all(haystack, |caps: &Captures| { |
| 138 | + variables.get(&caps[1]).expect("Unknown variable") // FIXME: error handling |
| 139 | + }) |
| 140 | + .into_owned() |
| 141 | +} |
0 commit comments