Skip to content

Commit

Permalink
convert the option to be named --output-format!
Browse files Browse the repository at this point in the history
  • Loading branch information
cosmicexplorer committed Oct 11, 2019
1 parent 23585ee commit 2a65176
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 56 deletions.
135 changes: 81 additions & 54 deletions src/python/pants/rules/core/list_targets.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,86 +10,113 @@
from pants.engine.legacy.graph import FingerprintedTargetCollection, HydratedTargets
from pants.engine.rules import console_rule
from pants.engine.selectors import Get
from pants.util.objects import enum


class List(LineOriented, Goal):
"""Lists all targets matching the target specs."""

name = 'list'

class OutputFormat(enum([
'address-specs',
'provides',
'documented',
'json',
])): pass

@classmethod
def register_options(cls, register):
super().register_options(register)
register('--provides', type=bool,
removal_version='1.24.0.dev2',
removal_hint='Use --output-format=provides instead!',
help='List only targets that provide an artifact, displaying the columns specified by '
'--provides-columns.')
register('--provides-columns', default='address,artifact_id',
help='Display these columns when --provides is specified. Available columns are: '
'address, artifact_id, repo_name, repo_url, push_db_basedir')

register('--documented', type=bool,
removal_version='1.24.0.dev2',
removal_hint='Use --output-format=documented instead!',
help='Print only targets that are documented with a description.')
register('--with-fingerprints', type=bool,
help='Print out target fingerprint information in lines of JSON.')

register('--output-format', type=cls.OutputFormat, default=cls.OutputFormat.address_specs,
help='How to format targets when printed to stdout.')


def _make_provides_print_fn(provides_columns):
extractors = dict(
address=lambda target: target.address.spec,
artifact_id=lambda target: str(target.adaptor.provides),
repo_name=lambda target: target.adaptor.provides.repo.name,
repo_url=lambda target: target.adaptor.provides.repo.url,
push_db_basedir=lambda target: target.adaptor.provides.repo.push_db_basedir,
)

def print_provides(column_extractors, target):
if getattr(target.adaptor, 'provides', None):
return ' '.join(extractor(target) for extractor in column_extractors)

try:
column_extractors = [extractors[col] for col in (provides_columns.split(','))]
except KeyError:
raise Exception('Invalid columns specified: {0}. Valid columns are: address, artifact_id, '
'repo_name, repo_url, push_db_basedir.'.format(provides_columns))

return lambda target: print_provides(column_extractors, target)


def _print_documented_target(target):
description = getattr(target.adaptor, 'description', None)
if description:
return '{0}\n {1}'.format(target.address.spec,
'\n '.join(description.strip().split('\n')))


def _print_fingerprinted_target(fingerprinted_target):
was_root = fingerprinted_target.was_root
address = fingerprinted_target.address.spec
intransitive = fingerprinted_target.intransitive_fingerprint_arg
transitive = fingerprinted_target.transitive_fingerprint_arg
return json.dumps({
'was_root': was_root,
'address': address,
'intransitive': intransitive,
'transitive': transitive,
})


@console_rule
def list_targets(console: Console, list_options: List.Options, specs: Specs) -> List:
provides = list_options.values.provides
provides_columns = list_options.values.provides_columns
documented = list_options.values.documented
with_fingerprints = list_options.values.with_fingerprints
if provides or documented or with_fingerprints:
if provides:
# To get provides clauses, we need hydrated targets.
collection = yield Get(HydratedTargets, Specs, specs)
extractors = dict(
address=lambda target: target.address.spec,
artifact_id=lambda target: str(target.adaptor.provides),
repo_name=lambda target: target.adaptor.provides.repo.name,
repo_url=lambda target: target.adaptor.provides.repo.url,
push_db_basedir=lambda target: target.adaptor.provides.repo.push_db_basedir,
)

def print_provides(column_extractors, target):
if getattr(target.adaptor, 'provides', None):
return ' '.join(extractor(target) for extractor in column_extractors)

try:
column_extractors = [extractors[col] for col in (provides_columns.split(','))]
except KeyError:
raise Exception('Invalid columns specified: {0}. Valid columns are: address, artifact_id, '
'repo_name, repo_url, push_db_basedir.'.format(provides_columns))

print_fn = lambda target: print_provides(column_extractors, target)
elif documented:
# To get documentation, we need hydrated targets.
collection = yield Get(HydratedTargets, Specs, specs)
def print_documented(target):
description = getattr(target.adaptor, 'description', None)
if description:
return '{0}\n {1}'.format(target.address.spec,
'\n '.join(description.strip().split('\n')))
print_fn = print_documented
else:
assert with_fingerprints
# To get fingerprints of each target and its dependencies, we have to request that information
# specifically.
collection = yield Get(FingerprintedTargetCollection, Specs, specs)

def print_fingerprinted(fingerprinted_target):
was_root = fingerprinted_target.was_root
address = fingerprinted_target.address.spec
intransitive = fingerprinted_target.intransitive_fingerprint_arg
transitive = fingerprinted_target.transitive_fingerprint_arg
return json.dumps({
'was_root': was_root,
'address': address,
'intransitive': intransitive,
'transitive': transitive,
})

print_fn = print_fingerprinted
output_format = list_options.values.output_format

# TODO: Remove when these options have completed their deprecation cycle!
if provides:
output_format = List.OutputFormat.provides
elif documented:
output_format = List.OutputFormat.documented

# TODO: a .resolve_for_enum_variant() which allows `yield Get()` within it somehow!
if output_format == List.OutputFormat.provides:
# To get provides clauses, we need hydrated targets.
collection = yield Get(HydratedTargets, Specs, specs)
print_fn = _make_provides_print_fn(provides_columns)
elif output_format == List.OutputFormat.documented:
# To get documentation, we need hydrated targets.
collection = yield Get(HydratedTargets, Specs, specs)
print_fn = _print_documented_target
elif output_format == List.OutputFormat.json:
# To get fingerprints of each target and its dependencies, we have to request that information
# specifically.
collection = yield Get(FingerprintedTargetCollection, Specs, specs)
print_fn = _print_fingerprinted_target
else:
assert output_format == List.OutputFormat.address_specs
# Otherwise, we can use only addresses.
collection = yield Get(BuildFileAddresses, Specs, specs)
print_fn = lambda address: address.spec
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,10 +180,10 @@ def test_list_documented(self):
args=['--documented', '::'],
)

def test_list_with_fingerprints(self):
def test_list_json(self):
self.assert_console_output_ordered(
json.dumps({"was_root": True, "address": "f:alias", "intransitive": "77e220c58aa54b51c7321115b21cd6e4781939b4", "transitive": "2ecd51bf9eb89dd7fb50e0563015f46a40df798f"}),
json.dumps({"was_root": False, "address": "a/b/c:c3", "intransitive": "2e36109fb3a97737513744edc85c03d8b7845e8f", "transitive": "97d170e1550eee4afc0af065b78cda302a97674c"}),
json.dumps({"was_root": False, "address": "a/b/d:d", "intransitive": "eb212be02154e79f8936fce7e9a6f31d0ddd39ff", "transitive": "97d170e1550eee4afc0af065b78cda302a97674c"}),
args=['--with-fingerprints', 'f:alias'],
args=['--output-format=json', 'f:alias'],
)

0 comments on commit 2a65176

Please sign in to comment.