pluginctl/CLAUDE.md
Felipe Martin fd6e4a4513
Initial implementation of pluginctl CLI tool
- Add comprehensive info command with plugin manifest parsing -
Implement global --plugin-path flag and PLUGINCTL_PLUGIN_PATH env var -
Add full test suite with fixtures for various plugin configurations -
Set up build system with Makefile, goreleaser, and golangci-lint -
Include development tools with pinned versions for reproducible builds

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-08 14:30:09 +02:00

8.7 KiB

pluginctl - Mattermost Plugin Development CLI

Project Overview

pluginctl is a command-line interface tool for Mattermost plugin development. It provides utilities to manage, inspect, and work with Mattermost plugins from the command line.

Architecture Guidelines

Project Structure

pluginctl/
├── cmd/pluginctl/main.go      # CLI entrypoint with command routing
├── plugin.go                  # Plugin manifest handling utilities
├── info.go                    # Info command implementation
├── [command].go               # Additional command implementations
├── go.mod                     # Go module definition
├── go.sum                     # Go module dependencies
├── pluginctl                  # Built binary (gitignored)
└── CLAUDE.md                  # This architecture document

Design Principles

1. Separation of Concerns

  • CLI Framework: cmd/pluginctl/main.go handles argument parsing, command routing, and error handling
  • Command Implementation: Each command gets its own file (e.g., info.go, build.go, deploy.go)
  • Utility Functions: Common plugin operations in plugin.go

2. Plugin Manifest Handling

  • Always use official Mattermost types: Import github.com/mattermost/mattermost/server/public/model and use model.Manifest
  • Validation: Always validate plugin.json existence and format before operations
  • Path handling: Support both current directory and custom path operations

3. Command Structure

  • Main command router: Add new commands to the runCommand() function in main.go
  • Command functions: Name pattern: run[Command]Command(args []string) error
  • Error handling: Return descriptive errors, let main.go handle exit codes

4. Code Organization

  • No inline implementations: Keep command logic in separate files
  • Reusable utilities: Common operations go in plugin.go
  • Self-contained: Each command file should be importable and testable

Current Commands

info

  • Purpose: Display plugin manifest information
  • Implementation: info.go
  • Usage: pluginctl info
  • Features:
    • Shows plugin ID, name, version
    • Displays minimum Mattermost version
    • Indicates server/webapp code presence
    • Shows settings schema availability
  • Path Resolution: Uses global path logic (--plugin-path flag, environment variable, or current directory)

Adding New Commands

Step 1: Create Command File

Create a new file named [command].go with the command implementation:

package main

import (
    "fmt"
    "github.com/mattermost/mattermost/server/public/model"
)

func run[Command]Command(args []string, pluginPath string) error {
    // Command implementation here
    // Use pluginPath to load plugin manifest
    return nil
}

Step 2: Register in Main Router

Add the command to the runCommand() function in cmd/pluginctl/main.go:

func runCommand(command string, args []string, pluginPath string) error {
    switch command {
    case "info":
        return runInfoCommand(args, pluginPath)
    case "new-command":
        return runNewCommandCommand(args, pluginPath)
    // ... other commands
    }
}

Step 3: Update Help Text

Add the command to the showUsage() function in main.go.

Dependencies

Core Dependencies

  • github.com/mattermost/mattermost/server/public/model - Official Mattermost plugin types
  • Standard Go library for CLI operations

Dependency Management

  • Use go mod tidy to manage dependencies
  • Prefer standard library over external packages when possible
  • Only add dependencies that provide significant value

Build System and Development Tools

Tool Versions

The project uses pinned versions for reproducible builds:

  • golangci-lint: v1.62.2
  • goreleaser: v2.6.2
  • gosec: v2.22.0
  • Go: 1.24.3

Makefile Targets

Development Workflow:

  • make dev - Quick development build (fmt, lint, build)
  • make check-changes - Check changes (lint, security, test)
  • make verify - Full verification (clean, lint, test, build)

