summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Allbery <rra@cpan.org>2020-12-25 12:13:50 -0800
committerRuss Allbery <rra@cpan.org>2020-12-25 12:13:50 -0800
commit3cd3e8f108b4ccf29fec3e53203d3a21b42c0985 (patch)
tree79c8b5e049e7d86b751cd94b1129d92d029193f9
parent97aa9a30155bb3ac45d0443610bc08818271adfb (diff)
parent413cd8f921496b98cf149b5d6b0e30faa6e93518 (diff)
New upstream version 4.00
-rw-r--r--.github/dependabot.yml6
-rw-r--r--.github/workflows/build.yaml2
-rw-r--r--Build.PL6
-rw-r--r--Changes43
-rw-r--r--MANIFEST180
-rw-r--r--META.json23
-rw-r--r--META.yml19
-rw-r--r--README30
-rw-r--r--README.md34
-rwxr-xr-xbin/docknot25
-rw-r--r--cpanfile2
-rw-r--r--docs/docknot.yaml145
-rw-r--r--docs/metadata/blurb6
-rw-r--r--docs/metadata/description30
-rw-r--r--docs/metadata/metadata.json70
-rw-r--r--docs/metadata/requirements12
-rw-r--r--docs/metadata/test/suffix16
-rw-r--r--lib/App/DocKnot.pm4
-rw-r--r--lib/App/DocKnot/Command.pm26
-rw-r--r--lib/App/DocKnot/Config.pm184
-rw-r--r--lib/App/DocKnot/Dist.pm14
-rw-r--r--lib/App/DocKnot/Generate.pm99
-rw-r--r--lib/App/DocKnot/Update.pm391
-rw-r--r--share/licenses.json11
-rw-r--r--share/licenses.yaml70
-rw-r--r--share/licenses/BSD-3-clause-or-GPL-1+31
-rw-r--r--share/licenses/Expat17
-rw-r--r--share/licenses/Perl5
-rw-r--r--share/schema/docknot.yaml248
-rw-r--r--share/schema/licenses.yaml17
-rw-r--r--share/templates/readme-md.tmpl51
-rw-r--r--share/templates/readme.tmpl35
-rw-r--r--share/templates/thread.tmpl33
-rwxr-xr-xt/cli/errors.t5
-rwxr-xr-xt/cli/generate.t4
-rwxr-xr-xt/config/basic.t35
-rw-r--r--t/data/dist/MANIFEST5
-rw-r--r--t/data/dist/docs/docknot.yaml27
-rw-r--r--t/data/dist/docs/metadata/blurb1
-rw-r--r--t/data/dist/docs/metadata/description1
-rw-r--r--t/data/dist/docs/metadata/metadata.json14
-rw-r--r--t/data/dist/docs/metadata/requirements1
-rw-r--r--t/data/generate/ansicolor/docknot.yaml113
-rw-r--r--t/data/generate/ansicolor/output/readme8
-rw-r--r--t/data/generate/ansicolor/output/readme-md16
-rw-r--r--t/data/generate/ansicolor/output/thread4
-rw-r--r--t/data/generate/c-tap-harness/docknot.yaml265
-rw-r--r--t/data/generate/c-tap-harness/output/readme4
-rw-r--r--t/data/generate/c-tap-harness/output/readme-md6
-rw-r--r--t/data/generate/control-archive/docknot.yaml342
-rw-r--r--t/data/generate/control-archive/output/readme22
-rw-r--r--t/data/generate/control-archive/output/readme-md10
-rw-r--r--t/data/generate/control-archive/output/thread6
-rw-r--r--t/data/generate/docknot/output/thread23
-rw-r--r--t/data/generate/lbcd/docknot.yaml122
-rw-r--r--t/data/generate/lbcd/output/readme-md4
-rw-r--r--t/data/generate/pam-krb5/docknot.yaml533
-rw-r--r--t/data/generate/pam-krb5/metadata/README6
-rw-r--r--t/data/generate/pam-krb5/output/readme8
-rw-r--r--t/data/generate/pam-krb5/output/readme-md10
-rw-r--r--t/data/generate/pgp-sign/docknot.yaml114
-rw-r--r--t/data/generate/pgp-sign/output/readme161
-rw-r--r--t/data/generate/pgp-sign/output/readme-md161
-rw-r--r--t/data/generate/pgp-sign/output/thread180
-rw-r--r--t/data/generate/remctl/docknot.yaml392
-rw-r--r--t/data/generate/remctl/output/readme4
-rw-r--r--t/data/generate/remctl/output/readme-md10
-rw-r--r--t/data/generate/rra-c-util/docknot.yaml282
-rw-r--r--t/data/generate/rra-c-util/output/readme41
-rw-r--r--t/data/generate/rra-c-util/output/readme-md49
-rw-r--r--t/data/generate/wallet/docknot.yaml351
-rw-r--r--t/data/generate/wallet/output/readme373
-rw-r--r--t/data/generate/wallet/output/readme-md374
-rw-r--r--t/data/generate/wallet/output/thread331
-rw-r--r--t/data/perlcriticrc3
-rwxr-xr-xt/data/regenerate-data4
-rw-r--r--t/data/update/ansicolor/docknot.yaml106
-rw-r--r--t/data/update/ansicolor/old/blurb (renamed from t/data/generate/ansicolor/metadata/blurb)0
-rw-r--r--t/data/update/ansicolor/old/description (renamed from t/data/generate/ansicolor/metadata/description)0
-rw-r--r--t/data/update/ansicolor/old/metadata.json (renamed from t/data/generate/ansicolor/metadata/metadata.json)0
-rw-r--r--t/data/update/ansicolor/old/notices (renamed from t/data/generate/ansicolor/metadata/notices)0
-rw-r--r--t/data/update/ansicolor/old/quote (renamed from t/data/generate/ansicolor/metadata/quote)0
-rw-r--r--t/data/update/ansicolor/old/requirements (renamed from t/data/generate/ansicolor/metadata/requirements)0
-rw-r--r--t/data/update/c-tap-harness/docknot.yaml255
-rw-r--r--t/data/update/c-tap-harness/old/blurb (renamed from t/data/generate/c-tap-harness/metadata/blurb)0
-rw-r--r--t/data/update/c-tap-harness/old/build/suffix (renamed from t/data/generate/c-tap-harness/metadata/build/suffix)0
-rw-r--r--t/data/update/c-tap-harness/old/description (renamed from t/data/generate/c-tap-harness/metadata/description)0
-rw-r--r--t/data/update/c-tap-harness/old/metadata.json (renamed from t/data/generate/c-tap-harness/metadata/metadata.json)0
-rw-r--r--t/data/update/c-tap-harness/old/requirements (renamed from t/data/generate/c-tap-harness/metadata/requirements)0
-rw-r--r--t/data/update/c-tap-harness/old/sections/testing (renamed from t/data/generate/c-tap-harness/metadata/sections/testing)0
-rw-r--r--t/data/update/c-tap-harness/old/sections/using-the-harness (renamed from t/data/generate/c-tap-harness/metadata/sections/using-the-harness)0
-rw-r--r--t/data/update/control-archive/docknot.yaml321
-rw-r--r--t/data/update/control-archive/old/blurb (renamed from t/data/generate/control-archive/metadata/blurb)0
-rw-r--r--t/data/update/control-archive/old/description (renamed from t/data/generate/control-archive/metadata/description)0
-rw-r--r--t/data/update/control-archive/old/metadata.json (renamed from t/data/generate/control-archive/metadata/metadata.json)0
-rw-r--r--t/data/update/control-archive/old/notices (renamed from t/data/generate/control-archive/metadata/notices)0
-rw-r--r--t/data/update/control-archive/old/quote (renamed from t/data/generate/control-archive/metadata/quote)0
-rw-r--r--t/data/update/control-archive/old/requirements (renamed from t/data/generate/control-archive/metadata/requirements)0
-rw-r--r--t/data/update/control-archive/old/sections/bootstrapping (renamed from t/data/generate/control-archive/metadata/sections/bootstrapping)0
-rw-r--r--t/data/update/control-archive/old/sections/installation (renamed from t/data/generate/control-archive/metadata/sections/installation)0
-rw-r--r--t/data/update/control-archive/old/sections/layout (renamed from t/data/generate/control-archive/metadata/sections/layout)0
-rw-r--r--t/data/update/control-archive/old/sections/maintenance (renamed from t/data/generate/control-archive/metadata/sections/maintenance)0
-rw-r--r--t/data/update/control-archive/old/sections/versioning (renamed from t/data/generate/control-archive/metadata/sections/versioning)0
-rw-r--r--t/data/update/control-archive/old/support/extra (renamed from t/data/generate/control-archive/metadata/support/extra)0
-rw-r--r--t/data/update/lbcd/docknot.yaml113
-rw-r--r--t/data/update/lbcd/old/blurb (renamed from t/data/generate/lbcd/metadata/blurb)0
-rw-r--r--t/data/update/lbcd/old/build/middle (renamed from t/data/generate/lbcd/metadata/build/middle)0
-rw-r--r--t/data/update/lbcd/old/build/suffix (renamed from t/data/generate/lbcd/metadata/build/suffix)0
-rw-r--r--t/data/update/lbcd/old/debian/summary (renamed from t/data/generate/lbcd/metadata/debian/summary)0
-rw-r--r--t/data/update/lbcd/old/description (renamed from t/data/generate/lbcd/metadata/description)0
-rw-r--r--t/data/update/lbcd/old/metadata.json (renamed from t/data/generate/lbcd/metadata/metadata.json)0
-rw-r--r--t/data/update/lbcd/old/orphaned (renamed from t/data/generate/lbcd/metadata/orphaned)0
-rw-r--r--t/data/update/lbcd/old/requirements (renamed from t/data/generate/lbcd/metadata/requirements)0
-rw-r--r--t/data/update/lbcd/old/test/suffix (renamed from t/data/generate/lbcd/metadata/test/suffix)0
-rw-r--r--t/data/update/pam-krb5/docknot.yaml508
-rw-r--r--t/data/update/pam-krb5/old/README (renamed from docs/metadata/README)0
-rw-r--r--t/data/update/pam-krb5/old/blurb (renamed from t/data/generate/pam-krb5/metadata/blurb)0
-rw-r--r--t/data/update/pam-krb5/old/build/middle (renamed from t/data/generate/pam-krb5/metadata/build/middle)0
-rw-r--r--t/data/update/pam-krb5/old/debian/summary (renamed from t/data/generate/pam-krb5/metadata/debian/summary)0
-rw-r--r--t/data/update/pam-krb5/old/description (renamed from t/data/generate/pam-krb5/metadata/description)0
-rw-r--r--t/data/update/pam-krb5/old/metadata.json (renamed from t/data/generate/pam-krb5/metadata/metadata.json)0
-rw-r--r--t/data/update/pam-krb5/old/quote (renamed from t/data/generate/pam-krb5/metadata/quote)0
-rw-r--r--t/data/update/pam-krb5/old/requirements (renamed from t/data/generate/pam-krb5/metadata/requirements)0
-rw-r--r--t/data/update/pam-krb5/old/sections/configuring (renamed from t/data/generate/pam-krb5/metadata/sections/configuring)0
-rw-r--r--t/data/update/pam-krb5/old/sections/debugging (renamed from t/data/generate/pam-krb5/metadata/sections/debugging)0
-rw-r--r--t/data/update/pam-krb5/old/sections/history-and-acknowledgements (renamed from t/data/generate/pam-krb5/metadata/sections/history-and-acknowledgements)0
-rw-r--r--t/data/update/pam-krb5/old/sections/implementation-notes (renamed from t/data/generate/pam-krb5/metadata/sections/implementation-notes)0
-rw-r--r--t/data/update/pam-krb5/old/test/prefix (renamed from t/data/generate/pam-krb5/metadata/test/prefix)0
-rw-r--r--t/data/update/pam-krb5/old/test/suffix (renamed from t/data/generate/pam-krb5/metadata/test/suffix)0
-rw-r--r--t/data/update/remctl/docknot.yaml380
-rw-r--r--t/data/update/remctl/old/blurb (renamed from t/data/generate/remctl/metadata/blurb)0
-rw-r--r--t/data/update/remctl/old/bootstrap (renamed from t/data/generate/remctl/metadata/bootstrap)0
-rw-r--r--t/data/update/remctl/old/build/middle (renamed from t/data/generate/remctl/metadata/build/middle)0
-rw-r--r--t/data/update/remctl/old/debian/summary (renamed from t/data/generate/remctl/metadata/debian/summary)0
-rw-r--r--t/data/update/remctl/old/description (renamed from t/data/generate/remctl/metadata/description)0
-rw-r--r--t/data/update/remctl/old/metadata.json (renamed from t/data/generate/remctl/metadata/metadata.json)0
-rw-r--r--t/data/update/remctl/old/packaging/extra (renamed from t/data/generate/remctl/metadata/packaging/extra)0
-rw-r--r--t/data/update/remctl/old/quote (renamed from t/data/generate/remctl/metadata/quote)0
-rw-r--r--t/data/update/remctl/old/requirements (renamed from t/data/generate/remctl/metadata/requirements)0
-rw-r--r--t/data/update/remctl/old/sections/building-on-windows (renamed from t/data/generate/remctl/metadata/sections/building-on-windows)0
-rw-r--r--t/data/update/remctl/old/test/prefix (renamed from t/data/generate/remctl/metadata/test/prefix)0
-rw-r--r--t/data/update/remctl/old/test/suffix (renamed from t/data/generate/remctl/metadata/test/suffix)0
-rw-r--r--t/data/update/rra-c-util/docknot.yaml318
-rw-r--r--t/data/update/rra-c-util/old/blurb (renamed from t/data/generate/rra-c-util/metadata/blurb)0
-rw-r--r--t/data/update/rra-c-util/old/description (renamed from t/data/generate/rra-c-util/metadata/description)0
-rw-r--r--t/data/update/rra-c-util/old/metadata.json (renamed from t/data/generate/rra-c-util/metadata/metadata.json)0
-rw-r--r--t/data/update/rra-c-util/old/quote (renamed from t/data/generate/rra-c-util/metadata/quote)0
-rw-r--r--t/data/update/rra-c-util/old/requirements (renamed from t/data/generate/rra-c-util/metadata/requirements)0
-rw-r--r--t/data/update/rra-c-util/old/sections/building (renamed from t/data/generate/rra-c-util/metadata/sections/building)0
-rw-r--r--t/data/update/rra-c-util/old/sections/testing (renamed from t/data/generate/rra-c-util/metadata/sections/testing)0
-rw-r--r--t/data/update/rra-c-util/old/sections/using-this-code (renamed from t/data/generate/rra-c-util/metadata/sections/using-this-code)0
-rwxr-xr-xt/dist/basic.t6
-rwxr-xr-xt/dist/commands.t13
-rwxr-xr-xt/docs/spdx-license.t4
-rwxr-xr-xt/generate/basic.t11
-rwxr-xr-xt/generate/output.t4
-rw-r--r--t/lib/Test/RRA.pm2
-rw-r--r--t/lib/Test/RRA/Config.pm2
-rw-r--r--t/lib/Test/RRA/ModuleVersion.pm2
-rwxr-xr-xt/metadata/licenses.t34
-rwxr-xr-xt/style/coverage.t6
-rwxr-xr-xt/style/obsolete-strings.t2
-rwxr-xr-xt/update/basic.t52
163 files changed, 7617 insertions, 832 deletions
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..5ace460
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,6 @@
+version: 2
+updates:
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "weekly"
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index e231b85..74e5bf1 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -35,7 +35,7 @@ jobs:
steps:
- uses: actions/checkout@v2
- - uses: perl-actions/install-with-cpm@v1.3
+ - uses: perl-actions/install-with-cpm@v1.4
with:
cpanfile: "cpanfile"
args: "--with-suggests"
diff --git a/Build.PL b/Build.PL
index 6ca1e39..3ec2de0 100644
--- a/Build.PL
+++ b/Build.PL
@@ -47,9 +47,7 @@ my $build = Module::Build->new(
'meta-spec' => { version => '2' },
resources => {
bugtracker => {
- mailto => 'bug-App-DocKnot@rt.cpan.org',
- web =>
- 'https://rt.cpan.org/Dist/Display.html?Name=App-DocKnot',
+ web => 'https://github.com/rra/docknot/issues',
},
homepage => 'https://www.eyrie.org/~eagle/software/docknot',
repository => {
@@ -69,9 +67,11 @@ my $build = Module::Build->new(
'IPC::Run' => 0,
'IPC::System::Simple' => 0,
'JSON::MaybeXS' => 0,
+ 'Kwalify' => 0,
'List::SomeUtils' => 0,
'Perl6::Slurp' => 0,
'Template' => 0,
+ 'YAML::XS' => '0.81',
perl => '5.024',
},
test_requires => {
diff --git a/Changes b/Changes
index fd6e15a..f716898 100644
--- a/Changes
+++ b/Changes
@@ -1,5 +1,48 @@
User-Visible DocKnot Changes
+DocKnot 4.00 (2020-12-25)
+
+ Change the metadata format to a single YAML file, with a slightly
+ different internal representation, whose default location is
+ docs/docknot.yaml. The new docknot update command (or the
+ App::DocKnot::Update module) will convert from the old JSON format.
+ The new metadata format is checked against a schema when read.
+ DocKnot now depends on YAML::XS and Kwalify.
+
+ Support a test.override metadata key that overrides the Testing
+ section in README and README.md files entirely, except for the note
+ about Lancaster Consensus environment variables.
+
+ Move bootstrap metadata to build.bootstrap, build.lancaster to
+ test.lancaster, packaging to distribution.packaging, packaging.debian
+ to distribution.packaging.debian.package, debian to
+ distribution.packaging.debian, and readme.sections to sections to
+ clean up some old issues with the schema now that there's an upgrade
+ process. If readme.sections defined a testing section, move that to
+ test.override.
+
+ Drop support for the support.cpan metadata key, since the CPAN RT
+ instance is going away. For packages with support.cpan set, if
+ vcs.github was set and support.github was not, set support.github to
+ match vcs.github during a docknot update.
+
+ Drop the current version number from the title of README.md. This is
+ not a common practice and doesn't seem to add much value.
+
+ Word wrap numeric lists and, in Markdown output, quoted paragraphs.
+ Previously these preserved the original spacing from the input text
+ snippets.
+
+ Require paragraphs be indented by at least six spaces, not five, to be
+ treated as verbatim paragraphs and left unwrapped. (Markdown
+ paragraphs can still use four spaces because they are wrapped in
+ markup lines.)
+
+ Add some additional markup to the Markdown version of building
+ instructions for packages that use Kerberos and Autoconf.
+
+ Use https for the link and badge for unmaintained packages.
+
DocKnot 3.05 (2020-08-09)
Change the heuristic for when to refrain from wrapping output
diff --git a/MANIFEST b/MANIFEST
index 657cea1..a75cf99 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1,29 +1,25 @@
+.github/dependabot.yml
.github/workflows/build.yaml
.gitignore
bin/docknot
Build.PL
Changes
cpanfile
-docs/metadata/blurb
-docs/metadata/description
-docs/metadata/metadata.json
-docs/metadata/README
-docs/metadata/requirements
-docs/metadata/test/suffix
+docs/docknot.yaml
lib/App/DocKnot.pm
lib/App/DocKnot/Command.pm
lib/App/DocKnot/Config.pm
lib/App/DocKnot/Dist.pm
lib/App/DocKnot/Generate.pm
+lib/App/DocKnot/Update.pm
LICENSE
MANIFEST This list of files
MANIFEST.SKIP
README
README.md
-share/licenses.json
-share/licenses/BSD-3-clause-or-GPL-1+
-share/licenses/Expat
-share/licenses/Perl
+share/licenses.yaml
+share/schema/docknot.yaml
+share/schema/licenses.yaml
share/templates/readme-md.tmpl
share/templates/readme.tmpl
share/templates/thread.tmpl
@@ -31,108 +27,127 @@ t/cli/errors.t
t/cli/generate.t
t/config/basic.t
t/data/dist/Build.PL
-t/data/dist/docs/metadata/blurb
-t/data/dist/docs/metadata/description
-t/data/dist/docs/metadata/metadata.json
-t/data/dist/docs/metadata/requirements
+t/data/dist/docs/docknot.yaml
t/data/dist/lib/Empty.pm
t/data/dist/MANIFEST
t/data/dist/MANIFEST.SKIP
t/data/dist/t/api/empty.t.in
-t/data/generate/ansicolor/metadata/blurb
-t/data/generate/ansicolor/metadata/description
-t/data/generate/ansicolor/metadata/metadata.json
-t/data/generate/ansicolor/metadata/notices
-t/data/generate/ansicolor/metadata/quote
-t/data/generate/ansicolor/metadata/requirements
+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
-t/data/generate/c-tap-harness/metadata/blurb
-t/data/generate/c-tap-harness/metadata/build/suffix
-t/data/generate/c-tap-harness/metadata/description
-t/data/generate/c-tap-harness/metadata/metadata.json
-t/data/generate/c-tap-harness/metadata/requirements
-t/data/generate/c-tap-harness/metadata/sections/testing
-t/data/generate/c-tap-harness/metadata/sections/using-the-harness
+t/data/generate/c-tap-harness/docknot.yaml
t/data/generate/c-tap-harness/output/readme
t/data/generate/c-tap-harness/output/readme-md
t/data/generate/c-tap-harness/output/thread
-t/data/generate/control-archive/metadata/blurb
-t/data/generate/control-archive/metadata/description
-t/data/generate/control-archive/metadata/metadata.json
-t/data/generate/control-archive/metadata/notices
-t/data/generate/control-archive/metadata/quote
-t/data/generate/control-archive/metadata/requirements
-t/data/generate/control-archive/metadata/sections/bootstrapping
-t/data/generate/control-archive/metadata/sections/installation
-t/data/generate/control-archive/metadata/sections/layout
-t/data/generate/control-archive/metadata/sections/maintenance
-t/data/generate/control-archive/metadata/sections/versioning
-t/data/generate/control-archive/metadata/support/extra
+t/data/generate/control-archive/docknot.yaml
t/data/generate/control-archive/output/readme
t/data/generate/control-archive/output/readme-md
t/data/generate/control-archive/output/thread
t/data/generate/docknot/output/thread
-t/data/generate/lbcd/metadata/blurb
-t/data/generate/lbcd/metadata/build/middle
-t/data/generate/lbcd/metadata/build/suffix
-t/data/generate/lbcd/metadata/debian/summary
-t/data/generate/lbcd/metadata/description
-t/data/generate/lbcd/metadata/metadata.json
-t/data/generate/lbcd/metadata/orphaned
-t/data/generate/lbcd/metadata/requirements
-t/data/generate/lbcd/metadata/test/suffix
+t/data/generate/lbcd/docknot.yaml
t/data/generate/lbcd/output/readme
t/data/generate/lbcd/output/readme-md
t/data/generate/lbcd/output/thread
-t/data/generate/pam-krb5/metadata/blurb
-t/data/generate/pam-krb5/metadata/build/middle
-t/data/generate/pam-krb5/metadata/debian/summary
-t/data/generate/pam-krb5/metadata/description
-t/data/generate/pam-krb5/metadata/metadata.json
-t/data/generate/pam-krb5/metadata/quote
-t/data/generate/pam-krb5/metadata/README
-t/data/generate/pam-krb5/metadata/requirements
-t/data/generate/pam-krb5/metadata/sections/configuring
-t/data/generate/pam-krb5/metadata/sections/debugging
-t/data/generate/pam-krb5/metadata/sections/history-and-acknowledgements
-t/data/generate/pam-krb5/metadata/sections/implementation-notes
-t/data/generate/pam-krb5/metadata/test/prefix
-t/data/generate/pam-krb5/metadata/test/suffix
+t/data/generate/pam-krb5/docknot.yaml
t/data/generate/pam-krb5/output/readme
t/data/generate/pam-krb5/output/readme-md
t/data/generate/pam-krb5/output/thread
-t/data/generate/remctl/metadata/blurb
-t/data/generate/remctl/metadata/bootstrap
-t/data/generate/remctl/metadata/build/middle
-t/data/generate/remctl/metadata/debian/summary
-t/data/generate/remctl/metadata/description
-t/data/generate/remctl/metadata/metadata.json
-t/data/generate/remctl/metadata/packaging/extra
-t/data/generate/remctl/metadata/quote
-t/data/generate/remctl/metadata/requirements
-t/data/generate/remctl/metadata/sections/building-on-windows
-t/data/generate/remctl/metadata/test/prefix
-t/data/generate/remctl/metadata/test/suffix
+t/data/generate/pgp-sign/docknot.yaml
+t/data/generate/pgp-sign/output/readme
+t/data/generate/pgp-sign/output/readme-md
+t/data/generate/pgp-sign/output/thread
+t/data/generate/remctl/docknot.yaml
t/data/generate/remctl/output/readme
t/data/generate/remctl/output/readme-md
t/data/generate/remctl/output/thread
-t/data/generate/rra-c-util/metadata/blurb
-t/data/generate/rra-c-util/metadata/description
-t/data/generate/rra-c-util/metadata/metadata.json
-t/data/generate/rra-c-util/metadata/quote
-t/data/generate/rra-c-util/metadata/requirements
-t/data/generate/rra-c-util/metadata/sections/building
-t/data/generate/rra-c-util/metadata/sections/testing
-t/data/generate/rra-c-util/metadata/sections/using-this-code
+t/data/generate/rra-c-util/docknot.yaml
t/data/generate/rra-c-util/output/readme
t/data/generate/rra-c-util/output/readme-md
t/data/generate/rra-c-util/output/thread
+t/data/generate/wallet/docknot.yaml
+t/data/generate/wallet/output/readme
+t/data/generate/wallet/output/readme-md
+t/data/generate/wallet/output/thread
t/data/perl.conf
t/data/perlcriticrc
t/data/perltidyrc
t/data/regenerate-data
+t/data/update/ansicolor/docknot.yaml
+t/data/update/ansicolor/old/blurb
+t/data/update/ansicolor/old/description
+t/data/update/ansicolor/old/metadata.json
+t/data/update/ansicolor/old/notices
+t/data/update/ansicolor/old/quote
+t/data/update/ansicolor/old/requirements
+t/data/update/c-tap-harness/docknot.yaml
+t/data/update/c-tap-harness/old/blurb
+t/data/update/c-tap-harness/old/build/suffix
+t/data/update/c-tap-harness/old/description
+t/data/update/c-tap-harness/old/metadata.json
+t/data/update/c-tap-harness/old/requirements
+t/data/update/c-tap-harness/old/sections/testing
+t/data/update/c-tap-harness/old/sections/using-the-harness
+t/data/update/control-archive/docknot.yaml
+t/data/update/control-archive/old/blurb
+t/data/update/control-archive/old/description
+t/data/update/control-archive/old/metadata.json
+t/data/update/control-archive/old/notices
+t/data/update/control-archive/old/quote
+t/data/update/control-archive/old/requirements
+t/data/update/control-archive/old/sections/bootstrapping
+t/data/update/control-archive/old/sections/installation
+t/data/update/control-archive/old/sections/layout
+t/data/update/control-archive/old/sections/maintenance
+t/data/update/control-archive/old/sections/versioning
+t/data/update/control-archive/old/support/extra
+t/data/update/lbcd/docknot.yaml
+t/data/update/lbcd/old/blurb
+t/data/update/lbcd/old/build/middle
+t/data/update/lbcd/old/build/suffix
+t/data/update/lbcd/old/debian/summary
+t/data/update/lbcd/old/description
+t/data/update/lbcd/old/metadata.json
+t/data/update/lbcd/old/orphaned
+t/data/update/lbcd/old/requirements
+t/data/update/lbcd/old/test/suffix
+t/data/update/pam-krb5/docknot.yaml
+t/data/update/pam-krb5/old/blurb
+t/data/update/pam-krb5/old/build/middle
+t/data/update/pam-krb5/old/debian/summary
+t/data/update/pam-krb5/old/description
+t/data/update/pam-krb5/old/metadata.json
+t/data/update/pam-krb5/old/quote
+t/data/update/pam-krb5/old/README
+t/data/update/pam-krb5/old/requirements
+t/data/update/pam-krb5/old/sections/configuring
+t/data/update/pam-krb5/old/sections/debugging
+t/data/update/pam-krb5/old/sections/history-and-acknowledgements
+t/data/update/pam-krb5/old/sections/implementation-notes
+t/data/update/pam-krb5/old/test/prefix
+t/data/update/pam-krb5/old/test/suffix
+t/data/update/remctl/docknot.yaml
+t/data/update/remctl/old/blurb
+t/data/update/remctl/old/bootstrap
+t/data/update/remctl/old/build/middle
+t/data/update/remctl/old/debian/summary
+t/data/update/remctl/old/description
+t/data/update/remctl/old/metadata.json
+t/data/update/remctl/old/packaging/extra
+t/data/update/remctl/old/quote
+t/data/update/remctl/old/requirements
+t/data/update/remctl/old/sections/building-on-windows
+t/data/update/remctl/old/test/prefix
+t/data/update/remctl/old/test/suffix
+t/data/update/rra-c-util/docknot.yaml
+t/data/update/rra-c-util/old/blurb
+t/data/update/rra-c-util/old/description
+t/data/update/rra-c-util/old/metadata.json
+t/data/update/rra-c-util/old/quote
+t/data/update/rra-c-util/old/requirements
+t/data/update/rra-c-util/old/sections/building
+t/data/update/rra-c-util/old/sections/testing
+t/data/update/rra-c-util/old/sections/using-this-code
t/dist/basic.t
t/dist/commands.t
t/docs/pod-coverage.t
@@ -153,6 +168,7 @@ t/style/minimum-version.t
t/style/module-version.t
t/style/obsolete-strings.t
t/style/strict.t
+t/update/basic.t
TODO
META.yml
META.json
diff --git a/META.json b/META.json
index 9908465..9629703 100644
--- a/META.json
+++ b/META.json
@@ -27,9 +27,11 @@
"IPC::Run" : "0",
"IPC::System::Simple" : "0",
"JSON::MaybeXS" : "0",
+ "Kwalify" : "0",
"List::SomeUtils" : "0",
"Perl6::Slurp" : "0",
"Template" : "0",
+ "YAML::XS" : "0.81",
"perl" : "5.024"
}
},
@@ -43,30 +45,33 @@
"provides" : {
"App::DocKnot" : {
"file" : "lib/App/DocKnot.pm",
- "version" : "3.05"
+ "version" : "4.00"
},
"App::DocKnot::Command" : {
"file" : "lib/App/DocKnot/Command.pm",
- "version" : "3.05"
+ "version" : "4.00"
},
"App::DocKnot::Config" : {
"file" : "lib/App/DocKnot/Config.pm",
- "version" : "3.05"
+ "version" : "4.00"
},
"App::DocKnot::Dist" : {
"file" : "lib/App/DocKnot/Dist.pm",
- "version" : "3.05"
+ "version" : "4.00"
},
"App::DocKnot::Generate" : {
"file" : "lib/App/DocKnot/Generate.pm",
- "version" : "3.05"
+ "version" : "4.00"
+ },
+ "App::DocKnot::Update" : {
+ "file" : "lib/App/DocKnot/Update.pm",
+ "version" : "4.00"
}
},
"release_status" : "stable",
"resources" : {
"bugtracker" : {
- "mailto" : "bug-App-DocKnot@rt.cpan.org",
- "web" : "https://rt.cpan.org/Dist/Display.html?Name=App-DocKnot"
+ "web" : "https://github.com/rra/docknot/issues"
},
"homepage" : "https://www.eyrie.org/~eagle/software/docknot",
"license" : [
@@ -78,6 +83,6 @@
"web" : "https://github.com/rra/docknot"
}
},
- "version" : "3.05",
- "x_serialization_backend" : "JSON::PP version 4.02"
+ "version" : "4.00",
+ "x_serialization_backend" : "JSON::PP version 4.04"
}
diff --git a/META.yml b/META.yml
index 47ccc1a..a02a145 100644
--- a/META.yml
+++ b/META.yml
@@ -17,19 +17,22 @@ name: App-DocKnot
provides:
App::DocKnot:
file: lib/App/DocKnot.pm
- version: '3.05'
+ version: '4.00'
App::DocKnot::Command:
file: lib/App/DocKnot/Command.pm
- version: '3.05'
+ version: '4.00'
App::DocKnot::Config:
file: lib/App/DocKnot/Config.pm
- version: '3.05'
+ version: '4.00'
App::DocKnot::Dist:
file: lib/App/DocKnot/Dist.pm
- version: '3.05'
+ version: '4.00'
App::DocKnot::Generate:
file: lib/App/DocKnot/Generate.pm
- version: '3.05'
+ version: '4.00'
+ App::DocKnot::Update:
+ file: lib/App/DocKnot/Update.pm
+ version: '4.00'
requires:
File::BaseDir: '0'
File::ShareDir: '1.00'
@@ -37,14 +40,16 @@ requires:
IPC::Run: '0'
IPC::System::Simple: '0'
JSON::MaybeXS: '0'
+ Kwalify: '0'
List::SomeUtils: '0'
Perl6::Slurp: '0'
Template: '0'
+ YAML::XS: '0.81'
perl: '5.024'
resources:
- bugtracker: https://rt.cpan.org/Dist/Display.html?Name=App-DocKnot
+ bugtracker: https://github.com/rra/docknot/issues
homepage: https://www.eyrie.org/~eagle/software/docknot
license: http://www.opensource.org/licenses/mit-license.php
repository: https://github.com/rra/docknot.git
-version: '3.05'
+version: '4.00'
x_serialization_backend: 'CPAN::Meta::YAML version 0.018'
diff --git a/README b/README
index 82a77f9..eb82cdc 100644
--- a/README
+++ b/README
@@ -1,5 +1,5 @@
- DocKnot 3.05
- (package documentation generator)
+ DocKnot 4.00
+ (Package documentation generator)
Maintained by Russ Allbery <rra@cpan.org>
Copyright 2013-2020 Russ Allbery <rra@cpan.org>. This software is
@@ -9,11 +9,11 @@
BLURB
DocKnot is a system for generating consistent human-readable software
- package documentation from metadata files and templates. The metadata
- is primarily JSON files, but can include files of documentation
- snippets. The goal is to generate both web pages and distributed
- documentation files (such as README) from the same source, using
- templates for consistency across multiple packages.
+ package documentation from a YAML metadata file and templates. The goal
+ is to generate both web pages and distributed documentation files (such
+ as README) from the same source, using templates for consistency across
+ multiple packages. DocKnot also automates generating distribution
+ tarballs for software packages.
DESCRIPTION
@@ -26,7 +26,7 @@ DESCRIPTION
version of README as well, avoiding the ugly text rendering on the
GitHub page for a package.
- This package uses one metadata directory as its source information and
+ This package uses one metadata file as its source information and
generates all the various bits of documentation for a package. This
allows me to make any changes in one place and then just regenerate the
web page, included documentation, and other files to incorporate those
@@ -34,6 +34,10 @@ DESCRIPTION
shared wording and push that out to every package I maintain during its
next release, without having to remember which changes I wanted to make.
+ DocKnot is also slowly absorbing other tools that I use for software
+ distribution and web site maintenance, such as generating distribution
+ tarballs for software packages.
+
DocKnot was designed and written for my personal needs, and I'm not sure
it will be useful for anyone else. At the least, the template files are
rather specific to my preferences about how to write package
@@ -59,9 +63,11 @@ REQUIREMENTS
* IPC::Run
* IPC::System::Simple
* JSON::MaybeXS
+ * Kwalify
* List::SomeUtils
* Perl6::Slurp
* Template (part of Template Toolkit)
+ * YAML::XS
BUILDING AND INSTALLATION
@@ -118,9 +124,9 @@ SUPPORT
will always have the current version of this package, the current
documentation, and pointers to any additional resources.
- For bug tracking, use the CPAN bug tracker at:
+ For bug tracking, use the issue tracker on GitHub:
- https://rt.cpan.org/Dist/Display.html?Name=App-DocKnot
+ https://github.com/rra/docknot/issues
However, please be aware that I tend to be extremely busy and work
projects often take priority. I'll save your report and get to it as
@@ -143,9 +149,7 @@ SOURCE REPOSITORY
The eyrie.org repository is the canonical one, maintained by the author,
but using GitHub is probably more convenient for most purposes. Pull
- requests are gratefully reviewed and normally accepted. It's probably
- better to use the CPAN bug tracker than GitHub issues, though, to keep
- all Perl module issues in the same place.
+ requests are gratefully reviewed and normally accepted.
LICENSE
diff --git a/README.md b/README.md
index 49fabb8..af110a0 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# DocKnot 3.05
+# DocKnot
[![Build
status](https://github.com/rra/docknot/workflows/build/badge.svg)](https://github.com/rra/docknot/actions)
@@ -13,11 +13,11 @@ distributed under a BSD-style license. Please see the section
## Blurb
DocKnot is a system for generating consistent human-readable software
-package documentation from metadata files and templates. The metadata is
-primarily JSON files, but can include files of documentation snippets.
-The goal is to generate both web pages and distributed documentation files
-(such as `README`) from the same source, using templates for consistency
-across multiple packages.
+package documentation from a YAML metadata file and templates. The goal
+is to generate both web pages and distributed documentation files (such as
+`README`) from the same source, using templates for consistency across
+multiple packages. DocKnot also automates generating distribution
+tarballs for software packages.
## Description
@@ -30,7 +30,7 @@ straw was when GitHub became popular and I wanted to provide a Markdown
version of `README` as well, avoiding the ugly text rendering on the
GitHub page for a package.
-This package uses one metadata directory as its source information and
+This package uses one metadata file as its source information and
generates all the various bits of documentation for a package. This
allows me to make any changes in one place and then just regenerate the
web page, included documentation, and other files to incorporate those
@@ -38,6 +38,10 @@ changes. It also lets me make changes to the templates to improve shared
wording and push that out to every package I maintain during its next
release, without having to remember which changes I wanted to make.
+DocKnot is also slowly absorbing other tools that I use for software
+distribution and web site maintenance, such as generating distribution
+tarballs for software packages.
+
DocKnot was designed and written for my personal needs, and I'm not sure
it will be useful for anyone else. At the least, the template files are
rather specific to my preferences about how to write package
@@ -63,9 +67,11 @@ The following additional Perl modules are required to use it:
* IPC::Run
* IPC::System::Simple
* JSON::MaybeXS
+* Kwalify
* List::SomeUtils
* Perl6::Slurp
* Template (part of Template Toolkit)
+* YAML::XS
## Building and Installation
@@ -125,11 +131,11 @@ The [DocKnot web page](https://www.eyrie.org/~eagle/software/docknot/)
will always have the current version of this package, the current
documentation, and pointers to any additional resources.
-For bug tracking, use the [CPAN bug
-tracker](https://rt.cpan.org/Dist/Display.html?Name=App-DocKnot).
-However, please be aware that I tend to be extremely busy and work
-projects often take priority. I'll save your report and get to it as soon
-as I can, but it may take me a couple of months.
+For bug tracking, use the [issue tracker on
+GitHub](https://github.com/rra/docknot/issues). However, please be aware
+that I tend to be extremely busy and work projects often take priority.
+I'll save your report and get to it as soon as I can, but it may take me a
+couple of months.
## Source Repository
@@ -143,9 +149,7 @@ web](https://git.eyrie.org/?p=devel/docknot.git).
The eyrie.org repository is the canonical one, maintained by the author,
but using GitHub is probably more convenient for most purposes. Pull
-requests are gratefully reviewed and normally accepted. It's probably
-better to use the CPAN bug tracker than GitHub issues, though, to keep all
-Perl module issues in the same place.
+requests are gratefully reviewed and normally accepted.
## License
diff --git a/bin/docknot b/bin/docknot
index 1133224..f2de52c 100755
--- a/bin/docknot
+++ b/bin/docknot
@@ -38,6 +38,8 @@ B<docknot> generate [B<-m> I<metadata>] [B<-w> I<width>] I<template> [I<output>]
B<docknot> generate-all [B<-m> I<metadata>] [B<-w> I<width>]
+B<docknot> update [B<-m> I<metadata>] [B<-o> I<output>]
+
=head1 DESCRIPTION
B<docknot> can perform various actions related to documenting or releasing
@@ -67,6 +69,10 @@ Like C<generate>, but generates all of the package documentation for which
default output files are configured. This is a quick short-cut to generating
all documentation that's shipped with the package.
+=item update
+
+Update the DocKnot package configuration from an older format.
+
=back
=head1 OPTIONS
@@ -153,6 +159,25 @@ Column width at which the generated output is wrapped. Default: 74.
=back
+=head2 update
+
+=over 4
+
+=item B<-m> I<metadata>, B<--metdata>=I<metadata>
+
+The path to the JSON metadata files for the package that should be converted
+to the new YAML format. This should be a directory containing all the package
+metadata files required by App::DocKnot. Default: F<docs/metadata> relative
+to the current directory.
+
+=item B<-o> I<output>, B<--output>=I<output>
+
+The output file for the updated package configuration. Default:
+F<docs/docknot.yaml> relative to the current directory (which is the
+recommended metadata path for a project).
+
+=back
+
=head1 DIAGNOSTICS
If B<docknot> fails with errors, see the underlying module for that subcommand
diff --git a/cpanfile b/cpanfile
index 164c82c..e5f5ca1 100644
--- a/cpanfile
+++ b/cpanfile
@@ -6,9 +6,11 @@ requires 'IO::Compress::Xz';
requires 'IPC::Run';
requires 'IPC::System::Simple';
requires 'JSON::MaybeXS';
+requires 'Kwalify';
requires 'List::SomeUtils';
requires 'Perl6::Slurp';
requires 'Template';
+requires 'YAML::XS';
on 'test' => sub {
requires 'Capture::Tiny';
diff --git a/docs/docknot.yaml b/docs/docknot.yaml
new file mode 100644
index 0000000..b28bd55
--- /dev/null
+++ b/docs/docknot.yaml
@@ -0,0 +1,145 @@
+# Package metadata for DocKnot.
+#
+# This file contains configuration for DocKnot used to generate
+# documentation files (like README.md) and web pages. Other documentation
+# in this package is generated automatically from these files as part of
+# the release process. For more information, see DocKnot's documentation.
+#
+# DocKnot is available from <https://www.eyrie.org/~eagle/software/docknot/>.
+#
+# Copyright 2016, 2018-2020 Russ Allbery <rra@cpan.org>
+#
+# SPDX-License-Identifier: MIT
+
+format: v1
+
+name: DocKnot
+maintainer: Russ Allbery <rra@cpan.org>
+version: '4.00'
+synopsis: Package documentation generator
+
+license:
+ name: Expat
+copyrights:
+ - holder: Russ Allbery <rra@cpan.org>
+ years: 2013-2020
+
+build:
+ type: Module::Build
+distribution:
+ cpan: App-DocKnot
+ packaging:
+ debian:
+ personal: true
+ section: devel
+ tarname: App-DocKnot
+ version: docknot
+support:
+ email: rra@cpan.org
+ github: rra/docknot
+ web: https://www.eyrie.org/~eagle/software/docknot/
+vcs:
+ browse: https://git.eyrie.org/?p=devel/docknot.git
+ github: rra/docknot
+ status:
+ workflow: build
+ type: Git
+ url: https://git.eyrie.org/git/devel/docknot.git
+
+docs:
+ api:
+ - name: api/app-docknot
+ title: App::DocKnot
+ - name: api/app-docknot-command
+ title: App::DocKnot::Command
+ - name: api/app-docknot-config
+ title: App::DocKnot::Config
+ - name: api/app-docknot-dist
+ title: App::DocKnot::Dist
+ - name: api/app-docknot-generate
+ title: App::DocKnot::Generate
+ - name: api/app-docknot-update
+ title: App::DocKnot::Update
+ user:
+ - name: docknot
+ title: docknot manual page
+
+blurb: |
+ DocKnot is a system for generating consistent human-readable software
+ package documentation from a YAML metadata file and templates. The goal
+ is to generate both web pages and distributed documentation files (such
+ as `README`) from the same source, using templates for consistency
+ across multiple packages. DocKnot also automates generating
+ distribution tarballs for software packages.
+
+description: |
+ After years of maintaining a variety of small free software packages, I
+ found the most tedious part of making a new release was updating the
+ documentation in multiple locations. Copyright dates would change,
+ prerequisites and package descriptions would change, and I had to update
+ at least the package `README` file and its web pages separately. The
+ last straw was when GitHub became popular and I wanted to provide a
+ Markdown version of `README` as well, avoiding the ugly text rendering
+ on the GitHub page for a package.
+
+ This package uses one metadata file as its source information and
+ generates all the various bits of documentation for a package. This
+ allows me to make any changes in one place and then just regenerate the
+ web page, included documentation, and other files to incorporate those
+ changes. It also lets me make changes to the templates to improve
+ shared wording and push that out to every package I maintain during its
+ next release, without having to remember which changes I wanted to make.
+
+ DocKnot is also slowly absorbing other tools that I use for software
+ distribution and web site maintenance, such as generating distribution
+ tarballs for software packages.
+
+ DocKnot was designed and written for my personal needs, and I'm not sure
+ it will be useful for anyone else. At the least, the template files are
+ rather specific to my preferences about how to write package
+ documentation, and the web page output is in my personal thread language
+ as opposed to HTML. I'm not sure if I'll have the time to make it a
+ more general tool. But you're certainly welcome to use it if you find
+ it useful, send pull requests to make it more general, or take ideas
+ from it for your own purposes.
+
+ Currently included in this package are just the App::DocKnot module and
+ its submodules, a small docknot driver program, and the templates I use
+ for my own software. Over time, it may include more of my web
+ publishing framework, time permitting.
+
+requirements: |
+ Perl 5.24 or later and Module::Build are required to build this module.
+ The following additional Perl modules are required to use it:
+
+ * File::BaseDir
+ * File::ShareDir
+ * IO::Compress::Xz (part of IO-Compress-LZMA)
+ * IPC::Run
+ * IPC::System::Simple
+ * JSON::MaybeXS
+ * Kwalify
+ * List::SomeUtils
+ * Perl6::Slurp
+ * Template (part of Template Toolkit)
+ * YAML::XS
+
+test:
+ lancaster: true
+ suffix: |
+ Capture::Tiny and File::Copy::Recursive are required to run the test
+ suite. The following additional Perl modules will be used by the test
+ suite if present:
+
+ * Devel::Cover
+ * Perl::Critic::Freenode
+ * Test::MinimumVersion
+ * Test::Perl::Critic
+ * Test::Pod
+ * Test::Pod::Coverage
+ * Test::Spelling
+ * Test::Strict
+ * Test::Synopsis
+
+ All are available on CPAN. Those tests will be skipped if the modules
+ are not available.
diff --git a/docs/metadata/blurb b/docs/metadata/blurb
deleted file mode 100644
index d36e8b7..0000000
--- a/docs/metadata/blurb
+++ /dev/null
@@ -1,6 +0,0 @@
-DocKnot is a system for generating consistent human-readable software
-package documentation from metadata files and templates. The metadata is
-primarily JSON files, but can include files of documentation snippets.
-The goal is to generate both web pages and distributed documentation files
-(such as `README`) from the same source, using templates for consistency
-across multiple packages.
diff --git a/docs/metadata/description b/docs/metadata/description
deleted file mode 100644
index d60771f..0000000
--- a/docs/metadata/description
+++ /dev/null
@@ -1,30 +0,0 @@
-After years of maintaining a variety of small free software packages, I
-found the most tedious part of making a new release was updating the
-documentation in multiple locations. Copyright dates would change,
-prerequisites and package descriptions would change, and I had to update
-at least the package `README` file and its web pages separately. The last
-straw was when GitHub became popular and I wanted to provide a Markdown
-version of `README` as well, avoiding the ugly text rendering on the
-GitHub page for a package.
-
-This package uses one metadata directory as its source information and
-generates all the various bits of documentation for a package. This
-allows me to make any changes in one place and then just regenerate the
-web page, included documentation, and other files to incorporate those
-changes. It also lets me make changes to the templates to improve shared
-wording and push that out to every package I maintain during its next
-release, without having to remember which changes I wanted to make.
-
-DocKnot was designed and written for my personal needs, and I'm not sure
-it will be useful for anyone else. At the least, the template files are
-rather specific to my preferences about how to write package
-documentation, and the web page output is in my personal thread language
-as opposed to HTML. I'm not sure if I'll have the time to make it a more
-general tool. But you're certainly welcome to use it if you find it
-useful, send pull requests to make it more general, or take ideas from it
-for your own purposes.
-
-Currently included in this package are just the App::DocKnot module and
-its submodules, a small docknot driver program, and the templates I use
-for my own software. Over time, it may include more of my web publishing
-framework, time permitting.
diff --git a/docs/metadata/metadata.json b/docs/metadata/metadata.json
deleted file mode 100644
index 57c0c22..0000000
--- a/docs/metadata/metadata.json
+++ /dev/null
@@ -1,70 +0,0 @@
-{
- "name": "DocKnot",
- "version": "3.05",
- "synopsis": "package documentation generator",
- "maintainer": "Russ Allbery <rra@cpan.org>",
- "copyrights": [
- {
- "holder": "Russ Allbery <rra@cpan.org>",
- "years": "2013-2020",
- },
- ],
- "license": "Expat",
- "build": {
- "lancaster": true,
- "type": "Module::Build",
- },
- "support": {
- "cpan": "App-DocKnot",
- "email": "rra@cpan.org",
- "web": "https://www.eyrie.org/~eagle/software/docknot/",
- },
- "vcs": {
- "type": "Git",
- "url": "https://git.eyrie.org/git/devel/docknot.git",
- "browse": "https://git.eyrie.org/?p=devel/docknot.git",
- "github": "rra/docknot",
- "status": {
- "workflow": "build",
- },
- },
- "distribution": {
- "section": "devel",
- "tarname": "App-DocKnot",
- "version": "docknot",
- "cpan": "App-DocKnot",
- },
- "debian": {
- "personal": true,
- },
- "docs": {
- "user": [
- {
- "name": "docknot",
- "title": "docknot manual page",
- },
- ],
- "api": [
- {
- "name": "api/app-docknot",
- "title": "App::DocKnot",
- },
- {
- "name": "api/app-docknot-command",
- "title": "App::DocKnot::Command",
- },
- {
- "name": "api/app-docknot-config",
- "title": "App::DocKnot::Config",
- },
- {
- "name": "api/app-docknot-dist",
- "title": "App::DocKnot::Dist",
- },
- {
- "name": "api/app-docknot-generate",
- "title": "App::DocKnot::Generate",
- },
- ],
- },
-}
diff --git a/docs/metadata/requirements b/docs/metadata/requirements
deleted file mode 100644
index 6c137d5..0000000
--- a/docs/metadata/requirements
+++ /dev/null
@@ -1,12 +0,0 @@
-Perl 5.24 or later and Module::Build are required to build this module.
-The following additional Perl modules are required to use it:
-
-* File::BaseDir
-* File::ShareDir
-* IO::Compress::Xz (part of IO-Compress-LZMA)
-* IPC::Run
-* IPC::System::Simple
-* JSON::MaybeXS
-* List::SomeUtils
-* Perl6::Slurp
-* Template (part of Template Toolkit)
diff --git a/docs/metadata/test/suffix b/docs/metadata/test/suffix
deleted file mode 100644
index faed7f9..0000000
--- a/docs/metadata/test/suffix
+++ /dev/null
@@ -1,16 +0,0 @@
-Capture::Tiny and File::Copy::Recursive are required to run the test
-suite. The following additional Perl modules will be used by the test
-suite if present:
-
-* Devel::Cover
-* Perl::Critic::Freenode
-* Test::MinimumVersion
-* Test::Perl::Critic
-* Test::Pod
-* Test::Pod::Coverage
-* Test::Spelling
-* Test::Strict
-* Test::Synopsis
-
-All are available on CPAN. Those tests will be skipped if the modules are
-not available.
diff --git a/lib/App/DocKnot.pm b/lib/App/DocKnot.pm
index e20eae7..3fba7f6 100644
--- a/lib/App/DocKnot.pm
+++ b/lib/App/DocKnot.pm
@@ -11,7 +11,7 @@
# Modules and declarations
##############################################################################
-package App::DocKnot 3.05;
+package App::DocKnot 4.00;
use 5.024;
use autodie;
@@ -35,7 +35,6 @@ use Perl6::Slurp;
# We therefore try File::BaseDir first (which handles the XDG paths) and fall
# back on using File::ShareDir to locate the data.
#
-# $self - The App::DocKnot object
# @path - The relative path of the file as a list of components
#
# Returns: The absolute path to the application data
@@ -57,7 +56,6 @@ sub appdata_path {
# and returns the resulting decoded contents. This uses the relaxed parsing
# mode, so comments and commas after data elements are supported.
#
-# $self - The App::DocKnot object
# @path - The path of the file to load, as a list of components
#
# Returns: Anonymous hash or array resulting from decoding the JSON object
diff --git a/lib/App/DocKnot/Command.pm b/lib/App/DocKnot/Command.pm
index beec39e..db5ac96 100644
--- a/lib/App/DocKnot/Command.pm
+++ b/lib/App/DocKnot/Command.pm
@@ -10,7 +10,7 @@
# Modules and declarations
##############################################################################
-package App::DocKnot::Command 3.05;
+package App::DocKnot::Command 4.00;
use 5.024;
use autodie;
@@ -18,6 +18,7 @@ use warnings;
use App::DocKnot::Dist;
use App::DocKnot::Generate;
+use App::DocKnot::Update;
use Getopt::Long;
# Defines the subcommands, their options, and the module and method that
@@ -74,6 +75,12 @@ our %COMMANDS = (
options => ['metadata|m=s', 'width|w=i'],
maximum => 0,
},
+ update => {
+ method => 'update',
+ module => 'App::DocKnot::Update',
+ options => ['metadata|m=s', 'output|o=s'],
+ maximum => 0,
+ },
);
##############################################################################
@@ -82,7 +89,6 @@ our %COMMANDS = (
# Parse command-line options and do any required error handling.
#
-# $self - The App::DocKnot::Command object
# $command - The command being run or undef for top-level options
# $options_ref - A reference to the options specification
# @args - The arguments to the command
@@ -123,7 +129,6 @@ sub _parse_options {
# Parse command-line options for a given command.
#
-# $self - The App::DocKnot::Command object
# $command - The command being run
# @args - The arguments to the command
#
@@ -143,8 +148,6 @@ sub _parse_command {
# Create a new App::DocKnot::Command object.
#
-# $class - Class of object to create
-#
# Returns: Newly created object
sub new {
my ($class) = @_;
@@ -156,7 +159,6 @@ sub new {
# Parse command-line options to determine which command to run, and then
# dispatch that command.
#
-# $self - The App::DocKnot::Command object
# @args - Command-line arguments (optional, default: @ARGV)
#
# Returns: undef
@@ -206,13 +208,9 @@ sub run {
# Dispatch the command and turn exceptions into error messages.
eval {
- if ($COMMANDS{$command}{code}) {
- $COMMANDS{$command}{code}->($opts_ref, $args_ref->@*);
- } else {
- my $object = $COMMANDS{$command}{module}->new($opts_ref);
- my $method = $COMMANDS{$command}{method};
- $object->$method($args_ref->@*);
- }
+ my $object = $COMMANDS{$command}{module}->new($opts_ref);
+ my $method = $COMMANDS{$command}{method};
+ $object->$method($args_ref->@*);
};
if ($@) {
my $error = $@;
@@ -285,7 +283,7 @@ Russ Allbery <rra@cpan.org>
=head1 COPYRIGHT AND LICENSE
-Copyright 2018-2019 Russ Allbery <rra@cpan.org>
+Copyright 2018-2020 Russ Allbery <rra@cpan.org>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/lib/App/DocKnot/Config.pm b/lib/App/DocKnot/Config.pm
index 8ecb86f..74b2148 100644
--- a/lib/App/DocKnot/Config.pm
+++ b/lib/App/DocKnot/Config.pm
@@ -9,7 +9,7 @@
# Modules and declarations
##############################################################################
-package App::DocKnot::Config 3.05;
+package App::DocKnot::Config 4.00;
use 5.024;
use autodie;
@@ -18,71 +18,8 @@ use warnings;
use Carp qw(croak);
use File::Spec;
-use JSON::MaybeXS qw(JSON);
-use Perl6::Slurp;
-
-# Additional files to load from the metadata directory if they exist. The
-# contents of these files will be added to the configuration in a key of the
-# same name. If the key contains a slash, like foo/bar, it will be stored as
-# a nested hash, as $data{foo}{bar}.
-our @METADATA_FILES = qw(
- bootstrap
- build/middle
- build/suffix
- debian/summary
- packaging/extra
- support/extra
- test/prefix
- test/suffix
-);
-
-##############################################################################
-# Helper methods
-##############################################################################
-
-# Internal helper routine to return the path of a file or directory from the
-# package metadata directory. The resulting file or directory path is not
-# checked for existence.
-#
-# $self - The App::DocKnot::Generate object
-# @path - The relative path of the file as a list of components
-#
-# Returns: The absolute path in the metadata directory
-sub _metadata_path {
- my ($self, @path) = @_;
- return File::Spec->catdir($self->{metadata}, @path);
-}
-
-# Internal helper routine to read a file from the package metadata directory
-# and return the contents. The file is specified as a list of path
-# components.
-#
-# $self - The App::DocKnot::Generate object
-# @path - The path of the file to load, as a list of components
-#
-# Returns: The contents of the file as a string
-# Throws: slurp exception on failure to read the file
-sub _load_metadata {
- my ($self, @path) = @_;
- return slurp($self->_metadata_path(@path));
-}
-
-# Like _load_metadata, but interprets the contents of the metadata file as
-# JSON and decodes it, returning the resulting object. This uses the relaxed
-# parsing mode, so comments and commas after data elements are supported.
-#
-# $self - The App::DocKnot::Generate object
-# @path - The path of the file to load, as a list of components
-#
-# Returns: Anonymous hash or array resulting from decoding the JSON object
-# Throws: slurp or JSON exception on failure to load or decode the object
-sub _load_metadata_json {
- my ($self, @path) = @_;
- my $data = $self->_load_metadata(@path);
- my $json = JSON->new;
- $json->relaxed;
- return $json->decode($data);
-}
+use Kwalify qw(validate);
+use YAML::XS ();
##############################################################################
# Public Interface
@@ -91,9 +28,8 @@ sub _load_metadata_json {
# Create a new App::DocKnot::Config object, which will be used for subsequent
# calls.
#
-# $class - Class of object to create
# $args - Anonymous hash of arguments with the following keys:
-# metadata - Path to the directory containing package metadata
+# metadata - Path to the docknot.yaml file
#
# Returns: Newly created object
# Throws: Text exceptions on invalid metadata directory path
@@ -101,12 +37,9 @@ sub new {
my ($class, $args_ref) = @_;
# Ensure we were given a valid metadata argument.
- my $metadata = $args_ref->{metadata};
- if (!defined($metadata)) {
- $metadata = 'docs/metadata';
- }
- if (!-d $metadata) {
- croak("metadata path $metadata does not exist or is not a directory");
+ my $metadata = $args_ref->{metadata} // 'docs/docknot.yaml';
+ if (!-e $metadata) {
+ croak("metadata path $metadata does not exist");
}
# Create and return the object.
@@ -117,86 +50,51 @@ sub new {
# Load the DocKnot package configuration.
#
-# $self - The App::DocKnot::Config object
-#
# Returns: The package configuration as a dict
-# Throws: autodie exception on failure to read metadata
+# Throws: YAML::XS exception on invalid package metadata
+# Text exception on schema mismatch for package metadata
# Text exception on inconsistencies in the package data
sub config {
my ($self) = @_;
- # Localize $@ since we catch and ignore a lot of exceptions and don't want
- # to leak changes to $@ to the caller.
- local $@ = q{};
-
- # Load the package metadata from JSON.
- my $data_ref = $self->_load_metadata_json('metadata.json');
+ # Tell YAML::XS to use real booleans. Otherwise, Kwalify is unhappy with
+ # data elements set to false.
+ local $YAML::XS::Boolean = 'JSON::PP';
+
+ # Load the metadata and check it against the schema.
+ my $data_ref = YAML::XS::LoadFile($self->{metadata});
+ my $schema_path = $self->appdata_path('schema/docknot.yaml');
+ my $schema_ref = YAML::XS::LoadFile($schema_path);
+ eval { validate($schema_ref, $data_ref) };
+ if ($@) {
+ my $errors = $@;
+ chomp($errors);
+ die "Schema validation for $self->{metadata} failed:\n$errors\n";
+ }
# build.install defaults to true.
if (!exists($data_ref->{build}{install})) {
$data_ref->{build}{install} = 1;
}
- # Load supplemental README sections. readme.sections will contain a list
- # of sections to add to the README file.
- for my $section ($data_ref->{readme}{sections}->@*) {
- my $title = $section->{title};
-
- # The file containing the section data will match the title, converted
- # to lowercase and with spaces changed to dashes.
- my $file = lc($title);
- $file =~ tr{ }{-};
-
- # Load the section content.
- $section->{body} = $self->_load_metadata('sections', $file);
-
- # If this contains a testing section, that overrides our default. Set
- # a flag so that the templates know this has happened.
- if ($file eq 'testing') {
+ # Set a flag indicating whether the testing section was overridden. This
+ # is easier for templates to check.
+ for my $section_ref ($data_ref->{readme}{sections}->@*) {
+ if (lc($section_ref->{title}) eq 'testing') {
$data_ref->{readme}{testing} = 1;
+ last;
}
}
- # If the package is marked orphaned, load the explanation.
- if ($data_ref->{orphaned}) {
- $data_ref->{orphaned} = $self->_load_metadata('orphaned');
- }
-
- # If the package has a quote, load the text of the quote.
- if ($data_ref->{quote}) {
- $data_ref->{quote}{text} = $self->_load_metadata('quote');
- }
-
# Expand the package license into license text.
- my $license = $data_ref->{license};
- my $licenses_ref = $self->load_appdata_json('licenses.json');
+ my $license = $data_ref->{license}{name};
+ my $licenses_path = $self->appdata_path('licenses.yaml');
+ my $licenses_ref = YAML::XS::LoadFile($licenses_path);
if (!exists($licenses_ref->{$license})) {
die "Unknown license $license\n";
}
- my $license_text = slurp($self->appdata_path('licenses', $license));
- $data_ref->{license} = { $licenses_ref->{$license}->%* };
- $data_ref->{license}{full} = $license_text;
-
- # Load additional license notices if they exist.
- eval { $data_ref->{license}{notices} = $self->_load_metadata('notices') };
-
- # Load the standard sections.
- $data_ref->{blurb} = $self->_load_metadata('blurb');
- $data_ref->{description} = $self->_load_metadata('description');
- $data_ref->{requirements} = $self->_load_metadata('requirements');
-
- # Load optional information if it exists.
- for my $file (@METADATA_FILES) {
- my @file = split(m{/}xms, $file);
- if (scalar(@file) == 1) {
- eval { $data_ref->{$file} = $self->_load_metadata(@file) };
- } else {
- eval {
- $data_ref->{ $file[0] }{ $file[1] }
- = $self->_load_metadata(@file);
- };
- }
- }
+ $data_ref->{license}{summary} = $licenses_ref->{$license}{summary};
+ $data_ref->{license}{text} = $licenses_ref->{$license}{text};
# Return the resulting configuration.
return $data_ref;
@@ -210,7 +108,7 @@ sub config {
__END__
=for stopwords
-Allbery DocKnot MERCHANTABILITY NONINFRINGEMENT sublicense CPAN XDG
+Allbery DocKnot MERCHANTABILITY NONINFRINGEMENT sublicense CPAN XDG Kwalify
=head1 NAME
@@ -219,13 +117,13 @@ App::DocKnot::Config - Read and return DocKnot package configuration
=head1 SYNOPSIS
use App::DocKnot::Config;
- my $reader = App::DocKnot::Config->new({ metadata => 'docs/metadata' });
+ my $reader = App::DocKnot::Config->new({ metadata => 'docs/docknot.yaml' });
my $config = $reader->config();
=head1 REQUIREMENTS
-Perl 5.24 or later and the modules File::BaseDir, File::ShareDir, JSON, and
-Perl6::Slurp, all of which are available from CPAN.
+Perl 5.24 or later and the modules File::BaseDir, File::ShareDir, Kwalify, and
+YAML::XS, all of which are available from CPAN.
=head1 DESCRIPTION
@@ -253,8 +151,8 @@ Files included in the package.
=back
-Default license metadata files are included with the App::DocKnot module and
-are used unless more specific configuration files exist.
+Default license metadata is included with the App::DocKnot module and is used
+unless more specific configuration files exist.
=head1 CLASS METHODS
@@ -270,8 +168,8 @@ following keys:
=item metadata
-The path to the directory containing metadata for a package. Default:
-F<docs/metadata> relative to the current directory.
+The path to the metadata for a package. Default: F<docs/docknot.yaml>
+relative to the current directory.
=back
diff --git a/lib/App/DocKnot/Dist.pm b/lib/App/DocKnot/Dist.pm
index 7758a82..965d217 100644
--- a/lib/App/DocKnot/Dist.pm
+++ b/lib/App/DocKnot/Dist.pm
@@ -10,7 +10,7 @@
# Modules and declarations
##############################################################################
-package App::DocKnot::Dist 3.05;
+package App::DocKnot::Dist 4.00;
use 5.024;
use autodie;
@@ -94,7 +94,6 @@ our @DIST_IGNORE = (
# Given the path to the source tree, generate a list of files that we expect
# to find in the distribution tarball.
#
-# $self - The App::DocKnot::Dist object
# $path - The directory path
#
# Returns: A list of files (no directories) that the distribution tarball
@@ -131,7 +130,6 @@ sub _expected_dist_files {
# Find the tarball compressed with gzip given a directory and a prefix.
#
-# $self - The App::DocKnot::Dist object
# $path - The directory path
# $prefix - The tarball file prefix
#
@@ -149,7 +147,6 @@ sub _find_gzip_tarball {
# Find matching tarballs given a directory and a prefix.
#
-# $self - The App::DocKnot::Dist object
# $path - The directory path
# $prefix - The tarball file prefix
#
@@ -167,7 +164,6 @@ sub _find_matching_tarballs {
# all the desired compression formats exist. Currently this only handles
# generating the xz version of a gzip tarball.
#
-# $self - The App::DocKnot::Dist object
# $path - The directory path
# $prefix - The tarball file prefix
#
@@ -201,7 +197,6 @@ sub _generate_compression_formats {
# signatures), and a destination directory, move all matching files from the
# source directory to the destination directory.
#
-# $self - The App::DocKnot::Dist object
# $source_path - The source directory path
# $prefix - The tarball file prefix
# $dest_path - The destination directory path
@@ -223,7 +218,6 @@ sub _move_tarballs {
# configured path to Perl, if any. Assumes that the perl configuration
# parameter is set in the object and should not be called if this is not true.
#
-# $self - The App::DocKnot::Dist object
# $command_ref - Reference to an array representing a command with arguments
#
# Returns: Reference to an array representing a command with arguments, with
@@ -246,7 +240,6 @@ sub _replace_perl_path {
# Create a new App::DocKnot::Dist object, which will be used for subsequent
# calls.
#
-# $class - Class of object to create
# $args - Anonymous hash of arguments with the following keys:
# distdir - Path to the directory for distribution tarball
# metadata - Path to the directory containing package metadata
@@ -288,7 +281,6 @@ sub new {
# distribution tarball. Assumes that it is run from the root of the source
# directory.
#
-# $self - The App::DocKnot::Dist object
# $source - Path to the source directory
# $tarball - Path to a gzip-compressed distribution tarball
#
@@ -310,8 +302,6 @@ sub check_dist {
# Analyze a source directory and return the list of commands to run to
# generate a distribution tarball.
#
-# $self - The App::DocKnot::Dist object
-#
# Returns: List of commands, each of which is a list of strings representing
# a command and its arguments
sub commands {
@@ -354,8 +344,6 @@ sub commands {
# exports the Git repository, runs the commands to generate the tarball, and
# then removes the working tree.
#
-# $self - The App::DocKnot::Dist object
-#
# Throws: Text exception if any of the commands fail
# Text exception if the distribution is missing files
sub make_distribution {
diff --git a/lib/App/DocKnot/Generate.pm b/lib/App/DocKnot/Generate.pm
index 53e6fed..cc55b12 100644
--- a/lib/App/DocKnot/Generate.pm
+++ b/lib/App/DocKnot/Generate.pm
@@ -10,7 +10,7 @@
# Modules and declarations
##############################################################################
-package App::DocKnot::Generate 3.05;
+package App::DocKnot::Generate 4.00;
use 5.024;
use autodie;
@@ -19,6 +19,7 @@ use warnings;
use App::DocKnot::Config;
use Carp qw(croak);
+use Encode qw(encode);
use Template;
use Text::Wrap qw(wrap);
@@ -41,8 +42,6 @@ my %DEFAULT_OUTPUT = (
# the line. The returned code will take a line of text and return that line
# with leading whitespace added as required.
#
-# $self - The App::DocKnot::Generate object
-#
# Returns: Code reference to a closure that uses $self->{width} for width
sub _code_for_center {
my ($self) = @_;
@@ -64,7 +63,6 @@ sub _code_for_center {
# They will be wrapped with a four-space outdent and kept within
# $self->{width} columns.
#
-# $self - The App::DocKnot::Generate object
# $copyrights_ref - A reference to a list of anonymous hashes, each with keys:
# holder - The copyright holder for that copyright
# years - The years of that copyright
@@ -114,8 +112,6 @@ sub _code_for_copyright {
# doesn't use any configuration. It takes the indentation and an optional
# prefix to put at the start of each line.
#
-# $self - The App::DocKnot::Generate object
-#
# Returns: Code reference to a closure
sub _code_for_indent {
my ($self) = @_;
@@ -136,8 +132,6 @@ sub _code_for_indent {
# be influenced by App::DocKnot configuration in the future, but it currently
# doesn't use any configuration.
#
-# $self - The App::DocKnot::Generate object
-#
# Returns: Code reference to a closure that takes a block of text and returns
# the converted text
sub _code_for_to_text {
@@ -209,8 +203,6 @@ sub _code_for_to_text {
# be influenced by App::DocKnot configuration in the future, but it currently
# doesn't use any configuration.
#
-# $self - The App::DocKnot::Generate object
-#
# Returns: Code reference to a closure that takes a block of text and returns
# the converted thread
sub _code_for_to_thread {
@@ -310,56 +302,77 @@ sub _code_for_to_thread {
# four spaces and consistently on each line, remove the indentation and then
# add it back in while wrapping the text.
#
-# $self - The App::DocKnot::Generate object
-# $paragraph - A paragraph of text to wrap
+# $para - A paragraph of text to wrap
+# $options_ref - Options to controll the wrapping
+# ignore_indent - Ignore indentation when choosing whether to wrap
#
# Returns: The wrapped paragraph
sub _wrap_paragraph {
- my ($self, $paragraph) = @_;
- my ($indent) = ($paragraph =~ m{ \A ([ ]*) \S }xms);
-
- # If the indent is longer than four characters, leave it alone.
- if (length($indent) > 4) {
- return $paragraph;
+ my ($self, $para, $options_ref) = @_;
+ $options_ref //= {};
+ my ($indent) = ($para =~ m{ \A ([ ]*) \S }xms);
+
+ # If the indent is longer than five characters and the ignore indent
+ # option is not set, leave it alone. Allow an indent of five characters
+ # since it may be a continuation of a numbered list entry.
+ if (length($indent) > 5 && !$options_ref->{ignore_indent}) {
+ return $para;
}
# If this looks like thread commands or URLs, leave it alone.
- if ($paragraph =~ m{ \A \s* (?: \\ | \[\d+\] ) }xms) {
- return $paragraph;
+ if ($para =~ m{ \A \s* (?: \\ | \[\d+\] ) }xms) {
+ return $para;
}
# If this starts with a bullet, strip the bullet off, wrap the paragraph,
# and then add it back in.
- if ($paragraph =~ s{ \A (\s*) [*] (\s+) }{$1 $2}xms) {
+ if ($para =~ s{ \A (\s*) [*] (\s+) }{$1 $2}xms) {
my $offset = length($1);
- $paragraph = $self->_wrap_paragraph($paragraph);
- substr($paragraph, $offset, 1, q{*});
- return $paragraph;
+ $para = $self->_wrap_paragraph($para, { ignore_indent => 1 });
+ substr($para, $offset, 1, q{*});
+ return $para;
}
- # If this looks like a Markdown block quote leave it alone, but strip
- # trailing whitespace.
- if ($paragraph =~ m{ \A \s* > \s }xms) {
- $paragraph =~ s{ [ ]+ \n }{\n}xmsg;
- return $paragraph;
+ # If this starts with a number, strip the number off, wrap the paragraph,
+ # and then add it back in.
+ if ($para =~ s{\A (\s*) (\d+[.]) (\s+)}{$1 . q{ } x length($2) . $3}xmse) {
+ my $offset = length($1);
+ my $number = $2;
+ $para = $self->_wrap_paragraph($para, { ignore_indent => 1 });
+ substr($para, $offset, length($number), $number);
+ return $para;
+ }
+
+ # If this looks like a Markdown block quote, strip trailing whitespace,
+ # remove the leading indentation marks, wrap the paragraph, and then put
+ # them back.
+ ## no critic (RegularExpressions::ProhibitCaptureWithoutTest)
+ if ($para =~ m{ \A (\s*) > \s }xms) {
+ $para =~ s{ [ ]+ \n }{\n}xmsg;
+ $para =~ s{ ^ (\s*) > (\s) }{$1 $2}xmsg;
+ my $offset = length($1);
+ $para = $self->_wrap_paragraph($para, { ignore_indent => 1 });
+ $para =~ s{ ^ (\s{$offset}) \s }{$1>}xmsg;
+ return $para;
}
+ ## use critic
# If this looks like a bunch of short lines, leave it alone.
- if ($paragraph =~ m{ \A (?: \Q$indent\E [^\n]{1,45} \n ){3,} }xms) {
- return $paragraph;
+ if ($para =~ m{ \A (?: \Q$indent\E [^\n]{1,45} \n ){3,} }xms) {
+ return $para;
}
# If this paragraph is not consistently indented, leave it alone.
- if ($paragraph !~ m{ \A (?: \Q$indent\E \S[^\n]+ \n )+ \z }xms) {
- return $paragraph;
+ if ($para !~ m{ \A (?: \Q$indent\E \S[^\n]+ \n )+ \z }xms) {
+ return $para;
}
# Strip the indent from each line.
- $paragraph =~ s{ (?: \A | (?<=\n) ) \Q$indent\E }{}xmsg;
+ $para =~ s{ (?: \A | (?<=\n) ) \Q$indent\E }{}xmsg;
# Remove any existing newlines, preserving two spaces after periods.
- $paragraph =~ s{ [.] ([)\"]?) \n (\S) }{.$1 $2}xmsg;
- $paragraph =~ s{ \n(\S) }{ $1}xmsg;
+ $para =~ s{ [.] ([)\"]?) \n (\S) }{.$1 $2}xmsg;
+ $para =~ s{ \n(\S) }{ $1}xmsg;
# Force locally correct configuration of Text::Wrap.
local $Text::Wrap::break = qr{\s+}xms;
@@ -368,21 +381,20 @@ sub _wrap_paragraph {
local $Text::Wrap::unexpand = 0;
# Do the wrapping. This modifies @paragraphs in place.
- $paragraph = wrap($indent, $indent, $paragraph);
+ $para = wrap($indent, $indent, $para);
# Strip any trailing whitespace, since some gets left behind after periods
# by Text::Wrap.
- $paragraph =~ s{ [ ]+ \n }{\n}xmsg;
+ $para =~ s{ [ ]+ \n }{\n}xmsg;
# All done.
- return $paragraph;
+ return $para;
}
# Word-wrap a block of text. This requires some annoying heuristics, but the
# alternative is to try to get the template to always produce correctly
# wrapped results, which is far harder.
#
-# $self - The App::DocKnot::Generate object
# $text - The text to wrap
#
# Returns: The wrapped text
@@ -416,7 +428,6 @@ sub _wrap {
# Create a new App::DocKnot::Generate object, which will be used for
# subsequent calls.
#
-# $class - Class of object to create
# $args - Anonymous hash of arguments with the following keys:
# metadata - Path to the directory containing package metadata
# width - Line length at which to wrap output files
@@ -444,7 +455,6 @@ sub new {
# Generate a documentation file from the package metadata.
#
-# $self - The App::DocKnot::Generate object
# $template - Name of the documentation template (using Template Toolkit)
#
# Returns: The generated documentation as a string
@@ -483,8 +493,6 @@ sub generate {
# Generate all package documentation from the package metadata. Only
# generates the output for templates with a default output file.
#
-# $self - The App::DocKnot::Generate object
-#
# Returns: undef
# Throws: autodie exception on failure to read metadata or write the output
# Text exception on Template Toolkit failures
@@ -499,7 +507,6 @@ sub generate_all {
# Generate a documentation file from the package metadata.
#
-# $self - The App::DocKnot::Generate object
# $template - Name of the documentation template
# $output - Output file name (undef to use the default)
#
@@ -518,7 +525,7 @@ sub generate_output {
# Generate the output.
open(my $outfh, '>', $output);
- print {$outfh} $self->generate($template)
+ print {$outfh} encode('utf-8', $self->generate($template))
or croak("cannot write to $output: $!");
close($outfh);
return;
diff --git a/lib/App/DocKnot/Update.pm b/lib/App/DocKnot/Update.pm
new file mode 100644
index 0000000..b76accc
--- /dev/null
+++ b/lib/App/DocKnot/Update.pm
@@ -0,0 +1,391 @@
+# Update package configuration for a DocKnot version upgrade.
+#
+# Adjusts the DocKnot configuration data for changes in format for newer
+# versions of DocKnot.
+#
+# SPDX-License-Identifier: MIT
+
+##############################################################################
+# Modules and declarations
+##############################################################################
+
+package App::DocKnot::Update 4.00;
+
+use 5.024;
+use autodie;
+use parent qw(App::DocKnot);
+use warnings;
+
+use Carp qw(croak);
+use File::Spec;
+use JSON::MaybeXS qw(JSON);
+use Kwalify qw(validate);
+use Perl6::Slurp;
+use YAML::XS ();
+
+# The older JSON metadata format stored text snippets in separate files in the
+# file system. This is the list of additional files to load from the metadata
+# directory if they exist. The contents of these files will be added to the
+# configuration in a key of the same name. If the key contains a slash, like
+# foo/bar, it will be stored as a nested hash, as $data{foo}{bar}.
+our @JSON_METADATA_FILES = qw(
+ bootstrap
+ build/middle
+ build/suffix
+ debian/summary
+ packaging/extra
+ support/extra
+ test/prefix
+ test/suffix
+);
+
+##############################################################################
+# JSON helper methods
+##############################################################################
+
+# Internal helper routine to return the path of a file or directory from the
+# package metadata directory. The resulting file or directory path is not
+# checked for existence.
+#
+# @path - The relative path of the file as a list of components
+#
+# Returns: The absolute path in the metadata directory
+sub _metadata_path {
+ my ($self, @path) = @_;
+ return File::Spec->catdir($self->{metadata}, @path);
+}
+
+# Internal helper routine to read a file from the package metadata directory
+# and return the contents. The file is specified as a list of path
+# components.
+#
+# @path - The path of the file to load, as a list of components
+#
+# Returns: The contents of the file as a string
+# Throws: slurp exception on failure to read the file
+sub _load_metadata {
+ my ($self, @path) = @_;
+ return slurp('<:utf8', $self->_metadata_path(@path));
+}
+
+# Like _load_metadata, but interprets the contents of the metadata file as
+# JSON and decodes it, returning the resulting object. This uses the relaxed
+# parsing mode, so comments and commas after data elements are supported.
+#
+# @path - The path of the file to load, as a list of components
+#
+# Returns: Anonymous hash or array resulting from decoding the JSON object
+# Throws: slurp or JSON exception on failure to load or decode the object
+sub _load_metadata_json {
+ my ($self, @path) = @_;
+ my $data = $self->_load_metadata(@path);
+ my $json = JSON->new;
+ $json->relaxed;
+ return $json->decode($data);
+}
+
+# Load the legacy JSON DocKnot package configuration.
+#
+# Returns: The package configuration as a dict
+# Throws: autodie exception on failure to read metadata
+# Text exception on inconsistencies in the package data
+sub _config_from_json {
+ my ($self) = @_;
+
+ # Localize $@ since we catch and ignore a lot of exceptions and don't want
+ # to leak changes to $@ to the caller.
+ local $@ = q{};
+
+ # Load the package metadata from JSON.
+ my $data_ref = $self->_load_metadata_json('metadata.json');
+
+ # Load supplemental README sections. readme.sections will contain a list
+ # of sections to add to the README file.
+ for my $section_ref ($data_ref->{readme}{sections}->@*) {
+ my $title = $section_ref->{title};
+
+ # The file containing the section data will match the title, converted
+ # to lowercase and with spaces changed to dashes.
+ my $file = lc($title);
+ $file =~ tr{ }{-};
+
+ # Load the section content.
+ $section_ref->{body} = $self->_load_metadata('sections', $file);
+ }
+
+ # If there are no supplemental README sections, remove that data element.
+ if (!$data_ref->{readme}{sections}->@*) {
+ delete($data_ref->{readme});
+ }
+
+ # If the package is marked orphaned, load the explanation.
+ if ($data_ref->{orphaned}) {
+ $data_ref->{orphaned} = $self->_load_metadata('orphaned');
+ }
+
+ # If the package has a quote, load the text of the quote.
+ if ($data_ref->{quote}) {
+ $data_ref->{quote}{text} = $self->_load_metadata('quote');
+ }
+
+ # Move the name of the license to its new metadata key.
+ my $license = $data_ref->{license};
+ $data_ref->{license} = { name => $license };
+
+ # Load additional license notices if they exist.
+ eval { $data_ref->{license}{notices} = $self->_load_metadata('notices') };
+
+ # Load the standard sections.
+ $data_ref->{blurb} = $self->_load_metadata('blurb');
+ $data_ref->{description} = $self->_load_metadata('description');
+ $data_ref->{requirements} = $self->_load_metadata('requirements');
+
+ # Load optional information if it exists.
+ for my $file (@JSON_METADATA_FILES) {
+ my @file = split(m{/}xms, $file);
+ if (scalar(@file) == 1) {
+ eval { $data_ref->{$file} = $self->_load_metadata(@file) };
+ } else {
+ eval {
+ $data_ref->{ $file[0] }{ $file[1] }
+ = $self->_load_metadata(@file);
+ };
+ }
+ }
+
+ # Return the resulting configuration.
+ return $data_ref;
+}
+
+##############################################################################
+# Public Interface
+##############################################################################
+
+# Create a new App::DocKnot::Update object, which will be used for subsequent
+# calls.
+#
+# $args - Anonymous hash of arguments with the following keys:
+# metadata - Path to the directory containing package metadata
+# output - Path to the output file with the converted metadata
+#
+# Returns: Newly created object
+# Throws: Text exceptions on invalid metadata directory path
+sub new {
+ my ($class, $args_ref) = @_;
+
+ # Ensure we were given a valid metadata argument.
+ my $metadata = $args_ref->{metadata} // 'docs/metadata';
+ if (!-d $metadata) {
+ croak("metadata path $metadata does not exist or is not a directory");
+ }
+
+ # Create and return the object.
+ my $self = {
+ metadata => $metadata,
+ output => $args_ref->{output} // 'docs/docknot.yaml',
+ };
+ bless($self, $class);
+ return $self;
+}
+
+# Update an older version of DocKnot configuration. Currently, this only
+# handles the old JSON format.
+#
+# Raises: autodie exception on failure to read metadata
+# Text exception on inconsistencies in the package data
+# Text exception if schema checking failed on the converted config
+sub update {
+ my ($self) = @_;
+
+ # Tell YAML::XS that we'll be feeding it JSON::PP booleans.
+ local $YAML::XS::Boolean = 'JSON::PP';
+
+ # Load the config.
+ my $data_ref = $self->_config_from_json();
+
+ # Add the current format version.
+ $data_ref->{format} = 'v1';
+
+ # Move bootstrap to build.bootstrap.
+ if (defined($data_ref->{bootstrap})) {
+ $data_ref->{build}{bootstrap} = $data_ref->{bootstrap};
+ delete $data_ref->{bootstrap};
+ }
+
+ # Move build.lancaster to test.lancaster.
+ if (defined($data_ref->{build}{lancaster})) {
+ $data_ref->{test}{lancaster} = $data_ref->{build}{lancaster};
+ delete $data_ref->{build}{lancaster};
+ }
+
+ # Move packaging.debian to packaging.debian.package, move debian to
+ # packaging.debian, and move packaging to distribution.packaging.
+ if (defined($data_ref->{packaging})) {
+ if (defined($data_ref->{packaging}{debian})) {
+ my $package = $data_ref->{packaging}{debian};
+ $data_ref->{packaging}{debian} = { package => $package };
+ }
+ }
+ if (defined($data_ref->{debian})) {
+ $data_ref->{packaging}{debian} //= {};
+ $data_ref->{packaging}{debian}
+ = { $data_ref->{debian}->%*, $data_ref->{packaging}{debian}->%* };
+ delete $data_ref->{debian};
+ }
+ if ($data_ref->{packaging}) {
+ $data_ref->{distribution}{packaging} = $data_ref->{packaging};
+ delete $data_ref->{packaging};
+ }
+
+ # Move readme.sections to sections. If there was a testing override, move
+ # it to test.override and delete it from sections.
+ if (defined($data_ref->{readme})) {
+ $data_ref->{sections} = $data_ref->{readme}{sections};
+ delete $data_ref->{readme};
+ for my $section_ref ($data_ref->{sections}->@*) {
+ if (lc($section_ref->{title}) eq 'testing') {
+ $data_ref->{test}{override} = $section_ref->{body};
+ last;
+ }
+ }
+ $data_ref->{sections}
+ = [grep { lc($_->{title}) ne 'testing' } $data_ref->{sections}->@*];
+ }
+
+ # support.cpan is obsolete. If vcs.github is set and support.github is
+ # not, use it as support.github.
+ if (defined($data_ref->{support}{cpan})) {
+ if (!defined($data_ref->{support}{github})) {
+ if (defined($data_ref->{vcs}{github})) {
+ $data_ref->{support}{github} = $data_ref->{vcs}{github};
+ }
+ }
+ delete $data_ref->{support}{cpan};
+ }
+
+ # Check the schema of the resulting file.
+ my $schema_path = $self->appdata_path('schema/docknot.yaml');
+ my $schema_ref = YAML::XS::LoadFile($schema_path);
+ eval { validate($schema_ref, $data_ref) };
+ if ($@) {
+ my $errors = $@;
+ chomp($errors);
+ die "Schema validation failed:\n$errors\n";
+ }
+
+ # Write the new YAML package configuration.
+ YAML::XS::DumpFile($self->{output}, $data_ref);
+ return;
+}
+
+##############################################################################
+# Module return value and documentation
+##############################################################################
+
+1;
+__END__
+
+=for stopwords
+Allbery DocKnot MERCHANTABILITY NONINFRINGEMENT sublicense CPAN XDG
+
+=head1 NAME
+
+App::DocKnot::Update - Update DocKnot package configuration for new formats
+
+=head1 SYNOPSIS
+
+ use App::DocKnot::Update;
+ my $reader = App::DocKnot::Update->new(
+ {
+ metadata => 'docs/metadata',
+ output => 'docs/docknot.yaml',
+ }
+ );
+ my $config = $reader->update();
+
+=head1 REQUIREMENTS
+
+Perl 5.24 or later and the modules File::BaseDir, File::ShareDir, JSON,
+Perl6::Slurp, and YAML::XS, all of which are available from CPAN.
+
+=head1 DESCRIPTION
+
+This component of DocKnot updates package configuration from older versions.
+Currently, its main purpose is to convert from the JSON format used prior to
+DocKnot 4.0 to the current YAML syntax.
+
+=head1 CLASS METHODS
+
+=over 4
+
+=item new(ARGS)
+
+Create a new App::DocKnot::Update object. This should be used for all
+subsequent actions. ARGS should be a hash reference with one or more of the
+following keys:
+
+=over 4
+
+=item metadata
+
+The path to the directory containing the legacy JSON metadata for a package.
+Default: F<docs/metadata> relative to the current directory.
+
+=item output
+
+The path to which to write the new YAML configuration. Default:
+F<docs/docknot.yaml> relative to the current directory.
+
+=back
+
+=back
+
+=head1 INSTANCE METHODS
+
+=over 4
+
+=item update()
+
+Load the legacy JSON metadata and write out the YAML equivalent.
+
+=back
+
+=head1 AUTHOR
+
+Russ Allbery <rra@cpan.org>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright 2013-2020 Russ Allbery <rra@cpan.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+=head1 SEE ALSO
+
+L<docknot(1)>
+
+This module is part of the App-DocKnot distribution. The current version of
+App::DocKnot is available from CPAN, or directly from its web site at
+L<https://www.eyrie.org/~eagle/software/docknot/>.
+
+=cut
+
+# Local Variables:
+# copyright-at-end-flag: t
+# End:
diff --git a/share/licenses.json b/share/licenses.json
deleted file mode 100644
index 9fb67bf..0000000
--- a/share/licenses.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "BSD-3-clause-or-GPL-1+": {
- "summary": "a BSD-style license",
- },
- "Expat": {
- "summary": "a BSD-style license",
- },
- "Perl": {
- "summary": "the same terms as Perl itself",
- },
-}
diff --git a/share/licenses.yaml b/share/licenses.yaml
new file mode 100644
index 0000000..c7a9bfc
--- /dev/null
+++ b/share/licenses.yaml
@@ -0,0 +1,70 @@
+# License metadata for DocKnot.
+#
+# Copyright 2013, 2016-2017, 2020 Russ Allbery <rra@cpan.org>
+#
+# SPDX-License-Identifier: MIT
+
+BSD-3-clause-or-GPL-1+:
+ summary: a BSD-style license
+ text: |
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, and the entire permission notice in its entirety, including
+ the disclaimer of warranties.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ 3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ ALTERNATIVELY, this product may be distributed under the terms of the GNU
+ General Public License, in which case the provisions of the GPL are
+ required INSTEAD OF the above restrictions. (This clause is necessary due
+ to a potential bad interaction between the GPL and the restrictions
+ contained in a BSD-style copyright.)
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Expat:
+ summary: a BSD-style license
+ text: |
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+
+Perl:
+ summary: the same terms as Perl itself
+ text: |
+ This program is free software; you may redistribute it and/or modify it
+ under the same terms as Perl itself. This means that you may choose
+ between the two licenses that Perl is released under: the GNU GPL and the
+ Artistic License. Please see your Perl distribution for the details and
+ copies of the licenses.
diff --git a/share/licenses/BSD-3-clause-or-GPL-1+ b/share/licenses/BSD-3-clause-or-GPL-1+
deleted file mode 100644
index 5eadfd0..0000000
--- a/share/licenses/BSD-3-clause-or-GPL-1+
+++ /dev/null
@@ -1,31 +0,0 @@
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-1. Redistributions of source code must retain the above copyright
- notice, and the entire permission notice in its entirety, including
- the disclaimer of warranties.
-
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-3. The name of the author may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-ALTERNATIVELY, this product may be distributed under the terms of the GNU
-General Public License, in which case the provisions of the GPL are
-required INSTEAD OF the above restrictions. (This clause is necessary due
-to a potential bad interaction between the GPL and the restrictions
-contained in a BSD-style copyright.)
-
-THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
-THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/share/licenses/Expat b/share/licenses/Expat
deleted file mode 100644
index 1e4a5f8..0000000
--- a/share/licenses/Expat
+++ /dev/null
@@ -1,17 +0,0 @@
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/share/licenses/Perl b/share/licenses/Perl
deleted file mode 100644
index d35363b..0000000
--- a/share/licenses/Perl
+++ /dev/null
@@ -1,5 +0,0 @@
-This program is free software; you may redistribute it and/or modify it
-under the same terms as Perl itself. This means that you may choose
-between the two licenses that Perl is released under: the GNU GPL and the
-Artistic License. Please see your Perl distribution for the details and
-copies of the licenses.
diff --git a/share/schema/docknot.yaml b/share/schema/docknot.yaml
new file mode 100644
index 0000000..d205d2e
--- /dev/null
+++ b/share/schema/docknot.yaml
@@ -0,0 +1,248 @@
+# Kwalify schema for DocKnot metadata.
+#
+# Copyright 2020 Russ Allbery <rra@cpan.org>
+#
+# SPDX-License-Identifier: MIT
+
+type: map
+mapping:
+ advisories:
+ type: seq
+ sequence:
+ - type: map
+ mapping:
+ date:
+ type: text
+ required: true
+ versions:
+ type: text
+ required: true
+ threshold:
+ type: text
+ required: true
+ blurb:
+ type: text
+ required: true
+ build:
+ type: map
+ mapping:
+ autoconf:
+ type: text
+ automake:
+ type: text
+ autotools:
+ type: bool
+ bootstrap:
+ type: text
+ cplusplus:
+ type: bool
+ gssapi:
+ type: bool
+ install:
+ type: bool
+ kerberos:
+ type: bool
+ manpages:
+ type: bool
+ middle:
+ type: text
+ reduced_depends:
+ type: bool
+ suffix:
+ type: text
+ type:
+ type: text
+ enum:
+ - Autoconf
+ - ExtUtils::MakeMaker
+ - Module::Build
+ - make
+ valgrind:
+ type: bool
+ copyrights:
+ type: seq
+ sequence:
+ - type: map
+ mapping:
+ holder:
+ type: text
+ required: true
+ unique: true
+ years:
+ type: text
+ required: true
+ description:
+ type: text
+ required: true
+ distribution:
+ type: map
+ mapping:
+ cpan:
+ type: text
+ ignore:
+ type: seq
+ sequence:
+ - type: text
+ packaging:
+ type: map
+ mapping:
+ debian:
+ type: map
+ mapping:
+ package:
+ type: text
+ personal:
+ type: bool
+ summary:
+ type: text
+ extra:
+ type: text
+ section:
+ type: text
+ required: true
+ tarname:
+ type: text
+ required: true
+ version:
+ type: text
+ required: true
+ docs:
+ type: map
+ mapping:
+ api: &pagelist
+ type: seq
+ sequence:
+ - type: map
+ mapping:
+ name:
+ type: text
+ required: true
+ unique: true
+ title:
+ type: text
+ required: true
+ contrib: *pagelist
+ developer: *pagelist
+ extra:
+ type: seq
+ sequence:
+ - type: map
+ mapping:
+ title:
+ type: text
+ required: true
+ links: *pagelist
+ user: *pagelist
+ format:
+ type: text
+ required: true
+ enum:
+ - v1
+ license:
+ type: map
+ mapping:
+ name:
+ type: text
+ required: true
+ notices:
+ type: text
+ maintainer:
+ type: text
+ required: true
+ name:
+ type: text
+ required: true
+ orphaned:
+ type: text
+ quote:
+ type: map
+ mapping:
+ author:
+ type: text
+ required: true
+ broken:
+ type: bool
+ date:
+ type: text
+ text:
+ type: text
+ required: true
+ title:
+ type: text
+ work:
+ type: text
+ requirements:
+ type: text
+ required: true
+ sections:
+ type: seq
+ sequence:
+ - type: map
+ mapping:
+ body:
+ type: text
+ required: true
+ title:
+ type: text
+ required: true
+ support:
+ type: map
+ mapping:
+ email:
+ type: text
+ required: true
+ extra:
+ type: text
+ github:
+ type: text
+ listname:
+ type: text
+ listurl:
+ type: text
+ web:
+ type: text
+ required: true
+ synopsis:
+ type: text
+ required: true
+ test:
+ type: map
+ mapping:
+ lancaster:
+ type: bool
+ override:
+ type: text
+ prefix:
+ type: text
+ suffix:
+ type: text
+ vcs:
+ type: map
+ mapping:
+ browse:
+ type: text
+ required: true
+ github:
+ type: text
+ openhub:
+ type: text
+ status:
+ type: map
+ mapping:
+ travis:
+ type: text
+ workflow:
+ type: text
+ enum:
+ - build
+ type:
+ type: text
+ required: true
+ enum:
+ - Git
+ url:
+ type: text
+ required: true
+ version:
+ type: text
+ required: true
diff --git a/share/schema/licenses.yaml b/share/schema/licenses.yaml
new file mode 100644
index 0000000..1ae7fe6
--- /dev/null
+++ b/share/schema/licenses.yaml
@@ -0,0 +1,17 @@
+# Kwalify schema for the licenses.yaml metadata file.
+#
+# Copyright 2020 Russ Allbery <rra@cpan.org>
+#
+# SPDX-License-Identifier: MIT
+
+type: map
+mapping:
+ =:
+ type: map
+ mapping:
+ summary:
+ type: text
+ required: true
+ text:
+ type: text
+ required: true
diff --git a/share/templates/readme-md.tmpl b/share/templates/readme-md.tmpl
index 4f3da52..5535f31 100644
--- a/share/templates/readme-md.tmpl
+++ b/share/templates/readme-md.tmpl
@@ -1,10 +1,10 @@
-# [% name %] [% version %]
-[% IF vcs.status || distribution.cpan || orphaned || packaging.debian %]
-[% IF orphaned %][![No maintenance intended](http://unmaintained.tech/badge.svg)](http://unmaintained.tech/) [% END -%]
+# [% name %]
+[% IF vcs.status || distribution.cpan || orphaned || distribution.packaging.debian %]
+[% IF orphaned %][![No maintenance intended](https://unmaintained.tech/badge.svg)](https://unmaintained.tech/) [% END -%]
[% IF vcs.status.travis %][![Build status](https://travis-ci.org/[% vcs.status.travis %].svg?branch=master)](https://travis-ci.org/[% vcs.status.travis %]) [% END -%]
[% IF vcs.status.workflow %][![Build status](https://github.com/[% vcs.github %]/workflows/[% vcs.status.workflow %]/badge.svg)](https://github.com/[% vcs.github %]/actions) [% END -%]
[% IF distribution.cpan %][![CPAN version](https://img.shields.io/cpan/v/[% distribution.cpan %])](https://metacpan.org/release/[% distribution.cpan %])[% IF vcs.github %] [![License](https://img.shields.io/cpan/l/[% distribution.cpan %])](https://github.com/[% vcs.github %]/blob/master/LICENSE)[% END %] [% END -%]
-[% IF packaging.debian %][![Debian package](https://img.shields.io/debian/v/[% packaging.debian %]/unstable)](https://tracker.debian.org/pkg/[% packaging.debian %])[% END -%]
+[% IF distribution.packaging.debian.package %][![Debian package](https://img.shields.io/debian/v/[% distribution.packaging.debian.package %]/unstable)](https://tracker.debian.org/pkg/[% distribution.packaging.debian.package %])[% END -%]
[% END %]
[% FOREACH copr IN copyrights %]Copyright [% copr.years %]
@@ -35,8 +35,8 @@ and need to regenerate Makefile.in, you will need Automake
configure.ac or any of the m4 files it includes and need to regenerate
configure or config.h.in, you will need Autoconf [% build.autoconf %] or
later.[% IF build.manpages %] Perl is also required to generate manual
-pages from a fresh Git checkout.[% END %][% IF bootstrap %]
-[% bootstrap %][% END %]
+pages from a fresh Git checkout.[% END %][% IF build.bootstrap %]
+[% build.bootstrap %][% END %]
[% END %][% IF build.type == 'Module::Build' %]
## Building and Installation
@@ -117,11 +117,11 @@ you need to specify a different Kerberos installation root via
You can also individually set the paths to the include directory and the
library directory with `--with-krb5-include` and `--with-krb5-lib`. You
-may need to do this if Autoconf can't figure out whether to use lib,
-lib32, or lib64 on your platform.
+may need to do this if Autoconf can't figure out whether to use `lib`,
+`lib32`, or `lib64` on your platform.
-To not use krb5-config and force library probing even if there is a
-krb5-config script on your path, set PATH_KRB5_CONFIG to a nonexistent
+To not use `krb5-config` and force library probing even if there is a
+`krb5-config` script on your path, set `PATH_KRB5_CONFIG` to a nonexistent
path:
```
@@ -155,9 +155,11 @@ that make shared library migrations more difficult. If none of the above
made any sense to you, don't bother with this flag.
[% END %][% IF build.suffix %]
[% build.suffix %]
-[% END %][% END %][% IF !readme.testing && (build.type == 'Module::Build' || build.type == 'ExtUtils::MakeMaker' || build.type == 'Autoconf') %]
+[% END %][% END %][% IF test.override || build.type == 'Module::Build' || build.type == 'ExtUtils::MakeMaker' || build.type == 'Autoconf' %]
## Testing
-[% IF test.prefix %]
+[% IF test.override %]
+[% test.override %]
+[% ELSE %][% IF test.prefix %]
[% test.prefix %]
[% ELSE %]
[% name %] comes with a test suite, which you can run after building with:
@@ -196,7 +198,7 @@ Do this instead of running the test program directly since it will ensure
that necessary environment variables are set up.
[% END %][% IF test.suffix %]
[% test.suffix %]
-[% END %][% IF build.lancaster %]
+[% END %][% END %][% IF test.lancaster %]
To enable tests that don't detect functionality problems but are used to
sanity-check the release, set the environment variable `RELEASE_TESTING`
to a true value. To enable tests that may be sensitive to the local
@@ -204,19 +206,11 @@ environment or that produce a lot of false positives without uncovering
many problems, set the environment variable `AUTHOR_TESTING` to a true
value.
[% END %][% END %]
-[% FOREACH section IN readme.sections %]## [% section.title %]
+[% FOREACH section IN sections %]## [% section.title %]
[% section.body %]
-[% IF section.title == 'Testing' && build.lancaster %]
-To enable tests that don't detect functionality problems but are used to
-sanity-check the release, set the environment variable `RELEASE_TESTING`
-to a true value. To enable tests that may be sensitive to the local
-environment or that produce a lot of false positives without uncovering
-many problems, set the environment variable `AUTHOR_TESTING` to a true
-value.
-
-[% END %][% END %]## Support
+[% END %]## Support
The [[% name %] web page]([% support.web %]) will always have the current
version of this package, the current documentation, and pointers to any
@@ -228,9 +222,7 @@ mailing list. To subscribe or see the list archives, go to the
[% END %][% IF support.extra %]
[% support.extra %]
[% END %]
-[% IF support.cpan %]
-For bug tracking, use the [CPAN bug
-tracker](https://rt.cpan.org/Dist/Display.html?Name=[% support.cpan %]).[% ELSIF support.github %]
+[% IF support.github %]
For bug tracking, use the [issue tracker on
GitHub](https://github.com/[% support.github %]/issues).[% ELSE %]
I welcome bug reports and patches for this package at
@@ -252,12 +244,9 @@ or [view the repository on the web]([% vcs.browse %]).
The eyrie.org repository is the canonical one, maintained by the
author, but using GitHub is probably more convenient for most purposes.
Pull requests are gratefully reviewed and normally accepted.
-[% IF support.cpan %]It's probably better to use the CPAN bug tracker than
-GitHub issues, though, to keep all Perl module issues in the same
-place.[% END %]
[% ELSIF vcs.type == 'Git' %]
When contributing modifications, patches (possibly generated by
-git-format-patch) are preferred to Git pull requests.
+`git-format-patch`) are preferred to Git pull requests.
[% END %]
## License
@@ -267,7 +256,7 @@ statement and license:
> Copyright [% copr.years %]
> [% copr.holder %]
>[% END %]
-[% indent(license.full, 1, '>') %][% IF license.notices %]
+[% indent(license.text, 1, '>') %][% IF license.notices %]
>
[% indent(license.notices, 1, '>') %][% END %]
diff --git a/share/templates/readme.tmpl b/share/templates/readme.tmpl
index 49b0fee..b4ed2c8 100644
--- a/share/templates/readme.tmpl
+++ b/share/templates/readme.tmpl
@@ -31,8 +31,8 @@ REQUIREMENTS
configure.ac or any of the m4 files it includes and need to regenerate
configure or config.h.in, you will need Autoconf [% build.autoconf %] or
later.[% IF build.manpages %] Perl is also required to generate manual
- pages from a fresh Git checkout.[% END %][% IF bootstrap %]
-[% indent(to_text(bootstrap), 2) %][% END %]
+ pages from a fresh Git checkout.[% END %][% IF build.bootstrap %]
+[% indent(to_text(build.bootstrap), 2) %][% END %]
[% END %][% IF build.type == 'Module::Build' %]
BUILDING AND INSTALLATION
@@ -137,8 +137,11 @@ BUILDING
If none of the above made any sense to you, don't bother with this flag.
[% END %][% IF build.suffix %]
[% indent(to_text(build.suffix), 2) %]
-[% END %][% END %][% IF !readme.testing && (build.type == 'Module::Build' || build.type == 'ExtUtils::MakeMaker' || build.type == 'Autoconf') %]
+[% END %][% END %][% IF test.override || build.type == 'Module::Build' || build.type == 'ExtUtils::MakeMaker' || build.type == 'Autoconf' %]
TESTING
+[% IF test.override %]
+[% indent(to_text(test.override), 2) %]
+[% ELSE %]
[% IF test.prefix %]
[% indent(to_text(test.prefix), 2) %]
[% ELSE %]
@@ -167,7 +170,7 @@ TESTING
ensure that necessary environment variables are set up.
[% END %][% IF test.suffix %]
[% indent(to_text(test.suffix), 2) %]
-[% END %][% IF build.lancaster %]
+[% END %][% END %][% IF test.lancaster %]
To enable tests that don't detect functionality problems but are used to
sanity-check the release, set the environment variable RELEASE_TESTING
to a true value. To enable tests that may be sensitive to the local
@@ -175,19 +178,11 @@ TESTING
many problems, set the environment variable AUTHOR_TESTING to a true
value.
[% END %][% END %]
-[% FOREACH section IN readme.sections %][% section.title FILTER upper %]
+[% FOREACH section IN sections %][% section.title FILTER upper %]
[% indent(to_text(section.body), 2) %]
-[% IF section.title == 'Testing' && build.lancaster %]
- To enable tests that don't detect functionality problems but are used to
- sanity-check the release, set the environment variable RELEASE_TESTING
- to a true value. To enable tests that may be sensitive to the local
- environment or that produce a lot of false positives without uncovering
- many problems, set the environment variable AUTHOR_TESTING to a true
- value.
-
-[% END %][% END %]SUPPORT
+[% END %]SUPPORT
The [% name %] web page at:
@@ -203,12 +198,7 @@ TESTING
[% END %][% IF support.extra %]
[% indent(to_text(support.extra), 2) %]
[% END %]
-[% IF support.cpan %]
- For bug tracking, use the CPAN bug tracker at:
-
- https://rt.cpan.org/Dist/Display.html?Name=[% support.cpan %]
-
-[% ELSIF support.github %]
+[% IF support.github %]
For bug tracking, use the issue tracker on GitHub:
https://github.com/[% support.github %]/issues
@@ -238,9 +228,6 @@ SOURCE REPOSITORY
The eyrie.org repository is the canonical one, maintained by the author,
but using GitHub is probably more convenient for most purposes. Pull
requests are gratefully reviewed and normally accepted.
- [% IF support.cpan %]It's probably better to use the CPAN bug tracker
- than GitHub issues, though, to keep all Perl module issues in the same
- place.[% END %]
[% ELSIF vcs.type == 'Git' %]
When contributing modifications, patches (possibly generated by
git-format-patch) are preferred to Git pull requests.
@@ -252,7 +239,7 @@ LICENSE
[% copyright(4) %]
-[% indent(license.full, 4) %]
+[% indent(license.text, 4) %]
[% IF license.notices %]
[% indent(to_text(license.notices), 4) %]
[% END %]
diff --git a/share/templates/thread.tmpl b/share/templates/thread.tmpl
index 58b931c..f46ae31 100644
--- a/share/templates/thread.tmpl
+++ b/share/templates/thread.tmpl
@@ -32,8 +32,8 @@
\download[[% name %]][[% distribution.version %]]
[[% distribution.section %]/[% distribution.tarname %]-\version[[% distribution.version %]]]
-[% IF packaging.debian %]
- \link[https://packages.debian.org/source/sid/[% packaging.debian %]]
+[% IF distribution.packaging.debian.package %]
+ \link[https://packages.debian.org/source/sid/[% distribution.packaging.debian.package %]]
[Debian packages] \break[% END %]
\link[https://archives.eyrie.org/software/ARCHIVE/[% distribution.tarname %]/]
[Archive]
@@ -56,8 +56,6 @@
\link[https://github.com/[% vcs.github %]]
[GitHub][% END %][% IF support.github %] \break
\link[https://github.com/[% support.github %]/issues]
- [Bug tracker][% ELSIF support.cpan %] \break
- \link[https://rt.cpan.org/Dist/Display.html?Name=[% support.cpan %]]
[Bug tracker][% END %][% IF vcs.type == 'Git' %] \break
\link[[% vcs.browse %]]
[Git repository][% END %][% IF vcs.status.travis %] \break
@@ -66,8 +64,8 @@
\link[https://metacpan.org/release/[% distribution.cpan %]]
[MetaCPAN][% END %][% IF vcs.openhub %] \break
\link[[% vcs.openhub %]]
- [Open HUB code analysis][% END %][% IF packaging.debian %] \break
- \link[https://tracker.debian.org/pkg/[% packaging.debian %]]
+ [Open HUB code analysis][% END %][% IF distribution.packaging.debian.package %] \break
+ \link[https://tracker.debian.org/pkg/[% distribution.packaging.debian.package %]]
[Debian package tracker][% END %]
]
[% IF orphaned %]
@@ -94,8 +92,8 @@ need to regenerate Makefile.in, you will need Automake
configure.ac or any of the m4 files it includes and need to regenerate
configure or config.h.in, you will need Autoconf [% build.autoconf %] or
later.[% IF build.manpages %] Perl is also required to generate manual
-pages from a fresh Git checkout.[% END %][% IF bootstrap %]
-[% to_thread(bootstrap) %][% END %]
+pages from a fresh Git checkout.[% END %][% IF build.bootstrap %]
+[% to_thread(build.bootstrap) %][% END %]
[% END %]
\h2[Download]
@@ -110,13 +108,14 @@ An \link[https://archives.eyrie.org/software/ARCHIVE/[% distribution.tarname %]/
[archive of older releases] is also available.[% IF advisories %]
\class(alert)[Versions older than [% advisories.0.threshold %] have known
security vulnerabilities and should not be used.][% END %]
-[% IF debian.summary %]
-[% to_thread(debian.summary) | trim %][% IF debian.summary.match('\n\n') %]
+[% IF distribution.packaging.debian.summary %]
+[% to_thread(distribution.packaging.debian.summary) | trim %][% IF distribution.packaging.debian.summary.match('\n\n') %]
[% ELSE %] [% END %]See the \link[https://tracker.debian.org/pkg/[%
-packaging.debian %]][Debian package tracker] for more information.
+distribution.packaging.debian.package %]][Debian package tracker] for more
+information.
-[% ELSIF debian.personal %]
+[% ELSIF distribution.packaging.debian.personal %]
A Debian package is available from my \link[../debian.html][personal
repository].
[% END %][% IF distribution.cpan %]
@@ -124,8 +123,8 @@ repository].
\link[https://metacpan.org/release/[% distribution.cpan %]]
[[% distribution.cpan %] distribution].
[% END %]
-[% IF packaging.extra %]
-[% to_thread(packaging.extra) %]
+[% IF distribution.packaging.extra %]
+[% to_thread(distribution.packaging.extra) %]
[% END %][% name %] is maintained using the [% vcs.type %] version control
system. To check out the current development tree, [% IF vcs.github %]see
\link[https://github.com/[% vcs.github %]][GitHub] or [% END %]clone:
@@ -157,8 +156,6 @@ also \link[[% vcs.browse %]][browse the current development source].
\doc[https://github.com/[% vcs.github %]]
[GitHub][% END %][% IF support.github %]
\doc[https://github.com/[% support.github %]/issues]
- [Bug tracker][% ELSIF support.cpan %]
- \doc[https://rt.cpan.org/Dist/Display.html?Name=[% support.cpan %]]
[Bug tracker][% END %][% IF vcs.status.travis %]
\doc[https://travis-ci.org/[% vcs.status.travis %]]
[Travis-CI][% END %][% IF vcs.openhub %]
@@ -202,8 +199,6 @@ Developer documentation:
\doc[https://github.com/[% vcs.github %]]
[GitHub][% END %][% IF support.github %]
\doc[https://github.com/[% support.github %]/issues]
- [Bug tracker][% ELSIF support.cpan %]
-\doc[https://rt.cpan.org/Dist/Display.html?Name=[% support.cpan %]]
[Bug tracker][% END %][% IF vcs.status.travis %]
\doc[https://travis-ci.org/[% vcs.status.travis %]]
[Travis-CI][% END %][% IF vcs.openhub %]
@@ -225,7 +220,7 @@ and license:
[% copr.holder %]
[% END %]
-[% indent(to_thread(license.full), 4) %]
+[% indent(to_thread(license.text), 4) %]
[% IF license.notices %]
[% indent(to_thread(license.notices), 4) %]
[% END %]
diff --git a/t/cli/errors.t b/t/cli/errors.t
index 7a3152f..5348eca 100755
--- a/t/cli/errors.t
+++ b/t/cli/errors.t
@@ -57,10 +57,7 @@ is_error($@, 'generate-all: too many arguments', 'Too many arguments');
# Trigger an error in a submodule to test error rewriting.
eval { $docknot->run('generate', '-m', '/nonexistent', 'readme') };
-is_error(
- $@,
-'generate: metadata path /nonexistent does not exist or is not a directory',
-);
+is_error($@, 'generate: metadata path /nonexistent does not exist');
# Check for a missing required argument.
eval { $docknot->run('dist') };
diff --git a/t/cli/generate.t b/t/cli/generate.t
index a76db9e..c94b2d7 100755
--- a/t/cli/generate.t
+++ b/t/cli/generate.t
@@ -2,7 +2,7 @@
#
# Tests for the App::DocKnot command dispatch for generate.
#
-# Copyright 2018-2019 Russ Allbery <rra@cpan.org>
+# Copyright 2018-2020 Russ Allbery <rra@cpan.org>
#
# SPDX-License-Identifier: MIT
@@ -55,7 +55,7 @@ my $tempdir = File::Temp->newdir();
# Save the paths to various files in the source directory.
my $readme_path = File::Spec->catfile(getcwd(), 'README');
my $readme_md_path = File::Spec->catfile(getcwd(), 'README.md');
-my $metadata_path = File::Spec->catfile(getcwd(), 'docs', 'metadata');
+my $metadata_path = File::Spec->catfile(getcwd(), 'docs', 'docknot.yaml');
# Generate all of the files using generate-all in a new temporary directory.
my $tmpdir = File::Temp->newdir();
diff --git a/t/config/basic.t b/t/config/basic.t
index 7da11a0..404971c 100755
--- a/t/config/basic.t
+++ b/t/config/basic.t
@@ -12,10 +12,9 @@ use warnings;
use File::ShareDir qw(module_file);
use File::Spec;
-use JSON::MaybeXS qw(JSON);
-use Perl6::Slurp;
+use YAML::XS ();
-use Test::More tests => 7;
+use Test::More tests => 5;
# Load the modules.
BEGIN { use_ok('App::DocKnot::Config') }
@@ -24,28 +23,16 @@ BEGIN { use_ok('App::DocKnot::Config') }
my $dataroot = File::Spec->catfile('t', 'data', 'generate');
# Load a test configuration and check a few inobvious pieces of it.
-my $metadata_path = File::Spec->catfile($dataroot, 'ansicolor', 'metadata');
-my $config = App::DocKnot::Config->new({ metadata => $metadata_path });
+my $metadata_path
+ = File::Spec->catfile($dataroot, 'ansicolor', 'docknot.yaml');
+my $config = App::DocKnot::Config->new({ metadata => $metadata_path });
isa_ok($config, 'App::DocKnot::Config');
my $data_ref = $config->config();
-is($data_ref->{build}{install}, 1, 'build/install defaults to 1');
-my $blurb_path = File::Spec->catfile($metadata_path, 'blurb');
-is($data_ref->{blurb}, slurp($blurb_path), 'blurb contains file contents');
-my $notices_path = File::Spec->catfile($metadata_path, 'notices');
-is($data_ref->{license}{notices},
- slurp($notices_path), 'license/notices loaded');
-my $quote_path = File::Spec->catfile($metadata_path, 'quote');
-is($data_ref->{quote}{text}, slurp($quote_path), 'quote/text loaded');
+ok($data_ref->{build}{install}, 'build/install defaults to true');
# Check that the license data is expanded correctly.
-my $json = JSON->new;
-$json->relaxed;
-my $license_path = module_file('App::DocKnot', 'licenses.json');
-my $license_data = $json->decode(scalar(slurp($license_path)));
-my $perl_license_data = $license_data->{Perl};
-my $full_license_path
- = module_file('App::DocKnot', File::Spec->catfile('licenses', 'Perl'));
-$perl_license_data->{full} = slurp($full_license_path);
-delete($data_ref->{license}{notices});
-is_deeply($data_ref->{license}, $perl_license_data,
- 'license data loaded properly');
+my $licenses_path = module_file('App::DocKnot', 'licenses.yaml');
+my $licenses_ref = YAML::XS::LoadFile($licenses_path);
+my $perl_license_ref = $licenses_ref->{Perl};
+is($data_ref->{license}{summary}, $perl_license_ref->{summary}, 'summary');
+is($data_ref->{license}{text}, $perl_license_ref->{text}, 'text');
diff --git a/t/data/dist/MANIFEST b/t/data/dist/MANIFEST
index 7ae2399..7d4e37d 100644
--- a/t/data/dist/MANIFEST
+++ b/t/data/dist/MANIFEST
@@ -1,8 +1,5 @@
Build.PL
-docs/metadata/blurb
-docs/metadata/description
-docs/metadata/metadata.json
-docs/metadata/requirements
+docs/docknot.yaml
lib/Empty.pm
MANIFEST This list of files
MANIFEST.SKIP
diff --git a/t/data/dist/docs/docknot.yaml b/t/data/dist/docs/docknot.yaml
new file mode 100644
index 0000000..7263826
--- /dev/null
+++ b/t/data/dist/docs/docknot.yaml
@@ -0,0 +1,27 @@
+format: v1
+
+name: Empty
+maintainer: Russ Allbery <rra@cpan.org>
+version: '1.00'
+synopsis: An empty package
+
+license:
+ name: Expat
+
+build:
+ type: Module::Build
+distribution:
+ ignore:
+ - \Aignored-file\z
+ section: devel
+ tarname: Empty
+ version: empty
+
+blurb: |
+ Test package.
+
+description: |
+ Test package.
+
+requirements: |
+ Test package.
diff --git a/t/data/dist/docs/metadata/blurb b/t/data/dist/docs/metadata/blurb
deleted file mode 100644
index 1d115d1..0000000
--- a/t/data/dist/docs/metadata/blurb
+++ /dev/null
@@ -1 +0,0 @@
-Test package.
diff --git a/t/data/dist/docs/metadata/description b/t/data/dist/docs/metadata/description
deleted file mode 100644
index 1d115d1..0000000
--- a/t/data/dist/docs/metadata/description
+++ /dev/null
@@ -1 +0,0 @@
-Test package.
diff --git a/t/data/dist/docs/metadata/metadata.json b/t/data/dist/docs/metadata/metadata.json
deleted file mode 100644
index 0a3829a..0000000
--- a/t/data/dist/docs/metadata/metadata.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "name": "Empty",
- "version": "1.00",
- "license": "Expat",
- "build": {
- "type": "Module::Build",
- },
- "distribution": {
- "tarname": "Empty",
- "ignore": [
- "\\Aignored-file\\z",
- ],
- },
-}
diff --git a/t/data/dist/docs/metadata/requirements b/t/data/dist/docs/metadata/requirements
deleted file mode 100644
index 1d115d1..0000000
--- a/t/data/dist/docs/metadata/requirements
+++ /dev/null
@@ -1 +0,0 @@
-Test package.
diff --git a/t/data/generate/ansicolor/docknot.yaml b/t/data/generate/ansicolor/docknot.yaml
new file mode 100644
index 0000000..840e04e
--- /dev/null
+++ b/t/data/generate/ansicolor/docknot.yaml
@@ -0,0 +1,113 @@
+format: v1
+
+name: Term::ANSIColor
+maintainer: Russ Allbery <rra@cpan.org>
+version: '4.06'
+synopsis: simple ANSI text attribute control module
+
+license:
+ name: Perl
+ notices: |
+ PUSH/POP support submitted 2007 by openmethods.com voice solutions
+copyrights:
+ - holder: Russ Allbery <rra@cpan.org>
+ years: 1996-1998, 2000-2002, 2005-2006, 2008-2016
+ - holder: Zenin
+ years: '1996'
+ - holder: Kurt Starsinic <kstarsinic@gmail.com>
+ years: '2012'
+
+build:
+ type: ExtUtils::MakeMaker
+distribution:
+ section: devel
+ tarname: Term-ANSIColor
+ version: term-ansicolor
+support:
+ email: rra@cpan.org
+ github: rra/ansicolor
+ web: https://www.eyrie.org/~eagle/software/ansicolor/
+test:
+ lancaster: true
+vcs:
+ browse: https://git.eyrie.org/?p=perl/ansicolor.git
+ github: rra/ansicolor
+ type: Git
+ url: https://git.eyrie.org/git/perl/ansicolor.git
+
+quote:
+ author: Dave van Domelen
+ text: |
+ Ah, September, when the sysadmins turn colors and fall off the trees....
+
+docs:
+ user:
+ - name: docs
+ title: Module documentation
+ - name: thanks
+ title: Thanks and credits
+
+blurb: |
+ Term::ANSIColor provides constants and simple functions for setting ANSI
+ text attributes, most notably colors. It can be used to set the current
+ text attributes or to apply a set of attributes to a string and reset the
+ current text attributes at the end of that string. Eight-color,
+ sixteen-color, and 256-color escape sequences are all supported.
+
+description: |
+ This Perl module is a simple and convenient interface to the ANSI terminal
+ escape sequences for color (from ECMA-48, also included in ISO 6429). The
+ color sequences are provided in two forms, either as constants for each
+ color or via a function that takes the names of colors and returns the
+ appropriate escape codes or wraps them around the provided text. The
+ non-color text style codes from ANSI X3.64 (bold, dark, underline, and
+ reverse, for example), which were also included in ECMA-48 and ISO 6429,
+ are also supported. Also supported are the extended colors used for
+ sixteen-color and 256-color emulators.
+
+ This module is very stable, and I've used it in a wide variety of
+ applications. It has been included in the core Perl distribution starting
+ with version 5.6.0, so you don't need to download and install it yourself
+ unless you have an old version of Perl or need a newer version of the
+ module than comes with your version of Perl. I continue to maintain it as
+ a separate module, and the version included in Perl is resynced with mine
+ before each release.
+
+ The original module came out of a discussion in comp.lang.perl.misc and is
+ a combination of two approaches, one with constants by Zenin and one with
+ functions that I wrote. I offered to maintain a combined module that
+ included both approaches.
+
+requirements: |
+ Term::ANSIColor is written in pure Perl and has no module dependencies
+ that aren't found in Perl core. It should work with any version of Perl
+ after 5.6, although it hasn't been tested with old versions in some time.
+
+ In order to actually see color, you will need to use a terminal window
+ that supports the ANSI escape sequences for color. Any recent version of
+ xterm, most xterm derivatives and replacements, and most telnet and ssh
+ clients for Windows and Macintosh should work, as will the MacOS X
+ Terminal application (although Terminal.app reportedly doesn't support 256
+ colors). The console windows for Windows NT and Windows 2000 will not
+ work, as they do not even attempt to support ANSI X3.64.
+
+ For a complete (to my current knowledge) compatibility list, see the
+ Term::ANSIColor module documentation. If you have any additions to the
+ table in the documentation, please send them to me.
+
+ The test suite requires Test::More (part of Perl since 5.6.2). The
+ following additional Perl modules will be used by the test suite if
+ present:
+
+ * Devel::Cover
+ * Test::MinimumVersion
+ * Test::Perl::Critic
+ * Test::Pod
+ * Test::Pod::Coverage
+ * Test::Spelling
+ * Test::Strict
+ * Test::Synopsis
+ * Test::Warn
+
+ All are available on CPAN. Those tests will be skipped if the modules are
+ not available.
diff --git a/t/data/generate/ansicolor/output/readme b/t/data/generate/ansicolor/output/readme
index 935eae9..bb6a6c1 100644
--- a/t/data/generate/ansicolor/output/readme
+++ b/t/data/generate/ansicolor/output/readme
@@ -116,9 +116,9 @@ SUPPORT
will always have the current version of this package, the current
documentation, and pointers to any additional resources.
- For bug tracking, use the CPAN bug tracker at:
+ For bug tracking, use the issue tracker on GitHub:
- https://rt.cpan.org/Dist/Display.html?Name=Term-ANSIColor
+ https://github.com/rra/ansicolor/issues
However, please be aware that I tend to be extremely busy and work
projects often take priority. I'll save your report and get to it as
@@ -141,9 +141,7 @@ SOURCE REPOSITORY
The eyrie.org repository is the canonical one, maintained by the author,
but using GitHub is probably more convenient for most purposes. Pull
- requests are gratefully reviewed and normally accepted. It's probably
- better to use the CPAN bug tracker than GitHub issues, though, to keep
- all Perl module issues in the same place.
+ requests are gratefully reviewed and normally accepted.
LICENSE
diff --git a/t/data/generate/ansicolor/output/readme-md b/t/data/generate/ansicolor/output/readme-md
index cb5082b..3296d05 100644
--- a/t/data/generate/ansicolor/output/readme-md
+++ b/t/data/generate/ansicolor/output/readme-md
@@ -1,4 +1,4 @@
-# Term::ANSIColor 4.06
+# Term::ANSIColor
Copyright 1996-1998, 2000-2002, 2005-2006, 2008-2016 Russ Allbery
<rra@cpan.org>. Copyright 1996 Zenin. Copyright 2012 Kurt Starsinic
@@ -117,11 +117,11 @@ page](https://www.eyrie.org/~eagle/software/ansicolor/) will always have
the current version of this package, the current documentation, and
pointers to any additional resources.
-For bug tracking, use the [CPAN bug
-tracker](https://rt.cpan.org/Dist/Display.html?Name=Term-ANSIColor).
-However, please be aware that I tend to be extremely busy and work
-projects often take priority. I'll save your report and get to it as soon
-as I can, but it may take me a couple of months.
+For bug tracking, use the [issue tracker on
+GitHub](https://github.com/rra/ansicolor/issues). However, please be
+aware that I tend to be extremely busy and work projects often take
+priority. I'll save your report and get to it as soon as I can, but it
+may take me a couple of months.
## Source Repository
@@ -136,9 +136,7 @@ web](https://git.eyrie.org/?p=perl/ansicolor.git).
The eyrie.org repository is the canonical one, maintained by the author,
but using GitHub is probably more convenient for most purposes. Pull
-requests are gratefully reviewed and normally accepted. It's probably
-better to use the CPAN bug tracker than GitHub issues, though, to keep all
-Perl module issues in the same place.
+requests are gratefully reviewed and normally accepted.
## License
diff --git a/t/data/generate/ansicolor/output/thread b/t/data/generate/ansicolor/output/thread
index 47ebb62..965195e 100644
--- a/t/data/generate/ansicolor/output/thread
+++ b/t/data/generate/ansicolor/output/thread
@@ -49,7 +49,7 @@
\link[todo.html][To-do list] \break
\link[https://github.com/rra/ansicolor]
[GitHub] \break
- \link[https://rt.cpan.org/Dist/Display.html?Name=Term-ANSIColor]
+ \link[https://github.com/rra/ansicolor/issues]
[Bug tracker] \break
\link[https://git.eyrie.org/?p=perl/ansicolor.git]
[Git repository]
@@ -160,7 +160,7 @@ Developer documentation:
\doc[todo.html][To-do list]
\doc[https://github.com/rra/ansicolor]
[GitHub]
-\doc[https://rt.cpan.org/Dist/Display.html?Name=Term-ANSIColor]
+\doc[https://github.com/rra/ansicolor/issues]
[Bug tracker]
\h2[License]
diff --git a/t/data/generate/c-tap-harness/docknot.yaml b/t/data/generate/c-tap-harness/docknot.yaml
new file mode 100644
index 0000000..8a74885
--- /dev/null
+++ b/t/data/generate/c-tap-harness/docknot.yaml
@@ -0,0 +1,265 @@
+format: v1
+
+name: C TAP Harness
+maintainer: Russ Allbery <eagle@eyrie.org>
+version: '4.0'
+synopsis: C harness for running TAP-compliant tests
+
+license:
+ name: Expat
+copyrights:
+ - holder: Russ Allbery <eagle@eyrie.org>
+ years: 2000-2001, 2004, 2006-2016
+ - holder: The Board of Trustees of the Leland Stanford Junior University
+ years: 2006-2009, 2011-2013
+
+build:
+ autoconf: '2.64'
+ automake: '1.11'
+ autotools: true
+ cplusplus: true
+ install: false
+ manpages: true
+ suffix: |
+ Installing C TAP Harness is not normally done. Instead, see the section
+ on using the harness below.
+ type: Autoconf
+ valgrind: true
+distribution:
+ section: devel
+ tarname: c-tap-harness
+ version: c-tap-harness
+support:
+ email: eagle@eyrie.org
+ github: rra/c-tap-harness
+ web: https://www.eyrie.org/~eagle/software/c-tap-harness/
+vcs:
+ browse: https://git.eyrie.org/?p=devel/c-tap-harness.git
+ github: rra/c-tap-harness
+ openhub: https://www.openhub.net/p/c-tap-harness
+ type: Git
+ url: https://git.eyrie.org/git/devel/c-tap-harness.git
+
+docs:
+ api:
+ - name: bail
+ title: bail and sysbail
+ - name: bmalloc
+ title: bmalloc, bcalloc, brealloc, bstrdup, and bstrndup
+ - name: breallocarray
+ title: breallocarray
+ - name: diag
+ title: diag and sysdiag
+ - name: diag_file_add
+ title: diag_file_add and diag_file_remove
+ - name: is_int
+ title: is_bool, is_int, is_double, is_string, and is_hex
+ - name: ok
+ title: ok, okv, and ok_block
+ - name: plan
+ title: plan and plan_lazy
+ - name: skip
+ title: skip and skip_block
+ - name: skip_all
+ title: skip_all
+ - name: test_cleanup_register
+ title: test_cleanup_register
+ - name: test_file_path
+ title: test_file_path and test_file_path_free
+ - name: test_tmpdir
+ title: test_tmpdir and test_tmpdir_free
+ user:
+ - name: writing
+ title: Writing TAP tests
+ - name: runtests
+ title: runtests manual page
+
+blurb: |
+ C TAP Harness is a pure-C implementation of TAP, the Test Anything
+ Protocol. TAP is the text-based protocol used by Perl's test suite. This
+ package provides a harness similar to Perl's Test::Harness for running
+ tests, with some additional features useful for test suites in packages
+ that use Autoconf and Automake, and C and shell libraries to make writing
+ TAP-compliant test programs easier.
+
+description: |
+ This package started as the runtests program I wrote for INN in 2000 to
+ serve as the basis for a new test suite using a test protocol similar to
+ that used for Perl modules. When I started maintaining additional C
+ packages, I adopted runtests for the test suite driver of those as well,
+ resulting in further improvements but also separate copies of the same
+ program in different distributions. The C TAP Harness distribution merges
+ all the various versions into a single code base that all my packages can
+ pull from.
+
+ C TAP Harness provides a full TAP specification driver (apart from a few
+ possible edge cases) and has additional special features for supporting
+ builds outside the source directory. It's mostly useful for packages
+ using Autoconf and Automake and because it doesn't assume or require Perl.
+
+ The runtests program can be built with knowledge of the source and build
+ directory and pass that knowledge on to test scripts, and will search for
+ test scripts in both the source and build directory. This makes it easier
+ for packages using Autoconf and Automake and supporting out-of-tree builds
+ to build some test programs, ship others, and run them all regardless of
+ what tree they're in. It also makes it easier for test cases to find
+ their supporting files when they run.
+
+ Also included in this package are C and shell libraries that provide
+ utility functions for writing test scripts that use TAP to report results.
+ The C library also provides a variety of utility functions useful for test
+ programs running as part of an Automake-built package: finding test data
+ files, creating temporary files, reporting output from external programs
+ running in the background, and similar common problems.
+
+requirements: |
+ C TAP Harness requires a C compiler to build. Any ISO C89 or later C
+ compiler on a system supporting the Single UNIX Specification, version 3
+ (SUSv3) should be sufficient. This should not be a problem on any modern
+ system. The test suite and shell library require a Bourne-compatible
+ shell. Outside of the test suite, C TAP Harness has no other
+ prerequisites or requirements.
+
+ To run the test suite, you will need Perl plus the Perl module Test::More,
+ which comes with Perl 5.8 or later. The following additional Perl modules
+ will be used by the test suite if present:
+
+ * Test::Pod
+ * Test::Spelling
+
+ All are available on CPAN. Those tests will be skipped if the modules are
+ not available.
+
+sections:
+ - title: Using the Harness
+ body: |
+ While there is an install target that installs runtests in the
+ default binary directory (`/usr/local/bin` by default) and installs
+ the man pages, one normally wouldn't install anything from this
+ package. Instead, the code is intended to be copied into your
+ package and refreshed from the latest release of C TAP Harness for
+ each release.
+
+ You can obviously copy the code and integrate it however works best
+ for your package and your build system. Here's how I do it for my
+ packages as an example:
+
+ * Create a tests directory and copy tests/runtests.c into it.
+ Create a `tests/tap` subdirectory and copy the portions of the TAP
+ library (from `tests/tap`) that I need for that package into it.
+ The TAP library is designed to let you drop in additional source
+ and header files for additional utility functions that are useful
+ in your package.
+
+ * Add code to my top-level `Makefile.am` (I always use a
+ non-recursive Makefile with `subdir-objects` set) to build
+ `runtests` and the test library:
+
+ ```make
+ check_PROGRAMS = tests/runtests
+ tests_runtests_CPPFLAGS = -DC_TAP_SOURCE='"$(abs_top_srcdir)/tests"' \
+ -DC_TAP_BUILD='"$(abs_top_builddir)/tests"'
+ check_LIBRARIES = tests/tap/libtap.a
+ tests_tap_libtap_a_CPPFLAGS = -I$(abs_top_srcdir)/tests
+ tests_tap_libtap_a_SOURCES = tests/tap/basic.c tests/tap/basic.h \
+ tests/tap/float.c tests/tap/float.h tests/tap/macros.h
+ ```
+
+ Omit `float.c` and `float.h` from the last line if your package
+ doesn't need the `is_double` function. Building the build and
+ source directories into runtests will let `tests/runtests -o
+ <test>` work for users without requiring that they set any other
+ variables, even if they're doing an out-of-source build.
+
+ Add additional source files and headers that should go into the
+ TAP library if you added extra utility functions for your package.
+
+ * Add code to `Makefile.am` to run the test suite:
+
+ ```make
+ check-local: $(check_PROGRAMS)
+ cd tests && ./runtests -l $(abs_top_srcdir)/tests/TESTS
+ ```
+
+ See the `Makefile.am` in this package for an example.
+
+ * List the test programs in the `tests/TESTS` file. This should
+ have the name of the test executable with the trailing "-t" or
+ ".t" (you can use either extension as you prefer) omitted.
+
+ Test programs must be executable.
+
+ For any test programs that need to be compiled, add build rules
+ for them in `Makefile.am`, similar to:
+
+ ```make
+ tests_libtap_c_basic_LDADD = tests/tap/libtap.a
+ ```
+
+ and add them to `check_PROGRAMS`. If you include the `float.c`
+ add-on in your libtap library, you will need to add `-lm` to the
+ `_LDADD` setting for all test programs linked against it.
+
+ A more complex example from the remctl package that needs
+ additional libraries:
+
+ ```make
+ tests_client_open_t_LDFLAGS = $(GSSAPI_LDFLAGS)
+ tests_client_open_t_LDADD = client/libremctl.la tests/tap/libtap.a \
+ util/libutil.la $(GSSAPI_LIBS)
+ ```
+
+ If the test program doesn't need to be compiled, add it to
+ `EXTRA_DIST` so that it will be included in the distribution.
+
+ * If you have test programs written in shell, copy
+ `tests/tap/libtap.sh` the tap subdirectory of your tests directory
+ and add it to `EXTRA_DIST`. Shell programs should start with:
+
+ ```sh
+ . "${C_TAP_SOURCE}/tap/libtap.sh"
+ ```
+
+ and can then use the functions defined in the library.
+
+ * Optionally copy `docs/writing-tests` into your package somewhere,
+ such as `tests/README`, as instructions to contributors on how to
+ write tests for this framework.
+
+ If you have configuration files that the user must create to enable
+ some of the tests, conventionally they go into `tests/config`.
+
+ If you have data files that your test cases use, conventionally they
+ go into `tests/data`. You can then find the data directory relative
+ to the `C_TAP_SOURCE` environment variable (set by `runtests`) in
+ your test program. If you have data that's compiled or generated by
+ Autoconf, it will be relative to the `BUILD` environment variable.
+ Don't forget to add test data to `EXTRA_DIST` as necessary.
+
+ For more TAP library add-ons, generally ones that rely on additional
+ portability code not shipped in this package or with narrower uses,
+ see [the rra-c-util
+ package](https://www.eyrie.org/~eagle/software/rra-c-util/). There
+ are several additional TAP library add-ons in the `tests/tap`
+ directory in that package. It's also an example of how to use this
+ test harness in another package.
+
+test:
+ override: |
+ C TAP Harness comes with a test suite, which you can run after
+ building with:
+
+ ```
+ make check
+ ```
+
+ If a test fails, you can run a single test with verbose output via:
+
+ ```
+ ./runtests -b `pwd`/tests -s `pwd`/tests -o <name-of-test>
+ ```
+
+ Do this instead of running the test program directly since it will
+ ensure that necessary environment variables are set up. You may need
+ to change the `-s` option argument if you build with a separate build
+ directory from the source directory.
diff --git a/t/data/generate/c-tap-harness/output/readme b/t/data/generate/c-tap-harness/output/readme
index 181201e..b8f69a4 100644
--- a/t/data/generate/c-tap-harness/output/readme
+++ b/t/data/generate/c-tap-harness/output/readme
@@ -98,8 +98,8 @@ BUILDING
TESTING
- C TAP Harness comes with a comprehensive test suite, which you can run
- after building with:
+ C TAP Harness comes with a test suite, which you can run after building
+ with:
make check
diff --git a/t/data/generate/c-tap-harness/output/readme-md b/t/data/generate/c-tap-harness/output/readme-md
index 0071860..4c4323d 100644
--- a/t/data/generate/c-tap-harness/output/readme-md
+++ b/t/data/generate/c-tap-harness/output/readme-md
@@ -1,4 +1,4 @@
-# C TAP Harness 4.0
+# C TAP Harness
Copyright 2000-2001, 2004, 2006-2016 Russ Allbery <eagle@eyrie.org>.
Copyright 2006-2009, 2011-2013 The Board of Trustees of the Leland
@@ -96,8 +96,8 @@ on using the harness below.
## Testing
-C TAP Harness comes with a comprehensive test suite, which you can run
-after building with:
+C TAP Harness comes with a test suite, which you can run after building
+with:
```
make check
diff --git a/t/data/generate/control-archive/docknot.yaml b/t/data/generate/control-archive/docknot.yaml
new file mode 100644
index 0000000..54c7af7
--- /dev/null
+++ b/t/data/generate/control-archive/docknot.yaml
@@ -0,0 +1,342 @@
+format: v1
+
+name: control-archive
+maintainer: Russ Allbery <eagle@eyrie.org>
+version: 1.8.0
+synopsis: processing and archiving of Netnews control messages
+
+license:
+ name: Expat
+ notices: |
+ This product includes software developed by UUNET Technologies, Inc.
+copyrights:
+ - holder: Russ Allbery <eagle@eyrie.org>
+ years: 2002-2004, 2007-2014, 2016-2018
+ - holder: Marco d'Itri
+ years: '2001'
+ - holder: UUNET Technologies, Inc.
+ years: '1996'
+
+build:
+ install: false
+ type: make
+distribution:
+ section: usenet
+ tarname: control-archive
+ version: control-archive
+support:
+ email: eagle@eyrie.org
+ extra: |
+ Configuration updates should be sent to usenet-config@isc.org.
+ github: rra/control-archive
+ web: https://www.eyrie.org/~eagle/software/control-archive/
+vcs:
+ browse: https://git.eyrie.org/?p=usenet/control.archive.git
+ github: rra/control-archive
+ type: Git
+ url: https://git.eyrie.org/git/usenet/control-archive.git
+
+quote:
+ author: Gene Spafford
+ text: |
+ Usenet is like a herd of performing elephants with diarrhea — massive,
+ difficult to redirect, awe-inspiring, entertaining, and a source of
+ mind-boggling amounts of excrement when you least expect it.
+docs:
+ user:
+ - name: control-summary
+ title: control-summary manual page
+ - name: export-control
+ title: export-control manual page
+ - name: generate-files
+ title: generate-files manual page
+ - name: process-control
+ title: process-control manual page
+ - name: update-control
+ title: update-control manual page
+
+blurb: |
+ This software generates an INN control.ctl configuration file from
+ hierarchy configuration fragments, verifies control messages using GnuPG
+ where possible, processes new control messages to update a newsgroup list,
+ archives new control messages, and exports the list of newsgroups in a
+ format suitable for synchronizing the newsgroup list of a Netnews news
+ server. It is the software that maintains the control message and
+ newsgroup lists available from ftp.isc.org.
+
+description: |
+ This package contains three major components:
+
+ * All of the configuration used to generate a `control.ctl` file for INN
+ and the `PGPKEYS` and `README.html` files distributed with pgpcontrol,
+ along with the script to generate those files.
+
+ * Software to process control messages, verify them against that
+ authorization information, and maintain a control message archive and
+ list of active newsgroups. Software is also included to generate
+ reports of recent changes to the list of active newsgroups.
+
+ * The documentation files included in the control message archive and
+ newsgroup lists on ftp.isc.org.
+
+ Manual changes to the canonical newsgroup list are supported in a way that
+ generates the same log messages and uses the same locking structure so
+ that they can co-exist with automated changes and be included in the same
+ reports.
+
+ This is the software that generates the [active newsgroup
+ lists](ftp://ftp.isc.org/pub/usenet/CONFIG/) and [control message
+ archive](ftp://ftp.isc.org/pub/usenet/control/) hosted on ftp.isc.org, and
+ the source of the `control.ctl` file provided with INN.
+
+ For a web presentation of the information recorded here, as well as other
+ useful information about Usenet hierarchies, please see the [list of
+ Usenet managed hierarchies](http://usenet.trigofacile.com/hierarchies/).
+
+requirements: |
+ Perl 5.6 or later plus the following additional Perl modules are required:
+
+ * Compress::Zlib (included in Perl 5.10 and later)
+ * Date::Parse (part of TimeDate)
+ * Net::NNTP (included in Perl 5.8 and later)
+ * Text::Template
+
+ [gzip](https://www.gnu.org/software/gzip/) and
+ [bzip2](http://www.bzip.org/) are required. Both are generally available
+ with current operating systems, possibly as supplemental packages.
+
+ process-control expects to be fed file names and message IDs of control
+ messages on standard input and therefore needs to be run from a news
+ server or some other source of control messages. A minimalist news server
+ like tinyleaf is suitable for this (I wrote tinyleaf, available as part of
+ [INN](https://www.eyrie.org/~eagle/software/inn/), for this purpose).
+
+sections:
+ - title: Versioning
+ body: |
+ This package uses a three-part version number. The first number
+ will be incremented for major changes, major new functionality,
+ incompatible changes to the configuration format (more than just
+ adding new keys), or similar disruptive changes. For lesser
+ changes, the second number will be incremented for any change to the
+ code or functioning of the software. A change to the third part of
+ the version number indicates a release with changes only to the
+ configuration, PGP keys, and documentation files.
+ - title: Layout
+ body: |
+ The configuration data is in one file per hierarchy in the `config`
+ directory. Each file has the format specified in FORMAT and is
+ designed to be readable by INN's new configuration parser in case
+ this can be further automated down the road. The `config/special`
+ directory contains overrides, raw `control.ctl` fragments that
+ should be used for particular hierarchies instead of
+ automatically-generated entries (usually for special comments).
+ Eventually, the format should be extended to handle as many of these
+ cases as possible.
+
+ The `keys` directory contains the PGP public keys for every
+ hierarchy that has one. The user IDs on these keys must match the
+ signer expected by the configuration data for the corresponding
+ hierarchy.
+
+ The `forms` directory contains the basic file structure for the
+ three generated files.
+
+ The `scripts` directory contains all the software that generates the
+ configuration and documentation files, processes control messages,
+ updates the database, creates the newsgroup lists, and generates
+ reports. Most scripts in that directory have POD documentation
+ included at the end of the script, viewable by running perldoc on
+ the script.
+
+ The `templates` directory contains templates for the
+ `control-summary` script. These are the templates I use myself.
+ Other installations should customize them.
+
+ The `docs` directory contains the extra documentation files that are
+ distributed from ftp.isc.org in the control message archive and
+ newsgroup list directories, plus the DocKnot metadata for this
+ package.
+ - title: Installation
+ body: |
+ This software is set up to run from `/srv/control`. To use a
+ different location, edit the paths at the beginning of each of the
+ scripts in the `scripts` directory to use different paths. By
+ default, copying all the files from the distribution into a
+ `/srv/control` directory is almost all that's needed. An install
+ rule is provided to do this. To install the software, run:
+
+ ```sh
+ 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:
+
+ ```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
+ ```
+
+ Both of these are done automatically as part of `make install`.
+ process-control expects `/srv/control/archive` to exist and archives
+ control messages there. It expects `/srv/control/tmp` to exist and
+ uses it for temporary files for GnuPG control message verification.
+
+ To process incoming control messages, you need to run
+ `process-control` on each message. `process-control` expects to
+ receive, on standard input, lines consisting of a path to a file, a
+ space, and a message ID. This input format is designed to work with
+ the tinyleaf server that comes with INN 2.5 and later, but it should
+ also work as a channel feed from pre-storage-API versions of INN
+ (1.x). It will not work without modification via a channel feed
+ from a current version of INN, since it doesn't understand the
+ storage API and doesn't know how to retrieve articles by tokens.
+ This could be easily added; I just haven't needed it.
+
+ If you're using tinyleaf, here is the setup process:
+
+ 1. Create a directory that tinyleaf will use to store incoming
+ articles temporarily, the archive directory, and the logs
+ directory and install the software:
+
+ ```sh
+ make install
+ ```
+
+ 2. Run tinyleaf on some port, configuring it to use that directory
+ and to run process-control. A typical tinyleaf command line
+ would be:
+
+ ```sh
+ tinyleaf /srv/control/spool /srv/control/scripts/process-control
+ ```
+
+ I run tinyleaf using systemd, but any inetd implementation should
+ work equally well.
+
+ 3. Set up a news feed to the system running tinyleaf that sends
+ control messages of interest. You should be careful not to send
+ cancel control messages or you'll get a ton of junk in your logs.
+ The INN newsfeeds entry I use is:
+
+ ```
+ isc-control:control,control.*,!control.cancel:Tf,Wnm:
+ ```
+
+ combined with nntpsend to send the articles.
+
+ That should be all there is to it. Watch the logs directory to see
+ what happens for incoming messages.
+
+ `scripts/process-control` just maintains a database file. To export
+ that data in a format that's useful for other software, run
+ `scripts/export-control`. This expects a `/srv/control/export`
+ directory into which it stores active and newsgroups files, a copy
+ of the `control.ctl` file, and all of the logs in a `LOGS`
+ subdirectory. This export directory can then be made available on
+ the web, copied to another system, or whatever else is appropriate.
+ Generally, `scripts/export-control` should be run periodically from
+ cron.
+
+ Reports can be generated using `scripts/control-summary`. This
+ script needs configuration before running; see the top of the script
+ and its included POD documentation. There is a sample template in
+ the `templates` directory, and `scripts/weekly-report` shows a
+ sample cron job for sending out a regular report.
+ - title: Bootstrapping
+ body: |
+ This package is intended to provide all of the tools, configuration,
+ and information required to duplicate the ftp.isc.org control
+ message archive and newsgroup list service if you so desire. To set
+ up a similar service based on that service, however, you will also
+ want to bootstrap from the existing data. Here is the procedure for
+ that:
+
+ 1. Be sure that you're starting from the latest software and set of
+ configuration files. I will generally try to make a new release
+ after committing a batch of changes, but I may not make a new
+ release after every change. See the sections below for
+ information about the Git repository in which this package is
+ maintained. You can always clone that repository to get the
+ latest configuration (and then merge or cherry-pick changes from
+ my repository into your repository as you desire).
+
+ 2. Download the current newsgroup list from:
+
+ ftp://ftp.isc.org/pub/usenet/CONFIG/newsgroups.bz2
+
+ and then bootstrap the database from it:
+
+ ```sh
+ bzip2 -dc newsgroups.bz2 | scripts/update-control bulkload
+ ```
+
+ 3. If you want the log information so that your reports will include
+ changes made in the ftp.isc.org archive before you created your
+ own, copy the contents of
+ ftp://ftp.isc.org/pub/usenet/CONFIG/LOGS/ into
+ `/srv/control/logs`.
+
+ 4. If you want to start with the existing control message
+ repository, download the contents of
+ ftp://ftp.isc.org/pub/usenet/control/ into
+ `/srv/control/archive`. You can do this using a recursive
+ download tool that understands FTP, such as wget, but please use
+ the options that add delays and don't hammer the server to death.
+
+ After finishing those steps, you will have a copy of the ftp.isc.org
+ archive and can start processing control messages, possibly with
+ different configuration choices. You can generate the files that
+ are found in ftp://ftp.isc.org/pub/usenet/CONFIG/ by running
+ `scripts/export-control` as described above.
+ - title: Maintenance
+ body: |
+ 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>
+ ```
+
+ where <hierarchy> is the hierarchy the checkgroups is for and
+ <checkgroups> is the path to the checkgroups file.
diff --git a/t/data/generate/control-archive/output/readme b/t/data/generate/control-archive/output/readme
index 1436086..6ff5643 100644
--- a/t/data/generate/control-archive/output/readme
+++ b/t/data/generate/control-archive/output/readme
@@ -174,13 +174,13 @@ INSTALLATION
tinyleaf /srv/control/spool /srv/control/scripts/process-control
- I run tinyleaf using systemd, but any inetd implementation should work
- equally well.
+ I run tinyleaf using systemd, but any inetd implementation should
+ work equally well.
3. Set up a news feed to the system running tinyleaf that sends control
- messages of interest. You should be careful not to send cancel control
- messages or you'll get a ton of junk in your logs. The INN newsfeeds
- entry I use is:
+ messages of interest. You should be careful not to send cancel
+ control messages or you'll get a ton of junk in your logs. The INN
+ newsfeeds entry I use is:
isc-control:control,control.*,!control.cancel:Tf,Wnm:
@@ -213,12 +213,12 @@ BOOTSTRAPPING
bootstrap from the existing data. Here is the procedure for that:
1. Be sure that you're starting from the latest software and set of
- configuration files. I will generally try to make a new release after
- committing a batch of changes, but I may not make a new release after
- every change. See the sections below for information about the Git
- repository in which this package is maintained. You can always clone
- that repository to get the latest configuration (and then merge or
- cherry-pick changes from my repository into your repository as you
+ configuration files. I will generally try to make a new release
+ after committing a batch of changes, but I may not make a new release
+ after every change. See the sections below for information about the
+ Git repository in which this package is maintained. You can always
+ clone that repository to get the latest configuration (and then merge
+ or cherry-pick changes from my repository into your repository as you
desire).
2. Download the current newsgroup list from:
diff --git a/t/data/generate/control-archive/output/readme-md b/t/data/generate/control-archive/output/readme-md
index d6cd952..02d859b 100644
--- a/t/data/generate/control-archive/output/readme-md
+++ b/t/data/generate/control-archive/output/readme-md
@@ -1,4 +1,4 @@
-# control-archive 1.8.0
+# control-archive
Copyright 2002-2004, 2007-2014, 2016-2018 Russ Allbery <eagle@eyrie.org>.
Copyright 2001 Marco d'Itri. Copyright 1996 UUNET Technologies, Inc..
@@ -157,15 +157,15 @@ articles by tokens. This could be easily added; I just haven't needed it.
If you're using tinyleaf, here is the setup process:
1. Create a directory that tinyleaf will use to store incoming articles
- temporarily, the archive directory, and the logs directory and
- install the software:
+ temporarily, the archive directory, and the logs directory and install
+ the software:
```sh
make install
```
-2. Run tinyleaf on some port, configuring it to use that directory and
- to run process-control. A typical tinyleaf command line would be:
+2. Run tinyleaf on some port, configuring it to use that directory and to
+ run process-control. A typical tinyleaf command line would be:
```sh
tinyleaf /srv/control/spool /srv/control/scripts/process-control
diff --git a/t/data/generate/control-archive/output/thread b/t/data/generate/control-archive/output/thread
index 20bf4b8..0b4d96b 100644
--- a/t/data/generate/control-archive/output/thread
+++ b/t/data/generate/control-archive/output/thread
@@ -23,9 +23,9 @@
\quote[
- Usenet is like a herd of performing elephants with diarrhea —
- massive, difficult to redirect, awe-inspiring, entertaining, and a
- source of mind-boggling amounts of excrement when you least expect it.
+ Usenet is like a herd of performing elephants with diarrhea — massive,
+ difficult to redirect, awe-inspiring, entertaining, and a source of
+ mind-boggling amounts of excrement when you least expect it.
][Gene Spafford][]
diff --git a/t/data/generate/docknot/output/thread b/t/data/generate/docknot/output/thread
index 0e4e46c..4d39ac3 100644
--- a/t/data/generate/docknot/output/thread
+++ b/t/data/generate/docknot/output/thread
@@ -41,7 +41,7 @@
\link[todo.html][To-do list] \break
\link[https://github.com/rra/docknot]
[GitHub] \break
- \link[https://rt.cpan.org/Dist/Display.html?Name=App-DocKnot]
+ \link[https://github.com/rra/docknot/issues]
[Bug tracker] \break
\link[https://git.eyrie.org/?p=devel/docknot.git]
[Git repository] \break
@@ -52,11 +52,11 @@
\h2[Blurb]
DocKnot is a system for generating consistent human-readable software
-package documentation from metadata files and templates. The metadata is
-primarily JSON files, but can include files of documentation snippets.
-The goal is to generate both web pages and distributed documentation files
-(such as \code[README]) from the same source, using templates for
-consistency across multiple packages.
+package documentation from a YAML metadata file and templates. The goal
+is to generate both web pages and distributed documentation files (such as
+\code[README]) from the same source, using templates for consistency
+across multiple packages. DocKnot also automates generating distribution
+tarballs for software packages.
\h2[Description]
@@ -69,7 +69,7 @@ last straw was when GitHub became popular and I wanted to provide a
Markdown version of \code[README] as well, avoiding the ugly text
rendering on the GitHub page for a package.
-This package uses one metadata directory as its source information and
+This package uses one metadata file as its source information and
generates all the various bits of documentation for a package. This
allows me to make any changes in one place and then just regenerate the
web page, included documentation, and other files to incorporate those
@@ -77,6 +77,10 @@ changes. It also lets me make changes to the templates to improve shared
wording and push that out to every package I maintain during its next
release, without having to remember which changes I wanted to make.
+DocKnot is also slowly absorbing other tools that I use for software
+distribution and web site maintenance, such as generating distribution
+tarballs for software packages.
+
DocKnot was designed and written for my personal needs, and I'm not sure
it will be useful for anyone else. At the least, the template files are
rather specific to my preferences about how to write package
@@ -102,9 +106,11 @@ The following additional Perl modules are required to use it:
\bullet(packed)[IPC::Run]
\bullet(packed)[IPC::System::Simple]
\bullet(packed)[JSON::MaybeXS]
+\bullet(packed)[Kwalify]
\bullet(packed)[List::SomeUtils]
\bullet(packed)[Perl6::Slurp]
\bullet(packed)[Template (part of Template Toolkit)]
+\bullet(packed)[YAML::XS]
\h2[Download]
@@ -150,7 +156,7 @@ development source].
\doc[todo.html][To-do list]
\doc[https://github.com/rra/docknot]
[GitHub]
- \doc[https://rt.cpan.org/Dist/Display.html?Name=App-DocKnot]
+ \doc[https://github.com/rra/docknot/issues]
[Bug tracker]
]
@@ -163,6 +169,7 @@ development source].
\doc[api/app-docknot-config.html][App::DocKnot::Config]
\doc[api/app-docknot-dist.html][App::DocKnot::Dist]
\doc[api/app-docknot-generate.html][App::DocKnot::Generate]
+ \doc[api/app-docknot-update.html][App::DocKnot::Update]
]
\h2(after)[License]
diff --git a/t/data/generate/lbcd/docknot.yaml b/t/data/generate/lbcd/docknot.yaml
new file mode 100644
index 0000000..6dbffa9
--- /dev/null
+++ b/t/data/generate/lbcd/docknot.yaml
@@ -0,0 +1,122 @@
+format: v1
+
+name: lbcd
+maintainer: Russ Allbery <eagle@eyrie.org>
+version: 3.4.2
+synopsis: responder for load balancing
+
+license:
+ name: Expat
+copyrights:
+ - holder: The Board of Trustees of the Leland Stanford Junior University
+ years: 1993-1994, 1996-1998, 2000, 2003-2009, 2012-2013
+
+build:
+ autoconf: '2.64'
+ automake: '1.11'
+ autotools: true
+ middle: |
+ lbcd looks for `$sysconfdir/nolbcd` and returns the maximum load if that
+ file is present, allowing one to effectively drop a system out of a
+ load-balanced pool by touching that file. By default, the path is
+ `/usr/local/etc/nolbcd`, but you may want to pass `--sysconfdir=/etc` to
+ configure to use `/etc/nolbcd`.
+
+ lbcdclient is written in Perl, so you may have to edit the first line of
+ the script to point to the correct Perl location on your system. It does
+ not use any sophisticated Perl features or add-on modules.
+ suffix: |
+ You will generally want to start lbcd at system boot. All that is needed
+ is a simple init script to start lbcd with the appropriate options or kill
+ it again. It writes its PID into `/var/run/lbcd.pid` by default (and this
+ can be changed with the `-P` option). On many systems, lbcd will need to
+ run as root or as a member of particular groups to obtain system load
+ average and uptime information.
+ type: Autoconf
+distribution:
+ packaging:
+ debian:
+ package: lbcd
+ summary: |
+ A Debian package is included in Debian 5.0 (lenny) and later
+ releases. Thanks to Guido Guenther for doing the initial upload
+ to Debian.
+ section: system
+ tarname: lbcd
+ version: lbcd
+support:
+ email: eagle@eyrie.org
+ listname: lbnamed-users
+ listurl: https://mailman.stanford.edu/mailman/listinfo/lbnamed-users
+ web: https://www.eyrie.org/~eagle/software/lbcd/
+vcs:
+ browse: https://git.eyrie.org/?p=system/lbcd.git
+ github: rra/lbcd
+ type: Git
+ url: https://git.eyrie.org/git/system/lbcd.git
+
+docs:
+ user:
+ - name: lbcd
+ title: lbcd manual page
+ - name: lbcdclient
+ title: lbcdclient manual page
+
+blurb: |
+ lbcd is a daemon that runs on a UNIX system and answers UDP queries with
+ information about system load, number of logged-on users, uptime, and free
+ /tmp space. This information can be used to accumulate system status
+ across a cluster with light-weight queries or can be used as input to a
+ load-balancing system to choose the best system to which to direct new
+ incoming connections.
+
+orphaned: |
+ Although I believe it is still useful, I no longer use this method of DNS
+ load balancing and am no longer maintaining this package. If you would
+ like to pick up maintenance of it, please feel free. Contact me if you
+ would like this page to redirect to its new home.
+
+description: |
+ lbcd provides a lightweight way to query a system via unauthenticated UDP
+ for system load information plus some related information that may be
+ relevant to determining which system to hand out. It was designed for use
+ with the [lbnamed DNS load
+ balancer](https://www.stanford.edu/~riepel/lbnamed/). System load, number
+ of logged-in users, free /tmp space, and system uptime are always
+ returned. lbcd can also be configured to probe various local services and
+ modify the returned weights based on whether those services are reachable,
+ or to return a static weight for round-robin load balancing.
+
+ The information provided isn't particularly sophisticated, and a good
+ hardware load balancer will be able to consider such things as connection
+ latency and responsiveness to make better decisions. However, lbcd with
+ lbnamed works quite well for smaller scale problems, scales well to
+ multiple load balance pools for different services, provides a simple UDP
+ health check service, and is much simpler and cheaper to understand and
+ deploy.
+
+ Included in this package is a small client program, lbcdclient, which can
+ query an lbcd server and display a formatted version of the returned
+ information.
+
+ It was originally written by Roland Schemers. Larry Schwimmer rewrote it
+ to add protocol version 3 with some additional features and service
+ probing, and then I rewrote it again to update the coding style and use my
+ standard portability layer.
+
+requirements: |
+ lbcd is written in C, so you'll need a C compiler. It also uses kernel
+ calls to obtain load and uptime information, and at present has only been
+ ported to Linux, Solaris, AIX, various BSD systems, Mac OS X, HP-UX, IRIX,
+ and Tru64. It is currently primarily tested on Linux. Platforms not
+ listed may require some porting effort, as may old or unusual platforms
+ that aren't regularly tested.
+
+ The lbcdclient program requires Perl 5.6 or later and requires the
+ IO::Socket::INET6 module for IPv6 support.
+
+test:
+ lancaster: true
+ suffix: |
+ Currently, the test suite only checks the portability and utility
+ libraries, not the functionality of lbcd or lbcdclient.
diff --git a/t/data/generate/lbcd/output/readme-md b/t/data/generate/lbcd/output/readme-md
index cd86c13..3e7a939 100644
--- a/t/data/generate/lbcd/output/readme-md
+++ b/t/data/generate/lbcd/output/readme-md
@@ -1,7 +1,7 @@
-# lbcd 3.4.2
+# lbcd
[![No maintenance
-intended](http://unmaintained.tech/badge.svg)](http://unmaintained.tech/)
+intended](https://unmaintained.tech/badge.svg)](https://unmaintained.tech/)
[![Debian
package](https://img.shields.io/debian/v/lbcd/unstable)](https://tracker.debian.org/pkg/lbcd)
diff --git a/t/data/generate/pam-krb5/docknot.yaml b/t/data/generate/pam-krb5/docknot.yaml
new file mode 100644
index 0000000..cf4ce0b
--- /dev/null
+++ b/t/data/generate/pam-krb5/docknot.yaml
@@ -0,0 +1,533 @@
+format: v1
+
+name: pam-krb5
+maintainer: Russ Allbery <eagle@eyrie.org>
+version: '4.8'
+synopsis: PAM module for Kerberos authentication
+
+license:
+ name: BSD-3-clause-or-GPL-1+
+copyrights:
+ - holder: Russ Allbery <eagle@eyrie.org>
+ years: 2005-2010, 2014-2015, 2017
+ - holder: The Board of Trustees of the Leland Stanford Junior University
+ years: 2009-2011
+ - holder: Andres Salomon <dilinger@debian.org>
+ years: '2005'
+ - holder: Frank Cusack <fcusack@fcusack.com>
+ years: 1999-2000
+
+build:
+ autoconf: '2.64'
+ automake: '1.11'
+ autotools: true
+ kerberos: true
+ manpages: true
+ middle: |
+ The module will be installed in `/usr/local/lib/security` by default,
+ except on 64-bit versions of Linux which will use
+ `/usr/local/lib64/security` to match the default PAM configuration. You
+ can change the installation locations with the `--prefix`, `--mandir`, and
+ `--libdir` options to configure. The module will always be installed in a
+ subdirectory named `security` under the specified libdir. On Linux, use
+ `--prefix=/usr` to install the man page into `/usr/share/man` and the PAM
+ module in `/lib/security` or `/lib64/security`.
+ reduced_depends: true
+ type: Autoconf
+distribution:
+ packaging:
+ debian:
+ package: libpam-krb5
+ summary: |
+ Debian packages are available from Debian in Debian 4.0 (etch) and
+ later releases as libpam-krb5 and libpam-heimdal. The former
+ packages are built against the MIT Kerberos libraries and the
+ latter against the Heimdal libraries.
+ section: kerberos
+ tarname: pam-krb5
+ version: pam-krb5
+support:
+ email: eagle@eyrie.org
+ github: rra/pam-krb5
+ web: https://www.eyrie.org/~eagle/software/pam-krb5/
+vcs:
+ browse: https://git.eyrie.org/?p=kerberos/pam-krb5.git
+ github: rra/pam-krb5
+ openhub: https://www.openhub.net/p/pamkrb5
+ type: Git
+ url: https://git.eyrie.org/git/kerberos/pam-krb5.git
+
+quote:
+ author: Joyce McGreevy
+ date: 2003-11-17
+ text: |
+ "You're always going to have some people who can't appreciate the thrill
+ of a tepid change for the somewhat better," explained one source.
+ title: '"Look, ma, no hands!"'
+ work: Salon
+advisories:
+ - date: 2009-02-11
+ threshold: '3.13'
+ versions: 3.12 and earlier
+docs:
+ user:
+ - name: pam-krb5
+ title: Manual page
+
+blurb: |
+ pam-krb5 is a Kerberos PAM module for either MIT Kerberos or Heimdal. It
+ supports ticket refreshing by screen savers, configurable authorization
+ handling, authentication of non-local accounts for network services,
+ password changing, and password expiration, as well as all the standard
+ expected PAM features. It works correctly with OpenSSH, even with
+ ChallengeResponseAuthentication and PrivilegeSeparation enabled, and
+ supports extensive configuration either by PAM options or in krb5.conf or
+ both. PKINIT is supported with recent versions of both MIT Kerberos and
+ Heimdal and FAST is supported with recent MIT Kerberos.
+
+description: |
+ pam-krb5 provides a Kerberos PAM module that supports authentication, user
+ ticket cache handling, simple authorization (via .k5login or checking
+ Kerberos principals against local usernames), and password changing. It
+ can be configured through either options in the PAM configuration itself
+ or through entries in the system krb5.conf file, and it tries to work
+ around PAM implementation flaws in commonly-used PAM-enabled applications
+ such as OpenSSH and xdm. It supports both PKINIT and FAST to the extent
+ that the underlying Kerberos libraries support these features.
+
+ This is not the Kerberos PAM module maintained on Sourceforge and used on
+ Red Hat systems. It is an independent implementation that, if it ever
+ shared any common code, diverged long ago. It supports some features that
+ the Sourceforge module does not (particularly around authorization), and
+ does not support some options (particularly ones not directly related to
+ Kerberos) that it does. This module will never support Kerberos v4 or
+ AFS. For an AFS session module that works with this module (or any other
+ Kerberos PAM module), see
+ [pam-afs-session](https://www.eyrie.org/~eagle/software/pam-afs-session/).
+
+ If there are other options besides AFS and Kerberos v4 support from the
+ Sourceforge PAM module that you're missing in this module, please let me
+ know.
+
+sections:
+ - title: Configuring
+ body: |
+ Just installing the module does not enable it or change anything
+ about your system authentication configuration. To use the module
+ for all system authentication on Debian systems, put something like:
+
+ ```
+ auth sufficient pam_krb5.so minimum_uid=1000
+ auth required pam_unix.so try_first_pass nullok_secure
+ ```
+
+ in `/etc/pam.d/common-auth`, something like:
+
+ ```
+ session optional pam_krb5.so minimum_uid=1000
+ session required pam_unix.so
+ ```
+
+ in `/etc/pam.d/common-session`, and something like:
+
+ ```
+ account required pam_krb5.so minimum_uid=1000
+ account required pam_unix.so
+ ```
+
+ in `/etc/pam.d/common-account`. The `minimum_uid` setting tells the
+ PAM module to pass on any users with a UID lower than 1000, thereby
+ bypassing Kerberos authentication for the root account and any
+ system accounts. You normally want to do this since otherwise, if
+ the network is down, the Kerberos authentication can time out and
+ make it difficult to log in as root and fix matters. This also
+ avoids problems with Kerberos principals that happen to match system
+ accounts accidentally getting access to those accounts.
+
+ Be sure to include the module in the session group as well as the
+ auth group. Without the session entry, the user's ticket cache will
+ not be created properly for ssh logins (among possibly others).
+
+ If your users should normally all use Kerberos passwords
+ exclusively, putting something like:
+
+ ```
+ password sufficient pam_krb5.so minimum_uid=1000
+ password required pam_unix.so try_first_pass obscure md5
+ ```
+
+ in `/etc/pam.d/common-password` will change users' passwords in
+ Kerberos by default and then only fall back on Unix if that doesn't
+ work. (You can make this tighter by using the more complex
+ new-style PAM configuration.) If you instead want to synchronize
+ local and Kerberos passwords and change them both at the same time,
+ you can do something like:
+
+ ```
+ password required pam_unix.so obscure sha512
+ password required pam_krb5.so use_authtok minimum_uid=1000
+ ```
+
+ If you have multiple environments that you want to synchronize and
+ you don't want password changes to continue if the Kerberos password
+ change fails, use the `clear_on_fail` option. For example:
+
+ ```
+ password required pam_krb5.so clear_on_fail minimum_uid=1000
+ password required pam_unix.so use_authtok obscure sha512
+ password required pam_smbpass.so use_authtok
+ ```
+
+ In this case, if `pam_krb5` cannot change the password (due to
+ password strength rules on the KDC, for example), it will clear the
+ stored password (because of the `clear_on_fail` option), and since
+ `pam_unix` and `pam_smbpass` are both configured with `use_authtok`,
+ they will both fail. `clear_on_fail` is not the default because it
+ would interfere with the more common pattern of falling back to
+ local passwords if the user doesn't exist in Kerberos.
+
+ If you use a more complex configuration with the Linux PAM `[]`
+ syntax for the session and account groups, note that `pam_krb5`
+ returns a status of ignore, not success, if the user didn't log on
+ with Kerberos. You may need to handle that explicitly with
+ `ignore=ignore` in your action list.
+
+ There are many, many other possibilities. See the Linux PAM
+ documentation for all the configuration options.
+
+ On Red Hat systems, modify `/etc/pam.d/system-auth` instead, which
+ contains all of the configuration for the different stacks.
+
+ You can also use pam-krb5 only for specific services. In that case,
+ modify the files in `/etc/pam.d` for that particular service to use
+ `pam_krb5.so` for authentication. For services that are using
+ passwords over TLS to authenticate users, you may want to use the
+ `ignore_k5login` and `no_ccache` options to the authenticate module.
+ `.k5login` authorization is only meaningful for local accounts and
+ ticket caches are usually (although not always) only useful for
+ interactive sessions.
+
+ Configuring the module for Solaris is both simpler and less
+ flexible, since Solaris (at least Solaris 8 and 9, which are the
+ last versions of Solaris with which this module was extensively
+ tested) use a single `/etc/pam.conf` file that contains
+ configuration for all programs. For console login on Solaris, try
+ something like:
+
+ ```
+ login auth sufficient /usr/local/lib/security/pam_krb5.so minimum_uid=100
+ login auth required /usr/lib/security/pam_unix_auth.so.1 use_first_pass
+ login account required /usr/local/lib/security/pam_krb5.so minimum_uid=100
+ login account required /usr/lib/security/pam_unix_account.so.1
+ login session required /usr/local/lib/security/pam_krb5.so retain_after_close minimum_uid=100
+ login session required /usr/lib/security/pam_unix_session.so.1
+ ```
+
+ A similar configuration could be used for other services, such as
+ ssh. See the pam.conf(5) man page for more information. When using
+ this module with Solaris login (at least on Solaris 8 and 9), you
+ will probably also need to add `retain_after_close` to the PAM
+ configuration to avoid having the user's credentials deleted before
+ they are logged in.
+
+ The Solaris Kerberos library reportedly does not support prompting
+ for a password change of an expired account during authentication.
+ Supporting password change for expired accounts on Solaris with
+ native Kerberos may therefore require setting the `defer_pwchange`
+ or `force_pwchange` option for selected login applications. See the
+ description and warnings about that option in the pam_krb5(5) man
+ page.
+
+ Some configuration options may be put in the `krb5.conf` file used
+ by your Kerberos libraries (usually `/etc/krb5.conf` or
+ `/usr/local/etc/krb5.conf`) instead or in addition to the PAM
+ configuration. See the man page for more details.
+
+ The Kerberos library, via pam-krb5, will prompt the user to change
+ their password if their password is expired, but when using OpenSSH,
+ this will only work when `ChallengeResponseAuthentication` is
+ enabled. Unless this option is enabled, OpenSSH doesn't pass PAM
+ messages to the user and can only respond to a simple password
+ prompt.
+
+ If you are using MIT Kerberos, be aware that users whose passwords
+ are expired will not be prompted to change their password unless the
+ KDC configuration for your realm in `[realms]` in `krb5.conf`
+ contains a `master_kdc` setting or, if using DNS SRV records, you
+ have a DNS entry for `_kerberos-master` as well as `_kerberos`.
+ - title: Debugging
+ body: |
+ The first step when debugging any problems with this module is to
+ add `debug` to the PAM options for the module (either in the PAM
+ configuration or in `krb5.conf`). This will significantly increase
+ the logging from the module and should provide a trace of exactly
+ what failed and any available error information.
+
+ Many Kerberos authentication problems are due to configuration
+ issues in `krb5.conf`. If pam-krb5 doesn't work, first check that
+ `kinit` works on the same system. That will test your basic
+ Kerberos configuration. If the system has a keytab file installed
+ that's readable by the process doing authentication via PAM, make
+ sure that the keytab is current and contains a key for
+ `host/<system>` where <system> is the fully-qualified hostname.
+ pam-krb5 prevents KDC spoofing by checking the user's credentials
+ when possible, but this means that if a keytab is present it must be
+ correct or authentication will fail. You can check the keytab with
+ `klist -k` and `kinit -k`.
+
+ Be sure that all libraries and modules, including PAM modules,
+ loaded by a program use the same Kerberos libraries. Sometimes
+ programs that use PAM, such as current versions of OpenSSH, also
+ link against Kerberos directly. If your sshd is linked against one
+ set of Kerberos libraries and pam-krb5 is linked against a different
+ set of Kerberos libraries, this will often cause problems (such as
+ segmentation faults, bus errors, assertions, or other strange
+ behavior). Similar issues apply to the com_err library or any other
+ library used by both modules and shared libraries and by the
+ application that loads them. If your OS ships Kerberos libraries,
+ it's usually best if possible to build all Kerberos software on the
+ system against those libraries.
+ - title: Implementation Notes
+ body: |
+ The normal sequence of actions taken for a user login is:
+
+ ```
+ pam_authenticate
+ pam_setcred(PAM_ESTABLISH_CRED)
+ pam_open_session
+ pam_acct_mgmt
+ ```
+
+ and then at logout:
+
+ ```
+ pam_close_session
+ ```
+
+ followed by closing the open PAM session. The corresponding
+ `pam_sm_*` functions in this module are called when an application
+ calls those public interface functions. Not all applications call
+ all of those functions, or in particularly that order, although
+ `pam_authenticate` is always first and has to be.
+
+ When `pam_authenticate` is called, pam-krb5 creates a temporary
+ ticket cache in `/tmp` and sets the PAM environment variable
+ `PAM_KRB5CCNAME` to point to it. This ticket cache will be
+ automatically destroyed when the PAM session is closed and is there
+ only to pass the initial credentials to the call to `pam_setcred`.
+ The module would use a memory cache, but memory caches will only
+ work if the application preserves the PAM environment between the
+ calls to `pam_authenticate` and `pam_setcred`. Most do, but OpenSSH
+ notoriously does not and calls `pam_authenticate` in a subprocess,
+ so this method is used to pass the tickets to the `pam_setcred` call
+ in a different process.
+
+ `pam_authenticate` does a complete authentication, including
+ checking the resulting TGT by obtaining a service ticket for the
+ local host if possible, but this requires read access to the system
+ keytab. If the keytab doesn't exist, can't be read, or doesn't
+ include the appropriate credentials, the default is to accept the
+ authentication. This can be controlled by setting
+ `verify_ap_req_nofail` to true in `[libdefaults]` in
+ `/etc/krb5.conf`. `pam_authenticate` also does a basic
+ authorization check, by default calling `krb5_kuserok` (which uses
+ `~/.k5login` if available and falls back to checking that the
+ principal corresponds to the account name). This can be customized
+ with several options documented in the pam_krb5(5) man page.
+
+ pam-krb5 treats `pam_open_session` and
+ `pam_setcred(PAM_ESTABLISH_CRED)` as synonymous, as some
+ applications call one and some call the other. Both copy the
+ initial credentials from the temporary cache into a permanent cache
+ for this session and set `KRB5CCNAME` in the environment. It will
+ remember when the credential cache has been established and then
+ avoid doing any duplicate work afterwards, since some applications
+ call `pam_setcred` or `pam_open_session` multiple times (most
+ notably X.Org 7 and earlier xdm, which also throws away the module
+ settings the last time it calls them).
+
+ `pam_acct_mgmt` finds the ticket cache, reads it in to obtain the
+ authenticated principal, and then does is another authorization
+ check against `.k5login` or the local account name as described
+ above.
+
+ After the call to `pam_setcred` or `pam_open_session`, the ticket
+ cache will be destroyed whenever the calling application either
+ destroys the PAM environment or calls `pam_close_session`, which it
+ should do on user logout.
+
+ The normal sequence of events when refreshing a ticket cache (such
+ as inside a screensaver) is:
+
+ ```
+ pam_authenticate
+ pam_setcred(PAM_REINITIALIZE_CRED)
+ pam_acct_mgmt
+ ```
+
+ (`PAM_REFRESH_CRED` may be used instead.) Authentication proceeds
+ as above. At the `pam_setcred` stage, rather than creating a new
+ ticket cache, the module instead finds the current ticket cache
+ (from the `KRB5CCNAME` environment variable or the default ticket
+ cache location from the Kerberos library) and then reinitializes it
+ with the credentials from the temporary `pam_authenticate` ticket
+ cache. When refreshing a ticket cache, the application should not
+ open a session. Calling `pam_acct_mgmt` is optional; pam-krb5
+ doesn't do anything different when it's called in this case.
+
+ If `pam_authenticate` apparently didn't succeed, or if an account
+ was configured to be ignored via `ignore_root` or `minimum_uid`,
+ `pam_setcred` (and therefore `pam_open_session`) and `pam_acct_mgmt`
+ return `PAM_IGNORE`, which tells the PAM library to proceed as if
+ that module wasn't listed in the PAM configuration at all.
+ `pam_authenticate`, however, returns failure in the ignored user
+ case by default, since otherwise a configuration using `ignore_root`
+ with pam-krb5 as the only PAM module would allow anyone to log in as
+ root without a password. There doesn't appear to be a case where
+ returning `PAM_IGNORE` instead would improve the module's behavior,
+ but if you know of a case, please let me know.
+
+ By default, `pam_authenticate` intentionally does not follow the PAM
+ standard for handling expired accounts and instead returns failure
+ from `pam_authenticate` unless the Kerberos libraries are able to
+ change the account password during authentication. Too many
+ applications either do not call `pam_acct_mgmt` or ignore its exit
+ status. The fully correct PAM behavior (returning success from
+ `pam_authenticate` and `PAM_NEW_AUTHTOK_REQD` from `pam_acct_mgmt`)
+ can be enabled with the `defer_pwchange` option.
+
+ The `defer_pwchange` option is unfortunately somewhat tricky to
+ implement. In this case, the calling sequence is:
+
+ ```
+ pam_authenticate
+ pam_acct_mgmt
+ pam_chauthtok
+ pam_setcred
+ pam_open_session
+ ```
+
+ During the first `pam_authenticate`, we can't obtain credentials and
+ therefore a ticket cache since the password is expired. But
+ `pam_authenticate` isn't called again after `pam_chauthtok`, so
+ `pam_chauthtok` has to create a ticket cache. We however don't want
+ it to do this for the normal password change (`passwd`) case.
+
+ What we do is set a flag in our PAM data structure saying that we're
+ processing an expired password, and `pam_chauthtok`, if it sees that
+ flag, redoes the authentication with password prompting disabled
+ after it finishes changing the password.
+
+ Unfortunately, when handling password changes this way,
+ `pam_chauthtok` will always have to prompt the user for their
+ current password again even though they just typed it. This is
+ because the saved authentication tokens are cleared after
+ `pam_authenticate` returns, for security reasons. We could hack
+ around this by saving the password in our PAM data structure, but
+ this would let the application gain access to it (exactly what the
+ clearing is intended to prevent) and breaks a PAM library guarantee.
+ We could also work around this by having `pam_authenticate` get the
+ `kadmin/changepw` authenticator in the expired password case and
+ store it for `pam_chauthtok`, but it doesn't seem worth the hassle.
+ - title: History and Acknowledgements
+ body: |
+ Originally written by Frank Cusack <fcusack@fcusack.com>, with the
+ following acknowledgement:
+
+ > Thanks to Naomaru Itoi <itoi@eecs.umich.edu>, Curtis King
+ > <curtis.king@cul.ca>, and Derrick Brashear <shadow@dementia.org>,
+ > all of whom have written and made available Kerberos 4/5 modules.
+ > Although no code in this module is directly from these author's
+ > modules, (except the get_user_info() routine in support.c; derived
+ > from whichever of these authors originally wrote the first module
+ > the other 2 copied from), it was extremely helpful to look over
+ > their code which aided in my design.
+
+ The module was then patched for the FreeBSD ports collection with
+ additional modifications by unknown maintainers and then was
+ modified by Joel Kociolek <joko@logidee.com> to be usable with
+ Debian GNU/Linux.
+
+ It was packaged by Sam Hartman as the Kerberos v5 PAM module for
+ Debian and improved and modified by him and later by Russ Allbery to
+ fix bugs and add additional features. It was then adopted by Andres
+ Salomon, who added support for refreshing credentials.
+
+ The current distribution is maintained by Russ Allbery, who also
+ added support for reading configuration from `krb5.conf`, added many
+ features for compatibility with the Sourceforge module, commented
+ and standardized the formatting of the code, and overhauled the
+ documentation.
+
+ Thanks to Douglas E. Engert for the initial implementation of PKINIT
+ support. I have since modified and reworked it extensively, so any
+ bugs or compilation problems are my fault.
+
+ Thanks to Markus Moeller for lots of debugging and multiple patches
+ and suggestions for improved portability.
+
+ Thanks to Booker Bense for the implementation of the `alt_auth_map`
+ option.
+
+ Thanks to Sam Hartman for the FAST support implementation.
+
+requirements: |
+ Either MIT Kerberos (or Kerberos implementations based on it) or Heimdal
+ are supported. MIT Keberos 1.3 or later may be required; this module has
+ not been tested with earlier versions.
+
+ For PKINIT support, Heimdal 0.8rc1 or later or MIT Kerberos 1.6.3 or later
+ are required. Earlier MIT Kerberos 1.6 releases have a bug in their
+ handling of PKINIT options.
+
+ For FAST (Flexible Authentication Secure Tunneling) support, MIT Kerberos
+ 1.7 or higher is required. For anonymous FAST support, anonymous
+ authentication (generally anonymous PKINIT) support is required in both
+ the Kerberos libraries and in the local KDC.
+
+ This module should work on Linux and Solaris (and build with gcc, clang,
+ or the Sun C compiler), but has been far more heavily tested on Linux.
+ There is beta-quality support for the AIX NAS Kerberos implementation.
+ Other PAM implementations will probably require some porting, although
+ untested build system support is present for FreeBSD, Mac OS X, and HP-UX.
+ I personally can only test on Linux and rely on others to report problems
+ on other operating systems.
+
+ Old versions of OpenSSH are known to call `pam_authenticate` followed by
+ `pam_setcred(PAM_REINITIALIZE_CRED)` without first calling
+ `pam_open_session`, thereby requesting that an existing ticket cache be
+ renewed (similar to what a screensaver would want) rather than requesting
+ a new ticket cache be created. Since this behavior is indistinguishable
+ at the PAM level from a screensaver, pam-krb5 when used with these old
+ versions of OpenSSH will refresh the ticket cache of the OpenSSH daemon
+ rather than setting up a new ticket cache for the user. The resulting
+ ticket cache will have the correct permissions (this is not a security
+ concern), but will not be named correctly or referenced in the user's
+ environment and will be overwritten by the next user login. The best
+ solution to this problem is to upgrade OpenSSH. I'm not sure exactly when
+ this problem was fixed, but at the very least OpenSSH 4.3 and later do not
+ exhibit it.
+
+test:
+ prefix: |
+ pam-krb5 comes with a comprehensive test suite, but it requires some
+ configuration in order to test anything other than low-level utility
+ functions. For the full test suite, you will need to have a running KDC
+ in which you can create two test accounts, one with admin access to the
+ other. Using a test KDC environment, if you have one, is recommended.
+
+ Follow the instructions in `tests/config/README` to configure the test
+ suite.
+
+ Now, you can run the test suite with:
+ suffix: |
+ The default libkadm5clnt library on the system must match the
+ implementation of your KDC for the module/expired test to work, since the
+ two kadmin protocols are not compatible. If you use the MIT library
+ against a Heimdal server, the test will be skipped; if you use the Heimdal
+ library against an MIT server, the test suite may hang.
+
+ Several `module/expired` tests are expected to fail with Heimdal 1.5 due
+ to a bug in Heimdal with reauthenticating immediately after a
+ library-mediated password change of an expired password. This is fixed in
+ later releases of Heimdal.
diff --git a/t/data/generate/pam-krb5/metadata/README b/t/data/generate/pam-krb5/metadata/README
deleted file mode 100644
index 26316da..0000000
--- a/t/data/generate/pam-krb5/metadata/README
+++ /dev/null
@@ -1,6 +0,0 @@
-This directory contains configuration for DocKnot used to generate
-documentation files (like README.md) and web pages. Other documentation
-in this package is generated automatically from these files as part of the
-release process. For more information, see DocKnot's documentation.
-
-DocKnot is available from <https://www.eyrie.org/~eagle/software/docknot/>.
diff --git a/t/data/generate/pam-krb5/output/readme b/t/data/generate/pam-krb5/output/readme
index 755e5e7..5d6e7a0 100644
--- a/t/data/generate/pam-krb5/output/readme
+++ b/t/data/generate/pam-krb5/output/readme
@@ -582,10 +582,12 @@ LICENSE
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
+ documentation and/or other materials provided with the
+ distribution.
- 3. The name of the author may not be used to endorse or promote products
- derived from this software without specific prior written permission.
+ 3. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
ALTERNATIVELY, this product may be distributed under the terms of the
GNU General Public License, in which case the provisions of the GPL
diff --git a/t/data/generate/pam-krb5/output/readme-md b/t/data/generate/pam-krb5/output/readme-md
index 1902bf0..9834f04 100644
--- a/t/data/generate/pam-krb5/output/readme-md
+++ b/t/data/generate/pam-krb5/output/readme-md
@@ -1,4 +1,4 @@
-# pam-krb5 4.8
+# pam-krb5
[![Debian
package](https://img.shields.io/debian/v/libpam-krb5/unstable)](https://tracker.debian.org/pkg/libpam-krb5)
@@ -140,11 +140,11 @@ you need to specify a different Kerberos installation root via
You can also individually set the paths to the include directory and the
library directory with `--with-krb5-include` and `--with-krb5-lib`. You
-may need to do this if Autoconf can't figure out whether to use lib,
-lib32, or lib64 on your platform.
+may need to do this if Autoconf can't figure out whether to use `lib`,
+`lib32`, or `lib64` on your platform.
-To not use krb5-config and force library probing even if there is a
-krb5-config script on your path, set PATH_KRB5_CONFIG to a nonexistent
+To not use `krb5-config` and force library probing even if there is a
+`krb5-config` script on your path, set `PATH_KRB5_CONFIG` to a nonexistent
path:
```
diff --git a/t/data/generate/pgp-sign/docknot.yaml b/t/data/generate/pgp-sign/docknot.yaml
new file mode 100644
index 0000000..dfaddd4
--- /dev/null
+++ b/t/data/generate/pgp-sign/docknot.yaml
@@ -0,0 +1,114 @@
+format: v1
+
+name: PGP::Sign
+maintainer: Russ Allbery <rra@cpan.org>
+version: '1.00'
+synopsis: create and verify detached PGP signatures
+
+license:
+ name: Perl
+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
+ github: rra/pgp-sign
+ web: https://www.eyrie.org/~eagle/software/pgp-sign/
+vcs:
+ browse: https://git.eyrie.org/?p=perl/pgp-sign.git
+ github: rra/pgp-sign
+ status:
+ workflow: build
+ type: Git
+ url: https://git.eyrie.org/git/perl/pgp-sign.git
+
+quote:
+ author: William Shakespeare
+ broken: true
+ text: |
+ This above all: to thine own self be true,
+ And it must follow, as the night the day,
+ Thou canst not then be false to any man.
+ work: Hamlet
+docs:
+ user:
+ - name: docs
+ title: Module documentation
+ - name: thanks
+ title: Thanks and credits
+
+blurb: |
+ PGP::Sign is a Perl module for generating and verifying detached OpenPGP
+ signatures of textual data using GnuPG. It was written to support Netnews
+ article signatures for signed control messages and PGPMoose.
+
+description: |
+ PGP::Sign is a Perl module that can generate and verify OpenPGP signatures
+ on some data. Currently, only textual data (data that can be processed
+ using GnuPG's `--textmode` option) is supported. It uses GnuPG under the
+ hood to do the work.
+
+ The original purpose of this module was to factor out common code in a
+ News::Article class written by Andrew Gierth that handled PGPMoose and
+ control message signatures. It is used to verify control message
+ signatures for the ftp.isc.org Netnews metadata archive, and to generate
+ signed control messages for the Big Eight Usenet hierarchies.
+
+ Data to be signed or verified can be passed into PGP::Sign in a wide
+ variety of formats: scalars, arrays, open files, even code references that
+ act as generators. Keys with passphrases are supported and the passphrase
+ is passed to GnuPG securely (although getting the passphrase to the
+ PGP::Sign module is a problem for the calling application).
+
+ This module supports both GnuPG v2 and GnuPG v1 and, when used with GnuPG
+ v1, supports using OpenPGP keys and generating and verifying signatures
+ that are backward-compatible with PGP 2.6.2.
+
+ PGP::Sign provides both a (recommended) object-oriented API and a (legacy)
+ function-based API that uses global variables for configuration and is
+ backward-compatible with earlier versions of PGP::Sign.
+
+requirements: |
+ Perl 5.20 or later and Module::Build are required to build this module,
+ and IPC::Run is required to use it. Either GnuPG v2 or GnuPG v1
+ (selectable at runtime) is also required. It has not been tested with
+ versions of GnuPG older than 1.4.23.
+
+ PGP::Sign uses IPC::Run features that are documented as not available on
+ Windows (primarily higher-numbered file descriptors) and has never been
+ tested with Gpg4win, so will probably not work on Windows (or, for that
+ matter, other non-UNIX systems).
+
+test:
+ lancaster: true
+ suffix: |
+ The following additional Perl modules will be used by the test suite if
+ present:
+
+ * Devel::Cover
+ * Test::MinimumVersion
+ * Test::Perl::Critic
+ * Test::Pod
+ * Test::Pod::Coverage
+ * Test::Spelling
+ * Test::Strict
+ * Test::Synopsis
+
+ All are available on CPAN. Those tests will be skipped if the modules are
+ not available.
diff --git a/t/data/generate/pgp-sign/output/readme b/t/data/generate/pgp-sign/output/readme
new file mode 100644
index 0000000..d718b02
--- /dev/null
+++ b/t/data/generate/pgp-sign/output/readme
@@ -0,0 +1,161 @@
+ PGP::Sign 1.00
+ (create and verify detached PGP signatures)
+ Maintained by Russ Allbery <rra@cpan.org>
+
+ Copyright 1997-2000, 2002, 2004, 2018, 2020 Russ Allbery <rra@cpan.org>.
+ This software is distributed under the same terms as Perl itself.
+ Please see the section LICENSE below for more information.
+
+BLURB
+
+ PGP::Sign is a Perl module for generating and verifying detached OpenPGP
+ signatures of textual data using GnuPG. It was written to support
+ Netnews article signatures for signed control messages and PGPMoose.
+
+DESCRIPTION
+
+ PGP::Sign is a Perl module that can generate and verify OpenPGP
+ signatures on some data. Currently, only textual data (data that can be
+ processed using GnuPG's --textmode option) is supported. It uses GnuPG
+ under the hood to do the work.
+
+ The original purpose of this module was to factor out common code in a
+ News::Article class written by Andrew Gierth that handled PGPMoose and
+ control message signatures. It is used to verify control message
+ signatures for the ftp.isc.org Netnews metadata archive, and to generate
+ signed control messages for the Big Eight Usenet hierarchies.
+
+ Data to be signed or verified can be passed into PGP::Sign in a wide
+ variety of formats: scalars, arrays, open files, even code references
+ that act as generators. Keys with passphrases are supported and the
+ passphrase is passed to GnuPG securely (although getting the passphrase
+ to the PGP::Sign module is a problem for the calling application).
+
+ This module supports both GnuPG v2 and GnuPG v1 and, when used with
+ GnuPG v1, supports using OpenPGP keys and generating and verifying
+ signatures that are backward-compatible with PGP 2.6.2.
+
+ PGP::Sign provides both a (recommended) object-oriented API and a
+ (legacy) function-based API that uses global variables for configuration
+ and is backward-compatible with earlier versions of PGP::Sign.
+
+REQUIREMENTS
+
+ Perl 5.20 or later and Module::Build are required to build this module,
+ and IPC::Run is required to use it. Either GnuPG v2 or GnuPG v1
+ (selectable at runtime) is also required. It has not been tested with
+ versions of GnuPG older than 1.4.23.
+
+ PGP::Sign uses IPC::Run features that are documented as not available on
+ Windows (primarily higher-numbered file descriptors) and has never been
+ tested with Gpg4win, so will probably not work on Windows (or, for that
+ matter, other non-UNIX systems).
+
+BUILDING AND INSTALLATION
+
+ PGP::Sign uses Module::Build and can be installed using the same process
+ as any other Module::Build module:
+
+ perl Build.PL
+ ./Build
+ ./Build install
+
+ You will have to run the last command as root unless you're installing
+ into a local Perl module tree in your home directory.
+
+TESTING
+
+ PGP::Sign comes with a test suite, which you can run after building
+ with:
+
+ ./Build test
+
+ If a test fails, you can run a single test with verbose output via:
+
+ ./Build test --test_files <path-to-test>
+
+ The following additional Perl modules will be used by the test suite if
+ present:
+
+ * Devel::Cover
+ * Test::MinimumVersion
+ * Test::Perl::Critic
+ * Test::Pod
+ * Test::Pod::Coverage
+ * Test::Spelling
+ * Test::Strict
+ * Test::Synopsis
+
+ All are available on CPAN. Those tests will be skipped if the modules
+ are not available.
+
+ To enable tests that don't detect functionality problems but are used to
+ sanity-check the release, set the environment variable RELEASE_TESTING
+ to a true value. To enable tests that may be sensitive to the local
+ environment or that produce a lot of false positives without uncovering
+ many problems, set the environment variable AUTHOR_TESTING to a true
+ value.
+
+SUPPORT
+
+ The PGP::Sign web page at:
+
+ https://www.eyrie.org/~eagle/software/pgp-sign/
+
+ will always have the current version of this package, the current
+ documentation, and pointers to any additional resources.
+
+ For bug tracking, use the issue tracker on GitHub:
+
+ https://github.com/rra/pgp-sign/issues
+
+ However, please be aware that I tend to be extremely busy and work
+ projects often take priority. I'll save your report and get to it as
+ soon as I can, but it may take me a couple of months.
+
+SOURCE REPOSITORY
+
+ PGP::Sign is maintained using Git. You can access the current source on
+ GitHub at:
+
+ https://github.com/rra/pgp-sign
+
+ or by cloning the repository at:
+
+ https://git.eyrie.org/git/perl/pgp-sign.git
+
+ or view the repository via the web at:
+
+ https://git.eyrie.org/?p=perl/pgp-sign.git
+
+ The eyrie.org repository is the canonical one, maintained by the author,
+ but using GitHub is probably more convenient for most purposes. Pull
+ requests are gratefully reviewed and normally accepted.
+
+LICENSE
+
+ The PGP::Sign package as a whole is covered by the following copyright
+ statement and license:
+
+ Copyright 1997-2000, 2002, 2004, 2018, 2020
+ Russ Allbery <rra@cpan.org>
+
+ This program is free software; you may redistribute it and/or modify
+ it under the same terms as Perl itself. This means that you may
+ choose between the two licenses that Perl is released under: the GNU
+ GPL and the Artistic License. Please see your Perl distribution for
+ the details and copies of the licenses.
+
+ Some files in this distribution are individually released under
+ different licenses, all of which are compatible with the above general
+ package license but which may require preservation of additional
+ notices. All required notices, and detailed information about the
+ licensing of each file, are recorded in the LICENSE file.
+
+ Files covered by a license with an assigned SPDX License Identifier
+ include SPDX-License-Identifier tags to enable automated processing of
+ license information. See https://spdx.org/licenses/ for more
+ information.
+
+ For any copyright range specified by files in this package as YYYY-ZZZZ,
+ the range specifies every single year in that closed interval.
diff --git a/t/data/generate/pgp-sign/output/readme-md b/t/data/generate/pgp-sign/output/readme-md
new file mode 100644
index 0000000..f7355c2
--- /dev/null
+++ b/t/data/generate/pgp-sign/output/readme-md
@@ -0,0 +1,161 @@
+# PGP::Sign
+
+[![Build
+status](https://github.com/rra/pgp-sign/workflows/build/badge.svg)](https://github.com/rra/pgp-sign/actions)
+[![CPAN
+version](https://img.shields.io/cpan/v/PGP-Sign)](https://metacpan.org/release/PGP-Sign)
+[![License](https://img.shields.io/cpan/l/PGP-Sign)](https://github.com/rra/pgp-sign/blob/master/LICENSE)
+[![Debian
+package](https://img.shields.io/debian/v/libpgp-sign-perl/unstable)](https://tracker.debian.org/pkg/libpgp-sign-perl)
+
+Copyright 1997-2000, 2002, 2004, 2018, 2020 Russ Allbery <rra@cpan.org>.
+This software is distributed under the same terms as Perl itself. Please
+see the section [License](#license) below for more information.
+
+## Blurb
+
+PGP::Sign is a Perl module for generating and verifying detached OpenPGP
+signatures of textual data using GnuPG. It was written to support Netnews
+article signatures for signed control messages and PGPMoose.
+
+## Description
+
+PGP::Sign is a Perl module that can generate and verify OpenPGP signatures
+on some data. Currently, only textual data (data that can be processed
+using GnuPG's `--textmode` option) is supported. It uses GnuPG under the
+hood to do the work.
+
+The original purpose of this module was to factor out common code in a
+News::Article class written by Andrew Gierth that handled PGPMoose and
+control message signatures. It is used to verify control message
+signatures for the ftp.isc.org Netnews metadata archive, and to generate
+signed control messages for the Big Eight Usenet hierarchies.
+
+Data to be signed or verified can be passed into PGP::Sign in a wide
+variety of formats: scalars, arrays, open files, even code references that
+act as generators. Keys with passphrases are supported and the passphrase
+is passed to GnuPG securely (although getting the passphrase to the
+PGP::Sign module is a problem for the calling application).
+
+This module supports both GnuPG v2 and GnuPG v1 and, when used with GnuPG
+v1, supports using OpenPGP keys and generating and verifying signatures
+that are backward-compatible with PGP 2.6.2.
+
+PGP::Sign provides both a (recommended) object-oriented API and a (legacy)
+function-based API that uses global variables for configuration and is
+backward-compatible with earlier versions of PGP::Sign.
+
+## Requirements
+
+Perl 5.20 or later and Module::Build are required to build this module,
+and IPC::Run is required to use it. Either GnuPG v2 or GnuPG v1
+(selectable at runtime) is also required. It has not been tested with
+versions of GnuPG older than 1.4.23.
+
+PGP::Sign uses IPC::Run features that are documented as not available on
+Windows (primarily higher-numbered file descriptors) and has never been
+tested with Gpg4win, so will probably not work on Windows (or, for that
+matter, other non-UNIX systems).
+
+## Building and Installation
+
+PGP::Sign uses Module::Build and can be installed using the same process
+as any other Module::Build module:
+
+```
+ perl Build.PL
+ ./Build
+ ./Build install
+```
+
+You will have to run the last command as root unless you're installing
+into a local Perl module tree in your home directory.
+
+## Testing
+
+PGP::Sign comes with a test suite, which you can run after building with:
+
+```
+ ./Build test
+```
+
+If a test fails, you can run a single test with verbose output via:
+
+```
+ ./Build test --test_files <path-to-test>
+```
+
+The following additional Perl modules will be used by the test suite if
+present:
+
+* Devel::Cover
+* Test::MinimumVersion
+* Test::Perl::Critic
+* Test::Pod
+* Test::Pod::Coverage
+* Test::Spelling
+* Test::Strict
+* Test::Synopsis
+
+All are available on CPAN. Those tests will be skipped if the modules are
+not available.
+
+To enable tests that don't detect functionality problems but are used to
+sanity-check the release, set the environment variable `RELEASE_TESTING`
+to a true value. To enable tests that may be sensitive to the local
+environment or that produce a lot of false positives without uncovering
+many problems, set the environment variable `AUTHOR_TESTING` to a true
+value.
+
+## Support
+
+The [PGP::Sign web page](https://www.eyrie.org/~eagle/software/pgp-sign/)
+will always have the current version of this package, the current
+documentation, and pointers to any additional resources.
+
+For bug tracking, use the [issue tracker on
+GitHub](https://github.com/rra/pgp-sign/issues). However, please be aware
+that I tend to be extremely busy and work projects often take priority.
+I'll save your report and get to it as soon as I can, but it may take me a
+couple of months.
+
+## Source Repository
+
+PGP::Sign is maintained using Git. You can access the current source on
+[GitHub](https://github.com/rra/pgp-sign) or by cloning the repository at:
+
+https://git.eyrie.org/git/perl/pgp-sign.git
+
+or [view the repository on the
+web](https://git.eyrie.org/?p=perl/pgp-sign.git).
+
+The eyrie.org repository is the canonical one, maintained by the author,
+but using GitHub is probably more convenient for most purposes. Pull
+requests are gratefully reviewed and normally accepted.
+
+## License
+
+The PGP::Sign package as a whole is covered by the following copyright
+statement and license:
+
+> Copyright 1997-2000, 2002, 2004, 2018, 2020
+> Russ Allbery <rra@cpan.org>
+>
+> This program is free software; you may redistribute it and/or modify it
+> under the same terms as Perl itself. This means that you may choose
+> between the two licenses that Perl is released under: the GNU GPL and the
+> Artistic License. Please see your Perl distribution for the details and
+> copies of the licenses.
+
+Some files in this distribution are individually released under different
+licenses, all of which are compatible with the above general package
+license but which may require preservation of additional notices. All
+required notices, and detailed information about the licensing of each
+file, are recorded in the LICENSE file.
+
+Files covered by a license with an assigned SPDX License Identifier
+include SPDX-License-Identifier tags to enable automated processing of
+license information. See https://spdx.org/licenses/ for more information.
+
+For any copyright range specified by files in this package as YYYY-ZZZZ,
+the range specifies every single year in that closed interval.
diff --git a/t/data/generate/pgp-sign/output/thread b/t/data/generate/pgp-sign/output/thread
new file mode 100644
index 0000000..5376afc
--- /dev/null
+++ b/t/data/generate/pgp-sign/output/thread
@@ -0,0 +1,180 @@
+\==[doc] [2] [\bullet(packed)[\link[\1][\2]]]
+\==[program] [3]
+ [\tablerow[\1 \version[\2]] [\release[\2]]
+ [\link[https://archives.eyrie.org/software/\3.tar.gz][tar.gz]
+ (\link[https://archives.eyrie.org/software/\3.tar.gz.asc]
+ [PGP signature])]
+ [\link[https://archives.eyrie.org/software/\3.tar.xz][tar.xz]
+ (\link[https://archives.eyrie.org/software/\3.tar.xz.asc]
+ [PGP signature])]]
+\==[download] [3]
+ [\1 \version[\2]\break
+ \link[https://archives.eyrie.org/software/\3.tar.gz][tar.gz]
+ (\link[https://archives.eyrie.org/software/\3.tar.gz.asc]
+ [signature])\break
+ \link[https://archives.eyrie.org/software/\3.tar.xz][tar.xz]
+ (\link[https://archives.eyrie.org/software/\3.tar.xz.asc]
+ [signature])\break
+ Released \release[\2]]
+
+\heading[PGP::Sign][software]
+
+\h1[PGP::Sign]
+
+\quote(broken)[
+
+ This above all: to thine own self be true,
+ And it must follow, as the night the day,
+ Thou canst not then be false to any man.
+
+][William Shakespeare][\cite[Hamlet]]
+
+\div(sidebar)[
+ \h2[Download]
+
+ \download[PGP::Sign][pgp-sign]
+ [perl/PGP-Sign-\version[pgp-sign]]
+
+ \link[https://packages.debian.org/source/sid/libpgp-sign-perl]
+ [Debian packages] \break
+ \link[https://archives.eyrie.org/software/ARCHIVE/PGP-Sign/]
+ [Archive]
+
+ \h2[Documentation]
+
+ \link[readme.html][General overview] \break
+ \link[news.html][Change summary] \break
+ \link[docs.html][Module documentation] \break
+ \link[thanks.html][Thanks and credits]
+
+ \h2[Development]
+
+ \link[todo.html][To-do list] \break
+ \link[https://github.com/rra/pgp-sign]
+ [GitHub] \break
+ \link[https://github.com/rra/pgp-sign/issues]
+ [Bug tracker] \break
+ \link[https://git.eyrie.org/?p=perl/pgp-sign.git]
+ [Git repository] \break
+ \link[https://metacpan.org/release/PGP-Sign]
+ [MetaCPAN] \break
+ \link[https://tracker.debian.org/pkg/libpgp-sign-perl]
+ [Debian package tracker]
+]
+
+\h2[Blurb]
+
+PGP::Sign is a Perl module for generating and verifying detached OpenPGP
+signatures of textual data using GnuPG. It was written to support Netnews
+article signatures for signed control messages and PGPMoose.
+
+\h2[Description]
+
+PGP::Sign is a Perl module that can generate and verify OpenPGP signatures
+on some data. Currently, only textual data (data that can be processed
+using GnuPG's \code[--textmode] option) is supported. It uses GnuPG under
+the hood to do the work.
+
+The original purpose of this module was to factor out common code in a
+News::Article class written by Andrew Gierth that handled PGPMoose and
+control message signatures. It is used to verify control message
+signatures for the ftp.isc.org Netnews metadata archive, and to generate
+signed control messages for the Big Eight Usenet hierarchies.
+
+Data to be signed or verified can be passed into PGP::Sign in a wide
+variety of formats: scalars, arrays, open files, even code references that
+act as generators. Keys with passphrases are supported and the passphrase
+is passed to GnuPG securely (although getting the passphrase to the
+PGP::Sign module is a problem for the calling application).
+
+This module supports both GnuPG v2 and GnuPG v1 and, when used with GnuPG
+v1, supports using OpenPGP keys and generating and verifying signatures
+that are backward-compatible with PGP 2.6.2.
+
+PGP::Sign provides both a (recommended) object-oriented API and a (legacy)
+function-based API that uses global variables for configuration and is
+backward-compatible with earlier versions of PGP::Sign.
+
+\h2[Requirements]
+
+Perl 5.20 or later and Module::Build are required to build this module,
+and IPC::Run is required to use it. Either GnuPG v2 or GnuPG v1
+(selectable at runtime) is also required. It has not been tested with
+versions of GnuPG older than 1.4.23.
+
+PGP::Sign uses IPC::Run features that are documented as not available on
+Windows (primarily higher-numbered file descriptors) and has never been
+tested with Gpg4win, so will probably not work on Windows (or, for that
+matter, other non-UNIX systems).
+
+\h2[Download]
+
+The distribution:
+
+\table[][
+ \program[PGP::Sign][pgp-sign]
+ [perl/PGP-Sign-\version[pgp-sign]]
+]
+
+An \link[https://archives.eyrie.org/software/ARCHIVE/PGP-Sign/] [archive
+of older releases] is also available.
+
+PGP::Sign is packaged for Debian as libpgp-sign-perl. See the
+\link[https://tracker.debian.org/pkg/libpgp-sign-perl][Debian package
+tracker] for more information.
+
+PGP::Sign is available from CPAN as the
+\link[https://metacpan.org/release/PGP-Sign]
+[PGP-Sign distribution].
+
+PGP::Sign is maintained using the Git version control system. To check
+out the current development tree, see
+\link[https://github.com/rra/pgp-sign][GitHub] or clone:
+
+\pre[ https://git.eyrie.org/git/perl/pgp-sign.git]
+
+Pull requests on GitHub are welcome. You can also
+\link[https://git.eyrie.org/?p=perl/pgp-sign.git][browse the current
+development source].
+
+\h2[Documentation]
+
+User documentation:
+
+\doc[readme.html][README]
+\doc[news.html][Change summary]
+\doc[docs.html][Module documentation]
+\doc[thanks.html][Thanks and credits]
+\doc[license.html][License and copyright]
+
+Developer documentation:
+
+\doc[todo.html][To-do list]
+\doc[https://github.com/rra/pgp-sign]
+ [GitHub]
+\doc[https://github.com/rra/pgp-sign/issues]
+ [Bug tracker]
+
+\h2[License]
+
+The PGP::Sign package as a whole is covered by the following copyright and
+license:
+
+\block[
+
+ Copyright 1997-2000, 2002, 2004, 2018, 2020
+ Russ Allbery <rra@cpan.org>
+
+ This program is free software; you may redistribute it and/or modify
+ it under the same terms as Perl itself. This means that you may
+ choose between the two licenses that Perl is released under: the GNU
+ GPL and the Artistic License. Please see your Perl distribution for
+ the details and copies of the licenses.
+
+]
+
+Some individual source files are covered by other, compatible licenses.
+For complete copyright and license information, see the file
+\link[license.html][LICENSE] in the PGP::Sign source distribution.
+
+\signature
diff --git a/t/data/generate/remctl/docknot.yaml b/t/data/generate/remctl/docknot.yaml
new file mode 100644
index 0000000..a588ee0
--- /dev/null
+++ b/t/data/generate/remctl/docknot.yaml
@@ -0,0 +1,392 @@
+format: v1
+
+name: remctl
+maintainer: Russ Allbery <eagle@eyrie.org>
+version: '3.15'
+synopsis: remote authenticated command execution with ACLs
+
+license:
+ name: Expat
+copyrights:
+ - holder: Russ Allbery <eagle@eyrie.org>
+ years: 2015-2016, 2018
+ - holder: The Board of Trustees of the Leland Stanford Junior University
+ years: 2002-2014
+
+advisories:
+ - date: 2018-04-01
+ threshold: '3.14'
+ versions: 3.12 and 3.13
+
+build:
+ autoconf: '2.64'
+ automake: '1.11'
+ autotools: true
+ bootstrap: |
+ You will also need pkg-config installed to regenerate configure and
+ xml2rfc to build the formatted protocol documentation.
+ gssapi: true
+ install: true
+ kerberos: true
+ manpages: true
+ middle: |
+ Solaris users should look at `examples/remctld.xml`, an SMF manifest for
+ running the `remctld` daemon.
+
+ To also build the Perl bindings for the libremctl client library, pass the
+ `--enable-perl` option to `configure`. The Perl module build is handled
+ by the normal Perl extension build system, and therefore will be built
+ with compiler flags defined by your Perl installation and installed into
+ your local Perl module directory regardless of the `--prefix` argument to
+ `configure`. To change this, you will need to run `perl Makefile.PL` in
+ the `perl` subdirectory of the build tree with appropriate options and
+ rebuild the module after running `make` and before running `make install`.
+
+ To also build the remctl PECL extension for PHP, pass the `--enable-php`
+ option to `configure`. The PHP PECL module build is handled by the normal
+ PHP extension build system and therefore will be installed into your local
+ PHP module directory. The configure script will look for `phpize` on your
+ `PATH` by default; if it's in some other directory, set the `PHPIZE`
+ environment variable to the full path or set it on the configure command
+ line. The configure script for the PECL extension will be run during the
+ build instead of during configure. This is unfortunately apparently
+ unavoidable given how the PECL build system works.
+
+ To also build the Python bindings for the libremctl client library, pass
+ the `--enable-python` option to configure. The Python module build is
+ handled by the normal Python extension build system, and therefore will be
+ installed into your local Python module directory regardless of the
+ `--prefix` argument to `configure`. To change this, you will need to run
+ `python setup.py install` by hand in the `python` directory with whatever
+ options you want to use.
+
+ To also build the Ruby bindings for the libremctl client library, pass
+ the `--enable-ruby` option to configure. The Ruby module build is handled
+ by the normal Ruby module build system, and therefore will be installed
+ into your local Ruby module directory regardless of the `--prefix`
+ argument to `configure`. To change this, override the `sitedir` variable on
+ the `make install` command line, as in:
+
+ ```
+ make install sitedir=/opt/ruby
+ ```
+
+ The remctl build system also supports a few other environment variables
+ that can be set to control aspects of the Perl, Python, and Ruby binding
+ build systems. These are primarily only of use when packaging the
+ software. For more information, a list of the variables, and their
+ effects, see the comment at the start of `Makefile.am`.
+
+ The Java client and server aren't integrated with the regular build
+ system. For information on building and installing them, see
+ `java/README`.
+
+ remctl will use pkg-config if it's available to find the build flags for
+ libevent. You can control which pkg-config binary and paths are used with
+ the normal pkg-config environment variables of `PKG_CONFIG`,
+ `PKG_CONFIG_PATH`, and `PKG_CONFIG_LIBDIR`, and you can override the
+ pkg-config results with `LIBEVENT_CFLAGS` and `LIBEVENT_LIBS`.
+ Alternately, you can bypass pkg-config by passing one or more of
+ `--with-libevent`, `--with-libevent-include`, and `--with-libevent-lib` to
+ indicate the install prefix, include directory, or library directory.
+
+ remctl will automatically build with PCRE support if pcre-config or the
+ PCRE library are found. You can pass `--with-pcre` to configure to
+ specify the root directory where PCRE is installed, or set the include and
+ library directories separately with `--with-pcre-include` and
+ `--with-pcre-lib`. You can also set `PCRE_CONFIG` to point to a different
+ pcre-config script, or do similar things as with `PATH_KRB5_CONFIG`
+ described below.
+
+ remctl will automatically build with GPUT support if the GPUT header and
+ library are found. You can pass `--with-gput` to configure to specify the
+ root directory where GPUT is installed, or set the include and library
+ directories separately with `--with-gput-include` and `--with-gput-lib`.
+ reduced_depends: true
+ type: Autoconf
+distribution:
+ packaging:
+ debian:
+ package: remctl
+ summary: |
+ Debian packages are available from Debian as of Debian 3.1
+ (sarge). For Debian 4.0 (etch) and later, install remctl-server
+ for the server and remctl-client for the client. (The sarge
+ release had a single remctl package that contained both.)
+
+ The Net::Remctl Perl module is available in Debian 5.0 (lenny) and
+ newer; install libnet-remctl-perl for it. The PHP bindings
+ (php5-remctl), Python bindings (python-remctl), and Ruby bindings
+ (ruby-remctl) are available in Debian 6.0 (squeeze) and newer.
+ The Ruby bindings package is named libremctl-ruby in Debian
+ versions before 7.0 (wheezy).
+ extra: |
+ For those using Puppet, there is a [Puppet
+ module](https://forge.puppetlabs.com/ccin2p3/remctl) available for
+ installing the remctl server and managing server configurations.
+ This was written and is maintained by the IN2P3 Computing Centre;
+ see that page for more information.
+ section: kerberos
+ tarname: remctl
+ version: remctl
+support:
+ email: eagle@eyrie.org
+ github: rra/remctl
+ web: https://www.eyrie.org/~eagle/software/remctl/
+vcs:
+ browse: https://git.eyrie.org/?p=kerberos/remctl.git
+ github: rra/remctl
+ openhub: https://www.openhub.net/p/remctl
+ status:
+ travis: rra/remctl
+ type: Git
+ url: https://git.eyrie.org/git/kerberos/remctl.git
+
+quote:
+ author: Peter Marshall
+ text: |
+ Small deeds done are better than great deeds planned.
+docs:
+ api:
+ - name: remctl-api
+ title: remctl and remctl_free_result
+ - name: remctl_new
+ title: remctl_new
+ - name: remctl_open
+ title: remctl_open
+ - name: remctl_command
+ title: remctl_command and remctl_commandv
+ - name: remctl_output
+ title: remctl_output
+ - name: remctl_noop
+ title: remctl_noop
+ - name: remctl_close
+ title: remctl_close
+ - name: remctl_error
+ title: remctl_error
+ - name: remctl_set_ccache
+ title: remctl_set_ccache
+ - name: remctl_set_source_ip
+ title: remctl_set_source_ip
+ - name: remctl_set_timeout
+ title: remctl_set_timeout
+ - name: net-remctl
+ title: Net::Remctl Perl module
+ - name: net-remctl-backend
+ title: Net::Remctl::Backend Perl module
+ developer:
+ - name: extending
+ title: Extending remctl
+ - name: protocol
+ title: Protocol specification
+ - name: protocol-v4
+ title: Protocol v4 draft
+ user:
+ - name: remctl
+ title: remctl manual page
+ - name: remctl-shell
+ title: remctl-shell manual page
+ - name: remctld
+ title: remctld manual page
+ - name: java-readme
+ title: Java client and server README
+ - name: php-readme
+ title: PHP bindings README
+ - name: python-readme
+ title: Python bindings README
+ - name: ruby-readme
+ title: Ruby bindings README
+ - name: thanks
+ title: Thanks and credits
+
+blurb: |
+ remctl is a client/server application that supports remote execution of
+ specific commands, using Kerberos GSS-API for authentication.
+ Authorization is controlled by a configuration file and ACL files and can
+ be set separately for each command, unlike with rsh. remctl is like a
+ Kerberos-authenticated simple CGI server, or a combination of Kerberos ssh
+ and sudo without most of the features and complexity of either.
+
+description: |
+ remctl is a client/server application that supports remote execution of
+ specific commands, using Kerberos GSS-API for authentication and
+ confidentiality. The commands a given user can execute are controlled by
+ a configuration file and ACL files and can easily be tightly limited,
+ unlike with rsh. The mapping of command to backend program is done by the
+ configuration file, which allows some additional flexibility compared to
+ ssh command restrictions and works with Kerberos authentications rather
+ than being limited to public key authentications.
+
+ remctld is very similar to a CGI server that uses a different network
+ protocol than HTTP, always does strong authentication before executing the
+ desired command, and guarantees the data is encrypted on the network.
+ Alternately, you can think of it as a very simple combination of Kerberos
+ ssh and sudo, without most of the features of both but with simpler
+ authorization.
+
+ There are a lot of different client/server systems that do something
+ similar, including regular rsh, CGI, IBM's sysctl (not to be confused with
+ the Linux kernel call and configuration file of the same name), CERN's
+ arc, and more elaborate systems like MIT's Moira. remctl has the
+ advantage over many of these schemes of using GSS-API and being about as
+ simple as it possibly can be while still being useful. It doesn't require
+ any particular programming language, builds self-contained binaries, and
+ uses as minimal of a protocol as possible.
+
+ Both C and Java clients and servers are provided, as well as Perl, PHP,
+ and Python bindings for the C client library. For more information about
+ the Java client, see `java/README`. For more information about the PHP
+ bindings, see `php/README`. For more information about the Python
+ bindings, see `python/README`.
+
+ Also included in the remctl package is an alternate way of running the
+ remctl server: remctl-shell. This program is designed to be run as either
+ a shell or a forced command under ssh, using ssh for authentication and
+ communicating the authentication information to remctl-shell via either
+ environment variables or command-line arguments via the forced command
+ configuration. This version of the server uses simple ssh clients, rather
+ than using the remctl client program or libraries.
+
+ remctl was originally written by Anton Ushakov as a replacement for IBM's
+ sysctl, a client/server application with Kerberos v4 authentication that
+ allowed the client to run Tcl code on the server, protected by ACLs. At
+ Stanford, we used sysctl extensively, but mostly only to run external
+ programs, so remctl was developed as a Kerberos v5 equivalent that did
+ only the portions we needed.
+
+ Complete protocol documentation is available in `docs/protocol.html`.
+ Also present, as `docs/design.html`, is the original design document (now
+ somewhat out of date).
+
+sections:
+ - title: Building on Windows
+ body: |
+ (These instructions are not tested by the author and are now dated.
+ Updated instructions via a pull request, issue, or email are very
+ welcome.)
+
+ First, install the Microsoft Windows SDK for Windows Vista if you
+ have not already. This is a free download from Microsoft for users
+ of "Genuine Microsoft Windows." The `vcvars32.bat` environment
+ provided by Visual Studio may work as an alternative, but has not
+ been tested.
+
+ Next, install the [MIT Kerberos for Windows
+ SDK](https://web.mit.edu/kerberos/www/dist/index.html). remctl has
+ been tested with version 3.2.1 but should hopefully work with later
+ versions.
+
+ Then, follow these steps:
+
+ 1. Run the `InitEnv.cmd` script included with the Windows SDK with
+ parameters `"/xp /release"`.
+
+ 2. Run the `configure.bat` script, giving it as an argument the
+ location of the Kerberos for Windows SDK. For example, if you
+ installed the KfW SDK in `"c:\KfW SDK"`, you should run:
+
+ ```
+ configure "c:\KfW SDK"
+ ```
+
+ 3. Run `nmake` to start compiling. You can ignore the warnings.
+
+ If all goes well, you will have `remctl.exe` and `remctl.dll`. The
+ latter is a shared library used by the client program. It exports
+ the same interface as the UNIX libremctl library.
+
+requirements: |
+ The remctld server and the standard client are written in C and require a
+ C compiler and GSS-API libraries to build. Both will build against either
+ MIT Kerberos or Heimdal of any reasonable vintage. remctl will also build
+ against the Kerberos GSS-API implementation shipped with AIX 5.2 (and
+ possibly later versions) and the Solaris 10 generic GSS-API library (and
+ possibly later versions). The `remctl_set_ccache` implementation is
+ improved by building with Kerberos libraries and a GSS-API library that
+ supports `gss_krb5_import_cred`.
+
+ The remctld server requires libevent 1.4.x or later. It's only been
+ tested with libevent 1.4.13-stable and later, but should work with 1.4.4
+ or later. It is now only tested with libevent 2.x, so moving to a later
+ version of libevent if possible is recommended.
+
+ The remctl server will support regex ACLs if the system supports the POSIX
+ regex API. The remctl server also optionally supports PCRE regular
+ expressions in ACLs. To include that support, the PCRE library is
+ required.
+
+ To build the remctl client for Windows, the Microsoft Windows SDK for
+ Windows Vista and the MIT Kerberos for Windows SDK are required, along
+ with a Microsoft Windows build environment (probably Visual Studio).
+ remctl has only been tested with the 3.2.1 MIT Kerberos for Windows SDK.
+ To run the resulting binary, MIT Kerberos for Windows must be installed
+ and configured. The client was tested on Windows XP and Vista and should
+ work on Windows 2000 and up; however, the primary maintainer does not use
+ or test Windows, so it's always possible Windows support has broken. The
+ server is not supported on Windows.
+
+ To build the Perl bindings for the C client library, you will need Perl
+ 5.8 or later.
+
+ To build the PHP bindings for the C client library, you will need PHP 5.x
+ or later and phpize, plus any other programs that phpize requires. PHP
+ 5.x support has only been tested on 5.2 and 5.3, and PHP support is now
+ only tested on PHP 7.x and later.
+
+ To build the Python bindings for the C client library, you will need
+ Python 2.3 or later (primarily tested with Python 2.7). Python 3 is not
+ (yet) supported.
+
+ To build the Ruby bindings for the C client library, you will need Ruby
+ 1.8 or later (primarily tested with 2.5 and later).
+
+ None of the language bindings have been tested on Windows.
+
+ A Java client and Java server are available in the java subdirectory, but
+ they are not integrated into the normal build or built by default. There
+ is a basic Makefile in that directory that may require some tweaking. It
+ currently requires the Sun Java JDK (1.4.2, 5, or 6) or OpenJDK 6 or
+ later. A considerably better Java client implementation is available on
+ the `java` branch in the Git repository but has not yet been merged.
+
+test:
+ lancaster: true
+ prefix: |
+ remctl comes with a comprehensive test suite, but it requires some
+ configuration in order to test anything other than low-level utility
+ functions. For the full test suite, you will need to have a keytab that
+ can authenticate to a running KDC. Using a test KDC environment, if you
+ have one, is recommended.
+
+ Follow the instructions in `tests/config/README` to configure the test
+ suite.
+
+ Now, you can run the test suite with:
+ suffix: |
+ On particularly slow or loaded systems, you may see intermittent failures
+ from the `server/streaming` test because it's timing-sensitive.
+
+ The test suite will also need to be able to bind to 127.0.0.1 on port
+ 11119 and 14373 to run test network server programs.
+
+ To test anonymous authentication, the KDC configured in the test suite
+ needs to support service tickets for the anonymous identity (not a
+ standard configuration). This test will be skipped if the KDC does not
+ support this.
+
+ To test user handling in remctld, you will need the `fakeroot` command
+ (available in the `fakeroot` package in Debian and Ubuntu). This test
+ will be skipped if `fakeroot` isn't available.
+
+ The following additional Perl modules will be used by the test suite for
+ the main package and the Perl bindings if installed:
+
+ * Test::MinimumVersion
+ * Test::Perl::Critic
+ * Test::Pod
+ * Test::Spelling
+ * Test::Strict
+ * Test::Synopsis
+
+ All are available on CPAN. Those tests will be skipped if the modules are
+ not available.
diff --git a/t/data/generate/remctl/output/readme b/t/data/generate/remctl/output/readme
index 1ef842c..917aec7 100644
--- a/t/data/generate/remctl/output/readme
+++ b/t/data/generate/remctl/output/readme
@@ -352,8 +352,8 @@ BUILDING ON WINDOWS
parameters "/xp /release".
2. Run the configure.bat script, giving it as an argument the location
- of the Kerberos for Windows SDK. For example, if you installed the KfW
- SDK in "c:\KfW SDK", you should run:
+ of the Kerberos for Windows SDK. For example, if you installed the
+ KfW SDK in "c:\KfW SDK", you should run:
configure "c:\KfW SDK"
diff --git a/t/data/generate/remctl/output/readme-md b/t/data/generate/remctl/output/readme-md
index f56e5b2..20b5e37 100644
--- a/t/data/generate/remctl/output/readme-md
+++ b/t/data/generate/remctl/output/readme-md
@@ -1,4 +1,4 @@
-# remctl 3.15
+# remctl
[![Build
status](https://travis-ci.org/rra/remctl.svg?branch=master)](https://travis-ci.org/rra/remctl)
@@ -246,11 +246,11 @@ you need to specify a different Kerberos installation root via
You can also individually set the paths to the include directory and the
library directory with `--with-krb5-include` and `--with-krb5-lib`. You
-may need to do this if Autoconf can't figure out whether to use lib,
-lib32, or lib64 on your platform.
+may need to do this if Autoconf can't figure out whether to use `lib`,
+`lib32`, or `lib64` on your platform.
-To not use krb5-config and force library probing even if there is a
-krb5-config script on your path, set PATH_KRB5_CONFIG to a nonexistent
+To not use `krb5-config` and force library probing even if there is a
+`krb5-config` script on your path, set `PATH_KRB5_CONFIG` to a nonexistent
path:
```
diff --git a/t/data/generate/rra-c-util/docknot.yaml b/t/data/generate/rra-c-util/docknot.yaml
new file mode 100644
index 0000000..4259d8e
--- /dev/null
+++ b/t/data/generate/rra-c-util/docknot.yaml
@@ -0,0 +1,282 @@
+format: v1
+
+name: rra-c-util
+maintainer: Russ Allbery <eagle@eyrie.org>
+version: '6.1'
+synopsis: Russ Allbery's utility libraries for C
+
+license:
+ name: Expat
+copyrights:
+ - holder: Russ Allbery <eagle@eyrie.org>
+ years: 2000, 2009-2010, 2013-2016
+ - holder: The Board of Trustees of the Leland Stanford Junior University
+ years: 2009-2014
+
+build:
+ autoconf: '2.64'
+ automake: '1.11'
+ autotools: true
+ gssapi: true
+ install: false
+ kerberos: true
+ manpages: true
+ middle: |
+ Pass `--enable-kafs` to configure to attempt to build kafs support,
+ which will use either an existing libkafs or libkopenafs library or
+ build the kafs replacement included in this package. You can also add
+ `--without-libkafs` to force the use of the internal kafs replacement.
+ type: Autoconf
+distribution:
+ section: devel
+ tarname: rra-c-util
+ version: rra-c-util
+support:
+ email: eagle@eyrie.org
+ github: rra/rra-c-util
+ web: https://www.eyrie.org/~eagle/software/rra-c-util/
+vcs:
+ browse: https://git.eyrie.org/?p=devel/rra-c-util.git
+ github: rra/rra-c-util
+ openhub: https://www.openhub.net/p/rra-c-util
+ type: Git
+ url: https://git.eyrie.org/git/devel/rra-c-util.git
+
+quote:
+ author: Phil Greenspun
+ text: |
+ Greenspun's Tenth Rule of Programming: any sufficiently complicated C or
+ Fortran program contains an ad hoc informally-specified bug-ridden slow
+ implementation of half of Common Lisp.
+docs:
+ api:
+ - name: xmalloc
+ title: xmalloc, xcalloc, and xrealloc
+ extra:
+ - title: Test scripts
+ links:
+ - name: module-version
+ title: tests/perl/module-version-t
+ - name: module-version-perl
+ title: t/style/module-version.t
+ user:
+ - name: fakepam
+ title: PAM testing
+ - name: test-rra
+ title: Test::RRA
+ - name: test-rra-automake
+ title: Test::RRA::Automake
+ - name: test-rra-config
+ title: Test::RRA::Config
+ - name: test-rra-moduleversion
+ title: Test::RRA::ModuleVersion
+
+blurb: |
+ rra-c-util is my collection of portability functions, utility functions,
+ Autoconf macros, and related shared C infrastructure, akin to gnulib but
+ without any GPL-covered code and additional support for Kerberos and PAM
+ development. It serves as a common repository of code and infrastructure
+ used across multiple projects so that files have a canonical latest
+ version. It's not intended for installation as a regular package;
+ instead, other packages are expected to copy files from here as needed.
+
+description: |
+ The origins of this package are in the libinn utility library in INN.
+ Some of the utility and portability functions here are directly inspired
+ by or based on versions in older versions of INN, and I wrote and rewrote
+ considerable additional portability code and utility libraries when I took
+ over INN maintenance. When I started maintaining other C packages, I
+ started copying pieces of libinn into those packages and merging it with
+ other portability and utility code. Over time, each package gained a
+ slightly different version of various utility functions, replacements for
+ missing functions, and Autoconf macros.
+
+ The goal of this package is to merge all the various versions of any
+ portability or utility code that's used in more than one of my packages in
+ one place. Then, each package can update to the latest rra-c-util version
+ before each release and gain from the improvements made for all other
+ packages. You can think of it as my version of
+ [Gnulib](https://www.gnu.org/software/gnulib/), with everything released
+ under a permissive license (no GPL).
+
+ As well as C portability frameworks, Autoconf macros, and a general C
+ utility library, this package has also accumulated a considerable
+ collection of standard tests (for C and Perl packages) and a large library
+ of test utilities and support functions. It also includes extensive
+ support for writing and testing PAM modules, and a portable implementation
+ of AFS PAGs.
+
+ This package uses the infrastructure of C TAP Harness for testing, but is
+ not the canonical version of `tests/runtests.c`, `tests/tap/basic.[ch]`,
+ `tests/tap/macros.h`, or `tests/tap/libtap.sh`. Those files should be
+ pulled from [C TAP
+ Harness](https://www.eyrie.org/~eagle/software/c-tap-harness/) instead.
+
+sections:
+ - title: Using This Code
+ body: |
+ While there is an install target, it's present only because Automake
+ provides it automatically. Its use is not recommended. Instead,
+ the code in this package is intended to be copied into your package
+ and refreshed from the latest release of rra-c-util for each
+ release.
+
+ You can obviously copy the code and integrate it however works best
+ for your package and your build system. Here's how I do it for my
+ packages as an example:
+
+ * Create a portable directory and copy `macros.h`, `system.h`,
+ `stdbool.h`, and `dummy.c` along with whatever additional
+ functions that your package uses that may not be present on all
+ systems. If you use much of the `util` directory (see below),
+ you'll need `asprintf.c`, `reallocarray.c`, and `snprintf.c` at
+ least. If you use `util/network.c`, you'll also need
+ `getaddrinfo.c`, `getaddrinfo.h`, `getnameinfo.c`,
+ `getnameinfo.h`, `inet_*.c`, and `socket.h`. You'll need
+ `winsock.c` for networking portability to Windows.
+
+ * Copy the necessary portions of `configure.ac` from this package
+ into your package. `configure.ac` is commented to try to give you
+ a guide for what you need to copy over. You will also need to
+ make an `m4` subdirectory, add the code to `configure.ac` to load
+ Autoconf macros from `m4`, and copy over `m4/snprintf.m4` and
+ possibly `m4/socket.m4` and `m4/inet-ntoa.m4`.
+
+ * Copy the code from `Makefile.am` for building `libportable.a` into
+ your package and be sure to link your package binaries with
+ `libportable.a`. If you include this code in a shared library,
+ you'll need to build `libportable.la` instead; see the Automake
+ manual for the differences. You'll need to change `LIBRARIES` to
+ `LTLIBRARIES` and `LIBOBJS` to `LTLIBOBJS` in addition to renaming
+ the targets.
+
+ * Create a `util` directory and copy over the portions of the
+ utility library that you want. You will probably need
+ `messages.[ch]` and `xmalloc.[ch]` if you copy anything over at
+ all, since most of the rest of the library uses those. You will
+ also need `m4/vamacros.m4` if you use `messages.[ch]`.
+
+ * Copy the code from `Makefile.am` for building `libutil.a` into
+ your package and be sure to link your package binaries with
+ `libutil.a`. As with `libportable.a`, if you want to use the
+ utility functions in a shared library, you'll need to instead
+ build `libutil.la` and change some of the Automake variables.
+
+ * If your package uses a TAP-based test suite written in C, consider
+ using the additional TAP utility functions in `tests/tap`
+ (specifically `messages.*`, `process.*`, and `string.*`).
+
+ * If you're using the Kerberos portability code, copy over
+ `portable/krb5.h`, `portable/krb5-extra.c`, `m4/krb5.m4`,
+ `m4/lib-depends.m4`, `m4/lib-pathname.m4`, and optionally
+ `util/messages-krb5.[ch]`. You'll also need the relevant
+ fragments of `configure.ac`. You may want to remove some things
+ from `krb5.h` and `krb5-extra.c` the corresponding configure
+ checks if your code doesn't need all of those functions. If you
+ need `krb5_get_renewed_creds`, also copy over `krb5-renew.c`.
+ Don't forget to add `$(KRB5_CPPFLAGS)` to `CPPFLAGS` for
+ `libportable` and possibly `libutil`, and if you're building a
+ shared library, also add `$(KRB5_LDFLAGS)` to `LDFLAGS` and
+ `$(KRB5_LIBS)` to `LIBADD` for those libraries.
+
+ For a Kerberos-enabled test suite, also consider copying the
+ `kerberos.*` libraries in `tests/tap` for a Kerberos-enabled test
+ suite. If you want to use `kerberos_generate_conf` from
+ `tests/tap/kerberos.c`, also copy over
+ `tests/data/generate-krb5-conf`.
+
+ * For testing that requires making Kerberos administrative changes,
+ consider copying over the `kadmin.*` libraries in `tests/tap`.
+
+ * For testing packages that use remctl, see the `tests/tap/remctl.c`
+ and `tests/tap/remctl.h` files for C tests and
+ `tests/tap/remctl.sh` for shell scripts.
+
+ * If you're using the kafs portability code, copy over the `kafs`
+ directory, `m4/kafs.m4`, `m4/lib-pathname.m4`,
+ `portable/k_haspag.c`, the code to build kafs from `Makefile.am`,
+ and the relevant fragments of `configure.ac`.
+
+ * If you're using the PAM portability code, copy over `pam-util/*`,
+ `portable/pam*`, `m4/pam-const.m4`, and the relevant fragments of
+ `configure.ac`.
+
+ * Copy over any other Autoconf macros that you want to use in your
+ package from the m4 directory.
+
+ * Copy over any generic tests from `tests/docs` and `tests/perl`
+ that are appropriate for your package. If you use any of these,
+ also copy over the `tests/tap/perl` directory and
+ `tests/data/perl.conf` (and customize the latter for your
+ package).
+
+ * If the package embeds a Perl module, copy over any tests from the
+ `perl/t` directory that are applicable. This can provide generic
+ testing of the embedded Perl module using Perl's own test
+ infrastructure. If you use any of these, also copy over the
+ `perl/t/data/perl.conf` file and customize it for your package.
+ You will need to arrange for `perl/t/data` to contain copies of
+ the `perlcriticrc` and `perltidyrc` files, either by making copies
+ of the files from `tests/data` or by using make to copy them.
+
+ I also copy over all the relevant tests from the `tests` directory
+ and the build machinery for them from `Makefile.am` so that the
+ portability and utility layer are tested along with the rest of the
+ package. The test driver should come from C TAP Harness.
+
+requirements: |
+ Everything requires a C compiler to build and expects an ISO C89 or later
+ C compiler and libraries. Presence of strdup is also assumed, which is
+ guaranteed by POSIX 2008 but common in many earlier C libraries as well.
+ Otherwise, the files are meant to be copied into packages and the
+ requirements depend on which files one copies.
+
+ A Kerberos library, either MIT Kerberos or Heimdal, is required to build
+ this package as-is, since the Kerberos portability layer is built and
+ tested by default. The other code will run fine without this requirement
+ when copied into other packages.
+
+ PAM libraries and headers are required to build the package as-is, since
+ the PAM supporting library is built and tested by default. Other code can
+ be copied from this package without introducing a PAM dependency.
+
+ To build the the kafs portability layer, one of Linux, Mac OS X, Solaris
+ 11, the kafs library that comes with either Heimdal or KTH Kerberos, the
+ kopenafs library that comes with newer OpenAFS, AFS header files (on any
+ other platform besides AIX or IRIX), or AFS libraries (on AIX and IRIX) is
+ required. AIX binaries with AFS PAG support may not run on AIX systems
+ that do not have an AFS client installed due to how AIX handles system
+ calls.
+
+ To run the full test suite, and to use the Perl test support libraries,
+ Perl 5.6.2 or later is required. The following additional Perl modules
+ will be used if present:
+
+ * IPC::System::Simple
+ * Test::MinimumVersion
+ * Test::Perl::Critic
+ * Test::Pod
+ * Test::Spelling
+ * Test::Strict
+
+ All are available on CPAN. Those tests will be skipped if the modules are
+ not available.
+
+test:
+ lancaster: true
+ override: |
+ rra-c-util comes with an extensive test suite, which you can run after
+ building with:
+
+ ```
+ make check
+ ```
+
+ If a test fails, you can run a single test with verbose output via:
+
+ ```
+ tests/runtests -o <name-of-test>
+ ```
+
+ Do this instead of running the test program directly since it will
+ ensure that necessary environment variables are set up.
diff --git a/t/data/generate/rra-c-util/output/readme b/t/data/generate/rra-c-util/output/readme
index 35cdcbb..7184396 100644
--- a/t/data/generate/rra-c-util/output/readme
+++ b/t/data/generate/rra-c-util/output/readme
@@ -101,28 +101,35 @@ REQUIREMENTS
BUILDING
- You can build rra-c-util with:
+ You can build rra-c-util with the standard commands:
./configure
make
+ If you are building from a Git clone, first run ./bootstrap in the
+ source directory to generate the build files. Building outside of the
+ source directory is also supported, if you wish, by creating an empty
+ directory and then running configure with the correct relative path.
+
Pass --enable-kafs to configure to attempt to build kafs support, which
will use either an existing libkafs or libkopenafs library or build the
kafs replacement included in this package. You can also add
--without-libkafs to force the use of the internal kafs replacement.
- Pass --enable-silent-rules to configure for a quieter build (similar to
- the Linux kernel). Use make warnings instead of make to build with full
- GCC compiler warnings (requires a relatively current version of GCC).
-
Normally, configure will use krb5-config to determine the flags to use
- to compile with your Kerberos libraries. If krb5-config isn't found, it
- will look for the standard Kerberos libraries in locations already
- searched by your compiler. If the the krb5-config script first in your
- path is not the one corresponding to the Kerberos libraries you want to
- use or if your Kerberos libraries and includes aren't in a location
- searched by default by your compiler, you need to specify a different
- Kerberos installation root via --with-krb5=PATH. For example:
+ to compile with your Kerberos libraries. To specify a particular
+ krb5-config script to use, either set the PATH_KRB5_CONFIG environment
+ variable or pass it to configure like:
+
+ ./configure PATH_KRB5_CONFIG=/path/to/krb5-config
+
+ If krb5-config isn't found, configure will look for the standard
+ Kerberos libraries in locations already searched by your compiler. If
+ the the krb5-config script first in your path is not the one
+ corresponding to the Kerberos libraries you want to use, or if your
+ Kerberos libraries and includes aren't in a location searched by default
+ by your compiler, you need to specify a different Kerberos installation
+ root via --with-krb5=PATH. For example:
./configure --with-krb5=/usr/pubsw
@@ -131,11 +138,6 @@ BUILDING
need to do this if Autoconf can't figure out whether to use lib, lib32,
or lib64 on your platform.
- To specify a particular krb5-config script to use, either set the
- PATH_KRB5_CONFIG environment variable or pass it to configure like:
-
- ./configure PATH_KRB5_CONFIG=/path/to/krb5-config
-
To not use krb5-config and force library probing even if there is a
krb5-config script on your path, set PATH_KRB5_CONFIG to a nonexistent
path:
@@ -151,6 +153,11 @@ BUILDING
GSS-API libraries, and --with-gssapi-include and --with-gssapi-lib can
be used to specify the exact paths, overriding any krb5-config results.
+ Pass --enable-silent-rules to configure for a quieter build (similar to
+ the Linux kernel). Use make warnings instead of make to build with full
+ compiler warnings (requires either GCC or Clang and may require a
+ relatively current version of the compiler).
+
TESTING
rra-c-util comes with an extensive test suite, which you can run after
diff --git a/t/data/generate/rra-c-util/output/readme-md b/t/data/generate/rra-c-util/output/readme-md
index 8bd88b7..294fac4 100644
--- a/t/data/generate/rra-c-util/output/readme-md
+++ b/t/data/generate/rra-c-util/output/readme-md
@@ -1,4 +1,4 @@
-# rra-c-util 6.1
+# rra-c-util
Copyright 2000, 2009-2010, 2013-2016 Russ Allbery <eagle@eyrie.org>.
Copyright 2009-2014 The Board of Trustees of the Leland Stanford Junior
@@ -96,30 +96,39 @@ fresh Git checkout.
## Building
-You can build rra-c-util with:
+You can build rra-c-util with the standard commands:
```
./configure
make
```
+If you are building from a Git clone, first run `./bootstrap` in the
+source directory to generate the build files. Building outside of the
+source directory is also supported, if you wish, by creating an empty
+directory and then running configure with the correct relative path.
+
Pass `--enable-kafs` to configure to attempt to build kafs support, which
will use either an existing libkafs or libkopenafs library or build the
kafs replacement included in this package. You can also add
`--without-libkafs` to force the use of the internal kafs replacement.
-Pass `--enable-silent-rules` to configure for a quieter build (similar to
-the Linux kernel). Use `make warnings` instead of make to build with full
-GCC compiler warnings (requires a relatively current version of GCC).
-
Normally, configure will use `krb5-config` to determine the flags to use
-to compile with your Kerberos libraries. If `krb5-config` isn't found, it
-will look for the standard Kerberos libraries in locations already
-searched by your compiler. If the the `krb5-config` script first in your
-path is not the one corresponding to the Kerberos libraries you want to
-use or if your Kerberos libraries and includes aren't in a location
-searched by default by your compiler, you need to specify a different
-Kerberos installation root via `--with-krb5=PATH`. For example:
+to compile with your Kerberos libraries. To specify a particular
+`krb5-config` script to use, either set the `PATH_KRB5_CONFIG` environment
+variable or pass it to configure like:
+
+```
+ ./configure PATH_KRB5_CONFIG=/path/to/krb5-config
+```
+
+If `krb5-config` isn't found, configure will look for the standard
+Kerberos libraries in locations already searched by your compiler. If the
+the `krb5-config` script first in your path is not the one corresponding
+to the Kerberos libraries you want to use, or if your Kerberos libraries
+and includes aren't in a location searched by default by your compiler,
+you need to specify a different Kerberos installation root via
+`--with-krb5=PATH`. For example:
```
./configure --with-krb5=/usr/pubsw
@@ -130,13 +139,6 @@ library directory with `--with-krb5-include` and `--with-krb5-lib`. You
may need to do this if Autoconf can't figure out whether to use `lib`,
`lib32`, or `lib64` on your platform.
-To specify a particular `krb5-config` script to use, either set the
-`PATH_KRB5_CONFIG` environment variable or pass it to configure like:
-
-```
- ./configure PATH_KRB5_CONFIG=/path/to/krb5-config
-```
-
To not use `krb5-config` and force library probing even if there is a
`krb5-config` script on your path, set `PATH_KRB5_CONFIG` to a nonexistent
path:
@@ -150,10 +152,15 @@ path:
GSS-API libraries are found the same way: with `krb5-config` by default if
it is found, and a `--with-gssapi=PATH` flag to specify the installation
-root. `PATH_KRB5_CONFIG` is similarly used to find krb5-config for the
+root. `PATH_KRB5_CONFIG` is similarly used to find `krb5-config` for the
GSS-API libraries, and `--with-gssapi-include` and `--with-gssapi-lib` can
be used to specify the exact paths, overriding any `krb5-config` results.
+Pass `--enable-silent-rules` to configure for a quieter build (similar to
+the Linux kernel). Use `make warnings` instead of `make` to build with
+full GCC compiler warnings (requires either GCC or Clang and may require a
+relatively current version of the compiler).
+
## Testing
rra-c-util comes with an extensive test suite, which you can run after
diff --git a/t/data/generate/wallet/docknot.yaml b/t/data/generate/wallet/docknot.yaml
new file mode 100644
index 0000000..5b05499
--- /dev/null
+++ b/t/data/generate/wallet/docknot.yaml
@@ -0,0 +1,351 @@
+format: v1
+
+maintainer: Russ Allbery <eagle@eyrie.org>
+name: wallet
+version: '1.4'
+synopsis: secure data management system
+
+license:
+ name: Expat
+copyrights:
+ - holder: Russ Allbery <eagle@eyrie.org>
+ years: 2014, 2016, 2018
+ - holder: The Board of Trustees of the Leland Stanford Junior University
+ years: 2006-2010, 2012-2014
+
+build:
+ autoconf: '2.64'
+ automake: '1.11'
+ autotools: true
+ install: true
+ kerberos: true
+ manpages: true
+ middle: |
+ If you are upgrading the wallet server from an earlier installed version,
+ run `wallet-admin upgrade` after installation to upgrade the database
+ schema. See the wallet-admin manual page for more information.
+
+ You can pass the `--with-wallet-server` and `--with-wallet-port` options
+ to configure to compile in a default wallet server and port. If no port
+ is set, the remctl default port is used. If no server is set, the server
+ must be specified either in `krb5.conf` configuration or on the wallet
+ command line or the client will exit with an error.
+
+ By default, wallet uses whatever Perl executable exists in the current
+ `PATH`. That Perl's path is what the server scripts will use, and that
+ Perl's configuration will be used to determine where the server Perl
+ modules will be installed.
+
+ To specify a particular Perl executable to use, either set the `PERL`
+ environment variable or pass it to configure like:
+
+ ```
+ ./configure PERL=/path/to/my/perl
+ ```
+
+ By default, wallet installs itself under `/usr/local` except for the
+ server Perl modules, which are installed into whatever default site module
+ path is used by your Perl installation. To change the installation
+ location of the files other than the Perl modules, pass the `--prefix=DIR`
+ argument to configure.
+
+ If remctl was installed in a path not normally searched by your compiler,
+ you must specify its installation prefix to configure with the
+ `--with-remctl=DIR` option, or alternately set the path to the include
+ files and libraries separately with `--with-remctl-include=DIR` and
+ `--with-remctl-lib=DIR`.
+ reduced_depends: true
+ type: Autoconf
+distribution:
+ packaging:
+ debian:
+ personal: true
+ section: kerberos
+ tarname: wallet
+ version: wallet
+support:
+ email: eagle@eyrie.org
+ github: rra/wallet
+ listname: kerberos
+ listurl: https://mailman.mit.edu/mailman/listinfo/kerberos
+ web: https://www.eyrie.org/~eagle/software/wallet/
+vcs:
+ browse: https://git.eyrie.org/?p=kerberos/wallet.git
+ github: rra/wallet
+ openhub: https://www.openhub.net/p/wallet
+ status:
+ workflow: build
+ type: Git
+ url: https://git.eyrie.org/git/kerberos/wallet.git
+
+docs:
+ api:
+ - name: api/acl
+ title: Wallet::ACL
+ - name: api/acl-base
+ title: Wallet::ACL::Base
+ - name: api/acl-external
+ title: Wallet::ACL::External
+ - name: api/acl-krb5
+ title: Wallet::ACL::Krb5
+ - name: api/acl-krb5-regex
+ title: Wallet::ACL::Krb5::Regex
+ - name: api/acl-ldap-attr
+ title: Wallet::ACL::LDAP::Attribute
+ - name: api/acl-ldap-attr-root
+ title: Wallet::ACL::LDAP::Attribute::Root
+ - name: api/acl-nested
+ title: Wallet::ACL::Nested
+ - name: api/acl-netdb
+ title: Wallet::ACL::NetDB
+ - name: api/acl-netdb-root
+ title: Wallet::ACL::NetDB::Root
+ - name: api/admin
+ title: Wallet::Admin
+ - name: api/config
+ title: Wallet::Config
+ - name: api/database
+ title: Wallet::Database
+ - name: api/kadmin
+ title: Wallet::Kadmin
+ - name: api/kadmin-ad
+ title: Wallet::Kadmin::AD
+ - name: api/kadmin-heimdal
+ title: Wallet::Kadmin::Heimdal
+ - name: api/kadmin-mit
+ title: Wallet::Kadmin::MIT
+ - name: api/object-base
+ title: Wallet::Object::Base
+ - name: api/object-duo
+ title: Wallet::Object::Duo
+ - name: api/object-file
+ title: Wallet::Object::File
+ - name: api/object-keytab
+ title: Wallet::Object::Keytab
+ - name: api/object-password
+ title: Wallet::Object::Password
+ - name: api/object-wakeyring
+ title: Wallet::Object::WAKeyring
+ - name: api/policy-stanford
+ title: Wallet::Policy::Stanford
+ - name: api/report
+ title: Wallet::Report
+ - name: api/schema
+ title: Wallet::Schema
+ - name: api/server
+ title: Wallet::Server
+ contrib:
+ - name: ad-keytab
+ title: ad-keytab
+ - name: used-principals
+ title: used-principals
+ - name: wallet-contacts
+ title: wallet-contacts
+ - name: wallet-rekey-periodic
+ title: wallet-rekey-periodic
+ - name: wallet-summary
+ title: wallet-summary
+ - name: wallet-unknown-hosts
+ title: wallet-unknown-hosts
+ developer:
+ - name: design
+ title: Overall design
+ - name: design-acl
+ title: ACL design
+ - name: design-api
+ title: Server module API design
+ - name: notes
+ title: Implementation notes
+ user:
+ - name: setup
+ title: Setup and configuration
+ - name: config
+ title: Configuration options
+ - name: objects-and-schemes
+ title: Objects and ACL schemes
+ - name: wallet
+ title: wallet
+ - name: wallet-admin
+ title: wallet-admin
+ - name: wallet-backend
+ title: wallet-backend
+ - name: wallet-report
+ title: wallet-report
+ - name: keytab-backend
+ title: keytab-backend
+ - name: naming
+ title: Stanford wallet naming policy
+ - name: thanks
+ title: Thanks and credits
+quote:
+ author: John M. Ford
+ broken: true
+ text: |
+ An architect
+ who does not believe
+ in privacy
+ may also lack faith
+ in keeping out the rain
+ work: Growing Up Weightless
+
+blurb: |
+ The wallet is a system for managing secure data, authorization rules to
+ retrieve or change that data, and audit rules for documenting actions
+ taken on that data. Objects of various types may be stored in the wallet
+ or generated on request and retrieved by authorized users. The wallet
+ tracks ACLs, metadata, and trace information. It is built on top of the
+ remctl protocol and uses Kerberos GSS-API authentication. One of the
+ object types it supports is Kerberos keytabs, making it suitable as a
+ user-accessible front-end to Kerberos kadmind with richer ACL and metadata
+ operations.
+
+description: |
+ The wallet is a client/server system using a central server with a
+ supporting database and a stand-alone client that can be widely
+ distributed to users. The server runs on a secure host with access to a
+ local database; tracks object metadata such as ACLs, attributes, history,
+ expiration, and ownership; and has the necessary access privileges to
+ create wallet-managed objects in external systems (such as Kerberos
+ service principals). The client uses the remctl protocol to send commands
+ to the server, store and retrieve objects, and query object metadata. The
+ same client can be used for both regular user operations and wallet
+ administrative actions.
+
+ All wallet actions are controlled by a fine-grained set of ACLs. Each
+ object has an owner ACL and optional get, store, show, destroy, and flags
+ ACLs that control more specific actions. A global administrative ACL
+ controls access to administrative actions. An ACL consists of zero or
+ more entries, each of which is a generic scheme and identifier pair,
+ allowing the ACL system to be extended to use any existing authorization
+ infrastructure. Supported ACL types include Kerberos principal names,
+ regexes matching Kerberos principal names, and LDAP attribute checks.
+
+ Currently, the object types supported are simple files, passwords,
+ Kerberos keytabs, WebAuth keyrings, and Duo integrations. By default,
+ whenever a Kerberos keytab object is retrieved from the wallet, the key is
+ changed in the Kerberos KDC and the wallet returns a keytab for the new
+ key. However, a keytab object can also be configured to preserve the
+ existing keys when retrieved. Included in the wallet distribution is a
+ script that can be run via remctl on an MIT Kerberos KDC to extract the
+ existing key for a principal, and the wallet system will use that
+ interface to retrieve the current key if the unchanging flag is set on a
+ Kerberos keytab object for MIT Kerberos. (Heimdal doesn't require any
+ special support.)
+
+requirements: |
+ The wallet client requires the C
+ [remctl](https://www.eyrie.org/~eagle/software/remctl/) client library and
+ a Kerberos library. It will build with either MIT Kerberos or Heimdal.
+
+ The wallet server is written in Perl and requires Perl 5.8.0 or later plus
+ the following Perl modules:
+
+ * Date::Parse (part of the TimeDate distribution)
+ * DBI
+ * DBIx::Class
+ * Module::Build
+ * SQL::Translator
+
+ You will also need a DBD Perl module for the database backend that you
+ intend to use, and the DateTime::Format::* module corresponding to that
+ DBD module (such as DateTime::Format::SQLite or DateTime::Format::PG).
+
+ Currently, the server has only been tested against SQLite 3, MySQL 5, and
+ PostgreSQL, and prebuilt SQL files (for database upgrades) are only
+ provided for those servers. It will probably not work fully with other
+ database backends. Porting is welcome.
+
+ The wallet server is intended to be run under `remctld` and use `remctld`
+ to do authentication. It can be ported to any other front-end, but doing
+ so will require writing a new version of `server/wallet-backend` that
+ translates the actions in that protocol into calls to the Wallet::Server
+ Perl object.
+
+ The keytab support in the wallet server supports Heimdal and MIT Kerberos
+ KDCs and has experimental support for Active Directory. The Heimdal
+ support requires the Heimdal::Kadm5 Perl module. The MIT Kerberos support
+ requires the MIT Kerberos `kadmin` client program be installed. The
+ Active Directory support requires the Net::LDAP, Authen::SASL, and
+ IPC::Run Perl modules and the `msktutil` client program.
+
+ To support the unchanging flag on keytab objects with an MIT Kerberos KDC,
+ the Net::Remctl Perl module (shipped with remctl) must be installed on the
+ server and the `keytab-backend` script must be runnable via remctl on the
+ KDC. This script also requires an MIT Kerberos `kadmin.local` binary that
+ supports the `-norandkey` option to `ktadd`. This option is included in
+ MIT Kerberos 1.7 and later.
+
+ The WebAuth keyring object support in the wallet server requires the
+ WebAuth Perl module from
+ [WebAuth 4.4.0 or later](https://www.eyrie.org/~eagle/software/webauth/).
+
+ The Duo integration object support in the wallet server requires the
+ [Net::Duo](https://www.eyrie.org/~eagle/software/net-duo/), JSON, and
+ Perl6::Slurp Perl modules.
+
+ The password object support in the wallet server requires the
+ Crypt::GeneratePassword Perl module.
+
+ The LDAP attribute ACL verifier requires the Authen::SASL and Net::LDAP
+ Perl modules. This verifier only works with LDAP servers that support
+ GSS-API binds.
+
+ The NetDB ACL verifier (only of interest at sites using NetDB to manage
+ DNS) requires the Net::Remctl Perl module.
+
+sections:
+ - title: Configuration
+ body: |
+ Before setting up the wallet server, review the Wallet::Config
+ documentation (with man Wallet::Config or perldoc Wallet::Config).
+ There are many customization options, some of which must be set.
+ You may also need to create a Kerberos keytab for the keytab object
+ backend and give it appropriate ACLs, and set up `keytab-backend`
+ and its `remctld` configuration on your KDC if you want unchanging
+ flag support.
+
+ For the basic setup and configuration of the wallet server, see the
+ file `docs/setup` in the source distribution. You will need to set
+ up a database on the server (unless you're using SQLite), initialize
+ the database, install `remctld` and the wallet Perl modules, and set
+ up `remctld` to run the `wallet-backend` program.
+
+ The wallet client supports reading configuration settings from the
+ system `krb5.conf` file. For more information, see the
+ CONFIGURATION section of the wallet client man page (`man wallet`).
+
+test:
+ lancaster: true
+ prefix: |
+ The wallet comes with a comprehensive test suite, but it requires some
+ configuration in order to test anything other than low-level utility
+ functions. To enable the full test suite, follow the instructions in:
+
+ * `tests/config/README`
+ * `perl/t/data/README`
+
+ Now, you can run the test suite with:
+ suffix: |
+ The test suite requires `remctld` be installed and available in the user's
+ path or in `/usr/local/sbin` or `/usr/sbin`; and that `sqlite3`, `kinit`,
+ and either `kvno` or `kgetcred` be installed and available on the user's
+ path. The test suite will also need to be able to bind to 127.0.0.1 on
+ ports 11119 and 14373 to test client/server network interactions.
+
+ The test suite uses a SQLite database for server-side and end-to-end
+ testing and therefore requires the DBD::SQLite and
+ DateTime::Format::SQLite Perl modules.
+
+ All of the requirements listed above will be required to run the full test
+ suite of server functionality, but tests will be selectively skipped if
+ their requirements aren't found.
+
+ The following additional Perl modules will be used if present:
+
+ * Test::MinimumVersion
+ * Test::Pod
+ * Test::Spelling
+ * Test::Strict
+
+ All are available on CPAN. Those tests will be skipped if the modules are
+ not available.
diff --git a/t/data/generate/wallet/output/readme b/t/data/generate/wallet/output/readme
new file mode 100644
index 0000000..2421f7b
--- /dev/null
+++ b/t/data/generate/wallet/output/readme
@@ -0,0 +1,373 @@
+ wallet 1.4
+ (secure data management system)
+ Maintained by Russ Allbery <eagle@eyrie.org>
+
+ Copyright 2014, 2016, 2018 Russ Allbery <eagle@eyrie.org>. Copyright
+ 2006-2010, 2012-2014 The Board of Trustees of the Leland Stanford Junior
+ University. This software is distributed under a BSD-style license.
+ Please see the section LICENSE below for more information.
+
+BLURB
+
+ The wallet is a system for managing secure data, authorization rules to
+ retrieve or change that data, and audit rules for documenting actions
+ taken on that data. Objects of various types may be stored in the
+ wallet or generated on request and retrieved by authorized users. The
+ wallet tracks ACLs, metadata, and trace information. It is built on top
+ of the remctl protocol and uses Kerberos GSS-API authentication. One of
+ the object types it supports is Kerberos keytabs, making it suitable as
+ a user-accessible front-end to Kerberos kadmind with richer ACL and
+ metadata operations.
+
+DESCRIPTION
+
+ The wallet is a client/server system using a central server with a
+ supporting database and a stand-alone client that can be widely
+ distributed to users. The server runs on a secure host with access to a
+ local database; tracks object metadata such as ACLs, attributes,
+ history, expiration, and ownership; and has the necessary access
+ privileges to create wallet-managed objects in external systems (such as
+ Kerberos service principals). The client uses the remctl protocol to
+ send commands to the server, store and retrieve objects, and query
+ object metadata. The same client can be used for both regular user
+ operations and wallet administrative actions.
+
+ All wallet actions are controlled by a fine-grained set of ACLs. Each
+ object has an owner ACL and optional get, store, show, destroy, and
+ flags ACLs that control more specific actions. A global administrative
+ ACL controls access to administrative actions. An ACL consists of zero
+ or more entries, each of which is a generic scheme and identifier pair,
+ allowing the ACL system to be extended to use any existing authorization
+ infrastructure. Supported ACL types include Kerberos principal names,
+ regexes matching Kerberos principal names, and LDAP attribute checks.
+
+ Currently, the object types supported are simple files, passwords,
+ Kerberos keytabs, WebAuth keyrings, and Duo integrations. By default,
+ whenever a Kerberos keytab object is retrieved from the wallet, the key
+ is changed in the Kerberos KDC and the wallet returns a keytab for the
+ new key. However, a keytab object can also be configured to preserve
+ the existing keys when retrieved. Included in the wallet distribution
+ is a script that can be run via remctl on an MIT Kerberos KDC to extract
+ the existing key for a principal, and the wallet system will use that
+ interface to retrieve the current key if the unchanging flag is set on a
+ Kerberos keytab object for MIT Kerberos. (Heimdal doesn't require any
+ special support.)
+
+REQUIREMENTS
+
+ The wallet client requires the C remctl [1] client library and a
+ Kerberos library. It will build with either MIT Kerberos or Heimdal.
+
+ [1] https://www.eyrie.org/~eagle/software/remctl/
+
+ The wallet server is written in Perl and requires Perl 5.8.0 or later
+ plus the following Perl modules:
+
+ * Date::Parse (part of the TimeDate distribution)
+ * DBI
+ * DBIx::Class
+ * Module::Build
+ * SQL::Translator
+
+ You will also need a DBD Perl module for the database backend that you
+ intend to use, and the DateTime::Format::* module corresponding to that
+ DBD module (such as DateTime::Format::SQLite or DateTime::Format::PG).
+
+ Currently, the server has only been tested against SQLite 3, MySQL 5,
+ and PostgreSQL, and prebuilt SQL files (for database upgrades) are only
+ provided for those servers. It will probably not work fully with other
+ database backends. Porting is welcome.
+
+ The wallet server is intended to be run under remctld and use remctld to
+ do authentication. It can be ported to any other front-end, but doing
+ so will require writing a new version of server/wallet-backend that
+ translates the actions in that protocol into calls to the Wallet::Server
+ Perl object.
+
+ The keytab support in the wallet server supports Heimdal and MIT
+ Kerberos KDCs and has experimental support for Active Directory. The
+ Heimdal support requires the Heimdal::Kadm5 Perl module. The MIT
+ Kerberos support requires the MIT Kerberos kadmin client program be
+ installed. The Active Directory support requires the Net::LDAP,
+ Authen::SASL, and IPC::Run Perl modules and the msktutil client program.
+
+ To support the unchanging flag on keytab objects with an MIT Kerberos
+ KDC, the Net::Remctl Perl module (shipped with remctl) must be installed
+ on the server and the keytab-backend script must be runnable via remctl
+ on the KDC. This script also requires an MIT Kerberos kadmin.local
+ binary that supports the -norandkey option to ktadd. This option is
+ included in MIT Kerberos 1.7 and later.
+
+ The WebAuth keyring object support in the wallet server requires the
+ WebAuth Perl module from WebAuth 4.4.0 or later [2].
+
+ [2] https://www.eyrie.org/~eagle/software/webauth/
+
+ The Duo integration object support in the wallet server requires the
+ Net::Duo [3], JSON, and Perl6::Slurp Perl modules.
+
+ [3] https://www.eyrie.org/~eagle/software/net-duo/
+
+ The password object support in the wallet server requires the
+ Crypt::GeneratePassword Perl module.
+
+ The LDAP attribute ACL verifier requires the Authen::SASL and Net::LDAP
+ Perl modules. This verifier only works with LDAP servers that support
+ GSS-API binds.
+
+ The NetDB ACL verifier (only of interest at sites using NetDB to manage
+ DNS) requires the Net::Remctl Perl module.
+
+ To bootstrap from a Git checkout, or if you change the Automake files
+ and need to regenerate Makefile.in, you will need Automake 1.11 or
+ later. For bootstrap or if you change configure.ac or any of the m4
+ files it includes and need to regenerate configure or config.h.in, you
+ will need Autoconf 2.64 or later. Perl is also required to generate
+ manual pages from a fresh Git checkout.
+
+BUILDING AND INSTALLATION
+
+ You can build and install wallet with the standard commands:
+
+ ./configure
+ make
+ make install
+
+ If you are building from a Git clone, first run ./bootstrap in the
+ source directory to generate the build files. make install will
+ probably have to be done as root. Building outside of the source
+ directory is also supported, if you wish, by creating an empty directory
+ and then running configure with the correct relative path.
+
+ If you are upgrading the wallet server from an earlier installed
+ version, run wallet-admin upgrade after installation to upgrade the
+ database schema. See the wallet-admin manual page for more information.
+
+ You can pass the --with-wallet-server and --with-wallet-port options to
+ configure to compile in a default wallet server and port. If no port is
+ set, the remctl default port is used. If no server is set, the server
+ must be specified either in krb5.conf configuration or on the wallet
+ command line or the client will exit with an error.
+
+ By default, wallet uses whatever Perl executable exists in the current
+ PATH. That Perl's path is what the server scripts will use, and that
+ Perl's configuration will be used to determine where the server Perl
+ modules will be installed.
+
+ To specify a particular Perl executable to use, either set the PERL
+ environment variable or pass it to configure like:
+
+ ./configure PERL=/path/to/my/perl
+
+ By default, wallet installs itself under /usr/local except for the
+ server Perl modules, which are installed into whatever default site
+ module path is used by your Perl installation. To change the
+ installation location of the files other than the Perl modules, pass the
+ --prefix=DIR argument to configure.
+
+ If remctl was installed in a path not normally searched by your
+ compiler, you must specify its installation prefix to configure with the
+ --with-remctl=DIR option, or alternately set the path to the include
+ files and libraries separately with --with-remctl-include=DIR and
+ --with-remctl-lib=DIR.
+
+ Normally, configure will use krb5-config to determine the flags to use
+ to compile with your Kerberos libraries. To specify a particular
+ krb5-config script to use, either set the PATH_KRB5_CONFIG environment
+ variable or pass it to configure like:
+
+ ./configure PATH_KRB5_CONFIG=/path/to/krb5-config
+
+ If krb5-config isn't found, configure will look for the standard
+ Kerberos libraries in locations already searched by your compiler. If
+ the the krb5-config script first in your path is not the one
+ corresponding to the Kerberos libraries you want to use, or if your
+ Kerberos libraries and includes aren't in a location searched by default
+ by your compiler, you need to specify a different Kerberos installation
+ root via --with-krb5=PATH. For example:
+
+ ./configure --with-krb5=/usr/pubsw
+
+ You can also individually set the paths to the include directory and the
+ library directory with --with-krb5-include and --with-krb5-lib. You may
+ need to do this if Autoconf can't figure out whether to use lib, lib32,
+ or lib64 on your platform.
+
+ To not use krb5-config and force library probing even if there is a
+ krb5-config script on your path, set PATH_KRB5_CONFIG to a nonexistent
+ path:
+
+ ./configure PATH_KRB5_CONFIG=/nonexistent
+
+ krb5-config is not used and library probing is always done if either
+ --with-krb5-include or --with-krb5-lib are given.
+
+ Pass --enable-silent-rules to configure for a quieter build (similar to
+ the Linux kernel). Use make warnings instead of make to build with full
+ compiler warnings (requires either GCC or Clang and may require a
+ relatively current version of the compiler).
+
+ You can pass the --enable-reduced-depends flag to configure to try to
+ minimize the shared library dependencies encoded in the binaries. This
+ omits from the link line all the libraries included solely because other
+ libraries depend on them and instead links the programs only against
+ libraries whose APIs are called directly. This will only work with
+ shared libraries and will only work on platforms where shared libraries
+ properly encode their own dependencies (this includes most modern
+ platforms such as all Linux). It is intended primarily for building
+ packages for Linux distributions to avoid encoding unnecessary shared
+ library dependencies that make shared library migrations more difficult.
+ If none of the above made any sense to you, don't bother with this flag.
+
+TESTING
+
+ The wallet comes with a comprehensive test suite, but it requires some
+ configuration in order to test anything other than low-level utility
+ functions. To enable the full test suite, follow the instructions in:
+
+ * tests/config/README
+ * perl/t/data/README
+
+ Now, you can run the test suite with:
+
+ make check
+
+ If a test fails, you can run a single test with verbose output via:
+
+ tests/runtests -o <name-of-test>
+
+ Do this instead of running the test program directly since it will
+ ensure that necessary environment variables are set up.
+
+ The test suite requires remctld be installed and available in the user's
+ path or in /usr/local/sbin or /usr/sbin; and that sqlite3, kinit, and
+ either kvno or kgetcred be installed and available on the user's path.
+ The test suite will also need to be able to bind to 127.0.0.1 on ports
+ 11119 and 14373 to test client/server network interactions.
+
+ The test suite uses a SQLite database for server-side and end-to-end
+ testing and therefore requires the DBD::SQLite and
+ DateTime::Format::SQLite Perl modules.
+
+ All of the requirements listed above will be required to run the full
+ test suite of server functionality, but tests will be selectively
+ skipped if their requirements aren't found.
+
+ The following additional Perl modules will be used if present:
+
+ * Test::MinimumVersion
+ * Test::Pod
+ * Test::Spelling
+ * Test::Strict
+
+ All are available on CPAN. Those tests will be skipped if the modules
+ are not available.
+
+ To enable tests that don't detect functionality problems but are used to
+ sanity-check the release, set the environment variable RELEASE_TESTING
+ to a true value. To enable tests that may be sensitive to the local
+ environment or that produce a lot of false positives without uncovering
+ many problems, set the environment variable AUTHOR_TESTING to a true
+ value.
+
+CONFIGURATION
+
+ Before setting up the wallet server, review the Wallet::Config
+ documentation (with man Wallet::Config or perldoc Wallet::Config).
+ There are many customization options, some of which must be set. You
+ may also need to create a Kerberos keytab for the keytab object backend
+ and give it appropriate ACLs, and set up keytab-backend and its remctld
+ configuration on your KDC if you want unchanging flag support.
+
+ For the basic setup and configuration of the wallet server, see the file
+ docs/setup in the source distribution. You will need to set up a
+ database on the server (unless you're using SQLite), initialize the
+ database, install remctld and the wallet Perl modules, and set up
+ remctld to run the wallet-backend program.
+
+ The wallet client supports reading configuration settings from the
+ system krb5.conf file. For more information, see the CONFIGURATION
+ section of the wallet client man page (man wallet).
+
+SUPPORT
+
+ The wallet web page at:
+
+ https://www.eyrie.org/~eagle/software/wallet/
+
+ will always have the current version of this package, the current
+ documentation, and pointers to any additional resources.
+
+ New wallet releases are announced on the kerberos mailing list. To
+ subscribe or see the list archives, go to:
+
+ https://mailman.mit.edu/mailman/listinfo/kerberos
+
+ For bug tracking, use the issue tracker on GitHub:
+
+ https://github.com/rra/wallet/issues
+
+ However, please be aware that I tend to be extremely busy and work
+ projects often take priority. I'll save your report and get to it as
+ soon as I can, but it may take me a couple of months.
+
+SOURCE REPOSITORY
+
+ wallet is maintained using Git. You can access the current source on
+ GitHub at:
+
+ https://github.com/rra/wallet
+
+ or by cloning the repository at:
+
+ https://git.eyrie.org/git/kerberos/wallet.git
+
+ or view the repository via the web at:
+
+ https://git.eyrie.org/?p=kerberos/wallet.git
+
+ The eyrie.org repository is the canonical one, maintained by the author,
+ but using GitHub is probably more convenient for most purposes. Pull
+ requests are gratefully reviewed and normally accepted.
+
+LICENSE
+
+ The wallet package as a whole is covered by the following copyright
+ statement and license:
+
+ Copyright 2014, 2016, 2018 Russ Allbery <eagle@eyrie.org>
+ Copyright 2006-2010, 2012-2014
+ The Board of Trustees of the Leland Stanford Junior University
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ Some files in this distribution are individually released under
+ different licenses, all of which are compatible with the above general
+ package license but which may require preservation of additional
+ notices. All required notices, and detailed information about the
+ licensing of each file, are recorded in the LICENSE file.
+
+ Files covered by a license with an assigned SPDX License Identifier
+ include SPDX-License-Identifier tags to enable automated processing of
+ license information. See https://spdx.org/licenses/ for more
+ information.
+
+ For any copyright range specified by files in this package as YYYY-ZZZZ,
+ the range specifies every single year in that closed interval.
diff --git a/t/data/generate/wallet/output/readme-md b/t/data/generate/wallet/output/readme-md
new file mode 100644
index 0000000..1ec3e6e
--- /dev/null
+++ b/t/data/generate/wallet/output/readme-md
@@ -0,0 +1,374 @@
+# wallet
+
+[![Build
+status](https://github.com/rra/wallet/workflows/build/badge.svg)](https://github.com/rra/wallet/actions)
+
+Copyright 2014, 2016, 2018 Russ Allbery <eagle@eyrie.org>. Copyright
+2006-2010, 2012-2014 The Board of Trustees of the Leland Stanford Junior
+University. This software is distributed under a BSD-style license.
+Please see the section [License](#license) below for more information.
+
+## Blurb
+
+The wallet is a system for managing secure data, authorization rules to
+retrieve or change that data, and audit rules for documenting actions
+taken on that data. Objects of various types may be stored in the wallet
+or generated on request and retrieved by authorized users. The wallet
+tracks ACLs, metadata, and trace information. It is built on top of the
+remctl protocol and uses Kerberos GSS-API authentication. One of the
+object types it supports is Kerberos keytabs, making it suitable as a
+user-accessible front-end to Kerberos kadmind with richer ACL and metadata
+operations.
+
+## Description
+
+The wallet is a client/server system using a central server with a
+supporting database and a stand-alone client that can be widely
+distributed to users. The server runs on a secure host with access to a
+local database; tracks object metadata such as ACLs, attributes, history,
+expiration, and ownership; and has the necessary access privileges to
+create wallet-managed objects in external systems (such as Kerberos
+service principals). The client uses the remctl protocol to send commands
+to the server, store and retrieve objects, and query object metadata. The
+same client can be used for both regular user operations and wallet
+administrative actions.
+
+All wallet actions are controlled by a fine-grained set of ACLs. Each
+object has an owner ACL and optional get, store, show, destroy, and flags
+ACLs that control more specific actions. A global administrative ACL
+controls access to administrative actions. An ACL consists of zero or
+more entries, each of which is a generic scheme and identifier pair,
+allowing the ACL system to be extended to use any existing authorization
+infrastructure. Supported ACL types include Kerberos principal names,
+regexes matching Kerberos principal names, and LDAP attribute checks.
+
+Currently, the object types supported are simple files, passwords,
+Kerberos keytabs, WebAuth keyrings, and Duo integrations. By default,
+whenever a Kerberos keytab object is retrieved from the wallet, the key is
+changed in the Kerberos KDC and the wallet returns a keytab for the new
+key. However, a keytab object can also be configured to preserve the
+existing keys when retrieved. Included in the wallet distribution is a
+script that can be run via remctl on an MIT Kerberos KDC to extract the
+existing key for a principal, and the wallet system will use that
+interface to retrieve the current key if the unchanging flag is set on a
+Kerberos keytab object for MIT Kerberos. (Heimdal doesn't require any
+special support.)
+
+## Requirements
+
+The wallet client requires the C
+[remctl](https://www.eyrie.org/~eagle/software/remctl/) client library and
+a Kerberos library. It will build with either MIT Kerberos or Heimdal.
+
+The wallet server is written in Perl and requires Perl 5.8.0 or later plus
+the following Perl modules:
+
+* Date::Parse (part of the TimeDate distribution)
+* DBI
+* DBIx::Class
+* Module::Build
+* SQL::Translator
+
+You will also need a DBD Perl module for the database backend that you
+intend to use, and the DateTime::Format::* module corresponding to that
+DBD module (such as DateTime::Format::SQLite or DateTime::Format::PG).
+
+Currently, the server has only been tested against SQLite 3, MySQL 5, and
+PostgreSQL, and prebuilt SQL files (for database upgrades) are only
+provided for those servers. It will probably not work fully with other
+database backends. Porting is welcome.
+
+The wallet server is intended to be run under `remctld` and use `remctld`
+to do authentication. It can be ported to any other front-end, but doing
+so will require writing a new version of `server/wallet-backend` that
+translates the actions in that protocol into calls to the Wallet::Server
+Perl object.
+
+The keytab support in the wallet server supports Heimdal and MIT Kerberos
+KDCs and has experimental support for Active Directory. The Heimdal
+support requires the Heimdal::Kadm5 Perl module. The MIT Kerberos support
+requires the MIT Kerberos `kadmin` client program be installed. The
+Active Directory support requires the Net::LDAP, Authen::SASL, and
+IPC::Run Perl modules and the `msktutil` client program.
+
+To support the unchanging flag on keytab objects with an MIT Kerberos KDC,
+the Net::Remctl Perl module (shipped with remctl) must be installed on the
+server and the `keytab-backend` script must be runnable via remctl on the
+KDC. This script also requires an MIT Kerberos `kadmin.local` binary that
+supports the `-norandkey` option to `ktadd`. This option is included in
+MIT Kerberos 1.7 and later.
+
+The WebAuth keyring object support in the wallet server requires the
+WebAuth Perl module from [WebAuth 4.4.0 or
+later](https://www.eyrie.org/~eagle/software/webauth/).
+
+The Duo integration object support in the wallet server requires the
+[Net::Duo](https://www.eyrie.org/~eagle/software/net-duo/), JSON, and
+Perl6::Slurp Perl modules.
+
+The password object support in the wallet server requires the
+Crypt::GeneratePassword Perl module.
+
+The LDAP attribute ACL verifier requires the Authen::SASL and Net::LDAP
+Perl modules. This verifier only works with LDAP servers that support
+GSS-API binds.
+
+The NetDB ACL verifier (only of interest at sites using NetDB to manage
+DNS) requires the Net::Remctl Perl module.
+
+To bootstrap from a Git checkout, or if you change the Automake files and
+need to regenerate Makefile.in, you will need Automake 1.11 or later. For
+bootstrap or if you change configure.ac or any of the m4 files it includes
+and need to regenerate configure or config.h.in, you will need Autoconf
+2.64 or later. Perl is also required to generate manual pages from a
+fresh Git checkout.
+
+## Building and Installation
+
+You can build and install wallet with the standard commands:
+
+```
+ ./configure
+ make
+ make install
+```
+
+If you are building from a Git clone, first run `./bootstrap` in the
+source directory to generate the build files. `make install` will
+probably have to be done as root. Building outside of the source
+directory is also supported, if you wish, by creating an empty directory
+and then running configure with the correct relative path.
+
+If you are upgrading the wallet server from an earlier installed version,
+run `wallet-admin upgrade` after installation to upgrade the database
+schema. See the wallet-admin manual page for more information.
+
+You can pass the `--with-wallet-server` and `--with-wallet-port` options
+to configure to compile in a default wallet server and port. If no port
+is set, the remctl default port is used. If no server is set, the server
+must be specified either in `krb5.conf` configuration or on the wallet
+command line or the client will exit with an error.
+
+By default, wallet uses whatever Perl executable exists in the current
+`PATH`. That Perl's path is what the server scripts will use, and that
+Perl's configuration will be used to determine where the server Perl
+modules will be installed.
+
+To specify a particular Perl executable to use, either set the `PERL`
+environment variable or pass it to configure like:
+
+```
+ ./configure PERL=/path/to/my/perl
+```
+
+By default, wallet installs itself under `/usr/local` except for the
+server Perl modules, which are installed into whatever default site module
+path is used by your Perl installation. To change the installation
+location of the files other than the Perl modules, pass the `--prefix=DIR`
+argument to configure.
+
+If remctl was installed in a path not normally searched by your compiler,
+you must specify its installation prefix to configure with the
+`--with-remctl=DIR` option, or alternately set the path to the include
+files and libraries separately with `--with-remctl-include=DIR` and
+`--with-remctl-lib=DIR`.
+
+Normally, configure will use `krb5-config` to determine the flags to use
+to compile with your Kerberos libraries. To specify a particular
+`krb5-config` script to use, either set the `PATH_KRB5_CONFIG` environment
+variable or pass it to configure like:
+
+```
+ ./configure PATH_KRB5_CONFIG=/path/to/krb5-config
+```
+
+If `krb5-config` isn't found, configure will look for the standard
+Kerberos libraries in locations already searched by your compiler. If the
+the `krb5-config` script first in your path is not the one corresponding
+to the Kerberos libraries you want to use, or if your Kerberos libraries
+and includes aren't in a location searched by default by your compiler,
+you need to specify a different Kerberos installation root via
+`--with-krb5=PATH`. For example:
+
+```
+ ./configure --with-krb5=/usr/pubsw
+```
+
+You can also individually set the paths to the include directory and the
+library directory with `--with-krb5-include` and `--with-krb5-lib`. You
+may need to do this if Autoconf can't figure out whether to use `lib`,
+`lib32`, or `lib64` on your platform.
+
+To not use `krb5-config` and force library probing even if there is a
+`krb5-config` script on your path, set `PATH_KRB5_CONFIG` to a nonexistent
+path:
+
+```
+ ./configure PATH_KRB5_CONFIG=/nonexistent
+```
+
+`krb5-config` is not used and library probing is always done if either
+`--with-krb5-include` or `--with-krb5-lib` are given.
+
+Pass `--enable-silent-rules` to configure for a quieter build (similar to
+the Linux kernel). Use `make warnings` instead of `make` to build with
+full GCC compiler warnings (requires either GCC or Clang and may require a
+relatively current version of the compiler).
+
+You can pass the `--enable-reduced-depends` flag to configure to try to
+minimize the shared library dependencies encoded in the binaries. This
+omits from the link line all the libraries included solely because other
+libraries depend on them and instead links the programs only against
+libraries whose APIs are called directly. This will only work with shared
+libraries and will only work on platforms where shared libraries properly
+encode their own dependencies (this includes most modern platforms such as
+all Linux). It is intended primarily for building packages for Linux
+distributions to avoid encoding unnecessary shared library dependencies
+that make shared library migrations more difficult. If none of the above
+made any sense to you, don't bother with this flag.
+
+## Testing
+
+The wallet comes with a comprehensive test suite, but it requires some
+configuration in order to test anything other than low-level utility
+functions. To enable the full test suite, follow the instructions in:
+
+* `tests/config/README`
+* `perl/t/data/README`
+
+Now, you can run the test suite with:
+
+```
+ make check
+```
+
+If a test fails, you can run a single test with verbose output via:
+
+```
+ tests/runtests -o <name-of-test>
+```
+
+Do this instead of running the test program directly since it will ensure
+that necessary environment variables are set up.
+
+The test suite requires `remctld` be installed and available in the user's
+path or in `/usr/local/sbin` or `/usr/sbin`; and that `sqlite3`, `kinit`,
+and either `kvno` or `kgetcred` be installed and available on the user's
+path. The test suite will also need to be able to bind to 127.0.0.1 on
+ports 11119 and 14373 to test client/server network interactions.
+
+The test suite uses a SQLite database for server-side and end-to-end
+testing and therefore requires the DBD::SQLite and
+DateTime::Format::SQLite Perl modules.
+
+All of the requirements listed above will be required to run the full test
+suite of server functionality, but tests will be selectively skipped if
+their requirements aren't found.
+
+The following additional Perl modules will be used if present:
+
+* Test::MinimumVersion
+* Test::Pod
+* Test::Spelling
+* Test::Strict
+
+All are available on CPAN. Those tests will be skipped if the modules are
+not available.
+
+To enable tests that don't detect functionality problems but are used to
+sanity-check the release, set the environment variable `RELEASE_TESTING`
+to a true value. To enable tests that may be sensitive to the local
+environment or that produce a lot of false positives without uncovering
+many problems, set the environment variable `AUTHOR_TESTING` to a true
+value.
+
+## Configuration
+
+Before setting up the wallet server, review the Wallet::Config
+documentation (with man Wallet::Config or perldoc Wallet::Config). There
+are many customization options, some of which must be set. You may also
+need to create a Kerberos keytab for the keytab object backend and give it
+appropriate ACLs, and set up `keytab-backend` and its `remctld`
+configuration on your KDC if you want unchanging flag support.
+
+For the basic setup and configuration of the wallet server, see the file
+`docs/setup` in the source distribution. You will need to set up a
+database on the server (unless you're using SQLite), initialize the
+database, install `remctld` and the wallet Perl modules, and set up
+`remctld` to run the `wallet-backend` program.
+
+The wallet client supports reading configuration settings from the system
+`krb5.conf` file. For more information, see the CONFIGURATION section of
+the wallet client man page (`man wallet`).
+
+## Support
+
+The [wallet web page](https://www.eyrie.org/~eagle/software/wallet/) will
+always have the current version of this package, the current
+documentation, and pointers to any additional resources.
+
+New wallet releases are announced on the kerberos mailing list. To
+subscribe or see the list archives, go to the [kerberos list information
+page](https://mailman.mit.edu/mailman/listinfo/kerberos).
+
+For bug tracking, use the [issue tracker on
+GitHub](https://github.com/rra/wallet/issues). However, please be aware
+that I tend to be extremely busy and work projects often take priority.
+I'll save your report and get to it as soon as I can, but it may take me a
+couple of months.
+
+## Source Repository
+
+wallet is maintained using Git. You can access the current source on
+[GitHub](https://github.com/rra/wallet) or by cloning the repository at:
+
+https://git.eyrie.org/git/kerberos/wallet.git
+
+or [view the repository on the
+web](https://git.eyrie.org/?p=kerberos/wallet.git).
+
+The eyrie.org repository is the canonical one, maintained by the author,
+but using GitHub is probably more convenient for most purposes. Pull
+requests are gratefully reviewed and normally accepted.
+
+## License
+
+The wallet package as a whole is covered by the following copyright
+statement and license:
+
+> Copyright 2014, 2016, 2018
+> Russ Allbery <eagle@eyrie.org>
+>
+> Copyright 2006-2010, 2012-2014
+> The Board of Trustees of the Leland Stanford Junior University
+>
+> Permission is hereby granted, free of charge, to any person obtaining a
+> copy of this software and associated documentation files (the "Software"),
+> to deal in the Software without restriction, including without limitation
+> the rights to use, copy, modify, merge, publish, distribute, sublicense,
+> and/or sell copies of the Software, and to permit persons to whom the
+> Software is furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in
+> all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+> THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+> FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+> DEALINGS IN THE SOFTWARE.
+
+Some files in this distribution are individually released under different
+licenses, all of which are compatible with the above general package
+license but which may require preservation of additional notices. All
+required notices, and detailed information about the licensing of each
+file, are recorded in the LICENSE file.
+
+Files covered by a license with an assigned SPDX License Identifier
+include SPDX-License-Identifier tags to enable automated processing of
+license information. See https://spdx.org/licenses/ for more information.
+
+For any copyright range specified by files in this package as YYYY-ZZZZ,
+the range specifies every single year in that closed interval.
diff --git a/t/data/generate/wallet/output/thread b/t/data/generate/wallet/output/thread
new file mode 100644
index 0000000..3351029
--- /dev/null
+++ b/t/data/generate/wallet/output/thread
@@ -0,0 +1,331 @@
+\==[doc] [2] [\bullet(packed)[\link[\1][\2]]]
+\==[program] [3]
+ [\tablerow[\1 \version[\2]] [\release[\2]]
+ [\link[https://archives.eyrie.org/software/\3.tar.gz][tar.gz]
+ (\link[https://archives.eyrie.org/software/\3.tar.gz.asc]
+ [PGP signature])]
+ [\link[https://archives.eyrie.org/software/\3.tar.xz][tar.xz]
+ (\link[https://archives.eyrie.org/software/\3.tar.xz.asc]
+ [PGP signature])]]
+\==[download] [3]
+ [\1 \version[\2]\break
+ \link[https://archives.eyrie.org/software/\3.tar.gz][tar.gz]
+ (\link[https://archives.eyrie.org/software/\3.tar.gz.asc]
+ [signature])\break
+ \link[https://archives.eyrie.org/software/\3.tar.xz][tar.xz]
+ (\link[https://archives.eyrie.org/software/\3.tar.xz.asc]
+ [signature])\break
+ Released \release[\2]]
+
+\heading[wallet][software]
+
+\h1[wallet]
+
+\quote(broken)[
+
+ An architect
+ who does not believe
+ in privacy
+ may also lack faith
+ in keeping out the rain
+
+][John M. Ford][\cite[Growing Up Weightless]]
+
+\div(sidebar)[
+ \h2[Download]
+
+ \download[wallet][wallet]
+ [kerberos/wallet-\version[wallet]]
+
+ \link[https://archives.eyrie.org/software/ARCHIVE/wallet/]
+ [Archive]
+
+ \h2[Documentation]
+
+ \link[readme.html][General overview] \break
+ \link[news.html][Change summary] \break
+ \link[setup.html][Setup and configuration] \break
+ \link[config.html][Configuration options] \break
+ \link[objects-and-schemes.html][Objects and ACL schemes] \break
+ \link[wallet.html][wallet] \break
+ \link[wallet-admin.html][wallet-admin] \break
+ \link[wallet-backend.html][wallet-backend] \break
+ \link[wallet-report.html][wallet-report] \break
+ \link[keytab-backend.html][keytab-backend] \break
+ \link[naming.html][Stanford wallet naming policy] \break
+ \link[thanks.html][Thanks and credits]
+
+ \h2[Development]
+
+ \link[todo.html][To-do list] \break
+ \link[design.html][Overall design] \break
+ \link[design-acl.html][ACL design] \break
+ \link[design-api.html][Server module API design] \break
+ \link[notes.html][Implementation notes] \break
+ \link[https://github.com/rra/wallet]
+ [GitHub] \break
+ \link[https://github.com/rra/wallet/issues]
+ [Bug tracker] \break
+ \link[https://git.eyrie.org/?p=kerberos/wallet.git]
+ [Git repository] \break
+ \link[https://www.openhub.net/p/wallet]
+ [Open HUB code analysis]
+]
+
+\h2[Blurb]
+
+The wallet is a system for managing secure data, authorization rules to
+retrieve or change that data, and audit rules for documenting actions
+taken on that data. Objects of various types may be stored in the wallet
+or generated on request and retrieved by authorized users. The wallet
+tracks ACLs, metadata, and trace information. It is built on top of the
+remctl protocol and uses Kerberos GSS-API authentication. One of the
+object types it supports is Kerberos keytabs, making it suitable as a
+user-accessible front-end to Kerberos kadmind with richer ACL and metadata
+operations.
+
+\h2[Description]
+
+The wallet is a client/server system using a central server with a
+supporting database and a stand-alone client that can be widely
+distributed to users. The server runs on a secure host with access to a
+local database; tracks object metadata such as ACLs, attributes, history,
+expiration, and ownership; and has the necessary access privileges to
+create wallet-managed objects in external systems (such as Kerberos
+service principals). The client uses the remctl protocol to send commands
+to the server, store and retrieve objects, and query object metadata. The
+same client can be used for both regular user operations and wallet
+administrative actions.
+
+All wallet actions are controlled by a fine-grained set of ACLs. Each
+object has an owner ACL and optional get, store, show, destroy, and flags
+ACLs that control more specific actions. A global administrative ACL
+controls access to administrative actions. An ACL consists of zero or
+more entries, each of which is a generic scheme and identifier pair,
+allowing the ACL system to be extended to use any existing authorization
+infrastructure. Supported ACL types include Kerberos principal names,
+regexes matching Kerberos principal names, and LDAP attribute checks.
+
+Currently, the object types supported are simple files, passwords,
+Kerberos keytabs, WebAuth keyrings, and Duo integrations. By default,
+whenever a Kerberos keytab object is retrieved from the wallet, the key is
+changed in the Kerberos KDC and the wallet returns a keytab for the new
+key. However, a keytab object can also be configured to preserve the
+existing keys when retrieved. Included in the wallet distribution is a
+script that can be run via remctl on an MIT Kerberos KDC to extract the
+existing key for a principal, and the wallet system will use that
+interface to retrieve the current key if the unchanging flag is set on a
+Kerberos keytab object for MIT Kerberos. (Heimdal doesn't require any
+special support.)
+
+\h2[Requirements]
+
+The wallet client requires the C
+\link[https://www.eyrie.org/~eagle/software/remctl/][remctl] client
+library and a Kerberos library. It will build with either MIT Kerberos or
+Heimdal.
+
+The wallet server is written in Perl and requires Perl 5.8.0 or later plus
+the following Perl modules:
+
+\bullet(packed)[Date::Parse (part of the TimeDate distribution)]
+\bullet(packed)[DBI]
+\bullet(packed)[DBIx::Class]
+\bullet(packed)[Module::Build]
+\bullet(packed)[SQL::Translator]
+
+You will also need a DBD Perl module for the database backend that you
+intend to use, and the DateTime::Format::* module corresponding to that
+DBD module (such as DateTime::Format::SQLite or DateTime::Format::PG).
+
+Currently, the server has only been tested against SQLite 3, MySQL 5, and
+PostgreSQL, and prebuilt SQL files (for database upgrades) are only
+provided for those servers. It will probably not work fully with other
+database backends. Porting is welcome.
+
+The wallet server is intended to be run under \code[remctld] and use
+\code[remctld] to do authentication. It can be ported to any other
+front-end, but doing so will require writing a new version of
+\code[server/wallet-backend] that translates the actions in that protocol
+into calls to the Wallet::Server Perl object.
+
+The keytab support in the wallet server supports Heimdal and MIT Kerberos
+KDCs and has experimental support for Active Directory. The Heimdal
+support requires the Heimdal::Kadm5 Perl module. The MIT Kerberos support
+requires the MIT Kerberos \code[kadmin] client program be installed. The
+Active Directory support requires the Net::LDAP, Authen::SASL, and
+IPC::Run Perl modules and the \code[msktutil] client program.
+
+To support the unchanging flag on keytab objects with an MIT Kerberos KDC,
+the Net::Remctl Perl module (shipped with remctl) must be installed on the
+server and the \code[keytab-backend] script must be runnable via remctl on
+the KDC. This script also requires an MIT Kerberos \code[kadmin.local]
+binary that supports the \code[-norandkey] option to \code[ktadd]. This
+option is included in MIT Kerberos 1.7 and later.
+
+The WebAuth keyring object support in the wallet server requires the
+WebAuth Perl module from
+\link[https://www.eyrie.org/~eagle/software/webauth/][WebAuth 4.4.0 or
+later].
+
+The Duo integration object support in the wallet server requires the
+\link[https://www.eyrie.org/~eagle/software/net-duo/][Net::Duo], JSON, and
+Perl6::Slurp Perl modules.
+
+The password object support in the wallet server requires the
+Crypt::GeneratePassword Perl module.
+
+The LDAP attribute ACL verifier requires the Authen::SASL and Net::LDAP
+Perl modules. This verifier only works with LDAP servers that support
+GSS-API binds.
+
+The NetDB ACL verifier (only of interest at sites using NetDB to manage
+DNS) requires the Net::Remctl Perl module.
+
+To bootstrap from a Git checkout, or if you change the Automake files and
+need to regenerate Makefile.in, you will need Automake 1.11 or later. For
+bootstrap or if you change configure.ac or any of the m4 files it includes
+and need to regenerate configure or config.h.in, you will need Autoconf
+2.64 or later. Perl is also required to generate manual pages from a
+fresh Git checkout.
+
+\h2[Download]
+
+The distribution:
+
+\table[][
+ \program[wallet][wallet]
+ [kerberos/wallet-\version[wallet]]
+]
+
+An \link[https://archives.eyrie.org/software/ARCHIVE/wallet/] [archive of
+older releases] is also available.
+
+A Debian package is available from my \link[../debian.html][personal
+repository].
+
+wallet is maintained using the Git version control system. To check out
+the current development tree, see
+\link[https://github.com/rra/wallet][GitHub] or clone:
+
+\pre[ https://git.eyrie.org/git/kerberos/wallet.git]
+
+Pull requests on GitHub are welcome. You can also
+\link[https://git.eyrie.org/?p=kerberos/wallet.git][browse the current
+development source].
+
+\h2[Documentation]
+
+\div(left)[
+ \class(first)[User documentation:]
+
+ \doc[readme.html][README]
+ \doc[news.html][Change summary]
+ \doc[setup.html][Setup and configuration]
+ \doc[config.html][Configuration options]
+ \doc[objects-and-schemes.html][Objects and ACL schemes]
+ \doc[wallet.html][wallet]
+ \doc[wallet-admin.html][wallet-admin]
+ \doc[wallet-backend.html][wallet-backend]
+ \doc[wallet-report.html][wallet-report]
+ \doc[keytab-backend.html][keytab-backend]
+ \doc[naming.html][Stanford wallet naming policy]
+ \doc[thanks.html][Thanks and credits]
+ \doc[license.html][License and copyright]
+
+ Developer documentation:
+
+ \doc[todo.html][To-do list]
+ \doc[design.html][Overall design]
+ \doc[design-acl.html][ACL design]
+ \doc[design-api.html][Server module API design]
+ \doc[notes.html][Implementation notes]
+ \doc[https://github.com/rra/wallet]
+ [GitHub]
+ \doc[https://github.com/rra/wallet/issues]
+ [Bug tracker]
+ \doc[https://www.openhub.net/p/wallet]
+ [Open HUB code analysis]
+
+ Contributed programs:
+
+ \doc[ad-keytab.html][ad-keytab]
+ \doc[used-principals.html][used-principals]
+ \doc[wallet-contacts.html][wallet-contacts]
+ \doc[wallet-rekey-periodic.html][wallet-rekey-periodic]
+ \doc[wallet-summary.html][wallet-summary]
+ \doc[wallet-unknown-hosts.html][wallet-unknown-hosts]
+
+]
+
+\div(right)[
+ \class(first)[API documentation:]
+
+ \doc[api/acl.html][Wallet::ACL]
+ \doc[api/acl-base.html][Wallet::ACL::Base]
+ \doc[api/acl-external.html][Wallet::ACL::External]
+ \doc[api/acl-krb5.html][Wallet::ACL::Krb5]
+ \doc[api/acl-krb5-regex.html][Wallet::ACL::Krb5::Regex]
+ \doc[api/acl-ldap-attr.html][Wallet::ACL::LDAP::Attribute]
+ \doc[api/acl-ldap-attr-root.html][Wallet::ACL::LDAP::Attribute::Root]
+ \doc[api/acl-nested.html][Wallet::ACL::Nested]
+ \doc[api/acl-netdb.html][Wallet::ACL::NetDB]
+ \doc[api/acl-netdb-root.html][Wallet::ACL::NetDB::Root]
+ \doc[api/admin.html][Wallet::Admin]
+ \doc[api/config.html][Wallet::Config]
+ \doc[api/database.html][Wallet::Database]
+ \doc[api/kadmin.html][Wallet::Kadmin]
+ \doc[api/kadmin-ad.html][Wallet::Kadmin::AD]
+ \doc[api/kadmin-heimdal.html][Wallet::Kadmin::Heimdal]
+ \doc[api/kadmin-mit.html][Wallet::Kadmin::MIT]
+ \doc[api/object-base.html][Wallet::Object::Base]
+ \doc[api/object-duo.html][Wallet::Object::Duo]
+ \doc[api/object-file.html][Wallet::Object::File]
+ \doc[api/object-keytab.html][Wallet::Object::Keytab]
+ \doc[api/object-password.html][Wallet::Object::Password]
+ \doc[api/object-wakeyring.html][Wallet::Object::WAKeyring]
+ \doc[api/policy-stanford.html][Wallet::Policy::Stanford]
+ \doc[api/report.html][Wallet::Report]
+ \doc[api/schema.html][Wallet::Schema]
+ \doc[api/server.html][Wallet::Server]
+]
+
+\h2(after)[License]
+
+The wallet package as a whole is covered by the following copyright and
+license:
+
+\block[
+
+ Copyright 2014, 2016, 2018
+ Russ Allbery <eagle@eyrie.org>
+
+ Copyright 2006-2010, 2012-2014
+ The Board of Trustees of the Leland Stanford Junior University
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+]
+
+Some individual source files are covered by other, compatible licenses.
+For complete copyright and license information, see the file
+\link[license.html][LICENSE] in the wallet source distribution.
+
+\signature
diff --git a/t/data/perlcriticrc b/t/data/perlcriticrc
index 9c65b79..851134f 100644
--- a/t/data/perlcriticrc
+++ b/t/data/perlcriticrc
@@ -105,8 +105,9 @@ min_value = 100000
# IO::Uncompress::Gunzip puts the error message in a package variable.
# Text::Wrap has a broken interface that requires use of package variables.
+# YAML::XS also cannot be configured without package variables.
[Variables::ProhibitPackageVars]
-add_packages = IO::Uncompress::Gunzip Text::Wrap
+add_packages = IO::Uncompress::Gunzip Text::Wrap YAML::XS
# use English was one of the worst ideas in the history of Perl. It makes the
# code slightly more readable for amateurs at the cost of confusing
diff --git a/t/data/regenerate-data b/t/data/regenerate-data
index 5b0f681..9ef8f62 100755
--- a/t/data/regenerate-data
+++ b/t/data/regenerate-data
@@ -32,9 +32,9 @@ closedir($datadir);
for my $package (@packages) {
my $metadata;
if ($package eq 'docknot') {
- $metadata = File::Spec->catdir('docs', 'metadata');
+ $metadata = File::Spec->catdir('docs', 'docknot.yaml');
} else {
- $metadata = File::Spec->catdir($data, $package, 'metadata');
+ $metadata = File::Spec->catdir($data, $package, 'docknot.yaml');
}
my $output = File::Spec->catdir($data, $package, 'output');
opendir(my $outputdir, $output);
diff --git a/t/data/update/ansicolor/docknot.yaml b/t/data/update/ansicolor/docknot.yaml
new file mode 100644
index 0000000..7a4b69c
--- /dev/null
+++ b/t/data/update/ansicolor/docknot.yaml
@@ -0,0 +1,106 @@
+---
+blurb: |
+ Term::ANSIColor provides constants and simple functions for setting ANSI
+ text attributes, most notably colors. It can be used to set the current
+ text attributes or to apply a set of attributes to a string and reset the
+ current text attributes at the end of that string. Eight-color,
+ sixteen-color, and 256-color escape sequences are all supported.
+build:
+ type: ExtUtils::MakeMaker
+copyrights:
+- holder: Russ Allbery <rra@cpan.org>
+ years: 1996-1998, 2000-2002, 2005-2006, 2008-2016
+- holder: Zenin
+ years: '1996'
+- holder: Kurt Starsinic <kstarsinic@gmail.com>
+ years: '2012'
+description: |
+ This Perl module is a simple and convenient interface to the ANSI terminal
+ escape sequences for color (from ECMA-48, also included in ISO 6429). The
+ color sequences are provided in two forms, either as constants for each
+ color or via a function that takes the names of colors and returns the
+ appropriate escape codes or wraps them around the provided text. The
+ non-color text style codes from ANSI X3.64 (bold, dark, underline, and
+ reverse, for example), which were also included in ECMA-48 and ISO 6429,
+ are also supported. Also supported are the extended colors used for
+ sixteen-color and 256-color emulators.
+
+ This module is very stable, and I've used it in a wide variety of
+ applications. It has been included in the core Perl distribution starting
+ with version 5.6.0, so you don't need to download and install it yourself
+ unless you have an old version of Perl or need a newer version of the
+ module than comes with your version of Perl. I continue to maintain it as
+ a separate module, and the version included in Perl is resynced with mine
+ before each release.
+
+ The original module came out of a discussion in comp.lang.perl.misc and is
+ a combination of two approaches, one with constants by Zenin and one with
+ functions that I wrote. I offered to maintain a combined module that
+ included both approaches.
+distribution:
+ section: devel
+ tarname: Term-ANSIColor
+ version: term-ansicolor
+docs:
+ user:
+ - name: docs
+ title: Module documentation
+ - name: thanks
+ title: Thanks and credits
+format: v1
+license:
+ name: Perl
+ notices: |
+ PUSH/POP support submitted 2007 by openmethods.com voice solutions
+maintainer: Russ Allbery <rra@cpan.org>
+name: Term::ANSIColor
+quote:
+ author: Dave van Domelen
+ text: |
+ Ah, September, when the sysadmins turn colors and fall off the trees....
+requirements: |
+ Term::ANSIColor is written in pure Perl and has no module dependencies
+ that aren't found in Perl core. It should work with any version of Perl
+ after 5.6, although it hasn't been tested with old versions in some time.
+
+ In order to actually see color, you will need to use a terminal window
+ that supports the ANSI escape sequences for color. Any recent version of
+ xterm, most xterm derivatives and replacements, and most telnet and ssh
+ clients for Windows and Macintosh should work, as will the MacOS X
+ Terminal application (although Terminal.app reportedly doesn't support 256
+ colors). The console windows for Windows NT and Windows 2000 will not
+ work, as they do not even attempt to support ANSI X3.64.
+
+ For a complete (to my current knowledge) compatibility list, see the
+ Term::ANSIColor module documentation. If you have any additions to the
+ table in the documentation, please send them to me.
+
+ The test suite requires Test::More (part of Perl since 5.6.2). The
+ following additional Perl modules will be used by the test suite if
+ present:
+
+ * Devel::Cover
+ * Test::MinimumVersion
+ * Test::Perl::Critic
+ * Test::Pod
+ * Test::Pod::Coverage
+ * Test::Spelling
+ * Test::Strict
+ * Test::Synopsis
+ * Test::Warn
+
+ All are available on CPAN. Those tests will be skipped if the modules are
+ not available.
+support:
+ email: rra@cpan.org
+ github: rra/ansicolor
+ web: https://www.eyrie.org/~eagle/software/ansicolor/
+synopsis: simple ANSI text attribute control module
+test:
+ lancaster: true
+vcs:
+ browse: https://git.eyrie.org/?p=perl/ansicolor.git
+ github: rra/ansicolor
+ type: Git
+ url: https://git.eyrie.org/git/perl/ansicolor.git
+version: '4.06'
diff --git a/t/data/generate/ansicolor/metadata/blurb b/t/data/update/ansicolor/old/blurb
index 36c74f5..36c74f5 100644
--- a/t/data/generate/ansicolor/metadata/blurb
+++ b/t/data/update/ansicolor/old/blurb
diff --git a/t/data/generate/ansicolor/metadata/description b/t/data/update/ansicolor/old/description
index b1e259a..b1e259a 100644
--- a/t/data/generate/ansicolor/metadata/description
+++ b/t/data/update/ansicolor/old/description
diff --git a/t/data/generate/ansicolor/metadata/metadata.json b/t/data/update/ansicolor/old/metadata.json
index 1dceffd..1dceffd 100644
--- a/t/data/generate/ansicolor/metadata/metadata.json
+++ b/t/data/update/ansicolor/old/metadata.json
diff --git a/t/data/generate/ansicolor/metadata/notices b/t/data/update/ansicolor/old/notices
index c38fa5a..c38fa5a 100644
--- a/t/data/generate/ansicolor/metadata/notices
+++ b/t/data/update/ansicolor/old/notices
diff --git a/t/data/generate/ansicolor/metadata/quote b/t/data/update/ansicolor/old/quote
index 21d524c..21d524c 100644
--- a/t/data/generate/ansicolor/metadata/quote
+++ b/t/data/update/ansicolor/old/quote
diff --git a/t/data/generate/ansicolor/metadata/requirements b/t/data/update/ansicolor/old/requirements
index da259e0..da259e0 100644
--- a/t/data/generate/ansicolor/metadata/requirements
+++ b/t/data/update/ansicolor/old/requirements
diff --git a/t/data/update/c-tap-harness/docknot.yaml b/t/data/update/c-tap-harness/docknot.yaml
new file mode 100644
index 0000000..ea434bb
--- /dev/null
+++ b/t/data/update/c-tap-harness/docknot.yaml
@@ -0,0 +1,255 @@
+---
+blurb: |
+ C TAP Harness is a pure-C implementation of TAP, the Test Anything
+ Protocol. TAP is the text-based protocol used by Perl's test suite. This
+ package provides a harness similar to Perl's Test::Harness for running
+ tests, with some additional features useful for test suites in packages
+ that use Autoconf and Automake, and C and shell libraries to make writing
+ TAP-compliant test programs easier.
+build:
+ autoconf: '2.64'
+ automake: '1.11'
+ autotools: true
+ cplusplus: true
+ install: false
+ manpages: true
+ suffix: |
+ Installing C TAP Harness is not normally done. Instead, see the section
+ on using the harness below.
+ type: Autoconf
+ valgrind: true
+copyrights:
+- holder: Russ Allbery <eagle@eyrie.org>
+ years: 2000-2001, 2004, 2006-2016
+- holder: The Board of Trustees of the Leland Stanford Junior University
+ years: 2006-2009, 2011-2013
+description: |
+ This package started as the runtests program I wrote for INN in 2000 to
+ serve as the basis for a new test suite using a test protocol similar to
+ that used for Perl modules. When I started maintaining additional C
+ packages, I adopted runtests for the test suite driver of those as well,
+ resulting in further improvements but also separate copies of the same
+ program in different distributions. The C TAP Harness distribution merges
+ all the various versions into a single code base that all my packages can
+ pull from.
+
+ C TAP Harness provides a full TAP specification driver (apart from a few
+ possible edge cases) and has additional special features for supporting
+ builds outside the source directory. It's mostly useful for packages
+ using Autoconf and Automake and because it doesn't assume or require Perl.
+
+ The runtests program can be built with knowledge of the source and build
+ directory and pass that knowledge on to test scripts, and will search for
+ test scripts in both the source and build directory. This makes it easier
+ for packages using Autoconf and Automake and supporting out-of-tree builds
+ to build some test programs, ship others, and run them all regardless of
+ what tree they're in. It also makes it easier for test cases to find
+ their supporting files when they run.
+
+ Also included in this package are C and shell libraries that provide
+ utility functions for writing test scripts that use TAP to report results.
+ The C library also provides a variety of utility functions useful for test
+ programs running as part of an Automake-built package: finding test data
+ files, creating temporary files, reporting output from external programs
+ running in the background, and similar common problems.
+distribution:
+ section: devel
+ tarname: c-tap-harness
+ version: c-tap-harness
+docs:
+ api:
+ - name: bail
+ title: bail and sysbail
+ - name: bmalloc
+ title: bmalloc, bcalloc, brealloc, bstrdup, and bstrndup
+ - name: breallocarray
+ title: breallocarray
+ - name: diag
+ title: diag and sysdiag
+ - name: diag_file_add
+ title: diag_file_add and diag_file_remove
+ - name: is_int
+ title: is_bool, is_int, is_double, is_string, and is_hex
+ - name: ok
+ title: ok, okv, and ok_block
+ - name: plan
+ title: plan and plan_lazy
+ - name: skip
+ title: skip and skip_block
+ - name: skip_all
+ title: skip_all
+ - name: test_cleanup_register
+ title: test_cleanup_register
+ - name: test_file_path
+ title: test_file_path and test_file_path_free
+ - name: test_tmpdir
+ title: test_tmpdir and test_tmpdir_free
+ user:
+ - name: writing
+ title: Writing TAP tests
+ - name: runtests
+ title: runtests manual page
+format: v1
+license:
+ name: Expat
+maintainer: Russ Allbery <eagle@eyrie.org>
+name: C TAP Harness
+requirements: |
+ C TAP Harness requires a C compiler to build. Any ISO C89 or later C
+ compiler on a system supporting the Single UNIX Specification, version 3
+ (SUSv3) should be sufficient. This should not be a problem on any modern
+ system. The test suite and shell library require a Bourne-compatible
+ shell. Outside of the test suite, C TAP Harness has no other
+ prerequisites or requirements.
+
+ To run the test suite, you will need Perl plus the Perl module Test::More,
+ which comes with Perl 5.8 or later. The following additional Perl modules
+ will be used by the test suite if present:
+
+ * Test::Pod
+ * Test::Spelling
+
+ All are available on CPAN. Those tests will be skipped if the modules are
+ not available.
+sections:
+- body: |
+ While there is an install target that installs runtests in the default
+ binary directory (`/usr/local/bin` by default) and installs the man pages,
+ one normally wouldn't install anything from this package. Instead, the
+ code is intended to be copied into your package and refreshed from the
+ latest release of C TAP Harness for each release.
+
+ You can obviously copy the code and integrate it however works best for
+ your package and your build system. Here's how I do it for my packages
+ as an example:
+
+ * Create a tests directory and copy tests/runtests.c into it. Create a
+ `tests/tap` subdirectory and copy the portions of the TAP library (from
+ `tests/tap`) that I need for that package into it. The TAP library is
+ designed to let you drop in additional source and header files for
+ additional utility functions that are useful in your package.
+
+ * Add code to my top-level `Makefile.am` (I always use a non-recursive
+ Makefile with `subdir-objects` set) to build `runtests` and the test
+ library:
+
+ ```make
+ check_PROGRAMS = tests/runtests
+ tests_runtests_CPPFLAGS = -DC_TAP_SOURCE='"$(abs_top_srcdir)/tests"' \
+ -DC_TAP_BUILD='"$(abs_top_builddir)/tests"'
+ check_LIBRARIES = tests/tap/libtap.a
+ tests_tap_libtap_a_CPPFLAGS = -I$(abs_top_srcdir)/tests
+ tests_tap_libtap_a_SOURCES = tests/tap/basic.c tests/tap/basic.h \
+ tests/tap/float.c tests/tap/float.h tests/tap/macros.h
+ ```
+
+ Omit `float.c` and `float.h` from the last line if your package doesn't
+ need the `is_double` function. Building the build and source
+ directories into runtests will let `tests/runtests -o <test>` work for
+ users without requiring that they set any other variables, even if
+ they're doing an out-of-source build.
+
+ Add additional source files and headers that should go into the TAP
+ library if you added extra utility functions for your package.
+
+ * Add code to `Makefile.am` to run the test suite:
+
+ ```make
+ check-local: $(check_PROGRAMS)
+ cd tests && ./runtests -l $(abs_top_srcdir)/tests/TESTS
+ ```
+
+ See the `Makefile.am` in this package for an example.
+
+ * List the test programs in the `tests/TESTS` file. This should have the
+ name of the test executable with the trailing "-t" or ".t" (you can use
+ either extension as you prefer) omitted.
+
+ Test programs must be executable.
+
+ For any test programs that need to be compiled, add build rules for
+ them in `Makefile.am`, similar to:
+
+ ```make
+ tests_libtap_c_basic_LDADD = tests/tap/libtap.a
+ ```
+
+ and add them to `check_PROGRAMS`. If you include the `float.c` add-on
+ in your libtap library, you will need to add `-lm` to the `_LDADD`
+ setting for all test programs linked against it.
+
+ A more complex example from the remctl package that needs additional
+ libraries:
+
+ ```make
+ tests_client_open_t_LDFLAGS = $(GSSAPI_LDFLAGS)
+ tests_client_open_t_LDADD = client/libremctl.la tests/tap/libtap.a \
+ util/libutil.la $(GSSAPI_LIBS)
+ ```
+
+ If the test program doesn't need to be compiled, add it to `EXTRA_DIST`
+ so that it will be included in the distribution.
+
+ * If you have test programs written in shell, copy `tests/tap/libtap.sh`
+ the tap subdirectory of your tests directory and add it to `EXTRA_DIST`.
+ Shell programs should start with:
+
+ ```sh
+ . "${C_TAP_SOURCE}/tap/libtap.sh"
+ ```
+
+ and can then use the functions defined in the library.
+
+ * Optionally copy `docs/writing-tests` into your package somewhere, such
+ as `tests/README`, as instructions to contributors on how to write tests
+ for this framework.
+
+ If you have configuration files that the user must create to enable some
+ of the tests, conventionally they go into `tests/config`.
+
+ If you have data files that your test cases use, conventionally they go
+ into `tests/data`. You can then find the data directory relative to the
+ `C_TAP_SOURCE` environment variable (set by `runtests`) in your test
+ program. If you have data that's compiled or generated by Autoconf, it
+ will be relative to the `BUILD` environment variable. Don't forget to add
+ test data to `EXTRA_DIST` as necessary.
+
+ For more TAP library add-ons, generally ones that rely on additional
+ portability code not shipped in this package or with narrower uses, see
+ [the rra-c-util
+ package](https://www.eyrie.org/~eagle/software/rra-c-util/). There are
+ several additional TAP library add-ons in the `tests/tap` directory in
+ that package. It's also an example of how to use this test harness in
+ another package.
+ title: Using the Harness
+support:
+ email: eagle@eyrie.org
+ github: rra/c-tap-harness
+ web: https://www.eyrie.org/~eagle/software/c-tap-harness/
+synopsis: C harness for running TAP-compliant tests
+test:
+ override: |
+ C TAP Harness comes with a comprehensive test suite, which you can run
+ after building with:
+
+ ```
+ make check
+ ```
+
+ If a test fails, you can run a single test with verbose output via:
+
+ ```
+ ./runtests -b `pwd`/tests -s `pwd`/tests -o <name-of-test>
+ ```
+
+ Do this instead of running the test program directly since it will ensure
+ that necessary environment variables are set up. You may need to change
+ the `-s` option argument if you build with a separate build directory from
+ the source directory.
+vcs:
+ browse: https://git.eyrie.org/?p=devel/c-tap-harness.git
+ github: rra/c-tap-harness
+ openhub: https://www.openhub.net/p/c-tap-harness
+ type: Git
+ url: https://git.eyrie.org/git/devel/c-tap-harness.git
+version: '4.0'
diff --git a/t/data/generate/c-tap-harness/metadata/blurb b/t/data/update/c-tap-harness/old/blurb
index f648587..f648587 100644
--- a/t/data/generate/c-tap-harness/metadata/blurb
+++ b/t/data/update/c-tap-harness/old/blurb
diff --git a/t/data/generate/c-tap-harness/metadata/build/suffix b/t/data/update/c-tap-harness/old/build/suffix
index 9abf545..9abf545 100644
--- a/t/data/generate/c-tap-harness/metadata/build/suffix
+++ b/t/data/update/c-tap-harness/old/build/suffix
diff --git a/t/data/generate/c-tap-harness/metadata/description b/t/data/update/c-tap-harness/old/description
index 5cb1bef..5cb1bef 100644
--- a/t/data/generate/c-tap-harness/metadata/description
+++ b/t/data/update/c-tap-harness/old/description
diff --git a/t/data/generate/c-tap-harness/metadata/metadata.json b/t/data/update/c-tap-harness/old/metadata.json
index 69fa575..69fa575 100644
--- a/t/data/generate/c-tap-harness/metadata/metadata.json
+++ b/t/data/update/c-tap-harness/old/metadata.json
diff --git a/t/data/generate/c-tap-harness/metadata/requirements b/t/data/update/c-tap-harness/old/requirements
index 54ddb22..54ddb22 100644
--- a/t/data/generate/c-tap-harness/metadata/requirements
+++ b/t/data/update/c-tap-harness/old/requirements
diff --git a/t/data/generate/c-tap-harness/metadata/sections/testing b/t/data/update/c-tap-harness/old/sections/testing
index 5e09e34..5e09e34 100644
--- a/t/data/generate/c-tap-harness/metadata/sections/testing
+++ b/t/data/update/c-tap-harness/old/sections/testing
diff --git a/t/data/generate/c-tap-harness/metadata/sections/using-the-harness b/t/data/update/c-tap-harness/old/sections/using-the-harness
index bf61cca..bf61cca 100644
--- a/t/data/generate/c-tap-harness/metadata/sections/using-the-harness
+++ b/t/data/update/c-tap-harness/old/sections/using-the-harness
diff --git a/t/data/update/control-archive/docknot.yaml b/t/data/update/control-archive/docknot.yaml
new file mode 100644
index 0000000..7c3e590
--- /dev/null
+++ b/t/data/update/control-archive/docknot.yaml
@@ -0,0 +1,321 @@
+---
+blurb: |
+ This software generates an INN control.ctl configuration file from
+ hierarchy configuration fragments, verifies control messages using GnuPG
+ where possible, processes new control messages to update a newsgroup list,
+ archives new control messages, and exports the list of newsgroups in a
+ format suitable for synchronizing the newsgroup list of a Netnews news
+ server. It is the software that maintains the control message and
+ newsgroup lists available from ftp.isc.org.
+build:
+ install: false
+ type: make
+copyrights:
+- holder: Russ Allbery <eagle@eyrie.org>
+ years: 2002-2004, 2007-2014, 2016-2018
+- holder: Marco d'Itri
+ years: '2001'
+- holder: UUNET Technologies, Inc.
+ years: '1996'
+description: |
+ This package contains three major components:
+
+ * All of the configuration used to generate a `control.ctl` file for INN
+ and the `PGPKEYS` and `README.html` files distributed with pgpcontrol,
+ along with the script to generate those files.
+
+ * Software to process control messages, verify them against that
+ authorization information, and maintain a control message archive and
+ list of active newsgroups. Software is also included to generate
+ reports of recent changes to the list of active newsgroups.
+
+ * The documentation files included in the control message archive and
+ newsgroup lists on ftp.isc.org.
+
+ Manual changes to the canonical newsgroup list are supported in a way that
+ generates the same log messages and uses the same locking structure so
+ that they can co-exist with automated changes and be included in the same
+ reports.
+
+ This is the software that generates the [active newsgroup
+ lists](ftp://ftp.isc.org/pub/usenet/CONFIG/) and [control message
+ archive](ftp://ftp.isc.org/pub/usenet/control/) hosted on ftp.isc.org, and
+ the source of the `control.ctl` file provided with INN.
+
+ For a web presentation of the information recorded here, as well as other
+ useful information about Usenet hierarchies, please see the [list of
+ Usenet managed hierarchies](http://usenet.trigofacile.com/hierarchies/).
+distribution:
+ section: usenet
+ tarname: control-archive
+ version: control-archive
+docs:
+ user:
+ - name: control-summary
+ title: control-summary manual page
+ - name: export-control
+ title: export-control manual page
+ - name: generate-files
+ title: generate-files manual page
+ - name: process-control
+ title: process-control manual page
+ - name: update-control
+ title: update-control manual page
+format: v1
+license:
+ name: Expat
+ notices: |
+ This product includes software developed by UUNET Technologies, Inc.
+maintainer: Russ Allbery <eagle@eyrie.org>
+name: control-archive
+quote:
+ author: Gene Spafford
+ text: |
+ Usenet is like a herd of performing elephants with diarrhea — massive,
+ difficult to redirect, awe-inspiring, entertaining, and a source of
+ mind-boggling amounts of excrement when you least expect it.
+requirements: |
+ Perl 5.6 or later plus the following additional Perl modules are required:
+
+ * Compress::Zlib (included in Perl 5.10 and later)
+ * Date::Parse (part of TimeDate)
+ * Net::NNTP (included in Perl 5.8 and later)
+ * Text::Template
+
+ [gzip](https://www.gnu.org/software/gzip/) and
+ [bzip2](http://www.bzip.org/) are required. Both are generally available
+ with current operating systems, possibly as supplemental packages.
+
+ process-control expects to be fed file names and message IDs of control
+ messages on standard input and therefore needs to be run from a news
+ server or some other source of control messages. A minimalist news server
+ like tinyleaf is suitable for this (I wrote tinyleaf, available as part of
+ [INN](https://www.eyrie.org/~eagle/software/inn/), for this purpose).
+sections:
+- body: |
+ This package uses a three-part version number. The first number will be
+ incremented for major changes, major new functionality, incompatible
+ changes to the configuration format (more than just adding new keys), or
+ similar disruptive changes. For lesser changes, the second number will be
+ incremented for any change to the code or functioning of the software. A
+ change to the third part of the version number indicates a release with
+ changes only to the configuration, PGP keys, and documentation files.
+ title: Versioning
+- body: |
+ The configuration data is in one file per hierarchy in the `config`
+ directory. Each file has the format specified in FORMAT and is designed
+ to be readable by INN's new configuration parser in case this can be
+ further automated down the road. The `config/special` directory contains
+ overrides, raw `control.ctl` fragments that should be used for particular
+ hierarchies instead of automatically-generated entries (usually for
+ special comments). Eventually, the format should be extended to handle as
+ many of these cases as possible.
+
+ The `keys` directory contains the PGP public keys for every hierarchy that
+ has one. The user IDs on these keys must match the signer expected by the
+ configuration data for the corresponding hierarchy.
+
+ The `forms` directory contains the basic file structure for the three
+ generated files.
+
+ The `scripts` directory contains all the software that generates the
+ configuration and documentation files, processes control messages, updates
+ the database, creates the newsgroup lists, and generates reports. Most
+ scripts in that directory have POD documentation included at the end of
+ the script, viewable by running perldoc on the script.
+
+ The `templates` directory contains templates for the `control-summary`
+ script. These are the templates I use myself. Other installations should
+ customize them.
+
+ The `docs` directory contains the extra documentation files that are
+ distributed from ftp.isc.org in the control message archive and newsgroup
+ list directories, plus the DocKnot metadata for this package.
+ title: Layout
+- body: |
+ This software is set up to run from `/srv/control`. To use a different
+ location, edit the paths at the beginning of each of the scripts in the
+ `scripts` directory to use different paths. By default, copying all the
+ files from the distribution into a `/srv/control` directory is almost all
+ that's needed. An install rule is provided to do this. To install the
+ software, run:
+
+ ```sh
+ 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:
+
+ ```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
+ ```
+
+ Both of these are done automatically as part of `make install`.
+ process-control expects `/srv/control/archive` to exist and archives
+ control messages there. It expects `/srv/control/tmp` to exist and uses
+ it for temporary files for GnuPG control message verification.
+
+ To process incoming control messages, you need to run `process-control` on
+ each message. `process-control` expects to receive, on standard input,
+ lines consisting of a path to a file, a space, and a message ID. This
+ input format is designed to work with the tinyleaf server that comes with
+ INN 2.5 and later, but it should also work as a channel feed from
+ pre-storage-API versions of INN (1.x). It will not work without
+ modification via a channel feed from a current version of INN, since it
+ doesn't understand the storage API and doesn't know how to retrieve
+ articles by tokens. This could be easily added; I just haven't needed it.
+
+ If you're using tinyleaf, here is the setup process:
+
+ 1. Create a directory that tinyleaf will use to store incoming articles
+ temporarily, the archive directory, and the logs directory and
+ install the software:
+
+ ```sh
+ make install
+ ```
+
+ 2. Run tinyleaf on some port, configuring it to use that directory and
+ to run process-control. A typical tinyleaf command line would be:
+
+ ```sh
+ tinyleaf /srv/control/spool /srv/control/scripts/process-control
+ ```
+
+ I run tinyleaf using systemd, but any inetd implementation should work
+ equally well.
+
+ 3. Set up a news feed to the system running tinyleaf that sends control
+ messages of interest. You should be careful not to send cancel control
+ messages or you'll get a ton of junk in your logs. The INN newsfeeds
+ entry I use is:
+
+ ```
+ isc-control:control,control.*,!control.cancel:Tf,Wnm:
+ ```
+
+ combined with nntpsend to send the articles.
+
+ That should be all there is to it. Watch the logs directory to see what
+ happens for incoming messages.
+
+ `scripts/process-control` just maintains a database file. To export that
+ data in a format that's useful for other software, run
+ `scripts/export-control`. This expects a `/srv/control/export` directory
+ into which it stores active and newsgroups files, a copy of the
+ `control.ctl` file, and all of the logs in a `LOGS` subdirectory. This
+ export directory can then be made available on the web, copied to another
+ system, or whatever else is appropriate. Generally,
+ `scripts/export-control` should be run periodically from cron.
+
+ Reports can be generated using `scripts/control-summary`. This script
+ needs configuration before running; see the top of the script and its
+ included POD documentation. There is a sample template in the `templates`
+ directory, and `scripts/weekly-report` shows a sample cron job for sending
+ out a regular report.
+ title: Installation
+- body: |
+ This package is intended to provide all of the tools, configuration, and
+ information required to duplicate the ftp.isc.org control message archive
+ and newsgroup list service if you so desire. To set up a similar service
+ based on that service, however, you will also want to bootstrap from the
+ existing data. Here is the procedure for that:
+
+ 1. Be sure that you're starting from the latest software and set of
+ configuration files. I will generally try to make a new release after
+ committing a batch of changes, but I may not make a new release after
+ every change. See the sections below for information about the Git
+ repository in which this package is maintained. You can always clone
+ that repository to get the latest configuration (and then merge or
+ cherry-pick changes from my repository into your repository as you
+ desire).
+
+ 2. Download the current newsgroup list from:
+
+ ftp://ftp.isc.org/pub/usenet/CONFIG/newsgroups.bz2
+
+ and then bootstrap the database from it:
+
+ ```sh
+ bzip2 -dc newsgroups.bz2 | scripts/update-control bulkload
+ ```
+
+ 3. If you want the log information so that your reports will include
+ changes made in the ftp.isc.org archive before you created your own,
+ copy the contents of ftp://ftp.isc.org/pub/usenet/CONFIG/LOGS/ into
+ `/srv/control/logs`.
+
+ 4. If you want to start with the existing control message repository,
+ download the contents of ftp://ftp.isc.org/pub/usenet/control/ into
+ `/srv/control/archive`. You can do this using a recursive download
+ tool that understands FTP, such as wget, but please use the options
+ that add delays and don't hammer the server to death.
+
+ After finishing those steps, you will have a copy of the ftp.isc.org
+ archive and can start processing control messages, possibly with different
+ configuration choices. You can generate the files that are found in
+ ftp://ftp.isc.org/pub/usenet/CONFIG/ by running `scripts/export-control`
+ as described above.
+ title: Bootstrapping
+- body: |
+ 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>
+ ```
+
+ where <hierarchy> is the hierarchy the checkgroups is for and
+ <checkgroups> is the path to the checkgroups file.
+ title: Maintenance
+support:
+ email: eagle@eyrie.org
+ extra: |
+ Configuration updates should be sent to usenet-config@isc.org.
+ github: rra/control-archive
+ web: https://www.eyrie.org/~eagle/software/control-archive/
+synopsis: processing and archiving of Netnews control messages
+vcs:
+ browse: https://git.eyrie.org/?p=usenet/control.archive.git
+ github: rra/control-archive
+ type: Git
+ url: https://git.eyrie.org/git/usenet/control-archive.git
+version: 1.8.0
diff --git a/t/data/generate/control-archive/metadata/blurb b/t/data/update/control-archive/old/blurb
index 19b415b..19b415b 100644
--- a/t/data/generate/control-archive/metadata/blurb
+++ b/t/data/update/control-archive/old/blurb
diff --git a/t/data/generate/control-archive/metadata/description b/t/data/update/control-archive/old/description
index b6170d0..b6170d0 100644
--- a/t/data/generate/control-archive/metadata/description
+++ b/t/data/update/control-archive/old/description
diff --git a/t/data/generate/control-archive/metadata/metadata.json b/t/data/update/control-archive/old/metadata.json
index dd20003..dd20003 100644
--- a/t/data/generate/control-archive/metadata/metadata.json
+++ b/t/data/update/control-archive/old/metadata.json
diff --git a/t/data/generate/control-archive/metadata/notices b/t/data/update/control-archive/old/notices
index d808155..d808155 100644
--- a/t/data/generate/control-archive/metadata/notices
+++ b/t/data/update/control-archive/old/notices
diff --git a/t/data/generate/control-archive/metadata/quote b/t/data/update/control-archive/old/quote
index 1ac4393..1ac4393 100644
--- a/t/data/generate/control-archive/metadata/quote
+++ b/t/data/update/control-archive/old/quote
diff --git a/t/data/generate/control-archive/metadata/requirements b/t/data/update/control-archive/old/requirements
index 2b21515..2b21515 100644
--- a/t/data/generate/control-archive/metadata/requirements
+++ b/t/data/update/control-archive/old/requirements
diff --git a/t/data/generate/control-archive/metadata/sections/bootstrapping b/t/data/update/control-archive/old/sections/bootstrapping
index 7063e23..7063e23 100644
--- a/t/data/generate/control-archive/metadata/sections/bootstrapping
+++ b/t/data/update/control-archive/old/sections/bootstrapping
diff --git a/t/data/generate/control-archive/metadata/sections/installation b/t/data/update/control-archive/old/sections/installation
index a162011..a162011 100644
--- a/t/data/generate/control-archive/metadata/sections/installation
+++ b/t/data/update/control-archive/old/sections/installation
diff --git a/t/data/generate/control-archive/metadata/sections/layout b/t/data/update/control-archive/old/sections/layout
index d12d7e1..d12d7e1 100644
--- a/t/data/generate/control-archive/metadata/sections/layout
+++ b/t/data/update/control-archive/old/sections/layout
diff --git a/t/data/generate/control-archive/metadata/sections/maintenance b/t/data/update/control-archive/old/sections/maintenance
index 676a6f7..676a6f7 100644
--- a/t/data/generate/control-archive/metadata/sections/maintenance
+++ b/t/data/update/control-archive/old/sections/maintenance
diff --git a/t/data/generate/control-archive/metadata/sections/versioning b/t/data/update/control-archive/old/sections/versioning
index 7326aeb..7326aeb 100644
--- a/t/data/generate/control-archive/metadata/sections/versioning
+++ b/t/data/update/control-archive/old/sections/versioning
diff --git a/t/data/generate/control-archive/metadata/support/extra b/t/data/update/control-archive/old/support/extra
index 082b244..082b244 100644
--- a/t/data/generate/control-archive/metadata/support/extra
+++ b/t/data/update/control-archive/old/support/extra
diff --git a/t/data/update/lbcd/docknot.yaml b/t/data/update/lbcd/docknot.yaml
new file mode 100644
index 0000000..087c3a9
--- /dev/null
+++ b/t/data/update/lbcd/docknot.yaml
@@ -0,0 +1,113 @@
+---
+blurb: |
+ lbcd is a daemon that runs on a UNIX system and answers UDP queries with
+ information about system load, number of logged-on users, uptime, and free
+ /tmp space. This information can be used to accumulate system status
+ across a cluster with light-weight queries or can be used as input to a
+ load-balancing system to choose the best system to which to direct new
+ incoming connections.
+build:
+ autoconf: '2.64'
+ automake: '1.11'
+ autotools: true
+ middle: |
+ lbcd looks for `$sysconfdir/nolbcd` and returns the maximum load if that
+ file is present, allowing one to effectively drop a system out of a
+ load-balanced pool by touching that file. By default, the path is
+ `/usr/local/etc/nolbcd`, but you may want to pass `--sysconfdir=/etc` to
+ configure to use `/etc/nolbcd`.
+
+ lbcdclient is written in Perl, so you may have to edit the first line of
+ the script to point to the correct Perl location on your system. It does
+ not use any sophisticated Perl features or add-on modules.
+ suffix: |
+ You will generally want to start lbcd at system boot. All that is needed
+ is a simple init script to start lbcd with the appropriate options or kill
+ it again. It writes its PID into `/var/run/lbcd.pid` by default (and this
+ can be changed with the `-P` option). On many systems, lbcd will need to
+ run as root or as a member of particular groups to obtain system load
+ average and uptime information.
+ type: Autoconf
+copyrights:
+- holder: The Board of Trustees of the Leland Stanford Junior University
+ years: 1993-1994, 1996-1998, 2000, 2003-2009, 2012-2013
+description: |
+ lbcd provides a lightweight way to query a system via unauthenticated UDP
+ for system load information plus some related information that may be
+ relevant to determining which system to hand out. It was designed for use
+ with the [lbnamed DNS load
+ balancer](https://www.stanford.edu/~riepel/lbnamed/). System load, number
+ of logged-in users, free /tmp space, and system uptime are always
+ returned. lbcd can also be configured to probe various local services and
+ modify the returned weights based on whether those services are reachable,
+ or to return a static weight for round-robin load balancing.
+
+ The information provided isn't particularly sophisticated, and a good
+ hardware load balancer will be able to consider such things as connection
+ latency and responsiveness to make better decisions. However, lbcd with
+ lbnamed works quite well for smaller scale problems, scales well to
+ multiple load balance pools for different services, provides a simple UDP
+ health check service, and is much simpler and cheaper to understand and
+ deploy.
+
+ Included in this package is a small client program, lbcdclient, which can
+ query an lbcd server and display a formatted version of the returned
+ information.
+
+ It was originally written by Roland Schemers. Larry Schwimmer rewrote it
+ to add protocol version 3 with some additional features and service
+ probing, and then I rewrote it again to update the coding style and use my
+ standard portability layer.
+distribution:
+ packaging:
+ debian:
+ package: lbcd
+ summary: |
+ A Debian package is included in Debian 5.0 (lenny) and later releases.
+ Thanks to Guido Guenther for doing the initial upload to Debian.
+ section: system
+ tarname: lbcd
+ version: lbcd
+docs:
+ user:
+ - name: lbcd
+ title: lbcd manual page
+ - name: lbcdclient
+ title: lbcdclient manual page
+format: v1
+license:
+ name: Expat
+maintainer: Russ Allbery <eagle@eyrie.org>
+name: lbcd
+orphaned: |
+ Although I believe it is still useful, I no longer use this method of DNS
+ load balancing and am no longer maintaining this package. If you would
+ like to pick up maintenance of it, please feel free. Contact me if you
+ would like this page to redirect to its new home.
+requirements: |
+ lbcd is written in C, so you'll need a C compiler. It also uses kernel
+ calls to obtain load and uptime information, and at present has only been
+ ported to Linux, Solaris, AIX, various BSD systems, Mac OS X, HP-UX, IRIX,
+ and Tru64. It is currently primarily tested on Linux. Platforms not
+ listed may require some porting effort, as may old or unusual platforms
+ that aren't regularly tested.
+
+ The lbcdclient program requires Perl 5.6 or later and requires the
+ IO::Socket::INET6 module for IPv6 support.
+support:
+ email: eagle@eyrie.org
+ listname: lbnamed-users
+ listurl: https://mailman.stanford.edu/mailman/listinfo/lbnamed-users
+ web: https://www.eyrie.org/~eagle/software/lbcd/
+synopsis: responder for load balancing
+test:
+ lancaster: true
+ suffix: |
+ Currently, the test suite only checks the portability and utility
+ libraries, not the functionality of lbcd or lbcdclient.
+vcs:
+ browse: https://git.eyrie.org/?p=system/lbcd.git
+ github: rra/lbcd
+ type: Git
+ url: https://git.eyrie.org/git/system/lbcd.git
+version: 3.4.2
diff --git a/t/data/generate/lbcd/metadata/blurb b/t/data/update/lbcd/old/blurb
index 3689eb9..3689eb9 100644
--- a/t/data/generate/lbcd/metadata/blurb
+++ b/t/data/update/lbcd/old/blurb
diff --git a/t/data/generate/lbcd/metadata/build/middle b/t/data/update/lbcd/old/build/middle
index 6efe4de..6efe4de 100644
--- a/t/data/generate/lbcd/metadata/build/middle
+++ b/t/data/update/lbcd/old/build/middle
diff --git a/t/data/generate/lbcd/metadata/build/suffix b/t/data/update/lbcd/old/build/suffix
index 064769e..064769e 100644
--- a/t/data/generate/lbcd/metadata/build/suffix
+++ b/t/data/update/lbcd/old/build/suffix
diff --git a/t/data/generate/lbcd/metadata/debian/summary b/t/data/update/lbcd/old/debian/summary
index 18524cb..18524cb 100644
--- a/t/data/generate/lbcd/metadata/debian/summary
+++ b/t/data/update/lbcd/old/debian/summary
diff --git a/t/data/generate/lbcd/metadata/description b/t/data/update/lbcd/old/description
index c367a1b..c367a1b 100644
--- a/t/data/generate/lbcd/metadata/description
+++ b/t/data/update/lbcd/old/description
diff --git a/t/data/generate/lbcd/metadata/metadata.json b/t/data/update/lbcd/old/metadata.json
index 36efc1c..36efc1c 100644
--- a/t/data/generate/lbcd/metadata/metadata.json
+++ b/t/data/update/lbcd/old/metadata.json
diff --git a/t/data/generate/lbcd/metadata/orphaned b/t/data/update/lbcd/old/orphaned
index 7f62227..7f62227 100644
--- a/t/data/generate/lbcd/metadata/orphaned
+++ b/t/data/update/lbcd/old/orphaned
diff --git a/t/data/generate/lbcd/metadata/requirements b/t/data/update/lbcd/old/requirements
index 8c3eace..8c3eace 100644
--- a/t/data/generate/lbcd/metadata/requirements
+++ b/t/data/update/lbcd/old/requirements
diff --git a/t/data/generate/lbcd/metadata/test/suffix b/t/data/update/lbcd/old/test/suffix
index 3626ede..3626ede 100644
--- a/t/data/generate/lbcd/metadata/test/suffix
+++ b/t/data/update/lbcd/old/test/suffix
diff --git a/t/data/update/pam-krb5/docknot.yaml b/t/data/update/pam-krb5/docknot.yaml
new file mode 100644
index 0000000..f91ad1c
--- /dev/null
+++ b/t/data/update/pam-krb5/docknot.yaml
@@ -0,0 +1,508 @@
+---
+advisories:
+- date: 2009-02-11
+ threshold: '3.13'
+ versions: 3.12 and earlier
+blurb: |
+ pam-krb5 is a Kerberos PAM module for either MIT Kerberos or Heimdal. It
+ supports ticket refreshing by screen savers, configurable authorization
+ handling, authentication of non-local accounts for network services,
+ password changing, and password expiration, as well as all the standard
+ expected PAM features. It works correctly with OpenSSH, even with
+ ChallengeResponseAuthentication and PrivilegeSeparation enabled, and
+ supports extensive configuration either by PAM options or in krb5.conf or
+ both. PKINIT is supported with recent versions of both MIT Kerberos and
+ Heimdal and FAST is supported with recent MIT Kerberos.
+build:
+ autoconf: '2.64'
+ automake: '1.11'
+ autotools: true
+ kerberos: true
+ manpages: true
+ middle: |
+ The module will be installed in `/usr/local/lib/security` by default,
+ except on 64-bit versions of Linux which will use
+ `/usr/local/lib64/security` to match the default PAM configuration. You
+ can change the installation locations with the `--prefix`, `--mandir`, and
+ `--libdir` options to configure. The module will always be installed in a
+ subdirectory named `security` under the specified libdir. On Linux, use
+ `--prefix=/usr` to install the man page into `/usr/share/man` and the PAM
+ module in `/lib/security` or `/lib64/security`.
+ reduced_depends: true
+ type: Autoconf
+copyrights:
+- holder: Russ Allbery <eagle@eyrie.org>
+ years: 2005-2010, 2014-2015, 2017
+- holder: The Board of Trustees of the Leland Stanford Junior University
+ years: 2009-2011
+- holder: Andres Salomon <dilinger@debian.org>
+ years: '2005'
+- holder: Frank Cusack <fcusack@fcusack.com>
+ years: 1999-2000
+description: |
+ pam-krb5 provides a Kerberos PAM module that supports authentication, user
+ ticket cache handling, simple authorization (via .k5login or checking
+ Kerberos principals against local usernames), and password changing. It
+ can be configured through either options in the PAM configuration itself
+ or through entries in the system krb5.conf file, and it tries to work
+ around PAM implementation flaws in commonly-used PAM-enabled applications
+ such as OpenSSH and xdm. It supports both PKINIT and FAST to the extent
+ that the underlying Kerberos libraries support these features.
+
+ This is not the Kerberos PAM module maintained on Sourceforge and used on
+ Red Hat systems. It is an independent implementation that, if it ever
+ shared any common code, diverged long ago. It supports some features that
+ the Sourceforge module does not (particularly around authorization), and
+ does not support some options (particularly ones not directly related to
+ Kerberos) that it does. This module will never support Kerberos v4 or
+ AFS. For an AFS session module that works with this module (or any other
+ Kerberos PAM module), see
+ [pam-afs-session](https://www.eyrie.org/~eagle/software/pam-afs-session/).
+
+ If there are other options besides AFS and Kerberos v4 support from the
+ Sourceforge PAM module that you're missing in this module, please let me
+ know.
+distribution:
+ packaging:
+ debian:
+ package: libpam-krb5
+ summary: |
+ Debian packages are available from Debian in Debian 4.0 (etch) and later
+ releases as libpam-krb5 and libpam-heimdal. The former packages are built
+ against the MIT Kerberos libraries and the latter against the Heimdal
+ libraries.
+ section: kerberos
+ tarname: pam-krb5
+ version: pam-krb5
+docs:
+ user:
+ - name: pam-krb5
+ title: Manual page
+format: v1
+license:
+ name: BSD-3-clause-or-GPL-1+
+maintainer: Russ Allbery <eagle@eyrie.org>
+name: pam-krb5
+quote:
+ author: Joyce McGreevy
+ date: 2003-11-17
+ text: |
+ "You're always going to have some people who can't appreciate the thrill
+ of a tepid change for the somewhat better," explained one source.
+ title: '"Look, ma, no hands!"'
+ work: Salon
+requirements: |
+ Either MIT Kerberos (or Kerberos implementations based on it) or Heimdal
+ are supported. MIT Keberos 1.3 or later may be required; this module has
+ not been tested with earlier versions.
+
+ For PKINIT support, Heimdal 0.8rc1 or later or MIT Kerberos 1.6.3 or later
+ are required. Earlier MIT Kerberos 1.6 releases have a bug in their
+ handling of PKINIT options.
+
+ For FAST (Flexible Authentication Secure Tunneling) support, MIT Kerberos
+ 1.7 or higher is required. For anonymous FAST support, anonymous
+ authentication (generally anonymous PKINIT) support is required in both
+ the Kerberos libraries and in the local KDC.
+
+ This module should work on Linux and Solaris (and build with gcc, clang,
+ or the Sun C compiler), but has been far more heavily tested on Linux.
+ There is beta-quality support for the AIX NAS Kerberos implementation.
+ Other PAM implementations will probably require some porting, although
+ untested build system support is present for FreeBSD, Mac OS X, and HP-UX.
+ I personally can only test on Linux and rely on others to report problems
+ on other operating systems.
+
+ Old versions of OpenSSH are known to call `pam_authenticate` followed by
+ `pam_setcred(PAM_REINITIALIZE_CRED)` without first calling
+ `pam_open_session`, thereby requesting that an existing ticket cache be
+ renewed (similar to what a screensaver would want) rather than requesting
+ a new ticket cache be created. Since this behavior is indistinguishable
+ at the PAM level from a screensaver, pam-krb5 when used with these old
+ versions of OpenSSH will refresh the ticket cache of the OpenSSH daemon
+ rather than setting up a new ticket cache for the user. The resulting
+ ticket cache will have the correct permissions (this is not a security
+ concern), but will not be named correctly or referenced in the user's
+ environment and will be overwritten by the next user login. The best
+ solution to this problem is to upgrade OpenSSH. I'm not sure exactly when
+ this problem was fixed, but at the very least OpenSSH 4.3 and later do not
+ exhibit it.
+sections:
+- body: |
+ Just installing the module does not enable it or change anything about
+ your system authentication configuration. To use the module for all
+ system authentication on Debian systems, put something like:
+
+ ```
+ auth sufficient pam_krb5.so minimum_uid=1000
+ auth required pam_unix.so try_first_pass nullok_secure
+ ```
+
+ in `/etc/pam.d/common-auth`, something like:
+
+ ```
+ session optional pam_krb5.so minimum_uid=1000
+ session required pam_unix.so
+ ```
+
+ in `/etc/pam.d/common-session`, and something like:
+
+ ```
+ account required pam_krb5.so minimum_uid=1000
+ account required pam_unix.so
+ ```
+
+ in `/etc/pam.d/common-account`. The `minimum_uid` setting tells the PAM
+ module to pass on any users with a UID lower than 1000, thereby bypassing
+ Kerberos authentication for the root account and any system accounts. You
+ normally want to do this since otherwise, if the network is down, the
+ Kerberos authentication can time out and make it difficult to log in as
+ root and fix matters. This also avoids problems with Kerberos principals
+ that happen to match system accounts accidentally getting access to those
+ accounts.
+
+ Be sure to include the module in the session group as well as the auth
+ group. Without the session entry, the user's ticket cache will not be
+ created properly for ssh logins (among possibly others).
+
+ If your users should normally all use Kerberos passwords exclusively,
+ putting something like:
+
+ ```
+ password sufficient pam_krb5.so minimum_uid=1000
+ password required pam_unix.so try_first_pass obscure md5
+ ```
+
+ in `/etc/pam.d/common-password` will change users' passwords in Kerberos
+ by default and then only fall back on Unix if that doesn't work. (You can
+ make this tighter by using the more complex new-style PAM configuration.)
+ If you instead want to synchronize local and Kerberos passwords and change
+ them both at the same time, you can do something like:
+
+ ```
+ password required pam_unix.so obscure sha512
+ password required pam_krb5.so use_authtok minimum_uid=1000
+ ```
+
+ If you have multiple environments that you want to synchronize and you
+ don't want password changes to continue if the Kerberos password change
+ fails, use the `clear_on_fail` option. For example:
+
+ ```
+ password required pam_krb5.so clear_on_fail minimum_uid=1000
+ password required pam_unix.so use_authtok obscure sha512
+ password required pam_smbpass.so use_authtok
+ ```
+
+ In this case, if `pam_krb5` cannot change the password (due to password
+ strength rules on the KDC, for example), it will clear the stored password
+ (because of the `clear_on_fail` option), and since `pam_unix` and
+ `pam_smbpass` are both configured with `use_authtok`, they will both fail.
+ `clear_on_fail` is not the default because it would interfere with the
+ more common pattern of falling back to local passwords if the user doesn't
+ exist in Kerberos.
+
+ If you use a more complex configuration with the Linux PAM `[]` syntax for
+ the session and account groups, note that `pam_krb5` returns a status of
+ ignore, not success, if the user didn't log on with Kerberos. You may
+ need to handle that explicitly with `ignore=ignore` in your action list.
+
+ There are many, many other possibilities. See the Linux PAM documentation
+ for all the configuration options.
+
+ On Red Hat systems, modify `/etc/pam.d/system-auth` instead, which
+ contains all of the configuration for the different stacks.
+
+ You can also use pam-krb5 only for specific services. In that case,
+ modify the files in `/etc/pam.d` for that particular service to use
+ `pam_krb5.so` for authentication. For services that are using passwords
+ over TLS to authenticate users, you may want to use the `ignore_k5login`
+ and `no_ccache` options to the authenticate module. `.k5login`
+ authorization is only meaningful for local accounts and ticket caches are
+ usually (although not always) only useful for interactive sessions.
+
+ Configuring the module for Solaris is both simpler and less flexible,
+ since Solaris (at least Solaris 8 and 9, which are the last versions of
+ Solaris with which this module was extensively tested) use a single
+ `/etc/pam.conf` file that contains configuration for all programs. For
+ console login on Solaris, try something like:
+
+ ```
+ login auth sufficient /usr/local/lib/security/pam_krb5.so minimum_uid=100
+ login auth required /usr/lib/security/pam_unix_auth.so.1 use_first_pass
+ login account required /usr/local/lib/security/pam_krb5.so minimum_uid=100
+ login account required /usr/lib/security/pam_unix_account.so.1
+ login session required /usr/local/lib/security/pam_krb5.so retain_after_close minimum_uid=100
+ login session required /usr/lib/security/pam_unix_session.so.1
+ ```
+
+ A similar configuration could be used for other services, such as ssh.
+ See the pam.conf(5) man page for more information. When using this module
+ with Solaris login (at least on Solaris 8 and 9), you will probably also
+ need to add `retain_after_close` to the PAM configuration to avoid having
+ the user's credentials deleted before they are logged in.
+
+ The Solaris Kerberos library reportedly does not support prompting for a
+ password change of an expired account during authentication. Supporting
+ password change for expired accounts on Solaris with native Kerberos may
+ therefore require setting the `defer_pwchange` or `force_pwchange` option
+ for selected login applications. See the description and warnings about
+ that option in the pam_krb5(5) man page.
+
+ Some configuration options may be put in the `krb5.conf` file used by your
+ Kerberos libraries (usually `/etc/krb5.conf` or
+ `/usr/local/etc/krb5.conf`) instead or in addition to the PAM
+ configuration. See the man page for more details.
+
+ The Kerberos library, via pam-krb5, will prompt the user to change their
+ password if their password is expired, but when using OpenSSH, this will
+ only work when `ChallengeResponseAuthentication` is enabled. Unless this
+ option is enabled, OpenSSH doesn't pass PAM messages to the user and can
+ only respond to a simple password prompt.
+
+ If you are using MIT Kerberos, be aware that users whose passwords are
+ expired will not be prompted to change their password unless the KDC
+ configuration for your realm in `[realms]` in `krb5.conf` contains a
+ `master_kdc` setting or, if using DNS SRV records, you have a DNS entry
+ for `_kerberos-master` as well as `_kerberos`.
+ title: Configuring
+- body: |
+ The first step when debugging any problems with this module is to add
+ `debug` to the PAM options for the module (either in the PAM configuration
+ or in `krb5.conf`). This will significantly increase the logging from the
+ module and should provide a trace of exactly what failed and any available
+ error information.
+
+ Many Kerberos authentication problems are due to configuration issues in
+ `krb5.conf`. If pam-krb5 doesn't work, first check that `kinit` works on
+ the same system. That will test your basic Kerberos configuration. If
+ the system has a keytab file installed that's readable by the process
+ doing authentication via PAM, make sure that the keytab is current and
+ contains a key for `host/<system>` where <system> is the fully-qualified
+ hostname. pam-krb5 prevents KDC spoofing by checking the user's
+ credentials when possible, but this means that if a keytab is present it
+ must be correct or authentication will fail. You can check the keytab
+ with `klist -k` and `kinit -k`.
+
+ Be sure that all libraries and modules, including PAM modules, loaded by a
+ program use the same Kerberos libraries. Sometimes programs that use PAM,
+ such as current versions of OpenSSH, also link against Kerberos directly.
+ If your sshd is linked against one set of Kerberos libraries and pam-krb5
+ is linked against a different set of Kerberos libraries, this will often
+ cause problems (such as segmentation faults, bus errors, assertions, or
+ other strange behavior). Similar issues apply to the com_err library or
+ any other library used by both modules and shared libraries and by the
+ application that loads them. If your OS ships Kerberos libraries, it's
+ usually best if possible to build all Kerberos software on the system
+ against those libraries.
+ title: Debugging
+- body: |
+ The normal sequence of actions taken for a user login is:
+
+ ```
+ pam_authenticate
+ pam_setcred(PAM_ESTABLISH_CRED)
+ pam_open_session
+ pam_acct_mgmt
+ ```
+
+ and then at logout:
+
+ ```
+ pam_close_session
+ ```
+
+ followed by closing the open PAM session. The corresponding `pam_sm_*`
+ functions in this module are called when an application calls those public
+ interface functions. Not all applications call all of those functions, or
+ in particularly that order, although `pam_authenticate` is always first
+ and has to be.
+
+ When `pam_authenticate` is called, pam-krb5 creates a temporary ticket
+ cache in `/tmp` and sets the PAM environment variable `PAM_KRB5CCNAME` to
+ point to it. This ticket cache will be automatically destroyed when the
+ PAM session is closed and is there only to pass the initial credentials to
+ the call to `pam_setcred`. The module would use a memory cache, but
+ memory caches will only work if the application preserves the PAM
+ environment between the calls to `pam_authenticate` and `pam_setcred`.
+ Most do, but OpenSSH notoriously does not and calls `pam_authenticate` in
+ a subprocess, so this method is used to pass the tickets to the
+ `pam_setcred` call in a different process.
+
+ `pam_authenticate` does a complete authentication, including checking the
+ resulting TGT by obtaining a service ticket for the local host if
+ possible, but this requires read access to the system keytab. If the
+ keytab doesn't exist, can't be read, or doesn't include the appropriate
+ credentials, the default is to accept the authentication. This can be
+ controlled by setting `verify_ap_req_nofail` to true in `[libdefaults]` in
+ `/etc/krb5.conf`. `pam_authenticate` also does a basic authorization
+ check, by default calling `krb5_kuserok` (which uses `~/.k5login` if
+ available and falls back to checking that the principal corresponds to the
+ account name). This can be customized with several options documented in
+ the pam_krb5(5) man page.
+
+ pam-krb5 treats `pam_open_session` and `pam_setcred(PAM_ESTABLISH_CRED)`
+ as synonymous, as some applications call one and some call the other.
+ Both copy the initial credentials from the temporary cache into a
+ permanent cache for this session and set `KRB5CCNAME` in the environment.
+ It will remember when the credential cache has been established and then
+ avoid doing any duplicate work afterwards, since some applications call
+ `pam_setcred` or `pam_open_session` multiple times (most notably X.Org 7
+ and earlier xdm, which also throws away the module settings the last time
+ it calls them).
+
+ `pam_acct_mgmt` finds the ticket cache, reads it in to obtain the
+ authenticated principal, and then does is another authorization check
+ against `.k5login` or the local account name as described above.
+
+ After the call to `pam_setcred` or `pam_open_session`, the ticket cache
+ will be destroyed whenever the calling application either destroys the PAM
+ environment or calls `pam_close_session`, which it should do on user
+ logout.
+
+ The normal sequence of events when refreshing a ticket cache (such as
+ inside a screensaver) is:
+
+ ```
+ pam_authenticate
+ pam_setcred(PAM_REINITIALIZE_CRED)
+ pam_acct_mgmt
+ ```
+
+ (`PAM_REFRESH_CRED` may be used instead.) Authentication proceeds as
+ above. At the `pam_setcred` stage, rather than creating a new ticket
+ cache, the module instead finds the current ticket cache (from the
+ `KRB5CCNAME` environment variable or the default ticket cache location
+ from the Kerberos library) and then reinitializes it with the credentials
+ from the temporary `pam_authenticate` ticket cache. When refreshing a
+ ticket cache, the application should not open a session. Calling
+ `pam_acct_mgmt` is optional; pam-krb5 doesn't do anything different when
+ it's called in this case.
+
+ If `pam_authenticate` apparently didn't succeed, or if an account was
+ configured to be ignored via `ignore_root` or `minimum_uid`, `pam_setcred`
+ (and therefore `pam_open_session`) and `pam_acct_mgmt` return
+ `PAM_IGNORE`, which tells the PAM library to proceed as if that module
+ wasn't listed in the PAM configuration at all. `pam_authenticate`,
+ however, returns failure in the ignored user case by default, since
+ otherwise a configuration using `ignore_root` with pam-krb5 as the only
+ PAM module would allow anyone to log in as root without a password. There
+ doesn't appear to be a case where returning `PAM_IGNORE` instead would
+ improve the module's behavior, but if you know of a case, please let me
+ know.
+
+ By default, `pam_authenticate` intentionally does not follow the PAM
+ standard for handling expired accounts and instead returns failure from
+ `pam_authenticate` unless the Kerberos libraries are able to change the
+ account password during authentication. Too many applications either do
+ not call `pam_acct_mgmt` or ignore its exit status. The fully correct PAM
+ behavior (returning success from `pam_authenticate` and
+ `PAM_NEW_AUTHTOK_REQD` from `pam_acct_mgmt`) can be enabled with the
+ `defer_pwchange` option.
+
+ The `defer_pwchange` option is unfortunately somewhat tricky to implement.
+ In this case, the calling sequence is:
+
+ ```
+ pam_authenticate
+ pam_acct_mgmt
+ pam_chauthtok
+ pam_setcred
+ pam_open_session
+ ```
+
+ During the first `pam_authenticate`, we can't obtain credentials and
+ therefore a ticket cache since the password is expired. But
+ `pam_authenticate` isn't called again after `pam_chauthtok`, so
+ `pam_chauthtok` has to create a ticket cache. We however don't want it to
+ do this for the normal password change (`passwd`) case.
+
+ What we do is set a flag in our PAM data structure saying that we're
+ processing an expired password, and `pam_chauthtok`, if it sees that flag,
+ redoes the authentication with password prompting disabled after it
+ finishes changing the password.
+
+ Unfortunately, when handling password changes this way, `pam_chauthtok`
+ will always have to prompt the user for their current password again even
+ though they just typed it. This is because the saved authentication
+ tokens are cleared after `pam_authenticate` returns, for security reasons.
+ We could hack around this by saving the password in our PAM data
+ structure, but this would let the application gain access to it (exactly
+ what the clearing is intended to prevent) and breaks a PAM library
+ guarantee. We could also work around this by having `pam_authenticate`
+ get the `kadmin/changepw` authenticator in the expired password case and
+ store it for `pam_chauthtok`, but it doesn't seem worth the hassle.
+ title: Implementation Notes
+- body: |
+ Originally written by Frank Cusack <fcusack@fcusack.com>, with the
+ following acknowledgement:
+
+ > Thanks to Naomaru Itoi <itoi@eecs.umich.edu>, Curtis King
+ > <curtis.king@cul.ca>, and Derrick Brashear <shadow@dementia.org>, all of
+ > whom have written and made available Kerberos 4/5 modules. Although no
+ > code in this module is directly from these author's modules, (except the
+ > get_user_info() routine in support.c; derived from whichever of these
+ > authors originally wrote the first module the other 2 copied from), it
+ > was extremely helpful to look over their code which aided in my design.
+
+ The module was then patched for the FreeBSD ports collection with
+ additional modifications by unknown maintainers and then was modified by
+ Joel Kociolek <joko@logidee.com> to be usable with Debian GNU/Linux.
+
+ It was packaged by Sam Hartman as the Kerberos v5 PAM module for Debian
+ and improved and modified by him and later by Russ Allbery to fix bugs and
+ add additional features. It was then adopted by Andres Salomon, who added
+ support for refreshing credentials.
+
+ The current distribution is maintained by Russ Allbery, who also added
+ support for reading configuration from `krb5.conf`, added many features
+ for compatibility with the Sourceforge module, commented and standardized
+ the formatting of the code, and overhauled the documentation.
+
+ Thanks to Douglas E. Engert for the initial implementation of PKINIT
+ support. I have since modified and reworked it extensively, so any bugs
+ or compilation problems are my fault.
+
+ Thanks to Markus Moeller for lots of debugging and multiple patches and
+ suggestions for improved portability.
+
+ Thanks to Booker Bense for the implementation of the `alt_auth_map`
+ option.
+
+ Thanks to Sam Hartman for the FAST support implementation.
+ title: History and Acknowledgements
+support:
+ email: eagle@eyrie.org
+ github: rra/pam-krb5
+ web: https://www.eyrie.org/~eagle/software/pam-krb5/
+synopsis: PAM module for Kerberos authentication
+test:
+ prefix: |
+ pam-krb5 comes with a comprehensive test suite, but it requires some
+ configuration in order to test anything other than low-level utility
+ functions. For the full test suite, you will need to have a running KDC
+ in which you can create two test accounts, one with admin access to the
+ other. Using a test KDC environment, if you have one, is recommended.
+
+ Follow the instructions in `tests/config/README` to configure the test
+ suite.
+
+ Now, you can run the test suite with:
+ suffix: |
+ The default libkadm5clnt library on the system must match the
+ implementation of your KDC for the module/expired test to work, since the
+ two kadmin protocols are not compatible. If you use the MIT library
+ against a Heimdal server, the test will be skipped; if you use the Heimdal
+ library against an MIT server, the test suite may hang.
+
+ Several `module/expired` tests are expected to fail with Heimdal 1.5 due
+ to a bug in Heimdal with reauthenticating immediately after a
+ library-mediated password change of an expired password. This is fixed in
+ later releases of Heimdal.
+vcs:
+ browse: https://git.eyrie.org/?p=kerberos/pam-krb5.git
+ github: rra/pam-krb5
+ openhub: https://www.openhub.net/p/pamkrb5
+ type: Git
+ url: https://git.eyrie.org/git/kerberos/pam-krb5.git
+version: '4.8'
diff --git a/docs/metadata/README b/t/data/update/pam-krb5/old/README
index 26316da..26316da 100644
--- a/docs/metadata/README
+++ b/t/data/update/pam-krb5/old/README
diff --git a/t/data/generate/pam-krb5/metadata/blurb b/t/data/update/pam-krb5/old/blurb
index a78f46f..a78f46f 100644
--- a/t/data/generate/pam-krb5/metadata/blurb
+++ b/t/data/update/pam-krb5/old/blurb
diff --git a/t/data/generate/pam-krb5/metadata/build/middle b/t/data/update/pam-krb5/old/build/middle
index a168962..a168962 100644
--- a/t/data/generate/pam-krb5/metadata/build/middle
+++ b/t/data/update/pam-krb5/old/build/middle
diff --git a/t/data/generate/pam-krb5/metadata/debian/summary b/t/data/update/pam-krb5/old/debian/summary
index f6dc7f4..f6dc7f4 100644
--- a/t/data/generate/pam-krb5/metadata/debian/summary
+++ b/t/data/update/pam-krb5/old/debian/summary
diff --git a/t/data/generate/pam-krb5/metadata/description b/t/data/update/pam-krb5/old/description
index 2220c95..2220c95 100644
--- a/t/data/generate/pam-krb5/metadata/description
+++ b/t/data/update/pam-krb5/old/description
diff --git a/t/data/generate/pam-krb5/metadata/metadata.json b/t/data/update/pam-krb5/old/metadata.json
index 7d424a3..7d424a3 100644
--- a/t/data/generate/pam-krb5/metadata/metadata.json
+++ b/t/data/update/pam-krb5/old/metadata.json
diff --git a/t/data/generate/pam-krb5/metadata/quote b/t/data/update/pam-krb5/old/quote
index 6b59a00..6b59a00 100644
--- a/t/data/generate/pam-krb5/metadata/quote
+++ b/t/data/update/pam-krb5/old/quote
diff --git a/t/data/generate/pam-krb5/metadata/requirements b/t/data/update/pam-krb5/old/requirements
index b871e0e..b871e0e 100644
--- a/t/data/generate/pam-krb5/metadata/requirements
+++ b/t/data/update/pam-krb5/old/requirements
diff --git a/t/data/generate/pam-krb5/metadata/sections/configuring b/t/data/update/pam-krb5/old/sections/configuring
index 457d4c0..457d4c0 100644
--- a/t/data/generate/pam-krb5/metadata/sections/configuring
+++ b/t/data/update/pam-krb5/old/sections/configuring
diff --git a/t/data/generate/pam-krb5/metadata/sections/debugging b/t/data/update/pam-krb5/old/sections/debugging
index 578fab0..578fab0 100644
--- a/t/data/generate/pam-krb5/metadata/sections/debugging
+++ b/t/data/update/pam-krb5/old/sections/debugging
diff --git a/t/data/generate/pam-krb5/metadata/sections/history-and-acknowledgements b/t/data/update/pam-krb5/old/sections/history-and-acknowledgements
index 0e6143e..0e6143e 100644
--- a/t/data/generate/pam-krb5/metadata/sections/history-and-acknowledgements
+++ b/t/data/update/pam-krb5/old/sections/history-and-acknowledgements
diff --git a/t/data/generate/pam-krb5/metadata/sections/implementation-notes b/t/data/update/pam-krb5/old/sections/implementation-notes
index 69f8338..69f8338 100644
--- a/t/data/generate/pam-krb5/metadata/sections/implementation-notes
+++ b/t/data/update/pam-krb5/old/sections/implementation-notes
diff --git a/t/data/generate/pam-krb5/metadata/test/prefix b/t/data/update/pam-krb5/old/test/prefix
index 3505fbc..3505fbc 100644
--- a/t/data/generate/pam-krb5/metadata/test/prefix
+++ b/t/data/update/pam-krb5/old/test/prefix
diff --git a/t/data/generate/pam-krb5/metadata/test/suffix b/t/data/update/pam-krb5/old/test/suffix
index 4b1b8c8..4b1b8c8 100644
--- a/t/data/generate/pam-krb5/metadata/test/suffix
+++ b/t/data/update/pam-krb5/old/test/suffix
diff --git a/t/data/update/remctl/docknot.yaml b/t/data/update/remctl/docknot.yaml
new file mode 100644
index 0000000..c64e868
--- /dev/null
+++ b/t/data/update/remctl/docknot.yaml
@@ -0,0 +1,380 @@
+---
+advisories:
+- date: 2018-04-01
+ threshold: '3.14'
+ versions: 3.12 and 3.13
+blurb: |
+ remctl is a client/server application that supports remote execution of
+ specific commands, using Kerberos GSS-API for authentication.
+ Authorization is controlled by a configuration file and ACL files and can
+ be set separately for each command, unlike with rsh. remctl is like a
+ Kerberos-authenticated simple CGI server, or a combination of Kerberos ssh
+ and sudo without most of the features and complexity of either.
+build:
+ autoconf: '2.64'
+ automake: '1.11'
+ autotools: true
+ bootstrap: |
+ You will also need pkg-config installed to regenerate configure and
+ xml2rfc to build the formatted protocol documentation.
+ gssapi: true
+ install: true
+ kerberos: true
+ manpages: true
+ middle: |
+ Solaris users should look at `examples/remctld.xml`, an SMF manifest for
+ running the `remctld` daemon.
+
+ To also build the Perl bindings for the libremctl client library, pass the
+ `--enable-perl` option to `configure`. The Perl module build is handled
+ by the normal Perl extension build system, and therefore will be built
+ with compiler flags defined by your Perl installation and installed into
+ your local Perl module directory regardless of the `--prefix` argument to
+ `configure`. To change this, you will need to run `perl Makefile.PL` in
+ the `perl` subdirectory of the build tree with appropriate options and
+ rebuild the module after running `make` and before running `make install`.
+
+ To also build the remctl PECL extension for PHP, pass the `--enable-php`
+ option to `configure`. The PHP PECL module build is handled by the normal
+ PHP extension build system and therefore will be installed into your local
+ PHP module directory. The configure script will look for `phpize` on your
+ `PATH` by default; if it's in some other directory, set the `PHPIZE`
+ environment variable to the full path or set it on the configure command
+ line. The configure script for the PECL extension will be run during the
+ build instead of during configure. This is unfortunately apparently
+ unavoidable given how the PECL build system works.
+
+ To also build the Python bindings for the libremctl client library, pass
+ the `--enable-python` option to configure. The Python module build is
+ handled by the normal Python extension build system, and therefore will be
+ installed into your local Python module directory regardless of the
+ `--prefix` argument to `configure`. To change this, you will need to run
+ `python setup.py install` by hand in the `python` directory with whatever
+ options you want to use.
+
+ To also build the Ruby bindings for the libremctl client library, pass
+ the `--enable-ruby` option to configure. The Ruby module build is handled
+ by the normal Ruby module build system, and therefore will be installed
+ into your local Ruby module directory regardless of the `--prefix`
+ argument to `configure`. To change this, override the `sitedir` variable on
+ the `make install` command line, as in:
+
+ ```
+ make install sitedir=/opt/ruby
+ ```
+
+ The remctl build system also supports a few other environment variables
+ that can be set to control aspects of the Perl, Python, and Ruby binding
+ build systems. These are primarily only of use when packaging the
+ software. For more information, a list of the variables, and their
+ effects, see the comment at the start of `Makefile.am`.
+
+ The Java client and server aren't integrated with the regular build
+ system. For information on building and installing them, see
+ `java/README`.
+
+ remctl will use pkg-config if it's available to find the build flags for
+ libevent. You can control which pkg-config binary and paths are used with
+ the normal pkg-config environment variables of `PKG_CONFIG`,
+ `PKG_CONFIG_PATH`, and `PKG_CONFIG_LIBDIR`, and you can override the
+ pkg-config results with `LIBEVENT_CFLAGS` and `LIBEVENT_LIBS`.
+ Alternately, you can bypass pkg-config by passing one or more of
+ `--with-libevent`, `--with-libevent-include`, and `--with-libevent-lib` to
+ indicate the install prefix, include directory, or library directory.
+
+ remctl will automatically build with PCRE support if pcre-config or the
+ PCRE library are found. You can pass `--with-pcre` to configure to
+ specify the root directory where PCRE is installed, or set the include and
+ library directories separately with `--with-pcre-include` and
+ `--with-pcre-lib`. You can also set `PCRE_CONFIG` to point to a different
+ pcre-config script, or do similar things as with `PATH_KRB5_CONFIG`
+ described below.
+
+ remctl will automatically build with GPUT support if the GPUT header and
+ library are found. You can pass `--with-gput` to configure to specify the
+ root directory where GPUT is installed, or set the include and library
+ directories separately with `--with-gput-include` and `--with-gput-lib`.
+ reduced_depends: true
+ type: Autoconf
+copyrights:
+- holder: Russ Allbery <eagle@eyrie.org>
+ years: 2015-2016, 2018
+- holder: The Board of Trustees of the Leland Stanford Junior University
+ years: 2002-2014
+description: |
+ remctl is a client/server application that supports remote execution of
+ specific commands, using Kerberos GSS-API for authentication and
+ confidentiality. The commands a given user can execute are controlled by
+ a configuration file and ACL files and can easily be tightly limited,
+ unlike with rsh. The mapping of command to backend program is done by the
+ configuration file, which allows some additional flexibility compared to
+ ssh command restrictions and works with Kerberos authentications rather
+ than being limited to public key authentications.
+
+ remctld is very similar to a CGI server that uses a different network
+ protocol than HTTP, always does strong authentication before executing the
+ desired command, and guarantees the data is encrypted on the network.
+ Alternately, you can think of it as a very simple combination of Kerberos
+ ssh and sudo, without most of the features of both but with simpler
+ authorization.
+
+ There are a lot of different client/server systems that do something
+ similar, including regular rsh, CGI, IBM's sysctl (not to be confused with
+ the Linux kernel call and configuration file of the same name), CERN's
+ arc, and more elaborate systems like MIT's Moira. remctl has the
+ advantage over many of these schemes of using GSS-API and being about as
+ simple as it possibly can be while still being useful. It doesn't require
+ any particular programming language, builds self-contained binaries, and
+ uses as minimal of a protocol as possible.
+
+ Both C and Java clients and servers are provided, as well as Perl, PHP,
+ and Python bindings for the C client library. For more information about
+ the Java client, see `java/README`. For more information about the PHP
+ bindings, see `php/README`. For more information about the Python
+ bindings, see `python/README`.
+
+ Also included in the remctl package is an alternate way of running the
+ remctl server: remctl-shell. This program is designed to be run as either
+ a shell or a forced command under ssh, using ssh for authentication and
+ communicating the authentication information to remctl-shell via either
+ environment variables or command-line arguments via the forced command
+ configuration. This version of the server uses simple ssh clients, rather
+ than using the remctl client program or libraries.
+
+ remctl was originally written by Anton Ushakov as a replacement for IBM's
+ sysctl, a client/server application with Kerberos v4 authentication that
+ allowed the client to run Tcl code on the server, protected by ACLs. At
+ Stanford, we used sysctl extensively, but mostly only to run external
+ programs, so remctl was developed as a Kerberos v5 equivalent that did
+ only the portions we needed.
+
+ Complete protocol documentation is available in `docs/protocol.html`.
+ Also present, as `docs/design.html`, is the original design document (now
+ somewhat out of date).
+distribution:
+ packaging:
+ debian:
+ package: remctl
+ summary: |
+ Debian packages are available from Debian as of Debian 3.1 (sarge). For
+ Debian 4.0 (etch) and later, install remctl-server for the server and
+ remctl-client for the client. (The sarge release had a single remctl
+ package that contained both.)
+
+ The Net::Remctl Perl module is available in Debian 5.0 (lenny) and newer;
+ install libnet-remctl-perl for it. The PHP bindings (php5-remctl), Python
+ bindings (python-remctl), and Ruby bindings (ruby-remctl) are available in
+ Debian 6.0 (squeeze) and newer. The Ruby bindings package is named
+ libremctl-ruby in Debian versions before 7.0 (wheezy).
+ extra: |
+ For those using Puppet, there is a
+ [Puppet module](https://forge.puppetlabs.com/ccin2p3/remctl)
+ available for installing the remctl server and managing server
+ configurations. This was written and is maintained by the IN2P3 Computing
+ Centre; see that page for more information.
+ section: kerberos
+ tarname: remctl
+ version: remctl
+docs:
+ api:
+ - name: remctl-api
+ title: remctl and remctl_free_result
+ - name: remctl_new
+ title: remctl_new
+ - name: remctl_open
+ title: remctl_open
+ - name: remctl_command
+ title: remctl_command and remctl_commandv
+ - name: remctl_output
+ title: remctl_output
+ - name: remctl_noop
+ title: remctl_noop
+ - name: remctl_close
+ title: remctl_close
+ - name: remctl_error
+ title: remctl_error
+ - name: remctl_set_ccache
+ title: remctl_set_ccache
+ - name: remctl_set_source_ip
+ title: remctl_set_source_ip
+ - name: remctl_set_timeout
+ title: remctl_set_timeout
+ - name: net-remctl
+ title: Net::Remctl Perl module
+ - name: net-remctl-backend
+ title: Net::Remctl::Backend Perl module
+ developer:
+ - name: extending
+ title: Extending remctl
+ - name: protocol
+ title: Protocol specification
+ - name: protocol-v4
+ title: Protocol v4 draft
+ user:
+ - name: remctl
+ title: remctl manual page
+ - name: remctl-shell
+ title: remctl-shell manual page
+ - name: remctld
+ title: remctld manual page
+ - name: java-readme
+ title: Java client and server README
+ - name: php-readme
+ title: PHP bindings README
+ - name: python-readme
+ title: Python bindings README
+ - name: ruby-readme
+ title: Ruby bindings README
+ - name: thanks
+ title: Thanks and credits
+format: v1
+license:
+ name: Expat
+maintainer: Russ Allbery <eagle@eyrie.org>
+name: remctl
+quote:
+ author: Peter Marshall
+ text: |
+ Small deeds done are better than great deeds planned.
+requirements: |
+ The remctld server and the standard client are written in C and require a
+ C compiler and GSS-API libraries to build. Both will build against either
+ MIT Kerberos or Heimdal of any reasonable vintage. remctl will also build
+ against the Kerberos GSS-API implementation shipped with AIX 5.2 (and
+ possibly later versions) and the Solaris 10 generic GSS-API library (and
+ possibly later versions). The `remctl_set_ccache` implementation is
+ improved by building with Kerberos libraries and a GSS-API library that
+ supports `gss_krb5_import_cred`.
+
+ The remctld server requires libevent 1.4.x or later. It's only been
+ tested with libevent 1.4.13-stable and later, but should work with 1.4.4
+ or later. It is now only tested with libevent 2.x, so moving to a later
+ version of libevent if possible is recommended.
+
+ The remctl server will support regex ACLs if the system supports the POSIX
+ regex API. The remctl server also optionally supports PCRE regular
+ expressions in ACLs. To include that support, the PCRE library is
+ required.
+
+ To build the remctl client for Windows, the Microsoft Windows SDK for
+ Windows Vista and the MIT Kerberos for Windows SDK are required, along
+ with a Microsoft Windows build environment (probably Visual Studio).
+ remctl has only been tested with the 3.2.1 MIT Kerberos for Windows SDK.
+ To run the resulting binary, MIT Kerberos for Windows must be installed
+ and configured. The client was tested on Windows XP and Vista and should
+ work on Windows 2000 and up; however, the primary maintainer does not use
+ or test Windows, so it's always possible Windows support has broken. The
+ server is not supported on Windows.
+
+ To build the Perl bindings for the C client library, you will need Perl
+ 5.8 or later.
+
+ To build the PHP bindings for the C client library, you will need PHP 5.x
+ or later and phpize, plus any other programs that phpize requires. PHP
+ 5.x support has only been tested on 5.2 and 5.3, and PHP support is now
+ only tested on PHP 7.x and later.
+
+ To build the Python bindings for the C client library, you will need
+ Python 2.3 or later (primarily tested with Python 2.7). Python 3 is not
+ (yet) supported.
+
+ To build the Ruby bindings for the C client library, you will need Ruby
+ 1.8 or later (primarily tested with 2.5 and later).
+
+ None of the language bindings have been tested on Windows.
+
+ A Java client and Java server are available in the java subdirectory, but
+ they are not integrated into the normal build or built by default. There
+ is a basic Makefile in that directory that may require some tweaking. It
+ currently requires the Sun Java JDK (1.4.2, 5, or 6) or OpenJDK 6 or
+ later. A considerably better Java client implementation is available on
+ the `java` branch in the Git repository but has not yet been merged.
+sections:
+- body: |
+ (These instructions are not tested by the author and are now dated.
+ Updated instructions via a pull request, issue, or email are very
+ welcome.)
+
+ First, install the Microsoft Windows SDK for Windows Vista if you have not
+ already. This is a free download from Microsoft for users of "Genuine
+ Microsoft Windows." The `vcvars32.bat` environment provided by Visual
+ Studio may work as an alternative, but has not been tested.
+
+ Next, install the [MIT Kerberos for Windows
+ SDK](https://web.mit.edu/kerberos/www/dist/index.html). remctl has been
+ tested with version 3.2.1 but should hopefully work with later versions.
+
+ Then, follow these steps:
+
+ 1. Run the `InitEnv.cmd` script included with the Windows SDK with
+ parameters `"/xp /release"`.
+
+ 2. Run the `configure.bat` script, giving it as an argument the location
+ of the Kerberos for Windows SDK. For example, if you installed the KfW
+ SDK in `"c:\KfW SDK"`, you should run:
+
+ ```
+ configure "c:\KfW SDK"
+ ```
+
+ 3. Run `nmake` to start compiling. You can ignore the warnings.
+
+ If all goes well, you will have `remctl.exe` and `remctl.dll`. The latter
+ is a shared library used by the client program. It exports the same
+ interface as the UNIX libremctl library.
+ title: Building on Windows
+support:
+ email: eagle@eyrie.org
+ github: rra/remctl
+ web: https://www.eyrie.org/~eagle/software/remctl/
+synopsis: remote authenticated command execution with ACLs
+test:
+ lancaster: true
+ prefix: |
+ remctl comes with a comprehensive test suite, but it requires some
+ configuration in order to test anything other than low-level utility
+ functions. For the full test suite, you will need to have a keytab that
+ can authenticate to a running KDC. Using a test KDC environment, if you
+ have one, is recommended.
+
+ Follow the instructions in `tests/config/README` to configure the test
+ suite.
+
+ Now, you can run the test suite with:
+ suffix: |
+ On particularly slow or loaded systems, you may see intermittent failures
+ from the `server/streaming` test because it's timing-sensitive.
+
+ The test suite will also need to be able to bind to 127.0.0.1 on port
+ 11119 and 14373 to run test network server programs.
+
+ To test anonymous authentication, the KDC configured in the test suite
+ needs to support service tickets for the anonymous identity (not a
+ standard configuration). This test will be skipped if the KDC does not
+ support this.
+
+ To test user handling in remctld, you will need the `fakeroot` command
+ (available in the `fakeroot` package in Debian and Ubuntu). This test
+ will be skipped if `fakeroot` isn't available.
+
+ The following additional Perl modules will be used by the test suite for
+ the main package and the Perl bindings if installed:
+
+ * Test::MinimumVersion
+ * Test::Perl::Critic
+ * Test::Pod
+ * Test::Spelling
+ * Test::Strict
+ * Test::Synopsis
+
+ All are available on CPAN. Those tests will be skipped if the modules are
+ not available.
+vcs:
+ browse: https://git.eyrie.org/?p=kerberos/remctl.git
+ github: rra/remctl
+ openhub: https://www.openhub.net/p/remctl
+ status:
+ travis: rra/remctl
+ type: Git
+ url: https://git.eyrie.org/git/kerberos/remctl.git
+version: '3.15'
diff --git a/t/data/generate/remctl/metadata/blurb b/t/data/update/remctl/old/blurb
index c062000..c062000 100644
--- a/t/data/generate/remctl/metadata/blurb
+++ b/t/data/update/remctl/old/blurb
diff --git a/t/data/generate/remctl/metadata/bootstrap b/t/data/update/remctl/old/bootstrap
index 0a018f7..0a018f7 100644
--- a/t/data/generate/remctl/metadata/bootstrap
+++ b/t/data/update/remctl/old/bootstrap
diff --git a/t/data/generate/remctl/metadata/build/middle b/t/data/update/remctl/old/build/middle
index 4a2820f..4a2820f 100644
--- a/t/data/generate/remctl/metadata/build/middle
+++ b/t/data/update/remctl/old/build/middle
diff --git a/t/data/generate/remctl/metadata/debian/summary b/t/data/update/remctl/old/debian/summary
index 8316a52..8316a52 100644
--- a/t/data/generate/remctl/metadata/debian/summary
+++ b/t/data/update/remctl/old/debian/summary
diff --git a/t/data/generate/remctl/metadata/description b/t/data/update/remctl/old/description
index 09aff27..09aff27 100644
--- a/t/data/generate/remctl/metadata/description
+++ b/t/data/update/remctl/old/description
diff --git a/t/data/generate/remctl/metadata/metadata.json b/t/data/update/remctl/old/metadata.json
index ebb63c7..ebb63c7 100644
--- a/t/data/generate/remctl/metadata/metadata.json
+++ b/t/data/update/remctl/old/metadata.json
diff --git a/t/data/generate/remctl/metadata/packaging/extra b/t/data/update/remctl/old/packaging/extra
index 2be114e..2be114e 100644
--- a/t/data/generate/remctl/metadata/packaging/extra
+++ b/t/data/update/remctl/old/packaging/extra
diff --git a/t/data/generate/remctl/metadata/quote b/t/data/update/remctl/old/quote
index f832afb..f832afb 100644
--- a/t/data/generate/remctl/metadata/quote
+++ b/t/data/update/remctl/old/quote
diff --git a/t/data/generate/remctl/metadata/requirements b/t/data/update/remctl/old/requirements
index 83bc59e..83bc59e 100644
--- a/t/data/generate/remctl/metadata/requirements
+++ b/t/data/update/remctl/old/requirements
diff --git a/t/data/generate/remctl/metadata/sections/building-on-windows b/t/data/update/remctl/old/sections/building-on-windows
index 3a08d3d..3a08d3d 100644
--- a/t/data/generate/remctl/metadata/sections/building-on-windows
+++ b/t/data/update/remctl/old/sections/building-on-windows
diff --git a/t/data/generate/remctl/metadata/test/prefix b/t/data/update/remctl/old/test/prefix
index 1afd097..1afd097 100644
--- a/t/data/generate/remctl/metadata/test/prefix
+++ b/t/data/update/remctl/old/test/prefix
diff --git a/t/data/generate/remctl/metadata/test/suffix b/t/data/update/remctl/old/test/suffix
index f7ef8c7..f7ef8c7 100644
--- a/t/data/generate/remctl/metadata/test/suffix
+++ b/t/data/update/remctl/old/test/suffix
diff --git a/t/data/update/rra-c-util/docknot.yaml b/t/data/update/rra-c-util/docknot.yaml
new file mode 100644
index 0000000..5bd8061
--- /dev/null
+++ b/t/data/update/rra-c-util/docknot.yaml
@@ -0,0 +1,318 @@
+---
+blurb: |
+ rra-c-util is my collection of portability functions, utility functions,
+ Autoconf macros, and related shared C infrastructure, akin to gnulib but
+ without any GPL-covered code and additional support for Kerberos and PAM
+ development. It serves as a common repository of code and infrastructure
+ used across multiple projects so that files have a canonical latest
+ version. It's not intended for installation as a regular package;
+ instead, other packages are expected to copy files from here as needed.
+build:
+ autoconf: '2.64'
+ automake: '1.11'
+ autotools: true
+ manpages: true
+copyrights:
+- holder: Russ Allbery <eagle@eyrie.org>
+ years: 2000, 2009-2010, 2013-2016
+- holder: The Board of Trustees of the Leland Stanford Junior University
+ years: 2009-2014
+description: |
+ The origins of this package are in the libinn utility library in INN.
+ Some of the utility and portability functions here are directly inspired
+ by or based on versions in older versions of INN, and I wrote and rewrote
+ considerable additional portability code and utility libraries when I took
+ over INN maintenance. When I started maintaining other C packages, I
+ started copying pieces of libinn into those packages and merging it with
+ other portability and utility code. Over time, each package gained a
+ slightly different version of various utility functions, replacements for
+ missing functions, and Autoconf macros.
+
+ The goal of this package is to merge all the various versions of any
+ portability or utility code that's used in more than one of my packages in
+ one place. Then, each package can update to the latest rra-c-util version
+ before each release and gain from the improvements made for all other
+ packages. You can think of it as my version of
+ [Gnulib](https://www.gnu.org/software/gnulib/), with everything released
+ under a permissive license (no GPL).
+
+ As well as C portability frameworks, Autoconf macros, and a general C
+ utility library, this package has also accumulated a considerable
+ collection of standard tests (for C and Perl packages) and a large library
+ of test utilities and support functions. It also includes extensive
+ support for writing and testing PAM modules, and a portable implementation
+ of AFS PAGs.
+
+ This package uses the infrastructure of C TAP Harness for testing, but is
+ not the canonical version of `tests/runtests.c`, `tests/tap/basic.[ch]`,
+ `tests/tap/macros.h`, or `tests/tap/libtap.sh`. Those files should be
+ pulled from [C TAP
+ Harness](https://www.eyrie.org/~eagle/software/c-tap-harness/) instead.
+distribution:
+ section: devel
+ tarname: rra-c-util
+ version: rra-c-util
+docs:
+ api:
+ - name: xmalloc
+ title: xmalloc, xcalloc, and xrealloc
+ extra:
+ - links:
+ - name: module-version
+ title: tests/perl/module-version-t
+ - name: module-version-perl
+ title: t/style/module-version.t
+ title: Test scripts
+ user:
+ - name: fakepam
+ title: PAM testing
+ - name: test-rra
+ title: Test::RRA
+ - name: test-rra-automake
+ title: Test::RRA::Automake
+ - name: test-rra-config
+ title: Test::RRA::Config
+ - name: test-rra-moduleversion
+ title: Test::RRA::ModuleVersion
+format: v1
+license:
+ name: Expat
+maintainer: Russ Allbery <eagle@eyrie.org>
+name: rra-c-util
+quote:
+ author: Phil Greenspun
+ text: |
+ Greenspun's Tenth Rule of Programming: any sufficiently complicated C or
+ Fortran program contains an ad hoc informally-specified bug-ridden slow
+ implementation of half of Common Lisp.
+requirements: |
+ Everything requires a C compiler to build and expects an ISO C89 or later
+ C compiler and libraries. Presence of strdup is also assumed, which is
+ guaranteed by POSIX 2008 but common in many earlier C libraries as well.
+ Otherwise, the files are meant to be copied into packages and the
+ requirements depend on which files one copies.
+
+ A Kerberos library, either MIT Kerberos or Heimdal, is required to build
+ this package as-is, since the Kerberos portability layer is built and
+ tested by default. The other code will run fine without this requirement
+ when copied into other packages.
+
+ PAM libraries and headers are required to build the package as-is, since
+ the PAM supporting library is built and tested by default. Other code can
+ be copied from this package without introducing a PAM dependency.
+
+ To build the the kafs portability layer, one of Linux, Mac OS X, Solaris
+ 11, the kafs library that comes with either Heimdal or KTH Kerberos, the
+ kopenafs library that comes with newer OpenAFS, AFS header files (on any
+ other platform besides AIX or IRIX), or AFS libraries (on AIX and IRIX) is
+ required. AIX binaries with AFS PAG support may not run on AIX systems
+ that do not have an AFS client installed due to how AIX handles system
+ calls.
+
+ To run the full test suite, and to use the Perl test support libraries,
+ Perl 5.6.2 or later is required. The following additional Perl modules
+ will be used if present:
+
+ * IPC::System::Simple
+ * Test::MinimumVersion
+ * Test::Perl::Critic
+ * Test::Pod
+ * Test::Spelling
+ * Test::Strict
+
+ All are available on CPAN. Those tests will be skipped if the modules are
+ not available.
+sections:
+- body: |
+ You can build rra-c-util with:
+
+ ```
+ ./configure
+ make
+ ```
+
+ Pass `--enable-kafs` to configure to attempt to build kafs support, which
+ will use either an existing libkafs or libkopenafs library or build the
+ kafs replacement included in this package. You can also add
+ `--without-libkafs` to force the use of the internal kafs replacement.
+
+ Pass `--enable-silent-rules` to configure for a quieter build (similar to
+ the Linux kernel). Use `make warnings` instead of make to build with full
+ GCC compiler warnings (requires a relatively current version of GCC).
+
+ Normally, configure will use `krb5-config` to determine the flags to use
+ to compile with your Kerberos libraries. If `krb5-config` isn't found, it
+ will look for the standard Kerberos libraries in locations already
+ searched by your compiler. If the the `krb5-config` script first in your
+ path is not the one corresponding to the Kerberos libraries you want to
+ use or if your Kerberos libraries and includes aren't in a location
+ searched by default by your compiler, you need to specify a different
+ Kerberos installation root via `--with-krb5=PATH`. For example:
+
+ ```
+ ./configure --with-krb5=/usr/pubsw
+ ```
+
+ You can also individually set the paths to the include directory and the
+ library directory with `--with-krb5-include` and `--with-krb5-lib`. You
+ may need to do this if Autoconf can't figure out whether to use `lib`,
+ `lib32`, or `lib64` on your platform.
+
+ To specify a particular `krb5-config` script to use, either set the
+ `PATH_KRB5_CONFIG` environment variable or pass it to configure like:
+
+ ```
+ ./configure PATH_KRB5_CONFIG=/path/to/krb5-config
+ ```
+
+ To not use `krb5-config` and force library probing even if there is a
+ `krb5-config` script on your path, set `PATH_KRB5_CONFIG` to a nonexistent
+ path:
+
+ ```
+ ./configure PATH_KRB5_CONFIG=/nonexistent
+ ```
+
+ `krb5-config` is not used and library probing is always done if either
+ `--with-krb5-include` or `--with-krb5-lib` are given.
+
+ GSS-API libraries are found the same way: with `krb5-config` by default if
+ it is found, and a `--with-gssapi=PATH` flag to specify the installation
+ root. `PATH_KRB5_CONFIG` is similarly used to find krb5-config for the
+ GSS-API libraries, and `--with-gssapi-include` and `--with-gssapi-lib` can
+ be used to specify the exact paths, overriding any `krb5-config` results.
+ title: Building
+- body: |
+ While there is an install target, it's present only because Automake
+ provides it automatically. Its use is not recommended. Instead, the code
+ in this package is intended to be copied into your package and refreshed
+ from the latest release of rra-c-util for each release.
+
+ You can obviously copy the code and integrate it however works best for
+ your package and your build system. Here's how I do it for my packages as
+ an example:
+
+ * Create a portable directory and copy `macros.h`, `system.h`,
+ `stdbool.h`, and `dummy.c` along with whatever additional functions that
+ your package uses that may not be present on all systems. If you use
+ much of the `util` directory (see below), you'll need `asprintf.c`,
+ `reallocarray.c`, and `snprintf.c` at least. If you use
+ `util/network.c`, you'll also need `getaddrinfo.c`, `getaddrinfo.h`,
+ `getnameinfo.c`, `getnameinfo.h`, `inet_*.c`, and `socket.h`. You'll
+ need `winsock.c` for networking portability to Windows.
+
+ * Copy the necessary portions of `configure.ac` from this package into
+ your package. `configure.ac` is commented to try to give you a guide
+ for what you need to copy over. You will also need to make an `m4`
+ subdirectory, add the code to `configure.ac` to load Autoconf macros
+ from `m4`, and copy over `m4/snprintf.m4` and possibly `m4/socket.m4`
+ and `m4/inet-ntoa.m4`.
+
+ * Copy the code from `Makefile.am` for building `libportable.a` into your
+ package and be sure to link your package binaries with `libportable.a`.
+ If you include this code in a shared library, you'll need to build
+ `libportable.la` instead; see the Automake manual for the differences.
+ You'll need to change `LIBRARIES` to `LTLIBRARIES` and `LIBOBJS` to
+ `LTLIBOBJS` in addition to renaming the targets.
+
+ * Create a `util` directory and copy over the portions of the utility
+ library that you want. You will probably need `messages.[ch]` and
+ `xmalloc.[ch]` if you copy anything over at all, since most of the rest
+ of the library uses those. You will also need `m4/vamacros.m4` if you
+ use `messages.[ch]`.
+
+ * Copy the code from `Makefile.am` for building `libutil.a` into your
+ package and be sure to link your package binaries with `libutil.a`. As
+ with `libportable.a`, if you want to use the utility functions in a
+ shared library, you'll need to instead build `libutil.la` and change
+ some of the Automake variables.
+
+ * If your package uses a TAP-based test suite written in C, consider using
+ the additional TAP utility functions in `tests/tap` (specifically
+ `messages.*`, `process.*`, and `string.*`).
+
+ * If you're using the Kerberos portability code, copy over
+ `portable/krb5.h`, `portable/krb5-extra.c`, `m4/krb5.m4`,
+ `m4/lib-depends.m4`, `m4/lib-pathname.m4`, and optionally
+ `util/messages-krb5.[ch]`. You'll also need the relevant fragments of
+ `configure.ac`. You may want to remove some things from `krb5.h` and
+ `krb5-extra.c` the corresponding configure checks if your code doesn't
+ need all of those functions. If you need `krb5_get_renewed_creds`, also
+ copy over `krb5-renew.c`. Don't forget to add `$(KRB5_CPPFLAGS)` to
+ `CPPFLAGS` for `libportable` and possibly `libutil`, and if you're
+ building a shared library, also add `$(KRB5_LDFLAGS)` to `LDFLAGS` and
+ `$(KRB5_LIBS)` to `LIBADD` for those libraries.
+
+ For a Kerberos-enabled test suite, also consider copying the
+ `kerberos.*` libraries in `tests/tap` for a Kerberos-enabled test suite.
+ If you want to use `kerberos_generate_conf` from `tests/tap/kerberos.c`,
+ also copy over `tests/data/generate-krb5-conf`.
+
+ * For testing that requires making Kerberos administrative changes,
+ consider copying over the `kadmin.*` libraries in `tests/tap`.
+
+ * For testing packages that use remctl, see the `tests/tap/remctl.c` and
+ `tests/tap/remctl.h` files for C tests and `tests/tap/remctl.sh` for
+ shell scripts.
+
+ * If you're using the kafs portability code, copy over the `kafs`
+ directory, `m4/kafs.m4`, `m4/lib-pathname.m4`, `portable/k_haspag.c`,
+ the code to build kafs from `Makefile.am`, and the relevant fragments of
+ `configure.ac`.
+
+ * If you're using the PAM portability code, copy over `pam-util/*`,
+ `portable/pam*`, `m4/pam-const.m4`, and the relevant fragments of
+ `configure.ac`.
+
+ * Copy over any other Autoconf macros that you want to use in your
+ package from the m4 directory.
+
+ * Copy over any generic tests from `tests/docs` and `tests/perl` that are
+ appropriate for your package. If you use any of these, also copy over
+ the `tests/tap/perl` directory and `tests/data/perl.conf` (and customize
+ the latter for your package).
+
+ * If the package embeds a Perl module, copy over any tests from the
+ `perl/t` directory that are applicable. This can provide generic
+ testing of the embedded Perl module using Perl's own test
+ infrastructure. If you use any of these, also copy over the
+ `perl/t/data/perl.conf` file and customize it for your package. You
+ will need to arrange for `perl/t/data` to contain copies of the
+ `perlcriticrc` and `perltidyrc` files, either by making copies of the
+ files from `tests/data` or by using make to copy them.
+
+ I also copy over all the relevant tests from the `tests` directory and the
+ build machinery for them from `Makefile.am` so that the portability and
+ utility layer are tested along with the rest of the package. The test
+ driver should come from C TAP Harness.
+ title: Using This Code
+support:
+ email: eagle@eyrie.org
+ github: rra/rra-c-util
+ web: https://www.eyrie.org/~eagle/software/rra-c-util/
+synopsis: Russ Allbery's utility libraries for C
+test:
+ lancaster: true
+ override: |
+ rra-c-util comes with an extensive test suite, which you can run after
+ building with:
+
+ ```
+ make check
+ ```
+
+ If a test fails, you can run a single test with verbose output via:
+
+ ```
+ tests/runtests -o <name-of-test>
+ ```
+
+ Do this instead of running the test program directly since it will ensure
+ that necessary environment variables are set up.
+vcs:
+ browse: https://git.eyrie.org/?p=devel/rra-c-util.git
+ github: rra/rra-c-util
+ openhub: https://www.openhub.net/p/rra-c-util
+ type: Git
+ url: https://git.eyrie.org/git/devel/rra-c-util.git
+version: '6.1'
diff --git a/t/data/generate/rra-c-util/metadata/blurb b/t/data/update/rra-c-util/old/blurb
index 0e5f5ad..0e5f5ad 100644
--- a/t/data/generate/rra-c-util/metadata/blurb
+++ b/t/data/update/rra-c-util/old/blurb
diff --git a/t/data/generate/rra-c-util/metadata/description b/t/data/update/rra-c-util/old/description
index b6149b9..b6149b9 100644
--- a/t/data/generate/rra-c-util/metadata/description
+++ b/t/data/update/rra-c-util/old/description
diff --git a/t/data/generate/rra-c-util/metadata/metadata.json b/t/data/update/rra-c-util/old/metadata.json
index 7c56cf4..7c56cf4 100644
--- a/t/data/generate/rra-c-util/metadata/metadata.json
+++ b/t/data/update/rra-c-util/old/metadata.json
diff --git a/t/data/generate/rra-c-util/metadata/quote b/t/data/update/rra-c-util/old/quote
index 56f2e6d..56f2e6d 100644
--- a/t/data/generate/rra-c-util/metadata/quote
+++ b/t/data/update/rra-c-util/old/quote
diff --git a/t/data/generate/rra-c-util/metadata/requirements b/t/data/update/rra-c-util/old/requirements
index b9292f6..b9292f6 100644
--- a/t/data/generate/rra-c-util/metadata/requirements
+++ b/t/data/update/rra-c-util/old/requirements
diff --git a/t/data/generate/rra-c-util/metadata/sections/building b/t/data/update/rra-c-util/old/sections/building
index b604917..b604917 100644
--- a/t/data/generate/rra-c-util/metadata/sections/building
+++ b/t/data/update/rra-c-util/old/sections/building
diff --git a/t/data/generate/rra-c-util/metadata/sections/testing b/t/data/update/rra-c-util/old/sections/testing
index 47cca20..47cca20 100644
--- a/t/data/generate/rra-c-util/metadata/sections/testing
+++ b/t/data/update/rra-c-util/old/sections/testing
diff --git a/t/data/generate/rra-c-util/metadata/sections/using-this-code b/t/data/update/rra-c-util/old/sections/using-this-code
index 0c9149a..0c9149a 100644
--- a/t/data/generate/rra-c-util/metadata/sections/using-this-code
+++ b/t/data/update/rra-c-util/old/sections/using-this-code
diff --git a/t/dist/basic.t b/t/dist/basic.t
index 5fc777b..bfcee9f 100755
--- a/t/dist/basic.t
+++ b/t/dist/basic.t
@@ -82,9 +82,9 @@ my $dist = App::DocKnot::Dist->new({ distdir => $distdir, perl => $^X });
capture_stdout {
eval { $dist->make_distribution() };
};
-ok(-e File::Spec->catfile($distdir, 'Empty-1.00.tar.gz'), 'dist exists');
-ok(-e File::Spec->catfile($distdir, 'Empty-1.00.tar.xz'), 'xz dist exists');
-ok(!-e File::Spec->catfile($distdir, 'Empty-1.00.tar'), 'tarball missing');
+ok(-e File::Spec->catfile($distdir, 'Empty-1.00.tar.gz'), 'dist exists');
+ok(-e File::Spec->catfile($distdir, 'Empty-1.00.tar.xz'), 'xz dist exists');
+ok(!-e File::Spec->catfile($distdir, 'Empty-1.00.tar'), 'tarball missing');
is($@, q{}, 'no errors');
# If we add an ignored file to the source tree, this should not trigger any
diff --git a/t/dist/commands.t b/t/dist/commands.t
index 8e841f0..baee19d 100755
--- a/t/dist/commands.t
+++ b/t/dist/commands.t
@@ -2,7 +2,7 @@
#
# Tests for App::DocKnot::Dist command selection to generate a distribution.
#
-# Copyright 2019 Russ Allbery <rra@cpan.org>
+# Copyright 2019-2020 Russ Allbery <rra@cpan.org>
#
# SPDX-License-Identifier: MIT
@@ -46,7 +46,8 @@ $docknot = App::DocKnot::Dist->new({ distdir => q{.}, perl => '/a/perl' });
is_deeply(\@seen, \@expected, 'Module::Build');
# ExtUtils::MakeMaker distribution.
-my $metadata_path = File::Spec->catfile($dataroot, 'ansicolor', 'metadata');
+my $metadata_path
+ = File::Spec->catfile($dataroot, 'ansicolor', 'docknot.yaml');
$docknot
= App::DocKnot::Dist->new({ distdir => q{.}, metadata => $metadata_path });
#<<<
@@ -60,7 +61,7 @@ $docknot
is_deeply(\@seen, \@expected, 'ExtUtils::MakeMaker');
# Autoconf distribution.
-$metadata_path = File::Spec->catfile($dataroot, 'lbcd', 'metadata');
+$metadata_path = File::Spec->catfile($dataroot, 'lbcd', 'docknot.yaml');
$docknot
= App::DocKnot::Dist->new({ distdir => q{.}, metadata => $metadata_path });
#<<<
@@ -82,7 +83,8 @@ $docknot
is_deeply(\@seen, \@expected, 'Autoconf');
# Autoconf distribution with C++ and valgrind.
-$metadata_path = File::Spec->catfile($dataroot, 'c-tap-harness', 'metadata');
+$metadata_path
+ = File::Spec->catfile($dataroot, 'c-tap-harness', 'docknot.yaml');
$docknot
= App::DocKnot::Dist->new({ distdir => q{.}, metadata => $metadata_path });
#<<<
@@ -108,7 +110,8 @@ $docknot
is_deeply(\@seen, \@expected, 'Autoconf with C++');
# Makefile only distribution (make).
-$metadata_path = File::Spec->catfile($dataroot, 'control-archive', 'metadata');
+$metadata_path
+ = File::Spec->catfile($dataroot, 'control-archive', 'docknot.yaml');
$docknot
= App::DocKnot::Dist->new({ distdir => q{.}, metadata => $metadata_path });
@expected = (['make', 'dist']);
diff --git a/t/docs/spdx-license.t b/t/docs/spdx-license.t
index 832acc6..e89e19b 100755
--- a/t/docs/spdx-license.t
+++ b/t/docs/spdx-license.t
@@ -66,8 +66,8 @@ my @IGNORE_PATHS = (
qr{ \A [.] /docs/metadata/ }xms, # Package license should be fine
qr{ \A [.] /README ( [.] .* )? \z }xms, # Package license should be fine
qr{ \A [.] /share/ }xms, # Package license should be fine
- qr{ \A [.] /t/data .* /metadata/ }xms, # Test metadata
- qr{ \A [.] /t/data .* /output/ }xms, # Test output
+ qr{ \A [.] /t/data/generate/ }xms, # Test metadata
+ qr{ \A [.] /t/data/update/ }xms, # Test output
qr{ \A [.] /t/data .* [.] json \z }xms, # Test metadata
);
## use critic
diff --git a/t/generate/basic.t b/t/generate/basic.t
index 608238c..9d496f7 100755
--- a/t/generate/basic.t
+++ b/t/generate/basic.t
@@ -2,7 +2,7 @@
#
# Tests for the App::DocKnot::Generate module API.
#
-# Copyright 2013, 2016-2019 Russ Allbery <rra@cpan.org>
+# Copyright 2013, 2016-2020 Russ Allbery <rra@cpan.org>
#
# SPDX-License-Identifier: MIT
@@ -12,12 +12,13 @@ use warnings;
use lib 't/lib';
+use Encode qw(encode);
use File::Spec;
use Test::RRA qw(is_file_contents);
use Test::More;
-# Load the modules.
+# Load the module.
BEGIN { use_ok('App::DocKnot::Generate') }
# We have a set of test cases in the data directory. Each of them contains
@@ -26,19 +27,19 @@ my $dataroot = File::Spec->catfile('t', 'data', 'generate');
opendir(my $tests, $dataroot);
my @tests = File::Spec->no_upwards(readdir($tests));
closedir($tests);
-@tests = grep { -d File::Spec->catfile($dataroot, $_, 'metadata') } @tests;
+@tests = grep { -e File::Spec->catfile($dataroot, $_, 'docknot.yaml') } @tests;
# For each of those cases, initialize an object from the metadata directory,
# generate file from known templates, and compare that with the corresponding
# output file.
for my $test (@tests) {
- my $metadata_path = File::Spec->catfile($dataroot, $test, 'metadata');
+ my $metadata_path = File::Spec->catfile($dataroot, $test, 'docknot.yaml');
my $docknot = App::DocKnot::Generate->new({ metadata => $metadata_path });
isa_ok($docknot, 'App::DocKnot::Generate', "for $test");
# Loop through the possible templates.
for my $template (qw(readme readme-md thread)) {
- my $got = $docknot->generate($template);
+ my $got = encode('utf-8', $docknot->generate($template));
my $path = File::Spec->catfile($dataroot, $test, 'output', $template);
is_file_contents($got, $path, "$template for $test");
}
diff --git a/t/generate/output.t b/t/generate/output.t
index 340d976..b9250da 100755
--- a/t/generate/output.t
+++ b/t/generate/output.t
@@ -3,7 +3,7 @@
# Test the generate_output method. This doubles as a test for whether the
# package metadata is consistent with the files currently in the distribution.
#
-# Copyright 2016, 2018-2019 Russ Allbery <rra@cpan.org>
+# Copyright 2016, 2018-2020 Russ Allbery <rra@cpan.org>
#
# SPDX-License-Identifier: MIT
@@ -25,7 +25,7 @@ use Test::More tests => 7;
BEGIN { use_ok('App::DocKnot::Generate') }
# Initialize the App::DocKnot object using the default metadata path.
-my $metadata_path = File::Spec->catfile(getcwd(), 'docs', 'metadata');
+my $metadata_path = File::Spec->catfile(getcwd(), 'docs', 'docknot.yaml');
my $docknot = App::DocKnot::Generate->new({ metadata => $metadata_path });
isa_ok($docknot, 'App::DocKnot::Generate');
diff --git a/t/lib/Test/RRA.pm b/t/lib/Test/RRA.pm
index 334e8c6..b4ed42b 100644
--- a/t/lib/Test/RRA.pm
+++ b/t/lib/Test/RRA.pm
@@ -52,7 +52,7 @@ BEGIN {
# This version should match the corresponding rra-c-util release, but with
# two digits for the minor version, including a leading zero if necessary,
# so that it will sort properly.
- $VERSION = '8.03';
+ $VERSION = '9.00';
}
# Compare a string to the contents of a file, similar to the standard is()
diff --git a/t/lib/Test/RRA/Config.pm b/t/lib/Test/RRA/Config.pm
index bbdba6a..557c682 100644
--- a/t/lib/Test/RRA/Config.pm
+++ b/t/lib/Test/RRA/Config.pm
@@ -32,7 +32,7 @@ BEGIN {
# This version should match the corresponding rra-c-util release, but with
# two digits for the minor version, including a leading zero if necessary,
# so that it will sort properly.
- $VERSION = '8.03';
+ $VERSION = '9.00';
}
# If C_TAP_BUILD or C_TAP_SOURCE are set in the environment, look for
diff --git a/t/lib/Test/RRA/ModuleVersion.pm b/t/lib/Test/RRA/ModuleVersion.pm
index bfed7fc..afa4760 100644
--- a/t/lib/Test/RRA/ModuleVersion.pm
+++ b/t/lib/Test/RRA/ModuleVersion.pm
@@ -29,7 +29,7 @@ BEGIN {
# This version should match the corresponding rra-c-util release, but with
# two digits for the minor version, including a leading zero if necessary,
# so that it will sort properly.
- $VERSION = '8.03';
+ $VERSION = '9.00';
}
# A regular expression matching the version string for a module using the
diff --git a/t/metadata/licenses.t b/t/metadata/licenses.t
index fe078e7..4006ffd 100755
--- a/t/metadata/licenses.t
+++ b/t/metadata/licenses.t
@@ -11,31 +11,17 @@ use autodie;
use warnings;
use File::ShareDir qw(module_file);
-use File::Spec;
-use JSON::MaybeXS qw(JSON);
-use Perl6::Slurp;
-use Test::More;
+use Kwalify qw(validate);
+use Test::More tests => 2;
+use YAML::XS ();
# Load the module.
BEGIN { use_ok('App::DocKnot') }
-# Load the licenses.json file.
-my $path = module_file('App::DocKnot', 'licenses.json');
-my $json = JSON->new;
-$json->relaxed;
-my $licenses_ref = $json->decode(scalar(slurp($path)));
-
-# The number of tests will be one plus two times the number of licenses.
-my $num_tests = 1 + 2 * keys($licenses_ref->%*);
-
-# Ensure that, for every license listed in this file, there is a summary and a
-# corresponding file containing license text.
-for my $key (sort keys($licenses_ref->%*)) {
- ok(defined($licenses_ref->{$key}{summary}), "summary for $key");
- my $license = File::Spec->catfile('licenses', $key);
- eval { $path = module_file('App::DocKnot', $license) };
- ok(!$@, "license file for $key");
-}
-
-# Check the number of tests was correct.
-done_testing($num_tests);
+# Check the schema of the licenses.yaml file.
+my $licenses_path = module_file('App::DocKnot', 'licenses.yaml');
+my $licenses_ref = YAML::XS::LoadFile($licenses_path);
+my $schema_path = module_file('App::DocKnot', 'schema/licenses.yaml');
+my $schema_ref = YAML::XS::LoadFile($schema_path);
+eval { validate($schema_ref, $licenses_ref) };
+is($@, q{}, 'licenses.yaml fails schema validation');
diff --git a/t/style/coverage.t b/t/style/coverage.t
index 688753c..5fd6feb 100755
--- a/t/style/coverage.t
+++ b/t/style/coverage.t
@@ -6,7 +6,7 @@
# which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
#
# Written by Russ Allbery <eagle@eyrie.org>
-# Copyright 2019 Russ Allbery <eagle@eyrie.org>
+# Copyright 2019-2020 Russ Allbery <eagle@eyrie.org>
# Copyright 2013-2014
# The Board of Trustees of the Leland Stanford Junior University
#
@@ -53,9 +53,9 @@ use_prereq('Test::Strict');
# Build a list of test directories to use for coverage.
my %ignore = map { $_ => 1 } qw(data docs style), @COVERAGE_SKIP_TESTS;
-opendir(my $testdir, 't') or BAIL_OUT("cannot open t: $!");
+opendir(my $testdir, 't') or BAIL_OUT("cannot open t: $!");
my @t_dirs = readdir($testdir) or BAIL_OUT("cannot read t: $!");
-closedir($testdir) or BAIL_OUT("cannot close t: $!");
+closedir($testdir) or BAIL_OUT("cannot close t: $!");
# Filter out ignored and system directories.
@t_dirs = grep { !$ignore{$_} } File::Spec->no_upwards(@t_dirs);
diff --git a/t/style/obsolete-strings.t b/t/style/obsolete-strings.t
index 026e6eb..c379946 100755
--- a/t/style/obsolete-strings.t
+++ b/t/style/obsolete-strings.t
@@ -48,7 +48,7 @@ my @BAD_STRINGS = qw(rra@stanford.edu RRA_MAINTAINER_TESTS);
# File or directory names to always skip.
my %SKIP = map { $_ => 1 } qw(
- .git Changes _build blib changelog cover_db obsolete-strings.t
+ .git .pc Changes _build blib changelog cover_db obsolete-strings.t
);
# Only run this test during automated testing, since failure doesn't indicate
diff --git a/t/update/basic.t b/t/update/basic.t
new file mode 100755
index 0000000..c93674f
--- /dev/null
+++ b/t/update/basic.t
@@ -0,0 +1,52 @@
+#!/usr/bin/perl
+#
+# Tests for the App::DocKnot::Update module API.
+#
+# Copyright 2020 Russ Allbery <rra@cpan.org>
+#
+# SPDX-License-Identifier: MIT
+
+use 5.024;
+use autodie;
+use warnings;
+
+use lib 't/lib';
+
+use File::Temp;
+use File::Spec;
+use Perl6::Slurp qw(slurp);
+use Test::RRA qw(is_file_contents);
+
+use Test::More;
+
+# Load the module.
+BEGIN { use_ok('App::DocKnot::Update') }
+
+# We have a set of test cases in the data directory. Each of them contains
+# an old directory for the old files and a docknot.yaml file for the results.
+my $dataroot = File::Spec->catfile('t', 'data', 'update');
+opendir(my $tests, $dataroot);
+my @tests = File::Spec->no_upwards(readdir($tests));
+closedir($tests);
+
+# For each of those cases, initialize an object, generate the updated
+# configuration, and compare it with the test output file.
+my $tempdir = File::Temp->newdir();
+for my $test (@tests) {
+ my $metadata_path = File::Spec->catfile($dataroot, $test, 'old');
+ my $expected_path = File::Spec->catfile($dataroot, $test, 'docknot.yaml');
+ my $output_path = File::Spec->catfile($tempdir, "$test.yaml");
+ my $docknot = App::DocKnot::Update->new(
+ {
+ metadata => $metadata_path,
+ output => $output_path,
+ },
+ );
+ isa_ok($docknot, 'App::DocKnot::Update', "for $test");
+ $docknot->update();
+ my $got = slurp($output_path);
+ is_file_contents($got, $expected_path, "output for $test");
+}
+
+# Check that we ran the correct number of tests.
+done_testing(1 + scalar(@tests) * 2);