#   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#
#   file: lib/Dist/Zilla/Plugin/Manifes/Read/Manual.pod
#
#   Copyright © 2015 Van de Bugger
#
#   This file is part of perl-Dist-Zilla-Plugin-Manifest-Read.
#
#   perl-Dist-Zilla-Plugin-Manifest-Read is free software: you can redistribute it and/or modify it
#   under the terms of the GNU General Public License as published by the Free Software Foundation,
#   either version 3 of the License, or (at your option) any later version.
#
#   perl-Dist-Zilla-Plugin-Manifest-Read is distributed in the hope that it will be useful, but
#   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
#   PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License along with
#   perl-Dist-Zilla-Plugin-Manifest-Read. If not, see <http://www.gnu.org/licenses/>.
#
#   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

# PODNAME: Dist::Zilla::Plugin::Manifest::Read::Manual
# ABSTRACT: C<Manifest::Read> plugin user manual

#pod =for :this This is C<Manifest::Read> plugin user manual. Read this if you want to
#pod have annotated source manifest.
#pod
#pod =for :those If you are going to hack or extend C<Manifest::Read>, read the L<module
#pod documentation|Dist::Zilla::Plugin::Manifest::Read>. General topics like getting source, building, installing, bug
#pod reporting and some others are covered in the F<README>.
#pod
#pod =cut

#pod =for test_synopsis BEGIN { die "SKIP: Not Perl code.\n" };
#pod
#pod =head1 SYNOPSIS
#pod
#pod In your F<dist.ini>:
#pod
#pod     ...
#pod     ; Add files listed in source MANIFEST to the distribution
#pod     ;     (Manifest::Read does FileGatherer role):
#pod     [Manifest::Read]        ; Read *source* MANIFEST
#pod                             ;     and add files to the distribution.
#pod     ...
#pod     [Manifest::Write]       ; Write *distribution* MANIFEST.
#pod         ; or [Manifest]
#pod     ...
#pod     ; Use files listed in source MANIFEST
#pod     ;     (Manifest::Read does FileFinder role):
#pod     [Templates]                             ; Treat as templates
#pod         templates = Manifest::Read          ;   all *your* files.
#pod     [Test::EOL]                             ; Check line endings are consistent
#pod         finder = Manifest::Read/TestFiles   ;   in *your* test files.
#pod     [Test::NoTabs]                          ; Ensure there are no tabs
#pod         finder = Manifest::Read/ExecFiles   ;   in *your* exec files.
#pod     ...
#pod
#pod In your source F<MANIFEST>:
#pod
#pod     # Files marked with "+" will be added to distribution.
#pod     # Files marked with "-" will *not* be added to distribution.
#pod     # Entries marked with "/" are directories.
#pod     # All the enlisted entities must exist, regardless of mark.
#pod
#pod     lib/                / Modules to install:
#pod     lib/Foo.pm          + Perl module
#pod     lib/Foo/Manual.pod  + and user manual.
#pod
#pod     t/                  / Tests.
#pod     t/basic.t           + Test basic functionality.
#pod     t/extended.t        - Do not include, not ready yet.
#pod
#pod     Changes             + Release history.
#pod     COPYING             + License.
#pod     MANIFEST            - Exclude *source* manifest.
#pod     dist.ini            - Exclude Dist-Zilla config.
#pod     weaver.ini          - Exclude PodWeaver config.
#pod
#pod =head1 DESCRIPTION
#pod
#pod C<Manifest::Read> reads the I<annotated source manifest>. Default manifest name is F<MANIFEST>, but
#pod it may be changed with C<manifest> option.
#pod
#pod Manifest enlists all the source files and directories. C<Manifest::Read> ensures all the manifested
#pod files and directories exist, and adds files marked with C<+> to the distribution. Files marked with
#pod C<-> and directories marked with C</> should exist, but they are I<not> added to the distribution.
#pod
#pod C<Manifest::Read> also provides a bunch of C<FileFinder>s, which can be used by other plugins, see
#pod L</"File Finders"> section below.
#pod
#pod =head2 Manifest File Format
#pod
#pod Manifest is a plain text file in UTF-8 encoding. Empty and whitespace-only lines are ignored.
#pod Comment line should have hash (C<#>) as the first non-whitespace character, comment lines are
#pod ignored too. Other lines must match  the following regular expression:
#pod
#pod     ^ \s* filename ( \s+ mark ( \s+ comment )? )? \s* $
#pod
#pod =over
#pod
#pod =item I<filename>
#pod
#pod Filename should be Perl single-quoted string, or should not contain whitespaces. It should not
#pod start with hash or apostrophe. Example of valid filenames:
#pod
#pod     lib/Assa.pm
#pod     '/Program Files/Common Files/Dummy File.txt'
#pod     'That\'s all, folks!'
#pod
#pod Within single-quoted string C<\\> denotes backslash, C<\'> denotes apostrophe, all other characters
#pod are treated literally: C<\n> denotes two characters C<\> and C<n>, I<not> newline (these are
#pod regular Perl rules for single-quoted strings).
#pod
#pod =item I<mark>
#pod
#pod Either plus (C<+>) or minus (C<->) sign, or slash (C</>). Plus sign is also used as default mark if
#pod no mark is explicitly specified.
#pod
#pod =item I<comment>
#pod
#pod Comment is arbitrary text.
#pod
#pod =back
#pod
#pod =head2 File Finders
#pod
#pod C<Manifest::Read> itself does C<FileFinder> role, providing the list of files read from the
#pod manifest, so you can pass C<Manifest::Read> to any plugin expecting C<FileFinder> (see
#pod L</"EXAMPLES">).
#pod
#pod C<Manifest::Read> itself is not the only file finder, it also provides a bunch of (sub)finders:
#pod
#pod =for :list
#pod =   Manifest::Read/AllFiles
#pod =   Manifest::Read/ExecFiles
#pod =   Manifest::Read/ExtraTestFiles
#pod =   Manifest::Read/InstallModules
#pod =   Manifest::Read/PerlExecFiles
#pod =   Manifest::Read/TestFiles
#pod
#pod Each of these finders returns the list of files read from the manifest, not pruned, I<and> falling
#pod to the specified category. For example, C<Manifest::Read/InstallModules> returns the list of your
#pod install modules (F<*.pm> and F<*.pod> files from F<lib/> directory), C<Manifest::Read/TestFiles>
#pod returns the list of your test files (all files from F<t/> directory), etc. Strictly speaking, a
#pod file finder C<Manifest::Read/I<X>> returns intersection of two sets: (1) files returned by
#pod C<Manifest::Read> and (2) files found by standard C<:I<X>> file finder (see
#pod L<Dist::Zilla::Role::FileFinderUser/"default_finders"> for list of standard finders).
#pod
#pod Note: Files marked with C<-> and directories are not included into distribution and so never
#pod reported by any of C<Manifest::Read> finders.
#pod
#pod Also note a subtle difference between C<Manifest::Read> and other file (sub)finders (especially
#pod C<Manifest::Read/AllFiles>): the result of the first one is not affected by C<FilePruner>s, while
#pod result of others are. However, in normal conditions the difference should not appear: there is no
#pod point in manifesting a file just to prune it.
#pod
#pod =option manifest
#pod
#pod Name of manifest file to read. Default value is F<MANIFEST>.
#pod
#pod The option may be used if you want to name differently source and distribution manifests, e. g.:
#pod
#pod     [Manifest::Read]
#pod         manifest = Manifest.source
#pod     [Manifest::Write]
#pod
#pod In such a case the source manifest has name F<Manifest.source>, while distribution manifest has
#pod default name F<MANIFEST>.
#pod
#pod =note File Finder Names
#pod
#pod When C<Manifest::Read> is passed to another plugin as a file finder, you should pass plugin
#pod I<name>, not I<moniker>:
#pod
#pod     [Manifest::Read/MR]             ; Plugin name is MR.
#pod     [Test::EOL]
#pod         finder = MR                 ; *Not* Manifest::Read!
#pod     [Test::Version]
#pod         finder = MR/InstallModules  ; *Not* Manifest::Read!
#pod
#pod =note Source Manifest Can Enlist Itself
#pod
#pod Source manifest can enlist itself but normally it should be I<excluded> from distribution:
#pod
#pod     ...
#pod     MANIFEST        - Source manifest, this file.
#pod     #              ^^^ *Not* +!
#pod     ...
#pod
#pod because source and distribution manifests (may) have the same name but they are distinctly
#pod different files with different content. Source manifest enlists source files and itself is a part
#pod of source, while distribution manifest enlists distribution files (including automatically
#pod generated files like F<Build.PL>, F<META.json>, F<META.yml>) and itself is a part of distribution.
#pod Distribution manifest may be a part of source (if created manually), but usually it is generated by
#pod C<Manifest> (or C<Manifest::Write>) plugin.
#pod
#pod =example C<Test::EOL> and C<Test::NoTabs> tests
#pod
#pod By default, C<Test::EOL> and C<Test::NoTabs> are applied to all install modules, executable files,
#pod and test files (i. e. to files returned by C<:InstallModules>, C<:ExecFiles>, C<:TestFiles>
#pod standard finders). Some of these files may be out of your control, for example, F<t/00-compile.t>
#pod generated by C<Test::Compile>. There is no point in testing such files: even if the test fails, you
#pod cannot fix the generated file (at least, easily). At the same time, you may want to apply these
#pod tests to other your files, like F<README>. To apply the tests to all your files:
#pod
#pod     [Manifest::Read]
#pod     [Test::EOL]
#pod         finder = Manifest::Read
#pod     [Test::NoTabs]
#pod         finder = Manifest::Read
#pod
#pod =example C<Test::Version> test
#pod
#pod By default, C<Test::Version> is applied to all Perl modules in F<lib/> directory. Some of these
#pod files may be out of your control. For example, F<Inline.pm> file generated by C<InlineModule>
#pod plugin. This file does not have C<$VERSION> assignment and so fails the test. To apply the test
#pod only to your modules:
#pod
#pod     [Manifest::Read]
#pod     [Test::Version]
#pod         finder = Manifest::Read/InstallModules
#pod
#pod =head1 SEE ALSO
#pod
#pod =for :list
#pod =   L<Dist::Zilla>
#pod =   L<Dist::Zilla::Plugin::GatherDir>
#pod =   L<Dist::Zilla::Plugin::GatherFromManifest>
#pod =   L<Dist::Zilla::Plugin::Test::EOL>
#pod =   L<Dist::Zilla::Plugin::Test::NoTabs>
#pod =   L<Dist::Zilla::Plugin::Test::Version>
#pod =   L<Dist::Zilla::Role::FileFinder>
#pod =   L<Dist::Zilla::Role::FileGatherer>
#pod =   L<Dist::Zilla::Role::FilePruner>
#pod
#pod =head1 COPYRIGHT AND LICENSE
#pod
#pod Copyright (C) 2015 Van de Bugger
#pod
#pod License GPLv3+: The GNU General Public License version 3 or later
#pod <http://www.gnu.org/licenses/gpl-3.0.txt>.
#pod
#pod This is free software: you are free to change and redistribute it. There is
#pod NO WARRANTY, to the extent permitted by law.
#pod
#pod
#pod =cut

