summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Build.PL2
-rw-r--r--Changes18
-rw-r--r--MANIFEST189
-rw-r--r--README14
-rw-r--r--README.md12
-rwxr-xr-xbin/docknot25
-rw-r--r--cpanfile2
-rw-r--r--docs/docknot.yaml138
-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/Command.pm9
-rw-r--r--lib/App/DocKnot/Config.pm179
-rw-r--r--lib/App/DocKnot/Generate.pm83
-rw-r--r--lib/App/DocKnot/Update.pm342
-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.yaml251
-rw-r--r--share/schema/licenses.yaml17
-rw-r--r--share/templates/readme-md.tmpl2
-rw-r--r--share/templates/readme.tmpl2
-rw-r--r--share/templates/thread.tmpl2
-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.yaml112
-rw-r--r--t/data/generate/c-tap-harness/docknot.yaml269
-rw-r--r--t/data/generate/control-archive/docknot.yaml346
-rw-r--r--t/data/generate/control-archive/output/readme22
-rw-r--r--t/data/generate/control-archive/output/readme-md8
-rw-r--r--t/data/generate/control-archive/output/thread6
-rw-r--r--t/data/generate/lbcd/docknot.yaml121
-rw-r--r--t/data/generate/pam-krb5/docknot.yaml546
-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/pgp-sign/docknot.yaml114
-rw-r--r--t/data/generate/pgp-sign/metadata/blurb3
-rw-r--r--t/data/generate/pgp-sign/metadata/debian/summary1
-rw-r--r--t/data/generate/pgp-sign/metadata/description24
-rw-r--r--t/data/generate/pgp-sign/metadata/metadata.json61
-rw-r--r--t/data/generate/pgp-sign/metadata/quote3
-rw-r--r--t/data/generate/pgp-sign/metadata/requirements9
-rw-r--r--t/data/generate/pgp-sign/metadata/test/suffix14
-rw-r--r--t/data/generate/remctl/docknot.yaml392
-rw-r--r--t/data/generate/remctl/output/readme4
-rw-r--r--t/data/generate/rra-c-util/docknot.yaml341
-rw-r--r--t/data/generate/wallet/docknot.yaml352
-rw-r--r--t/data/generate/wallet/metadata/blurb9
-rw-r--r--t/data/generate/wallet/metadata/build/middle33
-rw-r--r--t/data/generate/wallet/metadata/description31
-rw-r--r--t/data/generate/wallet/metadata/metadata.json261
-rw-r--r--t/data/generate/wallet/metadata/quote5
-rw-r--r--t/data/generate/wallet/metadata/requirements59
-rw-r--r--t/data/generate/wallet/metadata/sections/configuration16
-rw-r--r--t/data/generate/wallet/metadata/test/prefix8
-rw-r--r--t/data/generate/wallet/metadata/test/suffix23
-rw-r--r--t/data/perlcriticrc3
-rwxr-xr-xt/data/regenerate-data4
-rw-r--r--t/data/update/ansicolor/docknot.yaml105
-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.yaml256
-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.yaml322
-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.yaml509
-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.yaml381
-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.yaml319
-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
-rwxr-xr-xt/metadata/licenses.t34
-rwxr-xr-xt/style/coverage.t6
-rwxr-xr-xt/update/basic.t52
152 files changed, 5830 insertions, 1167 deletions
diff --git a/Build.PL b/Build.PL
index 6ca1e39..f0a8edd 100644
--- a/Build.PL
+++ b/Build.PL
@@ -69,9 +69,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..03d3e00 100644
--- a/Changes
+++ b/Changes
@@ -1,5 +1,23 @@
User-Visible DocKnot Changes
+DocKnot 4.00 (unreleased)
+
+ 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.
+
+ 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.)
+
DocKnot 3.05 (2020-08-09)
Change the heuristic for when to refrain from wrapping output
diff --git a/MANIFEST b/MANIFEST
index 2318824..13a75a4 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -5,26 +5,21 @@ 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
@@ -32,123 +27,45 @@ 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/pgp-sign/metadata/blurb
-t/data/generate/pgp-sign/metadata/debian/summary
-t/data/generate/pgp-sign/metadata/description
-t/data/generate/pgp-sign/metadata/metadata.json
-t/data/generate/pgp-sign/metadata/quote
-t/data/generate/pgp-sign/metadata/requirements
-t/data/generate/pgp-sign/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/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/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/metadata/blurb
-t/data/generate/wallet/metadata/build/middle
-t/data/generate/wallet/metadata/description
-t/data/generate/wallet/metadata/metadata.json
-t/data/generate/wallet/metadata/quote
-t/data/generate/wallet/metadata/requirements
-t/data/generate/wallet/metadata/sections/configuration
-t/data/generate/wallet/metadata/test/prefix
-t/data/generate/wallet/metadata/test/suffix
+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
@@ -156,6 +73,81 @@ 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
@@ -176,4 +168,5 @@ t/style/minimum-version.t
t/style/module-version.t
t/style/obsolete-strings.t
t/style/strict.t
+t/update/basic.t
TODO
diff --git a/README b/README
index 82a77f9..1ee079b 100644
--- a/README
+++ b/README
@@ -1,5 +1,5 @@
DocKnot 3.05
- (package documentation generator)
+ (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
@@ -59,9 +59,11 @@ REQUIREMENTS
* IPC::Run
* IPC::System::Simple
* JSON::MaybeXS
+ * Kwalify
* List::SomeUtils
* Perl6::Slurp
* Template (part of Template Toolkit)
+ * YAML::XS
BUILDING AND INSTALLATION
diff --git a/README.md b/README.md
index 49fabb8..4b63c49 100644
--- a/README.md
+++ b/README.md
@@ -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
@@ -63,9 +63,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
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..66c0f65
--- /dev/null
+++ b/docs/docknot.yaml
@@ -0,0 +1,138 @@
+# 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: '3.05'
+synopsis: Package documentation generator
+
+license:
+ name: Expat
+copyrights:
+ - holder: Russ Allbery <rra@cpan.org>
+ years: 2013-2020
+
+build:
+ lancaster: true
+ type: Module::Build
+distribution:
+ cpan: App-DocKnot
+ section: devel
+ tarname: App-DocKnot
+ version: docknot
+debian:
+ personal: true
+support:
+ cpan: App-DocKnot
+ email: rra@cpan.org
+ 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
+ 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 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.
+
+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:
+ 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/Command.pm b/lib/App/DocKnot/Command.pm
index beec39e..9869a13 100644
--- a/lib/App/DocKnot/Command.pm
+++ b/lib/App/DocKnot/Command.pm
@@ -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,
+ },
);
##############################################################################
@@ -285,7 +292,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..7db1dba 100644
--- a/lib/App/DocKnot/Config.pm
+++ b/lib/App/DocKnot/Config.pm
@@ -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
@@ -93,7 +30,7 @@ sub _load_metadata_json {
#
# $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 +38,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.
@@ -120,83 +54,50 @@ sub new {
# $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 +111,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 +120,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 +154,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 +171,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/Generate.pm b/lib/App/DocKnot/Generate.pm
index 53e6fed..4fc6550 100644
--- a/lib/App/DocKnot/Generate.pm
+++ b/lib/App/DocKnot/Generate.pm
@@ -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);
@@ -310,56 +311,78 @@ 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
+# $self - The App::DocKnot::Generate object
+# $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,14 +391,14 @@ 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
@@ -518,7 +541,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..21d2dc0
--- /dev/null
+++ b/lib/App/DocKnot/Update.pm
@@ -0,0 +1,342 @@
+# 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 3.05;
+
+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.
+#
+# $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('<: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.
+#
+# $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);
+}
+
+# Load the legacy JSON DocKnot package configuration.
+#
+# $self - The App::DocKnot::Config object
+#
+# 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 ($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 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.
+#
+# $class - Class of object to create
+# $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.
+#
+# $self - The App::DocKnot::Update object
+#
+# 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';
+
+ # 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..51339f5
--- /dev/null
+++ b/share/schema/docknot.yaml
@@ -0,0 +1,251 @@
+# 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
+ bootstrap:
+ type: text
+ build:
+ type: map
+ mapping:
+ autoconf:
+ type: text
+ automake:
+ type: text
+ autotools:
+ type: bool
+ cplusplus:
+ type: bool
+ gssapi:
+ type: bool
+ install:
+ type: bool
+ kerberos:
+ type: bool
+ lancaster:
+ 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
+ debian:
+ type: map
+ mapping:
+ personal:
+ type: bool
+ summary:
+ type: text
+ description:
+ type: text
+ required: true
+ distribution:
+ type: map
+ mapping:
+ cpan:
+ type: text
+ ignore:
+ type: seq
+ sequence:
+ - 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
+ packaging:
+ type: map
+ mapping:
+ debian:
+ type: text
+ extra:
+ 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
+ readme:
+ type: map
+ mapping:
+ sections:
+ type: seq
+ sequence:
+ - type: map
+ mapping:
+ body:
+ type: text
+ required: true
+ title:
+ type: text
+ required: true
+ requirements:
+ type: text
+ required: true
+ support:
+ type: map
+ mapping:
+ cpan:
+ type: text
+ 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:
+ 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..257d12d 100644
--- a/share/templates/readme-md.tmpl
+++ b/share/templates/readme-md.tmpl
@@ -267,7 +267,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..0a099f2 100644
--- a/share/templates/readme.tmpl
+++ b/share/templates/readme.tmpl
@@ -252,7 +252,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..23202ab 100644
--- a/share/templates/thread.tmpl
+++ b/share/templates/thread.tmpl
@@ -225,7 +225,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..68d6972
--- /dev/null
+++ b/t/data/generate/ansicolor/docknot.yaml
@@ -0,0 +1,112 @@
+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:
+ lancaster: true
+ type: ExtUtils::MakeMaker
+distribution:
+ section: devel
+ tarname: Term-ANSIColor
+ version: term-ansicolor
+support:
+ cpan: Term-ANSIColor
+ email: rra@cpan.org
+ web: https://www.eyrie.org/~eagle/software/ansicolor/
+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/c-tap-harness/docknot.yaml b/t/data/generate/c-tap-harness/docknot.yaml
new file mode 100644
index 0000000..d16c14e
--- /dev/null
+++ b/t/data/generate/c-tap-harness/docknot.yaml
@@ -0,0 +1,269 @@
+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.
+
+readme:
+ sections:
+ - title: Testing
+ body: |
+ 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.
+ - 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.
+
+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.
diff --git a/t/data/generate/control-archive/docknot.yaml b/t/data/generate/control-archive/docknot.yaml
new file mode 100644
index 0000000..586f4ea
--- /dev/null
+++ b/t/data/generate/control-archive/docknot.yaml
@@ -0,0 +1,346 @@
+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).
+
+readme:
+ 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..29f216d 100644
--- a/t/data/generate/control-archive/output/readme-md
+++ b/t/data/generate/control-archive/output/readme-md
@@ -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/lbcd/docknot.yaml b/t/data/generate/lbcd/docknot.yaml
new file mode 100644
index 0000000..2a25cc9
--- /dev/null
+++ b/t/data/generate/lbcd/docknot.yaml
@@ -0,0 +1,121 @@
+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
+ lancaster: 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:
+ section: system
+ tarname: lbcd
+ version: lbcd
+debian:
+ 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.
+packaging:
+ debian: 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:
+ 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/pam-krb5/docknot.yaml b/t/data/generate/pam-krb5/docknot.yaml
new file mode 100644
index 0000000..42f9637
--- /dev/null
+++ b/t/data/generate/pam-krb5/docknot.yaml
@@ -0,0 +1,546 @@
+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
+debian:
+ 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.
+distribution:
+ section: kerberos
+ tarname: pam-krb5
+ version: pam-krb5
+packaging:
+ debian: libpam-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.
+
+readme:
+ 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/pgp-sign/docknot.yaml b/t/data/generate/pgp-sign/docknot.yaml
new file mode 100644
index 0000000..010cb48
--- /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:
+ lancaster: true
+ type: Module::Build
+debian:
+ summary: |
+ PGP::Sign is packaged for Debian as libpgp-sign-perl.
+distribution:
+ cpan: PGP-Sign
+ ignore:
+ - ^t/data/gnupg1/random_seed$
+ - ^t/data/gnupg./trustdb\.gpg$
+ section: perl
+ tarname: PGP-Sign
+ version: pgp-sign
+packaging:
+ debian: libpgp-sign-perl
+support:
+ cpan: PGP-Sign
+ email: rra@cpan.org
+ 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:
+ 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/metadata/blurb b/t/data/generate/pgp-sign/metadata/blurb
deleted file mode 100644
index e2f3ad8..0000000
--- a/t/data/generate/pgp-sign/metadata/blurb
+++ /dev/null
@@ -1,3 +0,0 @@
-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.
diff --git a/t/data/generate/pgp-sign/metadata/debian/summary b/t/data/generate/pgp-sign/metadata/debian/summary
deleted file mode 100644
index 4688382..0000000
--- a/t/data/generate/pgp-sign/metadata/debian/summary
+++ /dev/null
@@ -1 +0,0 @@
-PGP::Sign is packaged for Debian as libpgp-sign-perl.
diff --git a/t/data/generate/pgp-sign/metadata/description b/t/data/generate/pgp-sign/metadata/description
deleted file mode 100644
index f41e56d..0000000
--- a/t/data/generate/pgp-sign/metadata/description
+++ /dev/null
@@ -1,24 +0,0 @@
-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.
diff --git a/t/data/generate/pgp-sign/metadata/metadata.json b/t/data/generate/pgp-sign/metadata/metadata.json
deleted file mode 100644
index 3a99430..0000000
--- a/t/data/generate/pgp-sign/metadata/metadata.json
+++ /dev/null
@@ -1,61 +0,0 @@
-{
- "name": "PGP::Sign",
- "version": "1.00",
- "synopsis": "create and verify detached PGP signatures",
- "maintainer": "Russ Allbery <rra@cpan.org>",
- "copyrights": [
- {
- "holder": "Russ Allbery <rra@cpan.org>",
- "years": "1997-2000, 2002, 2004, 2018, 2020",
- },
- ],
- "license": "Perl",
- "build": {
- "lancaster": true,
- "type": "Module::Build",
- },
- "support": {
- "cpan": "PGP-Sign",
- "email": "rra@cpan.org",
- "web": "https://www.eyrie.org/~eagle/software/pgp-sign/",
- },
- "vcs": {
- "type": "Git",
- "url": "https://git.eyrie.org/git/perl/pgp-sign.git",
- "browse": "https://git.eyrie.org/?p=perl/pgp-sign.git",
- "github": "rra/pgp-sign",
- "status": {
- "workflow": "build",
- },
- },
- "quote": {
- "author": "William Shakespeare",
- "work": "Hamlet",
- "broken": true,
- },
- "distribution": {
- "section": "perl",
- "tarname": "PGP-Sign",
- "version": "pgp-sign",
- "cpan": "PGP-Sign",
- "ignore": [
- "^t/data/gnupg1/random_seed$",
- "^t/data/gnupg./trustdb\\.gpg$",
- ],
- },
- "packaging": {
- "debian": "libpgp-sign-perl",
- },
- "docs": {
- "user": [
- {
- "name": "docs",
- "title": "Module documentation",
- },
- {
- "name": "thanks",
- "title": "Thanks and credits",
- },
- ],
- },
-}
diff --git a/t/data/generate/pgp-sign/metadata/quote b/t/data/generate/pgp-sign/metadata/quote
deleted file mode 100644
index df57c5e..0000000
--- a/t/data/generate/pgp-sign/metadata/quote
+++ /dev/null
@@ -1,3 +0,0 @@
-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.
diff --git a/t/data/generate/pgp-sign/metadata/requirements b/t/data/generate/pgp-sign/metadata/requirements
deleted file mode 100644
index 0b07801..0000000
--- a/t/data/generate/pgp-sign/metadata/requirements
+++ /dev/null
@@ -1,9 +0,0 @@
-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).
diff --git a/t/data/generate/pgp-sign/metadata/test/suffix b/t/data/generate/pgp-sign/metadata/test/suffix
deleted file mode 100644
index 8125372..0000000
--- a/t/data/generate/pgp-sign/metadata/test/suffix
+++ /dev/null
@@ -1,14 +0,0 @@
-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/remctl/docknot.yaml b/t/data/generate/remctl/docknot.yaml
new file mode 100644
index 0000000..d12a3d4
--- /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
+ gssapi: true
+ install: true
+ kerberos: true
+ lancaster: 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
+bootstrap: |
+ You will also need pkg-config installed to regenerate configure and
+ xml2rfc to build the formatted protocol documentation.
+debian:
+ 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).
+distribution:
+ section: kerberos
+ tarname: remctl
+ version: remctl
+packaging:
+ debian: remctl
+ 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.
+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).
+
+readme:
+ 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:
+ 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/rra-c-util/docknot.yaml b/t/data/generate/rra-c-util/docknot.yaml
new file mode 100644
index 0000000..ad5abf5
--- /dev/null
+++ b/t/data/generate/rra-c-util/docknot.yaml
@@ -0,0 +1,341 @@
+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
+ lancaster: true
+ manpages: true
+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.
+
+readme:
+ sections:
+ - title: Building
+ 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: Testing
+ body: |
+ 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.
+ - 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.
diff --git a/t/data/generate/wallet/docknot.yaml b/t/data/generate/wallet/docknot.yaml
new file mode 100644
index 0000000..c60b053
--- /dev/null
+++ b/t/data/generate/wallet/docknot.yaml
@@ -0,0 +1,352 @@
+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
+ lancaster: 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
+debian:
+ personal: true
+distribution:
+ 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.)
+
+readme:
+ 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`).
+
+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.
+
+test:
+ 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/metadata/blurb b/t/data/generate/wallet/metadata/blurb
deleted file mode 100644
index bd695b0..0000000
--- a/t/data/generate/wallet/metadata/blurb
+++ /dev/null
@@ -1,9 +0,0 @@
-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.
diff --git a/t/data/generate/wallet/metadata/build/middle b/t/data/generate/wallet/metadata/build/middle
deleted file mode 100644
index 8a15117..0000000
--- a/t/data/generate/wallet/metadata/build/middle
+++ /dev/null
@@ -1,33 +0,0 @@
-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`.
diff --git a/t/data/generate/wallet/metadata/description b/t/data/generate/wallet/metadata/description
deleted file mode 100644
index 190c1db..0000000
--- a/t/data/generate/wallet/metadata/description
+++ /dev/null
@@ -1,31 +0,0 @@
-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.)
diff --git a/t/data/generate/wallet/metadata/metadata.json b/t/data/generate/wallet/metadata/metadata.json
deleted file mode 100644
index f1d5074..0000000
--- a/t/data/generate/wallet/metadata/metadata.json
+++ /dev/null
@@ -1,261 +0,0 @@
-{
- "name": "wallet",
- "version": "1.4",
- "synopsis": "secure data management system",
- "maintainer": "Russ Allbery <eagle@eyrie.org>",
- "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",
- },
- ],
- "license": "Expat",
- "build": {
- "autotools": true,
- "automake": "1.11",
- "autoconf": "2.64",
- "install": true,
- "kerberos": true,
- "lancaster": true,
- "manpages": true,
- "reduced_depends": true,
- "type": "Autoconf",
- },
- "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": {
- "type": "Git",
- "url": "https://git.eyrie.org/git/kerberos/wallet.git",
- "browse": "https://git.eyrie.org/?p=kerberos/wallet.git",
- "github": "rra/wallet",
- "openhub": "https://www.openhub.net/p/wallet",
- "status": {
- "workflow": "build",
- },
- },
- "readme": {
- "sections": [
- { "title": "Configuration" },
- ],
- },
- "quote": {
- "author": "John M. Ford",
- "broken": true,
- "work": "Growing Up Weightless",
- },
- "distribution": {
- "section": "kerberos",
- "tarname": "wallet",
- "version": "wallet",
- },
- "debian": {
- "personal": true,
- },
- "docs": {
- "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",
- },
- ],
- "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",
- },
- ],
- "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",
- }
- ],
- "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",
- },
- ],
- },
-}
diff --git a/t/data/generate/wallet/metadata/quote b/t/data/generate/wallet/metadata/quote
deleted file mode 100644
index eafb546..0000000
--- a/t/data/generate/wallet/metadata/quote
+++ /dev/null
@@ -1,5 +0,0 @@
-An architect
-who does not believe
-in privacy
-may also lack faith
-in keeping out the rain
diff --git a/t/data/generate/wallet/metadata/requirements b/t/data/generate/wallet/metadata/requirements
deleted file mode 100644
index c2543ad..0000000
--- a/t/data/generate/wallet/metadata/requirements
+++ /dev/null
@@ -1,59 +0,0 @@
-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.
diff --git a/t/data/generate/wallet/metadata/sections/configuration b/t/data/generate/wallet/metadata/sections/configuration
deleted file mode 100644
index 975516d..0000000
--- a/t/data/generate/wallet/metadata/sections/configuration
+++ /dev/null
@@ -1,16 +0,0 @@
-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`).
diff --git a/t/data/generate/wallet/metadata/test/prefix b/t/data/generate/wallet/metadata/test/prefix
deleted file mode 100644
index c92c414..0000000
--- a/t/data/generate/wallet/metadata/test/prefix
+++ /dev/null
@@ -1,8 +0,0 @@
-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:
diff --git a/t/data/generate/wallet/metadata/test/suffix b/t/data/generate/wallet/metadata/test/suffix
deleted file mode 100644
index df44eed..0000000
--- a/t/data/generate/wallet/metadata/test/suffix
+++ /dev/null
@@ -1,23 +0,0 @@
-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/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..3cfc953
--- /dev/null
+++ b/t/data/update/ansicolor/docknot.yaml
@@ -0,0 +1,105 @@
+---
+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:
+ lancaster: true
+ 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:
+ cpan: Term-ANSIColor
+ email: rra@cpan.org
+ web: https://www.eyrie.org/~eagle/software/ansicolor/
+synopsis: simple ANSI text attribute control module
+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..88337dc
--- /dev/null
+++ b/t/data/update/c-tap-harness/docknot.yaml
@@ -0,0 +1,256 @@
+---
+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
+readme:
+ sections:
+ - body: |
+ 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.
+ title: Testing
+ - 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
+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.
+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
+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..4508720
--- /dev/null
+++ b/t/data/update/control-archive/docknot.yaml
@@ -0,0 +1,322 @@
+---
+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.
+readme:
+ 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
+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).
+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..3ee5145
--- /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
+ lancaster: 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
+debian:
+ 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.
+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:
+ 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.
+packaging:
+ debian: lbcd
+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:
+ 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..1a329a5
--- /dev/null
+++ b/t/data/update/pam-krb5/docknot.yaml
@@ -0,0 +1,509 @@
+---
+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
+debian:
+ 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.
+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:
+ 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
+packaging:
+ debian: libpam-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
+readme:
+ 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
+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.
+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..addf21e
--- /dev/null
+++ b/t/data/update/remctl/docknot.yaml
@@ -0,0 +1,381 @@
+---
+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.
+bootstrap: |
+ You will also need pkg-config installed to regenerate configure and
+ xml2rfc to build the formatted protocol documentation.
+build:
+ autoconf: '2.64'
+ automake: '1.11'
+ autotools: true
+ gssapi: true
+ install: true
+ kerberos: true
+ lancaster: 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
+debian:
+ 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).
+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:
+ 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
+packaging:
+ debian: remctl
+ 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.
+quote:
+ author: Peter Marshall
+ text: |
+ Small deeds done are better than great deeds planned.
+readme:
+ 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
+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.
+support:
+ email: eagle@eyrie.org
+ github: rra/remctl
+ web: https://www.eyrie.org/~eagle/software/remctl/
+synopsis: remote authenticated command execution with ACLs
+test:
+ 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..ced18a0
--- /dev/null
+++ b/t/data/update/rra-c-util/docknot.yaml
@@ -0,0 +1,319 @@
+---
+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
+ lancaster: 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.
+readme:
+ 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: |
+ 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.
+ title: Testing
+ - 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
+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.
+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
+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/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/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);