in reply to Re: CPANPLUS broken custom sources
in thread CPANPLUS broken custom sources

OK, your certainty was enough to make me go back and reduce things to figure this out. Since I'm new to cpanp, that was helpful. Because it seemed like the cleanest and best approach, I focused on cpanp "custom sources". Here's what I think I can say with some certainty (test follows):

  1. Custom sources determines "newer" version based on lexicographical compare, not version objects.
  2. cpanp _will_ find the latest install, provided your version numbers follow lexicographical ordering scheme (which I'm assuming is the older perl scheme). Thus it _does not_ need author/version as I'd said (I think the MiniCPAN method _does_ need this, but did not go back and test). Note that the newer perl versioning scheme (with the "v" on the front) doesn't work this way (example code below). So my guess is that cpanp does not use "version" objects. Thus for cpanp v0.10 < v0.9, which is _not_ true for version objects.
  3. cpanp _does not find_ any custom source preqs, regardless of how you specify the version in Build.PL. My guess is it is not even looking for these (although I haven't looked at the cpanp code yet).
  4. Custom sources requires one to do "/cs --list" prior to any command using an index, or it doesn't find the index (you get a URI index error). This is clearly a bug. My guess is that "/cs --list" may be populating an internal list. This _may_ be the reason I thought it was necessary to do some of the previous weirdness (write file then update). All one needs to do is, "/cs --list", "/cs --update 1" to update the custom sources (but note "/cs --list" _is_ necessary).

Here's a demo of perl version objects:

$ perl -e 'use version; $v1 = new version("v0.10"); $v2 = new version("v0.9"); print $v1 > $v2, "\n"'
1

Note it printed 1, so v0.10 > v0.9, which is not lexicographical, but the version object order (so we don't have to pad to v0.09 for example).

Next here's a demo showing that while it does install the latest module (provided you follow version lexicographical order), it will not find your prerequisite in custom sources. Note that I tried about 10 different slight permutation on the "requires" string in Build.PL, as described int the docs, from ultra simple, to prepending "v", etc. I couldn't get anything to work (i.e. cpanp never found any of these types). So I'm guessing that it doesn't even look (but I'm new to cpanp so take it with a grain of salt).

# Make empty custom sources dir

    $ mkdir customsrc

# Make dummy module

    $ module-starter --module=My::Module::Test --author="Jane Smith" --email=jane.smith@example.com --builder=Module::Install
    $ module-starter --module=My::Other::Module::Test --author="Jane Smith" --email=jane.smith@example.com --builder=Module::Install
    $ cd My-Module-Test

# Add version to generated lib/My/Module/Test.pm =>  "use version; our $VERSION = qv ('0.1');"
# Add "requires line" to Build.PL => "requires { 'My-Other-Module' => 'v0.1' },"
# Note, I tried many permutations of this, as well as
#   changing the version spec in My-Other-Module.
#   None of these 10 or so tries worked.

    $ perl Build.PL
    $ sudo Build dist
    $ cp My-Module-Test-v0.1.tar.gz ../customsrc
    $ sudo cpanp

    \CPANPLUS::Shell::Default -- CPAN exploration and module installation (v0.84)
    ...

    CPAN_Terminal> /cs --add file:////<path-to-your-local-dir>/customsrc

    Added remote source 'file:///Applications/MAMP/svn/qws-perl-libs/customsrc'

    Remote source contains:

       My-Module-Test-v0.1.tar.gz

    CPAN_Terminal> install My-Module-Test

# installs OK, but doesn't find My-Other-Module
    ...Warning: prerequisite My-Other-Module v0.1 not found.

I feel like the custom sources is very close to what I need, and seems a bit less flaky then I previously thought (well, now I am closer to knowing what the real bugs/problems are).

I still need to figure out how to make it look for the custom source prerequisites.

Replies are listed 'Best First'.
Re^3: CPANPLUS broken custom sources
by zerohero (Monk) on Mar 02, 2009 at 03:39 UTC

    Just a follow on message to let people know this is resolved, and custom sources works fine as long as you do the following two things:

    1. Use "old style" versions (i.e. $VERSION = "1.50"), which have a "2-digit zero padded minor form". Do not use extended versions (i.e. use version; our $VERSION = qv ("1.5")) as this doesn't seem to work.
    2. Make sure to refresh both the custom sources and update indexes any time there is a change. The non-obvious method (using a side effect of --write) to do this is:
      1. /cs --list
      2. /cs --write /dir
      3. /cs --update 1
      4. x

    You can validate that cpanp can "see" your sources by doing "m Your::Package". If this search doesn't find it, then cpanp won't install it.

    Custom sources are much easier than the MiniCPAN approach, in my opinion, if you just want to add your own libs.

      Do you realize qv("1.5") means 1.005?
      >perl -le"use version; print qv('1.5')->numify" 1.005000

      And for the numbers in the the grandparent

      >perl -le"use version; print qv('v0.9')->numify" 0.009000 >perl -le"use version; print qv('v0.10')->numify" 0.010000

      The "qv" forms work fine with cpan and CPAN. You just stick to using "qv" or stick to not using "qv". Switching can require a major version change.

      Here is a script which automates the cpanp steps to update a custom source dir, which I find tedious and error prone. It assumes that there is a writeable directory (so it can do /cs --write /dir), which is also readable through URI file:///dir. Just Build your .tar.gz files, drop them in your custom source dir, and execute this script prior to running cpanp.

      The script is a little unfinished in places (I didn't complete the part to read from ~/.xxx/config, and so $custom_src_dir is currently hardcoded).

      One thing I think could be better is reload_indices takes a long time. If we could selectively reload the index on a single custom source, this would be very fast.

      cpanp's scriptability is extremely well done. Great API.

      #!/usr/bin/perl
      
      use Getopt::Long;
      use Pod::Usage;
      use Data::Dumper;
      
      use CPANPLUS::Backend;
      
      sub main
      {
          my %options;
      
          GetOptions
              (\%options,
               'help|?',
               'man') or pod2usage (2);
      
          pod2usage (1) if $options{help};
          pod2usage (-exitstatus => 0, -verbose => 2)
              if $options{man};
      
          # TODO - get this from ~/.qws/devel_config custom_src_dir
          # this assumes that we have a custom source that is a file:/// which is also a writeable directory.
      
          my $custom_src_dir = "/Applications/MAMP/svn/deploy";
      
          # TODO - make sure this is an absolute path
      
          # Remove optional end / on $custom_src_dir
      
          if ($custom_src_dir =~ /^(.+)\/$/)
          {
              $custom_src_dir = $1;
          }
      
          my $custom_src_uri = "file://$custom_src_dir";
      
      
          my $cb = new CPANPLUS::Backend ();
      
          my %files = $cb->list_custom_sources ();
      
          my $found = 0;
          while (my ($n, $v) = each %files)
          {
              # match on URI => file:///fn
      
              if ($v =~ /^file:\/\/(.*)$/)
              {
                  my $filename = $1;
                  $found = 1 if ($filename eq $custom_src_dir);
              }
          }
      
      
          # If we don't have the source, add it.
      
          if ( ! $found)
          {
              # $cb->add_custom_source ($custom_src_uri);
      
              print STDERR "Added custom source '$custom_src_uri' to cpanp " .
                  "from your '~/.qws/devel_config' file.\n";
          }
      
          print STDERR "Writing custom source index\n";
      
          my $file = $cb->write_custom_source_index (path => $custom_src_dir);
      
          print STDERR "Updating custom source\n";
      
          my $updated = $cb->update_custom_source (remote => $custom_src_uri);
      
          print STDERR "Reloading indices\n";
      
          my $reloaded = $cb->reload_indices ();
      }