Subject: | Distroprefs should support global env settings and coderefs |
Distroprefs was - for me - the greatest recent improvement of CPAN!
However, I am missing two things:
1. The yml structure should support a global definition for
environment variable settings, like this:
---
matches: "..."
env:
CFLAGS: "-O2"
pl:
env:
LDFLAGS="-R /mylibpath"
I.e., the individual steps (get, pl, make, test, install) would use
both the global env settings and the individual ones, and the
individual ones override global ones.
2. Allow Perl coderefs as values: The configuration variable
yaml_load_code suggests that this would be possible, but that only
enables the YAML parser to read code definitions; the CPAN module
however does not understand coderefs (yet); the following error
appears when loading a file with a coderef (with yaml_load_code=1):
CPAN: Kwalify loaded ok (v1.19)
validation of distropref '/tmp2/Perl/Distroprefs/INGY.YAML.yml'[0]
against schema '/opt/perl_5.8.8/lib/CPAN/Kwalify/distroprefs.yml'
failed: - [/pl/env/CFLAGS] Non-valid data 'CODE(0x8eb115c)',
expected text
The attached script demonstrates that YAML supports code refs well
(although the deparse does not work for "use").
The code snippet below shows how both items can be solved - I took
the "pl" task as an example, near line 7869 of CPAN.pm; the enabling
of coderefs has to be coded elsewhere, too - maybe a central "_get_pref
()" which evaluates either coderefs or scalars would make sense
(including error handling):
sub _get_pref {
my ($key, $val) = @_;
if(ref($val) && ref($val) eq 'CODE') {
my $ret = eval { &$val() };
if($@) {
$CPAN::Frontend->myprint("Could not evaluate code for $key: $@");
return;
}
return $ret;
}
return $val;
}
... near 7869 of CPAN.pm ...
my %pl_env;
if ($self->prefs->{env}) {
%pl_env = %{$self->prefs->{env}};
}
if ($self->prefs->{pl}) {
%pl_env = (%pl_env, %{$self->prefs->{pl}{env}};
}
for my $e (keys %pl_env) {
my $val = _get_pref($e => $pl_env{$e});
$ENV{$e} = $val if defined $val;
}
I am sorry for not providing a full patch - that's because I am not
sure whether my approach is the right one; maybe you have a better
idea how to enable the two improvements.
Many thanks for your considerations, and keep up the good work!
Cheers,
Marek
Subject: | yaml.pl |
#!/opt/perl_5.8.8/bin/perl -w
use strict;
use YAML qw(Load Dump);
$YAML::UseCode = 1;
my @yaml = Load(<<'EOY');
---
pl:
env:
CFLAGS: !!perl/code |
{
use Config;
return $Config{'ccflags'} . ' ' .$Config{'optimize'};
}
EOY
print "CFLAGS=",&{$yaml[0]->{pl}->{env}->{CFLAGS}},"\n\n";
print "Loaded YAML with coderef:\n",Dump(\@yaml),"\n\n";
exit 0;