Example #1
0
def _initialize_build_configuration(
    plugin_resolver: PluginResolver,
    options_bootstrapper: OptionsBootstrapper,
    env: CompleteEnvironment,
) -> BuildConfiguration:
    """Initialize a BuildConfiguration for the given OptionsBootstrapper.

    NB: This method:
      1. has the side-effect of (idempotently) adding PYTHONPATH entries for this process
      2. is expensive to call, because it might resolve plugins from the network
    """

    bootstrap_options = options_bootstrapper.get_bootstrap_options().for_global_scope()
    working_set = plugin_resolver.resolve(options_bootstrapper, env)

    # Add any extra paths to python path (e.g., for loading extra source backends).
    for path in bootstrap_options.pythonpath:
        if path not in sys.path:
            sys.path.append(path)
            pkg_resources.fixup_namespace_packages(path)

    # Load plugins and backends.
    return load_backends_and_plugins(
        bootstrap_options.plugins,
        working_set,
        bootstrap_options.backend_packages,
    )
Example #2
0
  def _load_plugins(self, working_set, python_paths, plugins, backend_packages):
    # Add any extra paths to python path (e.g., for loading extra source backends).
    for path in python_paths:
      if path not in sys.path:
        sys.path.append(path)
        pkg_resources.fixup_namespace_packages(path)

    # Load plugins and backends.
    return load_backends_and_plugins(plugins, working_set, backend_packages)
Example #3
0
  def _load_plugins(self, working_set, python_paths, plugins, backend_packages):
    # Add any extra paths to python path (e.g., for loading extra source backends).
    for path in python_paths:
      if path not in sys.path:
        sys.path.append(path)
        pkg_resources.fixup_namespace_packages(path)

    # Load plugins and backends.
    return load_backends_and_plugins(plugins, working_set, backend_packages)
    def syspath_prepend(self, path):
        """ Prepend ``path`` to ``sys.path`` list of import locations. """
        from pkg_resources import fixup_namespace_packages

        if self._savesyspath is None:
            self._savesyspath = sys.path[:]
        sys.path.insert(0, str(path))

        # https://github.com/pypa/setuptools/blob/d8b901bc/docs/pkg_resources.txt#L162-L171
        fixup_namespace_packages(str(path))
Example #5
0
    def _load_plugins(self):
        # Add any extra paths to python path (e.g., for loading extra source backends).
        for path in self._bootstrap_options.pythonpath:
            if path not in sys.path:
                sys.path.append(path)
                pkg_resources.fixup_namespace_packages(path)

        # Load plugins and backends.
        return load_backends_and_plugins(
            self._bootstrap_options.plugins, self._bootstrap_options.plugins2,
            self._working_set, self._bootstrap_options.backend_packages,
            self._bootstrap_options.backend_packages2, BuildConfiguration())
Example #6
0
  def _load_plugins(self, working_set, python_paths, plugins, backend_packages):
    """Load backends and plugins.

    :returns: A `BuildConfiguration` object constructed during backend/plugin loading.
    """
    # Add any extra paths to python path (e.g., for loading extra source backends).
    for path in python_paths:
      if path not in sys.path:
        sys.path.append(path)
        pkg_resources.fixup_namespace_packages(path)

    # Load plugins and backends.
    return load_backends_and_plugins(plugins, working_set, backend_packages)
Example #7
0
    def _setup_options(self, options_bootstrapper, working_set):
        # TODO: This inline import is currently necessary to resolve a ~legitimate cycle between
        # `GoalRunner`->`EngineInitializer`->`OptionsInitializer`->`GoalRunner`.
        from pants.bin.goal_runner import GoalRunner

        bootstrap_options = options_bootstrapper.get_bootstrap_options()
        global_bootstrap_options = bootstrap_options.for_global_scope()

        if global_bootstrap_options.pants_version != pants_version():
            raise BuildConfigurationError(
                'Version mismatch: Requested version was {}, our version is {}.'
                .format(global_bootstrap_options.pants_version,
                        pants_version()))

        # Get logging setup prior to loading backends so that they can log as needed.
        if self._init_logging:
            self._setup_logging(global_bootstrap_options)

        # Add any extra paths to python path (e.g., for loading extra source backends).
        for path in global_bootstrap_options.pythonpath:
            sys.path.append(path)
            pkg_resources.fixup_namespace_packages(path)

        # Load plugins and backends.
        plugins = global_bootstrap_options.plugins
        backend_packages = global_bootstrap_options.backend_packages
        build_configuration = load_backends_and_plugins(
            plugins, working_set, backend_packages)

        # Now that plugins and backends are loaded, we can gather the known scopes.
        known_scope_infos = [GlobalOptionsRegistrar.get_scope_info()]

        # Add scopes for all needed subsystems via a union of all known subsystem sets.
        subsystems = Subsystem.closure(GoalRunner.subsystems()
                                       | Goal.subsystems()
                                       | build_configuration.subsystems())
        for subsystem in subsystems:
            known_scope_infos.append(subsystem.get_scope_info())

        # Add scopes for all tasks in all goals.
        for goal in Goal.all():
            known_scope_infos.extend(filter(None, goal.known_scope_infos()))

        # Now that we have the known scopes we can get the full options.
        options = options_bootstrapper.get_full_options(known_scope_infos)
        self._register_options(subsystems, options)

        # Make the options values available to all subsystems.
        Subsystem.set_options(options)

        return options, build_configuration
