def check_source_file_headers(project, logger): expected_header = project.get_property('pybuilder_header_plugin_expected_header') break_build = project.get_property('pybuilder_header_plugin_break_build') exclude_patterns = [] for pattern in project.get_property('pybuilder_header_plugin_exclude_patterns'): exclude_patterns.append(pattern.rstrip('/')) logger.debug('Exclude patterns: %s' % exclude_patterns) if break_build and not expected_header: raise PyBuilderException('Please specify expected file header!') affected_files_count = 0 source_directory = join('src', 'main', 'python') affected_files_count += search_in_directory(source_directory, exclude_patterns, expected_header, logger) unittest_directory = join('src', 'unittest', 'python') affected_files_count += search_in_directory(unittest_directory, exclude_patterns, expected_header, logger) integrationtest_directory = join('src', 'integrationtest', 'python') affected_files_count += search_in_directory(integrationtest_directory, exclude_patterns, expected_header, logger) if affected_files_count: message = "Found %d source files containing unexpected header." % affected_files_count if break_build: raise PyBuilderException(message) else: logger.warn(message)
def get_git_description(self): if self.is_a_git_repo(): exit_code, stdout, stderr = execute_command_and_capture_output( "git", "describe", "--always", "--tags", "--dirty") if exit_code != 0: raise PyBuilderException("Cannot determine git description: git describe failed:\n{0}". format(stderr)) else: return stdout.strip() else: raise PyBuilderException("Cannot determine git description: project is not a git repo.")
def get_git_hash(self, abbreviate=7): if self.is_a_git_repo(): exit_code, stdout, stderr = execute_command_and_capture_output( "git", "rev-parse", "--short={0}".format(abbreviate), "HEAD") if exit_code != 0: raise PyBuilderException("Cannot determine git hash: git rev-parse HEAD failed:\n{0}". format(stderr)) else: return stdout.strip() else: raise PyBuilderException("Cannot determine git hash: project is not a git repo.")
def description(self): """ Returns a human readable revision description as a string. """ if self.is_a_git_repo(): return self.get_git_description() if self.is_a_svn_repo(): raise PyBuilderException( "'description' is not implemented for svn repos") raise PyBuilderException( "Cannot determine VCS revision: project is neither a git nor a svn repo.")
def load_project_module(project_descriptor): try: return imp.load_source("build", project_descriptor) except ImportError as e: raise PyBuilderException( "Error importing project descriptor %s: %s" % (project_descriptor, e))
def _prepare_tasks(self, tasks): if not len(tasks): if self.project.default_task: tasks += as_list(self.project.default_task) else: raise PyBuilderException("No default task given.") else: new_tasks = [task for task in tasks if task[0] not in ("+", "^") or task in ("+", "^")] append_tasks = [task[1:] for task in tasks if task[0] == "+" and task != "+"] remove_tasks = [task[1:] for task in tasks if task[0] == "^" and task != "^"] if len(new_tasks): del tasks[:] tasks.extend(new_tasks) tasks.extend(append_tasks) for task in remove_tasks: try: tasks.remove(task) except ValueError: pass else: del tasks[:] if self.project.default_task: tasks += as_list(self.project.default_task) tasks += append_tasks for task in remove_tasks: try: tasks.remove(task) except ValueError: pass return tasks
def _prepare_tasks(self, tasks): if not len(tasks): if self.project.default_task: tasks += as_list(self.project.default_task) else: raise PyBuilderException("No default task given.") else: new_tasks = [ task for task in tasks if task[0] != '+' or task == "+" ] append_tasks = [ task[1:] for task in tasks if task[0] == '+' and task != "+" ] if len(new_tasks): del tasks[:] tasks.extend(new_tasks) tasks.extend(append_tasks) else: del tasks[:] if self.project.default_task: tasks += as_list(self.project.default_task) tasks += append_tasks return tasks
def get_svn_revision_count(self): exit_code, stdout, stderr = execute_command_and_capture_output( "svnversion") if exit_code != 0 or "Unversioned directory" in stdout or "Uncommitted" in stdout: raise PyBuilderException("Cannot determine svn revision: svnversion failed or unversioned directory:\n{0}". format(stderr)) return stdout.strip().replace("M", "").replace("S", "").replace("P", "").split(":")[0]
def get_git_revision_count(self): # NOTE: git rev-list HEAD --count does not work on RHEL6, hence we count ourselves. exit_code, stdout, stderr = execute_command_and_capture_output( "git", "rev-list", "HEAD") if exit_code != 0: raise PyBuilderException("Cannot determine git revision: git rev-list HEAD failed:\n{0}". format(stderr)) return str(len(stdout.splitlines()))
def verify_project_directory(project_directory, project_descriptor): project_directory = np(project_directory) if not os.path.exists(project_directory): raise PyBuilderException("Project directory does not exist: %s", project_directory) if not os.path.isdir(project_directory): raise PyBuilderException("Project directory is not a directory: %s", project_directory) project_descriptor_full_path = jp(project_directory, project_descriptor) if not os.path.exists(project_descriptor_full_path): raise PyBuilderException("Project directory does not contain descriptor file: %s", project_descriptor_full_path) if not os.path.isfile(project_descriptor_full_path): raise PyBuilderException("Project descriptor is not a file: %s", project_descriptor_full_path) return project_directory, project_descriptor_full_path
def count(self): """ Returns the current revision number as a string. """ if self.is_a_git_repo(): return self.get_git_revision_count() if self.is_a_svn_repo(): return self.get_svn_revision_count() raise PyBuilderException( "Cannot determine VCS revision: project is neither a git nor a svn repo.")
def mkdir(directory): """ Tries to create the directory denoted by the given name. If it exists and is a directory, nothing will be created and no error is raised. If it exists as a file a PyBuilderException is raised. Otherwise the directory incl. all parents is created. """ if os.path.exists(directory): if os.path.isfile(directory): message = "Unable to created directory '%s': A file with that name already exists" raise PyBuilderException(message, directory) return makedirs(directory, exist_ok=True)
def check_source_file_headers(project, logger): expected_header = project.get_property('pybuilder_header_plugin_expected_header') break_build = project.get_property('pybuilder_header_plugin_break_build') if break_build and not expected_header: raise PyBuilderException('Please specify expected file header!') affected_files = 0 source_directory = join('src', 'main', 'python') affected_files += search_in_directory(source_directory, expected_header, logger) test_directory = join('src', 'unittest', 'python') affected_files += search_in_directory(test_directory, expected_header, logger) if affected_files > 0: message = "Found %d source files containing unexpected header." % affected_files if break_build: raise PyBuilderException(message) else: logger.warn(message)
def build(self, tasks=None, environments=None): if not tasks: tasks = [] if not environments: environments = [] Reactor._current_instance = self if environments: self.logger.info("Activated environments: %s", ", ".join(environments)) self.execution_manager.execute_initializers(environments, logger=self.logger, project=self.project) self.log_project_properties() self.validate_project() tasks = as_list(tasks) if not len(tasks): if self.project.default_task: tasks += as_list(self.project.default_task) else: raise PyBuilderException("No default task given.") execution_plan = self.execution_manager.build_execution_plan(tasks) self.logger.debug("Execution plan is %s", ", ".join([task.name for task in execution_plan])) self.logger.info("Building %s version %s", self.project.name, self.project.version) self.logger.info("Executing build in %s", self.project.basedir) if len(tasks) == 1: self.logger.info("Going to execute task %s", tasks[0]) else: list_of_tasks = ", ".join(tasks) self.logger.info("Going to execute tasks: %s", list_of_tasks) task_execution_summaries = self.execution_manager.execute_execution_plan( execution_plan, logger=self.logger, project=self.project, reactor=self) return BuildSummary(self.project, task_execution_summaries)
def django_run_server(project, logger): django_module_name = project.get_mandatory_property("django_module") logger.info("Running Django development server for %s", django_module_name) settings_module_name = "{0}.settings".format(django_module_name) sys.path.append(project.expand_path("$dir_source_main_python")) try: __import__(settings_module_name) except ImportError as e: raise PyBuilderException("Error when importing settings module: " + str(e)) from django import VERSION as DJANGO_VERSION if DJANGO_VERSION < (1, 4, 0): from django.core.management import execute_manager execute_manager(sys.modules[settings_module_name], ["", "runserver"]) else: os.environ.setdefault("DJANGO_SETTINGS_MODULE", settings_module_name) from django.core.management import execute_from_command_line execute_from_command_line(["", "runserver"])
def create_execution_plan(self, tasks, environments): Reactor._set_current_instance(self) if environments: self.logger.info( "Activated environments: %s", ", ".join(environments)) self.execution_manager.execute_initializers( environments, logger=self.logger, project=self.project) self.log_project_properties() self.validate_project() if not len(tasks): if self.project.default_task: tasks += as_list(self.project.default_task) else: raise PyBuilderException("No default task given.") return self.execution_manager.build_execution_plan(tasks)
def main(*args): if not args: args = sys.argv[1:] try: options, arguments = parse_options(args) except CommandLineUsageException as e: print_error_line("Usage error: %s\n" % e) print_error(e.usage) return 1 start = datetime.datetime.now() logger = init_logger(options) reactor = init_reactor(logger) if options.start_project: return start_project() if options.update_project: return update_project() if options.list_tasks or options.list_plan_tasks: try: reactor.prepare_build(property_overrides=options.property_overrides, project_directory=options.project_directory, exclude_optional_tasks=options.exclude_optional_tasks, exclude_tasks=options.exclude_tasks, exclude_all_optional=options.exclude_all_optional ) if options.list_tasks: print_list_of_tasks(reactor, quiet=options.very_quiet) if options.list_plan_tasks: print_plan_list_of_tasks(options, arguments, reactor, quiet=options.very_quiet) return 0 except PyBuilderException as e: print_build_status(str(e), options, successful=False) return 1 if not options.very_quiet: print_styled_text_line( "PyBuilder version {0}".format(__version__), options, BOLD) print_text_line("Build started at %s" % format_timestamp(start)) draw_line() successful = True failure_message = None summary = None try: try: reactor.prepare_build(property_overrides=options.property_overrides, project_directory=options.project_directory, exclude_optional_tasks=options.exclude_optional_tasks, exclude_tasks=options.exclude_tasks, exclude_all_optional=options.exclude_all_optional ) if options.verbose or options.debug: logger.debug("Verbose output enabled.\n") reactor.project.set_property("verbose", True) summary = reactor.build( environments=options.environments, tasks=arguments) except KeyboardInterrupt: raise PyBuilderException("Build aborted") except (Exception, SystemExit) as e: successful = False failure_message = str(e) if options.debug: traceback.print_exc(file=sys.stderr) finally: end = datetime.datetime.now() if not options.very_quiet: print_summary( successful, summary, start, end, options, failure_message) if not successful: return 1 return 0
def test_pyb_error_message(self): try: raise PyBuilderException("test") except Exception: self.assertRegexpMatches(get_failure_message(), r"test \(cli_tests.py\:\d+\)")
def fork_test_func_exc(): raise PyBuilderException("Test failure message")
def get_millis(self): if self.end_time is None: raise PyBuilderException("Timer is running.") return int((self.end_time - self.start_time) * 1000)
def test_should_format_exception_message_with_arguments(self): self.assertEqual("spam and eggs", str(PyBuilderException("%s and %s", "spam", "eggs")))
def test_func(): raise PyBuilderException("Test failure message")