1*9bb1b549SSpandan Das# The MIT License (MIT) 2*9bb1b549SSpandan Das# Copyright © 2018 Jeff Hodges <[email protected]> 3*9bb1b549SSpandan Das 4*9bb1b549SSpandan Das# Permission is hereby granted, free of charge, to any person obtaining a copy 5*9bb1b549SSpandan Das# of this software and associated documentation files (the “Software”), to deal 6*9bb1b549SSpandan Das# in the Software without restriction, including without limitation the rights 7*9bb1b549SSpandan Das# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8*9bb1b549SSpandan Das# copies of the Software, and to permit persons to whom the Software is 9*9bb1b549SSpandan Das# furnished to do so, subject to the following conditions: 10*9bb1b549SSpandan Das 11*9bb1b549SSpandan Das# The above copyright notice and this permission notice shall be included in 12*9bb1b549SSpandan Das# all copies or substantial portions of the Software. 13*9bb1b549SSpandan Das 14*9bb1b549SSpandan Das# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15*9bb1b549SSpandan Das# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16*9bb1b549SSpandan Das# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17*9bb1b549SSpandan Das# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18*9bb1b549SSpandan Das# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19*9bb1b549SSpandan Das# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20*9bb1b549SSpandan Das# THE SOFTWARE. 21*9bb1b549SSpandan Das 22*9bb1b549SSpandan Das# The rules in this files are still under development. Breaking changes are planned. 23*9bb1b549SSpandan Das# DO NOT USE IT. 24*9bb1b549SSpandan Das 25*9bb1b549SSpandan Dasload("//go/private:context.bzl", "go_context") 26*9bb1b549SSpandan Dasload("//go/private:go_toolchain.bzl", "GO_TOOLCHAIN") 27*9bb1b549SSpandan Dasload("//go/private/rules:wrappers.bzl", go_binary = "go_binary_macro") 28*9bb1b549SSpandan Dasload("//go/private:providers.bzl", "GoLibrary") 29*9bb1b549SSpandan Dasload("@bazel_skylib//lib:paths.bzl", "paths") 30*9bb1b549SSpandan Das 31*9bb1b549SSpandan Das_MOCKGEN_TOOL = Label("//extras/gomock:mockgen") 32*9bb1b549SSpandan Das_MOCKGEN_MODEL_LIB = Label("//extras/gomock:mockgen_model") 33*9bb1b549SSpandan Das 34*9bb1b549SSpandan Dasdef _gomock_source_impl(ctx): 35*9bb1b549SSpandan Das go_ctx = go_context(ctx) 36*9bb1b549SSpandan Das 37*9bb1b549SSpandan Das # create GOPATH and copy source into GOPATH 38*9bb1b549SSpandan Das source_relative_path = paths.join("src", ctx.attr.library[GoLibrary].importmap, ctx.file.source.basename) 39*9bb1b549SSpandan Das source = ctx.actions.declare_file(paths.join("gopath", source_relative_path)) 40*9bb1b549SSpandan Das 41*9bb1b549SSpandan Das # trim the relative path of source to get GOPATH 42*9bb1b549SSpandan Das gopath = source.path[:-len(source_relative_path)] 43*9bb1b549SSpandan Das ctx.actions.run_shell( 44*9bb1b549SSpandan Das outputs = [source], 45*9bb1b549SSpandan Das inputs = [ctx.file.source], 46*9bb1b549SSpandan Das command = "mkdir -p {0} && cp -L {1} {0}".format(source.dirname, ctx.file.source.path), 47*9bb1b549SSpandan Das ) 48*9bb1b549SSpandan Das 49*9bb1b549SSpandan Das # passed in source needs to be in gopath to not trigger module mode 50*9bb1b549SSpandan Das args = ["-source", source.path] 51*9bb1b549SSpandan Das 52*9bb1b549SSpandan Das args, needed_files = _handle_shared_args(ctx, args) 53*9bb1b549SSpandan Das 54*9bb1b549SSpandan Das if len(ctx.attr.aux_files) > 0: 55*9bb1b549SSpandan Das aux_files = [] 56*9bb1b549SSpandan Das for target, pkg in ctx.attr.aux_files.items(): 57*9bb1b549SSpandan Das f = target.files.to_list()[0] 58*9bb1b549SSpandan Das aux = ctx.actions.declare_file(paths.join(gopath, "src", pkg, f.basename)) 59*9bb1b549SSpandan Das ctx.actions.run_shell( 60*9bb1b549SSpandan Das outputs = [aux], 61*9bb1b549SSpandan Das inputs = [f], 62*9bb1b549SSpandan Das command = "mkdir -p {0} && cp -L {1} {0}".format(aux.dirname, f.path), 63*9bb1b549SSpandan Das ) 64*9bb1b549SSpandan Das aux_files.append("{0}={1}".format(pkg, aux.path)) 65*9bb1b549SSpandan Das needed_files.append(f) 66*9bb1b549SSpandan Das args += ["-aux_files", ",".join(aux_files)] 67*9bb1b549SSpandan Das 68*9bb1b549SSpandan Das inputs = ( 69*9bb1b549SSpandan Das needed_files + 70*9bb1b549SSpandan Das go_ctx.sdk.headers + go_ctx.sdk.srcs + go_ctx.sdk.tools 71*9bb1b549SSpandan Das ) + [source] 72*9bb1b549SSpandan Das 73*9bb1b549SSpandan Das # We can use the go binary from the stdlib for most of the environment 74*9bb1b549SSpandan Das # variables, but our GOPATH is specific to the library target we were given. 75*9bb1b549SSpandan Das ctx.actions.run_shell( 76*9bb1b549SSpandan Das outputs = [ctx.outputs.out], 77*9bb1b549SSpandan Das inputs = inputs, 78*9bb1b549SSpandan Das tools = [ 79*9bb1b549SSpandan Das ctx.file.mockgen_tool, 80*9bb1b549SSpandan Das go_ctx.go, 81*9bb1b549SSpandan Das ], 82*9bb1b549SSpandan Das command = """ 83*9bb1b549SSpandan Das export GOPATH=$(pwd)/{gopath} && 84*9bb1b549SSpandan Das {cmd} {args} > {out} 85*9bb1b549SSpandan Das """.format( 86*9bb1b549SSpandan Das gopath = gopath, 87*9bb1b549SSpandan Das cmd = "$(pwd)/" + ctx.file.mockgen_tool.path, 88*9bb1b549SSpandan Das args = " ".join(args), 89*9bb1b549SSpandan Das out = ctx.outputs.out.path, 90*9bb1b549SSpandan Das mnemonic = "GoMockSourceGen", 91*9bb1b549SSpandan Das ), 92*9bb1b549SSpandan Das env = { 93*9bb1b549SSpandan Das # GOCACHE is required starting in Go 1.12 94*9bb1b549SSpandan Das "GOCACHE": "./.gocache", 95*9bb1b549SSpandan Das }, 96*9bb1b549SSpandan Das ) 97*9bb1b549SSpandan Das 98*9bb1b549SSpandan Das_gomock_source = rule( 99*9bb1b549SSpandan Das _gomock_source_impl, 100*9bb1b549SSpandan Das attrs = { 101*9bb1b549SSpandan Das "library": attr.label( 102*9bb1b549SSpandan Das doc = "The target the Go library where this source file belongs", 103*9bb1b549SSpandan Das providers = [GoLibrary], 104*9bb1b549SSpandan Das mandatory = True, 105*9bb1b549SSpandan Das ), 106*9bb1b549SSpandan Das "source": attr.label( 107*9bb1b549SSpandan Das doc = "A Go source file to find all the interfaces to generate mocks for. See also the docs for library.", 108*9bb1b549SSpandan Das mandatory = False, 109*9bb1b549SSpandan Das allow_single_file = True, 110*9bb1b549SSpandan Das ), 111*9bb1b549SSpandan Das "out": attr.output( 112*9bb1b549SSpandan Das doc = "The new Go file to emit the generated mocks into", 113*9bb1b549SSpandan Das mandatory = True, 114*9bb1b549SSpandan Das ), 115*9bb1b549SSpandan Das "aux_files": attr.label_keyed_string_dict( 116*9bb1b549SSpandan Das default = {}, 117*9bb1b549SSpandan Das doc = "A map from auxilliary Go source files to their packages.", 118*9bb1b549SSpandan Das allow_files = True, 119*9bb1b549SSpandan Das ), 120*9bb1b549SSpandan Das "package": attr.string( 121*9bb1b549SSpandan Das doc = "The name of the package the generated mocks should be in. If not specified, uses mockgen's default.", 122*9bb1b549SSpandan Das ), 123*9bb1b549SSpandan Das "self_package": attr.string( 124*9bb1b549SSpandan Das doc = "The full package import path for the generated code. The purpose of this flag is to prevent import cycles in the generated code by trying to include its own package. This can happen if the mock's package is set to one of its inputs (usually the main one) and the output is stdio so mockgen cannot detect the final output package. Setting this flag will then tell mockgen which import to exclude.", 125*9bb1b549SSpandan Das ), 126*9bb1b549SSpandan Das "imports": attr.string_dict( 127*9bb1b549SSpandan Das doc = "Dictionary of name-path pairs of explicit imports to use.", 128*9bb1b549SSpandan Das ), 129*9bb1b549SSpandan Das "mock_names": attr.string_dict( 130*9bb1b549SSpandan Das doc = "Dictionary of interface name to mock name pairs to change the output names of the mock objects. Mock names default to 'Mock' prepended to the name of the interface.", 131*9bb1b549SSpandan Das default = {}, 132*9bb1b549SSpandan Das ), 133*9bb1b549SSpandan Das "copyright_file": attr.label( 134*9bb1b549SSpandan Das doc = "Optional file containing copyright to prepend to the generated contents.", 135*9bb1b549SSpandan Das allow_single_file = True, 136*9bb1b549SSpandan Das mandatory = False, 137*9bb1b549SSpandan Das ), 138*9bb1b549SSpandan Das "mockgen_tool": attr.label( 139*9bb1b549SSpandan Das doc = "The mockgen tool to run", 140*9bb1b549SSpandan Das default = _MOCKGEN_TOOL, 141*9bb1b549SSpandan Das allow_single_file = True, 142*9bb1b549SSpandan Das executable = True, 143*9bb1b549SSpandan Das cfg = "exec", 144*9bb1b549SSpandan Das mandatory = False, 145*9bb1b549SSpandan Das ), 146*9bb1b549SSpandan Das "_go_context_data": attr.label( 147*9bb1b549SSpandan Das default = "//:go_context_data", 148*9bb1b549SSpandan Das ), 149*9bb1b549SSpandan Das }, 150*9bb1b549SSpandan Das toolchains = [GO_TOOLCHAIN], 151*9bb1b549SSpandan Das) 152*9bb1b549SSpandan Das 153*9bb1b549SSpandan Dasdef gomock(name, library, out, source = None, interfaces = [], package = "", self_package = "", aux_files = {}, mockgen_tool = _MOCKGEN_TOOL, imports = {}, copyright_file = None, mock_names = {}, **kwargs): 154*9bb1b549SSpandan Das """Calls [mockgen](https://github.com/golang/mock) to generates a Go file containing mocks from the given library. 155*9bb1b549SSpandan Das 156*9bb1b549SSpandan Das If `source` is given, the mocks are generated in source mode; otherwise in reflective mode. 157*9bb1b549SSpandan Das 158*9bb1b549SSpandan Das Args: 159*9bb1b549SSpandan Das name: the target name. 160*9bb1b549SSpandan Das library: the Go library to took for the interfaces (reflecitve mode) or source (source mode). 161*9bb1b549SSpandan Das out: the output Go file name. 162*9bb1b549SSpandan Das source: a Go file in the given `library`. If this is given, `gomock` will call mockgen in source mode to mock all interfaces in the file. 163*9bb1b549SSpandan Das interfaces: a list of interfaces in the given `library` to be mocked in reflective mode. 164*9bb1b549SSpandan Das package: the name of the package the generated mocks should be in. If not specified, uses mockgen's default. See [mockgen's -package](https://github.com/golang/mock#flags) for more information. 165*9bb1b549SSpandan Das self_package: the full package import path for the generated code. The purpose of this flag is to prevent import cycles in the generated code by trying to include its own package. See [mockgen's -self_package](https://github.com/golang/mock#flags) for more information. 166*9bb1b549SSpandan Das aux_files: a map from source files to their package path. This only needed when `source` is provided. See [mockgen's -aux_files](https://github.com/golang/mock#flags) for more information. 167*9bb1b549SSpandan Das mockgen_tool: the mockgen tool to run. 168*9bb1b549SSpandan Das imports: dictionary of name-path pairs of explicit imports to use. See [mockgen's -imports](https://github.com/golang/mock#flags) for more information. 169*9bb1b549SSpandan Das copyright_file: optional file containing copyright to prepend to the generated contents. See [mockgen's -copyright_file](https://github.com/golang/mock#flags) for more information. 170*9bb1b549SSpandan Das mock_names: dictionary of interface name to mock name pairs to change the output names of the mock objects. Mock names default to 'Mock' prepended to the name of the interface. See [mockgen's -mock_names](https://github.com/golang/mock#flags) for more information. 171*9bb1b549SSpandan Das kwargs: common attributes](https://bazel.build/reference/be/common-definitions#common-attributes) to all Bazel rules. 172*9bb1b549SSpandan Das """ 173*9bb1b549SSpandan Das if source: 174*9bb1b549SSpandan Das _gomock_source( 175*9bb1b549SSpandan Das name = name, 176*9bb1b549SSpandan Das library = library, 177*9bb1b549SSpandan Das out = out, 178*9bb1b549SSpandan Das source = source, 179*9bb1b549SSpandan Das package = package, 180*9bb1b549SSpandan Das self_package = self_package, 181*9bb1b549SSpandan Das aux_files = aux_files, 182*9bb1b549SSpandan Das mockgen_tool = mockgen_tool, 183*9bb1b549SSpandan Das imports = imports, 184*9bb1b549SSpandan Das copyright_file = copyright_file, 185*9bb1b549SSpandan Das mock_names = mock_names, 186*9bb1b549SSpandan Das **kwargs 187*9bb1b549SSpandan Das ) 188*9bb1b549SSpandan Das else: 189*9bb1b549SSpandan Das _gomock_reflect( 190*9bb1b549SSpandan Das name = name, 191*9bb1b549SSpandan Das library = library, 192*9bb1b549SSpandan Das out = out, 193*9bb1b549SSpandan Das interfaces = interfaces, 194*9bb1b549SSpandan Das package = package, 195*9bb1b549SSpandan Das self_package = self_package, 196*9bb1b549SSpandan Das mockgen_tool = mockgen_tool, 197*9bb1b549SSpandan Das imports = imports, 198*9bb1b549SSpandan Das copyright_file = copyright_file, 199*9bb1b549SSpandan Das mock_names = mock_names, 200*9bb1b549SSpandan Das **kwargs 201*9bb1b549SSpandan Das ) 202*9bb1b549SSpandan Das 203*9bb1b549SSpandan Dasdef _gomock_reflect(name, library, out, mockgen_tool, **kwargs): 204*9bb1b549SSpandan Das interfaces = kwargs.pop("interfaces", None) 205*9bb1b549SSpandan Das 206*9bb1b549SSpandan Das mockgen_model_lib = _MOCKGEN_MODEL_LIB 207*9bb1b549SSpandan Das if kwargs.get("mockgen_model_library", None): 208*9bb1b549SSpandan Das mockgen_model_lib = kwargs["mockgen_model_library"] 209*9bb1b549SSpandan Das 210*9bb1b549SSpandan Das prog_src = name + "_gomock_prog" 211*9bb1b549SSpandan Das prog_src_out = prog_src + ".go" 212*9bb1b549SSpandan Das _gomock_prog_gen( 213*9bb1b549SSpandan Das name = prog_src, 214*9bb1b549SSpandan Das interfaces = interfaces, 215*9bb1b549SSpandan Das library = library, 216*9bb1b549SSpandan Das out = prog_src_out, 217*9bb1b549SSpandan Das mockgen_tool = mockgen_tool, 218*9bb1b549SSpandan Das ) 219*9bb1b549SSpandan Das prog_bin = name + "_gomock_prog_bin" 220*9bb1b549SSpandan Das go_binary( 221*9bb1b549SSpandan Das name = prog_bin, 222*9bb1b549SSpandan Das srcs = [prog_src_out], 223*9bb1b549SSpandan Das deps = [library, mockgen_model_lib], 224*9bb1b549SSpandan Das ) 225*9bb1b549SSpandan Das _gomock_prog_exec( 226*9bb1b549SSpandan Das name = name, 227*9bb1b549SSpandan Das interfaces = interfaces, 228*9bb1b549SSpandan Das library = library, 229*9bb1b549SSpandan Das out = out, 230*9bb1b549SSpandan Das prog_bin = prog_bin, 231*9bb1b549SSpandan Das mockgen_tool = mockgen_tool, 232*9bb1b549SSpandan Das **kwargs 233*9bb1b549SSpandan Das ) 234*9bb1b549SSpandan Das 235*9bb1b549SSpandan Dasdef _gomock_prog_gen_impl(ctx): 236*9bb1b549SSpandan Das args = ["-prog_only"] 237*9bb1b549SSpandan Das args.append(ctx.attr.library[GoLibrary].importpath) 238*9bb1b549SSpandan Das args.append(",".join(ctx.attr.interfaces)) 239*9bb1b549SSpandan Das 240*9bb1b549SSpandan Das cmd = ctx.file.mockgen_tool 241*9bb1b549SSpandan Das out = ctx.outputs.out 242*9bb1b549SSpandan Das ctx.actions.run_shell( 243*9bb1b549SSpandan Das outputs = [out], 244*9bb1b549SSpandan Das tools = [cmd], 245*9bb1b549SSpandan Das command = """ 246*9bb1b549SSpandan Das {cmd} {args} > {out} 247*9bb1b549SSpandan Das """.format( 248*9bb1b549SSpandan Das cmd = "$(pwd)/" + cmd.path, 249*9bb1b549SSpandan Das args = " ".join(args), 250*9bb1b549SSpandan Das out = out.path, 251*9bb1b549SSpandan Das ), 252*9bb1b549SSpandan Das mnemonic = "GoMockReflectProgOnlyGen", 253*9bb1b549SSpandan Das ) 254*9bb1b549SSpandan Das 255*9bb1b549SSpandan Das_gomock_prog_gen = rule( 256*9bb1b549SSpandan Das _gomock_prog_gen_impl, 257*9bb1b549SSpandan Das attrs = { 258*9bb1b549SSpandan Das "library": attr.label( 259*9bb1b549SSpandan Das doc = "The target the Go library is at to look for the interfaces in. When this is set and source is not set, mockgen will use its reflect code to generate the mocks. If source is set, its dependencies will be included in the GOPATH that mockgen will be run in.", 260*9bb1b549SSpandan Das providers = [GoLibrary], 261*9bb1b549SSpandan Das mandatory = True, 262*9bb1b549SSpandan Das ), 263*9bb1b549SSpandan Das "out": attr.output( 264*9bb1b549SSpandan Das doc = "The new Go source file put the mock generator code", 265*9bb1b549SSpandan Das mandatory = True, 266*9bb1b549SSpandan Das ), 267*9bb1b549SSpandan Das "interfaces": attr.string_list( 268*9bb1b549SSpandan Das allow_empty = False, 269*9bb1b549SSpandan Das doc = "The names of the Go interfaces to generate mocks for. If not set, all of the interfaces in the library or source file will have mocks generated for them.", 270*9bb1b549SSpandan Das mandatory = True, 271*9bb1b549SSpandan Das ), 272*9bb1b549SSpandan Das "mockgen_tool": attr.label( 273*9bb1b549SSpandan Das doc = "The mockgen tool to run", 274*9bb1b549SSpandan Das default = _MOCKGEN_TOOL, 275*9bb1b549SSpandan Das allow_single_file = True, 276*9bb1b549SSpandan Das executable = True, 277*9bb1b549SSpandan Das cfg = "exec", 278*9bb1b549SSpandan Das mandatory = False, 279*9bb1b549SSpandan Das ), 280*9bb1b549SSpandan Das "_go_context_data": attr.label( 281*9bb1b549SSpandan Das default = "//:go_context_data", 282*9bb1b549SSpandan Das ), 283*9bb1b549SSpandan Das }, 284*9bb1b549SSpandan Das toolchains = [GO_TOOLCHAIN], 285*9bb1b549SSpandan Das) 286*9bb1b549SSpandan Das 287*9bb1b549SSpandan Dasdef _gomock_prog_exec_impl(ctx): 288*9bb1b549SSpandan Das args = ["-exec_only", ctx.file.prog_bin.path] 289*9bb1b549SSpandan Das args, needed_files = _handle_shared_args(ctx, args) 290*9bb1b549SSpandan Das 291*9bb1b549SSpandan Das # annoyingly, the interfaces join has to go after the importpath so we can't 292*9bb1b549SSpandan Das # share those. 293*9bb1b549SSpandan Das args.append(ctx.attr.library[GoLibrary].importpath) 294*9bb1b549SSpandan Das args.append(",".join(ctx.attr.interfaces)) 295*9bb1b549SSpandan Das 296*9bb1b549SSpandan Das ctx.actions.run_shell( 297*9bb1b549SSpandan Das outputs = [ctx.outputs.out], 298*9bb1b549SSpandan Das inputs = [ctx.file.prog_bin] + needed_files, 299*9bb1b549SSpandan Das tools = [ctx.file.mockgen_tool], 300*9bb1b549SSpandan Das command = """{cmd} {args} > {out}""".format( 301*9bb1b549SSpandan Das cmd = "$(pwd)/" + ctx.file.mockgen_tool.path, 302*9bb1b549SSpandan Das args = " ".join(args), 303*9bb1b549SSpandan Das out = ctx.outputs.out.path, 304*9bb1b549SSpandan Das ), 305*9bb1b549SSpandan Das env = { 306*9bb1b549SSpandan Das # GOCACHE is required starting in Go 1.12 307*9bb1b549SSpandan Das "GOCACHE": "./.gocache", 308*9bb1b549SSpandan Das }, 309*9bb1b549SSpandan Das mnemonic = "GoMockReflectExecOnlyGen", 310*9bb1b549SSpandan Das ) 311*9bb1b549SSpandan Das 312*9bb1b549SSpandan Das_gomock_prog_exec = rule( 313*9bb1b549SSpandan Das _gomock_prog_exec_impl, 314*9bb1b549SSpandan Das attrs = { 315*9bb1b549SSpandan Das "library": attr.label( 316*9bb1b549SSpandan Das doc = "The target the Go library is at to look for the interfaces in. When this is set and source is not set, mockgen will use its reflect code to generate the mocks. If source is set, its dependencies will be included in the GOPATH that mockgen will be run in.", 317*9bb1b549SSpandan Das providers = [GoLibrary], 318*9bb1b549SSpandan Das mandatory = True, 319*9bb1b549SSpandan Das ), 320*9bb1b549SSpandan Das "out": attr.output( 321*9bb1b549SSpandan Das doc = "The new Go source file to put the generated mock code", 322*9bb1b549SSpandan Das mandatory = True, 323*9bb1b549SSpandan Das ), 324*9bb1b549SSpandan Das "interfaces": attr.string_list( 325*9bb1b549SSpandan Das allow_empty = False, 326*9bb1b549SSpandan Das doc = "The names of the Go interfaces to generate mocks for. If not set, all of the interfaces in the library or source file will have mocks generated for them.", 327*9bb1b549SSpandan Das mandatory = True, 328*9bb1b549SSpandan Das ), 329*9bb1b549SSpandan Das "package": attr.string( 330*9bb1b549SSpandan Das doc = "The name of the package the generated mocks should be in. If not specified, uses mockgen's default.", 331*9bb1b549SSpandan Das ), 332*9bb1b549SSpandan Das "self_package": attr.string( 333*9bb1b549SSpandan Das doc = "The full package import path for the generated code. The purpose of this flag is to prevent import cycles in the generated code by trying to include its own package. This can happen if the mock's package is set to one of its inputs (usually the main one) and the output is stdio so mockgen cannot detect the final output package. Setting this flag will then tell mockgen which import to exclude.", 334*9bb1b549SSpandan Das ), 335*9bb1b549SSpandan Das "imports": attr.string_dict( 336*9bb1b549SSpandan Das doc = "Dictionary of name-path pairs of explicit imports to use.", 337*9bb1b549SSpandan Das ), 338*9bb1b549SSpandan Das "mock_names": attr.string_dict( 339*9bb1b549SSpandan Das doc = "Dictionary of interfaceName-mockName pairs of explicit mock names to use. Mock names default to 'Mock'+ interfaceName suffix.", 340*9bb1b549SSpandan Das default = {}, 341*9bb1b549SSpandan Das ), 342*9bb1b549SSpandan Das "copyright_file": attr.label( 343*9bb1b549SSpandan Das doc = "Optional file containing copyright to prepend to the generated contents.", 344*9bb1b549SSpandan Das allow_single_file = True, 345*9bb1b549SSpandan Das mandatory = False, 346*9bb1b549SSpandan Das ), 347*9bb1b549SSpandan Das "prog_bin": attr.label( 348*9bb1b549SSpandan Das doc = "The program binary generated by mockgen's -prog_only and compiled by bazel.", 349*9bb1b549SSpandan Das allow_single_file = True, 350*9bb1b549SSpandan Das executable = True, 351*9bb1b549SSpandan Das cfg = "exec", 352*9bb1b549SSpandan Das mandatory = True, 353*9bb1b549SSpandan Das ), 354*9bb1b549SSpandan Das "mockgen_tool": attr.label( 355*9bb1b549SSpandan Das doc = "The mockgen tool to run", 356*9bb1b549SSpandan Das default = _MOCKGEN_TOOL, 357*9bb1b549SSpandan Das allow_single_file = True, 358*9bb1b549SSpandan Das executable = True, 359*9bb1b549SSpandan Das cfg = "exec", 360*9bb1b549SSpandan Das mandatory = False, 361*9bb1b549SSpandan Das ), 362*9bb1b549SSpandan Das "_go_context_data": attr.label( 363*9bb1b549SSpandan Das default = "//:go_context_data", 364*9bb1b549SSpandan Das ), 365*9bb1b549SSpandan Das }, 366*9bb1b549SSpandan Das toolchains = [GO_TOOLCHAIN], 367*9bb1b549SSpandan Das) 368*9bb1b549SSpandan Das 369*9bb1b549SSpandan Dasdef _handle_shared_args(ctx, args): 370*9bb1b549SSpandan Das needed_files = [] 371*9bb1b549SSpandan Das 372*9bb1b549SSpandan Das if ctx.attr.package != "": 373*9bb1b549SSpandan Das args += ["-package", ctx.attr.package] 374*9bb1b549SSpandan Das if ctx.attr.self_package != "": 375*9bb1b549SSpandan Das args += ["-self_package", ctx.attr.self_package] 376*9bb1b549SSpandan Das if len(ctx.attr.imports) > 0: 377*9bb1b549SSpandan Das imports = ",".join(["{0}={1}".format(name, pkg) for name, pkg in ctx.attr.imports.items()]) 378*9bb1b549SSpandan Das args += ["-imports", imports] 379*9bb1b549SSpandan Das if ctx.file.copyright_file != None: 380*9bb1b549SSpandan Das args += ["-copyright_file", ctx.file.copyright_file.path] 381*9bb1b549SSpandan Das needed_files.append(ctx.file.copyright_file) 382*9bb1b549SSpandan Das if len(ctx.attr.mock_names) > 0: 383*9bb1b549SSpandan Das mock_names = ",".join(["{0}={1}".format(name, pkg) for name, pkg in ctx.attr.mock_names.items()]) 384*9bb1b549SSpandan Das args += ["-mock_names", mock_names] 385*9bb1b549SSpandan Das 386*9bb1b549SSpandan Das return args, needed_files 387