Пример #1
0
 def test_dependants_direct(self):
   a = MockTarget('a')
   b = MockTarget('b', a)
   c = MockTarget('c', b)
   d = MockTarget('d', c, a)
   e = MockTarget('e', d)
   context = Context(ContextTest.config, options={}, target_roots=[a, b, c, d, e])
   dependees = context.dependants(lambda t: t in set([e, c]))
   self.assertEquals(set([c]), dependees.pop(d))
   self.assertEquals(0, len(dependees))
Пример #2
0
 def test_dependents_direct(self):
   a = MockTarget('a')
   b = MockTarget('b', [a])
   c = MockTarget('c', [b])
   d = MockTarget('d', [c, a])
   e = MockTarget('e', [d])
   context = Context(ContextTest.config, options={}, target_roots=[a, b, c, d, e])
   dependees = context.dependents(lambda t: t in set([e, c]))
   self.assertEquals(set([c]), dependees.pop(d))
   self.assertEquals(0, len(dependees))
Пример #3
0
def prepare_task(task_type, config=None, args=None, targets=None, **kwargs):
    """Prepares a Task for execution.

  task_type: The class of the Task to create.
  config: An optional string representing the contents of a pants.ini config.
  args: optional list of command line flags, these should be prefixed with '--test-'.
  targets: optional list of Target objects passed on the command line.
  **kwargs: Any additional args the Task subclass constructor takes beyond the required context.

  Returns a new Task ready to execute.
  """

    assert issubclass(
        task_type,
        Task), 'task_type must be a Task subclass, got %s' % task_type

    config = create_config(config or '')

    parser = OptionParser()
    option_group = OptionGroup(parser, 'test')
    mkflag = Mkflag('test')
    task_type.setup_parser(option_group, args, mkflag)
    options, _ = parser.parse_args(args or [])

    run_tracker = create_run_tracker()

    context = Context(config, options, run_tracker, targets or [])
    return task_type(context, **kwargs)
Пример #4
0
  def run(self, lock):
    # TODO(John Sirois): Consider moving to straight python logging.  The divide between the
    # context/work-unit logging and standard python logging doesn't buy us anything.

    # Enable standard python logging for code with no handle to a context/work-unit.
    if self.options.log_level:
      LogOptions.set_stderr_log_level((self.options.log_level or 'info').upper())
      logdir = self.options.logdir or self.config.get('goals', 'logdir', default=None)
      if logdir:
        safe_mkdir(logdir)
        LogOptions.set_log_dir(logdir)
        log.init('goals')
      else:
        log.init()

    # Update the reporting settings, now that we have flags etc.
    def is_console_task():
      for phase in self.phases:
        for goal in phase.goals():
          if issubclass(goal.task_type, ConsoleTask):
            return True
      return False

    is_explain = self.options.explain
    update_reporting(self.options, is_console_task() or is_explain, self.run_tracker)

    if self.options.dry_run:
      print('****** Dry Run ******')

    context = Context(
      self.config,
      self.options,
      self.run_tracker,
      self.targets,
      requested_goals=self.requested_goals,
      lock=lock)

    if self.options.recursive_directory:
      context.log.warn(
        '--all-recursive is deprecated, use a target spec with the form [dir]:: instead')
      for dir in self.options.recursive_directory:
        self.add_target_recursive(dir)

    if self.options.target_directory:
      context.log.warn('--all is deprecated, use a target spec with the form [dir]: instead')
      for dir in self.options.target_directory:
        self.add_target_directory(dir)

    unknown = []
    for phase in self.phases:
      if not phase.goals():
        unknown.append(phase)

    if unknown:
      _list_goals(context, 'Unknown goal(s): %s' % ' '.join(phase.name for phase in unknown))
      return 1

    return Goal._execute(context, self.phases, print_timing=self.options.time)
Пример #5
0
 def execute(cls, context, *names):
   parser = OptionParser()
   cls.add_global_options(parser)
   phases = [Phase(name) for name in names]
   Phase.setup_parser(parser, [], phases)
   options, _ = parser.parse_args([])
   context = Context(context.config, options, context.run_tracker, context.target_roots,
                     requested_goals=list(names))
   return cls._execute(context, phases, print_timing=False)
