After "carton install" some dependencies have "0" as version - perl

New to Perl here, apologies for the maybe silly question. After running "carton install" I noticed in the cpanfile.snapshot that some dependencies still has "0" as version, so basically, no version was selected.
Is this the expected behaviour?
To be more precise, the dependency is declared in the cpanfile with "0" as version and does not appear in the snapshot file at all.

According to the documentation for ExtUtils::MakeMaker :
PREREQ_PM
A hash of modules that are needed to run your module. The
keys are the module names ie. Test::More, and the minimum version is
the value. If the required version number is 0 any version will do.
The versions given may be a Perl v-string (see version) or a range
(see CPAN::Meta::Requirements).
This will go into the requires field of your META.yml and the runtime
of the prereqs field of your META.json.
PREREQ_PM => {
# Require Test::More at least 0.47
"Test::More" => "0.47",
# Require any version of Acme::Buffy
"Acme::Buffy" => 0, }
So a zero version in the cpanfile.snapshot means that a dependent or required module specified a version number of zero, meaning that any version will do.
To be more precise, the dependency is declared in the cpanfile with "0" as version and does not appear in the snapshot file at all.
It depends if it is a core module or not, core modules are not included in the snapshot, but you can implicitly declare a version by specifying a minimum version for perl itself in the cpanfile:
requires 'perl', '5.022000';
See also Specifying dependencies for your CPAN distribution for more information.

Related

Coq file generated by WP does not compile

