Skip to content

Creating Custom Commands

Status: Placeholder - Content coming soon

Prerequisites: Your First Module, Go programming knowledge

Planned Content

This tutorial teaches you how to extend the r2r CLI with custom commands, integrate with MCP servers, and automate project-specific workflows.

What You'll Learn

  • Understand the r2r CLI extension architecture
  • Create custom commands in Go
  • Register commands with the CLI
  • Access repository contracts and configuration
  • Implement command logic and validation
  • Write tests for custom commands
  • Package commands as extensions
  • Integrate with MCP protocol

Tutorial Structure

  1. Understanding CLI architecture
  2. Command structure and registration
  3. Extension points and hooks
  4. Command context and dependencies
  5. Configuration and contracts access

  6. Creating your first command

  7. Command structure (Cobra-based)
  8. Implement run-checks command
  9. Parse flags and arguments
  10. Access repository configuration

  11. Implementing command logic

  12. Read module contracts
  13. Execute validations
  14. Format output (table, JSON, markdown)
  15. Handle errors gracefully

  16. Testing custom commands

  17. Unit tests for command logic
  18. Integration tests with real contracts
  19. Mock dependencies
  20. Test command output

  21. Advanced command patterns

  22. Commands with subcommands
  23. Interactive commands (prompts)
  24. Long-running operations
  25. Progress reporting

  26. Packaging as extension

  27. Extension metadata
  28. Distribution (binary, source, container)
  29. Installation and discovery
  30. Versioning extensions

  31. MCP server integration

  32. Implement MCP protocol
  33. Expose commands via MCP
  34. Tool definitions and schemas
  35. Connect to Claude Code / IDEs

Example: Custom run-checks Command

The tutorial creates a custom command for pre-deployment checks:

Command usage:

r2r run-checks --module api-gateway --env production

Implementation structure:

go/eac-extensions/
├── commands/
│   └── checks/
│       ├── run_checks.go       # Command implementation
│       ├── run_checks_test.go  # Unit tests
│       └── validators.go       # Check logic
├── main.go                     # Extension entry point
└── go.mod

Command implementation:

package checks

import (
    "github.com/spf13/cobra"
    "github.com/ready-to-release/eac/pkg/contracts"
)

func NewRunChecksCommand() *cobra.Command {
    cmd := &cobra.Command{
        Use:   "run-checks",
        Short: "Run pre-deployment checks",
        RunE:  runChecks,
    }

    cmd.Flags().String("module", "", "Module to check")
    cmd.Flags().String("env", "", "Target environment")

    return cmd
}

func runChecks(cmd *cobra.Command, args []string) error {
    module := cmd.Flag("module").Value.String()
    env := cmd.Flag("env").Value.String()

    // Load contracts
    repo, err := contracts.LoadRepository()
    if err != nil {
        return err
    }

    // Run checks
    checks := []Check{
        CheckTestsPassing(module),
        CheckArtifactsExist(module),
        CheckSecurityScans(module),
        CheckEnvironmentReady(env),
    }

    // Execute and report
    results := ExecuteChecks(checks)
    PrintResults(results)

    return nil
}

Key Concepts Covered

  • Cobra command framework
  • r2r contract system
  • Command registration and discovery
  • Testing CLI commands
  • Extension packaging
  • MCP protocol integration

Command Development Workflow

  1. Design command interface
  2. Define command name and flags
  3. Plan command output
  4. Consider error cases

  5. Implement command logic

  6. Create command struct
  7. Implement RunE function
  8. Access contracts and config

  9. Write tests

  10. Unit test command logic
  11. Integration test with real data
  12. Test error handling

  13. Register command

  14. Add to extension registry
  15. Build and install extension

  16. Document command

  17. Add help text
  18. Create usage examples
  19. Document in reference section

Testing Custom Commands

func TestRunChecks(t *testing.T) {
    tests := []struct {
        name    string
        module  string
        env     string
        wantErr bool
    }{
        {
            name:    "valid module and env",
            module:  "api-gateway",
            env:     "staging",
            wantErr: false,
        },
        {
            name:    "invalid module",
            module:  "nonexistent",
            env:     "staging",
            wantErr: true,
        },
    }

    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            cmd := NewRunChecksCommand()
            cmd.SetArgs([]string{
                "--module", tt.module,
                "--env", tt.env,
            })

            err := cmd.Execute()
            if (err != nil) != tt.wantErr {
                t.Errorf("want error %v, got %v", tt.wantErr, err)
            }
        })
    }
}

MCP Integration

Expose custom commands via MCP server:

// Implement MCP protocol
type CommandsMCPServer struct {
    commands []*cobra.Command
}

func (s *CommandsMCPServer) ListTools() []Tool {
    tools := []Tool{}
    for _, cmd := range s.commands {
        tools = append(tools, Tool{
            Name:        cmd.Use,
            Description: cmd.Short,
            Schema:      generateSchema(cmd),
        })
    }
    return tools
}

func (s *CommandsMCPServer) ExecuteTool(name string, args map[string]interface{}) (string, error) {
    cmd := findCommand(s.commands, name)
    return executeCommand(cmd, args)
}

Use Cases for Custom Commands

  • Project-specific workflows: r2r deploy-to-k8s
  • Quality checks: r2r run-checks
  • Report generation: r2r generate-compliance-report
  • Integration with tools: r2r sync-jira
  • Automation: r2r batch-update-deps

Best Practices

  • Follow Cobra conventions
  • Provide comprehensive help text
  • Validate inputs early
  • Use structured output (JSON, table)
  • Write tests for all commands
  • Document in reference section
  • Version extensions semantically
  • Handle errors gracefully

Distribution Options

  1. Source code: Users build locally
  2. Binary: Pre-built for platforms
  3. Container: Docker image
  4. Plugin: Dynamic loading

Next Steps

After completing this tutorial, you've mastered advanced r2r CLI practices. Explore Specialized Topics for deep dives into BDD techniques, architecture documentation, and security scanning.


Tutorials | How-to Guides | Explanation | Reference

You are here: Tutorials — learning-oriented guides that take you through steps to complete a project.