Пример #6
0
    def run(self, lock):
        # Update the reporting settings, now that we have flags etc.
        def is_console_task():
            for phase in self.phases:
                for goal in phase.goals():
                    if issubclass(goal.task_type, ConsoleTask):
                        return True
            return False

        update_reporting(self.options, is_console_task(), self.run_tracker)

        if self.options.dry_run:
            print '****** Dry Run ******'

        context = Context(self.config,
                          self.options,
                          self.run_tracker,
                          self.targets,
                          requested_goals=self.requested_goals,
                          lock=lock)

        # TODO: Time to get rid of this hack.
        if self.options.recursive_directory:
            context.log.warn(
                '--all-recursive is deprecated, use a target spec with the form [dir]:: instead'
            )
            for dir in self.options.recursive_directory:
                self.add_target_recursive(dir)

        if self.options.target_directory:
            context.log.warn(
                '--all is deprecated, use a target spec with the form [dir]: instead'
            )
            for dir in self.options.target_directory:
                self.add_target_directory(dir)

        unknown = []
        for phase in self.phases:
            if not phase.goals():
                unknown.append(phase)

        if unknown:
            print('Unknown goal(s): %s' % ' '.join(phase.name
                                                   for phase in unknown))
            print('')
            return Phase.execute(context, 'goals')

        ret = Phase.attempt(context, self.phases)

        if self.options.cleanup_nailguns or self.config.get(
                'nailgun', 'autokill', default=False):
            if log:
                log.debug('auto-killing nailguns')
            if NailgunTask.killall:
                NailgunTask.killall(log)

        return ret
Пример #7
0
  def run(self, lock):
    with self.check_errors("Target contains a dependency cycle") as error:
      with self.timer.timing('parse:check_cycles'):
        for target in self.targets:
          try:
            InternalTarget.check_cycles(target)
          except InternalTarget.CycleException as e:
            error(target.id)

    logger = None
    if self.options.log or self.options.log_level:
      from twitter.common.log import init
      from twitter.common.log.options import LogOptions
      LogOptions.set_stderr_log_level((self.options.log_level or 'info').upper())
      logdir = self.options.logdir or self.config.get('goals', 'logdir', default=None)
      if logdir:
        safe_mkdir(logdir)
        LogOptions.set_log_dir(logdir)
        init('goals')
      else:
        init()
      logger = log

    if self.options.recursive_directory:
      log.warn('--all-recursive is deprecated, use a target spec with the form [dir]:: instead')
      for dir in self.options.recursive_directory:
        self.add_target_recursive(dir)

    if self.options.target_directory:
      log.warn('--all is deprecated, use a target spec with the form [dir]: instead')
      for dir in self.options.target_directory:
        self.add_target_directory(dir)

    context = Context(self.config, self.options, self.targets, lock=lock, log=logger)

    unknown = []
    for phase in self.phases:
      if not phase.goals():
        unknown.append(phase)

    if unknown:
        print('Unknown goal(s): %s' % ' '.join(phase.name for phase in unknown))
        print('')
        return Phase.execute(context, 'goals')

    if logger:
      logger.debug('Operating on targets: %s', self.targets)

    ret = Phase.attempt(context, self.phases, timer=self.timer if self.options.time else None)
    if self.options.time:
      print('Timing report')
      print('=============')
      self.timer.print_timings()
    return ret
Пример #8
0
 def testPartitioning(self):
   # Target e has conflicts; in this test, we want to check that partitioning
   # of valid targets works to prevent conflicts in chunks, so we only use a-d.
   a, b, c, d, _ = self.setupTargets()
   context = Context(ExclusivesTargetTest.config, options={}, run_tracker=None, target_roots=[a, b, c, d])
   context.products.require_data('exclusives_groups')
   check_exclusives_task = CheckExclusives(context, signal_error=True)
   check_exclusives_task.execute([a, b, c, d])
   egroups = context.products.get_data('exclusives_groups')
   self.assertEquals(egroups.get_targets_for_group_key("a=1"), set([a, b, d]))
   self.assertEquals(egroups.get_targets_for_group_key("a=2"), set([c]))
Пример #9
0
 def test_check_exclusives(self):
     a, b, c, d, e = self.setupTargets()
     context = Context(CheckExclusivesTest.config,
                       options={},
                       run_tracker=None,
                       target_roots=[d, e])
     check_exclusives_task = CheckExclusives(context, signal_error=True)
     try:
         check_exclusives_task.execute([d, e])
         self.fail(
             "Expected a conflicting exclusives exception to be thrown.")
     except TaskError:
         pass
