App-CPANtoRPM
view release on metacpan or search on metacpan
If you will be applying patches to a package, you will need the patch
command.
You also need to be able to read both YAML and JSON files included in
almost every module. This means that you will need one JSON module
installed out of the following:
JSON
JSON::XS
JSON::PP
JSON::DWIW
and one YAML module from the following:
YAML
YAML::Syck
YAML::XS
YAML::Tiny
You will also need to be able to examine POD files using one of the
following modules:
Pod::Select
Pod::Simple::TextContent
You'll should have:
Module::Build
Module::Build::Tiny
ExtUtils::MakeMaker
installed in order to build modules that use the Build.PL and
Makefile.PL scripts (both Module::Build and Module::Build::Tiny are
supported).
In order to build the rpm, you need the rpmbuild program.
This script also relies on the strace program. This is necessary because
many Makefile.PL and Build.PL scripts are interactive so when you run
them, they hang waiting for input. Unfortunately, I was not able to find
any pure perl way to run a program as a child (or in a thread) and
monitor it to see if it's still running because it's doing work, or
still running because it's waiting on user input. Though somewhat crude,
strace can be used to determine that.
In order to sign packages, you must have the gpg program installed, and
you must have a key set up to sign with. In order to do this
non-interactively, you also need either the Expect module or the expect
program installed.
In order to install the package, you either must be running as root, or
have the sudo program. The sudo command may be interactive, depending on
how you have it set up.
In order to install RPMs in a yum repository, the repository must exist.
HISTORY
This script is based loosely on Erick Calder's cpan2rpm script and
Steven Pritchard's cpanspec script. Initially, I set out to modify one
or the other of them, but I found that the modifications that I felt
necessary were extensive enough that I decided a fresh implementation
was both faster and cleaner.
cpan2rpm
cpan2rpm had basically the full functionality that I wanted. It
would download a module, write a spec file for it, create an RPM,
and then install it. The only functionality that was missing was
some simple functionality to add it to a local yum repository. That
would have been very simple to add. However, it suffered from
several other significant problems.
cpan2rpm is old. It has not been supported since 2003. It has
virtually no support for modules built using Build.PL scripts, and
adding it would have been quite complicated.
cpan2rpm is also not written as cleanly, or in a style that I'd like
to maintain, so it would take a bit of cleaning up to turn it into
something I'd want to maintain.
The main problem though is how it gets information from the
Makefile.PL script. In order to get all of the information necessary
to create a SPEC file, there's a lot of information about the module
that needs to be examined. Much of that information is stored in the
various META files in any new module distribution. None of that is
used in cpan2rpm (which predates most of them), so that would have
to be added. However, even with the META files, some information
comes from the Makefile.PL (or Build.PL script) such as the default
install location.
Since the data is in a script, cpan2rpm tries to be intelligent
about extracting the information. It loads in the Makefile.PL
script, modifies it (by turning 'exit' into 'return') and evals it.
The theory is that by eval'ing it, you end up with the appropriate
data structure that you can examine.
The modifications that it makes are completely unjustified though.
It makes drastic assumptions about what the Makefile.PL file looks
like, and I can think of any number of cases where turning 'exit'
into 'return' won't produce the result you want.
As such, cpan2rpm's handling of the Makefile.PL file needed to be
replaced entirely (and since that makes up a significant portion of
the script, that justified a complete rewrite).
In addition, if the script contained in Makefile.PL is interactive,
cpan2rpm hangs silently while trying to eval it, and there is no
easy way to determine what is causing it to hang.
cpanspec
cpanspec is much cleaner in most respects. It is well written,
handles both Makefile.PL and Build.PL installs, and handles all of
the new META files.
However, it has a few other problems.
It was written specifically for redhat distributions (redhat,
centos, fedora) and hardcodes some of the redhat specific paths in
it. Other RPM based distributions (such as OpenSuSE which I use) use
different paths. At the very least, the cpanspec file would need to
be modified to add options to override the defaults.
cpanspec also makes assumptions about where you want to install the
modules. It will only install in the vendor location of the primary
perl installation. If you want to install them anywhere else, you
are out of luck.
But the single biggest weakness was how it handles the Makefile.PL
and Build.PL scripts. Rather than evaluating the code, cpanspec just
opens them and tries to parse information from them.
Again, given that these are perl scripts, the only reliable way to
parse them is to actually use the perl interpreter. Although most
modern modules include Makefile.PL or Build.PL scripts that follow
certain conventions, it is by no means guaranteed, so I was not
satisfied with this assumption.
As with cpan2rpm, cpanspec does not deal with interactive installs.
It simply shuffles the problem to another location. In this case,
once the SPEC file is created, it is necessary to run rpmbuild, and
this will hang.
Due to the weaknesses in both of the existing alternatives, I decided a
clean rewrite was in order. The goals were:
Beginning-to-end functionality
cpantorpm will download the module from CPAN, create the SPEC file,
generate an RPM, install it, and store the RPM in a local YUM
repository for other hosts to use.
Cross platform
cpantorpm will work on any RPM based distribution (though this is
only tested on redhat and OpenSuSE to date). Also, many of the steps
can be done in many different ways, different one of which may be
available by default platforms, so most steps will try more than one
way to accomplish the task.
For example, to download a module, cpantorpm will use the CPAN
module, the CPANPLUS module, and various tools to download via HTTP
(such as wget, curl, etc.).
Correctly handle Makefile.PL and Build.PL
The only way to correctly handle these scripts is to actually build
the module. The files generated contain all of the information in a
standard format, and we can get it without making any assumptions
about the format of these scripts.
Handle interactive installs
Many installs are potentially interactive. If you are missing
prerequisites, many modules will stop and ask you if you want to
install them first.
cpantorpm traps this behavior and allows you to handle it, rather
than hanging for an unknown reason.
Note: by 'handle it', it will not try to install them. Rather, the
cpantorpm script will let you know what was being asked, and then
exit, and at that point, it's up to you to correct the problem. A
future version of cpantorpm may include some automatic handling of
missing prerequisites which is the primary cause of interactive
installs hanging.
All that being said, I have borrowed ideas (and in rare instances, code)
freely from cpanspec and cpan2rpm. I'm very grateful to the authors of
both cpan2rpm and cpanspec who's work has made mine much easier.
Hopefully, cpantorpm takes the best of both worlds and improves on that.
KNOWN BUGS
None known.
BUGS AND QUESTIONS
If you find a bug in cpantorpm, there are three ways to send it to me.
In order of preference, they are:
GitHub
You can submit it as an issue on GitHub. This can be done at the
following URL:
<https://github.com/SBECK-github/App-CPANtoRPM>
This is the preferred method. Please submit problems requests as
GitHub issues if at all possible.
( run in 1.301 second using v1.01-cache-2.11-cpan-364913b4093 )