Files
wehub-resource-sync f99010fae1
Desktop Artifacts / Desktop Build (Linux) (push) Waiting to run
Desktop Artifacts / Desktop Build (Windows) (push) Waiting to run
Desktop Artifacts / Desktop Build (Linux (arm64)) (push) Waiting to run
Desktop Artifacts (macOS) / Desktop Build (macOS (aarch64)) (push) Waiting to run
Desktop Artifacts (macOS) / Desktop Build (macOS (x86_64)) (push) Waiting to run
CI / lint (push) Failing after 1s
CI / frontend (push) Failing after 1s
CI / scripts (push) Failing after 1s
CI / Go Test (ubuntu-latest) (push) Failing after 0s
CI / frontend-node-25 (push) Failing after 1s
CI / docs (push) Failing after 0s
CI / coverage (push) Failing after 0s
CI / e2e (push) Failing after 0s
Docker / build-and-push (push) Failing after 1s
CI / integration (push) Failing after 4m43s
CI / Go Test (windows-latest) (push) Has been cancelled
CI / Desktop Unit Tests (Windows) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:30:36 +08:00

138 lines
4.7 KiB
Go

package parser
import "context"
// source_set.go provides the generic plumbing shared by every reusable
// source-set base. A SourceSet owns source resolution and parsing for one
// provider; SourceSetProvider wraps any SourceSet into a full Provider, and
// SourceSetFactory builds those providers from an AgentDef + Capabilities + a
// per-config constructor.
//
// The point is that a base such as multiSessionContainerSourceSet (or
// singleFileSourceSet) implements SourceSet once and reuses this factory and
// this delegating provider, instead of each base re-hand-rolling the
// Definition/Capabilities/NewProvider factory and the six forwarding provider
// methods. Provider-level concerns that every provider shares -- folding the
// raw session ID into FindSource requests, and the request/config machine
// fallback for Parse -- live here so the SourceSet implementations stay focused
// on agent-specific source logic.
// MaterializedFileSource is the Opaque payload for a session whose bytes were
// materialized to a local file outside any configured root -- an S3 object
// fetched to a temp dir. A source set resolves it straight to its Path, so
// provider.Parse can parse the file without re-deriving identity from a
// configured-root layout (the materialized path may not match the provider's
// on-disk convention). The caller supplies the project via SourceRef.ProjectHint
// and applies any source-identity rewrite to the parsed results.
type MaterializedFileSource struct {
Path string
}
// SourceSet is the source-resolution and parse core that a Provider delegates
// to. It is the Provider interface minus the Definition/Capabilities/config
// plumbing (supplied by SourceSetProvider) and minus ParseIncremental (which
// falls through to the ProviderBase "unsupported" default until a base needs
// it).
type SourceSet interface {
Discover(context.Context) ([]SourceRef, error)
WatchPlan(context.Context) (WatchPlan, error)
SourcesForChangedPath(
context.Context, ChangedPathRequest,
) ([]SourceRef, error)
FindSource(context.Context, FindSourceRequest) (SourceRef, bool, error)
Fingerprint(context.Context, SourceRef) (SourceFingerprint, error)
Parse(context.Context, ParseRequest) (ParseOutcome, error)
}
// SourceSetProvider adapts a SourceSet to the Provider interface. It supplies
// the AgentDef/Capabilities/config carried by ProviderBase, forwards the source
// methods to the SourceSet, and applies the two provider-level normalizations
// every provider performs: raw-session-ID injection on FindSource and the
// machine fallback on Parse. ParseIncremental is inherited from ProviderBase
// (unsupported) until a base opts in.
type SourceSetProvider struct {
ProviderBase
sources SourceSet
}
func (p *SourceSetProvider) Discover(ctx context.Context) ([]SourceRef, error) {
return p.sources.Discover(ctx)
}
func (p *SourceSetProvider) WatchPlan(ctx context.Context) (WatchPlan, error) {
return p.sources.WatchPlan(ctx)
}
func (p *SourceSetProvider) SourcesForChangedPath(
ctx context.Context,
req ChangedPathRequest,
) ([]SourceRef, error) {
return p.sources.SourcesForChangedPath(ctx, req)
}
func (p *SourceSetProvider) FindSource(
ctx context.Context,
req FindSourceRequest,
) (SourceRef, bool, error) {
return p.sources.FindSource(
ctx, ProviderFindRequestWithRawSessionID(p.Def, req),
)
}
func (p *SourceSetProvider) Fingerprint(
ctx context.Context,
source SourceRef,
) (SourceFingerprint, error) {
return p.sources.Fingerprint(ctx, source)
}
func (p *SourceSetProvider) Parse(
ctx context.Context,
req ParseRequest,
) (ParseOutcome, error) {
req.Machine = firstNonEmptyJSONLString(req.Machine, p.Config.Machine)
return p.sources.Parse(ctx, req)
}
// SourceSetFactory is the generic ProviderFactory for any SourceSet-backed
// provider. build constructs the SourceSet from the cloned per-provider config
// (roots, machine, path rewriter), so a base captures whatever config it needs
// in a closure rather than threading it through a struct.
type SourceSetFactory struct {
def AgentDef
caps Capabilities
build func(cfg ProviderConfig) SourceSet
}
func NewSourceSetFactory(
def AgentDef,
caps Capabilities,
build func(cfg ProviderConfig) SourceSet,
) ProviderFactory {
return SourceSetFactory{
def: cloneAgentDef(def),
caps: caps,
build: build,
}
}
func (f SourceSetFactory) Definition() AgentDef {
return cloneAgentDef(f.def)
}
func (f SourceSetFactory) Capabilities() Capabilities {
return f.caps
}
func (f SourceSetFactory) NewProvider(cfg ProviderConfig) Provider {
cfg = cfg.Clone()
return &SourceSetProvider{
ProviderBase: ProviderBase{
Def: cloneAgentDef(f.def),
Caps: f.caps,
Config: cfg,
},
sources: f.build(cfg),
}
}