Building:

  • make build - Build binary for current platform
  • make build-all - Build for all supported platforms
  • make install - Install binary to GOPATH/bin

Testing and Quality:

  • make test - Run tests
  • make test-coverage - Run tests with coverage report
  • make lint - Run linter
  • make lint-fix - Fix linting issues automatically
  • make security - Run security scan with gosec

Development Setup:

  • make dev-setup - Install all development tools with pinned versions
  • make deps - Install/update dependencies
  • make fmt - Format code

Release Management:

  • make release - Create production release (requires goreleaser)
  • make snapshot - Create snapshot release for testing

Utilities:

  • make clean - Clean build artifacts
  • make version - Show version and tool information
  • make help - Show all available targets

Configuration Files

Makefile

  • Uses go get -tool for Go 1.24+ tool management
  • Cross-platform build support (Linux, macOS, Windows)
  • Git-based version information in binaries

.goreleaser.yml

  • Multi-platform release automation
  • GitHub releases with changelog generation
  • Package manager integration (Homebrew, Scoop)
  • Docker image building support

.golangci.yml

  • 40+ enabled linters for comprehensive code quality
  • Optimized for Go 1.24
  • Security scanning integration
  • Test file exclusions for appropriate linters

Development Workflow

  1. Setup: make dev-setup (one-time)
  2. Development: make dev (format, lint, build)
  3. Before commit: make check-changes (lint, security, test)
  4. Full verification: make verify (complete build verification)

Building

# Quick build
make build

# Cross-platform builds
make build-all

# Development build with checks
make dev

Testing

  • Always test with a sample plugin.json file
  • Test both current directory and custom path operations
  • Verify help and version commands work correctly
  • Use make test-coverage for coverage reports

Error Handling Standards

Error Messages

  • Use descriptive error messages that help users understand what went wrong
  • Include file paths in error messages when relevant
  • Wrap errors with context using fmt.Errorf("operation failed: %w", err)

Exit Codes

  • 0: Success
  • 1: General error
  • Let main.go handle all exit codes - command functions should return errors

Plugin Path Resolution

Priority Order

  1. Command-line flag: --plugin-path /path/to/plugin
  2. Environment variable: PLUGINCTL_PLUGIN_PATH=/path/to/plugin
  3. Current directory: Default fallback

Implementation

  • getEffectivePluginPath(flagPath string) string - Determines effective plugin path
  • All commands receive the resolved plugin path as a parameter
  • Path is resolved to absolute path before use

Plugin Validation

Required Checks

  • Plugin.json file must exist
  • Plugin.json must be valid JSON
  • Plugin.json must conform to Mattermost manifest schema

Utility Functions (plugin.go)

  • LoadPluginManifest() - Load from current directory
  • LoadPluginManifestFromPath(path) - Load from specific path
  • HasServerCode(manifest) - Check for server-side code
  • HasWebappCode(manifest) - Check for webapp code
  • IsValidPluginDirectory() - Validate current directory

Future Command Ideas

  • init - Initialize a new plugin project
  • build - Build plugin for distribution
  • deploy - Deploy plugin to Mattermost instance
  • validate - Validate plugin structure and manifest
  • package - Package plugin for distribution
  • test - Run plugin tests

Version Management

  • Current version: 0.1.0
  • Update version in main.go when releasing
  • Follow semantic versioning

Documentation Maintenance

  • CRITICAL: Always keep README.md up to date with any changes
  • When adding new commands, update both CLAUDE.md and README.md
  • When changing build processes, update both architecture docs and user docs
  • When adding new dependencies or tools, document them in both files
  • README.md is the user-facing documentation - it must be comprehensive and current

Notes for Claude Sessions

  • Always maintain the separation between CLI framework and command implementation
  • Use the official Mattermost model types - never create custom manifest structs
  • Keep command implementations in separate files for maintainability
  • Always validate plugin.json before performing operations
  • Test new commands with the sample plugin.json file
  • Follow the established error handling patterns
  • Use the build system: make check-changes before any commits
  • Use pinned tool versions for reproducible development environments