The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
NAME
    cpantorpm - An RPM package for perl modules

SYNOPSIS
       cpantorpm [OPTIONS] MODULE

    This script takes a perl module and creates an RPM for it.

DESCRIPTION
    This script handles the entire process of obtaining a perl module and
    turning it into an RPM package. This includes the steps of obtaining the
    module distribution, creating an RPM from it, and then making the
    package available in various ways.

    The following steps are involved in this process, and are discussed in
    more detail below:

    Obtain the perl module
    Parse various perl modules files for necessary information
    Build the package
    Generate a spec file
    Create the RPM packages
    Install the RPM (optional)
    Store the RPM in a local yum repository (optional)

OPTIONS
    The following general purpose options exist.

    -h/--help
        Prints a help message describing command usage.

    -v/--version
        Prints the version of this program.

    -D/--debug
        Enable verbose debugging output.

    -t/--tmpdir DIR
        The cpantorpm script makes use of a default directory to store all
        of it's working files in. It defaults to:

           /tmp/cpantorpm

        but can be set explicitly with this option.

    -f/--optfile FILE
        All of the options below that may be specified on the command line
        may also come from a config file. The config file may contain the
        options for any number of modules and is described below.

    The following options affect how a module is downloaded.

    -c/--cpan
        When downloading modules from CPAN, the script will first try to use
        CPANPLUS and, if that is not available, it will use CPAN. If this
        option is included, only CPAN will be tried.

    Once the module is downloaded, it will be analyzed and various
    information about the module which will be used in creating the RPM is
    gathered. This includes looking at the perl META files, the main POD
    document, and the build scripts (Makefile.PL or Build.PL).

    The following options impact these operations:

    --name NAME
        By default, the name of the package will be obtained from the
        distribution name. This option can be used to explicitly set the
        name, overriding the distribution name.

        NOTE: the name of the RPM will be based on this, but will typically
        have a prefix added. See the --prefix and --no-prefix options below
        for more details.

    --summary TEXT
        Every package has a 1-line summary description. By default, this
        comes from the main POD document or the META files, but can be
        explicitly set using this option.

    --description FILE
        Every package has a multi-line description. To override the
        description that comes from the POD document, put the description in
        a local file, and pass that file name to this option.

    --mainpod FILE
        The description and summary of the module typically come from the
        main POD document, if it can be determined using the normal methods
        described below.

        In a few cases (where the POD document is named in some non-standard
        way), it may not be possible to determine which is the main POD
        document. In this case, you can specify it using this option.

        FILE is the path to the file relative to the top level in the module
        distribution. For example, it might be:

           lib/Foo/Bar.pm

    --author AUTHOR
        This lists an author for the module, overriding the values from the
        META files. This option can be included multiple times for multiple
        authors.

    --vers VERSION
        This specifies the version of the RPM. It defaults to the version of
        the package, but can be overridden here.

    The following options are used during the SPEC file creation step:

    -n/--no-tests
    --NO-TESTS
        When creating a module RPM, typically, the module tests are run as
        part of the process. These two options can be used to modify this
        behavior.

        The first will add the lines necessary to run the tests to the SPEC
        file, but (by use of an environment variable), the tests will not be
        run when the RPM is created. In this instance, if the SPEC file is
        used to create an RPM at some later date, the tests will run (unless
        the environment variable RPMBUILD_NO_TESTS is set).

        With the first option, the lines necessary to run the tests will not
        be added to the SPEC file at all.

    -d/--no-deps
    --NO-DEPS
        By default, when building an RPM, the prerequisites for the module
        will be tested.

        There are three types of prerequisites:

           prerequisites to build the module
           prerequisites to run the module tests
           prerequisites to use the installed module

        It is slightly unfortunate that RPM only recognizes two types. There
        is no way to specify requirements to run tests.

        As such, the build requirements will include those requirements to
        run the tests unless the --NO-TESTS option is given. In this case,
        requirements to run the tests will be omitted.

        If the --no-deps option is given, dependencies will not be tested
        (though they will be added to the SPEC file).

        If the --NO-DEPS option is given, dependencies will not be added to
        the SPEC file at all.

        In addition, if either of these are given, --no-tests is implied.

    --prefix PREFIX
    --no-prefix
        By default, a prefix of 'perl-' is added to the name of the package
        (or the name supplied using the --name option).

        To specify that no prefix be added, use the --no-prefix option. To
        specify an alternate prefix, use the --prefix option.

    -p/--packager PACKAGER
        Use this option to specify the name of the packager. The name of the
        packager may be suplied using the '%packager' macro in the
        ~/.rpmmacros file. If it is not there, this option must be included.

    --rpmbuild DIR
        RPMs are built in the RPM build hierarchy. This defaults to the
        value of the '%_topdir' macro, or it can be specified using this
        option.

        The directory will have the following subdirectories:

           BUILD
           SOURCES
           SPECS
           SRPMS
           RPMS

    --clean-macros
        By default, macros included in the existing ~/.rpmmacros file will
        be used. With this option, that file is temporarily removed (it will
        be restored when the script exits).

    --group GROUP
        Every package is a member of a group. If this is not specified, it
        defaults to:

           Development/Libraries

    --release STRING
    --disttag STRING
        The full name of an RPM is something like:

           foo-bar-1.00-1a-noarch.rpm

        The string '1a' here consists of the release (1) and a disttag (a).
        By default, release is '1' and disttag is the macro '%{?dist}', but
        these can be overridden with these options.

    --epoch EPOCH
        This sets an epoch number in the RPM when the version number is not
        sufficient to determine the relative age of two different versions.

    --add-require FEATURE[=VERS]
    --add-provide FEATURE[=VERS]
        Every RPM has a list of features that are required in order to use
        it, and a list of features that it provides.

        In some cases, you may need to add featurs to these two lists. Both
        options may include a version:

           --add-requires Foo::Bar=0.45

    --rem-require FEATURE
    --rem-provide FEATURE
        Related to the previous options, these options allow you to remove a
        feature from the requirements list, or the list of features
        provided.

        Unfortunately, there is no cross-platform way of doing this, so
        these options will only function on a RHEL or Fedora computer.
        Functionality on other platforms may be added in the future.

    -m, --macros
        Use the macro form of common SPEC constructs over the environment
        variable form (e.g. %{buildroot} vs $RPM_BUILD_ROOT).

    The perl module must be built as part of the process. The following
    options are used during the build:

    --build-type TYPE
        TYPE must be 'make' or 'build' and specifies that the build must be
        done using the Makefile.PL or Build.PL files respectively (for those
        modules that have both). If that file does not exist, an error is
        triggered.

    --config STRING
        The given string is passed to either the 'perl Build.PL' or 'perl
        Makefile.PL' command used to configure the module and create a Build
        script or a Makefile. This option can be passed in any number of
        times, but only a single option should be included in each STRING.

        Since the arguments passed in differ when using a Makefile.PL and a
        Build.PL procedure, for safety, you should always include the
        --build-type option when using this option.

    --build STRING
        Similar to the --config option except this passes strings which are
        passed to either the './Build' or 'make' command used to actually
        build the module. This option can be passed in any number of times.

    -T/--install-type TYPE
    -i/--install-base DIR
        These options allow you to specify where the module will be
        installed. By default, the module will be built to install in the
        standard perl location. In most cases, that would mean installing
        the module, documentation, and scripts in:

           BASEDIR/lib/perl5/PERLVERS
           BASEDIR/man
           BASEDIR/bin

        where BASEDIR is the place where perl is installed (which is
        typically /usr) and PERLVERS is the version directory (i.e. 5.14.2).
        To install in /usr/local instead of /usr, just use the option:

           --install-base /usr/local

        To change the module installation directory (but not the directory
        of the documentation or scripts) to either the site_perl or
        vendor_perl location, use:

           --install-type site
           --install-type vendor

        to set the module directory to be:

           BASEDIR/lib/perl5/site_perl/PERLVERS
           BASEDIR/lib/perl5/vendor_perl/PERLVERS

        respectively.

        The --install-type value must be one of:

           perl  (or core)
           site
           vendor

        and defaults to 'perl'. 'perl' and 'core' are synonyms. If this is
        passed in, it will override any default value set in the Makefile.PL
        or Build.PL scripts (so be careful about rebuilding core modules).

    --mandir STRING
        When specifying a prefix (using the --install-base option), it is
        necessary to determine where man pages should be installed relative
        to this directory.

        Most of the time, this can be determined automatically, but if your
        version of perl installs man pages by default in a completely
        separate location from where it installs libraries, it may not be
        able to be determined correctly and should be specified using this.

        The only time this would happen would be if the man pages were
        installed in one hierarchy and the libraries in a completely
        different hierarchy (i.e. man pages in /usr and libraries in /opt
        for example).

    To control what steps get done, the following options are available:

    --spec-only
        By default, the script creates a SPEC file, and then builds RPMs
        (both source and binary).

        With the --spec-only option, the SPEC file is created, but no
        further action is taken.

    --no-clean
        By default, the build tree will be removed after the RPM is built.
        If this option is given, it will be left in place.

OBTAIN THE PERL MODULE
    The perl module may be obtained in a number of different ways. The perl
    module may exist on local disk either as an archive file or a directory,
    or it can be retrieved from a URL or from CPAN.

    For example, any of the following ways could be used:

       cpantorpm Foo::Bar
       cpantorpm http://some.host.com/some/path/Foo-Bar-1.00.tar.gz
       cpantorpm /tmp/Foo-Bar-1.00.tar.gz
       cpantorpm /tmp/Foo-Bar-1.00

    When working with a CPAN module, you must use the form:

       Foo::Bar

    instead of

       Foo-Bar

    When downloading from a URL, both ftp:// and http:// URLs are supported
    (though others such as file:// and https:// are not supported at this
    time).

    For this script to work, the perl module must meet a few validity
    requirements:

    Valid name format
        The name of the distribution must be of the form:

           PACKAGE-VERS

        if obtained from a local directory, or

           PACKAGE-VERS.EXT

        if obtained from an archive (a local file, a URL, or from CPAN).
        Here VERS is any string which does NOT contain a dash (-). EXT may
        be any of the following extensions:

           .tar
           .tar.gz
           .tgz
           .tar.bz2
           .zip

            The module must contain either a Build.PL or Makefile.PL script.
            A module using some other non-standard build procedure cannot be
            built with this script.

        Getting the module in each of the 4 ways requires different system
        requirements. In general, the script will try several different ways
        to get the module, and will only fail if all of the different
        methods fail.

        The following system requirements exist for the different ways of
        obtaining a module:

        From a local directory
            You must be able to run the system command 'cp -r' (to
            recursively copy a directory) or be able to load the module
            File::Copy::Recursive.

        From a local file
            You must be able to run the system command 'cp' (to copy a file)
            or be able to load the module File::Copy.

            In addition, you must meet additional requirements for working
            with the different types of archives as described next.

        From a URL
            To get a module from a URL, you have to have one of the
            following packages installed:

               curl
               wget
               lynx
               links
               lftp

            or be able to load one of the modules:

               LWP::UserAgent
               HTTP::Lite

            In addition, you must meet additional requirements for working
            with the different types of archives as described next.

        From CPAN
            To get a module from CPAN, you must be able to load one of the
            perl modules:

               CPANPLUS::Backend
               CPAN

            In addition, you must meet additional requirements for working
            with the different types of archives as described next.

        In each case (except for obaining a module from a local directory),
        once you have obtained the archive, you need to be able to extract
        it.

        To do this, you need to meet the system requirements for the
        appropriate type of archive:

        .tar, .tar.gz, .tgz files
            You need to be able to run the system 'tar' command, or be able
            to load one of the perl modules:

               Archive::Extract
               Archive::Tar

            These modules will make use of other modules to handle .gz or
            .bz2 compression.

        .zip files
            You need to be able to run the system 'unzip' command, or be
            able to load one of the perl modules:

               Archive::Extract
               Archive::Zip

