Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for build tags to generated code #33

Merged
merged 2 commits into from
Oct 11, 2023
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
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ To specify a pointer receiver for the method, an optional `--pointer-receiver`
boolean flag can be specified. The flag will also govern whether the return
type is a pointer as well.

To specify build tags in the generated code, an optional `--tags` comma separated
list flag can be specified. The flag will add all items as build tags to the
generated code.

It might also be desirable to skip deeply copying certain fields, slice
members, or map members. To achieve that, selectors can be specified in the
optional comma-separated `--skip` flag. Multiple `--skip` flags can be
Expand Down Expand Up @@ -64,12 +68,13 @@ deep-copy <flags> github.com/globusdigital/deep-copy/some/sub/packages
Here is the full set of supported flags:

```bash
deep-copy \
deep-copy \
[-o /output/path.go] \
[--method DeepCopy] \
[--pointer-receiver] \
[--skip Selector1,Selector.Two --skip Selector2[i], Selector.Three[k]]
[--type Type1 --type Type2\ \
[--skip Selector1,Selector.Two --skip Selector2[i], Selector.Three[k]]
[--type Type1 --type Type2\ \
[--tags mytag,anotherTag ] \ \
/path/to/package/containing/type
```

Expand Down
8 changes: 7 additions & 1 deletion deepcopy/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,21 @@ type Generator struct {
maxDepth int
methodName string
skipLists SkipLists
buildTags []string

imports map[string]string
fns [][]byte
}

func NewGenerator(
isPtrRecv bool, methodName string, skipLists SkipLists, maxDepth int,
isPtrRecv bool, methodName string, skipLists SkipLists, maxDepth int, buildTags []string,
) Generator {
return Generator{
isPtrRecv: isPtrRecv,
methodName: methodName,
maxDepth: maxDepth,
skipLists: skipLists,
buildTags: buildTags,

imports: map[string]string{},
fns: [][]byte{},
Expand Down Expand Up @@ -134,6 +136,10 @@ func (g Generator) generateFile(w io.Writer, p *packages.Package) error {

fmt.Fprintf(&file, "// Code generated by %s; DO NOT EDIT.\n\npackage %s\n\n", strings.Join(os.Args, " "), p.Name)

for _, tag := range g.buildTags {
fmt.Fprintf(&file, "//go:build %s\n// +build %s\n", tag, tag)
}

if len(g.imports) > 0 {
file.WriteString("import (\n")
for name, path := range g.imports {
Expand Down
21 changes: 17 additions & 4 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ var (
maxDepthF = flag.Int("maxdepth", 0, "max depth of deep copying")
methodF = flag.String("method", "DeepCopy", "deep copy method name")

typesF typesVal
skipsF skipsVal
outputF outputVal
typesF typesVal
skipsF skipsVal
outputF outputVal
buildTagsF buildTagsVal
)

type typesVal []string
Expand Down Expand Up @@ -106,10 +107,22 @@ func (f *outputVal) Open() (io.WriteCloser, error) {
return f.file, nil
}

type buildTagsVal []string

func (b *buildTagsVal) String() string {
return strings.Join(*b, ",")
}

func (b *buildTagsVal) Set(v string) error {
*b = append(*b, v)
return nil
}

func init() {
flag.Var(&typesF, "type", "the concrete type. Multiple flags can be specified")
flag.Var(&skipsF, "skip", "comma-separated field/slice/map selectors to shallow copy. Multiple flags can be specified")
flag.Var(&outputF, "o", "the output file to write to. Defaults to STDOUT")
flag.Var(&buildTagsF, "tags", "comma-separated build tags to add to generated file")
}

func main() {
Expand All @@ -124,7 +137,7 @@ func main() {
}

sl := deepcopy.SkipLists(skipsF)
generator := deepcopy.NewGenerator(*pointerReceiverF, *methodF, sl, *maxDepthF)
generator := deepcopy.NewGenerator(*pointerReceiverF, *methodF, sl, *maxDepthF, buildTagsF)

output, err := outputF.Open()
if err != nil {
Expand Down
58 changes: 49 additions & 9 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ import (

func Test_run(t *testing.T) {
tests := []struct {
name string
types typesVal
path string
pointer bool
skips skipsVal
maxdepth int
method string
want []byte
name string
types typesVal
path string
pointer bool
skips skipsVal
maxdepth int
buildTags []string
method string
want []byte
}{
{name: "foo", types: typesVal{"Foo"}, path: "./testdata", want: []byte(FooFile)},
{name: "foo - pointer", types: typesVal{"Foo"}, pointer: true, path: "./testdata", want: []byte(FooPointerFile)},
Expand All @@ -43,6 +44,7 @@ func Test_run(t *testing.T) {
{name: "issue 15, parent has child pointer, pointer receiver", pointer: true, types: typesVal{"ParentHasChildPointer", "Child"}, path: "./testdata", want: []byte(I15ParentHasChildPointerPointerRecv)},
{name: "issue 17, with maxdepth", types: typesVal{"Depth1"}, pointer: true, maxdepth: 2, path: "./testdata", want: []byte(Issue17MaxDepth)},
{name: "alias import", types: typesVal{"Data"}, path: "./testdata/import_alias", want: []byte(AliasImport)},
{name: "using build tags", types: typesVal{"Foo"}, path: "./testdata", buildTags: []string{"!myTag", "anotherOne"}, want: []byte(FooFileBuildTags)},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand All @@ -51,7 +53,7 @@ func Test_run(t *testing.T) {
method = tt.method
}
g := deepcopy.NewGenerator(tt.pointer, method,
deepcopy.SkipLists(tt.skips), tt.maxdepth)
deepcopy.SkipLists(tt.skips), tt.maxdepth, tt.buildTags)
var buf bytes.Buffer
err := run(g, &buf, tt.path, tt.types)
if err != nil {
Expand Down Expand Up @@ -588,4 +590,42 @@ func (o Data) DeepCopy() Data {
}
return cp
}`

FooFileBuildTags = `// Code generated by deep-copy; DO NOT EDIT.

//go:build !myTag
//go:build anotherOne
// +build !myTag
// +build anotherOne

package testdata

// DeepCopy generates a deep copy of Foo
//
func (o Foo) DeepCopy() Foo {
var cp Foo = o
if o.Map != nil {
cp.Map = make(map[string]*Bar, len(o.Map))
for k2, v2 := range o.Map {
var cp_Map_v2 *Bar
if v2 != nil {
cp_Map_v2 = new(Bar)
*cp_Map_v2 = *v2
if v2.Slice != nil {
cp_Map_v2.Slice = make([]string, len(v2.Slice))
copy(cp_Map_v2.Slice, v2.Slice)
}
}
cp.Map[k2] = cp_Map_v2
}
}
if o.ch != nil {
cp.ch = make(chan float32, cap(o.ch))
}
if o.baz.StringPointer != nil {
cp.baz.StringPointer = new(string)
*cp.baz.StringPointer = *o.baz.StringPointer
}
return cp
}`
)