Skip to content

Commit

Permalink
Add documentation and further increase feature coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
dralley committed Jan 6, 2024
1 parent 70cbe7a commit a29dc0e
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 6 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `Dependency::script_pre()`, `Dependency::script_post()`, `Dependency::script_preun()`, `Dependency::script_postun()`
- `Dependency::user()`, `Dependency::group()`
- Added support for the automatic user/group creation feature in rpm 4.19
- `PackageBuilder::group()` and `PackageBuilder::packager()`
- `FileOptions::is_artifact()` and `FileOptions::is_missingok()`

### Changed

- Improved documentation

## 0.13.1

Expand Down
28 changes: 25 additions & 3 deletions src/rpm/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ pub struct PackageBuilder {
compression: CompressionWithLevel,

vendor: Option<String>,
packager: Option<String>,
group: Option<String>,
url: Option<String>,
vcs: Option<String>,
cookie: Option<String>,
Expand Down Expand Up @@ -121,20 +123,39 @@ impl PackageBuilder {
}
}

/// Set the package vendor - the organization that is producing the package
pub fn vendor(mut self, content: impl Into<String>) -> Self {
self.vendor = Some(content.into());
self
}

/// Set the URL for the package. Most often this is the website of the upstream project being
/// packaged
pub fn url(mut self, content: impl Into<String>) -> Self {
self.url = Some(content.into());
self
}

/// Set the version control URL of the upstream project
pub fn vcs(mut self, content: impl Into<String>) -> Self {
self.vcs = Some(content.into());
self
}

/// Set the packager, the name of the person producing the package. This is often not present,
/// or set to the same value as the vendor
pub fn packager(mut self, content: impl Into<String>) -> Self {
self.packager = Some(content.into());
self
}

/// Set the package group (this is deprecated in most packaging guidelines)
pub fn group(mut self, content: impl Into<String>) -> Self {
self.group = Some(content.into());
self
}