PARSE VARIOUS PERL MODULES FILES FOR NECESSARY INFORMATION
    Building an RPM correctly involves getting a great deal of information
    from the module. We have to know what features are provided by this
    module, what features are required by the module to run, as well as the
    description of the module, the author, etc.

    This information can be obtained by a number of different files
    including:

    Makefile.PL, Build.PL
        Currently, these are only used to determine how the module should be
        built. Although they typically contain a great deal more
        information, it is written as perl code and there is no reasonable
        way to get the information from them.

        However, one of the steps done by this script is to actually build a
        Build script or Makefile (this ensures that the perl module can be
        correctly built), and information can be extracted from them since
        they do follow regular formats.

    META.json, MYMETA.json
        For a description of the type of data stored here, please refer to
        the CPAN-Meta documentation on CPAN.

        In order to interpret a JSON file, you have to be able to load one
        of the following perl modules:

           Parse::CPAN::Meta
           JSON
           JSON::XS
           JSON::PP
           JSON::DWIW

        Most of the information can be obtained from a complete JSON file.

    META.yml, MYMETA.yml
        For a description of the type of data stored here, please refer to
        the CPAN-Meta documentation on CPAN.

        In order to interpret a YAML file, you have to be able to load one
        of the following perl modules:

           Parse::CPAN::Meta
           CPAN::Meta::YAML
           YAML
           YAML::Syck
           YAML::XS
           YAML::Tiny

        Most of the information can be obtained from a complete YAML file.

    Pod file
        In most instances, some of the information (primarily the summary
        and description of the module) must be obtained from a pod document.
        This will require one of the modules:

           Pod::Select
           Pod::Simple::TextContent

        The script will need to determine which POD file to get this
        informaion from (the primary POD file for the package). Most of the
        time, the script is able to determine which file to use, but if it
        fails, it can be manually specified using the --mainpod option.