#pod =pod
#pod
#pod =encoding UTF-8
#pod
#pod =head1 WHAT?
#pod
#pod C<Dist-Zilla-Plugin-Manifest-Read> (or C<Manifest::Read> for brevity) is a C<Dist::Zilla> plugin. It reads
#pod I<annotated source> manifest, checks existence of all listed files and directories, and adds
#pod selected files to the distribution. C<Manifest::Read> also does C<FileFinder> role, providing the
#pod list of added files for other plugins.
#pod
#pod =cut

#pod =pod
#pod
#pod =encoding UTF-8
#pod
#pod =head1 WHY?
#pod
#pod C<Dist::Zilla> advertises using C<GatherDir> plugin to populate the distribution. However,
#pod C<GatherDir> has disadvantage: it grabs really all the files from the source directory, including
#pod files which are not meant to be added to distribution, like previously built distribution tarball.
#pod You have to use either C<GatherDir> parameters or dedicated plugins (e. g. C<PruneCruft>) to
#pod exclude unwanted files from distribution. However, risk to grab unwanted files remains.
#pod
#pod There is another (better to my taste) approach: grab only files explicitly listed in F<MANIFEST>
#pod file. This is implemented by nice C<GatherFromManifest> plugin.
#pod
#pod However I want a bit more. I also want to specify (and document) files (and directories) which are
#pod part of source, but should not be included to distribution. For example:
#pod
#pod     ex/                     / Examples.
#pod     ex/Assa/                / Very basic example.
#pod     ex/Assa/dist.ini        - dzil config file.
#pod     ex/Assa/dzil.out        - dzil output, included into user manual.
#pod
#pod     lib/                    / Modules to install:
#pod     lib/Assa.pm             + The primary module.
#pod
#pod     t/                      / Tests:
#pod     t/advanced.t            - Not ready yet, do not distribute.
#pod     t/basic.t               + Basic functional test.
#pod
#pod     tools/                  / Build tools:
#pod     tools/run-examples.sh   - Run examples, refresh dzil.out file.
#pod
#pod     Changes                 + Release history.
#pod     COPYING                 + License text.
#pod     README                  - Source documentation.
#pod     TODO                    - Plans and ideas.
#pod     VERSION                 + Version number.
#pod
#pod =cut


