use crate::helpers;
use crate::pkgbuild;
use crate::pkgbuild::Pkgbuild;
use crate::{Error, ErrorKind};
extern crate serde;
use serde::Serialize;
#[derive(Debug, Serialize, Eq)]
pub struct Pkgver(String);
impl Pkgver {
pub fn new(version: &str) -> Result<Pkgver, Error> {
let check = |x: char| x.is_alphanumeric() || x == '.' || x == '_';
if !version.chars().all(check) {
return Err(Error::new(
ErrorKind::ValidationError,
"pkgver can only contain letters, numbers, periods and underscores",
));
}
Ok(Pkgver(version.to_string()))
}
}
impl PartialEq for Pkgver {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}
impl PartialEq<str> for Pkgver {
fn eq(&self, other: &str) -> bool {
self.0[..] == other[..]
}
}
impl PartialEq<&str> for Pkgver {
fn eq(&self, other: &&str) -> bool {
self.0[..] == other[..]
}
}
#[derive(Debug, Serialize, Eq)]
pub struct Pkgname(String);
impl Pkgname {
pub fn new(name: &str) -> Result<Pkgname, Error> {
let check = |x: char| {
x.is_alphabetic() && x.is_lowercase()
|| x.is_numeric()
|| x == '@'
|| x == '.'
|| x == '_'
|| x == '+'
|| x == '-'
};
for (index, character) in name.chars().enumerate() {
if index == 0 && character == '-' {
return Err(Error::new(
ErrorKind::ValidationError,
"pkgname can't start with hyphens",
));
} else if index == 0 && character == '.' {
return Err(Error::new(
ErrorKind::ValidationError,
"pkgname can't start with dots",
));
} else if !check(character) {
return Err(Error::new(
ErrorKind::ValidationError,
"pkgname can only contain lowercase alphanumerics or @._+-",
));
}
}
Ok(Pkgname(name.to_string()))
}
}
impl PartialEq for Pkgname {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}
impl PartialEq<str> for Pkgname {
fn eq(&self, other: &str) -> bool {
self.0[..] == other[..]
}
}
impl PartialEq<&str> for Pkgname {
fn eq(&self, other: &&str) -> bool {
self.0[..] == other[..]
}
}
#[derive(Debug, Serialize, Eq)]
pub struct Pkgbase(String);
impl Pkgbase {
pub fn new(base: &str) -> Result<Pkgbase, Error> {
let first = base.chars().next().unwrap();
if first == '-' {
return Err(Error::new(
ErrorKind::ValidationError,
"pkgbase can't start with hyphens",
));
}
Ok(Pkgbase(base.to_string()))
}
}
impl PartialEq for Pkgbase {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}
impl PartialEq<str> for Pkgbase {
fn eq(&self, other: &str) -> bool {
self.0[..] == other[..]
}
}
impl PartialEq<&str> for Pkgbase {
fn eq(&self, other: &&str) -> bool {
self.0[..] == other[..]
}
}
#[derive(Debug)]
enum State<'a> {
VariableAssignment(&'a str),
NodeArray(&'a str),
Other,
}
#[derive(Debug, Serialize)]
pub struct PkgData {
pub pkgbase: Option<Pkgbase>,
pub pkgname: Vec<Pkgname>,
pub pkgver: Pkgver,
pub pkgrel: usize,
pub epoch: Option<usize>,
pub pkgdesc: Option<String>,
pub arch: Vec<String>,
pub url: Option<String>,
pub license: Option<Vec<String>>,
pub depends: Option<Vec<String>>,
pub optdepends: Option<Vec<String>>,
pub makedepends: Option<Vec<String>>,
pub checkdepends: Option<Vec<String>>,
pub provides: Option<Vec<String>>,
pub conflicts: Option<Vec<String>>,
pub replaces: Option<Vec<String>>,
pub source: Option<Vec<String>>,
pub validpgpkeys: Option<Vec<String>>,
pub md5sums: Option<Vec<String>>,
pub sha1sums: Option<Vec<String>>,
pub sha256sums: Option<Vec<String>>,
pub sha224sums: Option<Vec<String>>,
pub sha384sums: Option<Vec<String>>,
pub sha512sums: Option<Vec<String>>,
pub b2sums: Option<Vec<String>>,
}
impl PkgData {
#[allow(clippy::cognitive_complexity)]
pub fn from_source(source_code: &str) -> Result<PkgData, Error> {
let mut pkgname: Option<Vec<Pkgname>> = None;
let mut pkgver: Option<Pkgver> = None;
let mut pkgrel: Option<usize> = None;
let mut arch: Option<Vec<String>> = None;
let mut pkgbase: Option<Pkgbase> = None;
let mut epoch: Option<usize> = None;
let mut pkgdesc: Option<String> = None;
let mut url: Option<String> = None;
let mut license: Option<Vec<String>> = None;
let mut depends: Option<Vec<String>> = None;
let mut optdepends: Option<Vec<String>> = None;
let mut makedepends: Option<Vec<String>> = None;
let mut checkdepends: Option<Vec<String>> = None;
let mut provides: Option<Vec<String>> = None;
let mut conflicts: Option<Vec<String>> = None;
let mut replaces: Option<Vec<String>> = None;
let mut source: Option<Vec<String>> = None;
let mut validpgpkeys: Option<Vec<String>> = None;
let mut md5sums: Option<Vec<String>> = None;
let mut sha1sums: Option<Vec<String>> = None;
let mut sha256sums: Option<Vec<String>> = None;
let mut sha224sums: Option<Vec<String>> = None;
let mut sha384sums: Option<Vec<String>> = None;
let mut sha512sums: Option<Vec<String>> = None;
let mut b2sums: Option<Vec<String>> = None;
let mut state = State::Other;
let pkgbuild = Pkgbuild::new(source_code)?;
let walker = pkgbuild::TreeWalker::new(pkgbuild.tree.root_node());
for node in walker {
let node_kind = node.kind();
let mut text = node.utf8_text(&pkgbuild.source).unwrap();
match node_kind {
"variable_assignment" => {
if node.parent().unwrap().kind() == "program" {
state = State::VariableAssignment("");
}
}
"variable_name" => match state {
State::VariableAssignment(_) => {
state = State::VariableAssignment(text);
}
_ => continue,
},
"=" | "(" | "${" | "}" | "expansion" => match state {
State::VariableAssignment(_) | State::NodeArray(_) => continue,
_ => state = State::Other,
},
r#"""# => match state {
State::NodeArray(_) => continue,
_ => state = State::Other,
},
"array" => match state {
State::VariableAssignment(variable) => {
state = State::NodeArray(variable);
}
_ => continue,
},
"word" | "string" | "raw_string" => {
if node_kind == "raw_string" || node_kind == "string" {
text = helpers::cleanup_rawstring(text);
}
match state {
State::VariableAssignment(variable) => match variable {
"pkgbase" => pkgbase = Some(Pkgbase::new(text)?),
"pkgname" => pkgname = Some(vec![Pkgname::new(text)?]),
"pkgver" => pkgver = Some(Pkgver::new(text)?),
"pkgrel" => {
pkgrel = Some(text.parse::<usize>().map_err(|_| {
Error::new(
ErrorKind::ValidationError,
"pkgrel must be an integer",
)
})?);
}
"epoch" => {
epoch = Some(text.parse::<usize>().map_err(|_| {
Error::new(
ErrorKind::ValidationError,
"epoch must be an integer",
)
})?);
}
"pkgdesc" => pkgdesc = Some(text.to_string()),
"url" => url = Some(text.to_string()),
_ => eprintln!("Unknown variable `{}`", variable),
},
State::NodeArray(variable) => match variable {
"pkgname" => match &mut pkgname {
Some(array) => array.push(Pkgname::new(text)?),
None => pkgname = Some(vec![Pkgname::new(text)?]),
},
"arch" => match &mut arch {
Some(array) => array.push(text.to_string()),
None => arch = Some(vec![text.to_string()]),
},
"license" => match &mut license {
Some(array) => array.push(text.to_string()),
None => license = Some(vec![text.to_string()]),
},
"depends" => match &mut depends {
Some(array) => array.push(text.to_string()),
None => depends = Some(vec![text.to_string()]),
},
"optdepends" => match &mut optdepends {
Some(array) => array.push(text.to_string()),
None => optdepends = Some(vec![text.to_string()]),
},
"makedepends" => match &mut makedepends {
Some(array) => array.push(text.to_string()),
None => makedepends = Some(vec![text.to_string()]),
},
"checkdepends" => match &mut checkdepends {
Some(array) => array.push(text.to_string()),
None => checkdepends = Some(vec![text.to_string()]),
},
"provides" => match &mut provides {
Some(array) => array.push(text.to_string()),
None => provides = Some(vec![text.to_string()]),
},
"conflicts" => match &mut conflicts {
Some(array) => array.push(text.to_string()),
None => conflicts = Some(vec![text.to_string()]),
},
"replaces" => match &mut replaces {
Some(array) => array.push(text.to_string()),
None => replaces = Some(vec![text.to_string()]),
},
"source" => match &mut source {
Some(array) => array.push(text.to_string()),
None => source = Some(vec![text.to_string()]),
},
"validpgpkeys" => match &mut validpgpkeys {
Some(array) => array.push(text.to_string()),
None => validpgpkeys = Some(vec![text.to_string()]),
},
"md5sums" => match &mut md5sums {
Some(array) => array.push(text.to_string()),
None => md5sums = Some(vec![text.to_string()]),
},
"sha1sums" => match &mut sha1sums {
Some(array) => array.push(text.to_string()),
None => sha1sums = Some(vec![text.to_string()]),
},
"sha256sums" => match &mut sha256sums {
Some(array) => array.push(text.to_string()),
None => sha256sums = Some(vec![text.to_string()]),
},
"sha224sums" => match &mut sha224sums {
Some(array) => array.push(text.to_string()),
None => sha224sums = Some(vec![text.to_string()]),
},
"sha384sums" => match &mut sha384sums {
Some(array) => array.push(text.to_string()),
None => sha384sums = Some(vec![text.to_string()]),
},
"sha512sums" => match &mut sha512sums {
Some(array) => array.push(text.to_string()),
None => sha512sums = Some(vec![text.to_string()]),
},
"b2sums" => match &mut b2sums {
Some(array) => array.push(text.to_string()),
None => b2sums = Some(vec![text.to_string()]),
},
_ => eprintln!("Unknown variable `{}`", variable),
},
_ => continue,
}
}
_ => state = State::Other,
}
}
let pkgname = match pkgname {
Some(pkgname) => pkgname,
None => {
return Err(Error::new(
ErrorKind::InvalidPKGBUILDError,
"pkgname key must exist and have at least one value",
))
}
};
let pkgver = match pkgver {
Some(pkgver) => pkgver,
None => {
return Err(Error::new(
ErrorKind::InvalidPKGBUILDError,
"pkgver key must exist",
))
}
};
let pkgrel = match pkgrel {
Some(pkgrel) => pkgrel,
None => {
return Err(Error::new(
ErrorKind::InvalidPKGBUILDError,
"pkgrel key must exist",
))
}
};
let arch = match arch {
Some(arch) => arch,
None => {
return Err(Error::new(
ErrorKind::InvalidPKGBUILDError,
"arch key must exist",
))
}
};
Ok(PkgData {
pkgbase,
pkgname,
pkgver,
pkgrel,
epoch,
pkgdesc,
arch,
url,
license,
depends,
optdepends,
makedepends,
checkdepends,
provides,
conflicts,
replaces,
source,
validpgpkeys,
md5sums,
sha1sums,
sha256sums,
sha224sums,
sha384sums,
sha512sums,
b2sums,
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn pkgver_with_hyphen_should_fail() {
assert!(Pkgver::new("0.1.0-alpha").is_err());
}
#[test]
fn pkgver_expected_should_work() {
assert!(Pkgver::new("0.1.0").is_ok());
}
#[test]
fn pkgname_starts_with_hyphen_should_fail() {
assert!(Pkgname::new("-package12@._+-").is_err());
}
#[test]
fn pkgname_starts_with_dot_should_fail() {
assert!(Pkgname::new(".package12@._+-").is_err());
}
#[test]
fn pkgname_with_uppercase_should_fail() {
assert!(Pkgname::new("Package12@._+-").is_err());
}
#[test]
fn pkgname_expected_should_work() {
assert!(Pkgname::new("package12@._+-").is_ok());
}
#[test]
fn pkgbase_starts_with_hyphen_should_fail() {
assert!(Pkgbase::new("-test-PaCkAGe@._+-&*").is_err());
}
#[test]
fn pkgbase_expected_should_work() {
assert!(Pkgbase::new(".TeSt-PaCkAGe@._+-&*").is_ok());
}
#[test]
fn pkgdata_source_with_pkgname_missing_should_fail() {
let source_code = r#"
pkgver=0.1.0
pkgrel=1
arch=('any')
license=('MIT')
"#;
let pkgdata = PkgData::from_source(&source_code);
assert!(pkgdata.is_err());
let error = pkgdata.unwrap_err();
let expected_error = Error::new(
ErrorKind::InvalidPKGBUILDError,
"pkgname key must exist and have at least one value",
);
assert_eq!(error, expected_error);
}
#[test]
fn pkgdata_source_with_pkgname_empty_array_should_fail() {
let source_code = r#"
pkgname=()
pkgver=0.1.0
pkgrel=1
arch=('any')
license=('MIT')
"#;
let pkgdata = PkgData::from_source(&source_code);
assert!(pkgdata.is_err());
let error = pkgdata.unwrap_err();
let expected_error = Error::new(
ErrorKind::InvalidPKGBUILDError,
"pkgname key must exist and have at least one value",
);
assert_eq!(error, expected_error);
}
#[test]
fn pkgdata_source_with_pkgname_single_quote_array_should_work() {
let source_code = r#"
pkgname=('testing-package1' 'testing-package2')
pkgver=0.1.0
pkgrel=1
arch=('any')
license=('MIT')
"#;
let pkgdata = PkgData::from_source(&source_code).expect("this should have passed");
assert_eq!(
pkgdata.pkgname,
vec!["testing-package1", "testing-package2"]
);
}
#[test]
fn pkgdata_source_with_pkgname_double_quote_array_should_work() {
let source_code = r#"
pkgname=("testing-package1" "testing-package2")
pkgver=0.1.0
pkgrel=1
arch=('any')
license=('MIT')
"#;
let pkgdata = PkgData::from_source(&source_code).expect("this should have passed");
assert_eq!(
pkgdata.pkgname,
vec!["testing-package1", "testing-package2"]
);
}
#[test]
fn pkgdata_source_with_pkgname_no_quote_array_should_work() {
let source_code = r#"
pkgname=(testing-package1 testing-package2)
pkgver=0.1.0
pkgrel=1
arch=('any')
license=('MIT')
"#;
let pkgdata = PkgData::from_source(&source_code).expect("this should have passed");
assert_eq!(
pkgdata.pkgname,
vec!["testing-package1", "testing-package2"]
);
}
#[test]
fn pkgdata_source_with_pkgver_missing_should_fail() {
let source_code = r#"
pkgname=testing-package
pkgrel=1
arch=('any')
license=('MIT')
"#;
let pkgdata = PkgData::from_source(&source_code);
assert!(pkgdata.is_err());
let error = pkgdata.unwrap_err();
let expected_error = Error::new(ErrorKind::InvalidPKGBUILDError, "pkgver key must exist");
assert_eq!(error, expected_error);
}
#[test]
fn pkgdata_source_with_pkgrel_missing_should_fail() {
let source_code = r#"
pkgname=testing-package
pkgver=0.1.0
arch=('any')
license=('MIT')
"#;
let pkgdata = PkgData::from_source(&source_code);
assert!(pkgdata.is_err());
let error = pkgdata.unwrap_err();
let expected_error = Error::new(ErrorKind::InvalidPKGBUILDError, "pkgrel key must exist");
assert_eq!(error, expected_error);
}
#[test]
fn pkgdata_source_with_arch_missing_should_fail() {
let source_code = r#"
pkgname=testing-package
pkgver=0.1.0
pkgrel=1
license=('MIT')
"#;
let pkgdata = PkgData::from_source(&source_code);
assert!(pkgdata.is_err());
let error = pkgdata.unwrap_err();
let expected_error = Error::new(ErrorKind::InvalidPKGBUILDError, "arch key must exist");
assert_eq!(error, expected_error);
}
#[test]
fn pkgdata_source_with_invalid_pkgname() {
let source_code = r#"
pkgname=INVALID-PACKAGE
pkgver=0.1.0
pkgrel=1
arch=('any')
license=('MIT')
"#;
let error = PkgData::from_source(&source_code).unwrap_err();
let expected_error = Pkgname::new("INVALID-PACKAGE").unwrap_err();
assert_eq!(error, expected_error);
}
#[test]
fn pkgdata_source_with_invalid_pkgrel() {
let source_code = r#"
pkgname=testing-package
pkgver=0.1.0
pkgrel=invalid
arch=('any')
license=('MIT')
"#;
let error = PkgData::from_source(&source_code).unwrap_err();
let expected_error = Error::new(ErrorKind::ValidationError, "pkgrel must be an integer");
assert_eq!(error, expected_error);
}
#[test]
fn pkgdata_source_with_invalid_epoch() {
let source_code = r#"
pkgname=testing-package
pkgver=0.1.0
pkgrel=1
epoch=invalid
arch=('any')
license=('MIT')
"#;
let error = PkgData::from_source(&source_code).unwrap_err();
let expected_error = Error::new(ErrorKind::ValidationError, "epoch must be an integer");
assert_eq!(error, expected_error);
}
#[test]
fn pkgdata_source_with_invalid_pkgver() {
let source_code = r#"
pkgname=testing-package
pkgver=0.1.0-alpha
pkgrel=1
arch=('any')
license=('MIT')
"#;
let error = PkgData::from_source(&source_code).unwrap_err();
let expected_error = Pkgver::new("0.1.0-alpha").unwrap_err();
assert_eq!(error, expected_error);
}
#[test]
fn pkgdata_source_key_gets_ignored_if_not_at_root_level() {
let source_code = r#"
pkgname=testing-package
pkgver=0.1.0
pkgrel=1
arch=('any')
license=('MIT')
prepare() {
pkgname=overwritten-package
}
"#;
let pkgdata = PkgData::from_source(&source_code).unwrap();
assert_eq!(pkgdata.pkgname, vec!["testing-package"]);
assert_eq!(pkgdata.pkgver, "0.1.0");
assert_eq!(pkgdata.pkgrel, 1);
assert_eq!(pkgdata.arch, vec!["any"]);
assert_eq!(pkgdata.license, Some(vec!["MIT".to_string()]));
}
#[test]
fn pkgdata_simple_should_work() {
let source_code = r##"
# Maintainer: Sighery
pkgname=terraform-provider-njalla
pkgver=0.7.0
pkgrel=1
pkgdesc="Unofficial Terraform Njalla provider plugin"
url='https://github.com/Sighery/terraform-provider-njalla'
arch=('x86_64')
license=("MIT")
makedepends=(go)
source=(
"$pkgname-$pkgver.tar.gz::$url/archive/v$pkgver.tar.gz"
)
sha256sums=('29d5b4c94dcfe2260e0d217392e2aa935a6b81e7388f72305fde87f0b680189a')
build() {
export CGO_LDFLAGS="${LDFLAGS}"
export GOFLAGS="-trimpath"
cd $pkgname-$pkgver
go build -o "${pkgname}_v${pkgver}"
}
package() {
cd $pkgname-$pkgver
install -Dm755 "${pkgname}_v${pkgver}" "$pkgdir/usr/bin/${pkgname}_v${pkgver}"
# MIT license needs to be installed separately
install -Dm644 LICENSE $pkgdir/usr/share/licenses/$pkgname/LICENSE
}
"##;
let pkgdata = PkgData::from_source(&source_code).expect("this should have passed");
assert_eq!(pkgdata.pkgname, vec!["terraform-provider-njalla"]);
assert_eq!(pkgdata.pkgver, "0.7.0");
assert_eq!(pkgdata.pkgrel, 1);
assert_eq!(
pkgdata.pkgdesc,
Some("Unofficial Terraform Njalla provider plugin".to_string())
);
assert_eq!(
pkgdata.url,
Some("https://github.com/Sighery/terraform-provider-njalla".to_string())
);
assert_eq!(pkgdata.arch, vec!["x86_64"]);
assert_eq!(pkgdata.license, Some(vec!["MIT".to_string()]));
assert_eq!(pkgdata.makedepends, Some(vec!["go".to_string()]));
assert_eq!(
pkgdata.source,
Some(vec![
"$pkgname-$pkgver.tar.gz::$url/archive/v$pkgver.tar.gz".to_string()
])
);
assert_eq!(
pkgdata.sha256sums,
Some(vec![
"29d5b4c94dcfe2260e0d217392e2aa935a6b81e7388f72305fde87f0b680189a".to_string()
])
);
assert_eq!(pkgdata.pkgbase, None);
assert_eq!(pkgdata.epoch, None);
assert_eq!(pkgdata.depends, None);
assert_eq!(pkgdata.optdepends, None);
assert_eq!(pkgdata.checkdepends, None);
assert_eq!(pkgdata.provides, None);
assert_eq!(pkgdata.conflicts, None);
assert_eq!(pkgdata.replaces, None);
assert_eq!(pkgdata.validpgpkeys, None);
assert_eq!(pkgdata.md5sums, None);
assert_eq!(pkgdata.sha224sums, None);
assert_eq!(pkgdata.sha384sums, None);
assert_eq!(pkgdata.sha512sums, None);
assert_eq!(pkgdata.b2sums, None);
}
#[test]
fn pkgdata_complex_should_work() {
let source_code = r##"
# Maintainer: AwesomeHaircut <jesusbalbastro at gmail com>
# Maintainer: Mateusz Gozdek <mgozdekof@gmail.com>
# Contributor: Rein Fernhout <public@reinfernhout.xyz>
# Past Contributor: James An <james@jamesan.ca>
pkgbase=droidcam
pkgname=('droidcam' 'v4l2loopback-dc-dkms')
pkgver=1.7.3
pkgrel=1
epoch=1
pkgdesc='A tool for using your android device as a wireless/usb webcam'
arch=('x86_64')
url="https://github.com/aramg/${pkgbase}"
license=('GPL')
makedepends=('gtk3' 'ffmpeg' 'libusbmuxd')
source=("${pkgbase}.desktop"
"dkms.conf"
"${pkgbase}.conf"
"${pkgbase}-${pkgver}.zip::${url}/archive/v${pkgver}.zip"
)
sha512sums=('72d21aa2d7eecc9bb070aaf7059a671246feb22f9c39b934a5463a4839f9347050de00754e5031dbc44f78eb2731f58f0cd2fcf781bc241f6fbd1abb4308b7ee'
'27848dc6825c965c0aaac8e86220c3916ba20df6d941f5f05caecbf9c329ee744ee883bd2638ba58fe0dc3f40a8ae804dafbfbbe2efc23237e2b5450606cb78d'
'74415b349bf8b2d1bb8181906f4254416d6223c5c42951185051bf3dd3e2f780db3441078ebff4a670eb0ffc76cc08f3b36851e0824c55a7f70136ce4d0240bc'
'3934033dac931277a2f8ff348bcaa39b0cfe3e73885acd28f34b4b4efd8ce0b8606f23493b92206b5a7d3a2e1a2e1726d1d9ec33cd3f1876d1e6806dfb59c74f')
prepare() {
# Generate the module loading configuration files
echo "options v4l2loopback_dc width=640 height=480" >| "${pkgbase}.modprobe.conf"
}
build() {
cd ${pkgbase}-${pkgver}
# All JPEG* parameters are needed to use shared version of libturbojpeg instead of
# static one.
#
# Also libusbmuxd requires an override while linking.
make JPEG_DIR="" JPEG_INCLUDE="" JPEG_LIB="" JPEG=$(pkg-config --libs --cflags libturbojpeg) USBMUXD=-lusbmuxd-2.0
}
package_droidcam() {
depends=('alsa-lib' 'libjpeg-turbo' 'ffmpeg' 'v4l2loopback-dc-dkms' 'libusbmuxd')
optdepends=('gtk3: use GUI version in addition to CLI interface' 'libappindicator-gtk3: use GUI version in addition to CLI interface')
pushd ${pkgbase}-${pkgver}
# Install droidcam program files
install -Dm755 "${pkgbase}" "$pkgdir/usr/bin/${pkgbase}"
install -Dm755 "${pkgbase}-cli" "$pkgdir/usr/bin/${pkgbase}-cli"
install -Dm644 icon2.png "${pkgdir}/usr/share/pixmaps/${pkgbase}.png"
install -Dm644 icon2.png "${pkgdir}/opt/droidcam-icon.png"
install -Dm644 "${srcdir}/${pkgbase}.desktop" "${pkgdir}/usr/share/applications/${pkgbase}.desktop"
install -Dm644 "${srcdir}/${pkgbase}.conf" "${pkgdir}/etc/modules-load.d/${pkgbase}.conf"
install -Dm644 README.md "${pkgdir}/usr/share/licenses/${pkgbase}/LICENSE"
}
package_v4l2loopback-dc-dkms() {
depends=('dkms')
backup=("etc/modprobe.d/${pkgbase}.conf")
_pkgname=v4l2loopback-dc
local install_dir="${pkgdir}/usr/src/${_pkgname}-${pkgver}"
# Copy dkms.conf
install -Dm644 dkms.conf "${install_dir}/dkms.conf"
# Set name and version
sed -e "s/@_PKGNAME@/${_pkgname}/" -e "s/@PKGVER@/${pkgver}/" -i "${install_dir}/dkms.conf"
# Install module loading configuration
install -Dm644 "${pkgbase}.modprobe.conf" "${pkgdir}/etc/modprobe.d/${pkgbase}.conf"
# Install module source
cd ${pkgbase}-${pkgver}/v4l2loopback
for d in $(find . -type d); do
install -dm755 "${install_dir}/${d}"
done
for f in $(find . -type f ! -name '.gitignore'); do
install -m644 "${f}" "${install_dir}/${f}"
done
}
"##;
let pkgdata = PkgData::from_source(&source_code).expect("this should have passed");
assert_eq!(pkgdata.pkgbase.unwrap(), "droidcam");
assert_eq!(pkgdata.pkgname, vec!["droidcam", "v4l2loopback-dc-dkms"]);
assert_eq!(pkgdata.pkgver, "1.7.3");
assert_eq!(pkgdata.pkgrel, 1);
assert_eq!(pkgdata.epoch, Some(1));
assert_eq!(
pkgdata.pkgdesc,
Some("A tool for using your android device as a wireless/usb webcam".to_string())
);
assert_eq!(
pkgdata.url,
Some("https://github.com/aramg/${pkgbase}".to_string())
);
assert_eq!(pkgdata.arch, vec!["x86_64"]);
assert_eq!(pkgdata.license, Some(vec!["GPL".to_string()]));
assert_eq!(
pkgdata.makedepends,
Some(vec![
"gtk3".to_string(),
"ffmpeg".to_string(),
"libusbmuxd".to_string()
])
);
assert_eq!(
pkgdata.source,
Some(vec![
"${pkgbase}.desktop".to_string(),
"dkms.conf".to_string(),
"${pkgbase}.conf".to_string(),
"${pkgbase}-${pkgver}.zip::${url}/archive/v${pkgver}.zip".to_string(),
])
);
assert_eq!(
pkgdata.sha512sums,
Some(vec![
"72d21aa2d7eecc9bb070aaf7059a671246feb22f9c39b934a5463a4839f9347050de00754e5031dbc44f78eb2731f58f0cd2fcf781bc241f6fbd1abb4308b7ee".to_string(),
"27848dc6825c965c0aaac8e86220c3916ba20df6d941f5f05caecbf9c329ee744ee883bd2638ba58fe0dc3f40a8ae804dafbfbbe2efc23237e2b5450606cb78d".to_string(),
"74415b349bf8b2d1bb8181906f4254416d6223c5c42951185051bf3dd3e2f780db3441078ebff4a670eb0ffc76cc08f3b36851e0824c55a7f70136ce4d0240bc".to_string(),
"3934033dac931277a2f8ff348bcaa39b0cfe3e73885acd28f34b4b4efd8ce0b8606f23493b92206b5a7d3a2e1a2e1726d1d9ec33cd3f1876d1e6806dfb59c74f".to_string(),
])
);
assert_eq!(pkgdata.depends, None);
assert_eq!(pkgdata.optdepends, None);
assert_eq!(pkgdata.checkdepends, None);
assert_eq!(pkgdata.provides, None);
assert_eq!(pkgdata.conflicts, None);
assert_eq!(pkgdata.replaces, None);
assert_eq!(pkgdata.validpgpkeys, None);
assert_eq!(pkgdata.md5sums, None);
assert_eq!(pkgdata.sha224sums, None);
assert_eq!(pkgdata.sha256sums, None);
assert_eq!(pkgdata.sha384sums, None);
assert_eq!(pkgdata.b2sums, None);
}
}