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)
    *-------------------------------------------

# 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.

The only requirement is that lines starting with a # character are comment lines. 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.

$patcher->append($textstring)

Appends a text string to the config 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 <cpan@perlmeister.com>