Пример #10
0
def create_context(config='', options=None, target_roots=None, **kwargs):
    """Creates a ``Context`` with no config values, options, or targets by default.

  :param config: Either a ``Context`` object or else a string representing the contents of the
    pants.ini to parse the config from.
  :param options: An optional dict of of option values.
  :param target_roots: An optional list of target roots to seed the context target graph from.
  :param ``**kwargs``: Any additional keyword arguments to pass through to the Context constructor.
  """
    config = config if isinstance(config, Config) else create_config(config)
    run_tracker = create_run_tracker()
    target_roots = maybe_list(target_roots, Target) if target_roots else []
    return Context(config, create_options(options or {}), run_tracker,
                   target_roots, **kwargs)
Пример #11
0
    def test_check_exclusives(self):
        a = MockTarget('a', exclusives={'a': '1', 'b': '1'})
        b = MockTarget('b', exclusives={'a': '1'})
        c = MockTarget('c', exclusives={'a': '2'})
        d = MockTarget('d', dependencies=[a, b])
        e = MockTarget('e', dependencies=[a, c], exclusives={'c': '1'})

        context = Context(CheckExclusivesTest.config,
                          options={},
                          run_tracker=None,
                          target_roots=[d, e])
        check_exclusives_task = CheckExclusives(context, signal_error=True)
        try:
            check_exclusives_task.execute([d, e])
            self.fail(
                "Expected a conflicting exclusives exception to be thrown.")
        except TaskError:
            pass
Пример #12
0
    def testClasspathUpdates(self):
        # Check that exclusive groups classpaths accumulate properly.
        a = MockTarget('a', exclusives={'a': '1', 'b': '1'})
        b = MockTarget('b', exclusives={'a': '1', 'b': '<none>'})
        c = MockTarget('c', exclusives={'a': '2', 'b': '2'})
        d = MockTarget('d')

        context = Context(CheckExclusivesTest.config,
                          options={},
                          run_tracker=None,
                          target_roots=[a, b, c, d])
        context.products.require_data('exclusives_groups')
        check_exclusives_task = CheckExclusives(context, signal_error=True)
        check_exclusives_task.execute([a, b, c, d])
        egroups = context.products.get_data('exclusives_groups')

        egroups.set_base_classpath_for_group("a=1,b=1", ["a1", "b1"])
        egroups.set_base_classpath_for_group("a=1,b=<none>", ["a1"])
        egroups.set_base_classpath_for_group("a=2,b=2", ["a2", "b2"])
        egroups.set_base_classpath_for_group("a=<none>,b=<none>", ["none"])
        egroups.update_compatible_classpaths(None, ["update_without_group"])
        egroups.update_compatible_classpaths("a=<none>,b=<none>",
                                             ["update_all"])
        egroups.update_compatible_classpaths("a=1,b=<none>", ["update_a1bn"])
        egroups.update_compatible_classpaths("a=2,b=2", ["update_only_a2b2"])
        self.assertEquals(egroups.get_classpath_for_group("a=2,b=2"), [
            "a2", "b2", "update_without_group", "update_all",
            "update_only_a2b2"
        ])
        self.assertEquals(
            egroups.get_classpath_for_group("a=1,b=1"),
            ["a1", "b1", "update_without_group", "update_all", "update_a1bn"])
        self.assertEquals(
            egroups.get_classpath_for_group("a=1,b=<none>"),
            ["a1", "update_without_group", "update_all", "update_a1bn"])
        self.assertEquals(egroups.get_classpath_for_group("a=<none>,b=<none>"),
                          ["none", "update_without_group", "update_all"])

        # make sure repeated additions of the same thing are idempotent.
        egroups.update_compatible_classpaths("a=1,b=1", ["a1", "b1", "xxx"])
        self.assertEquals(egroups.get_classpath_for_group("a=1,b=1"), [
            "a1", "b1", "update_without_group", "update_all", "update_a1bn",
            "xxx"
        ])
Пример #13
0
def make_dag(nodes):
    return DoubleDag(nodes, lambda t: t.dependencies, Context.Log())
Пример #14
0
 def test_dependents_empty(self):
   context = Context(ContextTest.config, options={}, target_roots=[])
   dependees = context.dependents()
   self.assertEquals(0, len(dependees))