# end of file #

__END__

=pod

=encoding UTF-8

=head1 NAME

Dist::Zilla::Plugin::Manifest::Read::Manual - C<Manifest::Read> plugin user manual

=head1 VERSION

Version v0.4.0, released on 2015-11-01 17:30 UTC.

=head1 WHAT?

C<Dist-Zilla-Plugin-Manifest-Read> (or C<Manifest::Read> for brevity) is a C<Dist::Zilla> plugin. It reads
I<annotated source> manifest, checks existence of all listed files and directories, and adds
selected files to the distribution. C<Manifest::Read> also does C<FileFinder> role, providing the
list of added files for other plugins.

This is C<Manifest::Read> plugin user manual. Read this if you want to
have annotated source manifest.

If you are going to hack or extend C<Manifest::Read>, read the L<module
documentation|Dist::Zilla::Plugin::Manifest::Read>. General topics like getting source, building, installing, bug
reporting and some others are covered in the F<README>.

=head1 SYNOPSIS

In your F<dist.ini>:

    ...
    ; Add files listed in source MANIFEST to the distribution
    ;     (Manifest::Read does FileGatherer role):
    [Manifest::Read]        ; Read *source* MANIFEST
                            ;     and add files to the distribution.
    ...
    [Manifest::Write]       ; Write *distribution* MANIFEST.
        ; or [Manifest]
    ...
    ; Use files listed in source MANIFEST
    ;     (Manifest::Read does FileFinder role):
    [Templates]                             ; Treat as templates
        templates = Manifest::Read          ;   all *your* files.
    [Test::EOL]                             ; Check line endings are consistent
        finder = Manifest::Read/TestFiles   ;   in *your* test files.
    [Test::NoTabs]                          ; Ensure there are no tabs
        finder = Manifest::Read/ExecFiles   ;   in *your* exec files.
    ...

In your source F<MANIFEST>:

    # Files marked with "+" will be added to distribution.
    # Files marked with "-" will *not* be added to distribution.
    # Entries marked with "/" are directories.
    # All the enlisted entities must exist, regardless of mark.

    lib/                / Modules to install:
    lib/Foo.pm          + Perl module
    lib/Foo/Manual.pod  + and user manual.

    t/                  / Tests.
    t/basic.t           + Test basic functionality.
    t/extended.t        - Do not include, not ready yet.

    Changes             + Release history.
    COPYING             + License.
    MANIFEST            - Exclude *source* manifest.
    dist.ini            - Exclude Dist-Zilla config.
    weaver.ini          - Exclude PodWeaver config.

=head1 DESCRIPTION

C<Manifest::Read> reads the I<annotated source manifest>. Default manifest name is F<MANIFEST>, but
it may be changed with C<manifest> option.

