diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index d252793..a9095d2 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,8 +1,8 @@ -# GitHub Copilot Instructions: etcd_fdw Single Package Architecture +# GitHub Copilot Instructions: pg_etcd Single Package Architecture ## Project Context -**Tool**: etcd_fdw - Bidirectional synchronization between etcd and PostgreSQL +**Tool**: pg_etcd - Bidirectional synchronization between etcd and PostgreSQL **Language**: Go 1.25 **Architecture**: Single package consolidation (refactoring from separate internal/etcd and internal/db packages) **Database**: PostgreSQL with single `etcd` table using revision status encoding diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9a58c67..8bb9d8c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -33,7 +33,7 @@ jobs: cache-dependency-path: 'go.sum' - name: Build - run: go build ./cmd/etcd_fdw + run: go build ./cmd/pg_etcd - name: GolangCI-Lint uses: golangci/golangci-lint-action@v8 diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 2926869..1ca2eb5 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -1,7 +1,7 @@ version: 2 builds: -- main: ./cmd/etcd_fdw +- main: ./cmd/pg_etcd env: - CGO_ENABLED=0 goos: diff --git a/Makefile b/Makefile index 0258122..586b7f9 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,9 @@ -# etcd_fdw Makefile +# pg_etcd Makefile .PHONY: build test lint clean install help # Build variables -BINARY_NAME=etcd_fdw +BINARY_NAME=pg_etcd VERSION?=dev BUILD_DIR=. LDFLAGS=-ldflags="-X main.version=$(VERSION)" @@ -15,7 +15,7 @@ LDFLAGS=-ldflags="-X main.version=$(VERSION)" build: @echo "Building $(BINARY_NAME)..." @mkdir -p $(BUILD_DIR) - @go build $(LDFLAGS) -o $(BUILD_DIR)/$(BINARY_NAME) ./cmd/etcd_fdw + @go build $(LDFLAGS) -o $(BUILD_DIR)/$(BINARY_NAME) ./cmd/pg_etcd ## Run tests test: @@ -51,11 +51,11 @@ check: test lint build-all: @echo "Building for multiple platforms..." @mkdir -p $(BUILD_DIR) - @GOOS=linux GOARCH=amd64 go build $(LDFLAGS) -o $(BUILD_DIR)/$(BINARY_NAME)-linux-amd64 ./cmd/etcd_fdw - @GOOS=linux GOARCH=arm64 go build $(LDFLAGS) -o $(BUILD_DIR)/$(BINARY_NAME)-linux-arm64 ./cmd/etcd_fdw - @GOOS=darwin GOARCH=amd64 go build $(LDFLAGS) -o $(BUILD_DIR)/$(BINARY_NAME)-darwin-amd64 ./cmd/etcd_fdw - @GOOS=darwin GOARCH=arm64 go build $(LDFLAGS) -o $(BUILD_DIR)/$(BINARY_NAME)-darwin-arm64 ./cmd/etcd_fdw - @GOOS=windows GOARCH=amd64 go build $(LDFLAGS) -o $(BUILD_DIR)/$(BINARY_NAME)-windows-amd64.exe ./cmd/etcd_fdw + @GOOS=linux GOARCH=amd64 go build $(LDFLAGS) -o $(BUILD_DIR)/$(BINARY_NAME)-linux-amd64 ./cmd/pg_etcd + @GOOS=linux GOARCH=arm64 go build $(LDFLAGS) -o $(BUILD_DIR)/$(BINARY_NAME)-linux-arm64 ./cmd/pg_etcd + @GOOS=darwin GOARCH=amd64 go build $(LDFLAGS) -o $(BUILD_DIR)/$(BINARY_NAME)-darwin-amd64 ./cmd/pg_etcd + @GOOS=darwin GOARCH=arm64 go build $(LDFLAGS) -o $(BUILD_DIR)/$(BINARY_NAME)-darwin-arm64 ./cmd/pg_etcd + @GOOS=windows GOARCH=amd64 go build $(LDFLAGS) -o $(BUILD_DIR)/$(BINARY_NAME)-windows-amd64.exe ./cmd/pg_etcd ## Run the binary (requires PostgreSQL and etcd) run: build diff --git a/README.md b/README.md index 796c7a4..0b3f3cb 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ [![Coverage Status](https://coveralls.io/repos/github/cybertec-postgresql/etcd_fdw/badge.svg)](https://coveralls.io/github/cybertec-postgresql/etcd_fdw) -# etcd_fdw - Bidirectional Synchronization +# pg_etcd - Bidirectional Synchronization ## Overview -etcd_fdw provides bidirectional synchronization between etcd and PostgreSQL using a single table architecture with revision status encoding. +pg_etcd provides bidirectional synchronization between etcd and PostgreSQL using a single table architecture with revision status encoding. ## Architecture @@ -15,15 +15,15 @@ etcd_fdw provides bidirectional synchronization between etcd and PostgreSQL usin ## Installation ```bash -go install github.com/cybertec-postgresql/etcd_fdw/cmd/etcd_fdw@latest +go install github.com/cybertec-postgresql/pg_etcd/cmd/pg_etcd@latest ``` ## Usage ```bash # Basic usage -etcd_fdw --postgres-dsn="postgres://user:pass@localhost/db" --etcd-dsn="etcd://localhost:2379/prefix" +pg_etcd --postgres-dsn="postgres://user:pass@localhost/db" --etcd-dsn="etcd://localhost:2379/prefix" # With custom polling interval -etcd_fdw --postgres-dsn="..." --etcd-dsn="..." --polling-interval=2s +pg_etcd --postgres-dsn="..." --etcd-dsn="..." --polling-interval=2s ``` diff --git a/cmd/etcd_fdw/cli_test.go b/cmd/pg_etcd/cli_test.go similarity index 91% rename from cmd/etcd_fdw/cli_test.go rename to cmd/pg_etcd/cli_test.go index 942ef0f..64682cc 100644 --- a/cmd/etcd_fdw/cli_test.go +++ b/cmd/pg_etcd/cli_test.go @@ -1,4 +1,4 @@ -// Package main provides CLI testing for etcd_fdw command-line interface. +// Package main provides CLI testing for pg_etcd command-line interface. package main import ( @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/require" ) -// TestCLIParsing tests DSN parsing and flag validation for etcd_fdw CLI +// TestCLIParsing tests DSN parsing and flag validation for pg_etcd CLI // This test MUST FAIL until CLI implementation is complete (TDD approach) func TestCLIParsing(t *testing.T) { tests := []struct { @@ -124,8 +124,8 @@ func TestCLIParsing(t *testing.T) { // TestCLIEnvironmentVariables tests that CLI can read from environment variables func TestCLIEnvironmentVariables(t *testing.T) { // Set environment variables - t.Setenv("ETCD_FDW_POSTGRES_DSN", "postgres://env:pass@localhost:5432/envdb") - t.Setenv("ETCD_FDW_ETCD_DSN", "etcd://localhost:2379,localhost:2380/") + t.Setenv("pg_etcd_POSTGRES_DSN", "postgres://env:pass@localhost:5432/envdb") + t.Setenv("pg_etcd_ETCD_DSN", "etcd://localhost:2379,localhost:2380/") // This will fail because ParseCLI function doesn't exist yet config, err := ParseCLI([]string{}) @@ -139,8 +139,8 @@ func TestCLIEnvironmentVariables(t *testing.T) { // TestCLIFlagPrecedence tests that command-line flags override environment variables func TestCLIFlagPrecedence(t *testing.T) { // Set environment variables - t.Setenv("ETCD_FDW_POSTGRES_DSN", "postgres://env:pass@localhost:5432/envdb") - t.Setenv("ETCD_FDW_ETCD_DSN", "etcd://localhost:2379/") + t.Setenv("pg_etcd_POSTGRES_DSN", "postgres://env:pass@localhost:5432/envdb") + t.Setenv("pg_etcd_ETCD_DSN", "etcd://localhost:2379/") // Command-line flags should override environment args := []string{ diff --git a/cmd/etcd_fdw/main.go b/cmd/pg_etcd/main.go similarity index 76% rename from cmd/etcd_fdw/main.go rename to cmd/pg_etcd/main.go index 6a7c9de..056e99c 100644 --- a/cmd/etcd_fdw/main.go +++ b/cmd/pg_etcd/main.go @@ -1,4 +1,4 @@ -// Package main implements the etcd_fdw binary for bidirectional synchronization +// Package main implements the pg_etcd binary for bidirectional synchronization // between etcd and PostgreSQL. package main @@ -13,18 +13,17 @@ import ( "github.com/jessevdk/go-flags" "github.com/sirupsen/logrus" - "github.com/cybertec-postgresql/etcd_fdw/internal/log" - "github.com/cybertec-postgresql/etcd_fdw/internal/sync" + "github.com/cybertec-postgresql/pg_etcd/internal/log" + "github.com/cybertec-postgresql/pg_etcd/internal/sync" ) // Config holds the application configuration type Config struct { - PostgresDSN string `short:"p" env:"ETCD_FDW_POSTGRES_DSN" long:"postgres-dsn" description:"PostgreSQL connection string"` - EtcdDSN string `short:"e" env:"ETCD_FDW_ETCD_DSN" long:"etcd-dsn" description:"etcd connection string"` - LogLevel string `short:"l" env:"ETCD_FDW_LOG_LEVEL" long:"log-level" description:"Log level: debug|info|warn|error" default:"info"` + PostgresDSN string `short:"p" env:"pg_etcd_POSTGRES_DSN" long:"postgres-dsn" description:"PostgreSQL connection string"` + EtcdDSN string `short:"e" env:"pg_etcd_ETCD_DSN" long:"etcd-dsn" description:"etcd connection string"` + LogLevel string `short:"l" env:"pg_etcd_LOG_LEVEL" long:"log-level" description:"Log level: debug|info|warn|error" default:"info"` PollingInterval string `long:"polling-interval" description:"Polling interval for PostgreSQL to etcd sync" default:"1s"` Version bool `short:"v" long:"version" description:"Show version information"` - Help bool } var ( @@ -36,27 +35,20 @@ var ( // ParseCLI parses command-line arguments and returns the configuration func ParseCLI(args []string) (cmdOpts *Config, err error) { cmdOpts = new(Config) - parser := flags.NewParser(cmdOpts, flags.HelpFlag) - parser.SubcommandsOptional = true // if not command specified, start monitoring - nonParsedArgs, err := parser.ParseArgs(args) // parse and execute subcommand if any + parser := flags.NewParser(cmdOpts, flags.Default) + _, err = parser.ParseArgs(args) // parse and execute subcommand if any if err != nil { - if flagsErr, ok := err.(*flags.Error); ok && flagsErr.Type == flags.ErrHelp { - cmdOpts.Help = true - } if !flags.WroteHelp(err) { parser.WriteHelp(os.Stdout) } return cmdOpts, err } - if len(nonParsedArgs) > 0 { // we don't expect any non-parsed arguments - return cmdOpts, fmt.Errorf("unknown argument(s): %v", nonParsedArgs) - } return } // ShowVersion prints version information and exits func ShowVersion() { - fmt.Printf("etcd_fdw version %s\n", version) + fmt.Printf("pg_etcd version %s\n", version) if commit != "none" && commit != "" { fmt.Printf("commit: %s\n", commit) } @@ -85,7 +77,7 @@ func SetupLogging(logLevel string) error { "version": version, "commit": commit, "pid": os.Getpid(), - }).Info("etcd_fdw logging initialized") + }).Info("pg_etcd logging initialized") return nil } diff --git a/go.mod b/go.mod index 0a9d10f..13b4b6a 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/cybertec-postgresql/etcd_fdw +module github.com/cybertec-postgresql/pg_etcd go 1.25 diff --git a/internal/migrations/migrations.go b/internal/migrations/migrations.go index 72e61ea..f1c71fb 100644 --- a/internal/migrations/migrations.go +++ b/internal/migrations/migrations.go @@ -1,4 +1,4 @@ -// Package migrations contains database migration definitions and functionality for etcd_fdw. +// Package migrations contains database migration definitions and functionality for pg_etcd. package migrations import ( @@ -47,7 +47,7 @@ func getMigrator() (*migrator.Migrator, error) { once.Do(func() { migratorInstance, err = migrator.New( migrations(), - migrator.TableName("etcd_fdw_migrations"), + migrator.TableName("pg_etcd_migrations"), ) }) return migratorInstance, err diff --git a/internal/migrations/migrations_test.go b/internal/migrations/migrations_test.go index 86ecd8c..686cf4c 100644 --- a/internal/migrations/migrations_test.go +++ b/internal/migrations/migrations_test.go @@ -1,4 +1,4 @@ -// Package migrations provides migration testing for etcd_fdw database migrations. +// Package migrations provides migration testing for pg_etcd database migrations. package migrations import ( diff --git a/internal/sync/postgresql.go b/internal/sync/postgresql.go index abf8230..55c9b18 100644 --- a/internal/sync/postgresql.go +++ b/internal/sync/postgresql.go @@ -10,7 +10,7 @@ import ( "github.com/jackc/pgx/v5/pgxpool" "github.com/sirupsen/logrus" - "github.com/cybertec-postgresql/etcd_fdw/internal/migrations" + "github.com/cybertec-postgresql/pg_etcd/internal/migrations" ) // PgxIface is common interface for every pgx class diff --git a/internal/sync/sync.go b/internal/sync/sync.go index 1b3391b..beb2134 100644 --- a/internal/sync/sync.go +++ b/internal/sync/sync.go @@ -29,7 +29,7 @@ func NewService(pgPool PgxIface, etcdClient *EtcdClient, pollingInterval time.Du // Start begins the bidirectional synchronization process func (s *Service) Start(ctx context.Context) error { - logrus.Info("Starting etcd_fdw bidirectional synchronization") + logrus.Info("Starting pg_etcd bidirectional synchronization") // Perform initial sync from etcd to PostgreSQL if err := s.initialSync(ctx); err != nil { diff --git a/internal/sync/sync_test.go b/internal/sync/sync_test.go index 38c21d6..e99301f 100644 --- a/internal/sync/sync_test.go +++ b/internal/sync/sync_test.go @@ -1,4 +1,4 @@ -// Package sync provides synchronization testing for etcd_fdw. +// Package sync provides synchronization testing for pg_etcd. package sync import (