Пример #15
0
    def test_classpath_compatibility(self):
        # test the compatibility checks for different exclusive groups.
        a = MockTarget('a', exclusives={'a': '1', 'b': '1'})
        b = MockTarget('b', exclusives={'a': '1', 'b': '<none>'})
        c = MockTarget('c', exclusives={'a': '2', 'b': '2'})
        d = MockTarget('d')

        context = Context(CheckExclusivesTest.config,
                          options={},
                          run_tracker=None,
                          target_roots=[a, b, c, d])
        context.products.require_data('exclusives_groups')
        check_exclusives_task = CheckExclusives(context, signal_error=True)
        check_exclusives_task.execute([a, b, c, d])
        egroups = context.products.get_data('exclusives_groups')
        # Expected compatibility:
        # a is compatible with nothing but itself.
        self.assertTrue(
            egroups._is_compatible(egroups.target_to_key[a],
                                   egroups.target_to_key[a]))
        self.assertFalse(
            egroups._is_compatible(egroups.target_to_key[a],
                                   egroups.target_to_key[b]))
        self.assertFalse(
            egroups._is_compatible(egroups.target_to_key[a],
                                   egroups.target_to_key[d]))
        self.assertFalse(
            egroups._is_compatible(egroups.target_to_key[a],
                                   egroups.target_to_key[c]))

        # b is compatible with itself and a.
        self.assertTrue(
            egroups._is_compatible(egroups.target_to_key[b],
                                   egroups.target_to_key[a]))
        self.assertTrue(
            egroups._is_compatible(egroups.target_to_key[b],
                                   egroups.target_to_key[b]))
        self.assertFalse(
            egroups._is_compatible(egroups.target_to_key[b],
                                   egroups.target_to_key[c]))
        self.assertFalse(
            egroups._is_compatible(egroups.target_to_key[b],
                                   egroups.target_to_key[d]))

        # c is compatible with nothing but itself
        self.assertTrue(
            egroups._is_compatible(egroups.target_to_key[c],
                                   egroups.target_to_key[c]))
        self.assertFalse(
            egroups._is_compatible(egroups.target_to_key[c],
                                   egroups.target_to_key[a]))
        self.assertFalse(
            egroups._is_compatible(egroups.target_to_key[c],
                                   egroups.target_to_key[b]))
        self.assertFalse(
            egroups._is_compatible(egroups.target_to_key[c],
                                   egroups.target_to_key[d]))

        # d is compatible with everything.
        self.assertTrue(
            egroups._is_compatible(egroups.target_to_key[d],
                                   egroups.target_to_key[a]))
        self.assertTrue(
            egroups._is_compatible(egroups.target_to_key[d],
                                   egroups.target_to_key[b]))
        self.assertTrue(
            egroups._is_compatible(egroups.target_to_key[d],
                                   egroups.target_to_key[c]))
        self.assertTrue(
            egroups._is_compatible(egroups.target_to_key[d],
                                   egroups.target_to_key[d]))
Пример #16
0
    def run(self, lock):
        timer = None
        if self.options.time:

            class Timer(object):
                def now(self):
                    return time.time()

                def log(self, message):
                    print(message)

            timer = Timer()

        logger = None
        if self.options.log or self.options.log_level:
            from twitter.common.log import init
            from twitter.common.log.options import LogOptions
            LogOptions.set_stderr_log_level((self.options.log_level
                                             or 'info').upper())
            logdir = self.options.logdir or self.config.get(
                'goals', 'logdir', default=None)
            if logdir:
                safe_mkdir(logdir)
                LogOptions.set_log_dir(logdir)
                init('goals')
            else:
                init()
            logger = log

        if self.options.recursive_directory:
            log.warn(
                '--all-recursive is deprecated, use a target spec with the form [dir]:: instead'
            )
            for dir in self.options.recursive_directory:
                self.add_target_recursive(dir)

        if self.options.target_directory:
            log.warn(
                '--all is deprecated, use a target spec with the form [dir]: instead'
            )
            for dir in self.options.target_directory:
                self.add_target_directory(dir)

        context = Context(self.config,
                          self.options,
                          self.targets,
                          lock=lock,
                          log=logger)

        unknown = []
        for phase in self.phases:
            if not phase.goals():
                unknown.append(phase)

        if unknown:
            print('Unknown goal(s): %s' % ' '.join(phase.name
                                                   for phase in unknown))
            print('')
            return Phase.execute(context, 'goals')

        if logger:
            logger.debug('Operating on targets: %s', self.targets)

        return Phase.attempt(context, self.phases, timer=timer)
