def generate_targets()

in contrib/go/src/python/pants/contrib/go/tasks/go_buildgen.py [0:0]


  def generate_targets(self, local_go_targets=None):
    """Generate Go targets in memory to form a complete Go graph.

    :param local_go_targets: The local Go targets to fill in a complete target graph for.  If
                             `None`, then all local Go targets under the Go source root are used.
    :type local_go_targets: :class:`collections.Iterable` of
                            :class:`pants.contrib.go.targets.go_local_source import GoLocalSource`
    :returns: A generation result if targets were generated, else `None`.
    :rtype: :class:`GoBuildgen.GenerationResult`
    """
    # TODO(John Sirois): support multiple source roots like GOPATH does?
    # The GOPATH's 1st element is read-write, the rest are read-only; ie: their sources build to
    # the 1st element's pkg/ and bin/ dirs.

    go_roots_by_category = defaultdict(list)
    # TODO: Add "find source roots for lang" functionality to SourceRoots and use that instead.
    for sr in self.context.source_roots.all_roots():
      if 'go' in sr.langs:
        go_roots_by_category[sr.category].append(sr.path)

    if go_roots_by_category[SourceRootCategories.TEST]:
      raise self.InvalidLocalRootsError('Go buildgen does not support test source roots.')
    if go_roots_by_category[SourceRootCategories.UNKNOWN]:
      raise self.InvalidLocalRootsError('Go buildgen does not support source roots of '
                                        'unknown category.')

    local_roots = go_roots_by_category[SourceRootCategories.SOURCE]
    if not local_roots:
      raise self.NoLocalRootsError('Can only BUILD gen if a Go local sources source root is '
                                   'defined.')
    if len(local_roots) > 1:
      raise self.InvalidLocalRootsError('Can only BUILD gen for a single Go local sources source '
                                        'root, found:\n\t{}'
                                        .format('\n\t'.join(sorted(local_roots))))
    local_root = local_roots.pop()

    if local_go_targets:
      unrooted_locals = {t for t in local_go_targets if t.target_base != local_root}
      if unrooted_locals:
        raise self.UnrootedLocalSourceError('Cannot BUILD gen until the following targets are '
                                            'relocated to the source root at {}:\n\t{}'
                                            .format(local_root,
                                                    '\n\t'.join(sorted(t.address.reference()
                                                                       for t in unrooted_locals))))
    else:
      root = os.path.join(get_buildroot(), local_root)
      local_go_targets = self.context.scan(root=root).targets(self.is_local_src)
      if not local_go_targets:
        return None

    remote_roots = go_roots_by_category[SourceRootCategories.THIRDPARTY]
    if len(remote_roots) > 1:
      raise self.InvalidRemoteRootsError('Can only BUILD gen for a single Go remote library source '
                                         'root, found:\n\t{}'
                                         .format('\n\t'.join(sorted(remote_roots))))
    remote_root = remote_roots.pop() if remote_roots else None

    generator = GoTargetGenerator(self.import_oracle,
                                  self.context.build_graph,
                                  local_root,
                                  self.get_fetcher_factory(),
                                  generate_remotes=self.get_options().remote,
                                  remote_root=remote_root)
    with self.context.new_workunit('go.buildgen', labels=[WorkUnitLabel.MULTITOOL]):
      try:
        generated = generator.generate(local_go_targets)
        return self.GenerationResult(generated=generated,
                                     local_root=local_root,
                                     remote_root=remote_root)
      except generator.GenerationError as e:
        raise self.GenerationError(e)