monopam: accurate push wrap-up message
Before: when [monopam push] had no subtrees to push but workspace
repos still got pushed, the output contradicted itself --
Nothing to push (all repos in sync)
✓ opam-repo
✓ Changes pushed to your remotes. (3.6s)
"Nothing to push" came from the lib's [run_after_sync], "✓ opam-repo"
came from [workspace_repos] (which still ran), and "Changes pushed"
came from [cmd_push.ml]'s unconditional success message.
Restructure to track what actually got pushed and let the caller
print one accurate summary line.
- New type [Push.outcome = { subtrees : int; workspace : int }]
reporting how many of each kind of repo were pushed (Everything-up-
to-date counts as 0).
- [Push.run] returns [(outcome, error) result] instead of
[(unit, error) result].
- [workspace_repos] returns [(pushed_count * errors)] so the count
threads up. The "Everything up-to-date" branch demoted from
[Log.app] (visible "✓ already synced") to [Log.debug] -- when
nothing changed there's nothing to show.
- [run_after_sync] returns
[Ok { subtrees = 0; workspace = ws }] when subtrees are in sync,
and [Ok { subtrees = N; workspace = ws }] after [export_and_push].
The "Nothing to push (all repos in sync)" Log.app is gone -- the
caller now prints the wrap-up.
- [cmd_push.ml]'s [success_message] picks one of three forms based
on the outcome:
- total = 0: "All repos already in sync."
- local-only with subtree push: "Exported N subtree(s) to checkouts."
- upstream push: "Pushed N subtrees + M workspace repos
to your remotes."
[cmd_publish.ml]'s call to [Push.run] now ignores the outcome
explicitly via [Ok _outcome].