mirror of
https://github.com/kuhyx/diet-guard.git
synced 2026-11-10 20:27:11 +01:00
Every install mints a uuid and pushes under it, and nothing ever cleans those directories up. This remote holds 25: two live devices and 23 that stopped writing. Each dead one still costs a round trip in the log pull and in each of the three bank syncs -- roughly 400ms per peer per tick -- so they dominate what is left of the background tick. Diagnosis first, since the obvious theory was wrong. These are not the residue of phone reinstalls: seventeen of them are frozen at the *same* instant (2026-08-13T16:45:04) holding near-identical ~400-record copies of one log, which is the signature of repeated fresh-install runs, not organic use. That also means `adb install -r` preserving SharedPreferences was never the issue, so no Android backup change is warranted on this evidence. Dry-run by default, and the safety rails are the point: * `plan_prune` only reads; it is what the default run prints. * A device is prunable only when every record it holds is already held by a device being kept. Against the live remote that is 20 devices and **zero** records lost -- verified before writing the command, not after. * `pc`/`phone`/`desktop` are never proposed: they carry pre-migration history and `SYNC_LEGACY_DEVICE_ID` still names one as this device's own former path. * `--apply` refuses without `--backup-dir`, and every peer's raw bytes are written to disk before a single delete. Nothing has been deleted; this commit only adds the tool. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LJ5YnA3CERitQ57HjMu2Qz
103 lines
3.2 KiB
Python
103 lines
3.2 KiB
Python
"""Argument parsing for the diet_guard CLI.
|
|
|
|
Split out of :mod:`diet_guard._cli` to hold the repo's 250-line cap. This is
|
|
the declarative half -- every subcommand and flag the CLI accepts -- kept apart
|
|
from the handlers that act on them, so adding a flag never grows a file that
|
|
also contains logic.
|
|
|
|
Subparsers owned by a sibling handler register themselves through their own
|
|
module (``register_averages_subparser``, ``register_sync_subparser``) rather
|
|
than being spelled out here, so a subcommand's flags live next to its code.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
|
|
from diet_guard._cli_averages import register_averages_subparser
|
|
from diet_guard._cli_prune import register_prune_subparser
|
|
from diet_guard._cli_sync import register_sync_subparser
|
|
|
|
|
|
def parse_args(argv: list[str]) -> argparse.Namespace:
|
|
"""Parse diet_guard CLI arguments."""
|
|
parser = argparse.ArgumentParser(
|
|
prog="diet_guard",
|
|
description="Log calories and check your daily budget.",
|
|
)
|
|
sub = parser.add_subparsers(dest="command", required=True)
|
|
|
|
sub.add_parser(
|
|
"init",
|
|
help="Compute your starting daily budget from biometrics.",
|
|
)
|
|
|
|
ate = sub.add_parser("ate", help="Log a meal you just ate.")
|
|
ate.add_argument("description", help='What you ate, e.g. "big mac".')
|
|
ate.add_argument(
|
|
"--grams",
|
|
type=float,
|
|
default=None,
|
|
help="Portion size in grams (default: OFF serving size, else 100 g).",
|
|
)
|
|
ate.add_argument(
|
|
"--kcal",
|
|
type=float,
|
|
default=None,
|
|
help="Calories entered manually; skips the food bank and OFF lookup.",
|
|
)
|
|
ate.add_argument(
|
|
"--protein",
|
|
type=float,
|
|
default=None,
|
|
help="Protein in grams (recorded with --kcal to seed the food bank).",
|
|
)
|
|
ate.add_argument(
|
|
"--carbs",
|
|
type=float,
|
|
default=None,
|
|
help="Carbohydrate in grams (recorded with --kcal).",
|
|
)
|
|
ate.add_argument(
|
|
"--fat",
|
|
type=float,
|
|
default=None,
|
|
help="Fat in grams (recorded with --kcal).",
|
|
)
|
|
ate.add_argument(
|
|
"--per",
|
|
type=float,
|
|
default=None,
|
|
help="Grams the macros are stated for (e.g. 100 for a per-100 g label);"
|
|
" the typed macros are scaled from this to how much you ate.",
|
|
)
|
|
ate.add_argument(
|
|
"--count",
|
|
type=float,
|
|
default=None,
|
|
help="Number of items eaten (e.g. 5 apples) instead of --grams;"
|
|
" multiplied by the staple's unit weight.",
|
|
)
|
|
|
|
sub.add_parser("status", help="Show today's calories and budget band.")
|
|
sub.add_parser("undo", help="Remove today's most recent entry.")
|
|
register_averages_subparser(sub)
|
|
register_prune_subparser(sub)
|
|
register_sync_subparser(sub)
|
|
|
|
gate = sub.add_parser(
|
|
"gate",
|
|
help="Log-to-unlock screen gate (intended to be run by a timer).",
|
|
)
|
|
gate.add_argument(
|
|
"--check",
|
|
action="store_true",
|
|
help="Headless: exit 0 if NOT due, 1 if a lock is due. Prints, no window.",
|
|
)
|
|
gate.add_argument(
|
|
"--demo",
|
|
action="store_true",
|
|
help="Show the lock in safe demo mode (local grab + close button).",
|
|
)
|
|
return parser.parse_args(argv)
|