Skip to content

Releases: n36l3c7/hosts-cli

hosts 1.1.0

Choose a tag to compare

@github-actions github-actions released this 30 Jul 05:10
7d52894

check can now repair what it finds, for the findings where the repair is not a
guess.

Added

  • check --fix repairs five of the eleven rules: duplicate-entry, by removing
    the later line; duplicate-name, by taking the redundant name off the line
    and dropping the line if that leaves it with nothing but an address;
    missing-loopback and missing-loopback6, by adding the entry above the
    first entry the file has, or at the end when it has none; and
    missing-trailing-newline.

    The other six are left alone deliberately, and that line is the feature. An
    address or a name that does not parse cannot be repaired without inventing
    one. conflicting-ip is the one that tempts: two lines send a name to two
    addresses, and which of them is wanted is knowledge the file does not contain.
    control-character is left because stripping bytes out of a line in silence
    would destroy the evidence of what happened to it.

    It is a write like the others: it takes the lock before the read, backs up
    first, honours --dry-run and --no-backup, and asks before touching more
    than one line unless --yes is given. A file with nothing to fix is not
    written to at all. A line the fix did not touch is byte for byte what it was,
    which is the existing guarantee rather than a new one.

  • summary.fixed in the JSON output of check, counting what was repaired,
    and always present so the shape of the document does not depend on the flags.
    The schema version stays at 1: fields are added within a version, and a
    reader should ignore what it does not recognise. --fix with --dry-run is
    refused under --json, because the preview is a diff on standard output and
    would leave the document unparseable.

  • A fuzzing pass over the fix itself: hostile input is fixed, the result is
    still a file the program reads, and fixing it a second time changes nothing.

  • A recorded demonstration, in the README and at the top of the documentation
    site: an add, two rm and the ls between each. demo/session.sh runs the
    commands it prints, against a scratch file rather than /etc/hosts so that
    recording needs no privilege, and demo/record.sh turns it into
    docs/demo.gif. Keeping the recipe in the repository means the picture can be
    regenerated when output changes instead of quietly going stale.

Changed

  • After a fix the file is read and scanned again rather than the earlier
    findings being renumbered onto it. Removing lines moves everything below them,
    so a leftover finding would otherwise have been reported against a line that
    is now something else, and a message naming another line would have named the
    wrong one. Scanning again makes every number and message right by
    construction, and reports anything a fix itself introduced.

  • The documentation site leads with what the program is for. It gained an
    opening statement, the demonstration, the apt command with a button that
    copies it, and a navigation bar that follows the page and links to the
    sections, in place of three links to other pages. The stylesheet is still one
    hand-written file with no external asset and no font loaded from anywhere
    else. Every documented section is unchanged.

  • The workflows use actions that run on Node 24. The ones in use targeted Node
    20, which the runners have deprecated and were forcing onto 24 anyway: they
    worked, and one day they would not have. checkout went to v7 and the two
    Pages actions to v5, further along than expected, so the versions were
    looked up and the moving major tags checked rather than guessed at.

Fixed

  • The navigation bar of the documentation site stays on screen. It was the last
    child of the header, and a sticky element is confined to its containing block,
    so it came unstuck the moment the header scrolled past.

  • Every released version is installable from the apt repository, not only the
    most recent one. dpkg-scanpackages reports one version per package unless
    told otherwise, so earlier .deb files were being published and then left
    out of the index: present but not installable, which is not what "the index
    is rebuilt from every release" was meant to mean.

hosts 1.0.1

Choose a tag to compare

@github-actions github-actions released this 30 Jul 03:49
d559508

Verification of what 1.0.0 already claimed, and one claim that turned out not
to be true.

Fixed

  • Concurrent writers no longer lose each other's work. The lock was taken
    inside the write, after the file had already been read, so two writers each
    computed their change from the same starting point and the second one
    discarded the first. Serialising the writes prevented nothing, the rename
    having already made those indivisible: the update that got lost was lost
    during the read. The lock is now taken before the file is read and held
    until the new content is in place. 0.2.0 documented the protection this
    provides; it did not provide it.
  • hosts edit holds that lock for as long as the editor is open, so another
    writer waits and then fails saying so rather than quietly discarding one of
    the two changes.
  • The apt index is rebuilt after a release again. It was chained to the
    release event, which a release created by a workflow using the built-in
    token never raises: GitHub suppresses those so that workflows cannot
    trigger each other in a loop. It now chains to the release workflow itself,
    which is the mechanism meant for it. The index for 1.0.0 was published by
    running the workflow by hand.

Added

  • Tests that kill a write partway through, at a different point on each pass,
    and require the file to hold either the whole of the old content or the
    whole of the new one. That guarantee is the one the whole program rests on
    and had only ever been reasoned about.
  • A test that runs two writers at once against a file large enough for the
    race to be certain rather than merely possible. It is what found the lock
    defect above.
  • Tests that put the parser against input it was not written for: control
    bytes, addresses and names that nearly parse, lines of only whitespace, and
    a very long line. Three invariants are checked, the strongest being that
    export gives back exactly the bytes that were read. The generator is
    seeded so a failure can be reproduced. Nothing was found, which is also
    information.
  • A portability job that runs the whole suite on Debian 11 and 12 and Ubuntu
    22.04 and 24.04, as an ordinary user rather than as root so that the tests
    about refused permissions do not skip themselves. Everything had until now
    only ever run on one Ubuntu, which left every assumption about stat,
    date, realpath, sync, flock and install untested.

Changed

  • The README no longer implies bash 4.4 is tested. It is the documented floor;
    what the suite runs against is bash 5.1 and 5.2, because nothing still
    supported ships 4.4.
  • A test no longer expects a file to come out mode 644. Debian defaults to a
    umask of 022 and Ubuntu to 002, so the same fixture is 644 on one and 664 on
    the other; the sidecar records the mode the file actually has, which is what
    the test now checks. The portability job found this on its first run, which
    is the sort of thing it was added for.

hosts 1.0.0

Choose a tag to compare

@github-actions github-actions released this 27 Jul 06:15
5ce8d54

The first release that can be installed with apt, and the point from which
the interface is a promise.

Nothing in the program itself changed from 0.6.0. What changed is that there
is now a way to install it that does not begin with cloning a repository, and
a commitment about what will not break.

Added

  • A Debian package, hosts-cli, holding the command, the man page and the
    completions for bash and zsh. make deb builds it from the same artifacts
    make install uses.
  • An APT repository published on GitHub Pages, signed, and rebuilt from the
    packages attached to every GitHub Release so that it holds no state of its
    own and cannot drift from what was published.
  • A release workflow that runs on a tag, refuses to continue when the tag and
    the VERSION file disagree, installs the package it just built and uses it
    before publishing anything, and takes the release notes from this file.

Changed

  • GitHub Pages is deployed by a workflow rather than from the docs folder of
    the branch, because an APT repository contains a binary and committing one
    would put it in the history for good.
  • The following are now covered by semantic versioning, and breaking any of
    them costs a major version: the exit codes 0 to 8; the tab separated output
    of ls, search, check, backup ls, profile ls and flush, the number
    of fields included; the JSON schema; the rule identifiers of check; the
    environment variables and the layout of the backup and profile stores,
    sidecar format included.