Read all five documents against the code and fix what the sixth review found
check / check (push) Successful in 12m5s
check / check (push) Successful in 12m5s
Fixes the four findings of the sixth review: `snapshot remove` with `--local-only`, the two comma-chained permission lists, six undefined terms, and the sentence about an unfinished snapshot in the local index. Then reads every sentence of `README.md`, `ARCHITECTURE.md`, `docs/DATAMODEL.md`, `docs/REPOSTRUCTURE.md` and the comments in `config.example.yml` against the code for four faults: a command's needs or behaviour stated without regard to a flag, a false absolute, three or more things chained with commas, and a technical word not defined on first use. Each sentence changed is listed on the pull request. The help string of `snapshot remove --dry-run` now says it needs no permission to delete. Model: fable-5-1
This commit is contained in:
1 parent
a133b8838e
commit
46b2a9fc78
6 files changed
+341
-193
No files matched your search
@@ -3,7 +3,7 @@
|
||||
`vaultik` is an MIT-licensed command-line tool for incremental, encrypted
|
||||
backups, written in Go by [@sneak](https://sneak.berlin). It encrypts your files
|
||||
with a public key and uploads them to an S3-compatible object store, a local
|
||||
directory or an rclone remote.
|
||||
directory or any storage service that [rclone](https://rclone.org/) supports.
|
||||
|
||||
The machine being backed up holds only the public key. It cannot decrypt its own
|
||||
backups. You keep the private key somewhere else. A backup never needs it.
|
||||
@@ -25,13 +25,14 @@ It was written to meet these requirements together:
|
||||
|
||||
## Features
|
||||
|
||||
- Encryption with [age](https://age-encryption.org/) (X25519 and
|
||||
ChaCha20-Poly1305), to one or more public keys.
|
||||
- Encryption with [age](https://age-encryption.org/), to one or more public
|
||||
keys. age uses X25519 keys and the ChaCha20-Poly1305 cipher.
|
||||
- Incremental backups. A file is read again only when it has changed, or when
|
||||
part of its content has to be stored again.
|
||||
- Deduplication. Identical content is stored once, across files and across
|
||||
snapshots.
|
||||
- zstd compression at a level you choose.
|
||||
- Compression with [zstd](https://github.com/facebook/zstd), at a level you
|
||||
choose.
|
||||
- Small files are packed together into large objects. This keeps the number of
|
||||
S3 requests low.
|
||||
- File contents, names, paths and metadata are encrypted at the destination.
|
||||
@@ -91,12 +92,13 @@ vaultik snapshot list
|
||||
|
||||
The default config is written for macOS. It backs up your home directory and
|
||||
`/Applications`, with a list of excludes. A configured path that does not exist
|
||||
stops the backup. On another system, run `vaultik config edit` first and change
|
||||
the `snapshots` section.
|
||||
stops the backup, unless you give `--skip-errors`. On another system, run
|
||||
`vaultik config edit` first and change the `snapshots` section.
|
||||
|
||||
On macOS, grant your terminal app Full Disk Access before the first backup. The
|
||||
setting is under System Settings, Privacy & Security, Full Disk Access. Without
|
||||
it the backup stops with a permission error on a protected directory.
|
||||
it the backup stops with a permission error on a protected directory, unless you
|
||||
give `--skip-errors`.
|
||||
|
||||
## Everyday use
|
||||
|
||||
@@ -155,7 +157,7 @@ Use that remote key in place of the snapshot ID:
|
||||
```sh
|
||||
export VAULTIK_AGE_SECRET_KEY="$(cat vaultik_backup_private_key.txt)"
|
||||
|
||||
# Restore everything, then check the chunk hashes of every restored file.
|
||||
# Restore everything, then check the chunk hashes of the restored files.
|
||||
vaultik snapshot restore --verify <remote-key> ~/vaultik-restore
|
||||
|
||||
# Optionally, also check every blob of the snapshot at the destination.
|
||||
@@ -194,10 +196,14 @@ vaultik version
|
||||
|
||||
### What every command needs
|
||||
|
||||
`config init`, `completion` and `version` need nothing.
|
||||
`completion` and `version` need nothing. `config init` needs write access to the
|
||||
config directory.
|
||||
|
||||
`config edit`, `config get` and `config set` need a config file that exists. It
|
||||
does not have to be complete.
|
||||
These commands need a config file that exists, even an incomplete one:
|
||||
|
||||
- `config edit`
|
||||
- `config get`
|
||||
- `config set`
|
||||
|
||||
Every other command needs a config file that loads. See
|
||||
[Configuration](#configuration) for the checks.
|
||||
@@ -219,24 +225,34 @@ sets file owners only when it runs as root.
|
||||
[Where the config file is](#where-the-config-file-is).
|
||||
- `--verbose`, `-v`: write informational log records to stderr.
|
||||
- `--debug`: write debug log records to stderr.
|
||||
- `--quiet`, `-q`: print only warnings, errors and the output a script reads.
|
||||
See [Output](#output).
|
||||
- `--quiet`, `-q`: leave out the banner, the status lines, the tables and the
|
||||
reports. See [Output](#output).
|
||||
- `--skip-errors`: skip a file that cannot be read during a backup, or cannot be
|
||||
restored during a restore. Without it the command stops at the first such
|
||||
file.
|
||||
|
||||
`--quiet` and `--cron` override `--verbose` and `--debug`.
|
||||
|
||||
`--skip-errors` applies to `snapshot create` and `snapshot restore` only. A
|
||||
command that skipped anything still finishes, and then exits non-zero.
|
||||
|
||||
### Durations
|
||||
|
||||
`--keep-newer-than`, `--older-than` and `prune_grace_period` take a duration.
|
||||
These take a duration:
|
||||
|
||||
- `--keep-newer-than`
|
||||
- `--older-than`
|
||||
- `prune_grace_period`
|
||||
|
||||
These units are accepted:
|
||||
|
||||
- `d`: days.
|
||||
- `w`: weeks.
|
||||
- `mo`: months of 30 days.
|
||||
- `y`: years of 365 days.
|
||||
- `h`, `m` and `s`: hours, minutes and seconds, as in `36h` or `90m`.
|
||||
- `h`: hours, as in `36h`.
|
||||
- `m`: minutes, as in `90m`.
|
||||
- `s`: seconds.
|
||||
|
||||
`m` means minutes and `mo` means months. Days, weeks, months and years take
|
||||
whole numbers and can be combined, as in `2w3d`.
|
||||
@@ -249,9 +265,9 @@ Writes a default config file, with a comment that explains each setting it
|
||||
lists.
|
||||
|
||||
- It writes to the path from `--config`, or else from `VAULTIK_CONFIG`.
|
||||
- Otherwise it writes to `config.yml` in the platform config directory. That is
|
||||
`~/.config/vaultik/` on Linux and `~/Library/Application Support/vaultik/` on
|
||||
macOS.
|
||||
- Otherwise it writes to `config.yml` in the platform config directory. By
|
||||
default that is `~/.config/vaultik/` on Linux and
|
||||
`~/Library/Application Support/vaultik/` on macOS.
|
||||
- As root it writes to `/etc/vaultik/config.yml` instead.
|
||||
- It creates the file with mode `0600`, because the file can hold credentials.
|
||||
- It refuses to overwrite a file that exists.
|
||||
@@ -275,7 +291,8 @@ Sets one value in the config file. The key is a dotted path, as in
|
||||
- A key that does not exist yet is created. A missing parent becomes a list when
|
||||
the next part of the path is a number, and a map otherwise.
|
||||
- In a list, the index one past the end appends an entry.
|
||||
- The command prints the key it set, and never the value.
|
||||
- The command prints the key it set, and not the value. A refusal for a value
|
||||
of the wrong type quotes the beginning of that value.
|
||||
- It sets the file's mode to `0600` when group or others could read it.
|
||||
|
||||
The command refuses a change that would stop the config from loading. An example
|
||||
@@ -301,7 +318,8 @@ It needs:
|
||||
|
||||
It does not need the private key.
|
||||
|
||||
A file is read again when any of these holds:
|
||||
A file is read when the local index does not know it, or when any of these
|
||||
holds:
|
||||
|
||||
- Its size has changed since the last backup.
|
||||
- Its modification time has changed.
|
||||
@@ -383,9 +401,9 @@ config.
|
||||
|
||||
### `snapshot list`
|
||||
|
||||
Lists the snapshots in the local index and the snapshots at the destination, as
|
||||
one table. Before the table, the command prints the snapshot names and paths in
|
||||
the config.
|
||||
Lists the finished snapshots in the local index and the snapshots at the
|
||||
destination, as one table. Before the table, the command prints the snapshot
|
||||
names and paths in the config.
|
||||
|
||||
It needs permission to list and read at the destination. It needs no private
|
||||
key.
|
||||
@@ -402,7 +420,8 @@ The table has these columns:
|
||||
A snapshot at the destination that is not in the local index is shown as
|
||||
`<remote only:...>`. The dots stand for the first 12 characters of its remote
|
||||
key. Its last two columns read `<remote only>`, because those sizes come from
|
||||
the local index. Its timestamp is the time its backup finished.
|
||||
the local index. Its timestamp is the time its manifest was written, at the end
|
||||
of its backup.
|
||||
|
||||
The command reports these below the table:
|
||||
|
||||
@@ -424,7 +443,8 @@ marker file although the local index holds snapshots.
|
||||
- `remote_key`: the full 64-character remote key.
|
||||
- `timestamp`
|
||||
- `compressed_size`
|
||||
- `uncompressed_size` and `new_chunk_size`: left out for a remote-only snapshot.
|
||||
- `uncompressed_size` and `new_chunk_size`: left out when zero, and for a
|
||||
remote-only snapshot.
|
||||
- `locally_tracked`: whether the snapshot is in the local index.
|
||||
- `remote_present`: whether the snapshot is at the destination. It is `null`
|
||||
when the destination could not be listed.
|
||||
@@ -469,7 +489,8 @@ variable wins when both are set. See [The private key](#the-private-key).
|
||||
- It downloads and decrypts every blob. It checks the hash of each chunk, and
|
||||
the hash that names the blob.
|
||||
|
||||
It stops at the first blob that fails.
|
||||
The presence check counts every missing or wrong-size blob. The download check
|
||||
stops at the first blob that fails.
|
||||
|
||||
`--deep` proves that the stored data is intact and decrypts with your key. It
|
||||
does not prove who wrote the data.
|
||||
@@ -510,20 +531,22 @@ cannot be listed or has no marker file.
|
||||
Removes one snapshot. The argument must be a snapshot ID. A remote key is not
|
||||
accepted.
|
||||
|
||||
It needs the [lock](#locking), and permission to list and delete at the
|
||||
destination. It needs no private key.
|
||||
It needs the [lock](#locking). It needs permission to list and delete at the
|
||||
destination, unless you give `--local-only`. It needs no private key.
|
||||
|
||||
Flags:
|
||||
|
||||
- `--force`, `-f`: do not ask for confirmation.
|
||||
- `--dry-run`: say what would be removed, and remove nothing.
|
||||
- `--dry-run`: say what would be removed, and remove nothing. It needs no
|
||||
permission to delete.
|
||||
- `--local-only`: remove the snapshot from the local index only. The destination
|
||||
is not changed.
|
||||
- `--json`: print the result as JSON. This also skips the confirmation.
|
||||
|
||||
The command removes the snapshot from the local index. It also deletes the
|
||||
snapshot's directory under `metadata/` at the destination. Its blobs stay. Run
|
||||
`vaultik prune` afterwards to delete the blobs that no snapshot uses any more.
|
||||
The command removes the snapshot from the local index. Without `--local-only`,
|
||||
it also deletes the snapshot's directory under `metadata/` at the destination.
|
||||
Its blobs stay. Run `vaultik prune` afterwards to delete the blobs that no
|
||||
snapshot uses any more.
|
||||
|
||||
An ID that is in neither the local index nor the destination is an error. With
|
||||
`--local-only`, the snapshot must be in the local index.
|
||||
@@ -586,8 +609,8 @@ Restore into a new directory that only you can write, not a shared one such as
|
||||
|
||||
Flags:
|
||||
|
||||
- `--verify`: after the restore, read every restored file and check its chunk
|
||||
hashes.
|
||||
- `--verify`: after the restore, read every restored regular file and check its
|
||||
chunk hashes.
|
||||
|
||||
With `--skip-errors`, a file that cannot be restored is reported and skipped,
|
||||
and the command exits non-zero. `--verify` does not check a skipped file.
|
||||
@@ -666,12 +689,13 @@ Reports what the destination holds:
|
||||
It needs permission to list and read at the destination. It needs no private
|
||||
key.
|
||||
|
||||
When a manifest cannot be read, the figures for blobs that no manifest lists are
|
||||
reported as unknown. That snapshot's own blob count and size are unknown too.
|
||||
|
||||
The command skips a name under `metadata/` that is not a remote key, with a
|
||||
warning. It does not count a file under `blobs/` whose name is not a blob hash.
|
||||
|
||||
When a manifest cannot be read, that snapshot's blob count and size are unknown.
|
||||
The figures for blobs that no manifest lists are unknown when a manifest cannot
|
||||
be read or sits under a skipped name.
|
||||
|
||||
`--json` prints the report as JSON. Unknown figures are `null`.
|
||||
`unreadable_manifests` lists the remote key of each manifest that could not be
|
||||
read. `skipped_manifest_count` counts the manifests under skipped names.
|
||||
@@ -715,7 +739,12 @@ Use this command after you point the config at a different destination. See
|
||||
|
||||
### `completion <shell>`
|
||||
|
||||
Prints a completion script for `bash`, `zsh`, `fish` or `powershell`.
|
||||
Prints a completion script for one of these shells:
|
||||
|
||||
- `bash`
|
||||
- `zsh`
|
||||
- `fish`
|
||||
- `powershell`
|
||||
|
||||
```sh
|
||||
# zsh, for the current session
|
||||
@@ -736,31 +765,51 @@ vaultik completion fish > ~/.config/fish/completions/vaultik.fish
|
||||
|
||||
### `version`
|
||||
|
||||
Prints the version, the commit, the commit date and the platform. It labels the
|
||||
commit date `build date`. It also says when the binary is a development build,
|
||||
not a release.
|
||||
Prints these:
|
||||
|
||||
- the version
|
||||
- the commit
|
||||
- the commit date, labelled `build date`
|
||||
- the Go version
|
||||
- the platform
|
||||
- the author
|
||||
- the homepage
|
||||
- the license
|
||||
|
||||
It also says when the binary is a development build, not a release.
|
||||
|
||||
## Configuration
|
||||
|
||||
The config file is YAML. `vaultik config init` writes one to start from, and
|
||||
[`config.example.yml`](config.example.yml) is a longer example.
|
||||
|
||||
A command refuses to start when the config does not load. The `config` commands,
|
||||
`completion` and `version` are the exceptions. The config loads when all of
|
||||
these hold:
|
||||
A command refuses to start when the config does not load. These commands are
|
||||
the exceptions:
|
||||
|
||||
- the `config` commands
|
||||
- `completion`
|
||||
- `version`
|
||||
|
||||
The config loads when it is valid YAML and all of these hold:
|
||||
|
||||
- Every entry in `age_recipients` is an age X25519 public key.
|
||||
- `snapshots` has at least one name, and every name has at least one path.
|
||||
- A destination is set, with credentials when it is S3.
|
||||
- A destination is set. Its `storage_url` has one of the three schemes under
|
||||
[Destinations](#destinations). An S3 destination has credentials.
|
||||
- Every `${ENV:NAME}` names an environment variable with a non-empty value.
|
||||
- Every other setting below is within its limits.
|
||||
|
||||
`vaultik` warns when group or others can read the config file.
|
||||
Every command that needs the local index warns when group or others can read the
|
||||
config file.
|
||||
|
||||
A value written as `${ENV:NAME}` is replaced by the environment variable `NAME`.
|
||||
This keeps a credential out of the file.
|
||||
|
||||
A leading `~` is expanded to your home directory in snapshot paths, in
|
||||
`index_path` and in a `file://~/...` destination.
|
||||
A leading `~` is expanded to your home directory in these places:
|
||||
|
||||
- snapshot paths
|
||||
- `index_path`
|
||||
- a `file://~/...` destination
|
||||
|
||||
### Where the config file is
|
||||
|
||||
@@ -768,11 +817,13 @@ A leading `~` is expanded to your home directory in snapshot paths, in
|
||||
|
||||
- the path given with `--config`
|
||||
- the path in the `VAULTIK_CONFIG` environment variable
|
||||
- `config.yml` in the platform config directory, which is `~/.config/vaultik/`
|
||||
on Linux and `~/Library/Application Support/vaultik/` on macOS
|
||||
- `config.yml` in the platform config directory, which by default is
|
||||
`~/.config/vaultik/` on Linux and `~/Library/Application Support/vaultik/` on
|
||||
macOS
|
||||
- `/etc/vaultik/config.yml`
|
||||
|
||||
A path from `--config` or `VAULTIK_CONFIG` must exist.
|
||||
A command that reads the config fails when the path from `--config` or
|
||||
`VAULTIK_CONFIG` does not exist. `config init` creates the file there.
|
||||
|
||||
### Settings
|
||||
|
||||
@@ -806,7 +857,8 @@ A path from `--config` or `VAULTIK_CONFIG` must exist.
|
||||
- `s3.region`
|
||||
- The S3 region. Default: `us-east-1`.
|
||||
- `s3.part_size`
|
||||
- The size of each part of a multipart upload. Default: `5MiB`.
|
||||
- A large blob is uploaded to S3 in parts. This is the size of each part.
|
||||
Default: `5MiB`.
|
||||
- It must be between `5MiB` and `5GiB`.
|
||||
- A blob too large for 10,000 parts of this size is uploaded in larger
|
||||
parts.
|
||||
@@ -826,8 +878,11 @@ A path from `--config` or `VAULTIK_CONFIG` must exist.
|
||||
- It must be at least four times `chunk_size`.
|
||||
- `compression_level`
|
||||
- The zstd compression level, from `1` to `19`. Default: `3`.
|
||||
- Levels `1` to `2`, `3` to `5`, `6` to `9` and `10` to `19` form four
|
||||
groups. Levels in one group compress the same way.
|
||||
- Levels in one of these groups compress the same way:
|
||||
- `1` to `2`
|
||||
- `3` to `5`
|
||||
- `6` to `9`
|
||||
- `10` to `19`
|
||||
- `prune_grace_period`
|
||||
- How old unused data must be before `prune` deletes it. Default: `24h`.
|
||||
- It applies to a blob that no manifest lists. It also applies to every
|
||||
@@ -839,8 +894,8 @@ A path from `--config` or `VAULTIK_CONFIG` must exist.
|
||||
- Only the part before the first `.` is used.
|
||||
- `index_path`
|
||||
- The path of the local index.
|
||||
- Default: `index.sqlite` in the platform data directory. That is
|
||||
`~/.local/share/vaultik/` on Linux and
|
||||
- Default: `index.sqlite` in the platform data directory. By default that
|
||||
is `~/.local/share/vaultik/` on Linux and
|
||||
`~/Library/Application Support/vaultik/` on macOS.
|
||||
|
||||
Sizes take a number of bytes or a unit. `MB` and `GB` are powers of 1000. `MiB`
|
||||
@@ -856,7 +911,9 @@ and `GiB` are powers of 1024.
|
||||
destination.
|
||||
- `EDITOR`: the editor that `config edit` starts.
|
||||
- `TMPDIR`: the directory for temporary files.
|
||||
- `NO_COLOR`: when set, status lines have no color.
|
||||
- `NO_COLOR`: a non-empty value turns off color in status lines.
|
||||
- `XDG_CONFIG_HOME` and `XDG_DATA_HOME`: move the platform config and data
|
||||
directories.
|
||||
- `VAULTIK_CPUPROFILE`: write a CPU profile to this path. For debugging.
|
||||
- `VAULTIK_MEMPROFILE`: write a heap profile to this path on exit. For
|
||||
debugging.
|
||||
@@ -966,15 +1023,26 @@ A leftover `.partial` file is ignored. You can delete it.
|
||||
|
||||
### Destination permissions
|
||||
|
||||
Each command needs different permissions at the destination.
|
||||
Commands need these permissions at the destination:
|
||||
|
||||
- `snapshot create` needs only permission to write objects. A machine you back
|
||||
up can therefore hold credentials that can neither read nor delete.
|
||||
- `snapshot list`, `snapshot verify`, `snapshot restore` and `remote info` list
|
||||
and read.
|
||||
- `snapshot purge`, `snapshot remove` and `remote nuke` list and delete.
|
||||
- `snapshot create` without `--prune` needs only permission to write objects. A
|
||||
machine you back up can therefore hold credentials that can neither read nor
|
||||
delete.
|
||||
- These commands list and read:
|
||||
- `snapshot list`
|
||||
- `snapshot verify`
|
||||
- `snapshot restore`
|
||||
- `remote info`
|
||||
- These commands list and delete:
|
||||
- `snapshot purge`
|
||||
- `snapshot remove`
|
||||
- `remote nuke`
|
||||
- `prune` and `snapshot create --prune` list, read and delete.
|
||||
|
||||
`snapshot verify` and `snapshot restore` list only when you give a remote key.
|
||||
`snapshot remove --local-only` does not reach the destination.
|
||||
`snapshot remove --dry-run` deletes nothing.
|
||||
|
||||
A machine that runs `snapshot create --prune` can delete its own backups. To
|
||||
keep it to write-only credentials, run `prune` from a separate, trusted machine.
|
||||
|
||||
@@ -991,12 +1059,15 @@ unplugged volume leaves an empty directory at its mount point. Without the
|
||||
marker, that directory would look like a destination whose snapshots are all
|
||||
gone.
|
||||
|
||||
The check applies while the local index holds snapshots. When the destination
|
||||
then answers that the marker does not exist, commands treat the destination as
|
||||
not present:
|
||||
The check applies while the local index holds snapshots and belongs to the
|
||||
configured destination. When the destination then answers that the marker does
|
||||
not exist, commands treat the destination as not present:
|
||||
|
||||
- `snapshot create` refuses to write to it.
|
||||
- `prune`, `snapshot purge` and `remote nuke` fail.
|
||||
- These commands fail:
|
||||
- `prune`
|
||||
- `snapshot purge`
|
||||
- `remote nuke`
|
||||
- `snapshot list` shows the local index alone.
|
||||
- `snapshot remove` deletes nothing at the destination.
|
||||
|
||||
@@ -1025,7 +1096,11 @@ different destination:
|
||||
- `remote nuke`
|
||||
|
||||
The destination that is compared is `storage_url`. When `storage_url` is not
|
||||
set, it is `s3.endpoint`, `s3.bucket` and `s3.prefix`.
|
||||
set, these three settings are compared instead:
|
||||
|
||||
- `s3.endpoint`
|
||||
- `s3.bucket`
|
||||
- `s3.prefix`
|
||||
|
||||
There are two ways out:
|
||||
|
||||
@@ -1057,8 +1132,7 @@ The new snapshot cannot be restored afterwards.
|
||||
|
||||
## Locking
|
||||
|
||||
Commands that change data take a lock, so that only one of them runs at a time.
|
||||
These commands take it:
|
||||
Five commands take a lock, so that only one of them runs at a time:
|
||||
|
||||
- `snapshot create`
|
||||
- `snapshot purge`
|
||||
@@ -1068,9 +1142,9 @@ These commands take it:
|
||||
|
||||
A second one does not wait. It exits at once with an "already running" error.
|
||||
|
||||
The lock is the file `vaultik.pid` in the platform data directory. That is
|
||||
`~/.local/share/vaultik/` on Linux and `~/Library/Application Support/vaultik/`
|
||||
on macOS.
|
||||
The lock is the file `vaultik.pid` in the platform data directory. By default
|
||||
that is `~/.local/share/vaultik/` on Linux and
|
||||
`~/Library/Application Support/vaultik/` on macOS.
|
||||
|
||||
The lock covers one user on one machine. It does not stop another user or
|
||||
another machine from writing to the same destination. See
|
||||
@@ -1111,7 +1185,8 @@ banner, log records and a final error stay on your terminal.
|
||||
Log records are colored lines when stderr is a terminal. They are JSON, one
|
||||
object per line, when stderr is redirected.
|
||||
|
||||
Status lines are colored only on a terminal, and never when `NO_COLOR` is set.
|
||||
Status lines are colored only on a terminal, and never when `NO_COLOR` has a
|
||||
non-empty value.
|
||||
|
||||
### `--json`
|
||||
|
||||
@@ -1183,8 +1258,8 @@ destination, what it protects and the risks it accepts.
|
||||
|
||||
## Limitations
|
||||
|
||||
- **No extended attributes.** ACLs, macOS Finder metadata, quarantine flags and
|
||||
SELinux labels are not backed up.
|
||||
- **No extended attributes.** Access control lists, macOS Finder metadata,
|
||||
quarantine flags and SELinux labels are not backed up.
|
||||
- **No hard links.** Two hard links to one file are backed up as two files. The
|
||||
content is stored once, but a restore creates two separate files.
|
||||
- **No sparse files.** A sparse file is backed up at its full size, zeros
|
||||
@@ -1260,25 +1335,33 @@ call them.
|
||||
- `script/test`: runs the whole test suite, by building the `test` stage of the
|
||||
`Dockerfile`.
|
||||
- `script/lint`: runs the linter, by building the `lint` stage of the
|
||||
`Dockerfile`. The linter never runs on your machine.
|
||||
`Dockerfile`. The linter runs only inside Docker.
|
||||
- `script/lint-fix`: applies the linter's automatic fixes to your files. It
|
||||
needs a local Docker daemon. Run `script/lint` afterwards.
|
||||
- `script/fmt`: formats the Go code.
|
||||
- `script/fmt-check`: checks the formatting and changes nothing.
|
||||
- `script/check`: runs `script/test`, `script/lint` and `script/fmt-check`.
|
||||
- `script/precommit`: runs `go mod tidy`, `go fmt` and `script/check`. The git
|
||||
pre-commit hook calls it.
|
||||
- `script/check`: runs these three scripts:
|
||||
- `script/test`
|
||||
- `script/lint`
|
||||
- `script/fmt-check`
|
||||
- `script/precommit`: the git pre-commit hook calls it. It runs these three:
|
||||
- `go mod tidy`
|
||||
- `go fmt`
|
||||
- `script/check`
|
||||
- `script/install-precommit`: installs that hook.
|
||||
- `script/docker`: builds the Docker image. The build runs the linter and the
|
||||
tests too.
|
||||
- `script/cibuild`: what CI runs on every push. It runs `script/bootstrap`,
|
||||
`script/check` and the image build.
|
||||
- `script/cibuild`: what CI runs on every push. It runs these three:
|
||||
- `script/bootstrap`
|
||||
- `script/check`
|
||||
- the image build
|
||||
- `script/version`: prints the version to build into the binary.
|
||||
- `script/projectname`: prints the project name, which tags the Docker image.
|
||||
- `script/install-go`: installs the Go version that `go.mod` names into
|
||||
`.tool/go`. It checks the download against a checksum in the script.
|
||||
- `script/install-goreleaser`: installs the pinned `goreleaser` into
|
||||
`.tool/bin`, checked the same way.
|
||||
- `script/install-goreleaser`: installs the pinned
|
||||
[`goreleaser`](https://goreleaser.com/) into `.tool/bin`, checked the same
|
||||
way.
|
||||
- `script/release`: builds and publishes the release files.
|
||||
- `script/release-snapshot`: builds the release files into `./dist` and
|
||||
publishes nothing.
|
||||
@@ -1289,15 +1372,17 @@ skip the tests or the linter and still report success.
|
||||
The test suite has no separate integration target. Every test runs every time.
|
||||
Each test binary is stopped after 90 seconds.
|
||||
|
||||
To change the Go version, change these together: `go.mod`, the version and
|
||||
checksums in `script/install-go`, and the two `golang` image digests in the
|
||||
`Dockerfile`.
|
||||
To change the Go version, change these together:
|
||||
|
||||
- `go.mod`
|
||||
- the version and checksums in `script/install-go`
|
||||
- the two `golang` image digests in the `Dockerfile`
|
||||
|
||||
### Messages to the user
|
||||
|
||||
Status lines, warnings and errors go through `internal/ui`. The data a command
|
||||
exists to print is written plain, with no marker and no color. That covers
|
||||
tables, reports, JSON documents and `config get` values.
|
||||
Write status lines, warnings and errors through `internal/ui`. The data a
|
||||
command exists to print is written plain, with no marker and no color. That
|
||||
covers tables, reports, JSON documents and `config get` values.
|
||||
|
||||
`internal/ui` has these kinds of message:
|
||||
|
||||
@@ -1383,8 +1468,14 @@ version.
|
||||
`make release-snapshot` builds the same files into `./dist` and publishes
|
||||
nothing.
|
||||
|
||||
Each archive holds the binary, `LICENSE` and `README.md`. The release files are
|
||||
not signed, have no SBOM and are not built reproducibly.
|
||||
Each archive holds three files:
|
||||
|
||||
- the binary
|
||||
- `LICENSE`
|
||||
- `README.md`
|
||||
|
||||
The release files are not signed, have no software bill of materials and are
|
||||
not built reproducibly.
|
||||
|
||||
## license
|
||||
|
||||
|
||||
Reference in new issue
Block a user