Documentation
¶
Overview ¶
Package run orchestrates an extraction: temp-dir lifecycle, worker pool, per-(repo, connector) dispatch, manifest assembly, and provenance.
Index ¶
- Variables
- func InterruptSummary(in InterruptSummaryInput) string
- func NewLogger(verbose, quiet bool, extra ...io.Writer) *slog.Logger
- func NewLoggerNoStderr(verbose, quiet bool, writers ...io.Writer) *slog.Logger
- func Summarize(in SummaryInput) string
- type InflightJob
- type InterruptSummaryInput
- type Options
- type PartialFailure
- type Result
- type RunSummary
- type SummaryArtifact
- type SummaryInput
- type SummaryProvenance
Constants ¶
This section is empty.
Variables ¶
var ErrPartial = errors.New("run: one or more connectors or clones reported errors; see manifest")
ErrPartial signals a completed run that produced an artifact but where at least one connector or clone reported an error. The cmd-layer maps this to exit code 2 (artifact present, manifest records the failure); any other non-nil error from Run maps to exit code 3 (fatal).
Functions ¶
func InterruptSummary ¶
func InterruptSummary(in InterruptSummaryInput) string
InterruptSummary formats the stderr block printed on graceful Ctrl-C. Pure: caller is responsible for assembling the input. The exact wording is part of the CLI surface and is asserted in cmd/xray tests.
func NewLogger ¶
NewLogger configures slog for a run. verbose lowers the level to Debug (per-API-call timing), quiet raises it to Error. The default is Info. Logs always go to stderr; tokens are never emitted by any caller in this package and there is no logging code path that accepts tokens. An optional extra writer receives the same output (used for the run log file).
func NewLoggerNoStderr ¶
NewLoggerNoStderr configures slog without writing to stderr. Used by cmd/xray when the TTY status grid owns stdout and stderr lines would visibly leak into the rendered grid; the run log file (or any other passed writers) still captures everything.
func Summarize ¶
func Summarize(in SummaryInput) string
Summarize renders the post-run summary block. Pure: no filesystem, no DB, no network. Caller is responsible for assembling the inputs.
Types ¶
type InflightJob ¶
InflightJob is one (repo, connector) pair that was being extracted when ctx was canceled.
type InterruptSummaryInput ¶
type InterruptSummaryInput struct {
Phase string // "clone", "extract", "postprocess"
Inflight []InflightJob // populated only for the "extract" phase
TempDir string // absolute path; "" if no temp dir was created
Cleaned bool // true when the temp dir was removed (false with --keep-clones)
ExitCode int // 130 for graceful SIGINT
}
InterruptSummaryInput collects what InterruptSummary needs to render the stderr message produced when ctx is canceled mid-run.
type Options ¶
type Options struct {
Out string
Workers int
KeepClones bool
Connectors []connector.Connector
Logger *slog.Logger
ToolVersion string
// Progress is the sink for run-time phase events. Nil resolves to a
// no-op; the CLI selects a TTY grid / line log / NDJSON / no-op sink
// based on the --output mode resolved in cmd/xray/output.go.
Progress progress.Sink
// OnTempDir, if non-nil, is invoked exactly once with the absolute
// path of the per-run temp directory immediately after creation. The
// CLI uses it so the signal handler can name the leaked path in the
// double-Ctrl-C force-exit log line.
OnTempDir func(string)
}
Options configures a single run. Zero values pick spec-mandated defaults (4 workers, ./xray-export-<UTC>.tar.gz output, info-level stderr logger).
type PartialFailure ¶
PartialFailure identifies one (repo, connector) pair that errored during a partial run.
func ExtractPartialFailures ¶
func ExtractPartialFailures(provs []connector.Provenance) []PartialFailure
ExtractPartialFailures walks the manifest's provenance for non-empty Errors maps and returns one PartialFailure per (repo, connector). The reason is the first (sorted) error message — enough for the summary, the full set lives in manifest.json.
type Result ¶
type Result struct {
ArtifactPath string
SHA256 string
Size int64
Duration time.Duration
Manifest manifest.Manifest
// RateLimitWaits and RateLimitWaitSeconds are the cumulative wait
// count and total wait time across every connector's ratelimit
// transport, drained from the progress.RateLimitCounter that the CLI
// tees alongside the user-facing sink. Populated by the cmd layer
// after Run returns (Run itself does not aggregate the counter).
RateLimitWaits int
RateLimitWaitSeconds int
// Interrupted is true iff Run returned because ctx was canceled.
Interrupted bool
InterruptedPhase string // "clone", "extract", "postprocess"
InflightJobs []InflightJob // populated only during "extract" cancel
TempDir string // absolute path; non-empty whenever cleanup ran (or was skipped via KeepClones)
}
Result is everything the CLI needs after a successful (or partial) run to render the post-run summary block (issue #84). ArtifactPath is always set when Run returns either nil or ErrPartial; the other fields are derived from the same data the manifest records.
On graceful interrupt (Run returns context.Canceled), ArtifactPath is "" and the Interrupt* fields are populated so the cmd layer can render the stderr summary.
func Run ¶
Run is the entry point for `xray run`. It clones every repo, dispatches every (repo, connector) pair across the worker pool, assembles the manifest, packages the artifact, and removes the temp dir (unless opts.KeepClones is set).
Returns the absolute path of the produced .tar.gz. Errors are returned only when the run could not produce an artifact at all; per-connector failures are reported in the manifest's extraction_provenance and cause a non-nil error to be returned (so the CLI exits non-zero) while still completing artifact production.
type RunSummary ¶
type RunSummary struct {
Kind string `json:"kind"`
OK bool `json:"ok"`
DurationS int `json:"duration_s"`
Artifact SummaryArtifact `json:"artifact"`
Rows map[string]any `json:"rows"`
Provenance SummaryProvenance `json:"provenance"`
Partial []PartialFailure `json:"partial"`
}
RunSummary is the JSON-shape of the run-summary event emitted in --output json mode. The wire shape is documented in docs/spec.md and versioned independently of the artifact SchemaVersion.
func BuildRunSummary ¶
func BuildRunSummary(in SummaryInput, ok bool) RunSummary
BuildRunSummary assembles the JSON-shape companion to the human summary. ok is false when the run was partial.
type SummaryArtifact ¶
type SummaryArtifact struct {
Path string `json:"path"`
SizeBytes int64 `json:"size_bytes"`
SHA256 string `json:"sha256"`
SchemaVersion int `json:"schema_version"`
LogPath string `json:"log_path,omitempty"`
}
SummaryArtifact mirrors the human-readable Artifact block.
type SummaryInput ¶
type SummaryInput struct {
Manifest manifest.Manifest
ArtifactPath string
SHA256 string
Size int64
Duration time.Duration
LogPath string
PartialFails []PartialFailure
RateLimitWaits int
RateLimitWaitSeconds int
}
SummaryInput is everything Summarize needs. It is a thin pass-through so the caller assembles the inputs once and the renderer stays pure.
type SummaryProvenance ¶
type SummaryProvenance struct {
EndpointsAccessible int `json:"endpoints_accessible"`
EndpointsTotal int `json:"endpoints_total"`
EndpointsInaccessible int `json:"endpoints_inaccessible"`
PerRowErrors int `json:"per_row_errors"`
RateLimitTruncated int `json:"rate_limit_truncated"`
RateLimitWaits int `json:"rate_limit_waits"`
RateLimitWaitSeconds int `json:"rate_limit_wait_seconds"`
PartialPaginations int `json:"partial_paginations"`
}
SummaryProvenance collapses the per-row provenance stream into the aggregate counters the customer sees. RateLimitTruncated counts connectors whose pagination was cut off by the rate-limit budget; RateLimitWaits + RateLimitWaitSeconds come from progress.RateLimitCounter (the CLI tees one alongside the user-facing sink) so the summary reports the actual cumulative wait the customer paid, not just the count of budget-truncated connectors.