Example #8
0
  def _setup_options(self, options_bootstrapper, working_set):
    # TODO: This inline import is currently necessary to resolve a ~legitimate cycle between
    # `GoalRunner`->`EngineInitializer`->`OptionsInitializer`->`GoalRunner`.
    from pants.bin.goal_runner import GoalRunner

    bootstrap_options = options_bootstrapper.get_bootstrap_options()
    global_bootstrap_options = bootstrap_options.for_global_scope()

    if global_bootstrap_options.pants_version != pants_version():
      raise BuildConfigurationError(
        'Version mismatch: Requested version was {}, our version is {}.'.format(
          global_bootstrap_options.pants_version, pants_version()
        )
      )

    # Get logging setup prior to loading backends so that they can log as needed.
    if self._init_logging:
      self._setup_logging(global_bootstrap_options)

    # Add any extra paths to python path (e.g., for loading extra source backends).
    for path in global_bootstrap_options.pythonpath:
      sys.path.append(path)
      pkg_resources.fixup_namespace_packages(path)

    # Load plugins and backends.
    plugins = global_bootstrap_options.plugins
    backend_packages = global_bootstrap_options.backend_packages
    build_configuration = load_plugins_and_backends(plugins, working_set, backend_packages)

    # Now that plugins and backends are loaded, we can gather the known scopes.
    known_scope_infos = [GlobalOptionsRegistrar.get_scope_info()]

    # Add scopes for all needed subsystems via a union of all known subsystem sets.
    subsystems = Subsystem.closure(
      GoalRunner.subsystems() | Goal.subsystems() | build_configuration.subsystems()
    )
    for subsystem in subsystems:
      known_scope_infos.append(subsystem.get_scope_info())

    # Add scopes for all tasks in all goals.
    for goal in Goal.all():
      known_scope_infos.extend(filter(None, goal.known_scope_infos()))

    # Now that we have the known scopes we can get the full options.
    options = options_bootstrapper.get_full_options(known_scope_infos)
    self._register_options(subsystems, options)

    # Make the options values available to all subsystems.
    Subsystem.set_options(options)

    return options, build_configuration
Example #9
0
    def _setup_options(self, options_bootstrapper, working_set):
        bootstrap_options = options_bootstrapper.get_bootstrap_options()
        global_bootstrap_options = bootstrap_options.for_global_scope()

        # The pants_version may be set in pants.ini for bootstrapping, so we make sure the user actually
        # requested the version on the command line before deciding to print the version and exit.
        if global_bootstrap_options.is_flagged('pants_version'):
            print(global_bootstrap_options.pants_version)
            self._exiter(0)

        # Get logging setup prior to loading backends so that they can log as needed.
        self._setup_logging(global_bootstrap_options)

        # Add any extra paths to python path (e.g., for loading extra source backends).
        for path in global_bootstrap_options.pythonpath:
            sys.path.append(path)
            pkg_resources.fixup_namespace_packages(path)

        # Load plugins and backends.
        plugins = global_bootstrap_options.plugins
        backend_packages = global_bootstrap_options.backend_packages
        build_configuration = load_plugins_and_backends(
            plugins, working_set, backend_packages)

        # Now that plugins and backends are loaded, we can gather the known scopes.
        known_scope_infos = [GlobalOptionsRegistrar.get_scope_info()]

        # Add scopes for all needed subsystems via a union of all known subsystem sets.
        subsystems = Subsystem.closure(GoalRunner.subsystems()
                                       | Goal.subsystems()
                                       | build_configuration.subsystems())
        for subsystem in subsystems:
            known_scope_infos.append(subsystem.get_scope_info())

        # Add scopes for all tasks in all goals.
        for goal in Goal.all():
            known_scope_infos.extend(filter(None, goal.known_scope_infos()))

        # Now that we have the known scopes we can get the full options.
        options = options_bootstrapper.get_full_options(known_scope_infos)
        self._register_options(subsystems, options)

        # Make the options values available to all subsystems.
        Subsystem.set_options(options)

        return options, build_configuration
Example #10
0
  def _setup_options(self, options_bootstrapper, working_set):
    bootstrap_options = options_bootstrapper.get_bootstrap_options()
    global_bootstrap_options = bootstrap_options.for_global_scope()

    # The pants_version may be set in pants.ini for bootstrapping, so we make sure the user actually
    # requested the version on the command line before deciding to print the version and exit.
    if global_bootstrap_options.is_flagged('pants_version'):
      print(global_bootstrap_options.pants_version)
      self._exiter(0)

    # Get logging setup prior to loading backends so that they can log as needed.
    self._setup_logging(global_bootstrap_options)

    # Add any extra paths to python path (e.g., for loading extra source backends).
    for path in global_bootstrap_options.pythonpath:
      sys.path.append(path)
      pkg_resources.fixup_namespace_packages(path)

    # Load plugins and backends.
    plugins = global_bootstrap_options.plugins
    backend_packages = global_bootstrap_options.backend_packages
    build_configuration = load_plugins_and_backends(plugins, working_set, backend_packages)

    # Now that plugins and backends are loaded, we can gather the known scopes.
    known_scope_infos = [GlobalOptionsRegistrar.get_scope_info()]

    # Add scopes for all needed subsystems via a union of all known subsystem sets.
    subsystems = Subsystem.closure(
      GoalRunner.subsystems() | Goal.subsystems() | build_configuration.subsystems()
    )
    for subsystem in subsystems:
      known_scope_infos.append(subsystem.get_scope_info())

    # Add scopes for all tasks in all goals.
    for goal in Goal.all():
      known_scope_infos.extend(filter(None, goal.known_scope_infos()))

    # Now that we have the known scopes we can get the full options.
    options = options_bootstrapper.get_full_options(known_scope_infos)
    self._register_options(subsystems, options)

    # Make the options values available to all subsystems.
    Subsystem.set_options(options)

    return options, build_configuration
Example #11
0
    def syspathinsert(self, path=None):
        """Prepend a directory to sys.path, defaults to :py:attr:`tmpdir`.

        This is undone automatically when this object dies at the end of each
        test.
        """
        from pkg_resources import fixup_namespace_packages

        if path is None:
            path = self.tmpdir

        dirname = str(path)
        sys.path.insert(0, dirname)
        fixup_namespace_packages(dirname)

        # a call to syspathinsert() usually means that the caller wants to
        # import some dynamically created files, thus with python3 we
        # invalidate its import caches
        self._possibly_invalidate_import_caches()
Example #12
0
    def syspathinsert(self, path=None):
        """Prepend a directory to sys.path, defaults to :py:attr:`tmpdir`.

        This is undone automatically when this object dies at the end of each
        test.
        """
        from pkg_resources import fixup_namespace_packages

        if path is None:
            path = self.tmpdir

        dirname = str(path)
        sys.path.insert(0, dirname)
        fixup_namespace_packages(dirname)

        # a call to syspathinsert() usually means that the caller wants to
        # import some dynamically created files, thus with python3 we
        # invalidate its import caches
        self._possibly_invalidate_import_caches()
Example #13
0
    def syspath_prepend(self, path) -> None:
        """Prepend ``path`` to ``sys.path`` list of import locations."""
        from pkg_resources import fixup_namespace_packages

        if self._savesyspath is None:
            self._savesyspath = sys.path[:]
        sys.path.insert(0, str(path))

        # https://github.com/pypa/setuptools/blob/d8b901bc/docs/pkg_resources.txt#L162-L171
        fixup_namespace_packages(str(path))

        # A call to syspathinsert() usually means that the caller wants to
        # import some dynamically created files, thus with python3 we
        # invalidate its import caches.
        # This is especially important when any namespace package is in use,
        # since then the mtime based FileFinder cache (that gets created in
        # this case already) gets not invalidated when writing the new files
        # quickly afterwards.
        from importlib import invalidate_caches

        invalidate_caches()
Example #14
0
def PrepareProtobuf():
    CHROME_SRC = os.path.abspath(
        os.path.join(os.path.dirname(os.path.realpath(__file__)), "..", "..",
                     ".."))
    THIRD_PARTY = os.path.join(CHROME_SRC, 'third_party')
    sys.path.insert(0, os.path.join(THIRD_PARTY, 'protobuf', 'python'))
    sys.path.insert(
        1, os.path.join(THIRD_PARTY, 'protobuf', 'third_party', 'six'))

    @contextlib.contextmanager
    def temp_sys_path():
        orig_path = sys.path[:]
        try:
            yield
        finally:
            sys.path = orig_path

    with temp_sys_path():
        sys.path = [THIRD_PARTY]
        sys.modules.pop('google', None)
        pkg_resources.declare_namespace('google')
        pkg_resources.fixup_namespace_packages(THIRD_PARTY)
Example #15
0
    def syspath_prepend(self, path):
        """ Prepend ``path`` to ``sys.path`` list of import locations. """
        from pkg_resources import fixup_namespace_packages

        if self._savesyspath is None:
            self._savesyspath = sys.path[:]
        sys.path.insert(0, str(path))

        # https://github.com/pypa/setuptools/blob/d8b901bc/docs/pkg_resources.txt#L162-L171
        fixup_namespace_packages(str(path))

        # A call to syspathinsert() usually means that the caller wants to
        # import some dynamically created files, thus with python3 we
        # invalidate its import caches.
        # This is especially important when any namespace package is in used,
        # since then the mtime based FileFinder cache (that gets created in
        # this case already) gets not invalidated when writing the new files
        # quickly afterwards.
        if sys.version_info >= (3, 3):
            from importlib import invalidate_caches

            invalidate_caches()
Example #16
0
    #    library.
    # c) Build our standard first-is-preferred path for the remainder of the
    #    engine.
    import pkg_resources
    with temp_sys_path():
        # In a temporary environment where "sys.path" consists solely of our
        # "third_party" directory, register the google namespace. By restricting the
        # options in "sys.path", "pkg_resources" will not cache or prefer system
        # resources for this namespace or its derivatives.
        sys.path = [THIRD_PARTY]

        # Remove module if there is preloaded 'google' module
        sys.modules.pop('google', None)

        pkg_resources.declare_namespace('google')
        pkg_resources.fixup_namespace_packages(THIRD_PARTY)

    # From here on out, we're back to normal imports. Let's assert that the we're
    # using the correct protobuf package, though.
    #
    # We use "realpath" here because the importer may resolve the path differently
    # based on symlinks, and we want to make sure our calculated path matches the
    # impoter's path regardless.
    import google.protobuf
    assert (os.path.realpath(THIRD_PARTY)
            in os.path.realpath(google.protobuf.__path__[0]))


# Prune all VirtualEnv paths out of $PATH. This means that recipe engine
# 'unwraps' vpython VirtualEnv path manipulation. Invocations of `python` from
# recipes should never inherit the recipe engine's own VirtualEnv.
Example #17
0
  def setup(self):
    options_bootstrapper = OptionsBootstrapper()

    # Force config into the cache so we (and plugin/backend loading code) can use it.
    # TODO: Plumb options in explicitly.
    bootstrap_options = options_bootstrapper.get_bootstrap_options()
    self.config = Config.from_cache()

    # Get logging setup prior to loading backends so that they can log as needed.
    self._setup_logging(bootstrap_options.for_global_scope())

    # Add any extra paths to python path (eg for loading extra source backends)
    for path in bootstrap_options.for_global_scope().pythonpath:
      sys.path.append(path)
      pkg_resources.fixup_namespace_packages(path)

    # Load plugins and backends.
    backend_packages = self.config.getlist('backends', 'packages', [])
    plugins = self.config.getlist('backends', 'plugins', [])
    build_configuration = load_plugins_and_backends(plugins, backend_packages)

    # Now that plugins and backends are loaded, we can gather the known scopes.
    self.targets = []
    # TODO: Create a 'Subsystem' abstraction instead of special-casing run-tracker here
    # and in register_options().
    known_scopes = ['', 'run-tracker']
    for goal in Goal.all():
      # Note that enclosing scopes will appear before scopes they enclose.
      known_scopes.extend(filter(None, goal.known_scopes()))

    # Now that we have the known scopes we can get the full options.
    self.options = options_bootstrapper.get_full_options(known_scopes=known_scopes)
    self.register_options()

    self.run_tracker = RunTracker.from_options(self.options)
    report = initial_reporting(self.config, self.run_tracker)
    self.run_tracker.start(report)
    url = self.run_tracker.run_info.get_info('report_url')
    if url:
      self.run_tracker.log(Report.INFO, 'See a report at: %s' % url)
    else:
      self.run_tracker.log(Report.INFO, '(To run a reporting server: ./pants server)')

    self.build_file_parser = BuildFileParser(build_configuration=build_configuration,
                                             root_dir=self.root_dir,
                                             run_tracker=self.run_tracker)
    self.address_mapper = BuildFileAddressMapper(self.build_file_parser)
    self.build_graph = BuildGraph(run_tracker=self.run_tracker,
                                  address_mapper=self.address_mapper)

    with self.run_tracker.new_workunit(name='bootstrap', labels=[WorkUnit.SETUP]):
      # construct base parameters to be filled in for BuildGraph
      for path in self.config.getlist('goals', 'bootstrap_buildfiles', default=[]):
        build_file = BuildFile.from_cache(root_dir=self.root_dir, relpath=path)
        # TODO(pl): This is an unfortunate interface leak, but I don't think
        # in the long run that we should be relying on "bootstrap" BUILD files
        # that do nothing except modify global state.  That type of behavior
        # (e.g. source roots, goal registration) should instead happen in
        # project plugins, or specialized configuration files.
        self.build_file_parser.parse_build_file_family(build_file)

    # Now that we've parsed the bootstrap BUILD files, and know about the SCM system.
    self.run_tracker.run_info.add_scm_info()

    self._expand_goals_and_specs()
Example #18
0
  def setup(self, options_bootstrapper, working_set):
    bootstrap_options = options_bootstrapper.get_bootstrap_options()
    global_bootstrap_options = bootstrap_options.for_global_scope()

    # The pants_version may be set in pants.ini for bootstrapping, so we make sure the user actually
    # requested the version on the command line before deciding to print the version and exit.
    if global_bootstrap_options.is_flagged('pants_version'):
      print(global_bootstrap_options.pants_version)
      self._exiter(0)

    # Get logging setup prior to loading backends so that they can log as needed.
    self._setup_logging(global_bootstrap_options)

    # Add any extra paths to python path (e.g., for loading extra source backends).
    for path in global_bootstrap_options.pythonpath:
      sys.path.append(path)
      pkg_resources.fixup_namespace_packages(path)

    # Load plugins and backends.
    plugins = global_bootstrap_options.plugins
    backend_packages = global_bootstrap_options.backend_packages
    build_configuration = load_plugins_and_backends(plugins, working_set, backend_packages)

    # Now that plugins and backends are loaded, we can gather the known scopes.
    self.targets = []

    known_scope_infos = [GlobalOptionsRegistrar.get_scope_info()]

    # Add scopes for all needed subsystems.
    subsystems = Subsystem.closure(set(self.subsystems) |
                                   Goal.subsystems() |
                                   build_configuration.subsystems())
    for subsystem in subsystems:
      known_scope_infos.append(subsystem.get_scope_info())

    # Add scopes for all tasks in all goals.
    for goal in Goal.all():
      known_scope_infos.extend(filter(None, goal.known_scope_infos()))

    # Now that we have the known scopes we can get the full options.
    self.options = options_bootstrapper.get_full_options(known_scope_infos)
    self.register_options(subsystems)

    # Make the options values available to all subsystems.
    Subsystem._options = self.options

    # Now that we have options we can instantiate subsystems.
    self.run_tracker = RunTracker.global_instance()
    self.reporting = Reporting.global_instance()
    report = self.reporting.initial_reporting(self.run_tracker)
    self.run_tracker.start(report)
    url = self.run_tracker.run_info.get_info('report_url')
    if url:
      self.run_tracker.log(Report.INFO, 'See a report at: {}'.format(url))
    else:
      self.run_tracker.log(Report.INFO, '(To run a reporting server: ./pants server)')

    self.build_file_parser = BuildFileParser(build_configuration=build_configuration,
                                             root_dir=self.root_dir,
                                             run_tracker=self.run_tracker)

    rev = self.options.for_global_scope().build_file_rev
    if rev:
      ScmBuildFile.set_rev(rev)
      ScmBuildFile.set_scm(get_scm())
      build_file_type = ScmBuildFile
    else:
      build_file_type = FilesystemBuildFile
    self.address_mapper = BuildFileAddressMapper(self.build_file_parser, build_file_type)
    self.build_graph = BuildGraph(run_tracker=self.run_tracker,
                                  address_mapper=self.address_mapper)

    # TODO(John Sirois): Kill when source root registration is lifted out of BUILD files.
    with self.run_tracker.new_workunit(name='bootstrap', labels=[WorkUnitLabel.SETUP]):
      source_root_bootstrapper = SourceRootBootstrapper.global_instance()
      source_root_bootstrapper.bootstrap(self.address_mapper, self.build_file_parser)

    self._expand_goals_and_specs()

    # Now that we've parsed the bootstrap BUILD files, and know about the SCM system.
    self.run_tracker.run_info.add_scm_info()
Example #19
0
    def setUp(self):
        """Set up testcase."""
        super(EnhancedTestCase, self).setUp()

        # make sure option parser doesn't pick up any cmdline arguments/options
        while len(sys.argv) > 1:
            sys.argv.pop()

        # keep track of log handlers
        log = fancylogger.getLogger(fname=False)
        self.orig_log_handlers = log.handlers[:]

        log.info("setting up test %s" % self.id())

        self.orig_tmpdir = tempfile.gettempdir()
        # use a subdirectory for this test (which we can clean up easily after the test completes)
        self.test_prefix = set_tmpdir()

        self.log = fancylogger.getLogger(self.__class__.__name__, fname=False)
        fd, self.logfile = tempfile.mkstemp(suffix='.log', prefix='eb-test-')
        os.close(fd)
        self.cwd = os.getcwd()

        # keep track of original environment to restore
        self.orig_environ = copy.deepcopy(os.environ)

        # keep track of original environment/Python search path to restore
        self.orig_sys_path = sys.path[:]

        testdir = os.path.dirname(os.path.abspath(__file__))

        self.test_sourcepath = os.path.join(testdir, 'sandbox', 'sources')
        os.environ['EASYBUILD_SOURCEPATH'] = self.test_sourcepath
        os.environ['EASYBUILD_PREFIX'] = self.test_prefix
        self.test_buildpath = tempfile.mkdtemp()
        os.environ['EASYBUILD_BUILDPATH'] = self.test_buildpath
        self.test_installpath = tempfile.mkdtemp()
        os.environ['EASYBUILD_INSTALLPATH'] = self.test_installpath

        # make sure that the tests only pick up easyconfigs provided with the tests
        os.environ['EASYBUILD_ROBOT_PATHS'] = os.path.join(testdir, 'easyconfigs')

        # make sure no deprecated behaviour is being triggered (unless intended by the test)
        # trip *all* log.deprecated statements by setting deprecation version ridiculously high
        self.orig_current_version = eb_build_log.CURRENT_VERSION
        os.environ['EASYBUILD_DEPRECATED'] = '10000000'

        init_config()

        import easybuild
        # try to import easybuild.easyblocks(.generic) packages
        # it's OK if it fails here, but important to import first before fiddling with sys.path
        try:
            import easybuild.easyblocks
            import easybuild.easyblocks.generic
        except ImportError:
            pass

        # add sandbox to Python search path, update namespace packages
        sys.path.append(os.path.join(testdir, 'sandbox'))

        # workaround for bug in recent setuptools version (19.4 and newer, atleast until 20.3.1)
        # injecting <prefix>/easybuild is required to avoid a ValueError being thrown by fixup_namespace_packages
        # cfr. https://bitbucket.org/pypa/setuptools/issues/520/fixup_namespace_packages-may-trigger
        for path in sys.path[:]:
            if os.path.exists(os.path.join(path, 'easybuild', 'easyblocks', '__init__.py')):
                # keep track of 'easybuild' paths to inject into sys.path later
                sys.path.append(os.path.join(path, 'easybuild'))

        # required to make sure the 'easybuild' dir in the sandbox is picked up;
        # this relates to the other 'reload' statements below
        reload(easybuild)

        # this is strictly required to make the test modules in the sandbox available, due to declare_namespace
        fixup_namespace_packages(os.path.join(testdir, 'sandbox'))

        # remove any entries in Python search path that seem to provide easyblocks (except the sandbox)
        for path in sys.path[:]:
            if os.path.exists(os.path.join(path, 'easybuild', 'easyblocks', '__init__.py')):
                if not os.path.samefile(path, os.path.join(testdir, 'sandbox')):
                    sys.path.remove(path)

        # hard inject location to (generic) test easyblocks into Python search path
        # only prepending to sys.path is not enough due to 'declare_namespace' in easybuild/easyblocks/__init__.py
        import easybuild.easyblocks
        reload(easybuild.easyblocks)
        test_easyblocks_path = os.path.join(testdir, 'sandbox', 'easybuild', 'easyblocks')
        easybuild.easyblocks.__path__.insert(0, test_easyblocks_path)
        import easybuild.easyblocks.generic
        reload(easybuild.easyblocks.generic)
        test_easyblocks_path = os.path.join(test_easyblocks_path, 'generic')
        easybuild.easyblocks.generic.__path__.insert(0, test_easyblocks_path)

        # save values of $PATH & $PYTHONPATH, so they can be restored later
        # this is important in case EasyBuild was installed as a module, since that module may be unloaded,
        # for example due to changes to $MODULEPATH in case EasyBuild was installed in a module hierarchy
        # cfr. https://github.com/hpcugent/easybuild-framework/issues/1685
        self.env_path = os.environ['PATH']
        self.env_pythonpath = os.environ['PYTHONPATH']

        self.modtool = modules_tool()
        self.reset_modulepath([os.path.join(testdir, 'modules')])
        reset_module_caches()
Example #20
0
  def setup(self):
    options_bootstrapper = OptionsBootstrapper()
    bootstrap_options = options_bootstrapper.get_bootstrap_options()

    # Get logging setup prior to loading backends so that they can log as needed.
    self._setup_logging(bootstrap_options.for_global_scope())

    # Add any extra paths to python path (eg for loading extra source backends)
    for path in bootstrap_options.for_global_scope().pythonpath:
      sys.path.append(path)
      pkg_resources.fixup_namespace_packages(path)

    # Load plugins and backends.
    plugins = bootstrap_options.for_global_scope().plugins
    backend_packages = bootstrap_options.for_global_scope().backend_packages
    build_configuration = load_plugins_and_backends(plugins, backend_packages)

    # Now that plugins and backends are loaded, we can gather the known scopes.
    self.targets = []

    known_scope_infos = [ScopeInfo.for_global_scope()]

    # Add scopes for all needed subsystems.
    subsystems = (set(self.subsystems) | Goal.subsystems() | build_configuration.subsystems())
    for subsystem in subsystems:
      known_scope_infos.append(ScopeInfo(subsystem.options_scope, ScopeInfo.GLOBAL_SUBSYSTEM))

    # Add scopes for all tasks in all goals.
    for goal in Goal.all():
      known_scope_infos.extend(filter(None, goal.known_scope_infos()))

    # Now that we have the known scopes we can get the full options.
    self.options = options_bootstrapper.get_full_options(known_scope_infos)
    self.register_options(subsystems)

    # Make the options values available to all subsystems.
    Subsystem._options = self.options

    # Now that we have options we can instantiate subsystems.
    self.run_tracker = RunTracker.global_instance()
    self.reporting = Reporting.global_instance()
    report = self.reporting.initial_reporting(self.run_tracker)
    self.run_tracker.start(report)
    url = self.run_tracker.run_info.get_info('report_url')
    if url:
      self.run_tracker.log(Report.INFO, 'See a report at: {}'.format(url))
    else:
      self.run_tracker.log(Report.INFO, '(To run a reporting server: ./pants server)')

    self.build_file_parser = BuildFileParser(build_configuration=build_configuration,
                                             root_dir=self.root_dir,
                                             run_tracker=self.run_tracker)

    rev = self.options.for_global_scope().build_file_rev
    if rev:
      ScmBuildFile.set_rev(rev)
      ScmBuildFile.set_scm(get_scm())
      build_file_type = ScmBuildFile
    else:
      build_file_type = FilesystemBuildFile
    self.address_mapper = BuildFileAddressMapper(self.build_file_parser, build_file_type)
    self.build_graph = BuildGraph(run_tracker=self.run_tracker,
                                  address_mapper=self.address_mapper)

    # TODO(John Sirois): Kill when source root registration is lifted out of BUILD files.
    with self.run_tracker.new_workunit(name='bootstrap', labels=[WorkUnit.SETUP]):
      source_root_bootstrapper = SourceRootBootstrapper.global_instance()
      source_root_bootstrapper.bootstrap(self.address_mapper, self.build_file_parser)

    self._expand_goals_and_specs()

    # Now that we've parsed the bootstrap BUILD files, and know about the SCM system.
    self.run_tracker.run_info.add_scm_info()
