crystal-rpm

crystal-rpm

The RPM bindings for Crystal language based on ruby-rpm and ruby-rpm-ffi.

It supports RPM 4.8.0 or later.

Installation

  1. Add the dependency to your shard.yml:
dependencies:
  rpm:
    github: lugia-kun/crystal-rpm
  1. Run shards install

Usage

require "rpm"

The development files (pkg-config file) of RPM is required. Typically, it can be installed by yum install rpm-devel on CentOS or Red Hat, dnf install rpm-devel on Fedora, and zypper in rpm-devel on openSUSE or SLES.

Inspect package

pkg = RPM::Package.open("foobar-1.0-0.x86_64.rpm")
puts pkg[RPM::Tag::Name] # => "foobar"
puts pkg[RPM::Tag::Arch] # => "x86_64"
puts pkg[RPM::Tag::Summary] # => (Content of Summary)
# and so on...

pkg.requires # => Array of Requires.
pkg.provides # => Array of Provides.
pkg.conflicts # => Array of Conflicts.
pkg.obsoletes # => Array of Obsolstes.

Install package

RPM.transaction do |ts|
  path = "pkg_to_install-1.0-0.x86_64.rpm"
  pkg = RPM::Package.open(path)
  
  ts.install(pkg, path) # Add installation package. Package path is required.
  ts.commit   # Run Transaction
end

Search installed packages

# with given name
RPM.transaction do |ts|
  iter - ts.init_iterator(RPM::DbiTag::Name, "package-name-to-find")
  iter.each do |pkg|
    # Iterator over matching packages.
  end
end

# with given regexp
RPM.transaction do |ts|
  iter = ts.init_iterator   # Create iterator of installed packages
  
  # Set condition
  iter.regexp(RPM::DbiTag::Name, # <= Entry to search (here, Name)
              RPM::MireMode::REGEX, # <= Default matching method
              "simple.*") #  <= Name to search

  # Iterate over matching packages.
  iter.each do |pkg|
    puts pkg[RPM::Tag::Version].as(String) # => (Version of package "simple")
  end
end

# Iterate over all installed packages
RPM.transaction do |ts|
  iter = ts.init_iterator
  iter.each do |pkg|
    # ... iterates over all installed packages.
  end
end

# Lookup package(s) which contains a specific file
RPM.transaction do |ts|
  iter = ts.init_iterator(RPM::DbiTag::BaseNames, "/path/to/lookup")
  iter.each do |pkg|
    # ... iterates over packages contains "/path/to/lookup"
  end
end

# NOTE: Using regexp with BaseNames, it will search packages which
# contain a file whose basename is the given name.
RPM.transaction do |ts|
  iter = ts.init_iterator
  iter.regexp(RPM::DbiTag::BaseNames, RPM::MireMode::STRCMP, "README")
  iter.each do |pkg|
    # ... iterates over packages which contain a file named "README"
  end
end

Remove package

Currently, the following code does not work unless you are using OpenSUSE (see #1).

RPM.transaction do |ts|
  ts.delete(pkg) # Add to removal package
  ts.order
  ts.clean
  ts.commit   # Run Transaction
end

Using Transaction without block

ts = RPM::Transaction.new
begin
  ts.install(...)
  ts.delete(...)
  ts.order
  ts.clean
  ts.commit
ensure
  ts.close_db # Must close DB
end
ts.finalize # Not nesseary, but recommended.

Install/Remove Problems

RPM.transation do |ts|
  ts.install(...)
  ts.order
  ts.clean
  problems = ts.check
  problems.each do |problem|
    puts problem.to_s # => Output install (typically dependency) problems.
  end
end

Inspect Specfile

spec = RPM::Spec.open("foo.spec")
packages = spec.packages
packages[0][RPM::Tag::Name] # => (Name of the first package)
packages[1][RPM::Tag::Name] # => (Name of the second package)
# NOTE: The order is undefined.

spec.buildrequires # => Array of BuildRequires.

Build RPM (not yet available)

spec = RPM::Spec.open("foo.spec")
spec.build

Development

The definitiions of structs are written by hand. Tests can check their size and member offsets if you have a C compiler (optional).

fakechroot (recommended) or root permission (i.e., sudo) is required to run crystal spec, since this spec uses chroot().

Alternatively, using Docker is another method to test:

$ shards install
$ docker build -t [version] -f .travis/Dockerfile.rpm-[version] .
$ docker run -v $(pwd):/work -w /work [version] crystal spec

Note that shards should be installed on local (because git in CentOS 6 is too old and does not work with shards).

Contributing

  1. Fork it (https://github.com/lugia-kun/crystal-rpm/fork)
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

Contributors

Github statistic:
  • 0
  • 1
  • 0
  • 1
  • 2
  • about 1 month ago

License:

MIT License

Links: