NAME
    Module::Build::SysPath - install files to system folders according to
    FHS (or Sys::Path settings)

SYNOPSIS
        use Module::Build::SysPath;
        my $builder = Module::Build::SysPath->new(
            ...

DESCRIPTION
    A subclass of Module::Build using Sys::Path to determine the system
    folders. Help in task of installing files into system folders and
    keeping the option to work in local distribution files while developing
    the module.

    See Acme::SysPath for example usage of a module that needs a
    configuration and a folder to store templates in.

USAGE
  module-starter
        module-starter --builder=Module::Build --module=Acme::NewModule --author="Pod" --email=pod@pod
        cd Acme-NewModule/
        perl -lane 's/Module::Build-/Module::Build::SysPath-/; print $_;' -i Build.PL 
        vim Build.PL
        # s/Module::Build-/Module::Build::SysPath-/
        # add "configure_requires => { 'Module::Build::SysPath' => 0.10 },"
        # add "Module::Build::SysPath' => 0.10," to build_requires

  create SPc.pm
    copy <http://github.com/jozef/Sys-Path/blob/master/examples/SPc.pm> and
    add it to your source tree. Clean up the paths that you don't need.
    Local distribution folder names can be changed to anyones taste. For
    example:

        sub sysconfdir { File::Spec->catdir(__PACKAGE__->prefix, 'conf') };

    'conf' is the name of a folder with "conffile"s. All file put to this
    folder will be installed to Sys::Path->sysconfdir().

  use the SPc.pm
    Calling "Acme::NewModule::SPc->sysconfdir" before the distribution is
    installed will return path to the 'conf' folder in the distribution root
    folder. Calling it after install the distribution will return
    Sys::Path->sysconfdir().

EXAMPLE
    See Acme::SysPath for a really simple, Test::Daily for a real world
    example.

  new
    Populates:

        $builder->{'properties'}->{$path_type.'_files'} = ...;
        $builder->{'properties'}->{'install_path'}->{$path_type} = ...;
        $builder->add_build_element($path_type);

    To install files located in:

            sysconfdir
            datadir
            docdir
            localedir
            webdir
            srvdir

    Folders in:

        cachedir
        logdir
        spooldir
        rundir
        lockdir
        sharedstatedir

    are skipped during the installation. Add .exists to this folders if you
    want them to be created during `./Build install`. The .exists file
    itself is not installed.

    To install a specific file from a skipped folder, a file from a folder
    starting with a dot, or a file starting with a dot, list its path
    relative to the distribution root in the "<path_type>_files" property:

        my $builder = Module::Build::SysPath->new(
            ...
            sharedstatedir_files => {
                'var/lib/acme-notes/index.json' => 1,
            },
            webdir_files => {
                'www/.htaccess' => 1,
            },
        );

    Every "./Build install" overwrites such a file with the distribution
    version, so runtime changes to it are lost. To keep them, also list the
    file in "conffiles", or create the file at runtime instead of shipping
    it.

   MANIFEST
    When the distribution root contains a MANIFEST, only files listed in it
    are installed. "perl Build.PL" warns about every other file it would
    have installed:

        'etc/acme/secret.pem' is not listed in MANIFEST and will not be installed

    Files matching MANIFEST.SKIP (or the default skip list of
    ExtUtils::Manifest when there is no MANIFEST.SKIP) are left out on
    purpose, so they are not installed and not reported.

    Files kept out of the tarball by MANIFEST.SKIP are not installed from a
    checkout either. If a checkout install must deploy such files, for
    example keys that should not be published, copy them in a custom
    "ACTION_install" or deploy them outside the build.

    This keeps editor backups and other stray files in a checkout from being
    installed, and makes an install from a checkout match an install from
    the distribution tarball. Without a MANIFEST, every file found is
    installed.

    Rerun "perl Build.PL" after adding files. The file list is collected
    from the folders on disk when "perl Build.PL" runs, not when "./Build
    install" runs.

   Configuration files
    Configuration files get a special (Debian like) treatment. All files in
    "sysconfdir" and all files specified as
    "$builder->{'properties'}->{'conffiles'}" are configuration files. Using
    "install_checksums" in Sys::Path the c<conffile>s checksums are tracked.
    Here are the model situations:

    "conffile" was never installed jet
        The file is just copied in place (to sysconfdir) as it is. MD5 is
        recorded.

    distribution ships new version, no change in system
        The distribution changed the "conffile" (for example by adding new
        values), but the "conffile" was untouched in the system. Then the
        new version from distribution replaces the one in the system.

    distribution "conffile" wasn't changed, "conffile" changed in system
        Already installed distribution is getting upgrade. Distribution
        "conffile"s form installed and the new version didn't change. But
        the "conffile" was changed in the system. No prompt and the
        "conffile" is kept intact.

    distribution "conffile" change, "conffile" changed in system
        Already installed distribution is getting upgrade. When both the
        distribution changed the "conffile" and the "conffile" was changed
        in the system. User will be prompted what to do:

            Installing new version of config file /etc/SOMEFILE ...
    
            Configuration file `/etc/SOMEFILE'
             ==> Modified (by you or by a script) since installation.
             ==> Package distributor has shipped an updated version.
               What would you like to do about it ?  Your options are:
                Y or I  : install the package maintainer's version
                N or O  : keep your currently-installed version
                  D     : show the differences between the versions
                  Z     : background this process to examine the situation
             The default action is to keep your current version.
    
            *** /etc/SOMEFILE (Y/I/N/O/D/Z) ?

        If N or O is selected distribution files is installed with -spc
        suffix. If Y or I is selected the system "conffile" is renamed by
        adding suffix -old and distribution "conffile" is installed.
        Installation aborts without changing either file if the -old backup
        already exists. If the parent installation fails after the rename,
        the original "conffile" is restored.

        Unattended installs take the default answer N: the system "conffile"
        is kept and the distribution version is installed with the -spc
        suffix. An install is unattended with "PERL_MM_USE_DEFAULT=1", or
        without a terminal when standard input is at end of file.

        A system "conffile" without a recorded checksum counts as changed in
        the system.

   File modes
    Set the permissions of installed files with "file_modes". Keys are paths
    relative to the distribution root, values are modes written as Perl
    octal literals:

        my $builder = Module::Build::SysPath->new(
            ...
            file_modes => {
                'etc/acme/secret.ini' => 0640,
            },
        );

    Write the mode unquoted. A quoted '0640' would be read as a decimal
    number, so quoted modes with a leading zero are rejected.

    Every key must name a single file that is already selected for
    installation. "file_modes" does not select files: it neither bypasses
    MANIFEST nor replaces "<path_type>_files". A "file_modes" value that is
    not a hash, keys naming unselected files, the same file twice (for
    example etc/x and ./etc/x), directories, globs, .exists markers,
    absolute paths or paths leaving the distribution root, and modes outside
    0000..0777 or non-integer modes make "perl Build.PL" die.

    A declared mode is a ceiling. It never grants access that the file in
    the system does not already have:

    new file
        Gets the declared mode.

    existing file
        Gets the declared mode combined (bitwise AND) with its current mode.
        With 0640 declared, a 0644 file becomes 0640 and a 0600 file stays
        0600. This also applies to a kept "conffile", its -spc copy and an
        -old backup, whose current mode is the mode of the replaced
        "conffile", so a 0644 original becomes a 0640 backup. A new -spc
        copy is limited only by an existing -spc, not by the mode of the
        kept "conffile".

    "--destdir"
        The same rules apply to the staged files under the destination
        directory. Files in the live system are not touched.

    Without a declaration, files installed to "sysconfdir" and
    "sharedstatedir" are set to 0644, and other files keep the mode set by
    ExtUtils::Install (0444, or 0555 for executables).

    If setting a declared mode fails, the installation dies with the path
    and mode, and no "conffile" checksums are recorded.

    The declared mode is guaranteed only after a successful installation.
    ExtUtils::Install first installs every file with mode 0444 (0555 for
    executables), and "ACTION_install" sets the declared mode afterwards.
    Until then, and after a failed installation, a secret file can be
    readable by every local user who can reach its folder. Deployments that
    need stronger guarantees should install through a distribution package
    that sets permissions while copying.

   Owner and group
    Installation never assigns an owner or group of its own. A new file
    belongs to the user running the installation. When a file that already
    exists in the system is replaced, the new file gets the owner and group
    of the replaced file, so a "chgrp" of a secret "conffile" to the group
    of a service survives upgrades. This covers payload files of every path
    type, the -spc copy of a kept "conffile" and, when the new version of a
    "conffile" is accepted, the newly installed "conffile". A kept
    "conffile" and an -old backup are not replaced, so they keep their owner
    and group. With "--destdir", the same applies to the staged files.

    Only root can give a file to another user. If restoring the owner or
    group fails, the installation warns with the path and continues.

  ACTION_install
    This action is responsible for renaming files, replacing SPc.pm paths to
    systems once from Sys::Path. Also restores the owner and group of
    replaced files as described in "Owner and group", sets undeclared
    "sysconfdir" and "sharedstatedir" files to 0644, applies "file_modes" as
    described in "File modes", and stores the checksums of "conffile"s.

AUTHOR
    Jozef Kutej, <jkutej@cpan.org>

CONTRIBUTORS
    The following people have contributed to the Sys::Path by commiting
    their code, sending patches, reporting bugs, asking questions,
    suggesting useful advices, nitpicking, chatting on IRC or commenting on
    my blog (in no particular order):

        Lars Dɪᴇᴄᴋᴏᴡ 迪拉斯
        Emmanuel Rodriguez
        Slaven Rezić

COPYRIGHT & LICENSE
    Copyright 2009 Jozef Kutej, all rights reserved.

    This program is free software; you can redistribute it and/or modify it
    under the same terms as Perl itself.