/// Set the package epoch
pub fn epoch(mut self, epoch: u32) -> Self {
self.epoch = epoch;
self
Expand Down Expand Up @@ -184,7 +205,8 @@ impl PackageBuilder {
self
}

/// Define a value that can be used for associating several package builds as being part of one operation
/// Define a value that can be used for associating several package builds as being part of
/// one operation
///
/// You can use any value, but the standard format is "${build_host} ${build_time}"
pub fn cookie(mut self, cookie: impl AsRef<str>) -> Self {
Expand Down Expand Up @@ -223,8 +245,8 @@ impl PackageBuilder {
/// For Xz compression, the expected range is 0 to 9, with a default value of 9.
/// For Zstd compression, the expected range is 1 to 22, with a default value of 19.
///
/// If this method is not called, the payload will be Gzip compressed by default. This may change
/// in future versions of the library.
/// If this method is not called, the payload will be Gzip compressed by default. This may
/// change in future versions of the library.
pub fn compression(mut self, comp: impl Into<CompressionWithLevel>) -> Self {
self.compression = comp.into();
self
Expand Down
72 changes: 69 additions & 3 deletions src/rpm/headers/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,9 +184,6 @@ impl From<FileMode> for u16 {
}
}

/// Description of file modes.
///
/// A subset
#[derive(Debug)]
pub struct FileOptions {
pub(crate) destination: String,
Expand All @@ -200,6 +197,7 @@ pub struct FileOptions {
}

impl FileOptions {
/// Create a new FileOptions for a file which will be placed at the provided path.
#[allow(clippy::new_ret_no_self)]
pub fn new(dest: impl Into<String>) -> FileOptionsBuilder {
FileOptionsBuilder {
Expand All @@ -223,27 +221,46 @@ pub struct FileOptionsBuilder {
}

impl FileOptionsBuilder {
/// Indicates that the file should be owned by the specified username.
///
/// Specifying a non-root user here will direct RPM to create the user via sysusers.d at
/// installation time.
///
/// See: %attr from specfile syntax
pub fn user(mut self, user: impl Into<String>) -> Self {
self.inner.user = user.into();
self
}

/// Indicates that the file should be part of the specified group.
///
/// Specifying a non-root group here will direct RPM to create the group via sysusers.d at
/// installation time.
///
/// See: %attr from specfile syntax
pub fn group(mut self, group: impl Into<String>) -> Self {
self.inner.group = group.into();
self
}

/// Indicates that a file is a symlink pointing to the location provided
pub fn symlink(mut self, symlink: impl Into<String>) -> Self {
self.inner.symlink = symlink.into();
self
}

/// Set the FileMode - type of file (or directory, or symlink) and permissions.
///
/// See: %attr from specfile syntax
pub fn mode(mut self, mode: impl Into<FileMode>) -> Self {
self.inner.mode = mode.into();
self.inner.inherit_permissions = false;
self
}

/// Indicates that a file should have the provided POSIX file capabilities.
///
/// See: %caps from specfile syntax
pub fn caps(mut self, caps: impl Into<String>) -> Result<Self, errors::Error> {
// verify capabilities
self.inner.caps = match FileCaps::from_str(&caps.into()) {
Expand All @@ -257,35 +274,84 @@ impl FileOptionsBuilder {
Ok(self)
}

/// Indicates that a file is documentation.
///
/// See: %doc from specfile syntax
pub fn is_doc(mut self) -> Self {
self.inner.flag.insert(FileFlags::DOC);
self
}

/// Indicates that a file is a configuration file. When a package is updated, files marked as
/// configuration files will be checked for modifications compared to their default state,
/// and if any are present then the old configuration file will be saved with a .rpmsave extension.
///
/// User intervention may be required to reconcile the changes between the new and old configs.
///
/// See: %config from specfile syntax
pub fn is_config(mut self) -> Self {
self.inner.flag.insert(FileFlags::CONFIG);
self
}

/// Indicates that a file is allowed to be missing at install or uninstall time - it might be
/// created in a scriptlet.
///
/// Should be used in conjunction with `is_config()`
///
/// See: %config(missingok) from specfile syntax
pub fn is_missingok(mut self) -> Self {
self.inner.flag.insert(FileFlags::MISSINGOK);
self
}

/// Indicates that a (configuration) file should not be replaced if it has been modified.
/// When a package is updated, configuration files will be checked for modifications compared
/// to their default state, and if any are present then the new configuration file will
/// be installed with a .rpmnew extension.
///
/// User intervention may be required to reconcile the changes between the new and old configs.
///
/// See: %config(noreplace) from specfile syntax
pub fn is_no_replace(mut self) -> Self {
self.inner.flag.insert(FileFlags::NOREPLACE);
self
}

/// Indicates that a file ought not to actually be included in the package, but that it should
/// still be considered owned by a package (e.g. a log file). Its attributes are still tracked.
///
/// See: %ghost from specfile syntax
pub fn is_ghost(mut self) -> Self {
self.inner.flag.insert(FileFlags::GHOST);
self
}

/// Indicates that a file is a software license. License files are always included - they are
/// never filtered out during installation.
///
/// See: %license from specfile syntax
pub fn is_license(mut self) -> Self {
self.inner.flag.insert(FileFlags::LICENSE);
self
}

/// Deprecated (use `is_doc()`` instead). Marks a file as a README.
///
/// See: %readme from specfile syntax
pub fn is_readme(mut self) -> Self {
self.inner.flag.insert(FileFlags::README);
self
}

/// Indicates that a file is a packaging artifact (or similar) that could potentially be
/// excluded from installation if the user is low on disk space.
///
/// See: %artifact from specfile syntax
pub fn is_artifact(mut self) -> Self {
self.inner.flag.insert(FileFlags::ARTIFACT);
self
}
}

impl From<FileOptionsBuilder> for FileOptions {
Expand Down
1 change: 1 addition & 0 deletions src/rpm/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,7 @@ impl PackageMetadata {
.get_entry_data_as_i18n_string(IndexTag::RPMTAG_GROUP)
}

/// Get the packager, the name of the person that produced this package
#[inline]
pub fn get_packager(&self) -> Result<&str, Error> {
self.header
Expand Down

0 comments on commit a29dc0e

Please sign in to comment.