Example #21
0
    def setup(self):
        options_bootstrapper = OptionsBootstrapper()

        # Force config into the cache so we (and plugin/backend loading code) can use it.
        # TODO: Plumb options in explicitly.
        bootstrap_options = options_bootstrapper.get_bootstrap_options()
        self.config = Config.from_cache()

        # Add any extra paths to python path (eg for loading extra source backends)
        for path in bootstrap_options.for_global_scope().pythonpath:
            sys.path.append(path)
            pkg_resources.fixup_namespace_packages(path)

        # Load plugins and backends.
        backend_packages = self.config.getlist('backends', 'packages', [])
        plugins = self.config.getlist('backends', 'plugins', [])
        build_configuration = load_plugins_and_backends(
            plugins, backend_packages)

        # Now that plugins and backends are loaded, we can gather the known scopes.
        self.targets = []
        # TODO: Create a 'Subsystem' abstraction instead of special-casing run-tracker here
        # and in register_options().
        known_scopes = ['', 'run-tracker']
        for goal in Goal.all():
            # Note that enclosing scopes will appear before scopes they enclose.
            known_scopes.extend(filter(None, goal.known_scopes()))

        # Now that we have the known scopes we can get the full options.
        self.options = options_bootstrapper.get_full_options(
            known_scopes=known_scopes)
        self.register_options()

        # TODO(Eric Ayers) We are missing log messages. Set the log level earlier
        # Enable standard python logging for code with no handle to a context/work-unit.
        self._setup_logging()  # NB: self.options are needed for this call.

        self.run_tracker = RunTracker.from_options(self.options)
        report = initial_reporting(self.config, self.run_tracker)
        self.run_tracker.start(report)
        url = self.run_tracker.run_info.get_info('report_url')
        if url:
            self.run_tracker.log(Report.INFO, 'See a report at: %s' % url)
        else:
            self.run_tracker.log(
                Report.INFO, '(To run a reporting server: ./pants server)')

        self.build_file_parser = BuildFileParser(
            build_configuration=build_configuration,
            root_dir=self.root_dir,
            run_tracker=self.run_tracker)
        self.address_mapper = BuildFileAddressMapper(self.build_file_parser)
        self.build_graph = BuildGraph(run_tracker=self.run_tracker,
                                      address_mapper=self.address_mapper)

        with self.run_tracker.new_workunit(name='bootstrap',
                                           labels=[WorkUnit.SETUP]):
            # construct base parameters to be filled in for BuildGraph
            for path in self.config.getlist('goals',
                                            'bootstrap_buildfiles',
                                            default=[]):
                build_file = BuildFile.from_cache(root_dir=self.root_dir,
                                                  relpath=path)
                # TODO(pl): This is an unfortunate interface leak, but I don't think
                # in the long run that we should be relying on "bootstrap" BUILD files
                # that do nothing except modify global state.  That type of behavior
                # (e.g. source roots, goal registration) should instead happen in
                # project plugins, or specialized configuration files.
                self.build_file_parser.parse_build_file_family(build_file)

        # Now that we've parsed the bootstrap BUILD files, and know about the SCM system.
        self.run_tracker.run_info.add_scm_info()

        self._expand_goals_and_specs()
Example #22
0
def ROS_setup_pythonpath(workspace):

    # TODO : support python3 using checks like : sys.version_info >= (2, 7)
    # for indigo, python3 is better supported via virtual envs to not conflict with system install.
    package_paths = [
        os.path.join(workspace, 'lib', 'python2.7',
                     'dist-packages'),  # default for catkin
        os.path.join(
            workspace, 'lib', 'python2.7', 'site-packages'
        ),  # catkin_pip can create this in workspaces and we need to be able to access it
    ]

    # since ROS logic with package path is *incompatible* with python / venv logic
    # inspired from python site module (getting rid of known_path)
    def readdsitedir(sitedir):
        """Add 'sitedir' argument to sys.path if missing and handle .pth files in
        'sitedir'"""
        sitedir, sitedircase = site.makepath(sitedir)
        print("Re-adding {sitedir} in front of sys.path".format(**locals()))
        if sitedir in sys.path:
            sys.path.remove(sitedir)  # Remove path component
        sys.path.insert(1, sitedir)  # Insert path component in front
        try:
            names = os.listdir(sitedir)
        except os.error:
            return
        dotpth = os.extsep + "pth"
        names = [name for name in names if name.endswith(dotpth)]
        for name in sorted(names):
            readdpackage(sitedir, name)
        return

    # since ROS logic with package path is *incompatible* with python / venv logic
    # inspired from python site module (getting rid of known_path)
    def readdpackage(sitedir, name):
        """Process a .pth file within the site-packages directory:
           For each line in the file, if it doesnt start with 'import ', combine it with sitedir to a path
           and remove that from sys.path.
        """
        # All this code is inspired from site.addpackage
        fullname = os.path.join(sitedir, name)
        try:
            f = open(fullname, "rU")
        except IOError:
            return
        with f:
            for n, line in enumerate(f):
                if line.startswith("#") or line.startswith(
                    ("import ", "import\t")):
                    continue
                try:
                    line = line.rstrip()
                    dir, dircase = site.makepath(sitedir, line)
                    # If the path is already there, we remove it (to reinsert it in the proper place)
                    print("Re-adding {dir} in front of sys.path".format(
                        **locals()))
                    if dir in sys.path:
                        sys.path.remove(dir)
                    sys.path.insert(1, dir)
                except Exception as err:
                    print("Error processing line {:d} of {}:\n".format(
                        n + 1, fullname),
                          file=sys.stderr)
                    for record in traceback.format_exception(*sys.exc_info()):
                        for line in record.splitlines():
                            print('  ' + line, file=sys.stderr)
                    print("\nRemainder of file ignored", file=sys.stderr)
                    break

    # Note : virtualenvs are a much better solution to this problem,
    # but we have to simulate ROS behavior ( to work with ROS workspaces )

    # setting python path needed only to find ros shell commands (rosmaster)
    pplist = os.environ.get("PYTHONPATH", "").split(":")

    for pp in package_paths:
        if pp is not None and os.path.exists(pp):
            _logger.warning(
                "Prepending path {pp} to sys.path".format(**locals()))

            readdsitedir(pp)

            # similar logic for pythonpath as with readdsitedir
            if pp in pplist:
                pplist.remove(pp)
            pplist.insert(1, pp)

            # making sure our logic works for namespace packages as well
            pkg_resources.fixup_namespace_packages(
                pp)  # ensure that message subpackage is included

    os.environ["PYTHONPATH"] = ':'.join(pplist)
