cobra

package
v0.1.0-dev.20260203070556 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 3, 2026 License: MIT Imports: 10 Imported by: 0

README

Cobra Extractor

Extracts Starlark binding metadata from Go source files that use spf13/cobra.

Status: Proof of Concept (Working)

Created: 2026-01-11 Last tested: docker-cli v27.4.1 on 2026-01-11

What Works
  • Package discovery and loading via golang.org/x/tools/go/packages
  • AST traversal via golang.org/x/tools/go/ast/inspector
  • Extracts cobra.Command struct literals (Use, Short, Long, Deprecated, Hidden)
  • Extracts flag definitions from flags.StringVarP(), BoolVar(), etc.
  • Type inference from method names (StringSlice → string_list)
  • Function-level scope for command/flag association
  • Qualified command names - Uses package directory for prefixes (container_create, config_create)
Known Limitations

See TODO.md Section 7: Bindgen Tool for tracked issues and roadmap.

Test Results

Source: docker-cli v27.4.1
Location: ~/Workspace/OSS/docker-cli/

Extracted: 144 commands, 272 flags (up from 86/175 before prefix fix)

All 10 "create" commands now captured:
  checkpoint_create, config_create, container_create, context_create,
  manifest_create, network_create, plugin_create, secret_create,
  service_create, volume_create

See TODO.md Section 7 for detailed issue tracking.

Architecture

ExtractDir(dir)
    │
    ├── findPackages(dir)           # Walk tree, collect package patterns
    │
    ├── packages.Load(patterns)     # golang.org/x/tools loads AST
    │
    └── for each package:
            │
            ├── Check imports cobra?
            │
            ├── inspector.New(syntax)   # Efficient AST inspector
            │
            └── inspector.Preorder(FuncDecl):
                    │
                    └── extractFromFunction(fn)
                            │
                            ├── Find &cobra.Command{} literal
                            │   └── Extract Use, Short, Long, etc.
                            │
                            └── Find flags.StringVarP() calls
                                └── Extract name, short, type, default, desc

Usage

cd /path/to/lore  # clone of github.com/NobleFactor/lore

# Extract from docker-cli (requires go.mod symlink, see below)
go run ./cmd/bindgen extract-cobra ~/Workspace/OSS/docker-cli/cli/command/ > docker.yaml

# With verbose output
go run ./cmd/bindgen extract-cobra ~/Workspace/OSS/docker-cli/cli/command/ --verbose
Docker-CLI Setup

Docker-cli uses vendor.mod instead of go.mod. Symlinks were created:

cd ~/Workspace/OSS/docker-cli
ln -sf vendor.mod go.mod
ln -sf vendor.sum go.sum

Files

internal/bindgen/cobra/
├── extractor.go    # Main extraction logic (~430 lines)
└── README.md       # This file

cmd/bindgen/
└── main.go         # CLI with extract-cobra subcommand

Dependencies

import (
    "golang.org/x/tools/go/ast/inspector"  // Efficient AST traversal
    "golang.org/x/tools/go/packages"       // Package loading
)

Added to go.mod:

  • golang.org/x/tools v0.40.0
  • golang.org/x/mod v0.31.0
  • golang.org/x/sync v0.19.0
  • ADR-016 in lore/design/07-lore-design-decisions.md documents:
    • Prior art research on Starlark binding generation
    • Source introspection approach (this extractor)
    • Comparison with --help parsing
    • Stability analysis of CLI APIs

Test Data

  • Source: ~/Workspace/OSS/docker-cli/ (v27.4.1, shallow clone)
  • Output: 144 commands, 272 flags (after prefix fix)

End-to-End Code Generation Analysis

Question: Is binding generation fully automated, or is the extractor output used to bootstrap manual coding?

Answer: The pipeline is fully automated but produces incomplete bindings. Human refinement is required for production use.

Generated Output

Running the full pipeline:

bindgen extract-cobra ~/Workspace/OSS/docker-cli/cli/command/ > docker.yaml
bindgen generate docker.yaml

Produces:

  • command_gen.go — 4,124 lines, 144 commands
  • command_gen.star — IDE stubs (currently broken, template bug)
Generated Code Sample
// containerRun executes command container_run.
// Create and run a new container from an image
func (b *CommandBindings) containerRun(...) (starlark.Value, error) {
    var detach bool
    var name string
    // ... only 6 flags extracted ...

    cmdArgs := []string{"container_run"}  // BUG: should be "container", "run"
    if detach {
        cmdArgs = append(cmdArgs, "--detach")
    }
    return b.runCommand(cmdArgs)
}
Comparison: Generated vs Hand-Written
Metric Hand-written (docker.go) Generated (command_gen.go)
Commands 15 (curated high-value) 144 (all extracted)
Flags per command Complete Partial (~6 of ~100 for run)
Positional args Handled Not generated
Command invocation Correct (docker run) Broken (docker container_run)
Error handling Varies Consistent
Code size 634 lines 4,124 lines
Production ready Yes No
Intended Workflow

The generator is a development accelerator, not a production-ready solution:

┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│ 1. Extract      │ ──▶ │ 2. Generate     │ ──▶ │ 3. Refine       │
│                 │     │                 │     │                 │
│ bindgen extract │     │ bindgen generate│     │ Human review:   │
│ 144 commands    │     │ 4,124 lines Go  │     │ - Fix command   │
│ 272 flags       │     │ (scaffold)      │     │ - Add flags     │
│                 │     │                 │     │ - Add pos args  │
└─────────────────┘     └─────────────────┘     └─────────────────┘

Value proposition:

  • Saves writing boilerplate for 144 commands from scratch
  • Ensures consistent structure
  • Documents all available commands and their descriptions
  • Identifies which flags exist (even if not all captured)
Conclusion

The extractor works. The generator produces scaffolding. Human refinement is required.

See TODO.md Section 7 for known issues and roadmap.

Documentation

Overview

Package cobra extracts command metadata from Go source files using Cobra. Uses golang.org/x/tools for proper package loading and efficient AST traversal.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Extractor

type Extractor struct {
	// contains filtered or unexported fields
}

Extractor parses Go source files to find Cobra command definitions.

func NewExtractor

func NewExtractor(verbose bool) *Extractor

NewExtractor creates a new Cobra extractor.

func (*Extractor) ExtractDir

func (e *Extractor) ExtractDir(dir string) (*bindgen.BindingDef, error)

ExtractDir extracts commands from all Go packages in a directory.

func (*Extractor) Stats

func (e *Extractor) Stats() (commands int, flags int)

Stats returns extraction statistics.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL