Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zI
github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
Expand Down
268 changes: 268 additions & 0 deletions lint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
#!/usr/bin/env bash

# SPDX-License-Identifier: MIT
# Copyright (c) 2025 IBM

set -e

# Parse command line arguments
SKIP_SECURITY=false
for arg in "$@"; do
case $arg in
--skip-security)
SKIP_SECURITY=true
shift
;;
--help|-h)
echo "Usage: $0 [--skip-security]"
echo " --skip-security Skip security checks (govulncheck, gosec)"
exit 0
;;
esac
done

echo "🔍 Running linter on Maestro MCP Server project..."

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}

print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}

print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}

print_header() {
echo -e "${BLUE}[LINT]${NC} $1"
}

print_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}

# Function to check if command exists
command_exists() {
command -v "$1" >/dev/null 2>&1
}

# Go linting
echo "📁 Checking Go files..."
if command_exists go; then
print_header "Running Go linter..."

# Install golangci-lint if not present
if ! command_exists golangci-lint; then
print_status "Installing golangci-lint..."
if command_exists curl; then
# Use go install to build with current Go version for compatibility
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
else
print_warning "curl not found, please install golangci-lint manually"
print_status "Visit: https://golangci-lint.run/usage/install/"
fi
fi

# Run golangci-lint if available
if command_exists golangci-lint; then
print_status "Running golangci-lint..."
if golangci-lint run --timeout 5m ./src/...; then
print_success "Go linting passed!"
else
print_error "Go linting failed!"
exit 1
fi
else
# Fallback to go vet and go fmt
print_status "Running go vet..."
if go vet ./src/...; then
print_success "go vet passed!"
else
print_error "go vet failed!"
exit 1
fi

print_status "Checking go fmt..."
if [ "$(gofmt -s -l src/)" ]; then
print_warning "Code is not formatted with go fmt!"
print_status "Auto-fixing formatting..."
gofmt -s -w src/
print_success "Code formatting fixed!"
else
print_success "go fmt check passed!"
fi
fi

# Check for common Go issues
print_status "Checking for common Go issues..."

# Check for unused imports
if command_exists goimports; then
print_status "Checking imports..."
if [ "$(goimports -l src/)" ]; then
print_warning "Unused imports found. Run 'goimports -w src/' to fix"
else
print_success "Import check passed!"
fi
fi

# Check for race conditions
print_status "Checking for race conditions..."
if go test -race ./src/... >/dev/null 2>&1; then
print_success "Race condition check passed!"
else
print_warning "Race condition check failed or tests not available"
fi

print_success "Go linting checks passed!"
else
print_error "Go is not installed, skipping Go linting"
exit 1
fi

# JSON linting
echo "📄 Checking JSON files..."
if find . -name "*.json" -not -path "./src/vendor/*" -not -path "./node_modules/*" | grep -q .; then
find . -name "*.json" -not -path "./src/vendor/*" -not -path "./node_modules/*" -print0 | while IFS= read -r -d '' json_file; do
if ! python3 -m json.tool "$json_file" >/dev/null 2>&1; then
print_error "Invalid JSON found in $json_file"
exit 1
fi
done
print_success "JSON files are valid!"
else
echo "ℹ️ No JSON files found to validate"
fi

# YAML linting (excluding GitHub Actions workflows with false positives)
echo "📋 Checking YAML files..."
if find . -name "*.yml" -o -name "*.yaml" | grep -q .; then
if command_exists yamllint; then
# Use .yamllint config file to exclude GitHub Actions workflows with false positives
if yamllint .; then
print_success "YAML linting passed!"
else
print_warning "YAML linting issues found"
fi
else
print_warning "yamllint not found, skipping YAML linting"
print_status "Install yamllint: pip install yamllint"
fi
else
echo "ℹ️ No YAML files found to lint"
fi

# Markdown linting (excluding docs directory with extended formats)
echo "📝 Checking Markdown files..."
if find . -name "*.md" -not -path "./src/vendor/*" -not -path "./node_modules/*" -not -path "./docs/*" | grep -q .; then
if command_exists markdownlint; then
if npx markdownlint "**/*.md" --ignore node_modules --ignore src/vendor --ignore docs; then
print_success "Markdown linting passed!"
else
print_warning "Markdown linting issues found"
fi
else
print_warning "markdownlint not found, skipping Markdown linting"
print_status "Install markdownlint: npm install -g markdownlint-cli"
fi
else
echo "ℹ️ No Markdown files found to lint (excluding docs directory with extended formats)"
fi

# Shell script linting
echo "🐚 Checking shell scripts..."
if find . -name "*.sh" | grep -q .; then
if command_exists shellcheck; then
find . -name "*.sh" -print0 | while IFS= read -r -d '' sh_file; do
if shellcheck "$sh_file"; then
print_success "Shell script $sh_file passed!"
else
print_error "Shell script $sh_file has issues"
exit 1
fi
done
else
print_warning "shellcheck not found, skipping shell script linting"
print_status "Install shellcheck: brew install shellcheck (macOS) or apt-get install shellcheck (Ubuntu)"
fi
else
echo "ℹ️ No shell scripts found to lint"
fi

