App-DocKnot

 view release on metacpan or  search on metacpan

MANIFEST  view on Meta::CPAN

share/templates/html.tmpl
share/templates/index.tmpl
share/templates/readme-md.tmpl
share/templates/readme.tmpl
share/templates/rss.tmpl
share/templates/thread.tmpl
t/cli/errors.t
t/cli/generate.t
t/cli/spin.t
t/config/basic.t
t/data/dist/fake-gpg
t/data/dist/package/Build.PL
t/data/dist/package/docs/docknot.yaml
t/data/dist/package/lib/Empty.pm
t/data/dist/package/MANIFEST
t/data/dist/package/MANIFEST.SKIP
t/data/dist/package/t/api/empty.t.in
t/data/generate/ansicolor/docknot.yaml
t/data/generate/ansicolor/output/readme
t/data/generate/ansicolor/output/readme-md
t/data/generate/ansicolor/output/thread

lib/App/DocKnot/Dist.pm  view on Meta::CPAN

sub _sign_tarballs {
    my ($self, $path, $prefix) = @_;
    my $files_ref = latest_tarball($path, $prefix)->{files};
    for my $file (grep { m{ [.]tar [.][xg]z }xms } $files_ref->@*) {
        my $tarball_path = $path->child($file);
        my $sig_path = $path->child($tarball_path->basename() . '.asc');
        if ($sig_path->exists()) {
            $sig_path->remove();
        }
        systemx(
            $self->{gpg}, '--detach-sign', '--armor', '-u',
            $self->{pgp_key}, $tarball_path,
        );
    }
    return;
}

##############################################################################
# Public interface
##############################################################################

lib/App/DocKnot/Dist.pm  view on Meta::CPAN

    if (!defined($distdir)) {
        croak('distdir path not given');
    } elsif (!-d $distdir) {
        croak("distdir path $distdir does not exist or is not a directory");
    }

    # Create and return the object.
    my $self = {
        config  => $config_reader->config(),
        distdir => path($distdir),
        gpg     => $args_ref->{gpg} // 'gpg',
        perl    => $args_ref->{perl},
        pgp_key => $args_ref->{pgp_key} // $global_config_ref->{pgp_key},
    };
    bless($self, $class);
    return $self;
}

# Given a distribution tarball compressed with gzip, ensure that every file
# from the source directory that is expected to be there is in the
# distribution tarball.  Assumes that it is run from the root of the source

lib/App/DocKnot/Dist.pm  view on Meta::CPAN


##############################################################################
# Module return value and documentation
##############################################################################

1;
__END__

=for stopwords
Allbery DocKnot MERCHANTABILITY NONINFRINGEMENT sublicense JSON CPAN ARGS
distdir Automake xz gpg Kwalify IO-Compress-Lzma

=head1 NAME

App::DocKnot::Dist - Prepare a distribution tarball

=head1 SYNOPSIS

    use App::DocKnot::Dist;
    my $docknot = App::DocKnot::Dist->new({ distdir => '/path/to/dist' });
    $docknot->make_distribution();

lib/App/DocKnot/Dist.pm  view on Meta::CPAN

Git, Perl 5.24 or later, and the modules File::BaseDir, File::ShareDir,
Git::Repository, IO::Compress::Xz (part of IO-Compress-Lzma),
IO::Uncompress::Gunzip (part of IO-Compress), IPC::Run, IPC::System::Simple,
Kwalify, List::SomeUtils, Path::Tiny, and YAML::XS, all of which are available
from CPAN.

The tools to build whatever type of software distribution is being prepared
are also required, since the distribution is built and tested as part of
preparing the tarball.

To sign distribution tarballs, the GnuPG command-line program B<gpg> is
required.  (Any version, either GnuPG v1 or GnuPG v2, should work.)

=head1 DESCRIPTION

This component of DocKnot generates distribution tarballs for a package.  This
is a bit of an odd inclusion in the DocKnot suite, since it's not about
generating documentation, but it uses the same configuration and metadata as
the rest of DocKnot.

Specifically, App::DocKnot::Dist exports the current branch from Git into a

lib/App/DocKnot/Dist.pm  view on Meta::CPAN


=over 4

=item distdir

The path to the directory into which to put the distribution tarball.  This
should point to a trusted directory, not one where an attacker could have
written files (see make_distribution() below).  Required if not set in the
global configuration file.

=item gpg

The path to the B<gpg> binary, used to sign generated tarballs if C<pgp_key>
is present in the global configuration or provided as a constructor argument.
Default: The binary named C<gpg> on the user's PATH.

=item metadata

The path to the metadata for the package on which to operate.  Default:
F<docs/docknot.yaml> relative to the current directory.

=item perl

The path to the Perl executable to use for build steps that require it.  Used
primarily in the test suite.  Default: The binary named C<perl> on the user's

