Skip to content

Commit

Permalink
alpkit: Resolve arch in parsed APKBUILD
Browse files Browse the repository at this point in the history
  • Loading branch information
jirutka committed Aug 6, 2023
1 parent 4d04824 commit 2fc4074
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 13 deletions.
48 changes: 40 additions & 8 deletions alpkit/src/apkbuild.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,9 @@ pub struct Apkbuild {
/// Homepage of the software being packaged.
pub url: String,

/// Package architecture(s) to build for. It contains one or several of: the
/// architecture code (e.g. `x86_64`), `all` or `noarch`. `all` means all
/// architectures and `noarch` means that it's architecture-independent
/// (e.g. a pure-python package). Architectures can be negated using the `!`
/// character to exclude them from the list of supported architectures. For
/// example `["all", "!ppc64le"]` means that the package is allowed to be
/// built on all architectures but the `ppc64le` architecture.
// TODO: Replace String with an enum.
/// Package architecture(s) to build for. It doesn't contain `all`, `noarch`
/// or negated architectures -- `arch` is resolved on APKBUILD parsing as
/// per [`ApkbuildReader::arch_all`].
#[serde(default)]
pub arch: Vec<String>,

Expand Down Expand Up @@ -242,7 +237,14 @@ impl<'a> KeyValueLike<'a> for Secfix {

////////////////////////////////////////////////////////////////////////////////

/// The default list of CPU architectures (arch) to which the `all` and `noarch`
/// keywords are expanded.
pub const ARCH_ALL: &[&str] = &[
"aarch64", "armhf", "armv7", "ppc64le", "riscv64", "s390x", "x86", "x86_64",
];

pub struct ApkbuildReader {
arch_all: Vec<String>,
env: HashMap<OsString, OsString>,
inherit_env: bool,
shell_cmd: OsString,
Expand All @@ -258,6 +260,13 @@ impl ApkbuildReader {
Self::default()
}

/// Changes the list of CPU architectures (arch) to which the `all` and
/// `noarch` keywords are expanded. The default is [`ARCH_ALL`].
pub fn arch_all<S: ToString>(&mut self, arches: &[S]) -> &mut Self {
self.arch_all.extend(arches.iter().map(|s| s.to_string()));
self
}

/// Inserts or updates an environment variable mapping.
pub fn env<K, V>(&mut self, key: K, val: V) -> &mut Self
where
Expand Down Expand Up @@ -307,6 +316,7 @@ impl ApkbuildReader {

let values = self.evaluate(filepath)?;

let mut arch: Option<&str> = None;
let mut sha512sums: Option<&str> = None;
let mut source: Option<&str> = None;

Expand All @@ -316,6 +326,7 @@ impl ApkbuildReader {
.zip(values.trim_end().split_terminator('\x1E'))
.fold(Vec::with_capacity(64), |mut acc, (key, val)| {
match *key {
"arch" => arch = Some(val),
"source" => source = Some(val),
"sha512sums" => sha512sums = Some(val),
"license" | "pkgdesc" | "pkgver" | "url" => {
Expand All @@ -335,6 +346,9 @@ impl ApkbuildReader {

let mut apkbuild: Apkbuild = serde_key_value::from_ordered_pairs(parsed)?;

if let Some(arch) = arch {
apkbuild.arch = parse_and_expand_arch(arch, &self.arch_all);
}
if let Some(source) = source {
apkbuild.source = decode_source_and_sha512sums(source, sha512sums.unwrap_or(""))?;
}
Expand Down Expand Up @@ -424,6 +438,7 @@ impl Default for ApkbuildReader {
.into_bytes();

Self {
arch_all: ARCH_ALL.iter().map(|s| s.to_string()).collect(), // this is suboptiomal :/
shell_cmd: "/bin/sh".into(),
env: HashMap::from([("PATH".into(), path)]),
inherit_env: false,
Expand All @@ -434,6 +449,23 @@ impl Default for ApkbuildReader {
}
}

fn parse_and_expand_arch<'v, 's: 'v>(value: &'v str, arch_all: &'s [String]) -> Vec<String> {
value
.split_ascii_whitespace()
.fold(vec![], |mut acc, token| {
match token {
"all" | "noarch" => acc.extend(arch_all.iter().map(String::clone)),
s if s.starts_with('!') => acc.retain(|arch| arch != &s[1..]),
s => acc.push(s.to_owned()),
};
acc
})
.tap_mut(|v| {
v.sort();
v.dedup();
})
}

fn parse_comment_attribute<'a>(name: &str, line: &'a str) -> Option<&'a str> {
line.trim()
.strip_prefix("# ")
Expand Down
10 changes: 5 additions & 5 deletions alpkit/src/apkbuild.test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ fn read_apkbuild() {
pkgrel: 2,
pkgdesc: S!("A sample aport for testing"),
url: S!("https://example.org/sample"),
arch: vec![
S!("all"),
S!("!riscv64"),
S!("!s390x")
],
arch: ARCH_ALL
.iter()
.filter(|s| !matches!(**s, "riscv64" | "s390x"))
.map(ToString::to_string)
.collect(),
license: S!("ISC and BSD-2-Clause and BSD-3-Clause"),
depends: vec![
dependency("ruby>=3.0"),
Expand Down

0 comments on commit 2fc4074

Please sign in to comment.