Files
crawlab/cli/cmd/proto.go
2024-11-20 15:47:30 +08:00

100 lines
2.2 KiB
Go

package cmd
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"
"github.com/spf13/cobra"
)
var protoCmd = &cobra.Command{
Use: "proto",
Short: "Compile proto files to Python pb files",
Run: runProto,
}
var (
protoDir string
outputDir string
)
func init() {
protoCmd.Flags().StringVarP(&protoDir, "proto-dir", "p", "grpc/proto", "Directory containing proto files")
protoCmd.Flags().StringVarP(&outputDir, "output-dir", "o", "python/crawlab/grpc", "Output directory for Python pb files")
RootCmd.AddCommand(protoCmd)
}
func runProto(cmd *cobra.Command, args []string) {
// Ensure protoc is installed
if _, err := exec.LookPath("protoc"); err != nil {
fmt.Println("Error: protoc is not installed. Please install Protocol Buffers compiler first.")
os.Exit(1)
}
// Create output directory if it doesn't exist
if err := os.MkdirAll(outputDir, 0755); err != nil {
fmt.Printf("Error creating output directory: %v\n", err)
os.Exit(1)
}
// Find all proto files
protoFiles, err := filepath.Glob(filepath.Join(protoDir, "**/*.proto"))
if err != nil {
fmt.Printf("Error finding proto files: %v\n", err)
os.Exit(1)
}
for _, protoFile := range protoFiles {
relPath, _ := filepath.Rel(protoDir, protoFile)
fmt.Printf("Compiling: %s\n", relPath)
args := []string{
"--proto_path=" + protoDir,
"--python_out=" + outputDir,
"--grpc_python_out=" + outputDir,
protoFile,
}
cmd := exec.Command("protoc", args...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
fmt.Printf("Error compiling %s: %v\n", relPath, err)
os.Exit(1)
}
// Fix Python imports
fixPythonImports(outputDir)
}
fmt.Println("Successfully compiled all proto files to Python")
}
func fixPythonImports(dir string) error {
pbFiles, err := filepath.Glob(filepath.Join(dir, "**/*_pb2*.py"))
if err != nil {
return err
}
for _, file := range pbFiles {
content, err := os.ReadFile(file)
if err != nil {
return err
}
// Replace import statements
newContent := strings.ReplaceAll(string(content),
"from grpc.proto",
"from crawlab.grpc")
if err := os.WriteFile(file, []byte(newContent), 0644); err != nil {
return err
}
}
return nil
}