Expand description
§alpm-package
A library providing low-level functionality for Arch Linux Package Management (ALPM) based packages.
This library offers integration for creating an alpm-package from a prepared input directory, which contains all necessary files (i.e. metadata files, optional install scriptlets and data files).
§Documentation
- https://alpm.archlinux.page/rustdoc/alpm_package/ for development version of the crate
- https://docs.rs/alpm-package/latest/alpm_package/ for released versions of the crate
§Examples
§Library
A package file can be created from a prepared input directory.
The input directory must contain at the very least a valid BUILDINFO, a PKGINFO and an ALPM-MTREE file.
Then the relevant metadata/data/script files can be read from the package archive using the PackageReader
API.
use std::fs::{File, Permissions, create_dir_all};
use std::io::Write;
use std::os::unix::fs::PermissionsExt;
use alpm_mtree::create_mtree_v2_from_input_dir;
use alpm_package::{
CompressionSettings,
InputDir,
MetadataEntry,
OutputDir,
Package,
PackageCreationConfig,
PackageInput,
};
use alpm_types::MetadataFileName;
use tempfile::TempDir;
// Create a common temporary directory for input and output.
let temp_dir = TempDir::new()?;
let path = temp_dir.path();
let input_dir = path.join("input");
create_dir_all(&input_dir)?;
let input_dir = InputDir::new(input_dir)?;
let output_dir = OutputDir::new(path.join("output"))?;
// Create a valid, but minimal BUILDINFOv2 file.
let mut file = File::create(&input_dir.join(MetadataFileName::BuildInfo.as_ref()))?;
write!(file, r#"
builddate = 1
builddir = /build
startdir = /startdir/
buildtool = devtools
buildtoolver = 1:1.2.1-1-any
format = 2
installed = other-example-1.2.3-1-any
packager = John Doe <john@example.org>
pkgarch = any
pkgbase = example
pkgbuild_sha256sum = b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c
pkgname = example
pkgver = 1:1.0.0-1
"#)?;
// Create a valid, but minimal PKGINFOv2 file.
let mut file = File::create(&input_dir.join(MetadataFileName::PackageInfo.as_ref()))?;
write!(file, r#"
pkgname = example
pkgbase = example
xdata = pkgtype=pkg
pkgver = 1:1.0.0-1
pkgdesc = A project that returns true
url = https://example.org/
builddate = 1
packager = John Doe <john@example.org>
size = 181849963
arch = any
license = GPL-3.0-or-later
depend = bash
"#)?;
// Create a dummy script as package data.
create_dir_all(&input_dir.join("usr/bin"))?;
let mut file = File::create(&input_dir.join("usr/bin/example"))?;
write!(file, r#"!/bin/bash
true
"#)?;
file.set_permissions(Permissions::from_mode(0o755))?;
// Create a valid ALPM-MTREEv2 file from the input directory.
create_mtree_v2_from_input_dir(&input_dir)?;
// Create PackageInput and PackageCreationConfig.
let package_input: PackageInput = input_dir.try_into()?;
let config = PackageCreationConfig::new(
package_input,
output_dir,
Some(CompressionSettings::default()),
)?;
// Create package file.
let package = Package::try_from(&config)?;
// Create a reader for the package.
let mut reader = package.clone().into_reader()?;
// Read all the metadata from the package archive.
let metadata = reader.metadata()?;
let pkginfo = metadata.pkginfo;
let buildinfo = metadata.buildinfo;
let mtree = metadata.mtree;
// Or you can iterate over the metadata entries:
let mut reader = package.clone().into_reader()?;
for entry in reader.metadata_entries()? {
let entry = entry?;
match entry {
MetadataEntry::PackageInfo(pkginfo) => {}
MetadataEntry::BuildInfo(buildinfo) => {}
MetadataEntry::Mtree(mtree) => {}
_ => {}
}
}
// You can also read specific metadata files directly:
let mut reader = package.clone().into_reader()?;
let pkginfo = reader.read_metadata_file(MetadataFileName::PackageInfo)?;
// let buildinfo = reader.read_metadata_file(MetadataFileName::BuildInfo)?;
// let mtree = reader.read_metadata_file(MetadataFileName::Mtree)?;
// Read the install scriptlet, if present:
let mut reader = package.clone().into_reader()?;
let install_scriptlet = reader.read_install_scriptlet()?;
// Iterate over the data entries in the package archive.
let mut reader = package.clone().into_reader()?;
for data_entry in reader.data_entries()? {
let mut data_entry = data_entry?;
let content = data_entry.content()?;
// Note: data_entry also implements `Read`, so you can read from it directly.
}
// Convenience functions for reading packages without creating a reader:
let pkginfo = package.read_pkginfo()?;
let buildinfo = package.read_buildinfo()?;
let mtree = package.read_mtree()?;
let install_scriptlet = package.read_install_scriptlet()?;
§Contributing
Please refer to the contribution guidelines to learn how to contribute to this project.
§License
This project can be used under the terms of the Apache-2.0 or MIT. Contributions to this project, unless noted otherwise, are automatically licensed under the terms of both of those licenses.
Re-exports§
pub use compression::Bzip2CompressionLevel;
pub use compression::CompressionAlgorithm;
pub use compression::CompressionDecoder;
pub use compression::CompressionEncoder;
pub use compression::CompressionSettings;
pub use compression::GzipCompressionLevel;
pub use compression::XzCompressionLevel;
pub use compression::ZstdCompressionLevel;
pub use compression::ZstdThreads;
pub use config::OutputDir;
pub use config::PackageCreationConfig;
pub use error::Error;
pub use input::InputDir;
pub use input::PackageInput;
pub use package::DataEntry;
pub use package::ExistingAbsoluteDir;
pub use package::MetadataEntry;
pub use package::Package;
pub use package::PackageEntry;
pub use package::PackageReader;
Modules§
- compression
- Compression handling.
- config
- Package creation configuration.
- error
- Error handling.
- input
- Facilities for creating a package file from input.
- package
- Representation of alpm-package files.
- scriptlet 🔒
- Checks for alpm-install-scriptlet files.