Skip to content

Commit

Permalink
Enable v2 engine by default. (#4340)
Browse files Browse the repository at this point in the history
This enables the v2 engine by default and deprecates the `changed`-class goals.
  • Loading branch information
kwlzn authored Mar 22, 2017
1 parent 645dd3e commit cc9563c
Show file tree
Hide file tree
Showing 22 changed files with 92 additions and 32 deletions.
6 changes: 4 additions & 2 deletions src/python/pants/base/deprecated.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ def deprecated_conditional(predicate,
warn_or_error(removal_version, entity_description, hint_message, stacklevel=stacklevel)


def deprecated(removal_version, hint_message=None):
def deprecated(removal_version, hint_message=None, subject=None):
"""Marks a function or method as deprecated.
A removal version must be supplied and it must be greater than the current 'pantsbuild.pants'
Expand All @@ -146,6 +146,8 @@ def deprecated(removal_version, hint_message=None):
:param str removal_version: The pantsbuild.pants version which will remove the deprecated
function.
:param str hint_message: An optional hint pointing to alternatives to the deprecation.
:param str subject: The name of the subject that has been deprecated for logging clarity. Defaults
to the name of the decorated function/method.
:raises DeprecationApplicationError if the @deprecation is applied improperly.
"""
validate_removal_semver(removal_version)
Expand All @@ -158,7 +160,7 @@ def decorator(func):

@wraps(func)
def wrapper(*args, **kwargs):
warn_or_error(removal_version, func_full_name, hint_message)
warn_or_error(removal_version, subject or func_full_name, hint_message)
return func(*args, **kwargs)
return wrapper
return decorator
Expand Down
2 changes: 1 addition & 1 deletion src/python/pants/bin/engine_initializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def create_build_graph(self, target_roots, build_root=None):
:returns: A tuple of (BuildGraph, AddressMapper).
"""
logger.debug('target_roots are: %r', target_roots)
graph = LegacyBuildGraph(self.scheduler, self.engine, self.symbol_table_cls)
graph = LegacyBuildGraph.create(self.scheduler, self.engine, self.symbol_table_cls)
logger.debug('build_graph is: %s', graph)
with self.scheduler.locked():
# Ensure the entire generator is unrolled.
Expand Down
4 changes: 4 additions & 0 deletions src/python/pants/build_graph/build_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ def closure(*vargs, **kwargs):
def __init__(self):
self.reset()

@abstractmethod
def clone_new(self):
"""Returns a new BuildGraph instance of the same type and with the same __init__ params."""

def reset(self):
"""Clear out the state of the BuildGraph, in particular Target mappings and dependencies.
Expand Down
4 changes: 4 additions & 0 deletions src/python/pants/build_graph/mutable_build_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ def __init__(self, address_mapper):
self._address_mapper = address_mapper
super(MutableBuildGraph, self).__init__()

def clone_new(self):
"""Returns a new BuildGraph instance of the same type and with the same __init__ params."""
return MutableBuildGraph(self._address_mapper)

def reset(self):
super(MutableBuildGraph, self).reset()
self._addresses_already_closed = set()
Expand Down
6 changes: 6 additions & 0 deletions src/python/pants/core_tasks/changed_target_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,18 @@
from __future__ import (absolute_import, division, generators, nested_scopes, print_function,
unicode_literals, with_statement)

from pants.base.deprecated import deprecated
from pants.core_tasks.noop import NoopCompile, NoopTest
from pants.task.changed_target_task import ChangedTargetTask

# TODO: Remove this entire file in 1.5.0dev0.

class CompileChanged(ChangedTargetTask):
"""Find and compile changed targets."""

@classmethod
@deprecated('1.5.0dev0', 'Use e.g. `./pants --changed-parent=HEAD compile` instead.',
'`./pants compile-changed`')
def prepare(cls, options, round_manager):
super(CompileChanged, cls).prepare(options, round_manager)
round_manager.require_data(NoopCompile.product_types()[0])
Expand All @@ -22,6 +26,8 @@ class TestChanged(ChangedTargetTask):
"""Find and test changed targets."""

@classmethod
@deprecated('1.5.0dev0', 'Use e.g. `./pants --changed-parent=HEAD test` instead.',
'`./pants test-changed`')
def prepare(cls, options, round_manager):
super(TestChanged, cls).prepare(options, round_manager)
round_manager.require_data(NoopTest.product_types()[0])
1 change: 1 addition & 0 deletions src/python/pants/core_tasks/register.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ def register_goals():
task(name='test', action=NoopTest).install('test')

# Operations on files that the SCM detects as changed.
# TODO: Remove these in `1.5.0dev0` as part of the changed goal deprecations.
task(name='changed', action=WhatChanged).install()
task(name='compile-changed', action=CompileChanged).install()
task(name='test-changed', action=TestChanged).install()
Expand Down
9 changes: 7 additions & 2 deletions src/python/pants/core_tasks/what_changed.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
from __future__ import (absolute_import, division, generators, nested_scopes, print_function,
unicode_literals, with_statement)

from pants.base.deprecated import deprecated
from pants.scm.subsystems.changed import Changed
from pants.task.console_task import ConsoleTask

# TODO: Remove this entire file in 1.5.0dev0.

class WhatChanged(ConsoleTask):
"""Emits the targets that have been modified since a given commit."""
Expand All @@ -16,13 +18,16 @@ class WhatChanged(ConsoleTask):
def register_options(cls, register):
super(WhatChanged, cls).register_options(register)
# N.B. The bulk of options relevant to this task now come from the `Changed` subsystem.
register('--files', type=bool,
help='Show changed files instead of the targets that own them.')
register('--files', type=bool, removal_version='1.5.0dev0',
help='Show changed files instead of the targets that own them.',
removal_hint='Use your scm implementation (e.g. `git diff --stat`) instead.')

@classmethod
def subsystem_dependencies(cls):
return super(WhatChanged, cls).subsystem_dependencies() + (Changed.Factory,)

@deprecated('1.5.0dev0', 'Use e.g. `./pants --changed-parent=HEAD list` instead.',
'`./pants changed`')
def console_output(self, _):
# N.B. This task shares an options scope ('changed') with the `Changed` subsystem.
options = self.get_options()
Expand Down
16 changes: 13 additions & 3 deletions src/python/pants/engine/legacy/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,12 @@ class LegacyBuildGraph(BuildGraph):
class InvalidCommandLineSpecError(AddressLookupError):
"""Raised when command line spec is not a valid directory"""

def __init__(self, scheduler, engine, symbol_table_cls):
@classmethod
def create(cls, scheduler, engine, symbol_table_cls):
"""Construct a graph given a Scheduler, Engine, and a SymbolTable class."""
return cls(scheduler, engine, cls._get_target_types(symbol_table_cls))

def __init__(self, scheduler, engine, target_types):
"""Construct a graph given a Scheduler, Engine, and a SymbolTable class.
:param scheduler: A Scheduler that is configured to be able to resolve HydratedTargets.
Expand All @@ -55,11 +60,16 @@ def __init__(self, scheduler, engine, symbol_table_cls):
the symbol table installed in the scheduler (TODO: see comment in `_instantiate_target`).
"""
self._scheduler = scheduler
self._target_types = self._get_target_types(symbol_table_cls)
self._engine = engine
self._target_types = target_types
super(LegacyBuildGraph, self).__init__()

def _get_target_types(self, symbol_table_cls):
def clone_new(self):
"""Returns a new BuildGraph instance of the same type and with the same __init__ params."""
return LegacyBuildGraph(self._scheduler, self._engine, self._target_types)

@staticmethod
def _get_target_types(symbol_table_cls):
aliases = symbol_table_cls.aliases()
target_types = dict(aliases.target_types)
for alias, factory in aliases.target_macro_factories.items():
Expand Down
4 changes: 3 additions & 1 deletion src/python/pants/engine/legacy/structs.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ def get_sources(self):
see: https://github.com/pantsbuild/pants/issues/2997
"""
sources = getattr(self, 'sources', None)
if not sources:
# N.B. Here we check specifically for `sources is None`, as it's possible for sources
# to be e.g. an explicit empty list (sources=[]).
if sources is None:
if self.default_sources_globs:
return Globs(*self.default_sources_globs,
spec_path=self.address.spec_path,
Expand Down
3 changes: 1 addition & 2 deletions src/python/pants/goal/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
from pants.base.build_environment import get_buildroot, get_scm
from pants.base.worker_pool import SubprocPool
from pants.base.workunit import WorkUnitLabel
from pants.build_graph.mutable_build_graph import MutableBuildGraph
from pants.build_graph.target import Target
from pants.goal.products import Products
from pants.goal.workspace import ScmWorkspace
Expand Down Expand Up @@ -351,7 +350,7 @@ def scan(self, root=None):
:param string root: The path to scan; by default, the build root.
:returns: A new build graph encapsulating the targets found.
"""
build_graph = MutableBuildGraph(self.address_mapper)
build_graph = self.build_graph.clone_new()
for address in self.address_mapper.scan_addresses(root):
build_graph.inject_address_closure(address)
return build_graph
7 changes: 4 additions & 3 deletions src/python/pants/option/global_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,10 @@ def register_bootstrap_options(cls, register):
register('--enable-pantsd', advanced=True, type=bool, default=False,
help='Enables use of the pants daemon (and implicitly, the v2 engine). (Beta)')

# This facilitates use of the v2 engine for BuildGraph construction, sans daemon.
register('--enable-v2-engine', advanced=True, type=bool, default=False,
help='Enables use of the v2 engine. (Beta)')
# This facilitates use of the v2 engine, sans daemon.
# TODO: Add removal_version='1.5.0dev0' before 1.4 lands.
register('--enable-v2-engine', advanced=True, type=bool, default=True,
help='Enables use of the v2 engine.')

@classmethod
def register_options(cls, register):
Expand Down
1 change: 1 addition & 0 deletions src/python/pants/scm/change_calculator.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ def changed_target_addresses(self):
"""Find changed targets, according to SCM."""


# TODO: Remove this in 1.5.0dev0 in favor of `EngineChangeCalculator`.
class BuildGraphChangeCalculator(ChangeCalculator):
"""A `BuildGraph`-based helper for calculating changed target addresses."""

Expand Down
3 changes: 3 additions & 0 deletions src/python/pants/scm/subsystems/changed.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from pants.util.objects import datatype


# TODO: Remove this in 1.5.0dev0.
class _ChainedOptions(object):
def __init__(self, options_seq):
self._options_seq = options_seq
Expand Down Expand Up @@ -63,6 +64,7 @@ def register_options(cls, register):
register('--fast', type=bool,
help='Stop searching for owners once a source is mapped to at least one owning target.')

# TODO: Remove or reduce this in 1.5.0dev0 - we only need the subsystem's options scope going fwd.
@classmethod
def create(cls, alternate_options=None):
"""
Expand All @@ -80,6 +82,7 @@ def create(cls, alternate_options=None):
def __init__(self, changed_request):
self._changed_request = changed_request

# TODO: Remove this in 1.5.0dev0 in favor of `TargetRoots` use of `EngineChangeCalculator`.
def change_calculator(self, build_graph, address_mapper, scm=None, workspace=None,
exclude_target_regexp=None):
"""Constructs and returns a BuildGraphChangeCalculator.
Expand Down
3 changes: 3 additions & 0 deletions src/python/pants/task/changed_target_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
from pants.task.noop_exec_task import NoopExecTask


# TODO: Remove this entire file in 1.5.0dev0.


logger = logging.getLogger(__name__)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ def test_all(self):
'common/src/py/b/two.py common/src/py/b:b',
'common/src/py/b/three.py common/src/py/b:b',
'common/src/py/c/four.py common/src/py/c:c',
targets=self.targets('::')
)

def test_one(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from pants.backend.python.targets.python_library import PythonLibrary
from pants.build_graph.build_file_aliases import BuildFileAliases
from pants.build_graph.target import Target
from pants_test.subsystem.subsystem_util import init_subsystem
from pants_test.tasks.task_test_base import ConsoleTaskTestBase


Expand Down Expand Up @@ -126,7 +127,8 @@ def test_list_all(self):
'a/b/c:c3',
'a/b/d:d',
'a/b/e:e1',
'f:alias')
'f:alias',
targets=self.targets('::'))

