Skip to content

Commit 37d0206

Browse files
committed
default models package, always import as models
Two refinements on top of the initial #835 work: 1. output_models_package now defaults to filepath.Base(output_models_path) when unset, matching how `package` defaults to base(out). When only output_models_emit: false is configured (no path), it falls back to filepath.Base(output_models_import). 2. Query files always import the models package under the alias `models` and reference types as `models.User`, regardless of the actual package name. This keeps generated query code readable without users having to think about import aliases. The actual `package X` declaration in models.go still uses the configured (or defaulted) package name. https://claude.ai/code/session_01Nj4LbGbqFBTU1EPKKNHtNn
1 parent 9610f6a commit 37d0206

8 files changed

Lines changed: 63 additions & 54 deletions

File tree

internal/codegen/golang/imports.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -244,13 +244,13 @@ func buildImports(options *opts.Options, queries []Query, uses func(string) bool
244244
}
245245

246246
// Models package import. When models live in a separate Go package and
247-
// any type in this file references a qualified model type, we need to
248-
// import the models package. The qualifier is derived from the
249-
// configured models package name, so the alias matches references like
250-
// `model.User`.
247+
// any type in this file references a qualified model type, import the
248+
// models package under a fixed `models` alias so query files always
249+
// reference types as `models.User` regardless of how the actual
250+
// package is named.
251251
if options.ModelsAreExternal() {
252252
if uses(options.ModelsTypeQualifier()) {
253-
pkg[ImportSpec{Path: options.OutputModelsImport, ID: options.OutputModelsPackage}] = struct{}{}
253+
pkg[ImportSpec{Path: options.OutputModelsImport, ID: opts.ModelsImportAlias}] = struct{}{}
254254
}
255255
}
256256

internal/codegen/golang/opts/options.go

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,17 @@ func parseOpts(req *plugin.GenerateRequest) (*Options, error) {
9898
}
9999
}
100100

101+
// Default the models package name to the base of the models path. When
102+
// the user only configures output_models_emit: false (no path), fall
103+
// back to the base of the import path.
104+
if options.OutputModelsPackage == "" {
105+
if options.OutputModelsPath != "" {
106+
options.OutputModelsPackage = filepath.Base(options.OutputModelsPath)
107+
} else if options.OutputModelsImport != "" {
108+
options.OutputModelsPackage = filepath.Base(options.OutputModelsImport)
109+
}
110+
}
111+
101112
for i := range options.Overrides {
102113
if err := options.Overrides[i].parse(req); err != nil {
103114
return nil, err
@@ -174,9 +185,14 @@ func (o *Options) ModelsEmitEnabled() bool {
174185
return *o.OutputModelsEmit
175186
}
176187

177-
// ModelsPackage returns the Go package name to use for model types. When the
178-
// caller has not configured a separate models package, this is the same as
179-
// Package.
188+
// ModelsImportAlias is the fixed Go import alias used for the models
189+
// package in query files. Using a constant alias keeps the type qualifier
190+
// consistent regardless of how the user names the actual package.
191+
const ModelsImportAlias = "models"
192+
193+
// ModelsPackage returns the Go package name to use in the models file
194+
// itself (i.e. the `package X` declaration). When the caller has not
195+
// configured a separate models package, this is the same as Package.
180196
func (o *Options) ModelsPackage() string {
181197
if o.OutputModelsPackage != "" {
182198
return o.OutputModelsPackage
@@ -186,17 +202,17 @@ func (o *Options) ModelsPackage() string {
186202

187203
// ModelsAreExternal reports whether model types live in a different Go
188204
// package than the queries package. When true, query files must import the
189-
// models package and reference types as `<pkg>.Type`.
205+
// models package and reference types as `models.Type`.
190206
func (o *Options) ModelsAreExternal() bool {
191-
return o.OutputModelsPackage != "" && o.OutputModelsPackage != o.Package
207+
return o.OutputModelsImport != ""
192208
}
193209

194210
// ModelsTypeQualifier returns the prefix to use when referencing a model
195-
// type from a query file (e.g. "model."). Empty string when no qualifier is
211+
// type from a query file ("models."). Empty string when no qualifier is
196212
// needed.
197213
func (o *Options) ModelsTypeQualifier() string {
198214
if o.ModelsAreExternal() {
199-
return o.OutputModelsPackage + "."
215+
return ModelsImportAlias + "."
200216
}
201217
return ""
202218
}
@@ -219,12 +235,8 @@ func validateModelsOptions(opts *Options) error {
219235
return fmt.Errorf("invalid options: output_models_path is required when emitting models to a separate package")
220236
}
221237

222-
if opts.OutputModelsPackage == "" {
223-
return fmt.Errorf("invalid options: output_models_package is required when any output_models_* option is set")
224-
}
225-
226-
if !opts.ModelsEmitEnabled() && opts.OutputModelsPackage == opts.Package {
227-
return fmt.Errorf("invalid options: output_models_emit is false but output_models_package matches package; nothing to import")
238+
if opts.ModelsEmitEnabled() && opts.OutputModelsPath == opts.Out {
239+
return fmt.Errorf("invalid options: output_models_path matches out; models would overwrite the queries package")
228240
}
229241

230242
return nil

internal/endtoend/testdata/output_models_path/postgresql/db/querier.go

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/endtoend/testdata/output_models_path/postgresql/db/query.sql.go

Lines changed: 14 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/endtoend/testdata/output_models_path/postgresql/sqlc.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
"package": "db",
1212
"emit_interface": true,
1313
"output_models_path": "model",
14-
"output_models_package": "model",
1514
"output_models_import": "github.com/sqlc-dev/sqlc/endtoend/output_models_path/postgresql/model"
1615
}
1716
}

internal/endtoend/testdata/output_models_shared/postgresql/primary/query.sql.go

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/endtoend/testdata/output_models_shared/postgresql/replica/query.sql.go

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/endtoend/testdata/output_models_shared/postgresql/sqlc.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
"out": "primary",
1111
"package": "primary",
1212
"output_models_path": "model",
13-
"output_models_package": "model",
1413
"output_models_import": "github.com/sqlc-dev/sqlc/endtoend/output_models_shared/postgresql/model"
1514
}
1615
}
@@ -23,7 +22,6 @@
2322
"go": {
2423
"out": "replica",
2524
"package": "replica",
26-
"output_models_package": "model",
2725
"output_models_import": "github.com/sqlc-dev/sqlc/endtoend/output_models_shared/postgresql/model",
2826
"output_models_emit": false
2927
}

0 commit comments

Comments
 (0)