New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow pants to select targets by file(s) #5930
Changes from 7 commits
84084e9
f3a8793
c788fa2
f27872d
a018691
a32b40f
b555d96
09d3701
cd41c2f
66ae1a9
fdb38d2
0082c62
de6df60
118031f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -127,11 +127,17 @@ def create(cls, options, session, symbol_table, build_root=None): | |
# initialization paths. | ||
changed_options = options.for_scope('changed') | ||
changed_request = ChangedRequest.from_options(changed_options) | ||
|
||
owned_files = options.for_global_scope().owner_of | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd like to see a comment here, following the pattern for spec_roots and changed_options, and adding the blank line before and after. |
||
logger.debug('spec_roots are: %s', spec_roots) | ||
logger.debug('changed_request is: %s', changed_request) | ||
scm = get_scm() | ||
change_calculator = ChangeCalculator(session, symbol_table, scm) if scm else None | ||
owner_calculator = OwnerCalculator(session, symbol_table) if owned_files else None | ||
logger.debug('owner_files are: %s', owned_files) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
if changed_request.is_actionable() and owned_files: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be good to unify checking of "exactly one of these three types of options" into one check here, with one large and helpful error message (not a paragraph probably, but a few sentences certainly explaining the three choices that exist). You could then remove the |
||
# We've been provided a change request AND an owner request. Error out. | ||
raise InvalidSpecConstraint('cannot provide owner-of and changed parameters together') | ||
|
||
if change_calculator and changed_request.is_actionable(): | ||
if spec_roots: | ||
|
@@ -144,6 +150,16 @@ def create(cls, options, session, symbol_table, build_root=None): | |
logger.debug('changed addresses: %s', changed_addresses) | ||
return TargetRoots(tuple(SingleAddress(a.spec_path, a.target_name) for a in changed_addresses)) | ||
|
||
if owner_calculator and owned_files: | ||
if spec_roots: | ||
# We've been provided spec roots (e.g. `./pants list ::`) AND a owner request. Error out. | ||
raise InvalidSpecConstraint('cannot provide owner-of parameters and target specs!') | ||
# We've been provided no spec roots (e.g. `./pants list`) AND a owner request. Compute | ||
# alternate target roots. | ||
owner_addresses = owner_calculator.owner_target_addresses(owned_files) | ||
logger.debug('owner addresses: %s', owner_addresses) | ||
return TargetRoots(tuple(SingleAddress(a.spec_path, a.target_name) for a in owner_addresses)) | ||
|
||
return TargetRoots(spec_roots) | ||
|
||
|
||
|
@@ -211,3 +227,28 @@ def iter_changed_target_addresses(self, changed_request): | |
|
||
def changed_target_addresses(self, changed_request): | ||
return list(self.iter_changed_target_addresses(changed_request)) | ||
|
||
|
||
class OwnerCalculator(object): | ||
"""A class for owner-of target calculation""" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This docstring could describe what the class does better. |
||
|
||
def __init__(self, scheduler, symbol_table): | ||
""" | ||
:param scheduler: The `Scheduler` instance to use for computing file to target mapping | ||
:param symbol_table: The symbol table. | ||
""" | ||
self._scheduler = scheduler | ||
self._symbol_table = symbol_table | ||
self._mapper = EngineSourceMapper(self._scheduler) | ||
|
||
def iter_owner_target_addresses(self, owned_files): | ||
"""Given an list of owned files, compute and yield all affected target addresses""" | ||
owner_addresses = set(address | ||
for address | ||
in self._mapper.iter_target_addresses_for_sources(owned_files)) | ||
for address in owner_addresses: | ||
yield address | ||
return | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. xx the return, I think There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. shouldn't need this explicit |
||
|
||
def owner_target_addresses(self, owner_request): | ||
return list(self.iter_owner_target_addresses(owner_request)) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -183,6 +183,11 @@ def register_bootstrap_options(cls, register): | |
register('--subproject-roots', type=list, advanced=True, fromfile=True, default=[], | ||
help='Paths that correspond with build roots for any subproject that this ' | ||
'project depends on.') | ||
register('--owner-of', type=list, default=[], metavar='<path>', | ||
help='Select the targets that own these files.' | ||
'This is the third target calculation strategy along with the --changed' | ||
'options and specifying the targets directly. These three types of target' | ||
'selection are mutually exclusive.') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: add spaces to the end of the lines so that when they're concatenated, they'll have separations. |
||
|
||
# These logging options are registered in the bootstrap phase so that plugins can log during | ||
# registration and not so that their values can be interpolated in configs. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, the docs aren't clear here... based on https://www.pantsbuild.org/deprecation_policy.html , let's target this to
1.10.0.dev0
.