_codegen: add license and merge package 'imports' Merge code from package internal/imports (recently copied from package github.com/ernesto-jimenez/gogen/imports) into the codegen program itself. Also copy the license attached to it into the _codegen/main.go source, as _codegen/main.go was originally by the same author (Ernesto Jimenez) as the imported code and matches the license terms of the global Testify project. Also: Ernesto, who was queried about this project, didn't block it. https://github.com/stretchr/testify/pull/1782#discussion_r2322798422
diff --git a/_codegen/internal/imports/imports.go b/_codegen/internal/imports/imports.go deleted file mode 100644 index a0c7e2b..0000000 --- a/_codegen/internal/imports/imports.go +++ /dev/null
@@ -1,108 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2015 Ernesto Jiménez - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -package imports - -import ( - "go/types" - "os" - "path/filepath" - "strings" -) - -type Importer interface { - AddImportsFrom(t types.Type) - Imports() map[string]string -} - -// imports contains metadata about all the imports from a given package -type imports struct { - currentpkg string - imp map[string]string -} - -// AddImportsFrom adds imports used in the passed type -func (imp *imports) AddImportsFrom(t types.Type) { - switch el := t.(type) { - case *types.Basic: - case *types.Slice: - imp.AddImportsFrom(el.Elem()) - case *types.Pointer: - imp.AddImportsFrom(el.Elem()) - case *types.Named: - pkg := el.Obj().Pkg() - if pkg == nil { - return - } - if pkg.Name() == imp.currentpkg { - return - } - imp.imp[cleanImportPath(pkg.Path())] = pkg.Name() - case *types.Tuple: - for i := 0; i < el.Len(); i++ { - imp.AddImportsFrom(el.At(i).Type()) - } - default: - } -} - -func cleanImportPath(ipath string) string { - return gopathlessImportPath( - vendorlessImportPath(ipath), - ) -} - -func gopathlessImportPath(ipath string) string { - paths := strings.Split(os.Getenv("GOPATH"), ":") - for _, p := range paths { - ipath = strings.TrimPrefix(ipath, filepath.Join(p, "src")+string(filepath.Separator)) - } - return ipath -} - -// vendorlessImportPath returns the devendorized version of the provided import path. -// e.g. "foo/bar/vendor/a/b" => "a/b" -func vendorlessImportPath(ipath string) string { - // Devendorize for use in import statement. - if i := strings.LastIndex(ipath, "/vendor/"); i >= 0 { - return ipath[i+len("/vendor/"):] - } - if strings.HasPrefix(ipath, "vendor/") { - return ipath[len("vendor/"):] - } - return ipath -} - -// AddImportsFrom adds imports used in the passed type -func (imp *imports) Imports() map[string]string { - return imp.imp -} - -// New initializes a new structure to track packages imported by the currentpkg -func New(currentpkg string) Importer { - return &imports{ - currentpkg: currentpkg, - imp: make(map[string]string), - } -}
diff --git a/_codegen/main.go b/_codegen/main.go index f2653e8..fd242b0 100644 --- a/_codegen/main.go +++ b/_codegen/main.go
@@ -1,3 +1,27 @@ +/* +The MIT License (MIT) + +Copyright (c) 2015-2026 Ernesto Jiménez and contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + // This program reads all assertion functions from the assert package and // automatically generates the corresponding requires and forwarded assertions @@ -22,8 +46,6 @@ "regexp" "strings" "text/template" - - "github.com/stretchr/testify/_codegen/internal/imports" ) var ( @@ -42,17 +64,17 @@ log.Fatal(err) } - importer, funcs, err := analyzeCode(scope, docs) + imports, funcs, err := analyzeCode(scope, docs) if err != nil { log.Fatal(err) } - if err := generateCode(importer, funcs); err != nil { + if err := generateCode(imports, funcs); err != nil { log.Fatal(err) } } -func generateCode(importer imports.Importer, funcs []testFunc) error { +func generateCode(imports *imports, funcs []testFunc) error { buff := bytes.NewBuffer(nil) tmplHead, tmplFunc, err := parseTemplates() @@ -66,7 +88,7 @@ Imports map[string]string }{ *outputPkg, - importer.Imports(), + imports.imports, }); err != nil { return err } @@ -126,10 +148,13 @@ // analyzeCode takes the types scope and the docs and returns the import // information and information about all the assertion functions. -func analyzeCode(scope *types.Scope, docs *doc.Package) (imports.Importer, []testFunc, error) { +func analyzeCode(scope *types.Scope, docs *doc.Package) (*imports, []testFunc, error) { testingT := scope.Lookup("TestingT").Type().Underlying().(*types.Interface) - importer := imports.New(*outputPkg) + importer := &imports{ + currentPkg: *outputPkg, + imports: map[string]string{}, + } var funcs []testFunc // Go through all the top level functions for _, fdocs := range docs.Funcs { @@ -164,11 +189,43 @@ } funcs = append(funcs, testFunc{*outputPkg, fdocs, fn}) - importer.AddImportsFrom(sig.Params()) + importer.addImportsFrom(sig.Params()) } return importer, funcs, nil } +// imports collects a map of imported packages for a source file. +// +// This code has been copied from package github.com/ernesto-jimenez/gogen/imports +type imports struct { + currentPkg string + imports map[string]string +} + +func (imp *imports) addImportsFrom(t types.Type) { + switch el := t.(type) { + case *types.Basic: + case *types.Slice: + imp.addImportsFrom(el.Elem()) + case *types.Pointer: + imp.addImportsFrom(el.Elem()) + case *types.Named: + pkg := el.Obj().Pkg() + if pkg == nil { + return + } + if pkg.Name() == imp.currentPkg { + return + } + imp.imports[pkg.Path()] = pkg.Name() + case *types.Tuple: + for i := 0; i < el.Len(); i++ { + imp.addImportsFrom(el.At(i).Type()) + } + default: + } +} + // parsePackageSource returns the types scope and the package documentation from the package func parsePackageSource(pkg string) (*types.Scope, *doc.Package, error) { pd, err := build.Import(pkg, ".", 0)