Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,23 @@ that disagrees with it, and PyPI therefore always matches the tag.

- README documents the real `pipx install da-sync` path now that 0.1.0 is
published, replacing the placeholder that said it was unavailable.
- The getting-started guide now offers the PyPI install as well. It had
only ever documented `git clone` + `./install.sh`, so the tutorial a new
user is pointed at was the one place that never mentioned the published
package.
- `install_schedule.sh` ships in the repository but not in the wheel, so
the scheduling guide and the tutorial's scheduling step now say where to
get it rather than assuming a checkout. Its "not found on PATH" error
names both install paths instead of only `./install.sh`.

### Fixed

- The getting-started transcript of `./install.sh` omitted the
`(N modules)` suffix the script actually prints. `check_doc_references`
now asserts any documented module count against `dacli/`, so the number
cannot drift again — `docs/commands/` examples are executed by
`tests/test_docs_examples.py`, but `getting-started.md` is not, which is
how this survived.

## 0.1.0 — 2026-07-30

Expand Down
52 changes: 49 additions & 3 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,41 @@ Check again with `python3 --version` to confirm it's 3.10 or higher.

---

## Step 2: Download and install da-cli
## Step 2: Install da-cli

In your Terminal, run these three commands one at a time:
There are two ways. Read both first — they suit different people.

### Option A — install from PyPI (simplest)

The package is published under the name **`da-sync`**, and the command it
installs is called `da`. In your Terminal:

```bash
pipx install da-sync
```

If you don't have `pipx`, `python3 -m pip install --user da-sync` also
works. `pipx` is worth the extra step, because it gives the tool its own
private environment instead of mixing it into your system Python.

Check that it worked:

```bash
da --version
```

```text
da-cli 0.1.0
```

### Option B — clone the repository

Pick this one if you also want the optional macOS scheduling script from
[Daily automatic downloads](#optional-daily-automatic-downloads-macos)
below. That script lives in the repository and is **not** part of the
PyPI package, so Option A cannot give it to you.

Run these three commands one at a time:

```bash
git clone https://github.com/FZ2000/da-cli.git ~/da-cli
Expand All @@ -70,12 +102,15 @@ You should see output like:
```text
installed:
~/.local/share/da-cli/da
~/.local/share/da-cli/dacli/
~/.local/share/da-cli/dacli/ (17 modules)
~/.local/bin/da -> ~/.local/share/da-cli/da

da-cli 0.1.0
```

The module count reflects however many files the package currently has,
so don't worry if it isn't exactly 17.

**If you see a version number** — installation worked. Move to Step 3.

**If you see "da: command not found"** — your system doesn't know
Expand Down Expand Up @@ -351,6 +386,17 @@ da diagnose # health check (config, auth, disk space)

Want art downloaded automatically every day at 3 AM?

This step uses `install_schedule.sh`, which ships in the repository but
not in the PyPI package. If you installed with Option A, get it first:

```bash
git clone https://github.com/FZ2000/da-cli.git ~/da-cli
cd ~/da-cli
```

If you installed with Option B you are already in that directory. Either
way, then run:

```bash
./install_schedule.sh
```
Expand Down
12 changes: 12 additions & 0 deletions docs/guides/scheduling.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,18 @@ watched artists posted.

## macOS

`install_schedule.sh` is part of the repository, not of the `da-sync`
package on PyPI. If you installed with `pipx`, clone the repository to
get it — the script drives whatever `da` is already on your `PATH`, so
you do not need to reinstall:

```bash
git clone https://github.com/FZ2000/da-cli.git ~/da-cli
cd ~/da-cli
```

Then, from that directory:

```bash
./install_schedule.sh # daily at 03:00
./install_schedule.sh uninstall # remove it
Expand Down
3 changes: 2 additions & 1 deletion install_schedule.sh
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ fi

DA_BIN="$(command -v da || true)"
if [[ -z "$DA_BIN" ]]; then
echo "error: 'da' not found on PATH. Run ./install.sh first." >&2
echo "error: 'da' not found on PATH. Install it first — either" >&2
echo " './install.sh' from this repository, or 'pipx install da-sync'." >&2
exit 1
fi

Expand Down
32 changes: 31 additions & 1 deletion tools/check_doc_references.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,38 @@ def _source_text() -> str:
return "\n".join(parts)


def _check_module_count(problems: list[tuple[str, str, int, str]]) -> int:
"""`install.sh` prints a live module count; the docs quote a number.

A quoted count is a claim about the package, and it went stale the
moment it was written: the getting-started transcript omitted the
`(N modules)` suffix entirely while `install.sh` had been printing it
for some time. Nothing noticed, because prose is not executed.
"""
real = sum(1 for _ in (REPO / "dacli").rglob("*.py"))
found = 0
for doc in sorted(REPO.rglob("*.md")):
rel = str(doc.relative_to(REPO))
if any(x in rel for x in SKIP_DIRS):
continue
for lineno, line in enumerate(doc.read_text().splitlines(), 1):
m = re.search(r"\((\d+) modules\)", line)
if not m:
continue
found += 1
if int(m.group(1)) != real:
problems.append(
("module count is stale", rel, lineno, f"says {m.group(1)}, dacli/ has {real}")
)
return found


def main() -> int:
paths, by_name = _repo_files()
commands, flags = _cli_surface()
source = _source_text()
problems: list[tuple[str, str, int, str]] = []
module_counts = _check_module_count(problems)

checked = 0
for doc in sorted(REPO.rglob("*.md")):
Expand Down Expand Up @@ -199,7 +226,10 @@ def main() -> int:
# `checked`, not a fresh rglob: the summary must describe the files this
# run actually looked at, or a skipped tree inflates the number and the
# message quietly overstates the coverage.
print(f"all code references in {checked} markdown files resolve")
print(
f"all code references in {checked} markdown files resolve "
f"({module_counts} module-count claim(s) match dacli/)"
)
return 0


Expand Down
Loading