lib/App/DocKnot/Dist.pm  view on Meta::CPAN


If the native distribution tarball generation commands for the package
generate a gzip-compressed tarball but not an xz-compressed tarball, an
xz-compressed tarball will be created.

After the distribution is created, check_dist() will be run on it.  If any
files are missing from the distribution, they will be reported to standard
output and then an exception will be thrown.

If the C<pgp_key> constructor parameter or global configuration option is set,
the generated tarballs will then be signed with that key, using B<gpg>.  The
generated signature will be armored and stored in a file named by appending
C<.asc> to the name of the tarball.

=back

=head1 AUTHOR

Russ Allbery <rra@cpan.org>

=head1 COPYRIGHT AND LICENSE

t/data/dist/fake-gpg  view on Meta::CPAN

#!/bin/sh
#
# Fake gpg program for testing dist signing.

echo '#' "$@"
if [ "$1" != '--detach-sign' ]; then exit 1; fi
if [ "$2" != '--armor'       ]; then exit 1; fi
if [ "$3" != '-u'            ]; then exit 1; fi
if [ "$4" != 'some-pgp-key'  ]; then exit 1; fi
echo 'some signature' >"$5".asc
exit 0

t/data/generate/control-archive/docknot.yaml  view on Meta::CPAN


      You will need write access to `/srv/control` or permission to create
      it.

      `process-control` and `generate-files` need a GnuPG keyring
      containing all of the honored hierarchy keys.  To generate this
      keyring, run `make install` or:

      ```sh
          mkdir keyring
          gpg --homedir=keyring --allow-non-selfsigned-uid --import keys/*
      ```

      from the top level of this distribution.  `process-control` also
      expects a `control.ctl` file in `/srv/control/control.ctl`, which
      can be generated from the files included here (after creating the
      keyring as described above) by running `make install` or:

      ```sh
          scripts/generate-files
      ```

t/data/generate/control-archive/docknot.yaml  view on Meta::CPAN

      existing files, and run `scripts/generate-files` to create a new
      `control.ctl` file.  See the documentation in
      `scripts/generate-files` for details about the supported
      configuration keys.

      If the hierarchy uses PGP-signed control messages, also put the PGP
      key into the `keys` directory in a file named after the hierarchy.
      Then, run:

      ```sh
          gpg --homedir=keyring --import keys/<hierarchy>
      ```

      to add the new key to the working keyring.

      The first user ID on the key must match the signer expected by the
      configuration data for the corresponding hierarchy.  If a hierarchy
      administrator sets that up wrong (usually by putting additional key
      IDs on the key), this can be corrected by importing the key into a
      keyring with GnuPG, using `gpg --edit-key` to remove the offending
      user ID, and exporting the key again with `gpg --export --ascii`.

      When adding a new hierarchy, it's often useful to bootstrap the
      newsgroup list by importing the current checkgroups.  To do this,
      obtain the checkgroups as a text file (containing only the groups
      without any news headers) and run:

      ```sh
          scripts/update-control checkgroups <hierarchy> < <checkgroups>
      ```

