diff --git a/README.md b/README.md index d8382eb..e1e9494 100644 --- a/README.md +++ b/README.md @@ -105,15 +105,19 @@ cd ~/Documents/da-cli ./install.sh # copies da + the dacli package to ~/.local/share/da-cli/ and symlinks ~/.local/bin/da → that copy ``` -**Option B — pip install.** Not available: **da-cli is not published to -PyPI**, and the name is currently unregistered. Use Option A. +**Option B — pip install.** Not published yet. Use Option A for now. -Do not `pip install da-cli` on the strength of this README. Until the name -appears here as published, anything under it on PyPI is not this project — -and since this package installs a `da` command onto your `PATH` and handles -DeviantArt OAuth tokens, installing an impostor is not a harmless mistake. +When it is published the distribution will be named **`da-sync`**, not +`da-cli`: -Note also that `dacli` (no hyphen) on PyPI is an unrelated project. +```bash +pipx install da-sync # the command is still `da` +``` + +Two names on PyPI are close to this project and are **not** it: `dacli` +(an unrelated data-engineering tool) and `da-cli` (unregistered). Since +this package installs a `da` command onto your `PATH` and handles +DeviantArt OAuth tokens, check the name before installing anything. Python 3.10+ required (uses `argparse.BooleanOptionalAction` and `X | None` syntax). No third-party runtime dependencies. diff --git a/pyproject.toml b/pyproject.toml index b0a0ad4..e94caa9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,11 @@ [project] -name = "da-cli" +# The PyPI distribution name. NOT the import name (that is `dacli`) and +# not the command (that is `da`). It is `da-sync` rather than `da-cli` +# because PyPI refuses `da-cli` as too similar to the unrelated `dacli` +# project — the two differ only by a separator, which is precisely what +# its typosquat guard exists to catch. Note the name being free is not +# sufficient: `da-cli` returns 404 and is still rejected. +name = "da-sync" description = "Sync DeviantArt galleries to local folders — zero-dependency Python CLI with OAuth 2.1 PKCE, a SQLite index, and scheduled macOS syncs." readme = "README.md" license = "MIT" @@ -68,7 +74,7 @@ Issues = "https://github.com/FZ2000/da-cli/issues" Changelog = "https://github.com/FZ2000/da-cli/blob/main/CHANGELOG.md" Documentation = "https://github.com/FZ2000/da-cli#readme" -# `pip install da-cli` exposes a `da` script on PATH. This is the +# `pip install da-sync` exposes a `da` script on PATH. This is the # pip-installable counterpart of the `da` shim in the repo root; the # shim still exists for the git-clone-and-symlink install path # (see install.sh) used in the README. diff --git a/tools/check_version_sync.py b/tools/check_version_sync.py index 51ee29f..92273d7 100644 --- a/tools/check_version_sync.py +++ b/tools/check_version_sync.py @@ -85,9 +85,10 @@ def problems() -> list[str]: f"docs/reference/cli.md says version {found.group(1)}; run tools/gen_cli_docs.py" ) - # Any other file quoting a DIFFERENT release version in prose. Scoped to - # `da-cli ` and `v` so it cannot trip on the pinned versions - # of third-party tools, which are unrelated and legitimately differ. + # Any other file quoting a DIFFERENT release version in prose. Matches + # both names this project answers to — `da-cli` is the HTTP User-Agent + # and the repo, `da-sync` is the PyPI distribution — and nothing else, + # so it cannot trip on the pinned versions of third-party tools. tracked = subprocess.run( ["git", "-C", str(REPO), "ls-files"], capture_output=True, text=True, check=False ).stdout.split() @@ -109,7 +110,7 @@ def problems() -> list[str]: for i, line in enumerate(body.splitlines(), 1): out.extend( f"{rel}:{i}: quotes da-cli {other}, but the package is {VERSION}" - for other in re.findall(r"\bda-cli[ /]v?(\d+\.\d+\.\d+)\b", line) + for other in re.findall(r"\b(?:da-cli|da-sync)[ /]v?(\d+\.\d+\.\d+)\b", line) if other != VERSION ) return out