Manifest enlists all the source files and directories. C<Manifest::Read> ensures all the manifested
files and directories exist, and adds files marked with C<+> to the distribution. Files marked with
C<-> and directories marked with C</> should exist, but they are I<not> added to the distribution.

C<Manifest::Read> also provides a bunch of C<FileFinder>s, which can be used by other plugins, see
L</"File Finders"> section below.

=head2 Manifest File Format

Manifest is a plain text file in UTF-8 encoding. Empty and whitespace-only lines are ignored.
Comment line should have hash (C<#>) as the first non-whitespace character, comment lines are
ignored too. Other lines must match  the following regular expression:

    ^ \s* filename ( \s+ mark ( \s+ comment )? )? \s* $

=over

=item I<filename>

Filename should be Perl single-quoted string, or should not contain whitespaces. It should not
start with hash or apostrophe. Example of valid filenames:

    lib/Assa.pm
    '/Program Files/Common Files/Dummy File.txt'
    'That\'s all, folks!'

Within single-quoted string C<\\> denotes backslash, C<\'> denotes apostrophe, all other characters
are treated literally: C<\n> denotes two characters C<\> and C<n>, I<not> newline (these are
regular Perl rules for single-quoted strings).

=item I<mark>

Either plus (C<+>) or minus (C<->) sign, or slash (C</>). Plus sign is also used as default mark if
no mark is explicitly specified.

=item I<comment>

Comment is arbitrary text.

=back

=head2 File Finders

C<Manifest::Read> itself does C<FileFinder> role, providing the list of files read from the
manifest, so you can pass C<Manifest::Read> to any plugin expecting C<FileFinder> (see
L</"EXAMPLES">).

C<Manifest::Read> itself is not the only file finder, it also provides a bunch of (sub)finders:

=over 4

=item Manifest::Read/AllFiles

=item Manifest::Read/ExecFiles

=item Manifest::Read/ExtraTestFiles

=item Manifest::Read/InstallModules

=item Manifest::Read/PerlExecFiles

=item Manifest::Read/TestFiles

=back

Each of these finders returns the list of files read from the manifest, not pruned, I<and> falling
to the specified category. For example, C<Manifest::Read/InstallModules> returns the list of your
install modules (F<*.pm> and F<*.pod> files from F<lib/> directory), C<Manifest::Read/TestFiles>
returns the list of your test files (all files from F<t/> directory), etc. Strictly speaking, a
file finder C<Manifest::Read/I<X>> returns intersection of two sets: (1) files returned by
C<Manifest::Read> and (2) files found by standard C<:I<X>> file finder (see
L<Dist::Zilla::Role::FileFinderUser/"default_finders"> for list of standard finders).

Note: Files marked with C<-> and directories are not included into distribution and so never
reported by any of C<Manifest::Read> finders.

Also note a subtle difference between C<Manifest::Read> and other file (sub)finders (especially
C<Manifest::Read/AllFiles>): the result of the first one is not affected by C<FilePruner>s, while
result of others are. However, in normal conditions the difference should not appear: there is no
point in manifesting a file just to prune it.

=head1 OPTIONS

=head2 manifest

Name of manifest file to read. Default value is F<MANIFEST>.

The option may be used if you want to name differently source and distribution manifests, e. g.:

    [Manifest::Read]
        manifest = Manifest.source
    [Manifest::Write]

In such a case the source manifest has name F<Manifest.source>, while distribution manifest has
default name F<MANIFEST>.

=head1 EXAMPLES

=head2 C<Test::EOL> and C<Test::NoTabs> tests

By default, C<Test::EOL> and C<Test::NoTabs> are applied to all install modules, executable files,
and test files (i. e. to files returned by C<:InstallModules>, C<:ExecFiles>, C<:TestFiles>
standard finders). Some of these files may be out of your control, for example, F<t/00-compile.t>
generated by C<Test::Compile>. There is no point in testing such files: even if the test fails, you
cannot fix the generated file (at least, easily). At the same time, you may want to apply these
tests to other your files, like F<README>. To apply the tests to all your files:

    [Manifest::Read]
    [Test::EOL]
        finder = Manifest::Read
    [Test::NoTabs]
        finder = Manifest::Read

=head2 C<Test::Version> test

By default, C<Test::Version> is applied to all Perl modules in F<lib/> directory. Some of these
files may be out of your control. For example, F<Inline.pm> file generated by C<InlineModule>
plugin. This file does not have C<$VERSION> assignment and so fails the test. To apply the test
only to your modules:

    [Manifest::Read]
    [Test::Version]
        finder = Manifest::Read/InstallModules

=head1 NOTES

=head2 File Finder Names

When C<Manifest::Read> is passed to another plugin as a file finder, you should pass plugin
I<name>, not I<moniker>:

    [Manifest::Read/MR]             ; Plugin name is MR.
    [Test::EOL]
        finder = MR                 ; *Not* Manifest::Read!
    [Test::Version]
        finder = MR/InstallModules  ; *Not* Manifest::Read!

=head2 Source Manifest Can Enlist Itself

Source manifest can enlist itself but normally it should be I<excluded> from distribution:

    ...
    MANIFEST        - Source manifest, this file.
    #              ^^^ *Not* +!
    ...

because source and distribution manifests (may) have the same name but they are distinctly
different files with different content. Source manifest enlists source files and itself is a part
of source, while distribution manifest enlists distribution files (including automatically
generated files like F<Build.PL>, F<META.json>, F<META.yml>) and itself is a part of distribution.
Distribution manifest may be a part of source (if created manually), but usually it is generated by
C<Manifest> (or C<Manifest::Write>) plugin.

=head1 WHY?

C<Dist::Zilla> advertises using C<GatherDir> plugin to populate the distribution. However,
C<GatherDir> has disadvantage: it grabs really all the files from the source directory, including
files which are not meant to be added to distribution, like previously built distribution tarball.
You have to use either C<GatherDir> parameters or dedicated plugins (e. g. C<PruneCruft>) to
exclude unwanted files from distribution. However, risk to grab unwanted files remains.

There is another (better to my taste) approach: grab only files explicitly listed in F<MANIFEST>
file. This is implemented by nice C<GatherFromManifest> plugin.

However I want a bit more. I also want to specify (and document) files (and directories) which are
part of source, but should not be included to distribution. For example:

    ex/                     / Examples.
    ex/Assa/                / Very basic example.
    ex/Assa/dist.ini        - dzil config file.
    ex/Assa/dzil.out        - dzil output, included into user manual.

    lib/                    / Modules to install:
    lib/Assa.pm             + The primary module.

    t/                      / Tests:
    t/advanced.t            - Not ready yet, do not distribute.
    t/basic.t               + Basic functional test.

    tools/                  / Build tools:
    tools/run-examples.sh   - Run examples, refresh dzil.out file.

    Changes                 + Release history.
    COPYING                 + License text.
    README                  - Source documentation.
    TODO                    - Plans and ideas.
    VERSION                 + Version number.

=for test_synopsis BEGIN { die "SKIP: Not Perl code.\n" };

=head1 SEE ALSO

=over 4

=item L<Dist::Zilla>

=item L<Dist::Zilla::Plugin::GatherDir>

=item L<Dist::Zilla::Plugin::GatherFromManifest>

=item L<Dist::Zilla::Plugin::Test::EOL>

=item L<Dist::Zilla::Plugin::Test::NoTabs>

=item L<Dist::Zilla::Plugin::Test::Version>

=item L<Dist::Zilla::Role::FileFinder>

=item L<Dist::Zilla::Role::FileGatherer>

=item L<Dist::Zilla::Role::FilePruner>

=back

=head1 AUTHOR

Van de Bugger <van.de.bugger@gmail.com>

=head1 COPYRIGHT AND LICENSE

Copyright (C) 2015 Van de Bugger

License GPLv3+: The GNU General Public License version 3 or later
<http://www.gnu.org/licenses/gpl-3.0.txt>.

This is free software: you are free to change and redistribute it. There is
NO WARRANTY, to the extent permitted by law.

=cut
