diff --git a/Changelog b/Changelog index 79c070e..8459cdf 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,30 @@ + 2.41 + - fixed rt.cpan.org#38635. apache-like include now supports + quoted strings. + + - fixed rt.cpan.org#41748. saving config with -tie enabled + now keeps the tie as documented. + + - added unit test for -tie. For this to work, a copy of + Tie::LxHash module is delivered with Config::General + source, but will not installed, in fact, it is only + used for 'make test' (number 50) + + - fixed rt.cpan.org#39159. documentation of functional interface + now reflects that qw$method) is now required. + + - applied patch by AlexK fixing rt.cpan.org#41030: + if files are included by means of a glob pattern having the -IncludeGlob + option activated, paths specified by the -ConfigPath option are being + neglected when trying to spot the files. This patch fixes this + + - applied patch by fbicknel, fixes rt.cpan.org#41570: + An array of scalars (eg: option = [1,2,3]) cannot + be used for interpolation (which element shall we use?!), so + we ignore those types of lists and don't build a __stack for them. + + + 2.40 - fixed SplitDelimiter parser regex, it does no more consider non-whitespaces (\S+?) as the option name but anything diff --git a/General.pm b/General.pm index 8807e80..adafb7b 100644 --- a/General.pm +++ b/General.pm @@ -32,7 +32,7 @@ use Carp::Heavy; use Carp; use Exporter; -$Config::General::VERSION = 2.40; +$Config::General::VERSION = 2.41; use vars qw(@ISA @EXPORT_OK); use base qw(Exporter); @@ -413,6 +413,18 @@ sub _open { # Something like: *.conf (or maybe dir/*.conf) was included; expand it and # pass each expansion through this method again. my @include = grep { -f $_ } bsd_glob($configfile, GLOB_BRACE | GLOB_QUOTE); + + # applied patch by AlexK fixing rt.cpan.org#41030 + if ( !@include && defined $this->{ConfigPath} ) { + foreach my $dir (@{$this->{ConfigPath}}) { + my ($volume, $path, undef) = splitpath($basefile); + if ( -d catfile( $dir, $path ) ) { + push @include, grep { -f $_ } bsd_glob(catfile($dir, $basefile), GLOB_BRACE | GLOB_QUOTE); + last; + } + } + } + if (@include == 1) { $configfile = $include[0]; } @@ -694,8 +706,23 @@ sub _read { # fetch pathname of base config file, assuming the 1st one is the path of it $path = $this->{ConfigPath}->[0]; } - if (/^\s*<>\s*$/i || (/^\s*include\s+(.+?)\s*$/i && $this->{UseApacheInclude})) { - $incl_file = $1; + + # bugfix rt.cpan.org#38635: support quoted filenames + if ($this->{UseApacheInclude}) { + if (/^\s*include\s*(["'])(.*?)(?>\s*$/i) { + $incl_file = $1; + } + } + + if ($incl_file) { if ( $this->{IncludeRelative} && $path && !file_name_is_absolute($incl_file) ) { # include the file from within location of $this->{configfile} $this->_open( $incl_file, $path ); @@ -709,6 +736,7 @@ sub _read { # standard entry, (option = value) push @{$this->{content}}, $_; } + } } @@ -1104,14 +1132,14 @@ sub save_file { } if (!$config) { if (exists $this->{config}) { - $config_string = $this->_store(0, %{$this->{config}}); + $config_string = $this->_store(0, $this->{config}); } else { croak "Config::General: No config hash supplied which could be saved to disk!\n"; } } else { - $config_string = $this->_store(0,%{$config}); + $config_string = $this->_store(0, $config); } if ($config_string) { @@ -1137,14 +1165,14 @@ sub save_string { if (!$config || ref($config) ne 'HASH') { if (exists $this->{config}) { - return $this->_store(0, %{$this->{config}}); + return $this->_store(0, $this->{config}); } else { croak "Config::General: No config hash supplied which could be saved to disk!\n"; } } else { - return $this->_store(0, %{$config}); + return $this->_store(0, $config); } return; } @@ -1155,7 +1183,7 @@ sub _store { # # internal sub for saving a block # - my($this, $level, %config) = @_; + my($this, $level, $config) = @_; local $_; my $indent = q( ) x $level; @@ -1166,9 +1194,9 @@ sub _store { # are obviously the same, but I don't know how to call # a foreach() with sort and without sort() on the same # line (I think it's impossible) - foreach my $entry (sort keys %config) { - if (ref($config{$entry}) eq 'ARRAY') { - foreach my $line (sort @{$config{$entry}}) { + foreach my $entry (sort keys %{$config}) { + if (ref($config->{$entry}) eq 'ARRAY') { + foreach my $line (sort @{$config->{$entry}}) { if (ref($line) eq 'HASH') { $config_string .= $this->_write_hash($level, $entry, $line); } @@ -1177,18 +1205,18 @@ sub _store { } } } - elsif (ref($config{$entry}) eq 'HASH') { - $config_string .= $this->_write_hash($level, $entry, $config{$entry}); + elsif (ref($config->{$entry}) eq 'HASH') { + $config_string .= $this->_write_hash($level, $entry, $config->{$entry}); } else { - $config_string .= $this->_write_scalar($level, $entry, $config{$entry}); + $config_string .= $this->_write_scalar($level, $entry, $config->{$entry}); } } } else { - foreach my $entry (keys %config) { - if (ref($config{$entry}) eq 'ARRAY') { - foreach my $line (@{$config{$entry}}) { + foreach my $entry (keys %{$config}) { + if (ref($config->{$entry}) eq 'ARRAY') { + foreach my $line (@{$config->{$entry}}) { if (ref($line) eq 'HASH') { $config_string .= $this->_write_hash($level, $entry, $line); } @@ -1197,11 +1225,11 @@ sub _store { } } } - elsif (ref($config{$entry}) eq 'HASH') { - $config_string .= $this->_write_hash($level, $entry, $config{$entry}); + elsif (ref($config->{$entry}) eq 'HASH') { + $config_string .= $this->_write_hash($level, $entry, $config->{$entry}); } else { - $config_string .= $this->_write_scalar($level, $entry, $config{$entry}); + $config_string .= $this->_write_scalar($level, $entry, $config->{$entry}); } } } @@ -1266,7 +1294,7 @@ sub _write_hash { } $config_string .= $indent . q(<) . $entry . ">\n"; - $config_string .= $this->_store($level + 1, %{$line}); + $config_string .= $this->_store($level + 1, $line); $config_string .= $indent . q(\n"; return $config_string @@ -1373,7 +1401,7 @@ Config::General - Generic Config Module # # the procedural way - use Config::General; + use Config::General qw(ParseConfig SaveConfig SaveConfigString); my %config = ParseConfig("rcfile"); =head1 DESCRIPTION @@ -1686,7 +1714,7 @@ the same Tie class. Example: - use Config::General; + use Config::General qw(ParseConfig); use Tie::IxHash; tie my %hash, "Tie::IxHash"; %hash = ParseConfig( @@ -2494,7 +2522,7 @@ Thomas Linden =head1 VERSION -2.40 +2.41 =cut diff --git a/General/Interpolated.pm b/General/Interpolated.pm index a8597d8..3499c97 100644 --- a/General/Interpolated.pm +++ b/General/Interpolated.pm @@ -174,7 +174,11 @@ sub _var_array_stacker { next; } else { - $config->{__stack}->{$key} = $config->{$key}; + #### $config->{__stack}->{$key} = $config->{$key}; + # removed. a array of scalars (eg: option = [1,2,3]) cannot + # be used for interpolation (which one shall we use?!), so + # we ignore those types of lists. + # found by fbicknel, fixes rt.cpan.org#41570 } push @new, $entry; } diff --git a/MANIFEST b/MANIFEST index f932734..383fa8e 100644 --- a/MANIFEST +++ b/MANIFEST @@ -38,3 +38,4 @@ README example.cfg Changelog Makefile.PL +META.yml Module meta-data (added by MakeMaker) diff --git a/META.yml b/META.yml new file mode 100644 index 0000000..7a24753 --- /dev/null +++ b/META.yml @@ -0,0 +1,14 @@ +# http://module-build.sourceforge.net/META-spec.html +#XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX# +name: Config-General +version: 2.41 +version_from: General.pm +installdirs: site +requires: + File::Glob: 0 + File::Spec::Functions: 0 + FileHandle: 0 + IO::File: 0 + +distribution_type: module +generated_by: ExtUtils::MakeMaker version 6.30 diff --git a/Makefile.PL b/Makefile.PL index 2f3442f..6079c0b 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -19,6 +19,8 @@ WriteMakefile( 'FileHandle' => 0, 'File::Spec::Functions' => 0, 'File::Glob' => 0 - } + }, + ($ExtUtils::MakeMaker::VERSION ge '6.31'? + ('LICENSE' => 'perl', ) : ()), ); diff --git a/t/apache-include.conf b/t/apache-include.conf index 824338b..069e5b7 100644 --- a/t/apache-include.conf +++ b/t/apache-include.conf @@ -2,5 +2,5 @@ include t/included.conf - include t/included.conf + include "t/included.conf" diff --git a/t/run.t b/t/run.t index c3c12e0..5777c46 100644 --- a/t/run.t +++ b/t/run.t @@ -8,9 +8,16 @@ use Data::Dumper; -use Test::More tests => 49; +use Test::More tests => 50; #use Test::More qw(no_plan); +# ahem, we deliver the test code with a local copy of +# the Tie::IxHash module so we can do tests on sorted +# hashes without dependency to Tie::IxHash. +use lib qw(t); +use Tie::IxHash; + + ### 1 BEGIN { use_ok "Config::General"}; require_ok( 'Config::General' ); @@ -615,3 +622,19 @@ if ($got47 =~ /\Q$sorted\E/) { else { fail("Testing sorted save"); } + + + +tie my %hash48, "Tie::IxHash"; +my $ostr48 = +"zeppelin 1 +beach 2 +anathem 3 +mercury 4\n"; +my $cfg48 = new Config::General( + -String => $ostr48, + -Tie => "Tie::IxHash" + ); +%hash48 = $cfg48->getall(); +my $str48 = $cfg48->save_string(\%hash48); +is( $str48, $ostr48, "tied hash test");