App-CPANtoRPM
view release on metacpan or search on metacpan
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
( run in 1.904 second using v1.01-cache-2.11-cpan-98e64b0badf )