Пример #17
0
    def run(self, lock):
        # Update the reporting settings, now that we have flags etc.

        log_level = Report.log_level_from_string(self.options.log_level
                                                 or 'info')
        color = not self.options.no_color
        timing = self.options.time
        cache_stats = self.options.time  # TODO: Separate flag for this?

        settings_updates_map = {
            'console': {
                'log_level': log_level,
                'color': color,
                'timing': timing,
                'cache_stats': cache_stats
            },
            'html': {
                'log_level': log_level
            }
        }
        self.run_tracker.update_report_settings(settings_updates_map)
        # TODO: Do something useful with --logdir.

        if self.options.dry_run:
            print '****** Dry Run ******'

        context = Context(self.config,
                          self.options,
                          self.run_tracker,
                          self.targets,
                          requested_goals=self.requested_goals,
                          lock=lock)

        # TODO: Time to get rid of this hack.
        if self.options.recursive_directory:
            context.log.warn(
                '--all-recursive is deprecated, use a target spec with the form [dir]:: instead'
            )
            for dir in self.options.recursive_directory:
                self.add_target_recursive(dir)

        if self.options.target_directory:
            context.log.warn(
                '--all is deprecated, use a target spec with the form [dir]: instead'
            )
            for dir in self.options.target_directory:
                self.add_target_directory(dir)

        unknown = []
        for phase in self.phases:
            if not phase.goals():
                unknown.append(phase)

        if unknown:
            print('Unknown goal(s): %s' % ' '.join(phase.name
                                                   for phase in unknown))
            print('')
            return Phase.execute(context, 'goals')

        ret = Phase.attempt(context, self.phases)

        if self.options.cleanup_nailguns or self.config.get(
                'nailgun', 'autokill', default=False):
            if log:
                log.debug('auto-killing nailguns')
            if NailgunTask.killall:
                NailgunTask.killall(log)

        return ret
Пример #18
0
 def create_context(cls, **kwargs):
     return Context(cls.config,
                    run_tracker=None,
                    target_base=MockTarget,
                    **kwargs)
Пример #19
0
 def test_dependants_empty(self):
   context = Context(ContextTest.config, options={}, target_roots=[])
   dependees = context.dependants()
   self.assertEquals(0, len(dependees))
Пример #20
0
 def create_context(cls, **kwargs):
     return Context(cls.config, run_tracker=None, **kwargs)
Пример #21
0
    def run(self, lock):
        if self.options.dry_run:
            print '****** Dry Run ******'

        logger = None
        if self.options.log or self.options.log_level:
            from twitter.common.log import init
            from twitter.common.log.options import LogOptions
            LogOptions.set_stderr_log_level((self.options.log_level
                                             or 'info').upper())
            logdir = self.options.logdir or self.config.get(
                'goals', 'logdir', default=None)
            if logdir:
                safe_mkdir(logdir)
                LogOptions.set_log_dir(logdir)
                init('goals')
            else:
                init()
            logger = log

        if self.options.recursive_directory:
            log.warn(
                '--all-recursive is deprecated, use a target spec with the form [dir]:: instead'
            )
            for dir in self.options.recursive_directory:
                self.add_target_recursive(dir)

        if self.options.target_directory:
            log.warn(
                '--all is deprecated, use a target spec with the form [dir]: instead'
            )
            for dir in self.options.target_directory:
                self.add_target_directory(dir)

        context = Context(self.config,
                          self.options,
                          self.targets,
                          requested_goals=self.requested_goals,
                          lock=lock,
                          log=logger,
                          timer=self.timer if self.options.time else None)

        unknown = []
        for phase in self.phases:
            if not phase.goals():
                unknown.append(phase)

        if unknown:
            print('Unknown goal(s): %s' % ' '.join(phase.name
                                                   for phase in unknown))
            print('')
            return Phase.execute(context, 'goals')

        if logger:
            logger.debug('Operating on targets: %s', self.targets)

        ret = Phase.attempt(context, self.phases)

        if self.options.cleanup_nailguns or self.config.get(
                'nailgun', 'autokill', default=False):
            if log:
                log.debug('auto-killing nailguns')
            if NailgunTask.killall:
                NailgunTask.killall(log)

        if self.options.time:
            print('Timing report')
            print('=============')
            self.timer.print_timings()

        return ret