# Security checks (optional)
if [ "$SKIP_SECURITY" = true ]; then
echo "🔒 Skipping security checks (--skip-security flag used)"
else
echo "🔒 Running security checks..."
if command_exists govulncheck; then
print_status "Running govulncheck vulnerability scanner..."
if govulncheck ./src/...; then
print_success "Vulnerability scan passed!"
else
print_warning "Vulnerabilities found"
fi
else
print_status "govulncheck not available - using go mod audit as alternative"
if go list -json -m all | grep -q '"Indirect":true'; then
print_status "Checking for known vulnerabilities in dependencies..."
if go mod audit; then
print_success "Dependency audit passed!"
else
print_warning "Potential dependency issues found"
fi
else
print_status "No indirect dependencies to audit"
fi
fi

# Additional security checks with gosec if available
if command_exists gosec; then
print_status "Running gosec security scanner..."
if gosec ./src/...; then
print_success "Security scan passed!"
else
print_warning "Security issues found"
fi
else
print_status "gosec not available - using go vet as security alternative"
print_status "Running go vet for basic security checks..."
if go vet -unsafeptr=false ./src/...; then
print_success "Basic security checks passed!"
else
print_warning "Basic security checks found issues"
fi
fi
fi

# Dependency checks
echo "📦 Checking dependencies..."
if command_exists go; then
print_status "Checking for outdated dependencies..."
if command_exists go-mod-outdated; then
if go-mod-outdated -update -direct; then
print_success "Dependencies are up to date!"
else
print_warning "Some dependencies may be outdated"
fi
else
print_status "Checking go.mod..."
if go mod verify; then
print_success "Dependencies verified!"
else
print_error "Dependency verification failed!"
exit 1
fi
fi
fi

print_success "All code quality checks completed successfully!"
echo "🎯 Linting completed successfully!"
12 changes: 6 additions & 6 deletions src/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import (
"fmt"

"github.com/spf13/cobra"
"maestro/internal/common"
"maestro/internal/commands"
"maestro/internal/common"
)

// VDB Commands
Expand Down Expand Up @@ -402,13 +402,13 @@ var deprecatedCreateCmd = &cobra.Command{
Short: "*** Deprecated *** Create",
Long: `*** Deprecated *** Create: Use agent or tool create.`,
Aliases: []string{"create"},
Args: cobra.ExactArgs(1),
Args: cobra.ExactArgs(1),
Example: ` maestro agent/tool create yaml_file.`,
RunE: func(cmd *cobra.Command, args []string) error {
fmt.Println("***Deprecated Create: Use agent or tool create.***")
defs, _ := common.ParseYAML(args[0])
fmt.Println(defs[0]["kind"])
if defs[0]["kind"] == "Agent" || defs[0]["kind"] == "MCPTool"{
if defs[0]["kind"] == "Agent" || defs[0]["kind"] == "MCPTool" {
options := commands.NewCommandOptions(cmd)
return commands.DeprecatedCreateCommand(args[0], options)
}
Expand All @@ -422,7 +422,7 @@ var deprecatedCreateCrCmd = &cobra.Command{
Short: "*** Deprecated *** Create-cr",
Long: `*** Deprecated *** Create-cr: Use curomresource create yaml_file.`,
Aliases: []string{"create"},
Args: cobra.ExactArgs(1),
Args: cobra.ExactArgs(1),
Example: ` maestro agent/tool create-cr yaml_file.`,
RunE: func(cmd *cobra.Command, args []string) error {
fmt.Println("***Deprecated Create: Use agent or tool create.***")
Expand Down Expand Up @@ -451,7 +451,7 @@ var deprecatedDeployCmd = &cobra.Command{
Short: "*** Deprecated *** Deploy",
Long: `*** Deprecated *** Deploy: Use workflow deploy.`,
Aliases: []string{"deploy"},
Args: cobra.MinimumNArgs(2),
Args: cobra.MinimumNArgs(2),
Example: ` maestro deploy agentyaml_file workflowyaml_file.`,
RunE: func(cmd *cobra.Command, args []string) error {
fmt.Println("***Deprecated Deploy: Use workflow deploy.***")
Expand All @@ -466,7 +466,7 @@ var deprecatedServeCmd = &cobra.Command{
Short: "*** Deprecated *** Serve",
Long: `*** Deprecated *** : Use workflow/agent serve.`,
Aliases: []string{"serve"},
Args: cobra.ExactArgs(1),
Args: cobra.ExactArgs(1),
Example: ` maestro serve agentyaml_file.`,
RunE: func(cmd *cobra.Command, args []string) error {
fmt.Println("***Deprecated Serve: Use workflow serve.***")
Expand Down
2 changes: 1 addition & 1 deletion test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ if [ "$RUN_UNIT_TESTS" = true ]; then
# Run specific test files if they exist
if [ -f "tests/main_test.go" ]; then
print_status "Running main tests..."
go test -v tests/main_test.go tests/validate_test.go tests/create_test.go tests/delete_test.go tests/list_test.go
go test -v tests/main_test.go tests/test_utils.go tests/validate_test.go tests/create_test.go tests/delete_test.go tests/list_test.go
fi

print_status "✓ Unit tests completed successfully!"
Expand Down
Loading
Loading