semver-sync 0.1.1

Keep one version across every crate in a cargo workspace; bumps are checked as docker tags before any manifest is written.
# semver-sync

One version for every crate in a cargo workspace, moved by one command. These
versions become docker tags, so they are checked as tags before anything is
written.

## Install

```sh
cargo install semver-sync
```

From a checkout:

```sh
cargo install --path .
```

## Use

```sh
semver-sync alias   # install the shorter `ss`, then: source ~/.zshrc
ss                  # what every crate is at
ss patch            # 0.1.0 -> 0.1.1
ss minor            # 0.1.0 -> 0.2.0
ss major            # 0.1.0 -> 1.0.0
ss tag rc           # 0.1.0 -> 0.1.0-rc.0, then rc.1, rc.2 on the same tag
ss set 1.4.0-rc.0   # one exact version
ss update           # reinstall this tool from crates.io, cargo decides if it is newer
ss version          # the version of semver-sync itself
```

Run it from anywhere inside the workspace; the workspace is found through
cargo. Every command that writes takes `--dry-run`, which prints what would
move and then checks the manifests were left alone:

```sh
ss patch --dry-run
```

## What a write touches

- `[package] version` and `[workspace.package] version` in every manifest that
  holds one, including a workspace root that is a package itself.
- `version = "..."` pins on dependencies that point at another member of the
  workspace by path — the pins that stop cargo resolving when only the package
  versions move. Pins on crates.io dependencies are left alone.
- `Cargo.lock`, by asking cargo to resolve the workspace again once the
  manifests are written. If it does not resolve, the manifests are already on
  disk: `git diff -- '*Cargo.toml'` says what moved.

Crates that inherit `version.workspace = true` need nothing of their own; cargo
reports the version they resolve to, and that is what `ss` lists.

A level bump ignores a tag on the way: `1.2.3-rc.4` with `ss patch` gives
`1.2.4`. `ss tag rc` keeps the core version and starts a series — `1.2.3` gives
`1.2.3-rc.0`, and the same command again gives `1.2.3-rc.1`. A different tag
starts its own series: `1.2.3-hotfix.0`.

A version has to survive as a docker tag: start with a letter or a digit, then
`A-Z a-z 0-9 . _ -`, with no `..`. That rules out build metadata such as
`1.2.3+g1a2b`.

## Completions

```sh
ss completions zsh > ~/.zfunc/_semver-sync
compdef _semver-sync ss    # the script binds `semver-sync`; this binds the alias
```

## Development

```sh
cargo test
cargo clippy --all-targets -- -D warnings
cargo fmt --check
```