t/data/generate/control-archive/output/readme  view on Meta::CPAN


      make install

  You will need write access to /srv/control or permission to create it.

  process-control and generate-files need a GnuPG keyring containing all
  of the honored hierarchy keys.  To generate this keyring, run make
  install or:

      mkdir keyring
      gpg --homedir=keyring --allow-non-selfsigned-uid --import keys/*

  from the top level of this distribution.  process-control also expects a
  control.ctl file in /srv/control/control.ctl, which can be generated
  from the files included here (after creating the keyring as described
  above) by running make install or:

      scripts/generate-files

  Both of these are done automatically as part of make install.
  process-control expects /srv/control/archive to exist and archives

t/data/generate/control-archive/output/readme  view on Meta::CPAN


  To add a new hierarchy, add a configuration fragment in the config
  directory named after the hierarchy, following the format of the
  existing files, and run scripts/generate-files to create a new
  control.ctl file.  See the documentation in scripts/generate-files for
  details about the supported configuration keys.

  If the hierarchy uses PGP-signed control messages, also put the PGP key
  into the keys directory in a file named after the hierarchy.  Then, run:

      gpg --homedir=keyring --import keys/<hierarchy>

  to add the new key to the working keyring.

  The first user ID on the key must match the signer expected by the
  configuration data for the corresponding hierarchy.  If a hierarchy
  administrator sets that up wrong (usually by putting additional key IDs
  on the key), this can be corrected by importing the key into a keyring
  with GnuPG, using gpg --edit-key to remove the offending user ID, and
  exporting the key again with gpg --export --ascii.

  When adding a new hierarchy, it's often useful to bootstrap the
  newsgroup list by importing the current checkgroups.  To do this, obtain
  the checkgroups as a text file (containing only the groups without any
  news headers) and run:

      scripts/update-control checkgroups <hierarchy> < <checkgroups>

  where <hierarchy> is the hierarchy the checkgroups is for and
  <checkgroups> is the path to the checkgroups file.

t/data/generate/control-archive/output/readme-md  view on Meta::CPAN

```

You will need write access to `/srv/control` or permission to create it.

`process-control` and `generate-files` need a GnuPG keyring containing all
of the honored hierarchy keys.  To generate this keyring, run `make
install` or:

```sh
    mkdir keyring
    gpg --homedir=keyring --allow-non-selfsigned-uid --import keys/*
```

from the top level of this distribution.  `process-control` also expects a
`control.ctl` file in `/srv/control/control.ctl`, which can be generated
from the files included here (after creating the keyring as described
above) by running `make install` or:

```sh
    scripts/generate-files
```

t/data/generate/control-archive/output/readme-md  view on Meta::CPAN

To add a new hierarchy, add a configuration fragment in the `config`
directory named after the hierarchy, following the format of the existing
files, and run `scripts/generate-files` to create a new `control.ctl`
file.  See the documentation in `scripts/generate-files` for details about
the supported configuration keys.

If the hierarchy uses PGP-signed control messages, also put the PGP key
into the `keys` directory in a file named after the hierarchy.  Then, run:

```sh
    gpg --homedir=keyring --import keys/<hierarchy>
```

to add the new key to the working keyring.

The first user ID on the key must match the signer expected by the
configuration data for the corresponding hierarchy.  If a hierarchy
administrator sets that up wrong (usually by putting additional key IDs on
the key), this can be corrected by importing the key into a keyring with
GnuPG, using `gpg --edit-key` to remove the offending user ID, and
exporting the key again with `gpg --export --ascii`.

When adding a new hierarchy, it's often useful to bootstrap the newsgroup
list by importing the current checkgroups.  To do this, obtain the
checkgroups as a text file (containing only the groups without any news
headers) and run:

```sh
    scripts/update-control checkgroups <hierarchy> < <checkgroups>
```

t/data/generate/pgp-sign/docknot.yaml  view on Meta::CPAN

copyrights:
  - holder: Russ Allbery <rra@cpan.org>
    years: 1997-2000, 2002, 2004, 2018, 2020

build:
  type: Module::Build
distribution:
  cpan: PGP-Sign
  ignore:
    - ^t/data/gnupg1/random_seed$
    - ^t/data/gnupg./trustdb\.gpg$
  packaging:
    debian:
      package: libpgp-sign-perl
      summary: |
        PGP::Sign is packaged for Debian as libpgp-sign-perl.
  section: perl
  tarname: PGP-Sign
  version: pgp-sign
support:
  email: rra@cpan.org

t/data/update/control-archive/docknot.yaml  view on Meta::CPAN

    ```

    You will need write access to `/srv/control` or permission to create it.

    `process-control` and `generate-files` need a GnuPG keyring containing all
    of the honored hierarchy keys.  To generate this keyring, run `make
    install` or:

    ```sh
        mkdir keyring
        gpg --homedir=keyring --allow-non-selfsigned-uid --import keys/*
    ```

    from the top level of this distribution.  `process-control` also expects a
    `control.ctl` file in `/srv/control/control.ctl`, which can be generated
    from the files included here (after creating the keyring as described
    above) by running `make install` or:

    ```sh
        scripts/generate-files
    ```

t/data/update/control-archive/docknot.yaml  view on Meta::CPAN

    To add a new hierarchy, add a configuration fragment in the `config`
    directory named after the hierarchy, following the format of the existing
    files, and run `scripts/generate-files` to create a new `control.ctl`
    file.  See the documentation in `scripts/generate-files` for details about
    the supported configuration keys.

    If the hierarchy uses PGP-signed control messages, also put the PGP key
    into the `keys` directory in a file named after the hierarchy.  Then, run:

    ```sh
        gpg --homedir=keyring --import keys/<hierarchy>
    ```

    to add the new key to the working keyring.

    The first user ID on the key must match the signer expected by the
    configuration data for the corresponding hierarchy.  If a hierarchy
    administrator sets that up wrong (usually by putting additional key IDs on
    the key), this can be corrected by importing the key into a keyring with
    GnuPG, using `gpg --edit-key` to remove the offending user ID, and
    exporting the key again with `gpg --export --ascii`.

    When adding a new hierarchy, it's often useful to bootstrap the newsgroup
    list by importing the current checkgroups.  To do this, obtain the
    checkgroups as a text file (containing only the groups without any news
    headers) and run:

    ```sh
        scripts/update-control checkgroups <hierarchy> < <checkgroups>
    ```

t/data/update/control-archive/old/sections/installation  view on Meta::CPAN

```

You will need write access to `/srv/control` or permission to create it.

`process-control` and `generate-files` need a GnuPG keyring containing all
of the honored hierarchy keys.  To generate this keyring, run `make
install` or:

```sh
    mkdir keyring
    gpg --homedir=keyring --allow-non-selfsigned-uid --import keys/*
```

from the top level of this distribution.  `process-control` also expects a
`control.ctl` file in `/srv/control/control.ctl`, which can be generated
from the files included here (after creating the keyring as described
above) by running `make install` or:

```sh
    scripts/generate-files
```

t/data/update/control-archive/old/sections/maintenance  view on Meta::CPAN

To add a new hierarchy, add a configuration fragment in the `config`
directory named after the hierarchy, following the format of the existing
files, and run `scripts/generate-files` to create a new `control.ctl`
file.  See the documentation in `scripts/generate-files` for details about
the supported configuration keys.

If the hierarchy uses PGP-signed control messages, also put the PGP key
into the `keys` directory in a file named after the hierarchy.  Then, run:

```sh
    gpg --homedir=keyring --import keys/<hierarchy>
```

to add the new key to the working keyring.

The first user ID on the key must match the signer expected by the
configuration data for the corresponding hierarchy.  If a hierarchy
administrator sets that up wrong (usually by putting additional key IDs on
the key), this can be corrected by importing the key into a keyring with
GnuPG, using `gpg --edit-key` to remove the offending user ID, and
exporting the key again with `gpg --export --ascii`.

When adding a new hierarchy, it's often useful to bootstrap the newsgroup
list by importing the current checkgroups.  To do this, obtain the
checkgroups as a text file (containing only the groups without any news
headers) and run:

```sh
    scripts/update-control checkgroups <hierarchy> < <checkgroups>
```

t/dist/basic.t  view on Meta::CPAN


use Test::More;

# Isolate from the environment.
local $ENV{XDG_CONFIG_HOME} = '/nonexistent';
local $ENV{XDG_CONFIG_DIRS} = '/nonexistent';

# Find the full path to the test data.
my $cwd = Path::Tiny->cwd();
my $dataroot = $cwd->child('t', 'data', 'dist', 'package');
my $gpg_path = $cwd->child('t', 'data', 'dist', 'fake-gpg');

# Set up a temporary directory.
my $dir = Path::Tiny->tempdir();
my $sourcedir = $dir->child('source');
my $distdir = $dir->child('dist');

# Create a new repository, copy all files from the data directory, and commit
# them.  We have to rename the test while we copy it to avoid having it picked
# up by the main package test suite.
dircopy($dataroot, $sourcedir)

t/dist/basic.t  view on Meta::CPAN


# Switch to using a configuration file and enable signing.
$distdir->child('Empty-v2.0.0.tar.gz')->remove();
$distdir->child('Empty-v2.0.0.tar.xz')->remove();
$dir->child('docknot')->mkpath();
$dir->child('docknot', 'config.yaml')->spew_utf8(
    "distdir: $distdir\n",
    "pgp_key: some-pgp-key\n",
);
local $ENV{XDG_CONFIG_HOME} = "$dir";
$dist = App::DocKnot::Dist->new({ gpg => $gpg_path, perl => $^X });

# Create a dummy signature, which should be overwritten.
$distdir->child('Empty-v2.0.0.tar.gz.asc')->spew_utf8("bogus signature\n");

# If we add an ignored file to the source tree, this should not trigger any
# errors.
$sourcedir->child('ignored-file')->spew_utf8("Some data\n");
capture_stdout {
    eval { $dist->make_distribution() };
};
is($@, q{}, 'no errors with ignored file');

# And now there should be signatures.
ok($distdir->child('Empty-v2.0.0.tar.gz')->exists(), 'dist exists');
ok($distdir->child('Empty-v2.0.0.tar.xz')->exists(), 'xz dist exists');
ok($distdir->child('Empty-v2.0.0.tar.gz.asc')->exists(), 'gz signature');
ok($distdir->child('Empty-v2.0.0.tar.xz.asc')->exists(), 'xz signature');
is(
    "some signature\n",
    $distdir->child('Empty-v2.0.0.tar.gz.asc')->slurp_utf8(),
    'fake-gpg was run',
);

# If we add a new file to the source tree and run make_distribution() again,
# it should fail, and the output should contain an error message about an
# unknown file.
$sourcedir->child('some-file')->spew_utf8("Some data\n");
my $stdout = capture_stdout {
    eval { $dist->make_distribution() };
};
is($@, "1 file missing from distribution\n", 'correct error for extra file');



( run in 1.141 second using v1.01-cache-2.11-cpan-df04353d9ac )