self.assert_entries(', ',
'a:a',
Expand All @@ -137,7 +139,8 @@ def test_list_all(self):
'a/b/d:d',
'a/b/e:e1',
'f:alias',
options={'sep': ', '})
options={'sep': ', '},
targets=self.targets('::'))

self.assert_console_output(
'a:a',
Expand All @@ -147,20 +150,23 @@ def test_list_all(self):
'a/b/c:c3',
'a/b/d:d',
'a/b/e:e1',
'f:alias')
'f:alias',
targets=self.targets('::'))

def test_list_provides(self):
self.assert_console_output(
'a/b:b com.example#b',
'a/b/c:c2 com.example#c2',
options={'provides': True})
options={'provides': True},
targets=self.targets('::'))

def test_list_provides_customcols(self):
self.assert_console_output(
'/tmp a/b:b http://maven.example.com public com.example#b',
'/tmp a/b/c:c2 http://maven.example.com public com.example#c2',
options={'provides': True,
'provides_columns': 'push_db_basedir,address,repo_url,repo_name,artifact_id'}
'provides_columns': 'push_db_basedir,address,repo_url,repo_name,artifact_id'},
targets=self.targets('::')
)

def test_list_dedups(self):
Expand All @@ -178,7 +184,7 @@ def test_list_documented(self):
self.assert_console_output(
# Confirm empty listing
targets=[self.target('a/b')],
options={'documented': True},
options={'documented': True}
)