I have installed frama-c (18.0) and coqide (8.9) through opam (plus other needed dependencies of course, but that may not be the matter here). Well the point is I simply installed it through opam, not done anything else strange (and I didn't see any particular instruction that I should do otherwise).
Frama-c works as expected when I use Alt-ergo with WP, but if I try to use coq or coqide instead of Alt-ergo, then I get the following error for each goal that Qed does not manage to prove immediately:
[wp] 13 goals scheduled
[wp] [Coq] 'Qed.v' compilation failed.
------------------------------------------------------------
--- Coqc (stderr) :
------------------------------------------------------------
File "/tmp/wp7fe5dc.dir/coqwp/Qed.v", line 27, characters 8-17:
Error:
Cannot find a physical path bound to logical path matching suffix bool.
------------------------------------------------------------
[wp] [Coq] Goal typed_nondet_loop_inv_preserved : Failed
Compilation of 'Qed.v' failed.
As a note, before displaying the error, it manages to compile some other .v files. I have tried to open manually the files in coqide, and I get the same result. For the record, here are the lines coq complains about:
Require bool.Bool.
Require int.Int.
Require int.Abs.
Require int.ComputerDivision.
Require real.Real.
Require real.RealInfix.
Require real.FromInt.
I have also tried to downgrade coq a bit, but not lower than 8.7 (as otherwise opam complains of incompatible base installation package and I don't really want to screw up my installation), and got the same result.
If someone would have an idea of what is causing that and how I can get to set it up that correctly, that'd be nice. Even if for what I'm doing with it for now, Alt-ergo is sufficient, I would have liked to play a bit with coq to see how it can be used.
Regards,
--
Vincent Penelle.
First, indeed you need coq < 8.8 (e.g. 8.7.2) if you want to use it with Frama-C/WP, as newer versions are not supported for the moment.
Second, the order in which you have installed your packages is relevant. In particular, if the appropriate version of coq has been installed after frama-c, WP did not compile and install its coq libraries, which are the ones that are missing here. Thus, you may want to do opam reinstall frama-c to compile the package against a compatible coq version.

Is it possible to setup the cross module version in VERSION_FROM option (of Makefile.PL)?

I want to setup the same version for few projects in one place.
I've tried:
use ExtUtils::MakeMaker;
WriteMakefile(
VERSION_FROM => 'lib/project/version.pm',
...
In 'lib/project/version.pm':
package project::version;
use AnotherProject;
our $VERSION = AnotherProject->VERSION();
1;
Note: AnotherProject is located in separate directory, but could be loaded by 'use AnotherProject'. And contain 'our $VERSION="1.00"'.
$ perl Makefile.PL
WARNING: Setting VERSION via file 'lib/project/version.pm' failed
at /usr/lib64/perl5/5.18.2/ExtUtils/MakeMaker.pm line 599.
Can't parse version 'undef'
Is it possible to pass (get) the version string from another module?
Maybe there is another way to do it, please support me.
When you use VERSION_FROM, ExtUtils::MakeMaker doesn't run the file you point at, it parses it itself and tries to find a version number that way. In this case, that won't work. Using VERSION instead of VERSION_FROM in Makefile.PL and calling the other module from there should work.

Defining required packages and versions for a perl project

I am familiar with using package.json with node.js, Gemfile for Ruby, Podfile for Objective-C, et al.
What is the equivalent file for Perl and what is the syntax used?
I've installed a couple packages using cpanm and would like to save the package names and version in a single file that can be executed by team members.
For simple use cases, writing a cpanfile is a good choice. A sample file might look like
requires 'Marpa::R2', '2.078';
requires 'String::Escape', '2010.002';
requires 'Moo', '1.003001';
requires 'Eval::Closure', '0.11';
on test => sub {
requires 'Test::More', '0.98';
};
That is, it's actually a Perl script, not a data format. The dependencies can then be installed like
$ cd /path/to/your/module
$ cpanm --installdeps .
This does not install your module! But it makes sure that all dependencies are satisfied, so we can do:
use lib '/path/to/your-module/lib'; # add the location as a module search root
use Your::Module; # works! yay
This is usually sufficient e.g. for a git repository which you want others to tinker with.
If you want to create a tarball that can be distributed and installed easily, I'd recommend Dist::Zilla (although it's geared towards CPAN releases). Instead of a cpanfile we use a dist.ini:
name = Your-Module
version = 1.2.3
author = Your Self <you#example.com>
license = GPL_3
copyright_holder = Your Self
[#Basic]
[Prereqs]
Marpa::R2 = 2.078
String::Escape = 2010.002
Moo = 1.003001
Eval::Closure = 0.11
[Prereqs / TestRequires]
Test::More = 0.98
Then:
$ dzil test # sanity checks, and runs your tests
$ dzil build # creates a tarball
Dist::Zilla takes care of creating a Makefile.PL and other infrastructure that is needed to install the module.
You can then distribute that tarball, and install it like cpanm Your-Module-1.2.3.tar.gz. Dependencies are resolved, your packages are copied to a permanent location, and you can now use Your::Module in any script without having to specify the location.
Note that you should adhere to the standard directory layout for Perl modules:
./
lib/
Your/
Module.pm # package Your::Module
Module/
Helper.pm # package Your::Module::Helper
t/ # tests to verify the module works on the target syste,
foo.t
bar.t
xt/ # optional: Author tests that are not run on installation
baz.t
bin/ # optional: scripts that will later end up in the target system's $PATH
command-line-tool
Makefile.PL usually (along with a few other files; Perl has had packages for longer then any of the other languages you mention and suffers from a bit of inelegance here).
Module Starter is a sensible way to start writing a package. It has a getting started guide.

How to specify test prerequisites in the ExtUtils::MakeMaker Makefile.PL

PREREQ_PM specifies the runtime prerequisites, but how to specify which modules are required to run the test cases?
Should I use BUILD_REQUIRES for this?
As of ExtUtils::MakeMaker 6.64, there is a TEST_REQUIRES parameter.
use ExtUtils::MakeMaker 6.64;
WriteMakefile(
...,
TEST_REQUIRES => {
Test::More => 0.95,
},
...,
);
The CPAN::Meta::Spec defines how modules communicate their prerequisites to the toolchain. The version 2 spec revised the way prerequisites are listed. The test phase now has its own list of prerequisites.
But MakeMaker hasn't been updated for the v2 spec, and likely never will be. The only fully-compliant v2 distribution tool I know of is Dist::Zilla (and I recommend it for more reasons than that).
When CPAN::Meta::Converter converts from the v2 spec to v1.4, it merges the test requirements into build_requires.
So yes, if you stick with MakeMaker, any modules that are required to run the tests should be listed in BUILD_REQUIRES. PREREQ_PM should contain only modules that are still required after the module is installed.
If the tests fail without a module, then I list it in PREREQ_PM regardless of whether it's needed for testing or for running the module.
If I need modules for some tests, but they are not needed to run the module, I detect those when the tests are run, and I skip the tests (with a PASS) if I can't find them.
I don't think there is any field in ExtUtils::MakeMaker for what you want.

How can I safely compile a Perl 5.12 module for Perl 5.8.9?

I want to install File::Fetch, which is a core module in Perl 5.12, in my Perl 5.8.9. In general, I want to compile and install future-dated modules in my back-dated Perl because I cannot upgrade my Perl.
So I downloaded the module and also its dependencies. It's quite painful following the dependency tree but I'm more concerned about the fact that some of them are core modules. If I install these, my Perl 5.8.9 core will have patches from 5.12.
My question is how I can know whether I can safely install the future-dated modules, especially the core modules. Is there a tutorial for this purpose of testing backwardcompatability in Perl?
EDIT:
My module is dual lifed, but I cannot compile it using cpan. It said my FTPsite.yaml has a bad element. However, I followed the dependencies in the modules' META files, and I could compiled the module. Is this one of the odd bits with cpan? Thank you.
I cannot recreate the issue after I installed all those dependencies manually. But here is the error:
cpan[5]> install File::Fetch
Running install for module 'File::Fetch'
Running make for B/BI/BINGOS/File-Fetch-0.24.tar.gz
CPAN: Digest::SHA loaded ok (v5.48)
CPAN: Time::HiRes loaded ok (v1.9715)
CPAN: YAML loaded ok (v0.72)
Alert: While trying to 'parse' YAML file
'/Users/martin/.cpan/FTPstats.yml'
with 'YAML' the following error was encountered:
YAML Error: Invalid element in map
Code: YAML_LOAD_ERR_BAD_MAP_ELEMENT
Line: 3
Document: 1
at /opt/local/lib/perl5/site_perl/5.8.9/YAML.pm line 36
If the module is available separately (i.e. "dual-lifed"), as both a standalone distribution and inside core Perl, then the standalone version is safe to install on an earlier Perl, assuming its Makefile allows it. That is, if you can do cpan <Module> and it builds and tests without errors, then you are good.
The only problem is if a module is not dual-lifed, which I opined about in this question -- which is where you are likely S.O.L.
If a perl core module is also available separately, that means that it is intended to work on older perls (unless it explicitly requires some version of perl), and if it doesn't, that's a bug.
That said, 5.10 was released almost three years ago, and you are going to start seeing more and more problems using newer modules with older versions of perl.
cpan or cpanplus will handle dependencies for you.