Example #23
0
    def setUp(self):
        """Set up testcase."""
        super(EnhancedTestCase, self).setUp()

        # make sure option parser doesn't pick up any cmdline arguments/options
        while len(sys.argv) > 1:
            sys.argv.pop()

        # keep track of log handlers
        log = fancylogger.getLogger(fname=False)
        self.orig_log_handlers = log.handlers[:]

        log.info("setting up test %s" % self.id())

        self.orig_tmpdir = tempfile.gettempdir()
        # use a subdirectory for this test (which we can clean up easily after the test completes)
        self.test_prefix = set_tmpdir()

        self.log = fancylogger.getLogger(self.__class__.__name__, fname=False)
        fd, self.logfile = tempfile.mkstemp(suffix='.log', prefix='eb-test-')
        os.close(fd)
        self.cwd = os.getcwd()

        # keep track of original environment to restore
        self.orig_environ = copy.deepcopy(os.environ)

        # keep track of original environment/Python search path to restore
        self.orig_sys_path = sys.path[:]

        testdir = os.path.dirname(os.path.abspath(__file__))

        self.test_sourcepath = os.path.join(testdir, 'sandbox', 'sources')
        os.environ['EASYBUILD_SOURCEPATH'] = self.test_sourcepath
        os.environ['EASYBUILD_PREFIX'] = self.test_prefix
        self.test_buildpath = tempfile.mkdtemp()
        os.environ['EASYBUILD_BUILDPATH'] = self.test_buildpath
        self.test_installpath = tempfile.mkdtemp()
        os.environ['EASYBUILD_INSTALLPATH'] = self.test_installpath

        # make sure that the tests only pick up easyconfigs provided with the tests
        os.environ['EASYBUILD_ROBOT_PATHS'] = os.path.join(
            testdir, 'easyconfigs')

        # make sure no deprecated behaviour is being triggered (unless intended by the test)
        # trip *all* log.deprecated statements by setting deprecation version ridiculously high
        self.orig_current_version = eb_build_log.CURRENT_VERSION
        os.environ['EASYBUILD_DEPRECATED'] = '10000000'

        init_config()

        import easybuild
        # try to import easybuild.easyblocks(.generic) packages
        # it's OK if it fails here, but important to import first before fiddling with sys.path
        try:
            import easybuild.easyblocks
            import easybuild.easyblocks.generic
        except ImportError:
            pass

        # add sandbox to Python search path, update namespace packages
        sys.path.append(os.path.join(testdir, 'sandbox'))

        # workaround for bug in recent setuptools version (19.4 and newer, atleast until 20.3.1)
        # injecting <prefix>/easybuild is required to avoid a ValueError being thrown by fixup_namespace_packages
        # cfr. https://bitbucket.org/pypa/setuptools/issues/520/fixup_namespace_packages-may-trigger
        for path in sys.path[:]:
            if os.path.exists(
                    os.path.join(path, 'easybuild', 'easyblocks',
                                 '__init__.py')):
                # keep track of 'easybuild' paths to inject into sys.path later
                sys.path.append(os.path.join(path, 'easybuild'))

        # required to make sure the 'easybuild' dir in the sandbox is picked up;
        # this relates to the other 'reload' statements below
        reload(easybuild)

        # this is strictly required to make the test modules in the sandbox available, due to declare_namespace
        fixup_namespace_packages(os.path.join(testdir, 'sandbox'))

        # remove any entries in Python search path that seem to provide easyblocks (except the sandbox)
        for path in sys.path[:]:
            if os.path.exists(
                    os.path.join(path, 'easybuild', 'easyblocks',
                                 '__init__.py')):
                if not os.path.samefile(path, os.path.join(testdir,
                                                           'sandbox')):
                    sys.path.remove(path)

        # hard inject location to (generic) test easyblocks into Python search path
        # only prepending to sys.path is not enough due to 'declare_namespace' in easybuild/easyblocks/__init__.py
        import easybuild.easyblocks
        reload(easybuild.easyblocks)
        test_easyblocks_path = os.path.join(testdir, 'sandbox', 'easybuild',
                                            'easyblocks')
        easybuild.easyblocks.__path__.insert(0, test_easyblocks_path)
        import easybuild.easyblocks.generic
        reload(easybuild.easyblocks.generic)
        test_easyblocks_path = os.path.join(test_easyblocks_path, 'generic')
        easybuild.easyblocks.generic.__path__.insert(0, test_easyblocks_path)

        # save values of $PATH & $PYTHONPATH, so they can be restored later
        # this is important in case EasyBuild was installed as a module, since that module may be unloaded,
        # for example due to changes to $MODULEPATH in case EasyBuild was installed in a module hierarchy
        # cfr. https://github.com/hpcugent/easybuild-framework/issues/1685
        self.env_path = os.environ['PATH']
        self.env_pythonpath = os.environ['PYTHONPATH']

        self.modtool = modules_tool()
        self.reset_modulepath([os.path.join(testdir, 'modules')])
        reset_module_caches()
Example #24
0
 def _fix_sys_path(self):
     new_sys_path = self._get_new_sys_path()
     for new_path in set(new_sys_path) - set(sys.path):
         sys.path.insert(0, new_path)
         pkg_resources.fixup_namespace_packages(new_path)