Skip to content

Commit 9c8ce8b

Browse files
authored
feat: use connection string as command-line flag (#2)
* feat: use connection string as command-line flag Remove --host, --user, --database, --password * feat: add testutil package * feat: add build GHA workflow * fix: make linter happy
1 parent 773a1e1 commit 9c8ce8b

25 files changed

Lines changed: 454 additions & 1091 deletions

.github/workflows/build.yml

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
name: Build and Test
2+
3+
permissions:
4+
contents: write
5+
packages: write
6+
pages: write
7+
8+
on:
9+
push:
10+
branches:
11+
- master
12+
pull_request:
13+
paths-ignore: ['docs/**', 'mkdocs.yml']
14+
workflow_dispatch:
15+
16+
concurrency:
17+
group: ${{ github.workflow }}-${{ github.ref }}
18+
cancel-in-progress: true
19+
20+
jobs:
21+
build:
22+
name: Build and Lint
23+
runs-on: ubuntu-latest
24+
steps:
25+
26+
- name: Check out code
27+
uses: actions/checkout@v6
28+
29+
- name: Set up Golang
30+
uses: actions/setup-go@v6
31+
with:
32+
go-version: '1.25'
33+
cache-dependency-path: 'go.sum'
34+
35+
- name: Build
36+
run: |
37+
go build ./cmd/pgcov
38+
39+
- name: GolangCI-Lint
40+
uses: golangci/golangci-lint-action@v9
41+
with:
42+
version: latest
43+
44+
test:
45+
if: true # false to skip job during debug
46+
needs: build
47+
runs-on: ubuntu-latest
48+
name: Test
49+
steps:
50+
51+
- name: Check out code
52+
uses: actions/checkout@v6
53+
54+
- name: Set up Golang
55+
uses: actions/setup-go@v6
56+
with:
57+
go-version: '1.25'
58+
cache-dependency-path: 'go.sum'
59+
60+
- name: Test
61+
run: |
62+
go test -failfast -v -timeout=300s -coverprofile=profile.cov ./cmd/... ./internal/...
63+
64+
- name: Coveralls
65+
uses: coverallsapp/github-action@v2
66+
with:
67+
file: profile.cov

.golangci.yml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
version: "2"
2+
linters:
3+
enable:
4+
- misspell
5+
- revive
6+
disable:
7+
- gocyclo
8+
settings:
9+
gocyclo:
10+
min-complexity: 20
11+
exclusions:
12+
generated: lax
13+
presets:
14+
- comments
15+
- common-false-positives
16+
- legacy
17+
- std-error-handling
18+
rules:
19+
- path: (.+)\.go$
20+
text: SA1019 # CPUTimesStat.Total is deprecated
21+
- path: (.+)\.go$
22+
text: SA5008 # duplicate struct tag "choice" (staticcheck)
23+
- path: (.+)\.go$
24+
text: QF1001 # could apply De Morgan's law
25+
- path: pkg/
26+
text: "var-naming: avoid meaningless package names"
27+
linters:
28+
- revive
29+
paths:
30+
- third_party$
31+
- builtin$
32+
- examples$
33+
formatters:
34+
exclusions:
35+
generated: lax
36+
paths:
37+
- third_party$
38+
- builtin$
39+
- examples$

cmd/pgcov/main.go

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -23,24 +23,9 @@ func main() {
2323
Action: runCommand,
2424
Flags: []urfavecli.Flag{
2525
&urfavecli.StringFlag{
26-
Name: "host",
27-
Usage: "PostgreSQL host",
28-
},
29-
&urfavecli.IntFlag{
30-
Name: "port",
31-
Usage: "PostgreSQL port",
32-
},
33-
&urfavecli.StringFlag{
34-
Name: "user",
35-
Usage: "PostgreSQL user",
36-
},
37-
&urfavecli.StringFlag{
38-
Name: "password",
39-
Usage: "PostgreSQL password",
40-
},
41-
&urfavecli.StringFlag{
42-
Name: "database",
43-
Usage: "Template database for test databases",
26+
Name: "connection",
27+
Aliases: []string{"c"},
28+
Usage: "PostgreSQL connection string (URI or key=value format). Supports standard PG* environment variables.",
4429
},
4530
&urfavecli.DurationFlag{
4631
Name: "timeout",
@@ -95,20 +80,16 @@ func main() {
9580
// runCommand handles the 'pgcov run' command
9681
func runCommand(ctx context.Context, cmd *urfavecli.Command) error {
9782
// Load configuration
98-
config := cli.LoadConfig()
83+
config := &cli.DefaultConfig
9984

10085
// Apply flags
101-
host := cmd.String("host")
102-
port := cmd.Int("port")
103-
user := cmd.String("user")
104-
password := cmd.String("password")
105-
database := cmd.String("database")
86+
connection := cmd.String("connection")
10687
timeout := cmd.Duration("timeout")
10788
parallel := cmd.Int("parallel")
10889
coverageFile := cmd.String("coverage-file")
10990
verbose := cmd.Bool("verbose")
11091

111-
cli.ApplyFlagsToConfig(config, host, port, user, password, database, timeout, parallel, coverageFile, verbose)
92+
cli.ApplyFlagsToConfig(config, connection, timeout, parallel, coverageFile, verbose)
11293

11394
// Validate configuration
11495
if err := config.Validate(); err != nil {
@@ -142,5 +123,5 @@ func reportCommand(ctx context.Context, cmd *urfavecli.Command) error {
142123
output := cmd.String("output")
143124
coverageFile := cmd.String("coverage-file")
144125

145-
return cli.Report(coverageFile, format, output)
126+
return cli.Report(ctx, coverageFile, format, output)
146127
}

internal/cli/config.go

Lines changed: 9 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package cli
22

33
import (
4-
"os"
5-
"strconv"
64
"time"
75

86
"github.com/cybertec-postgresql/pgcov/pkg/types"
@@ -16,60 +14,19 @@ type ConfigError = types.ConfigError
1614

1715
// DefaultConfig provides default configuration values
1816
var DefaultConfig = Config{
19-
PGHost: "localhost",
20-
PGPort: 5432,
21-
PGDatabase: "postgres",
22-
Timeout: 30 * time.Second,
23-
Parallelism: 1,
24-
CoverageFile: ".pgcov/coverage.json",
25-
Verbose: false,
26-
}
27-
28-
// LoadConfig creates a configuration by layering flags → env vars → defaults
29-
// Priority: flags override env vars override defaults
30-
func LoadConfig() *Config {
31-
cfg := DefaultConfig
32-
33-
// Load from environment variables
34-
if host := os.Getenv("PGHOST"); host != "" {
35-
cfg.PGHost = host
36-
}
37-
if portStr := os.Getenv("PGPORT"); portStr != "" {
38-
if port, err := strconv.Atoi(portStr); err == nil {
39-
cfg.PGPort = port
40-
}
41-
}
42-
if user := os.Getenv("PGUSER"); user != "" {
43-
cfg.PGUser = user
44-
}
45-
if password := os.Getenv("PGPASSWORD"); password != "" {
46-
cfg.PGPassword = password
47-
}
48-
if database := os.Getenv("PGDATABASE"); database != "" {
49-
cfg.PGDatabase = database
50-
}
51-
52-
return &cfg
17+
ConnectionString: "",
18+
Timeout: 30 * time.Second,
19+
Parallelism: 1,
20+
CoverageFile: ".pgcov/coverage.json",
21+
Verbose: false,
5322
}
5423

5524
// ApplyFlagsToConfig applies command-line flag values to configuration
56-
func ApplyFlagsToConfig(c *Config, host string, port int, user, password, database string,
57-
timeout time.Duration, parallel int, coverageFile string, verbose bool) {
25+
func ApplyFlagsToConfig(c *Config, connection string, timeout time.Duration,
26+
parallel int, coverageFile string, verbose bool) {
5827

59-
if host != "" {
60-
c.PGHost = host
61-
}
62-
if port != 0 {
63-
c.PGPort = port
64-
}
65-
if user != "" {
66-
c.PGUser = user
67-
}
68-
if password != "" {
69-
c.PGPassword = password
70-
}
71-
if database != "" {
72-
c.PGDatabase = database
28+
if connection != "" {
29+
c.ConnectionString = connection
7330
}
7431
if timeout != 0 {
7532
c.Timeout = timeout

0 commit comments

Comments
 (0)