Skip to content

Commit 5dfc713

Browse files
authored
Port SQLCDEBUG to a registry-style package modeled after Go's GODEBUG (#4420)
1 parent 977ac6d commit 5dfc713

14 files changed

Lines changed: 366 additions & 113 deletions

File tree

internal/cmd/cmd.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@ import (
1818
"gopkg.in/yaml.v3"
1919

2020
"github.com/sqlc-dev/sqlc/internal/config"
21-
"github.com/sqlc-dev/sqlc/internal/debug"
2221
"github.com/sqlc-dev/sqlc/internal/info"
2322
"github.com/sqlc-dev/sqlc/internal/opts"
23+
"github.com/sqlc-dev/sqlc/internal/sqlcdebug"
2424
"github.com/sqlc-dev/sqlc/internal/tracer"
2525
)
2626

27+
var debugProcessPlugins = sqlcdebug.New("processplugins")
28+
2729
func init() {
2830
createDBCmd.Flags().StringP("queryset", "", "", "name of the queryset to use")
2931
pushCmd.Flags().BoolP("dry-run", "", false, "dump push request (default: false)")
@@ -55,7 +57,7 @@ func Do(args []string, stdin io.Reader, stdout io.Writer, stderr io.Writer) int
5557
rootCmd.SetErr(stderr)
5658

5759
ctx := context.Background()
58-
if debug.Debug.Trace != "" {
60+
if tracer.Path() != "" {
5961
tracectx, cleanup, err := tracer.Start(ctx)
6062
if err != nil {
6163
fmt.Printf("failed to start trace: %v\n", err)
@@ -137,15 +139,13 @@ var initCmd = &cobra.Command{
137139

138140
type Env struct {
139141
DryRun bool
140-
Debug opts.Debug
141142
Experiment opts.Experiment
142143
}
143144

144145
func ParseEnv(c *cobra.Command) Env {
145146
dr := c.Flag("dry-run")
146147
return Env{
147148
DryRun: dr != nil && dr.Changed,
148-
Debug: opts.DebugFromEnv(),
149149
Experiment: opts.ExperimentFromEnv(),
150150
}
151151
}
@@ -154,7 +154,7 @@ var ErrPluginProcessDisabled = errors.New("plugin: process-based plugins disable
154154

155155
func (e *Env) Validate(cfg *config.Config) error {
156156
for _, plugin := range cfg.Plugins {
157-
if plugin.Process != nil && !e.Debug.ProcessPlugins {
157+
if plugin.Process != nil && debugProcessPlugins.Value() == "0" {
158158
return ErrPluginProcessDisabled
159159
}
160160
}

internal/cmd/generate.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,11 @@ import (
2626
"github.com/sqlc-dev/sqlc/internal/multierr"
2727
"github.com/sqlc-dev/sqlc/internal/opts"
2828
"github.com/sqlc-dev/sqlc/internal/plugin"
29+
"github.com/sqlc-dev/sqlc/internal/sqlcdebug"
2930
)
3031

32+
var debugDumpCatalog = sqlcdebug.New("dumpcatalog")
33+
3134
const errMessageNoVersion = `The configuration file must have a version number.
3235
Set the version to 1 or 2 at the top of sqlc.json:
3336
@@ -244,7 +247,7 @@ func parse(ctx context.Context, name, dir string, sql config.SQL, combo config.C
244247
}
245248
return nil, true
246249
}
247-
if parserOpts.Debug.DumpCatalog {
250+
if debugDumpCatalog.Value() == "1" {
248251
debug.Dump(c.Catalog())
249252
}
250253
if err := c.ParseQueries(sql.Queries, parserOpts); err != nil {

internal/cmd/process.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import (
1313

1414
"github.com/sqlc-dev/sqlc/internal/compiler"
1515
"github.com/sqlc-dev/sqlc/internal/config"
16-
"github.com/sqlc-dev/sqlc/internal/debug"
1716
"github.com/sqlc-dev/sqlc/internal/opts"
1817
)
1918

@@ -87,9 +86,7 @@ func processQuerySets(ctx context.Context, rp ResultProcessor, conf *config.Conf
8786
sql.Queries = joined
8887

8988
var name, lang string
90-
parseOpts := opts.Parser{
91-
Debug: debug.Debug,
92-
}
89+
parseOpts := opts.Parser{}
9390

9491
switch {
9592
case sql.Gen.Go != nil:

internal/cmd/vet.go

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,16 @@ import (
3333
"github.com/sqlc-dev/sqlc/internal/quickdb"
3434
"github.com/sqlc-dev/sqlc/internal/shfmt"
3535
"github.com/sqlc-dev/sqlc/internal/sql/sqlpath"
36+
"github.com/sqlc-dev/sqlc/internal/sqlcdebug"
3637
"github.com/sqlc-dev/sqlc/internal/vet"
3738
)
3839

40+
var (
41+
debugDumpExplain = sqlcdebug.New("dumpexplain")
42+
debugDumpVetEnv = sqlcdebug.New("dumpvetenv")
43+
debugDatabases = sqlcdebug.New("databases")
44+
)
45+
3946
var ErrFailedChecks = errors.New("failed checks")
4047

4148
var pjson = protojson.UnmarshalOptions{AllowPartial: true, DiscardUnknown: true}
@@ -148,7 +155,7 @@ func Vet(ctx context.Context, dir, filename string, opts *Options) error {
148155
Dir: dir,
149156
Env: env,
150157
Stderr: stderr,
151-
OnlyManagedDB: e.Debug.OnlyManagedDatabases,
158+
OnlyManagedDB: debugDatabases.Value() == "managed",
152159
Replacer: shfmt.NewReplacer(nil),
153160
}
154161
errored := false
@@ -316,7 +323,7 @@ func (p *pgxConn) Explain(ctx context.Context, query string, args ...*plugin.Par
316323
if err := row.Scan(&result); err != nil {
317324
return nil, err
318325
}
319-
if debug.Debug.DumpExplain {
326+
if debugDumpExplain.Value() == "1" {
320327
fmt.Println(eQuery, "with args", eArgs)
321328
fmt.Println(string(result[0]))
322329
}
@@ -358,7 +365,7 @@ func (me *mysqlExplainer) Explain(ctx context.Context, query string, args ...*pl
358365
if err := row.Scan(&result); err != nil {
359366
return nil, err
360367
}
361-
if debug.Debug.DumpExplain {
368+
if debugDumpExplain.Value() == "1" {
362369
fmt.Println(eQuery, "with args", eArgs)
363370
fmt.Println(string(result))
364371
}
@@ -480,9 +487,7 @@ func (c *checker) checkSQL(ctx context.Context, s config.SQL) error {
480487
s.Queries = joined
481488

482489
var name string
483-
parseOpts := opts.Parser{
484-
Debug: debug.Debug,
485-
}
490+
parseOpts := opts.Parser{}
486491

487492
result, failed := parse(ctx, name, c.Dir, s, combo, parseOpts, c.Stderr)
488493
if failed {
@@ -642,7 +647,7 @@ func (c *checker) checkSQL(ctx context.Context, s config.SQL) error {
642647
evalMap["mysql"] = engineOutput.MySQL
643648
}
644649

645-
if debug.Debug.DumpVetEnv {
650+
if debugDumpVetEnv.Value() == "1" {
646651
fmt.Printf("vars for rule '%s' evaluating against query '%s':\n", name, query.Name)
647652
debug.DumpAsJSON(evalMap)
648653
}

internal/compiler/parse.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,15 @@ import (
1313
"github.com/sqlc-dev/sqlc/internal/sql/ast"
1414
"github.com/sqlc-dev/sqlc/internal/sql/astutils"
1515
"github.com/sqlc-dev/sqlc/internal/sql/validate"
16+
"github.com/sqlc-dev/sqlc/internal/sqlcdebug"
1617
)
1718

19+
var debugDumpAST = sqlcdebug.New("dumpast")
20+
1821
func (c *Compiler) parseQuery(stmt ast.Node, src string, o opts.Parser) (*Query, error) {
1922
ctx := context.Background()
2023

21-
if o.Debug.DumpAST {
24+
if debugDumpAST.Value() == "1" {
2225
debug.Dump(stmt)
2326
}
2427

internal/debug/dump.go

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,16 @@ package debug
33
import (
44
"encoding/json"
55
"fmt"
6-
"os"
76

87
"github.com/davecgh/go-spew/spew"
98

10-
"github.com/sqlc-dev/sqlc/internal/opts"
9+
"github.com/sqlc-dev/sqlc/internal/sqlcdebug"
1110
)
1211

13-
var Active bool
14-
var Debug opts.Debug
15-
16-
func init() {
17-
Active = os.Getenv("SQLCDEBUG") != ""
18-
if Active {
19-
Debug = opts.DebugFromEnv()
20-
}
21-
}
12+
// Active reports whether SQLCDEBUG had any value set at startup. It
13+
// remains a global so unrelated debug-spew sites that don't tie to a
14+
// specific setting can gate their output on "is debug mode on at all".
15+
var Active = sqlcdebug.Any()
2216

2317
func Dump(n ...interface{}) {
2418
if Active {

internal/endtoend/endtoend_test.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,26 @@ import (
1717
"github.com/sqlc-dev/sqlc/internal/cmd"
1818
"github.com/sqlc-dev/sqlc/internal/config"
1919
"github.com/sqlc-dev/sqlc/internal/opts"
20+
"github.com/sqlc-dev/sqlc/internal/sqlcdebug"
2021
"github.com/sqlc-dev/sqlc/internal/sqltest/docker"
2122
"github.com/sqlc-dev/sqlc/internal/sqltest/native"
2223
)
2324

25+
// withSQLCDEBUG installs the given SQLCDEBUG-formatted string for the
26+
// duration of the test and restores the empty default afterwards.
27+
//
28+
// Callers in TestReplay are sequential, so this does not need a mutex:
29+
// Go's test scheduler does not run TestReplay concurrently with the
30+
// parallel top-level tests in this package.
31+
func withSQLCDEBUG(t *testing.T, raw string) func() {
32+
t.Helper()
33+
if raw == "" {
34+
return func() {}
35+
}
36+
sqlcdebug.Update(raw)
37+
return func() { sqlcdebug.Update("") }
38+
}
39+
2440
func lineEndings() cmp.Option {
2541
return cmp.Transformer("LineEndings", func(in string) string {
2642
// Replace Windows new lines with Unix newlines
@@ -263,13 +279,15 @@ func TestReplay(t *testing.T) {
263279

264280
opts := cmd.Options{
265281
Env: cmd.Env{
266-
Debug: opts.DebugFromString(args.Env["SQLCDEBUG"]),
267282
Experiment: opts.ExperimentFromString(args.Env["SQLCEXPERIMENT"]),
268283
},
269284
Stderr: &stderr,
270285
MutateConfig: testctx.Mutate(t, path),
271286
}
272287

288+
release := withSQLCDEBUG(t, args.Env["SQLCDEBUG"])
289+
defer release()
290+
273291
switch args.Command {
274292
case "diff":
275293
err = cmd.Diff(ctx, path, "", &opts)

internal/engine/postgresql/analyzer/analyze.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,20 @@ import (
1414
core "github.com/sqlc-dev/sqlc/internal/analysis"
1515
"github.com/sqlc-dev/sqlc/internal/config"
1616
"github.com/sqlc-dev/sqlc/internal/dbmanager"
17-
"github.com/sqlc-dev/sqlc/internal/opts"
1817
"github.com/sqlc-dev/sqlc/internal/shfmt"
1918
"github.com/sqlc-dev/sqlc/internal/sql/ast"
2019
"github.com/sqlc-dev/sqlc/internal/sql/catalog"
2120
"github.com/sqlc-dev/sqlc/internal/sql/named"
2221
"github.com/sqlc-dev/sqlc/internal/sql/sqlerr"
22+
"github.com/sqlc-dev/sqlc/internal/sqlcdebug"
2323
)
2424

25+
var debugDatabases = sqlcdebug.New("databases")
26+
2527
type Analyzer struct {
2628
db config.Database
2729
client dbmanager.Client
2830
pool *pgxpool.Pool
29-
dbg opts.Debug
3031
replacer *shfmt.Replacer
3132
formats sync.Map
3233
columns sync.Map
@@ -36,7 +37,6 @@ type Analyzer struct {
3637
func New(client dbmanager.Client, db config.Database) *Analyzer {
3738
return &Analyzer{
3839
db: db,
39-
dbg: opts.DebugFromEnv(),
4040
client: client,
4141
replacer: shfmt.NewReplacer(nil),
4242
}
@@ -210,7 +210,7 @@ func (a *Analyzer) Analyze(ctx context.Context, n ast.Node, query string, migrat
210210
return nil, err
211211
}
212212
uri = edb.Uri
213-
} else if a.dbg.OnlyManagedDatabases {
213+
} else if debugDatabases.Value() == "managed" {
214214
return nil, fmt.Errorf("database: connections disabled via SQLCDEBUG=databases=managed")
215215
} else {
216216
uri = a.replacer.Replace(a.db.URI)
@@ -502,7 +502,7 @@ func (a *Analyzer) EnsureConn(ctx context.Context, migrations []string) error {
502502
return err
503503
}
504504
uri = edb.Uri
505-
} else if a.dbg.OnlyManagedDatabases {
505+
} else if debugDatabases.Value() == "managed" {
506506
return fmt.Errorf("database: connections disabled via SQLCDEBUG=databases=managed")
507507
} else {
508508
uri = a.replacer.Replace(a.db.URI)

internal/engine/sqlite/analyzer/analyze.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,26 @@ import (
1010

1111
core "github.com/sqlc-dev/sqlc/internal/analysis"
1212
"github.com/sqlc-dev/sqlc/internal/config"
13-
"github.com/sqlc-dev/sqlc/internal/opts"
1413
"github.com/sqlc-dev/sqlc/internal/shfmt"
1514
"github.com/sqlc-dev/sqlc/internal/sql/ast"
1615
"github.com/sqlc-dev/sqlc/internal/sql/catalog"
1716
"github.com/sqlc-dev/sqlc/internal/sql/named"
1817
"github.com/sqlc-dev/sqlc/internal/sql/sqlerr"
18+
"github.com/sqlc-dev/sqlc/internal/sqlcdebug"
1919
)
2020

21+
var debugDatabases = sqlcdebug.New("databases")
22+
2123
type Analyzer struct {
2224
db config.Database
2325
conn *sqlite3.Conn
24-
dbg opts.Debug
2526
replacer *shfmt.Replacer
2627
mu sync.Mutex
2728
}
2829

2930
func New(db config.Database) *Analyzer {
3031
return &Analyzer{
3132
db: db,
32-
dbg: opts.DebugFromEnv(),
3333
replacer: shfmt.NewReplacer(nil),
3434
}
3535
}
@@ -44,7 +44,7 @@ func (a *Analyzer) Analyze(ctx context.Context, n ast.Node, query string, migrat
4444
if a.db.Managed {
4545
// For managed databases, create an in-memory database
4646
uri = ":memory:"
47-
} else if a.dbg.OnlyManagedDatabases {
47+
} else if debugDatabases.Value() == "managed" {
4848
return nil, fmt.Errorf("database: connections disabled via SQLCDEBUG=databases=managed")
4949
} else {
5050
uri = a.replacer.Replace(a.db.URI)
@@ -200,7 +200,7 @@ func (a *Analyzer) EnsureConn(ctx context.Context, migrations []string) error {
200200
if a.db.Managed {
201201
// For managed databases, create an in-memory database
202202
uri = ":memory:"
203-
} else if a.dbg.OnlyManagedDatabases {
203+
} else if debugDatabases.Value() == "managed" {
204204
return fmt.Errorf("database: connections disabled via SQLCDEBUG=databases=managed")
205205
} else {
206206
uri = a.replacer.Replace(a.db.URI)

0 commit comments

Comments
 (0)