Configd

 view release on metacpan or  search on metacpan

lib/Configd/Language.pm  view on Meta::CPAN


A key cannot both accumulate and repeat; C<accumulates> is checked first.

=head2 separator($key)

What joins the parts of an accumulating directive.  A comma and a space by
default, which is what postfix uses; whitespace-separated languages override it.

=head2 @items = $language->items($key, $value)

The items of the value of an accumulating directive, in order.  They are
separated by whitespace and by the punctuation of C<separator>, so a value
written over several lines, or with a trailing comma as postfix's own
C<mydestination> has, gives no empty item.  A separator inside braces does not
split, because postfix reads C<{ ... }> as one item, as in an C<inline:> table.

=head2 @items = $language->combine($key, @items)

The items that an accumulating directive ends with, after the merge has
dropped the repeats.  C<@items> as they are by default.  A language overrides
this for a parameter whose items are not a plain set, such as C<all> in the
C<inet_interfaces> of postfix.

=head1 METHODS

=head2 $class->new(%opts)

C<root> relocates every path this language touches, so a test -- or a build for
a guest that is not this machine -- works against a directory rather than the
running system's C</etc>.

=head2 $language->name()

What this language is called on the command line: the last component of the
package name.

=head2 $language->root()

The directory every path this language touches is relocated under, or the empty
string for the running system.

=head2 $language->path($path)

C<$path> under this language's C<root>.  Every path in this class goes through
it, so that nothing writes outside the root it was given.

=head2 $language->fragment_dir($file)

The directory a file's fragments live in: the file's own path with C<.d> on the
end.

=head2 $language->fragments($file)

The fragment files for one managed file, in the order they are merged.

Sorted by name, so the numeric prefixes everybody already writes on C<conf.d>
entries do what they look like they do.  Names starting with a dot are skipped,
and so is anything ending in C<~>, C<.disabled>, C<.bak>, or one of the suffixes
dpkg and rpm leave behind -- C<.dpkg-old>, C<.dpkg-new>, C<.dpkg-dist>,
C<.rpmsave>, C<.rpmnew>.  Editors and package managers leave those lying about,
and a stray backup silently taking part in the merge is a bad afternoon.

=head2 $language->merge(@fragment_sets)

One list of directives out of several, applying C<accumulates> to decide which
of two directives for the same key wins and which of them join up.

An accumulating directive joins as a list of items, not as two strings.  Each
value is split into its items with C<items>, an item that the list already
holds is dropped, and C<combine> has the last word.  So a fragment that
repeats what C<00-original> says changes nothing, which is what it meant, and
does not make C<inet_interfaces = all, all>, which postfix refuses.

An accumulating directive with an B<empty value> resets it: whatever earlier
fragments put there is dropped, and anything after this adds to nothing rather
than to that.  It is the one thing accumulation cannot otherwise say, since a
fragment can add to what came before it and never take something out -- and
C<00-original> is sometimes wrong rather than merely incomplete.  A guest whose
hostname is a domain it hosts is the case that keeps coming up: the package's
own C<mydestination> names that domain, the domain has to be a virtual mailbox
domain instead, postfix will not have it in both, and no amount of adding fixes
it.

    mydestination =
    mydestination = $myhostname, localhost

systemd drop-ins spell it the same way, for the same reason.

Order is the order the keys were first seen, so a generated file reads like the
fragments that made it rather than like a hash.

Comments and blank lines are B<not> carried through.  A merged file cannot say
where a comment belongs -- the distribution's paragraph explaining a default sits
above a setting some later fragment has since replaced, and reproducing it there
tells the reader something that is no longer true.  They stay in the fragment
they were written in, which is where somebody editing will be looking, and
C<00-original> keeps every one the file arrived with.

=head2 $language->build($file)

Read every fragment for one file, merge them, and return the text to write.

=head2 $language->header($file)

The comment Configd puts at the top of a file it generates, saying so.

Somebody is going to edit the generated file -- it is where the settings are,
and it is where every piece of documentation on the internet says they live.
This is the one chance to tell them their edit will not survive the next restart
and where to put it instead.

=head2 $language->write($file)

Generate one file and put it in place, returning true if what is on disk
changed.

Written through a temporary file in the same directory and renamed over the
target, so that a service reading it at that moment sees the old file or the
new one and never half of either.

=head2 $language->adopt()



( run in 0.893 second using v1.01-cache-2.11-cpan-3f962061493 )