App-FuguWeb
view release on metacpan or search on metacpan
man/fuguweb/fuguweb.1 view on Meta::CPAN
.Pp
A plain file of the top level is one that a build writes.
A file below the root must be one that the site names,
or one of the shapes that the key directory takes.
A directory must hold a name of the site,
or be a directory of the key tree.
A symlink is never a thing that a build wrote.
The command refuses every other entry,
and it names the entry.
A path that you type must never take the tree of somebody else with it.
.Pp
Both
.Cm build
and
.Cm clean
also refuse the root of the filesystem,
the home directory,
the project root,
and any directory that holds the project.
They refuse the source directory as well,
and every directory of it.
.Pp
The source directory reads like a built site.
The key directory is the worst case.
Each key file sits at its top level,
where the clean takes a plain file.
A clean of it would take the trust anchor of every release.
.Pp
The output directory is the one exception below the source.
The default output directory is
.Pa web/build ,
and it sits inside the default source directory
.Pa web .
The description names that path,
so a build owns it.
A description that names neither directory takes the two defaults.
.Pp
With
.Fl Fl out
the command reads the
.Pa .fuguwebrc
when it can,
because the description is what names the key directory.
A description that does not load names nothing,
and one flat directory of files is then the whole site that
.Cm clean
knows.
That fallback is weak,
so the command asks for one more thing:
the target must hold the stylesheet.
Every build writes it,
so a target without it is the output of no build.
.Pp
The staging directory holds one flat directory of plain files.
The command refuses a staging directory of another shape,
and the build refuses the same one and leaves it.
.It Cm check Oo Fl Fl out Ar dir Oc Op Fl Fl verbose
Check a built site:
that every page and asset is there and is not empty,
that every page has a title and the whole navigation,
that every local link and every fragment resolves,
that no reference is root-absolute or a
.Ql file:
URL,
that no local link reads as a URL scheme,
that no manual cross-reference dangles,
that every page is reachable from the front page,
and that the output holds the site and nothing else.
.Pp
The command prints one line for each problem and exits 5.
It says nothing and exits 0 when the site is good.
.Fl Fl verbose
also notes every external link.
The command never fetches one:
the build and its checks touch no network.
.It Cm rotate-key Fl Fl step Ar mint Ns | Ns Ar promote \
Fl Fl purpose Ar word Fl Fl secret Ar path Op Fl Fl signer Ar path
Write the key directory:
mint the next key of a purpose,
or promote the one that a mint made.
.Pp
A consumer verifies a release against the copy of the public key that it holds.
A release that a new key signs therefore fails in each consumer
that holds the old copy.
One rotation runs in two steps,
and the trust order carries the gap.
.Pp
.Fl Fl step Ar mint
generates the next key of the purpose,
writes its public half into the key directory,
and writes its private half to
.Fl Fl secret .
The current key of the purpose signs the manifest that names the new key,
so
.Fl Fl signer
names the private half of that key.
The command refuses a mint that would sign with the key it generated.
.Pp
The first mint of a purpose finds no current key.
That key is current at once,
it signs its own manifest,
and the command takes no
.Fl Fl signer .
A site that publishes its first key holds no
.Ic keys
block,
so
.Fl Fl org
names the organization word,
and
.Fl Fl dir
and
.Fl Fl url
name the directory and the published prefix.
One commit carries the block and the key.
.Pp
.Fl Fl step Ar promote
makes the
.Ic next
key current and retires the key that was current.
.Fl Fl secret
( run in 0.943 second using v1.01-cache-2.11-cpan-364913b4093 )