BUILD THE PACKAGE
    The next step is to actually build the module.

    This step is a departure from the way cpanspec and cpan2rpm work. In
    both of these scripts, the SPEC file contains the procedure for building
    the perl module, but it is never tested to see if it works.

    This has a couple significant advantages:

    It ensures that the package builds
        A number of perl modules cannot be built automatically because the
        scripts are interactive. Unfortunately, the RPM build process does
        not handle this well, so what you end up with is a hanging process
        that (eventually) you will have to kill by hand. In other cases, the
        build process fails for other reasons.

        When the build process is put in the SPEC file untested, the RPM
        build process will either fail or hang.

        This script avoids many of those problems.

    It generates additional meta data
        Both cpanspec and cpan2rpm would interpret the Makefile.PL and
        Build.PL scripts directly to obtain information from them. Since
        there is no guarantee that these scripts follow any convention, I
        considered this a very poor option.

        By actually building the module, it creates either a Makefile or a
        _build hierarchy, and these DO follow regular conventions, and
        information can be obtained from them with a much greater chance of
        success.

    This script actually builds the module to ensure that it can be done. It
    watches the process to see if it enters a state where it's waiting for
    user input, and if it does, the process ends and the RPM is not built,
    and you can then go in and correct the problem (typically by installing
    some build prerequisite, or supplying a non-standard option to the build
    process, or in the worst case, by providing a patch to the module source
    that removes the interactive nature.

GENERATE A SPEC FILE
    Much of the process of generating a spec file is taken from the cpanspec
    package.

    The first step in creating a SPEC file is to determine where the RPM
    build hierachy lives (since that is where the SPEC file will live). This
    script supports using the standard build hierarchy, or specifying an
    alternate location.

    If the --rpmbuild option is used, it is used to specify the location of
    the build hierarchy. Otherwise, the standard location will be used. If a
    location is specified, and if there is a ~/.rpmmacros file present, the
    ~/.rpmmacros file must not contain the macro %_topdir that is different
    than the one specified by the --rpmbuild option. If the macro does
    exist, you can use the --rpm-clean option to specify a clean version of
    the .rpmmacros file be used.

    The SPEC file created by this script does deviate from the recommended
    form in one respect. The recommended way to handle the list of
    requirements and the list of features provided by an RPM is to leave out
    these lists in the SPEC file and allow rpmbuild to generate them
    automatically. In the SPEC file, you only list changes to the defaults.
    In other words, you can add features that are required or that the
    package provides that were not picked up automatically, or you can add
    lines to the SPEC file to filter out features that you do not want the
    rpm to depend on or provide.

    Unfortunately, even though adding prerequisites and provided features
    works well, removing them does not work nearly as smoothly. The methods
    for filtering prerequisites and features does not work well cross
    platform (attempts that worked for redhat would not work for openSuSE
    for example).

    As a result, I do not let the SPEC file tell rpmbuild to generate these
    lists. Instead, I generate the lists (using the standard rpm utilities
    when available, or using an included script when they are not) and
    explicitly put them in the SPEC file.

CREATE THE RPM PACKAGES
    Once the SPEC file is done, the RPM can be created using the standard
    RPM tools.

    It uses the standard RPM file structure and creates both a source RPM
    and a binary RPM.

    INSTALL THE RPM
        This is an optional step.

        *** FIX ***

    STORE THE RPM IN A LOCAL YUM REPOSITORY
        This is an optional step.

        *** FIX ***

CONFIG FILE
    A config file can be created which sets options on a per-module basis.
    It can be either a YAML file (ending in .yaml or .yml) or a JSON file
    (ending in .json).

    A sample YAML file is:

       ---
       Crypt::SSLeay:
          - --config=--default

       Foo::Bar:
          - --name Foobar

    Each line should contain one option of any of the forms:

       --opt=val
       --opt val
       -o    val

    If val contains spaces, you should NOT put quotes around it. Use:

       --summary This is the summary

    instead of:

       --summary "This is the summary"

SYSTEM REQUIREMENTS
    This module will try to function under many different situations, and it
    will often try multiple methods to accomplish a task, and many of those
    methods will be available on any common linux configuration. As such, a
    rigorous list of system requirements is overly complicated and won't be
    listed here. In the event that the script fails, it will list the
    methods tried and you can make sure that one of them will function on
    your host.

    The most common requirements will be listed here. In all probability, if
    you meet these requirements, this script will run.

    Since the most common way to obtain a module will be from CPAN, you will
    need one of the following modules installed and correctly configured:

       CPAN
       CPANPLUS

    To make sure it's configured, make sure you can run 'cpan' or 'cpanp' at
    the command line and have it work.

    You also need to be able to read the YAML and JSON files included in
    almost every module. This means that you will need one JSON module
    installed 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 both:

       Module::Build
       ExtUtils::MakeMaker

    installed in order to build modules that use the Build.PL and
    Makefile.PL scripts.

    This script also relies on the 'strace' program. This is necessary
    because many Makefile.PL and Build.PL scripts are interactive, but there
    is no easy way to determine whether a script is running because it is
    doing something time consuming, or if it's waiting on user input.
    'strace' is used to determine that.

HISTORY
    This script is based loosely on Erick Calder's cpan2rpm script and
    Steven Pritchard's cpanspec script.

    cpan2rpm had a lot more functionality, but has not been supported since
    2003. It has virtually no support for modules built using Build.PL
    scripts, and it's method of generating spec files was much too
    complicated and error prone. Initially, I was planning on modifying it,
    and I spent a bit of time working in that direction, but in the end, I
    decided that fixing it was actually more work than rewriting it, and I'd
    have a much cleaner script in the end if I rewrote it.

    cpanspec is much better at generating spec files, and is actively
    supported, but is missing the more complete functionality of cpan2rpm.
    It also made a few assumptions about how you wanted modules to be
    installed (for example, it will only install in the vendor location). I
    considered writing a wrapper around cpanspec, but in the end, I was not
    satisfied with it's functionality, and even then, I'd be required to
    modify it to get rid of some of the limitations that I didn't want.

    Perhaps the biggest single weakness in both of them was that they made
    assumptions about the format of the Makefile.PL and Build.PL scripts
    that were not justfied. Both cpan2rpm and cpanspec tried to interpret
    the Build.PL and Makefile.PL scripts to determine information about the
    module requirements (and other information). This relies on the fact
    that standard forms of these files are used. Since there is no standard
    for these files, I did not like the assumption that this could be done
    and I've replaced this by an alternate step. Rather than try to
    interpret the Makefile.PL or Build.PL scripts, cpantorpm will actually
    try to build the modules. If it fails for any reason, the error output
    will be shown and this script will exit. This script will trap any build
    processes which require human input (which some Makefile.PL and Build.PL
    scripts do) rather than hanging.

    Since I was not satisfied with the assuptions they made, and since
    starting from either would require modification on my part to support
    the functionality I wanted, I decided to just write my own copying the
    code from cpanspec for the functionality I wanted (I LOVE open source
    licenses!) modified as necessary. That being said, I'm very grateful to
    the author of cpanspec who's work has made mine much easier.

    Hopefully, cpantorpm gives the best of both worlds.

KNOWN BUGS
    None known.

BUGS AND QUESTIONS
    If you find a bug in cpantorpm, please send it directly to me (see the
    AUTHOR section below). Alternately, you can submit it on CPAN using the
    URL:

       http://rt.cpan.org/Public/Dist/Display.html?Name=cpantorpm

    Please do not use other means to report bugs (such as Usenet newsgroups,
    or forums for a specific OS or Linux distribution) as it is impossible
    for me to keep up with all of them.

    When filing a bug report, please include the version of cpantorpm you
    are using. You can get this by running:

       cpantorpm -v

    SEE ALSO
        cpan2rpm - Erick Calder's script to generate RPMs

        cpanspec - Steven Pritchard's script to generate spec files

LICENSE
    This script is free software; you can redistribute it and/or modify it
    under the same terms as Perl itself.

AUTHOR
    Sullivan Beck (sbeck@cpan.org)

POD ERRORS
    Hey! The above document had some coding errors, which are explained
    below:

    Around line 3671:
        =over should be: '=over' or '=over positive_number'

    Around line 3763:
        You forgot a '=back' before '=head1'

    Around line 3930:
        '=item' outside of any '=over'

    Around line 3942:
        You forgot a '=back' before '=head1'

    Around line 4095:
        '=item' outside of any '=over'

    Around line 4101:
        You forgot a '=back' before '=head1'