-
-
Notifications
You must be signed in to change notification settings - Fork 652
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
Print Target Definition Using Buildozer #5142
Changes from all commits
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 |
---|---|---|
|
@@ -72,17 +72,31 @@ def _execute_buildozer_script(self, command): | |
Buildozer.execute_binary(command, address.spec, binary=self._executable) | ||
|
||
@classmethod | ||
def execute_binary(cls, command, spec, binary=None, version='0.6.0.dce8b3c287652cbcaf43c8dd076b3f48c92ab44c'): | ||
def execute_binary(cls, command, spec, binary=None, version='0.6.0.dce8b3c287652cbcaf43c8dd076b3f48c92ab44c', suppress_warnings=False): | ||
binary = binary if binary else BinaryUtil.Factory.create().select_binary('scripts/buildozer', version, 'buildozer') | ||
Buildozer._execute_buildozer_command([binary, command, spec], suppress_warnings, output=False) | ||
|
||
Buildozer._execute_buildozer_command([binary, command, spec]) | ||
@classmethod | ||
def return_buildozer_output(cls, command, spec, binary=None, version='0.6.0.dce8b3c287652cbcaf43c8dd076b3f48c92ab44c', suppress_warnings=False): | ||
binary = binary if binary else BinaryUtil.Factory.create().select_binary('scripts/buildozer', version, 'buildozer') | ||
return Buildozer._execute_buildozer_command([binary, command, spec], suppress_warnings, output=True) | ||
|
||
@classmethod | ||
def _execute_buildozer_command(cls, buildozer_command): | ||
try: | ||
subprocess.check_call(buildozer_command, cwd=get_buildroot()) | ||
except subprocess.CalledProcessError as err: | ||
if err.returncode == 3: | ||
logger.warn('{} ... no changes were made'.format(buildozer_command)) | ||
else: | ||
raise TaskError('{} ... exited non-zero ({}).'.format(buildozer_command, err.returncode)) | ||
def _execute_buildozer_command(cls, buildozer_command, suppress_warnings, output): | ||
if not output: | ||
try: | ||
subprocess.check_call(buildozer_command, cwd=get_buildroot()) | ||
except subprocess.CalledProcessError as err: | ||
if err.returncode == 3: | ||
if not suppress_warnings: | ||
logger.warn('{} ... no changes were made'.format(buildozer_command)) | ||
else: | ||
raise TaskError('{} ... exited non-zero ({}).'.format(buildozer_command, err.returncode)) | ||
else: | ||
try: | ||
subprocess.check_output(buildozer_command, cwd=get_buildroot(), stderr=subprocess.STDOUT) | ||
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 did not get the chance to run the code step by step yet, so cannot tell the reason for 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. @itsedvard lets coordinate on this as both the |
||
except subprocess.CalledProcessError as err: | ||
if err.returncode == 3: | ||
return err.output | ||
else: | ||
raise TaskError('{} ... exited non-zero ({}).'.format(buildozer_command, err.returncode)) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# coding=utf-8 | ||
# Copyright 2017 Pants project contributors (see CONTRIBUTORS.md). | ||
# Licensed under the Apache License, Version 2.0 (see LICENSE). | ||
|
||
from __future__ import (absolute_import, division, generators, nested_scopes, print_function, | ||
unicode_literals, with_statement) | ||
|
||
from pants.base.exceptions import TaskError | ||
from pants.task.console_task import ConsoleTask | ||
|
||
from pants.contrib.buildrefactor.buildozer import Buildozer | ||
|
||
|
||
class PrintTarget(ConsoleTask): | ||
"""Print's a specified target if found in the associated build file | ||
|
||
line-number: optional flag to print the starting and ending line numbers of the target | ||
|
||
Example: | ||
$./pants print-target --line-number testprojects/tests/java/org/pantsbuild/testproject/dummies:passing_target | ||
""" | ||
|
||
@classmethod | ||
def register_options(cls, register): | ||
super(PrintTarget, cls).register_options(register) | ||
|
||
register('--line-number', help='Prints the starting line number of the named target.', type=bool, default=False) | ||
|
||
def __init__(self, *args, **kwargs): | ||
super(PrintTarget, self).__init__(*args, **kwargs) | ||
|
||
if len(self.context.target_roots) > 1: | ||
raise TaskError('More than one target specified:\n{}'.format(str(self.context.target_roots))) | ||
|
||
self.target = self.context.target_roots[0] | ||
self.options = self.get_options() | ||
|
||
def console_output(self, targets): | ||
|
||
spec_path = self.target.address.spec | ||
|
||
yield('\'{}\' found in BUILD file.\n'.format(self.target.name)) | ||
|
||
if self.options.line_number: | ||
startline_output = Buildozer.return_buildozer_output(spec = spec_path, command = 'print startline', suppress_warnings=True) | ||
startline_digit = int(filter(str.isdigit, startline_output)) | ||
|
||
endline_output = Buildozer.return_buildozer_output(spec = spec_path, command = 'print endline', suppress_warnings=True) | ||
endline_digit = int(filter(str.isdigit, endline_output)) | ||
|
||
yield('Line numbers: {}-{}.\n'.format(startline_digit, endline_digit)) | ||
|
||
yield('Target definiton:\n\n{}'.format(Buildozer.return_buildozer_output(spec = spec_path, command = 'print rule', suppress_warnings=True))) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# coding=utf-8 | ||
# Copyright 2017 Pants project contributors (see CONTRIBUTORS.md). | ||
# Licensed under the Apache License, Version 2.0 (see LICENSE). | ||
|
||
from __future__ import (absolute_import, division, generators, nested_scopes, print_function, | ||
unicode_literals, with_statement) | ||
|
||
from pants_test.pants_run_integration_test import PantsRunIntegrationTest | ||
|
||
|
||
class PrintTargetIntegrationTest(PantsRunIntegrationTest): | ||
"""Test Peek goal functionality | ||
|
||
$./pants test contrib/buildrefactor/tests/python/pants_test/contrib/buildrefactor:print_target_integration | ||
""" | ||
|
||
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. could you also add a negative case here with an invalid target to show what the behavior should be? 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. Updated to include additional test 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. Thanks. Also I think it's probably better to address 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. Responded to your comments on the Meta Relocate PR... TaskError:
I also updated 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. Had the CI fail with:
So I changed the import order in 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.
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. Thanks for the fix! |
||
def test_print_name(self): | ||
print_target_print_run = self.run_pants(['print-target', | ||
'testprojects/tests/java/org/pantsbuild/testproject/buildrefactor/x:X']) | ||
|
||
self.assertIn('\'X\' found in BUILD file.', print_target_print_run.stdout_data) | ||
self.assertIn('name = "X"', print_target_print_run.stdout_data) | ||
|
||
def test_print_invalid_name(self): | ||
print_target_invalid_name_run = self.run_pants(['print-target', | ||
'testprojects/tests/java/org/pantsbuild/testproject/buildrefactor/x:Y']) | ||
|
||
self.assertIn('ResolveError: "Y" was not found in namespace', print_target_invalid_name_run.stderr_data) | ||
self.assertIn('Did you mean one of:\n :X', print_target_invalid_name_run.stderr_data) | ||
|
||
def test_print_line_number(self): | ||
print_target_line_number_run = self.run_pants(['print-target', | ||
'--line-number', | ||
'testprojects/tests/java/org/pantsbuild/testproject/buildrefactor/x:X']) | ||
|
||
self.assertIn('Line numbers: 4-6.', print_target_line_number_run.stdout_data) | ||
self.assertIn('name = "X"', print_target_line_number_run.stdout_data) | ||
|
||
def test_multiple_targets(self): | ||
print_target_multiple_targets_run = self.run_pants(['print-target', | ||
'testprojects/tests/java/org/pantsbuild/testproject/buildrefactor/x:X', | ||
'tmp:tmp']) | ||
|
||
self.assertIn('FAILURE: More than one target specified:', print_target_multiple_targets_run.stdout_data or | ||
print_target_multiple_targets_run.stderr_data) |
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.
Ah I see you probably cannot use
self._executable
because it is an instance variable and does not apply to a classmethod.The correct way is to make Buildozer a subsystem and
--version
being an option in that subsystem, so various tasks with buildozer subsystem can use the same version of buildozer. E.g.pants/src/python/pants/ivy/bootstrapper.py
Line 65 in 0450732
This as it stands still needs some improvement. I understand as far as the class goes it ends tomorrow evening, but we will appreciate that you can follow up the effort if you cannot finish refactoring the subsystem into it by then.
Function wise, I can consider this PR gets the point, but for production code, we have to gate keep a bit more :)
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.
Thank you for the advice and approach recommendation, I will try to implement it this way as soon as possible - and am looking forward to continuing development on pants after the class is over.