######################################################################
Config::Patch 0.07
######################################################################
NAME
Config::Patch - Patch configuration files and unpatch them later
SYNOPSIS
use Config::Patch;
my $patcher = Config::Patch->new(
file => "/etc/syslog.conf",
key => "mypatch",
);
# Append a patch:
$patcher->append(q{
# Log my stuff
my.* /var/log/my
});
# Appends the following to /etc/syslog.conf:
*-------------------------------------------
| ...
| #(Config::Patch-mypatch-append)
| # Log my stuff
| my.* /var/log/my
| #(Config::Patch-mypatch-append)
*-------------------------------------------
# Prepend a patch:
$patcher->prepend(q{
# Log my stuff
my.* /var/log/my
});
# Prepends the following to /etc/syslog.conf:
*-------------------------------------------
| #(Config::Patch-mypatch-append)
| # Log my stuff
| my.* /var/log/my
| #(Config::Patch-mypatch-append)
| ...
*-------------------------------------------
# later on, to remove the patch:
$patcher->remove();
DESCRIPTION
"Config::Patch" helps changing configuration files, remembering the
changes, and undoing them if necessary.
Every change (patch) is marked by a *key*, which must be unique for the
change, in order allow undoing it later on.
To facilitate its usage, "Config::Patch" comes with a command line
script that performs all functions:
# Append a patch
echo "my patch text" | config-patch -a -k key -f textfile
# Patch a file by search-and-replace
echo "none:" | config-patch -s 'all:.*' -k key -f config_file
# Comment out sections matched by a regular expression:
config-patch -c '(?ms-xi:^all:.*?\n\n)' -k key -f config_file
# Remove a previously applied patch
config-patch -r -k key -f textfile
Note that 'patch' doesn't refer to a patch in the format used by the
*patch* program, but to an arbitrary section of text inserted into a
file. Patches are line-based, "Config::Patch" always adds/removes entire
lines.
Specify a different comment character
"Config::Patch" assumes that lines starting with a comment character are
ignored by their applications. This is important, since "Config::Patch"
uses comment lines to hides vital patch information in them for
recovering from patches later on.
By default, this comment character is '#', usable for file formats like
YAML, Makefiles, and Perl. To change this default and use a different
character, specify the comment character like
my $patcher = Config::Patch->new(
comment_char => ";", # comment char is now ";"
# ...
);
in the constructor call. The command line script "config-patch" expects
a different comment character with the "-C" option, check its manpage
for details. Make sure to use the same comment character for patching
and unpatching, otherwise chaos will ensue.
Other than that, "Config::Patch" is format-agnostic. If you need to pay
attention to the syntax of the configuration file to be patched, create
a subclass of "Config::Patch" and put the format specific logic there.
You can only patch a file *once* with a given key. Note that a single
patch might result in multiple patched sections within a file if you're
using the "replace()" or "comment_out()" methods.
To apply different patches to the same file, use different keys. They
can be can rolled back separately.
METHODS
"$patcher = Config::Patch->new(file => $file, key => $key)"
Creates a new patcher object. Optionally, exclusive updates are
ensured by flocking if the "flock" parameter is set to 1:
my $patcher = Config::Patch->new(
file => $file,
key => $key,
flock => 1,
);
"$patcher->append($textstring)"
Appends a text string to the config file.
"$patcher->prepend($textstring)"
Adds a text string to the beginning of the file.
"$patcher->remove()"
Remove a previously applied patch. The patch key has either been
provided with the constructor call previously or can be supplied as
"key => $key".
"$patcher->patched()"
Checks if a patch with the given key was applied to the file
already. The patch key has either been provided with the constructor
call previously or can be supplied as "key => $key".
"$patcher->replace($search, $replace)"
Patches by searching for a given pattern $search (regexp) and
replacing it by the text string $replace. Example:
# Replace the 'all:' target in a Makefile and all
# of its production rules by a dummy rule.
$patcher->replace(qr(^all:.*?\n\n)sm,
"all:\n\techo 'all is gone!'\n");
Note that the replace command will replace *the entire line* if it
finds that a regular expression is matching a partial line.
CAUTION: Make sure your $search patterns only cover the areas you'd
like to replace. Multiple matches within one line are ignored, and
so are matches that overlap with areas patched with different keys
(*forbidden zones*).
"$patcher->comment_out($search)"
Patches by commenting out config lines matching the regular
expression $search. Example:
# Remove the 'all:' target and its production rules
# from a makefile
$patcher->comment_out(qr(^all:.*?\n\n)sm);
Commenting out is just a special case of "replace()". Check its
documentation for details.
"$patcher->key($key)"
Set a new patch key for applying subsequent patches.
"($arrayref, $hashref) = $patcher->patches()"
Examines the file and locates all patches.
It returns two results: $arrayref, a reference to an array, mapping
patch keys to the text of the patched sections:
$arrayref = [ ['key1', 'patchtext1'], ['key2', 'patchtext2'],
['key2', 'patchtext3'] ];
Note that there can be several patched sections appearing under the
same patch key (like the two non-consecutive sections under "key2"
above).
The second result is a reference $hashref to a hash, holding all
patch keys as keys. Its values are the number of patch sections
appearing under a given key.
LIMITATIONS
"Config::Patch" assumes that a hashmark (#) at the beginning of a line
in the configuration file marks a comment.
COPYRIGHT AND LICENSE
Copyright 2005 by Mike Schilli. This library is free software; you can
redistribute it and/or modify it under the same terms as Perl itself.
AUTHOR
2005, Mike Schilli