1 package Config::GitLike;
6 use Scalar::Util qw(openhandle);
7 use Fcntl qw(O_CREAT O_EXCL O_WRONLY);
10 our $VERSION = '1.04';
19 # not defaulting to {} allows the predicate is_loaded
20 # to determine whether data has been loaded yet or not
23 predicate => 'is_loaded',
31 default => sub { +{} },
34 # filename where the definition of each key was loaded from
38 default => sub { +{} },
41 has 'config_files' => (
44 default => sub { [] },
47 # default to being more relaxed than git, but allow enforcement
48 # of only-write-things-that-git-config-can-read if you want to
63 my ($name, $mult) = (@_, 1);
64 $self->multiple->{$name} = $mult;
70 return if !defined $name;
71 return $self->multiple->{$name};
76 my $path = shift || Cwd::cwd;
79 $self->config_files([]);
82 $self->load_dirs( $path );
83 return wantarray ? %{$self->data} : \%{$self->data};
88 return "." . $self->confname;
94 my($vol, $dirs, undef) = File::Spec->splitpath( $path, 1 );
95 my @dirs = File::Spec->splitdir( $dirs );
98 my $path = File::Spec->catpath(
99 $vol, File::Spec->catdir(@dirs), $self->dir_file
103 last unless $self->cascade;
107 $self->load_file( $_ ) for reverse @found;
112 return "/etc/" . $self->confname;
117 return unless -f $self->global_file;
118 return $self->load_file( $self->global_file );
124 File::Spec->catfile( $ENV{'HOME'}, "." . $self->confname );
129 return unless -f $self->user_file;
130 return $self->load_file( $self->user_file );
133 # returns undef if the file was unable to be opened
136 my $filename = shift;
138 open(my $fh, '<', $filename) or return;
140 my $c = do {local $/; <$fh>};
142 $c =~ s/\n*$/\n/; # Ensure it ends with a newline
150 $self->data({}) unless $self->is_loaded;
152 return $self->data if grep {$_ eq $filename} @{$self->config_files};
154 my $c = $self->_read_config($filename);
155 $self->parse_content(
158 $self->define(@_, origin => $filename);
161 error_callback( @_, filename => $filename );
165 # note this filename as having been loaded
166 push @{$self->config_files}, $filename;
174 my $offset_of_prev_newline = rindex( $args{content}, "\n", $args{offset} );
175 my $offset_of_next_newline = index( $args{content}, "\n", $args{offset} );
178 $offset_of_prev_newline + 1,
179 $offset_of_next_newline - ($offset_of_prev_newline + 1),
183 my $current_offset = 0;
185 while ($current_offset <= $args{offset}) {
186 # nibble off a line of content
187 $args{content} =~ s/(.*\n)//;
189 $current_offset += length $1;
191 my $position = (length $line) - ($current_offset - ($args{offset} + 1));
192 die "Error parsing $args{filename} at line $line_number, position $position."
193 ."\nBad line was: '$line'\n";
204 my $c = $args{content};
205 return if !$c; # nothing to do if content is empty
206 my $length = length $c;
209 = $self->compatible ? qr/\A\[([0-9a-z.-]+)(?:[\t ]*"([^\n]*?)")?\]/im
210 : qr/\A\[([^\s\[\]"]+)(?:[\t ]*"([^\n]*?)")?\]/im;
213 = $self->compatible ? qr/\A([a-z][0-9a-z-]*)[\t ]*(?:[#;].*)?$/im
214 : qr/\A([^\[=\n][^=\n]*?)[\t ]*(?:[#;].*)?$/im;
217 = $self->compatible ? qr/\A([a-z][0-9a-z-]*)[\t ]*=[\t ]*/im
218 : qr/\A([^\[=\n][^=\n]*?)[\t ]*=[\t ]*/im;
220 my($section, $prev) = (undef, '');
222 # drop leading white space and blank lines
225 my $offset = $length - length($c);
226 # drop to end of line on comments
227 if ($c =~ s/\A[#;].*?$//im) {
230 # [sub]section headers of the format [section "subsection"] (with
231 # unlimited whitespace between) or [section.subsection] variable
232 # definitions may directly follow the section header, on the same line!
233 # - rules for sections: not case sensitive, only alphanumeric
234 # characters, -, and . allowed
235 # - rules for subsections enclosed in ""s: case sensitive, can
236 # contain any character except newline, " and \ must be escaped
237 # - rules for subsections with section.subsection alternate syntax:
238 # same rules as for sections
239 elsif ($c =~ s/$section_regex//) {
244 $check =~ s{\\\\}{}g;
246 return $args{error}->(
247 content => $args{content},
250 # don't allow quoted subsections to contain unescaped
251 # double-quotes or backslashes
252 ) if $check =~ /\\|"/;
254 $subsection =~ s{\\\\}{\\}g;
255 $subsection =~ s{\\"}{"}g;
256 $section .= ".$subsection";
262 length => ($length - length($c)) - $offset,
265 # keys followed by a unlimited whitespace and (optionally) a comment
268 # for keys, we allow any characters that won't screw up the parsing
269 # (= and newline) in non-compatible mode, and match non-greedily to
270 # allow any trailing whitespace to be dropped
272 # in compatible mode, keys can contain only 0-9a-z-
273 elsif ($c =~ s/$key_regex//) {
278 length => ($length - length($c)) - $offset,
281 # key/value pairs (this particular regex matches only the key part and
282 # the =, with unlimited whitespace around the =)
283 elsif ($c =~ s/$key_value_regex//) {
288 # comment or no content left on line
289 if ($c =~ s/\A([ \t]*[#;].*?)?$//im) {
292 # any amount of whitespace between words becomes a single space
293 elsif ($c =~ s/\A[\t ]+//im) {
296 # line continuation (\ character followed by new line)
297 elsif ($c =~ s/\A\\\r?\n//im) {
300 # escaped backslash characters is translated to actual \
301 elsif ($c =~ s/\A\\\\//im) {
304 # escaped quote characters are part of the value
305 elsif ($c =~ s/\A\\(['"])//im) {
308 # escaped newline in config is translated to actual newline
309 elsif ($c =~ s/\A\\n//im) {
312 # escaped tab in config is translated to actual tab
313 elsif ($c =~ s/\A\\t//im) {
316 # escaped backspace in config is translated to actual backspace
317 elsif ($c =~ s/\A\\b//im) {
320 # quote-delimited value (possibly containing escape codes)
321 elsif ($c =~ s/\A"([^"\\]*(?:(?:\\\n|\\[tbn"\\])[^"\\]*)*)"//im) {
323 # remove all continuations (\ followed by a newline)
325 # swap escaped newlines with actual newlines
327 # swap escaped tabs with actual tabs
329 # swap escaped backspaces with actual backspaces
331 # swap escaped \ with actual \
335 # valid value (no escape codes)
336 elsif ($c =~ s/\A([^\t \\\n]+)//im) {
341 # Note that $args{content} is the _original_
342 # content, not the nibbled $c, which is the
343 # remaining unparsed content
344 return $args{error}->(
345 content => $args{content},
355 length => ($length - length($c)) - $offset,
358 # end of content string; all done now
359 elsif (not length $c) {
364 # Note that $args{content} is the _original_ content, not
365 # the nibbled $c, which is the remaining unparsed content
366 return $args{error}->(
367 content => $args{content},
383 return unless defined $args{name};
384 $args{name} = lc $args{name};
385 my $key = join(".", grep {defined} @args{qw/section name/});
387 # we're either adding a whole new key or adding a multiple key from
389 if ( !defined $self->origins->{$key}
390 || $self->origins->{$key} eq $args{origin} ) {
391 if ($self->is_multiple($key)) {
392 push @{$self->data->{$key} ||= []}, $args{value};
394 elsif (exists $self->data->{$key}) {
395 $self->set_multiple($key);
396 $self->data->{$key} = [$self->data->{$key}, $args{value}];
399 $self->data->{$key} = $args{value};
402 # we're overriding a key set previously from a different file
404 # un-mark as multiple if it was previously marked as such
405 $self->set_multiple( $key, 0 ) if $self->is_multiple( $key );
408 $self->data->{$key} = $args{value};
410 $self->origins->{$key} = $args{origin};
417 as => undef, # bool, int, or num
418 human => undef, # true value / false value
423 BOOL_TRUE_REGEX => qr/^(?:true|yes|on|-?0*1)$/i,
424 BOOL_FALSE_REGEX => qr/^(?:false|no|off|0*)$/i,
425 NUM_REGEX => qr/^-?[0-9]*\.?[0-9]*[kmg]?$/,
428 if (defined $args{as} && $args{as} eq 'bool-or-int') {
429 if ( $args{value} =~ NUM_REGEX ) {
432 elsif ( $args{value} =~ BOOL_TRUE_REGEX ||
433 $args{value} =~ BOOL_FALSE_REGEX ) {
436 elsif ( !defined $args{value} ) {
440 die "Invalid bool-or-int '$args{value}'\n";
444 my $v = $args{value};
445 return $v unless defined $args{as};
446 if ($args{as} =~ /bool/i) {
447 return 1 unless defined $v;
448 if ( $v =~ BOOL_TRUE_REGEX ) {
449 if ( $args{human} ) {
456 elsif ($v =~ BOOL_FALSE_REGEX ) {
457 if ( $args{human} ) {
465 die "Invalid bool '$args{value}'\n";
468 elsif ($args{as} =~ /int|num/) {
469 die "Invalid unit while casting to $args{as}\n"
470 unless $v =~ NUM_REGEX;
472 if ($v =~ s/([kmg])$//) {
473 $v *= 1024 if $1 eq "k";
474 $v *= 1024*1024 if $1 eq "m";
475 $v *= 1024*1024*1024 if $1 eq "g";
478 return $args{as} eq 'int' ? int $v : $v + 0;
491 $self->load unless $self->is_loaded;
493 my ($section, $subsection, $name) = _split_key($args{key});
494 $args{key} = join( '.',
495 grep { defined } (lc $section, $subsection, lc $name),
498 return undef unless exists $self->data->{$args{key}};
499 my $v = $self->data->{$args{key}};
502 if (defined $args{filter}) {
503 if ($args{filter} =~ s/^!//) {
504 @results = grep { !/$args{filter}/i } @{$v};
507 @results = grep { m/$args{filter}/i } @{$v};
510 die "Multiple values" unless @results <= 1;
513 return $self->cast( value => $v, as => $args{as},
514 human => $args{human} );
517 # I'm pretty sure that someone can come up with an edge case where stripping
518 # all balanced quotes like this is not the right thing to do, but I don't
519 # see it actually being a problem in practice.
520 sub _remove_balanced_quotes {
523 no warnings 'uninitialized';
524 $key = join '', map { s/"(.*)"/$1/; $_ } split /("[^"]+"|[^.]+)/, $key;
525 $key = join '', map { s/'(.*)'/$1/; $_ } split /('[^']+'|[^.]+)/, $key;
537 $self->load unless $self->is_loaded;
538 my ($section, $subsection, $name) = _split_key($args{key});
539 $args{key} = join('.',
540 grep { defined } (lc $section, $subsection, lc $name),
543 return undef unless exists $self->data->{$args{key}};
544 my $v = $self->data->{$args{key}};
545 my @v = ref $v ? @{$v} : ($v);
547 if (defined $args{filter}) {
548 if ($args{filter} =~ s/^!//) {
549 @v = grep { !/$args{filter}/i } @v;
552 @v = grep { m/$args{filter}/i } @v;
556 @v = map {$self->cast( value => $_, as => $args{as} )} @v;
557 return wantarray ? @v : \@v;
570 $self->load unless $self->is_loaded;
572 $args{key} = lc $args{key};
575 for my $key (keys %{$self->data}) {
576 $results{$key} = $self->data->{$key} if lc $key =~ m/$args{key}/i;
579 if (defined $args{filter}) {
580 if ($args{filter} =~ s/^!//) {
581 map { delete $results{$_} if $results{$_} =~ m/$args{filter}/i }
585 map { delete $results{$_} if $results{$_} !~ m/$args{filter}/i }
590 @results{keys %results} =
592 value => $results{$_},
595 return wantarray ? %results : \%results;
601 return %{$self->data} if wantarray;
604 for my $key (sort keys %{$self->data}) {
606 if (defined $self->data->{$key}) {
608 if ( $self->is_multiple($key) ) {
610 $str .= join(', ', @{$self->data->{$key}});
614 $str .= $self->data->{$key}."\n";
620 if (!defined wantarray) {
628 return $data if defined wantarray;
640 if ($args{section} =~ /^(.*?)\.(.*)$/) {
641 my ($section, $subsection) = ($1, $2);
642 my $ret = qq|[$section "$subsection"]|;
643 $ret .= "\n" unless $args{bare};
647 my $ret = qq|[$args{section}]|;
648 $ret .= "\n" unless $args{bare};
653 sub format_definition {
661 my $quote = $args{value} =~ /(^\s|;|#|\s$)/ ? '"' : '';
662 $args{value} =~ s/\\/\\\\/g;
663 $args{value} =~ s/"/\\"/g;
664 $args{value} =~ s/\t/\\t/g;
665 $args{value} =~ s/\n/\\n/g;
666 my $ret = "$args{key} = $quote$args{value}$quote";
667 $ret = "\t$ret\n" unless $args{bare};
671 # Given a key, return its variable name, section, and subsection
672 # parts. Doesn't do any lowercase transformation.
676 my ($name, $section, $subsection);
677 # allow quoting of the key to, for example, preserve
678 # . characters in the key
679 if ( $key =~ s/\.["'](.*)["']$// ) {
684 $key =~ /^(?:(.*)\.)?(.*)$/;
685 # If we wanted, we could interpret quoting of the section name to
686 # allow for setting keys with section names including . characters.
687 # But git-config doesn't do that, so we won't bother for now. (Right
688 # now it will read these section names correctly but won't set them.)
689 ($section, $name) = map { _remove_balanced_quotes($_) }
690 grep { defined $_ } ($1, $2);
693 # Make sure the section name we're comparing against has
694 # case-insensitive section names and case-sensitive subsection names.
695 if (defined $section) {
696 $section =~ m/^([^.]+)(?:\.(.*))?$/;
697 ($section, $subsection) = ($1, $2);
700 ($section, $subsection) = (undef) x 2;
702 return ($section, $subsection, $name);
707 my ($filename, $args_ref) = @_;
709 my $c = $self->_read_config($filename); # undef if file doesn't exist
711 # loop through each value to set, modifying the content to be written
712 # or erroring out as we go
713 for my $args_hash (@{$args_ref}) {
714 my %args = %{$args_hash};
716 my ($section, $subsection, $name) = _split_key($args{key});
718 grep { defined } (lc $section, $subsection, lc $name),
721 $args{multiple} = $self->is_multiple($key)
722 unless defined $args{multiple};
724 die "No section given in key or invalid key $args{key}\n"
725 unless defined $section;
727 die "Invalid variable name $name\n"
728 if $self->_invalid_variable_name($name);
730 die "Invalid section name $section\n"
731 if $self->_invalid_section_name($section);
733 # if the subsection to write contains unescaped \ or ", escape them
735 my $unescaped_subsection;
736 if ( defined $subsection ) {
737 $unescaped_subsection = $subsection;
738 $subsection =~ s{\\}{\\\\}g;
739 $subsection =~ s{"}{\\"}g;
742 $args{value} = $self->cast(
743 value => $args{value},
746 ) if defined $args{value} && defined $args{as};
751 # use this for comparison
753 defined $unescaped_subsection
754 ? join( '.', lc $section, $unescaped_subsection )
756 # ...but this for writing (don't lowercase)
758 = defined $subsection ? join('.', $section, $subsection)
761 # There's not really a good, simple way to get around parsing the
762 # content for each of the values we're setting. If we wanted to
763 # extract the offsets for every single one using only a single parse
764 # run, we'd end up having to munge all the offsets afterwards as we
765 # did the actual replacement since every time we did a replacement it
766 # would change the offsets for anything that was formerly to be added
767 # at a later offset. Which I'm not sure is any better than just
769 $self->parse_content(
773 return unless $got{section} eq $cmp_section;
774 $new = $got{offset} + $got{length};
775 return unless defined $got{name};
778 # variable names are case-insensitive
779 if (lc $name eq $got{name}) {
780 if (defined $args{filter}) {
781 # copy the filter arg here since this callback may
782 # be called multiple times and we don't want to
783 # modify the original value
784 my $filter = $args{filter};
785 if ($filter =~ s/^!//) {
786 $matched = 1 if ($got{value} !~ m/$filter/i);
788 elsif ($got{value} =~ m/$filter/i) {
797 push @replace, {offset => $got{offset}, length => $got{length}}
801 error_callback(@_, filename => $args{filename})
805 die "Multiple occurrences of non-multiple key?"
806 if @replace > 1 && !$args{multiple};
808 # We're only replacing the first occurrance unless they said
809 # to replace them all.
810 @replace = ($replace[0]) if @replace and $args{value} and not $args{replace_all};
812 if (defined $args{value}) {
814 && (!$args{multiple} || $args{filter} || $args{replace_all})) {
815 # Replacing existing value(s)
817 # if the string we're replacing with is not the same length as
818 # what's being replaced, any offsets following will be wrong.
819 # save the difference between the lengths here and add it to
820 # any offsets that follow.
823 # when replacing multiple values, we combine them all into one,
824 # which is kept at the position of the last one
825 my $last = pop @replace;
827 # kill all values that are not last
828 ($c, $difference) = _unset_variables(\@replace, $c,
831 # substitute the last occurrence with the new value
834 $last->{offset}-$difference,
836 $self->format_definition(
838 value => $args{value},
843 elsif (defined $new) {
844 # Adding a new value to the end of an existing block
847 index($c, "\n", $new)+1,
849 $self->format_definition(
851 value => $args{value}
856 # Adding a new section
857 $c .= $self->format_section( section => $combined_section );
858 $c .= $self->format_definition(
860 value => $args{value},
865 # Removing an existing value (unset / unset-all)
866 die "No occurrence of $args{key} found to unset in $filename\n"
869 ($c, undef) = _unset_variables(\@replace, $c, 0);
872 return $self->_write_config( $filename, $c );
887 my $filename = $args{filename};
888 delete $args{filename};
890 return $self->group_set( $filename, [ \%args ] );
893 sub _unset_variables {
894 my ($variables, $c, $difference) = @_;
896 for my $var (@{$variables}) {
897 # start from either the last newline or the last section
898 # close bracket, since variable definitions can occur
899 # immediately following a section header without a \n
900 my $newline = rindex($c, "\n", $var->{offset}-$difference);
901 # need to add 1 here to not kill the ] too
902 my $bracket = rindex($c, ']', $var->{offset}-$difference) + 1;
903 my $start = $newline > $bracket ? $newline : $bracket;
906 index($c, "\n", $var->{offset}-$difference+$var->{length})-$start;
914 $difference += $length;
917 return ($c, $difference);
920 # In non-git-compatible mode, variables names can contain any characters that
921 # aren't newlines or = characters, but cannot start or end with whitespace.
923 # Allowing . characters in variable names actually makes it so you
924 # can get collisions between identifiers for things that are not
927 # For example, you could have a collision like this:
928 # [section "foo"] bar.com = 1
929 # [section] foo.bar.com = 1
931 # Both of these would be turned into 'section.foo.bar.com'. But it's
932 # unlikely to ever actually come up, since you'd have to have
933 # a *need* to have two things like this that are very similar
935 sub _invalid_variable_name {
936 my ($self, $name) = @_;
938 if ($self->compatible) {
939 return $name !~ /^[a-z][0-9a-z-]*$/i;
942 return $name !~ /^[^=\n\[][^=\n]*$/ || $name =~ /(?:^[ \t]+|[ \t+]$)/;
946 # section, NOT subsection!
947 sub _invalid_section_name {
948 my ($self, $section) = @_;
950 if ($self->compatible) {
951 return $section !~ /^[0-9a-z-.]+$/i;
954 return $section =~ /\s|\[|\]|"/;
958 # write config with locking
961 my($filename, $content) = @_;
963 # allow nested symlinks but only within reason
967 while ($max_depth--) {
968 my $readlink = readlink $filename;
969 $filename = $readlink if defined $readlink;
972 # write new config file to temp file
973 # (the only reason we call it .lock is because that's the
975 sysopen(my $fh, "${filename}.lock", O_CREAT|O_EXCL|O_WRONLY)
976 or die "Can't open ${filename}.lock for writing: $!\n";
981 rename("${filename}.lock", ${filename})
982 or die "Can't rename ${filename}.lock to ${filename}: $!\n";
995 die "No section to rename from given\n" unless defined $args{from};
997 my $c = $self->_read_config($args{filename});
998 # file couldn't be opened = nothing to rename
999 return if !defined($c);
1001 ($args{from}, $args{to}) = map { _remove_balanced_quotes($_) }
1002 grep { defined $_ } ($args{from}, $args{to});
1005 my $prev_matched = 0;
1006 $self->parse_content(
1011 $replace[-1]->{section_is_last} = 0
1012 if (@replace && !defined($got{name}));
1014 if (lc($got{section}) eq lc($args{from})) {
1015 if (defined $got{name}) {
1016 # if we're removing rather than replacing and
1017 # there was a previous section match, increase
1018 # its length so it will kill this variable
1020 if ($prev_matched && !defined $args{to} ) {
1021 $replace[-1]->{length} += ($got{offset} + $got{length})
1022 - ($replace[-1]{offset} + $replace[-1]->{length});
1026 # if we're removing rather than replacing, increase
1027 # the length of the previous match so when it's
1028 # replaced it will kill all the way up to the
1029 # beginning of this next section (this will kill
1030 # any leading whitespace on the line of the
1031 # next section, but that's OK)
1032 $replace[-1]->{length} += $got{offset} -
1033 ($replace[-1]->{offset} + $replace[-1]->{length})
1034 if @replace && $prev_matched && !defined($args{to});
1036 push @replace, {offset => $got{offset}, length =>
1037 $got{length}, section_is_last => 1};
1042 # if we're removing rather than replacing and there was
1043 # a previous section match, increase its length to kill all
1044 # the way up to this non-matching section (takes care
1045 # of newlines between here and there, etc.)
1046 $replace[-1]->{length} += $got{offset} -
1047 ($replace[-1]->{offset} + $replace[-1]->{length})
1048 if @replace && $prev_matched && !defined($args{to});
1053 error_callback( @_, filename => $args{filename} );
1056 die "No such section '$args{from}'\n"
1059 # if the string we're replacing with is not the same length as what's
1060 # being replaced, any offsets following will be wrong. save the difference
1061 # between the lengths here and add it to any offsets that follow.
1064 # rename ALL section headers that matched to
1065 # (there may be more than one)
1066 my $replace_with = defined $args{to} ?
1067 $self->format_section( section => $args{to}, bare => 1 ) : '';
1069 for my $header (@replace) {
1072 $header->{offset} + $difference,
1073 # if we're removing the last section, just kill all the way to the
1075 !defined($args{to}) && $header->{section_is_last} ? length($c) -
1076 ($header->{offset} + $difference) : $header->{length},
1079 $difference += (length($replace_with) - $header->{length});
1082 return $self->_write_config($args{filename}, $c);
1085 sub remove_section {
1094 die "No section given to remove\n" unless $args{section};
1096 # remove section is just a rename to nothing
1097 return $self->rename_section( from => $args{section}, filename =>
1107 Config::GitLike - git-compatible config file parsing
1111 This module parses git-style config files, which look like this:
1114 repositoryformatversion = 0
1117 logallrefupdates = true
1119 url = spang.cc:/srv/git/home.git
1120 fetch = +refs/heads/*:refs/remotes/origin/*
1121 [another-section "subsection"]
1123 key = multiple values are OK
1127 Code that uses this config module might look like:
1129 use Config::GitLike;
1131 my $c = Config::GitLike->new(confname => 'config');
1134 $c->get( key => 'section.name' );
1135 # make the return value a Perl true/false value
1136 $c->get( key => 'core.filemode', as => 'bool' );
1138 # replace the old value
1140 key => 'section.name',
1142 filename => '/home/user/.config',
1145 # make this key have multiple values rather than replacing the
1148 key => 'section.name',
1150 filename => '/home/user/.config',
1154 # replace all occurrences of the old value for section.name with a new one
1156 key => 'section.name',
1158 filename => '/home/user/.config',
1163 # make sure to reload the config files before reading if you've set
1167 # get only the value of 'section.name' that matches '2'
1168 $c->get( key => 'section.name', filter => '2' );
1169 $c->get_all( key => 'section.name' );
1170 # prefixing a search regexp with a ! negates it
1171 $c->get_regexp( key => '!na' );
1175 to => 'new-section',
1176 filename => '/home/user/.config'
1180 section => 'section',
1181 filename => '/home/user/.config'
1184 # unsets all instances of the given key
1185 $c->set( key => 'section.name', filename => '/home/user/.config' );
1187 my %config_vals = $config->dump;
1188 # string representation of config data
1189 my $str = $config->dump;
1190 # prints rather than returning
1195 This module handles interaction with configuration files of the style used
1196 by the version control system Git. It can both parse and modify these
1197 files, as well as create entirely new ones.
1199 You only need to know a few things about the configuration format in order
1200 to use this module. First, a configuration file is made up of key/value
1201 pairs. Every key must be contained in a section. Sections can have
1202 subsections, but they don't have to. For the purposes of setting and
1203 getting configuration variables, we join the section name,
1204 subsection name, and variable name together with dots to get a key
1205 name that looks like "section.subsection.variable". These are the
1206 strings that you'll be passing in to C<key> arguments.
1208 Configuration files inherit from each other. By default, C<Config::GitLike>
1209 loads data from a system-wide configuration file, a per-user
1210 configuration file, and a per-directory configuration file, but by
1211 subclassing and overriding methods you can obtain any combination of
1212 configuration files. By default, configuration files that don't
1213 exist are just skipped.
1216 L<http://www.kernel.org/pub/software/scm/git/docs/git-config.html#_configuration_file>
1217 for details on the syntax of git configuration files. We won't waste pixels
1218 on the nitty gritty here.
1220 While the behaviour of a couple of this module's methods differ slightly
1221 from the C<git config> equivalents, this module can read any config file
1222 written by git. The converse is usually true, but only if you don't take
1223 advantage of this module's increased permissiveness when it comes to key
1224 names. (See L<DIFFERENCES FROM GIT-CONFIG> for details.)
1226 This is an object-oriented module using L<Any::Moose|Any::Moose>. All
1227 subroutines are object method calls.
1229 A few methods have parameters that are always used for the same purpose:
1233 All methods that change things in a configuration file require a filename to
1234 write to, via the C<filename> parameter. Since a C<Config::GitLike> object can
1235 be working with multiple config files that inherit from each other, we don't
1236 try to figure out which one to write to automatically and let you specify
1241 All get and set methods can make sure the values they're returning or
1242 setting are valid values of a certain type: C<bool>, C<int>,
1243 C<num>, or C<bool-or-int> (or at least as close as Perl can get
1244 to having these types). Do this by passing one of these types
1245 in via the C<as> parameter. The set method, if told to write
1246 bools, will always write "true" or "false" (not anything else that
1247 C<cast> considers a valid bool).
1249 Methods that are told to cast values will throw exceptions if
1250 the values they're trying to cast aren't valid values of the
1253 See the L<"cast"> method documentation for more on what is considered valid
1258 All get and set methods can filter what values they return via their
1259 C<filter> parameter, which is expected to be a string that is a valid
1260 regex. If you want to filter items OUT instead of IN, you can
1261 prefix your regex with a ! and that'll do the trick.
1263 Now, on the the methods!
1267 There are the methods you're likely to use the most.
1269 =head2 new( confname => 'config' )
1271 Create a new configuration object with the base config name C<confname>.
1273 C<confname> is used to construct the filenames that will be loaded; by
1274 default, these are C</etc/confname> (global configuration file),
1275 C<~/.confname> (user configuration file), and C<<Cwd>/.confname> (directory
1276 configuration file).
1278 You can override these defaults by subclassing C<Config::GitLike> and
1279 overriding the methods C<global_file>, C<user_file>, and C<dir_file>. (See
1280 L<"METHODS YOU MAY WISH TO OVERRIDE"> for details.)
1282 If you wish to enforce only being able to read/write config files that
1283 git can read or write, pass in C<compatible =E<gt> 1> to this
1284 constructor. The default rules for some components of the config
1285 file are more permissive than git's (see L<"DIFFERENCES FROM GIT-CONFIG">).
1289 The configuration filename that you passed in when you created
1290 the C<Config::GitLike> object. You can change it if you want by
1291 passing in a new name (and then reloading via L<"load">).
1295 Load the global, local, and directory configuration file with the filename
1296 C<confname>(if they exist). Configuration variables loaded later
1297 override those loaded earlier, so variables from the directory
1298 configuration file have the highest precedence.
1300 Pass in an optional path, and it will be passed on to L<"load_dirs"> (which
1301 loads the directory configuration file(s)).
1303 Returns a hash copy of all loaded configuration data stored in the module
1304 after the files have been loaded, or a hashref to this hash in
1307 =head2 config_filenames
1309 An array reference containing the absolute filenames of all config files
1310 that are currently loaded, in the order they were loaded.
1316 key => 'sect.subsect.key'
1320 Return the config value associated with C<key> cast as an C<as>.
1322 The C<key> option is required (will return undef if unspecified); the C<as>
1323 option is not (will return a string by default). Sections and subsections
1324 are specified in the key by separating them from the key name with a .
1325 character. Sections, subsections, and keys may all be quoted (double or
1328 If C<key> doesn't exist in the config, undef is returned. Dies with
1329 the exception "Multiple values" if the given key has more than one
1330 value associated with it. (Use L<"get_all"> to retrieve multiple values.)
1332 Calls L<"load"> if it hasn't been done already. Note that if you've run any
1333 C<set> calls to the loaded configuration files since the last time they were
1334 loaded, you MUST call L<"load"> again before getting, or the returned
1335 configuration data may not match the configuration variables on-disk.
1341 key => 'section.sub'
1345 Like L<"get"> but does not fail if the number of values for the key is not
1348 Returns a list of values (or an arrayref in scalar context).
1358 Similar to L<"get_all"> but searches for values based on a key regex.
1360 Returns a hash of name/value pairs (or a hashref in scalar context).
1364 In scalar context, return a string containing all configuration data, sorted in
1365 ASCII order, in the form:
1370 If called in void context, this string is printed instead.
1372 In list context, returns a hash containing all the configuration data.
1378 key => 'section.name'
1380 filename => File::Spec->catfile(qw/home user/, '.'.$config->confname)
1386 Set the key C<foo> in the configuration section C<section> to the value C<bar>
1387 in the given filename.
1389 Replace C<key>'s value if C<key> already exists.
1391 To unset a key, pass in C<key> but not C<value>.
1393 Returns true on success.
1395 If you need to have a . character in your variable name, you can surround the
1396 name with quotes (single or double): C<key => 'section."foo.bar.com"'>
1397 Don't do this unless you really have to.
1399 =head3 multiple values
1401 By default, set will replace the old value rather than giving a key multiple
1402 values. To override this, pass in C<multiple =E<gt> 1>. If you want to replace
1403 all instances of a multiple-valued key with a new value, you need to pass
1404 in C<replace_all =E<gt> 1> as well.
1410 filename => '/home/foo/.bar'
1413 Same as L<"set">, but set a group of variables at the same time without
1414 writing to disk separately for each.
1416 C<args_ref> is an array reference containing a list of hash references which
1417 are essentially hashes of arguments to C<set>, excluding the C<filename>
1418 argument since that is specified separately and the same file is used for all
1419 variables to be set at once.
1421 =head2 rename_section
1425 from => 'name.subname'
1427 filename => '/file/to/edit'
1429 Rename the section existing in C<filename> given by C<from> to the section
1432 Throws an exception C<No such section> if the section in C<from> doesn't exist
1435 If no value is given for C<to>, the section is removed instead of renamed.
1437 Returns true on success, false if C<filename> didn't exist and thus
1438 the rename did nothing.
1440 =head2 remove_section
1444 section => 'section.subsection'
1445 filename => '/file/to/edit'
1447 Just a convenience wrapper around L<"rename_section"> for readability's sake.
1448 Removes the given section (which you can do by renaming to nothing as well).
1450 =head2 cascade( $bool )
1452 Gets or sets if only the B<deepest> configuration file in a directory
1453 tree is loaded, or if all of them are loaded, shallowest to deepest.
1454 Alternately, C<cascade =E<gt> 1> can be passed to C<new>.
1456 =head1 METHODS YOU MAY WISH TO OVERRIDE
1458 If your application's configuration layout is different from the default, e.g.
1459 if its home directory config files are in a directory within the home
1460 directory (like C<~/.git/config>) instead of just dot-prefixed, override these
1461 methods to return the right directory names. For fancier things like altering
1462 precedence, you'll need to override L<"load"> as well.
1466 Return a string containing the path to a configuration file with the
1467 name C<confname> in a directory. The directory isn't specified here.
1471 Return the string C</etc/confname>, the absolute name of the system-wide
1472 configuration file with name C<confname>.
1476 Return a string containing the path to a configuration file
1477 in the current user's home directory with filename C<confname>.
1485 Load the configuration file with the filename L<"dir_file"> in the current
1486 working directory into the memory or, if there is no config matching
1487 C<dir_file> in the current working directory, walk up the directory tree until
1488 one is found. (No error is thrown if none is found.) If an optional path
1489 is passed in, that directory will be used as the base directory instead
1490 of the working directory.
1492 You'll want to use L<"load_file"> to load config files from your overridden
1493 version of this subroutine.
1495 Returns nothing of note.
1497 =head1 OTHER METHODS
1499 These are mostly used internally in other methods, but could be useful anyway.
1503 If a global configuration file with the absolute name given by
1504 L<"global_file"> exists, load its configuration variables into memory.
1506 Returns the current contents of all the loaded configuration variables
1507 after the file has been loaded, or undef if no global config file is found.
1511 If a configuration file with the absolute name given by
1512 L<"user_file"> exists, load its config variables into memory.
1514 Returns the current contents of all the loaded configuration variables
1515 after the file has been loaded, or undef if no user config file is found.
1517 =head2 load_file( $filename )
1519 Takes a string containing the path to a file, opens it if it exists, loads its
1520 config variables into memory, and returns the currently loaded config
1521 variables (a hashref).
1523 Note that you ought to only call this subroutine with an argument that you
1524 know exists, otherwise config files that don't exist will be recorded as
1527 =head2 parse_content
1535 Parses the given content and runs callbacks as it finds valid information.
1537 Returns undef on success and C<error($content)> (the original content) on
1540 C<callback> is called like:
1542 callback(section => $str, offset => $num, length => $num, name => $str, value => $str)
1544 C<name> and C<value> may be omitted if the callback is not being called on a
1545 key/value pair, or if it is being called on a key with no value.
1547 C<error> is called like:
1549 error( content => $content, offset => $offset )
1551 Where C<offset> is the point in the content where the parse error occurred.
1553 If you need to use this method, you might be interested in L<"error_callback">
1556 =head2 error_callback
1562 filename => '/foo/bar/.baz'
1564 Made especially for passing to L<"parse_content">, passed through the
1565 C<error> parameter like this:
1568 error_callback( @_, filename => '/file/you/were/parsing' )
1571 It's used internally wherever L<"parse_content"> is used and will throw
1572 an exception with a useful message detailing the line number, position on
1573 the line, and contents of the bad line; if you find the need to use
1574 L<"parse_content"> elsewhere, you may find it useful as well.
1576 =head2 set_multiple( $name )
1578 Mark the key string C<$name> as containing multiple values.
1582 =head2 is_multiple( $name )
1584 Return a true value if the key string C<$name> contains multiple values; false
1595 Given a section, a key name, and a value¸ store this information
1596 in memory in the config object.
1598 Returns the value that was just defined on success, or undef
1599 if no name is given and thus the key cannot be defined.
1609 Return C<value> cast into the type specified by C<as>.
1611 Valid values for C<as> are C<bool>, C<int>, C<num>, or C<bool-or-num>. For
1612 C<bool>, C<true>, C<yes>, C<on>, C<1>, and undef are translated into a true
1613 value (for Perl); anything else is false. Specifying a true value for the
1614 C<human> arg will get you a human-readable 'true' or 'false' rather than a
1615 value that plays along with Perl's definition of truthiness (0 or 1).
1617 For C<int>s and C<num>s, if C<value> ends in C<k>, C<m>, or C<g>, it will be
1618 multiplied by 1024, 1048576, and 1073741824, respectively, before being
1619 returned. C<int>s are truncated after being multiplied, if they have
1622 C<bool-or-int>, as you might have guessed, gives you either
1623 a bool or an int depending on which one applies.
1625 If C<as> is unspecified, C<value> is returned unchanged.
1627 =head2 format_section
1631 section => 'section.subsection'
1634 Return a string containing the section/subsection header, formatted
1635 as it should appear in a config file. If C<bare> is true, the returned
1636 value is not followed be a newline.
1638 =head2 format_definition
1646 Return a string containing the key/value pair as they should be printed in the
1647 config file. If C<bare> is true, the returned value is not tab-indented nor
1648 followed by a newline.
1650 =head1 DIFFERENCES FROM GIT-CONFIG
1652 This module does the following things differently from git-config:
1654 We are much more permissive about valid key names and section names.
1655 For variables, instead of limiting variable names to alphanumeric characters
1656 and -, we allow any characters except for = and newlines, including spaces as
1657 long as they are not leading or trailing, and . as long as the key name is
1658 quoted. For sections, any characters but whitespace, [], and " are allowed.
1659 You can enforce reading/writing only git-compatible variable names and section
1660 headers by passing C<compatible =E<gt> 1> to the constructor.
1662 When replacing variable values and renaming sections, we merely use
1663 a substring replacement rather than writing out new lines formatted in the
1664 default manner for new lines. Git's replacement/renaming (as of
1665 1.6.3.2) is currently buggy and loses trailing comments and variables
1666 that are defined on the same line as a section being renamed. Our
1667 method preserves original formatting and surrounding information.
1669 We also allow the 'num' type for casting, since in many cases we
1670 might want to be more lenient on numbers.
1672 We truncate decimal numbers that are cast to C<int>s, whereas
1673 Git just rejects them.
1675 We don't support NUL-terminating output (the --null flag to
1676 git-config). Who needs it?
1680 If you find any bugs in this module, report them at:
1684 Include the version of the module you're using and any relevant problematic
1685 configuration files or code snippets.
1689 L<http://www.kernel.org/pub/software/scm/git/docs/git-config.html#_configuration_file>,
1690 L<Config::GitLike::Git>, L<http://syncwith.us/> (C<Config::GitLike> is
1691 used in Prophet/SD and provides a working example)
1695 This program is free software; you may modify and/or redistribute it
1696 under the same terms as Perl itself.
1700 Copyright 2010 Best Practical Solutions, LLC
1704 Alex Vandiver <alexmv@bestpractical.com>,
1705 Christine Spang <spang@bestpractical.com>