Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions doc.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
// Package codegen exposes utilities to build and test
// code generators that build go apps.
// Package codegen exposes utilities to build and test code generators that build go apps.
package codegen
2 changes: 1 addition & 1 deletion formatting/format_lite.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers
// SPDX-License-Identifier: Apache-2.0

package language
package formatting

import (
"bytes"
Expand Down
2 changes: 1 addition & 1 deletion formatting/format_lite_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers
// SPDX-License-Identifier: Apache-2.0

package language
package formatting

import (
"strings"
Expand Down
83 changes: 1 addition & 82 deletions formatting/golang.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers
// SPDX-License-Identifier: Apache-2.0

package language
package formatting

import (
"encoding/json"
Expand All @@ -24,17 +24,8 @@ var moduleRe = regexp.MustCompile(`module[ \t]+([^\s]+)`)
// GolangOpts returns [Options] for rendering items as golang code.
func GolangOpts(extraInitialisms ...string) *Options {
opts := new(Options)
opts.ReservedWords = []string{
"break", "default", "func", "interface", "select",
"case", "defer", "go", "map", "struct",
"chan", "else", "goto", "package", "switch",
"const", "fallthrough", "if", "range", "type",
"continue", "for", "import", "return", "var",
}
opts.ExtraInitialisms = extraInitialisms
opts.formatFunc = defaultGoFormatFunc() // this default may be overridden by [GenOpts]
opts.fileNameFunc = opts.defaultGoFilenameFunc(goOtherReservedSuffixes())
opts.dirNameFunc = defaultGoDirnameFunc()
opts.ImportsFunc = defaultGoImportsFunc()
opts.ArrayInitializerFunc = defaultGoArrayInitializerFunc()
opts.BaseImportFunc = defaultGoBaseImportFunc()
Expand All @@ -52,26 +43,6 @@ func defaultGoFormatFunc() FormatterFunc {
}
}

func (o *Options) defaultGoFilenameFunc(reservedSuffixes map[string]bool) MangleFunc {
return func(name string) string {
parts := strings.Split(o.Mangler.ToFileName(name), "_")
if reservedSuffixes[parts[len(parts)-1]] {
parts = append(parts, "swagger")
}
return strings.Join(parts, "_")
}
}

func defaultGoDirnameFunc() MangleFunc {
return func(name string) string {
switch name {
case "vendor", "internal":
return strings.Join([]string{name, "swagger"}, "_")
}
return name
}
}

func defaultGoImportsFunc() func(map[string]string) string {
return func(imports map[string]string) string {
if len(imports) == 0 {
Expand Down Expand Up @@ -277,55 +248,3 @@ func CheckPrefixAndFetchRelativePath(childpath string, parentpath string) (bool,

return false, ""
}

func goOtherReservedSuffixes() map[string]bool {
return map[string]bool{
// goos
"aix": true,
"android": true,
"darwin": true,
"dragonfly": true,
"freebsd": true,
"hurd": true,
"illumos": true,
"ios": true,
"js": true,
"linux": true,
"nacl": true,
"netbsd": true,
"openbsd": true,
"plan9": true,
"solaris": true,
"windows": true,
"zos": true,

// arch
"386": true,
"amd64": true,
"amd64p32": true,
"arm": true,
"armbe": true,
"arm64": true,
"arm64be": true,
"loong64": true,
"mips": true,
"mipsle": true,
"mips64": true,
"mips64le": true,
"mips64p32": true,
"mips64p32le": true,
"ppc": true,
"ppc64": true,
"ppc64le": true,
"riscv": true,
"riscv64": true,
"s390": true,
"s390x": true,
"sparc": true,
"sparc64": true,
"wasm": true,

// other reserved suffixes
"test": true,
}
}
23 changes: 12 additions & 11 deletions formatting/golang_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers
// SPDX-License-Identifier: Apache-2.0

package language
package formatting

import (
"strings"
Expand All @@ -15,7 +15,8 @@ func TestGolang_MangleFileName(t *testing.T) {
o := &Options{}
o.Init()
res := o.MangleFileName("aFileEndingInOsNameWindows")
assert.TrueT(t, strings.HasSuffix(res, "_windows"))
assert.FalseT(t, strings.HasSuffix(res, "_windows"))
assert.TrueT(t, strings.HasSuffix(res, "_windows_swagger"))

o = GolangOpts()
res = o.MangleFileName("aFileEndingInOsNameWindows")
Expand All @@ -36,20 +37,20 @@ func TestGolang_ManglePackage(t *testing.T) {
expectedName string
}{
{tested: "", expectedPath: defaultPackage, expectedName: defaultPackage},
{tested: "select", expectedPath: "select_default", expectedName: "select_default"},
{tested: "select", expectedPath: "selectpkg", expectedName: "selectpkg"}, // a package path may use a go keyword?
{tested: "x", expectedPath: "x", expectedName: "x"},
{tested: "a/b/c-d/e_f/g", expectedPath: "a/b/c-d/e_f/g", expectedName: "g"},
{tested: "a/b/c-d/e_f/g-h", expectedPath: "a/b/c-d/e_f/g_h", expectedName: "g_h"},
{tested: "a/b/c-d/e_f/2A", expectedPath: "a/b/c-d/e_f/nr2_a", expectedName: "nr2_a"},
{tested: "a/b/c-d/e_f/#", expectedPath: "a/b/c-d/e_f/hash_tag", expectedName: "hash_tag"},
{tested: "#help", expectedPath: "hash_tag_help", expectedName: "hash_tag_help"},
{tested: "vendor", expectedPath: "vendor_swagger", expectedName: "vendor_swagger"},
{tested: "internal", expectedPath: "internal_swagger", expectedName: "internal_swagger"},
{tested: "a/b/c-d/e_f/g-h", expectedPath: "a/b/c-d/e_f/g-h", expectedName: "h"},
{tested: "a/b/c-d/e_f/2A", expectedPath: "a/b/c-d/e_f/2-a", expectedName: "a"},
{tested: "a/b/c-d/e_f/#", expectedPath: "a/b/c-d/e_f/hash", expectedName: "hash"},
{tested: "#help", expectedPath: "hash-help", expectedName: "help"},
{tested: "vendor", expectedPath: "vendorpkg", expectedName: "vendorpkg"},
{tested: "internal", expectedPath: "internalpkg", expectedName: "internalpkg"},
} {
res := o.ManglePackagePath(v.tested, defaultPackage)
assert.EqualT(t, v.expectedPath, res)
assert.EqualTf(t, v.expectedPath, res, "expected ManglePackagePath(%q) to yield %q but go %q", v.tested, v.expectedPath, res)
res = o.ManglePackageName(v.tested, defaultPackage)
assert.EqualT(t, v.expectedName, res)
assert.EqualTf(t, v.expectedName, res, "expected ManglePackageName(%q) to yield %q but go %q", v.tested, v.expectedName, res)
}
}

Expand Down
71 changes: 21 additions & 50 deletions formatting/options.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers
// SPDX-License-Identifier: Apache-2.0

// Package language provides the language-specific options used by the
// Package formatting provides the language-specific options used by the
// go-swagger code generator. The primary type is [Options], which describes
// formatting, naming, and import resolution rules for a target language.
package language
package formatting

import (
"path"
"path/filepath"
"strings"

"golang.org/x/tools/imports"

golangfuncs "github.com/go-openapi/codegen/funcmaps/golang"
"github.com/go-openapi/codegen/mangling"
)

Expand Down Expand Up @@ -76,19 +73,15 @@ func FormatOptsWithDefault(opts []FormatOption) FormatOpts {

// Options describes a target language to the code generator.
type Options struct {
ReservedWords []string
BaseImportFunc MangleFunc `json:"-"`
ImportsFunc func(map[string]string) string `json:"-"`
ArrayInitializerFunc func(any) (string, error) `json:"-"`
FormatOnly bool
ExtraInitialisms []string
Mangler mangling.NameMangler
Mangler mangling.GoMangler

reservedWordsSet map[string]struct{}
initialized bool
formatFunc FormatterFunc
fileNameFunc MangleFunc // language specific source file naming rules
dirNameFunc MangleFunc // language specific directory naming rules
initialized bool
formatFunc FormatterFunc
}

// SetFormatFunc sets the formatting function for this language.
Expand All @@ -102,45 +95,30 @@ func (l *Options) Init() {
return
}

l.Mangler = mangling.NewNameMangler(
mangling.WithGoNamePrefixFunc(golangfuncs.PrefixForName),
mangling.WithAdditionalInitialisms(l.ExtraInitialisms...),
l.Mangler = mangling.MakeGoMangler(
mangling.WithGoInitialisms(l.ExtraInitialisms...),
)

l.initialized = true
l.reservedWordsSet = make(map[string]struct{})

for _, rw := range l.ReservedWords {
l.reservedWordsSet[rw] = struct{}{}
}
}

// MangleName makes sure a reserved word gets a safe name.
// MangleName makes sure a string becomes a safe go identifier.
func (l *Options) MangleName(name, suffix string) string {
if _, ok := l.reservedWordsSet[l.Mangler.ToFileName(name)]; !ok {
return name
if name == "" {
return suffix
}

return strings.Join([]string{name, suffix}, "_")
return l.Mangler.IdentExported(name)
}

// MangleVarName makes sure a reserved word gets a safe name.
func (l *Options) MangleVarName(name string) string {
nm := l.Mangler.ToVarName(name)
if _, ok := l.reservedWordsSet[nm]; !ok {
return nm
}

return nm + "Var"
return l.Mangler.IdentUnexported(name)
}

// MangleFileName makes sure a file name gets a safe name.
func (l *Options) MangleFileName(name string) string {
if l.fileNameFunc != nil {
return l.fileNameFunc(name)
}

return l.Mangler.ToFileName(name)
return l.Mangler.File(name)
}

// ManglePackageName makes sure a package gets a safe name.
Expand All @@ -149,12 +127,11 @@ func (l *Options) ManglePackageName(name, suffix string) string {
if name == "" {
return suffix
}
if l.dirNameFunc != nil {
name = l.dirNameFunc(name)
}
pth := filepath.ToSlash(filepath.Clean(name)) // preserve path
pkg := importAlias(pth) // drop path
return l.MangleName(l.Mangler.ToFileName(golangfuncs.PrefixForName(pkg)+pkg), suffix)

target := filepath.ToSlash(filepath.Clean(name)) // preserve path
short, _ := l.Mangler.Package(target)

return short
}

// ManglePackagePath makes sure a full package path gets a safe name.
Expand All @@ -163,11 +140,11 @@ func (l *Options) ManglePackagePath(name string, suffix string) string {
if name == "" {
return suffix
}

target := filepath.ToSlash(filepath.Clean(name)) // preserve path
parts := strings.Split(target, "/")
parts[len(parts)-1] = l.ManglePackageName(parts[len(parts)-1], suffix)
_, fqn := l.Mangler.Package(target)

return strings.Join(parts, "/")
return fqn
}

// FormatContent formats a file with a language specific formatter.
Expand Down Expand Up @@ -206,9 +183,3 @@ func (l *Options) BaseImport(tgt string) string {

return ""
}

// importAlias extracts the last path component from a package import path.
func importAlias(pkg string) string {
_, k := path.Split(pkg)
return k
}
2 changes: 1 addition & 1 deletion formatting/options_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers
// SPDX-License-Identifier: Apache-2.0

package language
package formatting

import (
"testing"
Expand Down
Loading
Loading