przemo has asked for the wisdom of the Perl Monks concerning the following question:

Dear monks

I have a need -- why so is a subject for another node -- for using separate CPANPLUS configurations (lets call them custom). Reading very old FAQ I found a note to define PERL5_CPANPLUS_CONFIG environment variable pointing to the config file.

However, for a long time it doesn't work. The appropriate RT ticket sends to CPANPLUS::Configure's save sub documentation:

Please follow the directions outlined in CPANPLUS::Configure->save or use the 's save' command in the default shell to use custom config files.

The instructions say how to write custom configuration, but nothing on reading it... The mentioned tickets also gives another hint:

Since 0.07x we have a new config file system that scans your @INC and homedir for config files

That was the time to use strace. Unfortunately, it showed that the order is just the opposite: first ~/.cpanplus/lib is searched (lets call it a user config), then @INC. So I can use custom config in current dir (which is in @INC) only when no user configuration is present.

To the question: what is the "right" way to use custom CPANPLUS configurations without removing user's one?

Replies are listed 'Best First'.
Re: CPANPLUS custom configurations
by ig (Vicar) on May 07, 2009 at 23:41 UTC

    cpanplus will load multiple configuration files if they are present. The default shell doesn't provide a function for saving the configuration anywhere but to the system and user configuration files, but you can create additional files yourself.

    It loads system configuration, then user configuration, then any other configuration file it finds. Your check with strace might suggest otherwise, but the system and user configuration modules are brought to the head of the list after discovery.

    A configuration file is any module with a name starting with "CPANPLUS/Config/", relative to the current base directory (by default: $home/.cpanplus on a linux system) or any folder in @INC. The modules other than the system and user modules are loaded in somewhat random order (keys %hash, with all the module names as the keys of the hash), so having more than one may be a bit confusing.

    So, you can have CPANPLUS/Configure/Custom.pm in your cwd when you run cpanp and this will be loaded after the system and user configurations. You can put whatever you want in your custom configuration module. An easy start might be to copy your user configuration module.

      A configuration file is any module with a name starting with "CPANPLUS/Config/", relative to the current base directory (by default: $home/.cpanplus on a linux system) or any folder in @INC.

      Thanks a lot, works.

      But what is interesting (strace-d), if any such module is found in @INC, the same module is also being loaded from $HOME/.cpanplus first, so the one found in @INC has no effect. A bug? A feature?

      What is also important, make sure that the package in which the configuration is defined matches the filename, or the configuration will be ignored (possibly with some errors on the console). Seems normal, but may be missed when copying the saved User.pm file to e.g. SomeLocal.pm without changing the package name.

      So to sum up with some code, I use custom cpanp configuration for local dir "installations" by starting it in a directory having CPANPLUS/Config/SomeLocal.pm:

      package CPANPLUS::Config::SomeLocal; use warnings; use strict; use Cwd; sub setup { my $conf = shift; my $d = getcwd; $conf->set_conf( base => "$d/.cpanplus" ); $conf->set_conf( buildflags => "install_base=$d/perl" ); $conf->set_conf( makemakerflags => "INSTALL_BASE=$d/perl" ); return 1; } 1;
        But what is interesting (strace-d), if any such module is found in @INC, the same module is also being loaded from $HOME/.cpanplus first, so the one found in @INC has no effect. A bug? A feature?

        The configuration modules are loaded using require. Thus a given module will only be loaded once, even if multiple instances occur in the various directories in @INC, and the first one found in @INC will be loaded. This is standard behavior for require.

        While loading configuration modules, CPANPLUS localizes @INC and prepends the user's cpanplus library directory to @INC (on unix systems this is ~/.cpanplus/lib with ~ expanded to the current user's home directory). Thus, as you observed, configuration is loaded preferentially from this directory in the case that a module of the same name also exists somewhere else.

        It seems quite deliberate, so I guess it's a feature.

Re: CPANPLUS custom configurations
by Anonymous Monk on May 07, 2009 at 23:44 UTC
    Since PERL5_CPANPLUS_CONFIG stopped working, I tried
    require 'myConfig.pl'; do 'cpanp'
    where myConfig.pl is
    BEGIN { $INC{'CPANPLUS/Config/System.pm'}=__FILE__;} package CPANPLUS::Config::System; ...
    seems to work well enough. Inline::Module