Skip to content

feat(shared): appkit metric sync CLI#459

Draft
atilafassina wants to merge 1 commit into
mainfrom
mv-cli
Draft

feat(shared): appkit metric sync CLI#459
atilafassina wants to merge 1 commit into
mainfrom
mv-cli

Conversation

@atilafassina

Copy link
Copy Markdown
Contributor

Summary

PR4 of the metric-views decomposition: a focused appkit metric sync CLI that runs the metric-view schema-fetch + type-emission outside the Vite dev loop — for CI, non-Vite builds, and manual refresh after pulling a teammate's metric-views.json.

Design — reuse via dynamic import (not reimplementation)

The CLI lives in shared and reaches appkit's metric-sync core via dynamic import("@databricks/appkit/type-generator") — the same pattern generate-types uses — backed by an ambient declaration and a graceful appkit-absent fallback, so shared keeps no static dependency on appkit.

A new appkit syncMetricTypes export runs readMetricConfig → resolveMetricConfig → syncMetrics → write metric.d.ts + metrics.metadata.json, reusing the existing metric writers, the adaptive DESCRIBE fetcher, and the post-#433 persistent cache helpers (loadCache / saveCache / metricCacheHash). Because it is the same code path, the emitted bundle is structurally identical to the Vite plugin output. It deliberately does not generate query types or route through generateFromEntryPoint.

Behaviour

  • Validation against metricSourceSchema (post-chore: Metric Views typegen #433 UC FQN grammar) before any sync, with issues formatted as path: message.
  • Exit-code taxonomy — an absent default config/queries/metric-views.json exits 0 (dormancy invariant); explicit-missing-path / JSON-parse / schema-validation / missing-FQN / unreachable-warehouse / auth each exit non-zero with a distinct message.
  • Interactive vs non-interactive — no flags → @clack/prompts flow (mirrors plugin create); any flag → non-interactive (detected via getOptionValueSource() === "cli").
  • Flags--warehouse-id (+ DATABRICKS_WAREHOUSE_ID fallback), --metric-views-json-path, --output-dir, --no-cache (→ cache: false: ignore + overwrite the metric cache).

Chain position

Fourth change in the metric-views decomposition, after #427 / #429 / #433. It is the second producer of shared/appkit-types/metrics.metadata.json (the Vite typegen path is the other); PR2 — next in the merge order — runtime-consumes that bundle, so its closed-mode validation now reviews against two real producers rather than synthetic fixtures.

Scope

9 files, +1943 / −0. Confined to packages/appkit/src/type-generator/** (the metric-only export + tests) and packages/shared/src/cli/commands/metric/** (+ the ambient decl and the cli/index.ts registration). No schemas/**, docs/static/schemas/, or dependency changes — the metric.jsonmetric-views.json doc-fix already landed in #433.

Tests

  • appkit syncMetricTypes — mock-fetcher unit tests (mixed SP/OBO fixtures, cache hit/miss, --no-cache re-describe).
  • shared CLI — 40 tests: validation accept/reject across the UC FQN grammar, the full exit-code taxonomy, interactive + non-interactive flows, and --no-cache propagation.
  • Full gate green: pnpm build && pnpm docs:build, pnpm check:fix && pnpm -r typecheck, pnpm test.

Opened as a draft pending review.


This pull request and its description were written by Isaac.


This PR was created with GitHub MCP.

@github-actions

Copy link
Copy Markdown
Contributor

🔬  Run evals on this PR  ·  Go to Evals Monitor →

@atilafassina atilafassina force-pushed the mv-cli branch 3 times, most recently from 5865783 to b0ca822 Compare June 23, 2026 10:01
Adds an appkit mv sync command that fetches Unity Catalog metric-view schemas
and emits metric.d.ts plus metrics.metadata.json outside the Vite dev loop (CI,
non-Vite builds, manual refresh). The command lives in shared and reaches
appkit's sync core via dynamic import of the type-generator entry with an
ambient declaration and a graceful appkit-absent fallback, so shared keeps no
static appkit dependency. A new appkit syncMetricViewsTypes export reuses the
existing metric writers, adaptive describe fetcher and persistent cache helpers,
so the emitted bundle matches the Vite plugin output. Config is validated
against metricSourceSchema before sync, an absent default file exits zero for
dormancy while error modes exit non-zero with distinct messages, and
interactive and non-interactive flows mirror plugin create. Flags are
--warehouse-id, --metric-views-json-path, --output-dir and --no-cache. Fourth
change in the metric-views decomposition after #427, #429 and #433.

Co-authored-by: Isaac
Signed-off-by: Atila Fassina <atila@fassina.eu>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant