< Summary - Repometa Coverage

Information
Class: Manifest
Assembly: repometa
File(s): /home/runner/work/repometa/repometa/manifest.go
Line coverage
100%
Covered lines: 14
Uncovered lines: 0
Coverable lines: 14
Total lines: 215
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
Languages0%00100%
Polyglot0%00100%

File(s)

/home/runner/work/repometa/repometa/manifest.go

#LineLine coverage
 1package repometa
 2
 3import "slices"
 4
 5// Manifest is the result of scanning a repository. Consumers iterate
 6// [Manifest.Components]; the ordering is deterministic (by root path,
 7// then by kind) so serialized output is diff-friendly.
 8type Manifest struct {
 9  // Root is the absolute path that was scanned. All [Component.Root]
 10  // and [Evidence.Path] values in this manifest are relative to Root.
 11  Root string
 12
 13  // Components lists every buildable unit detected under Root. May be
 14  // empty if the scan encountered no known ecosystem manifests.
 15  Components []Component
 16
 17  // Stats reports counters from the walk. Non-zero cap-hit fields
 18  // indicate the scan was truncated and may be incomplete.
 19  Stats ScanStats
 20}
 21
 22// Kind identifies the type of a [Component]. Values are open-ended
 23// strings so new detectors can be added without breaking consumers on
 24// enum drift; unknown values are safe to log or ignore.
 25type Kind string
 26
 27// Kind values for every ecosystem detector shipped in this package. See
 28// the README's "Supported detectors" table for the mapping to ecosystem.
 29const (
 30  KindGoModule       Kind = "go-module"
 31  KindRustCrate      Kind = "rust-crate"
 32  KindRustWorkspace  Kind = "rust-workspace"
 33  KindPythonPackage  Kind = "python-package"
 34  KindNodePackage    Kind = "node-package"
 35  KindDotNetProject  Kind = "dotnet-project"
 36  KindDotNetSolution Kind = "dotnet-solution"
 37  KindCppProject     Kind = "cpp-project"
 38  KindJavaProject    Kind = "java-project"
 39  KindCMakeProject   Kind = "cmake-project"
 40  KindMakeProject    Kind = "make-project"
 41  KindCSource        Kind = "c-source-tree"
 42  KindAsmSource      Kind = "asm-source-tree"
 43)
 44
 45// Component describes a single buildable unit inside the repo, anchored
 46// at a specific directory. A directory may produce multiple Components
 47// when more than one ecosystem's manifest is present (e.g. a Rust crate
 48// with a co-located Node package).
 49type Component struct {
 50  // Kind identifies the ecosystem and shape of the component.
 51  Kind Kind
 52
 53  // Root is the path relative to [Manifest.Root]; "." for the repo root.
 54  Root string
 55
 56  // Evidence lists the files that led to this component being reported.
 57  Evidence []Evidence
 58
 59  // Confidence is in [0.0, 1.0]; heuristic hits report < 1.0, and
 60  // manifest-driven detections report 1.0.
 61  Confidence float64
 62
 63  // Workspaces lists any monorepo layouts anchored at this component.
 64  Workspaces []Workspace
 65
 66  // Attributes carries ecosystem-specific metadata. Keys are namespaced
 67  // (e.g. "js.framework", "python.pm"). See the README for the current
 68  // set; unknown keys are safe to ignore.
 69  Attributes map[string]string
 70}
 71
 72// Evidence records a single fact that led to a [Component] being
 73// reported. Path is relative to [Manifest.Root] so evidence remains
 74// meaningful when the manifest is transported.
 75type Evidence struct {
 76  // Path is relative to [Manifest.Root]; forward slashes on every
 77  // platform.
 78  Path string
 79
 80  // Reason is a short human-readable description of why this file
 81  // counts as evidence (e.g. "go.mod present", "workspace = [...]").
 82  Reason string
 83}
 84
 85// Workspace describes a monorepo layout anchored at a [Component].
 86// Members may be empty when the workspace kind was detected by file
 87// presence alone rather than by parsing an explicit member list.
 88type Workspace struct {
 89  // Kind identifies the monorepo tooling.
 90  Kind WorkspaceKind
 91
 92  // Members lists the workspace's constituent package paths, relative
 93  // to [Manifest.Root], forward-slash separated.
 94  Members []string
 95}
 96
 97// WorkspaceKind identifies the workspace / monorepo tooling in use. Like
 98// [Kind], values are open-ended strings — unknown values are safe to
 99// log or ignore.
 100type WorkspaceKind string
 101
 102// WorkspaceKind values for every workspace layout recognized by the
 103// detectors in this package.
 104const (
 105  WorkspaceGo                 WorkspaceKind = "go-workspace"
 106  WorkspaceCargo              WorkspaceKind = "cargo-workspace"
 107  WorkspaceNpmYarn            WorkspaceKind = "npm-yarn-workspace"
 108  WorkspacePnpm               WorkspaceKind = "pnpm-workspace"
 109  WorkspaceNx                 WorkspaceKind = "nx"
 110  WorkspaceTurborepo          WorkspaceKind = "turborepo"
 111  WorkspaceUv                 WorkspaceKind = "uv-workspace"
 112  WorkspaceDotNetSolution     WorkspaceKind = "dotnet-solution"
 113  WorkspaceMavenMultiModule   WorkspaceKind = "maven-multi-module"
 114  WorkspaceGradleMultiProject WorkspaceKind = "gradle-multi-project"
 115)
 116
 117// Language is a coarse ecosystem label derived from a [Component.Kind].
 118// Multiple Kinds may map to the same Language: [KindRustCrate] and
 119// [KindRustWorkspace] both report [LanguageRust]; [KindCMakeProject],
 120// [KindMakeProject], and [KindCSource] all report [LanguageC];
 121// [KindDotNetProject] and [KindDotNetSolution] both report
 122// [LanguageDotNet]. This grouping is used by the helpers on [Manifest]
 123// to distinguish single-language repositories from polyglot ones —
 124// treat Component.Kind as the source of truth for finer-grained work.
 125type Language string
 126
 127// Language values. LanguageUnknown is used when a Component.Kind is not
 128// in the mapping table (added by a future detector; safely reported
 129// rather than dropped).
 130const (
 131  LanguageGo         Language = "go"
 132  LanguageRust       Language = "rust"
 133  LanguagePython     Language = "python"
 134  LanguageJavaScript Language = "javascript"
 135  LanguageDotNet     Language = "dotnet"
 136  LanguageJava       Language = "java"
 137  LanguageC          Language = "c"
 138  LanguageAssembly   Language = "assembly"
 139  LanguageUnknown    Language = "unknown"
 140)
 141
 142// Language returns the coarse ecosystem label for this Component. See
 143// [Language] for the mapping and rationale; unrecognized kinds return
 144// [LanguageUnknown].
 145func (c Component) Language() Language {
 146  switch c.Kind {
 147  case KindGoModule:
 148    return LanguageGo
 149  case KindRustCrate, KindRustWorkspace:
 150    return LanguageRust
 151  case KindPythonPackage:
 152    return LanguagePython
 153  case KindNodePackage:
 154    return LanguageJavaScript
 155  case KindDotNetProject, KindDotNetSolution:
 156    return LanguageDotNet
 157  case KindJavaProject:
 158    return LanguageJava
 159  case KindCMakeProject, KindMakeProject, KindCppProject, KindCSource:
 160    return LanguageC
 161  case KindAsmSource:
 162    return LanguageAssembly
 163  }
 164  return LanguageUnknown
 165}
 166
 167// Languages returns the sorted, de-duplicated list of [Language] values
 168// present across every [Component] in the manifest. A manifest with no
 169// components returns an empty slice.
 16170func (m *Manifest) Languages() []Language {
 16171  seen := make(map[Language]struct{}, len(m.Components))
 16172  for _, c := range m.Components {
 44173    seen[c.Language()] = struct{}{}
 44174  }
 16175  out := make([]Language, 0, len(seen))
 16176  for l := range seen {
 32177    out = append(out, l)
 32178  }
 16179  slices.Sort(out)
 16180  return out
 181}
 182
 183// Polyglot reports whether the manifest contains components spanning
 184// more than one [Language]. A manifest with zero components, or with
 185// components in a single Language, returns false. [LanguageUnknown]
 186// counts as its own language, so a repo mixing a known ecosystem with
 187// one repometa doesn't yet recognize is reported as polyglot.
 8188func (m *Manifest) Polyglot() bool {
 8189  return len(m.Languages()) > 1
 8190}
 191
 192// ScanStats reports counters from the walk. Non-zero DepthCapHits or
 193// DirCapHits indicate the scan was truncated by [WithMaxDepth] or
 194// [WithMaxDirs] respectively — callers should widen the cap and rescan
 195// if a complete manifest is required.
 196type ScanStats struct {
 197  // DirsVisited is the total number of directories entered by the walk.
 198  DirsVisited int
 199
 200  // FilesSeen is the total number of file entries observed (whether or
 201  // not their contents were read).
 202  FilesSeen int
 203
 204  // DepthCapHits counts the number of directories the walk refused to
 205  // descend into because the [WithMaxDepth] cap was reached.
 206  DepthCapHits int
 207
 208  // DirCapHits is 1 if the [WithMaxDirs] cap fired and aborted the walk;
 209  // 0 otherwise.
 210  DirCapHits int
 211
 212  // SymlinksSkipped counts the number of symlink entries skipped —
 213  // symlinks are never traversed regardless of target.
 214  SymlinksSkipped int
 215}

Methods/Properties

Languages
Polyglot