text: #!/usr/bin/env python
  # Copyright (C) 2017 The Android Open Source Project
  #
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  #
  # http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  #
  
  from __future__ import print_function
  import argparse
  import os
  import subprocess
  import re
  import sys
  import xml.dom.minidom
  
  JRE = '/'.join([
    'org.eclipse.jdt.launching.JRE_CONTAINER',
    'org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType',
    'JavaSE-1.8',
  ])
  
  opts = argparse.ArgumentParser("Create Eclipse Project")
  opts.add_argument('-r', '--root', help='Root directory entry')
  opts.add_argument('-n', '--name', help='Project name')
  opts.add_argument('-x', '--exclude', action='append', help='Exclude paths')
  opts.add_argument('-b', '--batch', action='store_true',
                    dest='batch', help='Bazel batch option')
  opts.add_argument('--bazel',
                    help=('name of the bazel executable. Defaults to using'
                          ' bazelisk if found, or bazel if bazelisk is not'
                          ' found.'),
                    action='store', default=None, dest='bazel_exe')
  args = opts.parse_args()
  
  if not args.root:
    opts.error('Root option not provided')
    sys.exit(1)
  
  root = args.root
  ROOT = os.path.abspath(root)
  while not os.path.exists(os.path.join(ROOT, 'WORKSPACE')):
    ROOT = os.path.dirname(ROOT)
  
  batch_option = '--batch' if args.batch else None
  
  def find_bazel():
    if args.bazel_exe:
      try:
        return subprocess.check_output(
          ['which', args.bazel_exe]).strip().decode('UTF-8')
      except subprocess.CalledProcessError:
        print('Bazel command: %s not found' % args.bazel_exe, file=sys.stderr)
        sys.exit(1)
    try:
      return subprocess.check_output(
        ['which', 'bazelisk']).strip().decode('UTF-8')
    except subprocess.CalledProcessError:
      try:
        return subprocess.check_output(
          ['which', 'bazel']).strip().decode('UTF-8')
      except subprocess.CalledProcessError:
        print("Neither bazelisk nor bazel found. Please see"
              " Documentation/dev-bazel for instructions on installing"
              " one of them.")
        sys.exit(1)
  
  bazel_exe = find_bazel()
  
  def _build_bazel_cmd(*args):
    cmd = [bazel_exe]
    if batch_option:
      cmd.append('--batch')
    for arg in args:
      cmd.append(arg)
    return cmd
  
  def retrieve_ext_location():
    return subprocess.check_output(_build_bazel_cmd('info', 'output_base')).strip()
  
  def _query_classpath():
    t = '//tools/eclipse:main_classpath_collect'
    try:
      subprocess.check_call(_build_bazel_cmd('build', t))
    except subprocess.CalledProcessError:
      exit(1)
    name = 'bazel-bin/tools/eclipse/' + t.split(':')[1] + '.runtime_classpath'
    return [line.rstrip('\n') for line in open(name)]
  
  def gen_project(name, root=ROOT):
    p = os.path.join(root, '.project')
    with open(p, 'w') as fd:
      print("""\
  <?xml version="1.0" encoding="UTF-8"?>
  <projectDescription>
    <name>%(name)s</name>
    <buildSpec>
      <buildCommand>
        <name>org.eclipse.jdt.core.javabuilder</name>
      </buildCommand>
    </buildSpec>
    <natures>
      <nature>org.eclipse.jdt.core.javanature</nature>
    </natures>
  </projectDescription>\
      """ % {"name": name}, file=fd)
  
  def gen_classpath(ext):
    def make_classpath():
      impl = xml.dom.minidom.getDOMImplementation()
      return impl.createDocument(None, 'classpath', None)
  
    def classpathentry(kind, path, src=None, out=None, exported=None):
      e = doc.createElement('classpathentry')
      e.setAttribute('kind', kind)
      # TODO(davido): Remove this and other exclude BUILD files hack
      # when this Bazel bug is fixed:
      # https://github.com/bazelbuild/bazel/issues/1083
      if kind == 'src':
        e.setAttribute('excluding', '**/BUILD')
      e.setAttribute('path', path)
      if src:
        e.setAttribute('sourcepath', src)
      if out:
        e.setAttribute('output', out)
      if exported:
        e.setAttribute('exported', 'true')
      doc.documentElement.appendChild(e)
  
    doc = make_classpath()
    src = set()
    lib = set()
  
    java_library = re.compile('bazel-out/(?:.*)-fastbuild/bin(.*)/[^/]+[.]jar$')
    srcs = re.compile('(.*)[.]jar')
    for p in _query_classpath():
      m = java_library.match(p)
      if m:
        src.add(m.group(1).lstrip('/'))
      else:
        if ext is not None and p.startswith("external"):
          p = os.path.join(ext, p)
          lib.add(p)
  
    src_paths = {}
    for s in sorted(src):
      out = None
  
      if s.startswith('lib/'):
        out = 'eclipse-out/lib'
  
      p = os.path.join(s, 'java')
      if os.path.exists(p):
        classpathentry('src', p, out=out)
        continue
  
      for env in ['main', 'test', 'java', 'javatests']:
        o = None
        if out:
          o = out + '/' + env
        elif env == 'test' or env == 'javatests':
          o = 'eclipse-out/test'
  
        if s.startswith(env + '/'):
          src_paths[env] = o
          continue
  
        for srctype in ['java', 'resources']:
          p = os.path.join(s, 'src', env, srctype)
          if os.path.exists(p):
            src_paths[p] = o
  
    for s in src_paths:
      classpathentry('src', s, out=src_paths[s])
  
    for libs in [lib]:
      for j in sorted(libs):
        if excluded(j):
          continue
        s = None
        m = srcs.match(j)
        if m:
          f = m.group(1)
          p = "%s-sources.jar" % f
          if os.path.exists(p):
            s = p
        classpathentry('lib', j, s)
  
    classpathentry('con', JRE)
    classpathentry('output', 'eclipse-out/classes')
  
    p = os.path.join(ROOT, '.classpath')
    with open(p, 'w') as fd:
      doc.writexml(fd, addindent='\t', newl='\n', encoding='UTF-8')
  
  def excluded(lib):
    if args.exclude:
      for x in args.exclude:
        if x in lib:
          return True
    return False
  
  try:
    name = args.name if args.name else os.path.basename(ROOT)
    gen_project(name)
    gen_classpath(retrieve_ext_location().decode('utf-8'))
  
  except KeyboardInterrupt:
    print('Interrupted by user', file=sys.stderr)
    exit(1)
  