self.assert_console_output(
Expand All @@ -187,16 +193,19 @@ def test_list_documented(self):
Exercises alias resolution.
Further description.
""").strip(),
options={'documented': True}
options={'documented': True},
targets=self.targets('::')
)

def test_no_synthetic_resources_in_output(self):
# `python_library` w/o `sources` requires initializing the needed subsystem.
init_subsystem(Target.Arguments)
self.add_to_build_file('BUILD', dedent("""
python_library(
name = 'lib',
resources = ['BUILD'],
)
"""))
output = self.execute_console_task()
output = self.execute_console_task(targets=self.targets('::'))
self.assertIn('//:lib', output)
self.assertTrue(all('synthetic' not in line for line in output))
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@
class ZincCompileIntegrationTest(BaseCompileIT):

def test_java_src_zinc_compile(self):
# TODO: Remove the --exclude-target-regexp once we're on Java 8 everywhere.
with self.do_test_compile('examples/src/java/::',
extra_args=['--exclude-target-regexp=examples/src/java/org/pantsbuild/example/javac/plugin']):
with self.do_test_compile('examples/src/java/::'):
# run succeeded as expected
pass
with self.do_test_compile('examples/tests/java/::'):
Expand Down
12 changes: 12 additions & 0 deletions tests/python/pants_test/base/test_deprecated.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,18 @@ def deprecated_function():
self.assertEqual(expected_return, deprecated_function())
self.assertIn(hint_message, str(extract_deprecation_warning()))

def test_deprecation_subject(self):
subject = '`./pants blah`'
expected_return = 'deprecated_function'

@deprecated(self.FUTURE_VERSION, subject=subject)
def deprecated_function():
return expected_return

with self._test_deprecation() as extract_deprecation_warning:
self.assertEqual(expected_return, deprecated_function())
self.assertIn(subject, str(extract_deprecation_warning()))

def test_removal_version_required(self):
with self.assertRaises(MissingRemovalVersionError):
@deprecated(None)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,10 @@

class BuildGraphIntegrationTest(PantsRunIntegrationTest):

# TODO: Disabled to expedite landing #3821: see #4007.
# @ensure_engine
def test_cycle(self):
prefix = 'testprojects/src/java/org/pantsbuild/testproject'
with self.file_renamed(os.path.join(prefix, 'cycle1'), 'TEST_BUILD', 'BUILD'):
with self.file_renamed(os.path.join(prefix, 'cycle2'), 'TEST_BUILD', 'BUILD'):
pants_run = self.run_pants(['compile', os.path.join(prefix, 'cycle1')])
self.assert_failure(pants_run)
self.assertIn('Cycle detected', pants_run.stderr_data)
self.assertIn('contained a cycle', pants_run.stderr_data)
Loading

0 comments on commit cc9563c

Please sign in to comment.