Example #1
0
class ProjectPackageDataTests(unittest.TestCase):
    def setUp(self):
        self.project = Project(basedir="/imaginary", name="Unittest")

    def test_should_raise_exception_when_package_name_not_given(self):
        self.assertRaises(ValueError, self.project.include_file, None, "spam")

    def test_should_raise_exception_when_filename_not_given(self):
        self.assertRaises(
            ValueError, self.project.include_file, "my_package", None)

    def test_should_raise_exception_when_package_name_is_empty_string(self):
        self.assertRaises(
            ValueError, self.project.include_file, "    \n", "spam")

    def test_should_raise_exception_when_filename_is_empty_string(self):
        self.assertRaises(
            ValueError, self.project.include_file, "eggs", "\t    \n")

    def test_should_raise_exception_when_package_path_not_given(self):
        self.assertRaises(ValueError, self.project.include_directory, None, "spam")

    def test_should_raise_exception_when_package_path_is_empty_string(self):
        self.assertRaises(ValueError, self.project.include_directory, "\t  \n", "spam")

    def test_should_raise_exception_when_patterns_list_not_given(self):
        self.assertRaises(ValueError, self.project.include_directory, "spam", None)

    def test_should_raise_exception_when_patterns_list_is_empty_list(self):
        self.assertRaises(ValueError, self.project.include_directory, "spam", ["\t   \n"])

    def test_should_package_data_dictionary_is_empty(self):
        self.assertEquals({}, self.project.package_data)

    def test_should_add_filename_to_list_of_included_files_for_package_spam(self):
        self.project.include_file("spam", "eggs")

        self.assertEquals({"spam": ["eggs"]}, self.project.package_data)

    def test_should_add_two_filenames_to_list_of_included_files_for_package_spam(self):
        self.project.include_file("spam", "eggs")
        self.project.include_file("spam", "ham")

        self.assertEquals({"spam": ["eggs", "ham"]}, self.project.package_data)

    def test_should_add_two_filenames_to_list_of_included_files_for_two_different_packages(self):
        self.project.include_file("spam", "eggs")
        self.project.include_file("monty", "ham")

        self.assertEquals(
            {"monty": ["ham"], "spam": ["eggs"]}, self.project.package_data)

    def test_should_add_two_filenames_to_list_of_included_files_and_to_manifest(self):
        self.project.include_file("spam", "eggs")
        self.project.include_file("monty", "ham")

        self.assertEquals(
            {"monty": ["ham"], "spam": ["eggs"]}, self.project.package_data)
        self.assertEquals(
            ["spam/eggs", "monty/ham"], self.project.manifest_included_files)
class PythonPathTests(TestCase):

    def setUp(self):
        self.project = Project('/path/to/project')
        self.project.set_property('dir_source_unittest_python', 'unittest')
        self.project.set_property('dir_source_main_python', 'src')

    def test_should_register_source_paths(self):
        system_path = ['some/python/path']

        _register_test_and_source_path_and_return_test_dir(self.project, system_path)

        self.assertTrue('/path/to/project/unittest' in system_path)
        self.assertTrue('/path/to/project/src' in system_path)

    def test_should_put_project_sources_before_other_sources(self):
        system_path = ['irrelevant/sources']

        _register_test_and_source_path_and_return_test_dir(self.project, system_path)

        test_sources_index_in_path = system_path.index('/path/to/project/unittest')
        main_sources_index_in_path = system_path.index('/path/to/project/src')
        irrelevant_sources_index_in_path = system_path.index('irrelevant/sources')
        self.assertTrue(test_sources_index_in_path < irrelevant_sources_index_in_path and
                        main_sources_index_in_path < irrelevant_sources_index_in_path)
class PythonPathTests(TestCase):
    def setUp(self):
        self.project = Project("/path/to/project")
        self.project.set_property("dir_source_unittest_python", "unittest")
        self.project.set_property("dir_source_main_python", "src")

    def test_should_register_source_paths(self):
        system_path = ["some/python/path"]

        _register_test_and_source_path_and_return_test_dir(self.project, system_path)

        self.assertTrue("/path/to/project/unittest" in system_path)
        self.assertTrue("/path/to/project/src" in system_path)

    def test_should_put_project_sources_before_other_sources(self):
        system_path = ["irrelevant/sources"]

        _register_test_and_source_path_and_return_test_dir(self.project, system_path)

        test_sources_index_in_path = system_path.index("/path/to/project/unittest")
        main_sources_index_in_path = system_path.index("/path/to/project/src")
        irrelevant_sources_index_in_path = system_path.index("irrelevant/sources")
        self.assertTrue(
            test_sources_index_in_path < irrelevant_sources_index_in_path
            and main_sources_index_in_path < irrelevant_sources_index_in_path
        )
 def test_initialize_sets_variables_correctly(self):
     project = Project(".")
     initialize_plugin(project)
     self.assertEqual(project.get_property("lambda_file_access_control"), "bucket-owner-full-control")
     self.assertEqual(project.get_property("bucket_prefix"), "")
     self.assertEqual(project.get_property("template_file_access_control"), "bucket-owner-full-control")
     self.assertEqual(project.get_property("template_key_prefix"), "")
class InstallBuildDependenciesTest(unittest.TestCase):

    def setUp(self):
        self.project = Project("unittest", ".")
        self.project.set_property("dir_install_logs", "any_directory")
        self.logger = mock(Logger)
        when(
            pybuilder.plugins.python.install_dependencies_plugin).execute_command(any_value(), any_value(),
                                                                                  shell=True).thenReturn(0)

    def tearDown(self):
        unstub()

    def test_should_install_multiple_dependencies(self):
        self.project.build_depends_on("spam")
        self.project.build_depends_on("eggs")

        install_build_dependencies(self.logger, self.project)

        verify(
            pybuilder.plugins.python.install_dependencies_plugin).execute_command("pip install 'spam'",
                                                                                  any_value(), shell=True)
        verify(
            pybuilder.plugins.python.install_dependencies_plugin).execute_command("pip install 'eggs'",
                                                                                  any_value(), shell=True)
Example #6
0
    def test_should_write_pycharm_file(self, os, mock_open):
        project = Project('basedir', name='pybuilder')
        project.set_property('dir_source_main_python', 'src/main/python')
        mock_open.return_value = MagicMock(spec=TYPE_FILE)
        os.path.join.side_effect = lambda first, second: first + '/' + second

        pycharm_generate(project, Mock())

        mock_open.assert_called_with('basedir/.idea/pybuilder.iml', 'w')
        metadata_file = mock_open.return_value.__enter__.return_value
        metadata_file.write.assert_called_with("""<?xml version="1.0" encoding="UTF-8"?>
<!-- This file has been generated by the PyBuilder PyCharm Plugin -->

<module type="PYTHON_MODULE" version="4">
  <component name="NewModuleRootManager">
    <content url="file://$MODULE_DIR$">
      <sourceFolder url="file://$MODULE_DIR$/src/main/python" isTestSource="false" />
    </content>
    <orderEntry type="inheritedJdk" />
    <orderEntry type="sourceFolder" forTests="false" />
  </component>
  <component name="PyDocumentationSettings">
    <option name="myDocStringFormat" value="Plain" />
  </component>
  <component name="TestRunnerService">
    <option name="projectConfiguration" value="Unittests" />
    <option name="PROJECT_TEST_RUNNER" value="Unittests" />
  </component>
</module>
""")
class RunSonarAnalysisTest(TestCase):

    def setUp(self):
        self.project = Project("any-project")
        self.project.version = "0.0.1"
        self.project.set_property("sonarqube_project_key", "project_key")
        self.project.set_property("sonarqube_project_name", "project_name")
        self.project.set_property("dir_source_main_python", "src/main/python")
        self.project.set_property("dir_target", "target")
        self.project.set_property("dir_reports", "target/reports")

    def test_should_build_sonar_runner_for_project(self):
        self.assertEqual(
            build_sonar_runner(self.project).as_string,
            "sonar-runner -Dsonar.projectKey=project_key "
            "-Dsonar.projectName=project_name "
            "-Dsonar.projectVersion=0.0.1 "
            "-Dsonar.sources=src/main/python "
            "-Dsonar.python.coverage.reportPath=target/reports/coverage*.xml")

    @patch("pybuilder.plugins.python.sonarqube_plugin.SonarCommandBuilder.run")
    def test_should_break_build_when_sonar_runner_fails(self, run_sonar_command):
        run_sonar_command.return_value = Mock(exit_code=1)

        self.assertRaises(BuildFailedException, run_sonar_analysis, self.project, Mock())

    @patch("pybuilder.plugins.python.sonarqube_plugin.SonarCommandBuilder.run")
    def test_should_not_break_build_when_sonar_runner_succeeds(self, run_sonar_command):
        run_sonar_command.return_value = Mock(exit_code=0)

        run_sonar_analysis(self.project, Mock())
class SonarCommandBuilderTests(TestCase):

    def setUp(self):
        self.project = Project("any-project")
        self.project.set_property("any-property-name", "any-property-value")
        self.sonar_builder = SonarCommandBuilder("sonar", self.project)

    def test_should_set_sonar_key_to_specific_value(self):
        self.sonar_builder.set_sonar_key("anySonarKey").to("anyValue")

        self.assertEqual(
            self.sonar_builder.as_string,
            "sonar -DanySonarKey=anyValue")

    def test_should_set_sonar_key_to_two_specific_values(self):
        self.sonar_builder.set_sonar_key("anySonarKey").to("anyValue").set_sonar_key("other").to("otherValue")

        self.assertEqual(
            self.sonar_builder.as_string,
            "sonar -DanySonarKey=anyValue -Dother=otherValue")

    def test_should_set_sonar_key_to_property_value(self):
        self.sonar_builder.set_sonar_key("anySonarKey").to_property_value("any-property-name")

        self.assertEqual(self.sonar_builder.as_string, "sonar -DanySonarKey=any-property-value")
    def test_should_break_build_when_warnings_and_set(self, execute_tool, warnings):
        project = Project(".")
        init_pylint(project)
        project.set_property("pylint_break_build", True)

        with self.assertRaises(BuildFailedException):
            execute_pylint(project, Mock(Logger))
    def test_should_run_pylint_with_custom_options(self, execute_tool):
        project = Project(".")
        init_pylint(project)
        project.set_property("pylint_options", ["--test", "-f", "--x=y"])

        execute_pylint(project, Mock(Logger))

        execute_tool.assert_called_with(project, "pylint", ["pylint", "--test", "-f", "--x=y"], True)
    def test_should_delegate_to_project_get_property_when_attribute_is_not_defined(self):
        project_mock = Project(".")
        project_mock.has_property = Mock(return_value=True)
        project_mock.get_property = Mock(return_value="eggs")

        self.assertEquals("eggs", ProjectDictWrapper(project_mock, Mock())["spam"])

        project_mock.get_property.assert_called_with("spam")
Example #12
0
 def test_find_files(self, discover_mock):
     project = Project('.')
     project.set_property('dir_source_cmdlinetest', '/any/dir')
     project.set_property('cram_test_file_glob', '*.t')
     expected = ['/any/dir/test.cram']
     discover_mock.return_value = expected
     received = _find_files(project)
     self.assertEquals(expected, received)
     discover_mock.assert_called_once_with('/any/dir', '*.t')
Example #13
0
    def test_running_plugin_cram_from_target(self,
                                             execute_mock,
                                             read_file_mock,
                                             os_mock,
                                             report_mock,
                                             find_files_mock,
                                             command_mock
                                             ):
        project = Project('.')
        project.set_property('cram_run_test_from_target', True)
        project.set_property('dir_dist', 'python')
        project.set_property('dir_dist_scripts', 'scripts')
        project.set_property('verbose', False)
        logger = Mock()

        command_mock.return_value = ['cram']
        find_files_mock.return_value = ['test1.cram', 'test2.cram']
        report_mock.return_value = 'report_file'
        os_mock.copy.return_value = {}
        read_file_mock.return_value = ['test failes for file', '# results']
        execute_mock.return_value = 0

        run_cram_tests(project, logger)
        execute_mock.assert_called_once_with(
            ['cram', 'test1.cram', 'test2.cram'], 'report_file',
            error_file_name='report_file',
            env={'PYTHONPATH': './python:', 'PATH': './python/scripts:'}
        )
        expected_info_calls = [call('Running Cram command line tests'),
                               call('Cram tests were fine'),
                               call('results'),
                               ]
        self.assertEquals(expected_info_calls, logger.info.call_args_list)
Example #14
0
    def test_running_plugin_failure_no_tests(self,
                                             execute_mock,
                                             read_file_mock,
                                             os_mock,
                                             report_mock,
                                             find_files_mock,
                                             command_mock
                                             ):
        project = Project('.')
        project.set_property('verbose', True)
        project.set_property('dir_source_main_python', 'python')
        project.set_property('dir_source_main_scripts', 'scripts')
        project.set_property("cram_fail_if_no_tests", True)
        logger = Mock()

        command_mock.return_value = ['cram']
        find_files_mock.return_value = []
        report_mock.return_value = 'report_file'
        os_mock.copy.return_value = {}
        read_file_mock.return_value = ['test failes for file', '# results']
        execute_mock.return_value = 1

        self.assertRaises(
            BuildFailedException, run_cram_tests, project, logger)

        execute_mock.assert_not_called()
        expected_info_calls = [call('Running Cram command line tests'),
                               ]
        self.assertEquals(expected_info_calls, logger.info.call_args_list)
    def test_should_run_pytddmon(self, subprocess):
        subprocess.check_output.side_effect = lambda *args, **kwargs: ' '.join(a for a in args)
        project = Project('/path/to/project', name='pybuilder')
        project.set_property('dir_source_main_python', 'path/to/source')
        project.set_property(
            'dir_source_unittest_python', 'src/unittest/python')

        pytddmon_plugin.pytddmon(project, Mock())

        subprocess.Popen.assert_called_with(
            ['which python', 'which pytddmon.py', '--no-pulse'], shell=False, cwd='src/unittest/python', env=ANY)
    def test_should_warn_when_substitution_is_skipped(self):
        project_mock = Project(".")
        logger_mock = Mock()
        project_mock.has_property = Mock(return_value=False)
        project_mock.get_property = Mock()

        self.assertEquals("${n/a}", ProjectDictWrapper(project_mock, logger_mock)["n/a"])

        project_mock.get_property.assert_not_called()
        logger_mock.warn.assert_called_with(
            "Skipping impossible substitution for 'n/a' - there is no matching project attribute or property.")
 def test_initialize_sets_variables_correctly(self):
     project = Project('.')
     initialize_plugin(project)
     self.assertEqual(project.get_property('lambda_file_access_control'),
                      'bucket-owner-full-control')
     self.assertEqual(project.get_property('bucket_prefix'),
                      '')
     self.assertEqual(project.get_property('template_file_access_control'),
                      'bucket-owner-full-control')
     self.assertEqual(project.get_property('template_key_prefix'),
                      '')
    def test_should_override_current_environment_keys_with_additional_environment(self):
        project = Project('any-directory')
        project.set_property(
            'integrationtest_additional_environment', {'foo': 'mooh'})
        environment = {'foo': 'bar'}

        add_additional_environment_keys(environment, project)

        self.assertEqual(environment,
                         {
                             'foo': 'mooh'
                         })
Example #19
0
    def test_ensure_project_properties_are_logged_when_calling_log_project_properties(self):
        project = Project("spam")
        project.set_property("spam", "spam")
        project.set_property("eggs", "eggs")

        self.reactor.project = project
        self.reactor.log_project_properties()

        call_args = self.logger.debug.call_args
        self.assertEquals(call_args[0][0], "Project properties: %s")
        self.assertTrue("basedir : spam" in call_args[0][1])
        self.assertTrue("eggs : eggs" in call_args[0][1])
        self.assertTrue("spam : spam" in call_args[0][1])
    def test_should_merge_additional_environment_into_current_one(self):
        project = Project('any-directory')
        project.set_property(
            'integrationtest_additional_environment', {'foo': 'bar'})
        environment = {'bar': 'baz'}

        add_additional_environment_keys(environment, project)

        self.assertEqual(environment,
                         {
                             'foo': 'bar',
                             'bar': 'baz'
                         })
class TestProxyTests(unittest.TestCase):

    def setUp(self):
        self.project = Project('basedir')

    def test_should_use_teamcity_proxy_if_project_property_is_set(self):
        self.project.set_property('teamcity_output', True)

        proxy = test_proxy_for(self.project)

        self.assertEquals(type(proxy), TeamCityTestProxy)

    def test_should_use_default_proxy_if_project_property_is_not_set(self):
        self.project.set_property('teamcity_output', False)

        proxy = test_proxy_for(self.project)

        self.assertEquals(type(proxy), TestProxy)

    def test_should_use_default_proxy_if_project_property_is_set_but_coverage_is_running(self):
        self.project.set_property('teamcity_output', True)
        self.project.set_property('__running_coverage', True)

        proxy = test_proxy_for(self.project)

        self.assertEquals(type(proxy), TestProxy)
class TestsWithS3(TestCase):
    def setUp(self):
        self.tempdir = tempfile.mkdtemp(prefix='palp-')
        self.project = Project(
            basedir=self.tempdir, name='palp', version='123')
        self.project.set_property('dir_target', 'target')
        self.bucket_name = 'palp-lambda-zips'
        self.project.set_property(
                'lambda_file_access_control', 'bucket-owner-full-control')
        self.project.set_property('bucket_name', self.bucket_name)
        self.project.set_property('bucket_prefix', '')
        self.dir_target = os.path.join(self.tempdir, 'target')
        os.mkdir(self.dir_target)
        self.zipfile_name = os.path.join(self.dir_target, 'palp.zip')
        self.test_data = b'testdata'
        with open(self.zipfile_name, 'wb') as fp:
            fp.write(self.test_data)

        self.my_mock_s3 = mock_s3()
        self.my_mock_s3.start()
        self.s3 = boto3.resource('s3')
        self.s3.create_bucket(Bucket=self.bucket_name)

    def tearDown(self):
        shutil.rmtree(self.tempdir)
        self.my_mock_s3.stop()
Example #23
0
    def test_ensure_project_properties_are_logged_when_calling_log_project_properties(self):
        project = Project("spam")
        project.set_property("spam", "spam")
        project.set_property("eggs", "eggs")

        self.reactor.project = project
        self.reactor.log_project_properties()

        verify(self.logger).debug(
            "Project properties: %s", contains("basedir : spam"))
        verify(self.logger).debug(
            "Project properties: %s", contains("eggs : eggs"))
        verify(self.logger).debug(
            "Project properties: %s", contains("spam : spam"))
    def test_should_write_pydev_files(self, os, mock_open):
        project = Project('basedir', name='pybuilder')
        project.set_property('dir_source_main_python', 'src/main/python')
        init_pydev_plugin(project)
        mock_open.return_value = MagicMock(spec=TYPE_FILE)
        os.path.join.side_effect = lambda first, second: first + '/' + second

        pydev_generate(project, Mock())

        self.assertEqual(mock_open.call_args_list,
                         [call('basedir/.project', 'w'), call('basedir/.pydevproject', 'w')])
        metadata_file = mock_open.return_value.__enter__.return_value

        self.assertEqual(metadata_file.write.call_args_list,
                         [call("""<?xml version="1.0" encoding="UTF-8"?>

<!-- This file has been generated by the PyBuilder Pydev Plugin -->

<projectDescription>
    <name>pybuilder</name>
    <comment></comment>
    <projects>
    </projects>
    <buildSpec>
        <buildCommand>
            <name>org.python.pydev.PyDevBuilder</name>
            <arguments>
            </arguments>
        </buildCommand>
    </buildSpec>
    <natures>
        <nature>org.python.pydev.pythonNature</nature>
    </natures>
</projectDescription>
"""),
                          call("""<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?eclipse-pydev version="1.0"?>

<!-- This file has been generated by the PyBuilder Pydev Plugin -->

<pydev_project>
    <pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
    <pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
    <pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
\t\t<path>/pybuilder/src/main/python</path>

    </pydev_pathproperty>
</pydev_project>
""")])
Example #25
0
    def test_should_generate_sphinx_build_command_per_project_properties(self):
        project = Project('basedir')

        project.set_property("sphinx_builder", "html")
        project.set_property("sphinx_config_path", "docs/")
        project.set_property("sphinx_source_dir", "docs/")
        project.set_property("sphinx_output_dir", "docs/_build/")

        sphinx_build_command = get_sphinx_build_command(project)

        self.assertEqual(sphinx_build_command,
                         "sphinx-build -b html -c basedir/docs/ basedir/docs/ basedir/docs/_build/")
 def setUp(self):
     self.project = Project("unittest", ".")
     self.project.set_property("dir_install_logs", "any_directory")
     self.logger = mock(Logger)
     initialize_install_dependencies_plugin(self.project)
     when(pybuilder.plugins.python.install_dependencies_plugin).execute_command(any_value(), any_value(),
                                                                                shell=False).thenReturn(0)
Example #27
0
    def prepare_build(self,
                      property_overrides=None,
                      project_directory=".",
                      project_descriptor="build.py",
                      exclude_optional_tasks=None,
                      exclude_tasks=None,
                      exclude_all_optional=False):
        if not property_overrides:
            property_overrides = {}
        Reactor._set_current_instance(self)

        project_directory, project_descriptor = self.verify_project_directory(
            project_directory, project_descriptor)

        self.logger.debug("Loading project module from %s", project_descriptor)

        self.project = Project(basedir=project_directory)

        self.project_module = self.load_project_module(project_descriptor)

        self.apply_project_attributes()
        self.override_properties(property_overrides)

        self.logger.debug("Have loaded plugins %s", ", ".join(self._plugins))

        self.collect_tasks_and_actions_and_initializers(self.project_module)

        self.execution_manager.resolve_dependencies(exclude_optional_tasks, exclude_tasks, exclude_all_optional)
 def setUp(self):
     self.project = Project("any-project")
     self.project.version = "0.0.1"
     self.project.set_property("sonarqube_project_key", "project_key")
     self.project.set_property("sonarqube_project_name", "project_name")
     self.project.set_property("dir_source_main_python", "src/main/python")
     self.project.set_property("dir_target", "target")
     self.project.set_property("dir_reports", "target/reports")
 def setUp(self):
     self.patch_popen = mock.patch("pybuilder_aws_plugin.lambda_tasks.subprocess.Popen")
     self.mock_popen = self.patch_popen.start()
     self.mock_process = mock.Mock()
     self.mock_process.returncode = 0
     self.mock_popen.return_value = self.mock_process
     self.input_project = Project(".")
     self.mock_logger = mock.Mock()
    def test_should_generate_command_abiding_to_configuration(self):
        project = Project('egg')
        project.set_property("dir_manpages", "docs/man")
        project.set_property("manpage_source", "README.md")
        project.set_property("manpage_section", 1)

        self.assertEqual(build_generate_manpages_command(project), 'ronn -r --pipe README.md | gzip -9 > docs/man/egg.1.gz')
Example #31
0
class Reactor(object):
    _current_instance = None

    @staticmethod
    def current_instance():
        return Reactor._current_instance

    def __init__(self, logger, execution_manager, plugin_loader=None):
        self.logger = logger
        self.execution_manager = execution_manager
        if not plugin_loader:
            builtin_plugin_loader = BuiltinPluginLoader(self.logger)
            installed_thirdparty_plugin_loader = ThirdPartyPluginLoader(
                self.logger)
            downloading_thirdparty_plugin_loader = DownloadingPluginLoader(
                self.logger)
            self.plugin_loader = DispatchingPluginLoader(
                self.logger, builtin_plugin_loader,
                installed_thirdparty_plugin_loader,
                downloading_thirdparty_plugin_loader)
        else:
            self.plugin_loader = plugin_loader
        self._plugins = []
        self.project = None

    def require_plugin(self, plugin):
        if plugin not in self._plugins:
            try:
                self._plugins.append(plugin)
                self.import_plugin(plugin)
            except:  # NOQA
                self._plugins.remove(plugin)
                raise

    def get_plugins(self):
        return self._plugins

    def get_tasks(self):
        return self.execution_manager.tasks

    def validate_project(self):
        validation_messages = self.project.validate()
        if len(validation_messages) > 0:
            raise ProjectValidationFailedException(validation_messages)

    def prepare_build(self,
                      property_overrides=None,
                      project_directory=".",
                      project_descriptor="build.py",
                      exclude_optional_tasks=None,
                      exclude_tasks=None):
        if not property_overrides:
            property_overrides = {}
        Reactor._current_instance = self

        project_directory, project_descriptor = self.verify_project_directory(
            project_directory, project_descriptor)

        self.logger.debug("Loading project module from %s", project_descriptor)

        self.project = Project(basedir=project_directory)

        self.project_module = self.load_project_module(project_descriptor)

        self.apply_project_attributes()
        self.override_properties(property_overrides)

        self.logger.debug("Have loaded plugins %s", ", ".join(self._plugins))

        self.collect_tasks_and_actions_and_initializers(self.project_module)

        self.execution_manager.resolve_dependencies(exclude_optional_tasks,
                                                    exclude_tasks)

    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 execute_task(self, task_name):
        execution_plan = self.execution_manager.build_execution_plan(task_name)

        self.execution_manager.execute_execution_plan(execution_plan,
                                                      logger=self.logger,
                                                      project=self.project,
                                                      reactor=self)

    def execute_task_shortest_plan(self, task_name):
        execution_plan = self.execution_manager.build_shortest_execution_plan(
            task_name)

        self.execution_manager.execute_execution_plan(execution_plan,
                                                      logger=self.logger,
                                                      project=self.project,
                                                      reactor=self)

    def override_properties(self, property_overrides):
        for property_override in property_overrides:
            self.project.set_property(property_override,
                                      property_overrides[property_override])

    def log_project_properties(self):
        formatted = ""
        for key in sorted(self.project.properties):
            formatted += "\n%40s : %s" % (key, self.project.get_property(key))
        self.logger.debug("Project properties: %s", formatted)

    def import_plugin(self, plugin):
        self.logger.debug("Loading plugin '%s'", plugin)
        plugin_module = self.plugin_loader.load_plugin(self.project, plugin)
        self.collect_tasks_and_actions_and_initializers(plugin_module)

    def collect_tasks_and_actions_and_initializers(self, project_module):
        for name in dir(project_module):
            candidate = getattr(project_module, name)

            if hasattr(candidate, NAME_ATTRIBUTE):
                name = getattr(candidate, NAME_ATTRIBUTE)
            elif hasattr(candidate, "__name__"):
                name = candidate.__name__
            description = getattr(candidate, DESCRIPTION_ATTRIBUTE) if hasattr(
                candidate, DESCRIPTION_ATTRIBUTE) else ""

            if hasattr(candidate, TASK_ATTRIBUTE) and getattr(
                    candidate, TASK_ATTRIBUTE):
                dependencies = getattr(
                    candidate, DEPENDS_ATTRIBUTE) if hasattr(
                        candidate, DEPENDS_ATTRIBUTE) else None
                required_dependencies = []
                optional_dependencies = []
                if dependencies:
                    dependencies = list(as_list(dependencies))
                    for d in dependencies:
                        if type(d) is optional:
                            d = as_list(d())
                            optional_dependencies += d
                        else:
                            required_dependencies.append(d)
                self.logger.debug(
                    "Found task '%s' with required dependencies %s and optional dependencies %s",
                    name, required_dependencies, optional_dependencies)
                self.execution_manager.register_task(
                    Task(name, candidate, required_dependencies, description,
                         optional_dependencies))

            elif hasattr(candidate, ACTION_ATTRIBUTE) and getattr(
                    candidate, ACTION_ATTRIBUTE):
                before = getattr(candidate, BEFORE_ATTRIBUTE) if hasattr(
                    candidate, BEFORE_ATTRIBUTE) else None
                after = getattr(candidate, AFTER_ATTRIBUTE) if hasattr(
                    candidate, AFTER_ATTRIBUTE) else None

                only_once = False
                if hasattr(candidate, ONLY_ONCE_ATTRIBUTE):
                    only_once = getattr(candidate, ONLY_ONCE_ATTRIBUTE)
                teardown = False
                if hasattr(candidate, TEARDOWN_ATTRIBUTE):
                    teardown = getattr(candidate, TEARDOWN_ATTRIBUTE)

                self.logger.debug("Found action %s", name)
                self.execution_manager.register_action(
                    Action(name, candidate, before, after, description,
                           only_once, teardown))

            elif hasattr(candidate, INITIALIZER_ATTRIBUTE) and getattr(
                    candidate, INITIALIZER_ATTRIBUTE):
                environments = []
                if hasattr(candidate, ENVIRONMENTS_ATTRIBUTE):
                    environments = getattr(candidate, ENVIRONMENTS_ATTRIBUTE)

                self.execution_manager.register_initializer(
                    Initializer(name, candidate, environments, description))

    def apply_project_attributes(self):
        self.propagate_property("name")
        self.propagate_property("version")
        self.propagate_property("default_task")
        self.propagate_property("summary")
        self.propagate_property("home_page")
        self.propagate_property("description")
        self.propagate_property("authors")
        self.propagate_property("license")
        self.propagate_property("url")

    def propagate_property(self, property):
        if hasattr(self.project_module, property):
            value = getattr(self.project_module, property)
            setattr(self.project, property, value)

    @staticmethod
    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))

    @staticmethod
    def verify_project_directory(project_directory, project_descriptor):
        project_directory = os.path.abspath(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 = os.path.join(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
Example #32
0
 def setUp(self):
     self.project = Project("basedir")
class InstallDependencyTest(unittest.TestCase):
    def setUp(self):
        self.project = Project("unittest", ".")
        self.project.set_property("dir_install_logs", "any_directory")
        self.logger = Mock(Logger)
        initialize_install_dependencies_plugin(self.project)

    @patch(
        "pybuilder.plugins.python.install_dependencies_plugin.get_package_version",
        return_value={})
    @patch(
        "pybuilder.plugins.python.install_dependencies_plugin.execute_command",
        return_value=0)
    def test_should_install_dependency_without_version(self, exec_command,
                                                       get_package_version):
        dependency = Dependency("spam")

        install_dependency(self.logger, self.project, dependency)

        exec_command.assert_called_with(PIP_EXEC_STANZA +
                                        ["install", '--upgrade', 'spam'],
                                        ANY,
                                        env=ANY,
                                        shell=False)

    @patch(
        "pybuilder.plugins.python.install_dependencies_plugin.get_package_version",
        return_value={})
    @patch(
        "pybuilder.plugins.python.install_dependencies_plugin.execute_command",
        return_value=0)
    def test_should_install_requirements_file_dependency(
            self, exec_command, get_package_version):
        dependency = RequirementsFile("requirements.txt")

        install_dependency(self.logger, self.project, dependency)

        exec_command(PIP_EXEC_STANZA + ["install", '-r', "requirements.txt"],
                     ANY,
                     env=ANY,
                     shell=False)

    @patch(
        "pybuilder.plugins.python.install_dependencies_plugin.get_package_version",
        return_value={})
    @patch(
        "pybuilder.plugins.python.install_dependencies_plugin.execute_command",
        return_value=0)
    def test_should_install_dependency_without_version_on_windows_derivate(
            self, exec_command, get_package_version):
        dependency = Dependency("spam")

        install_dependency(self.logger, self.project, dependency)

        exec_command(PIP_EXEC_STANZA + ["install", "spam"],
                     ANY,
                     env=ANY,
                     shell=False)

    @patch(
        "pybuilder.plugins.python.install_dependencies_plugin.get_package_version",
        return_value={})
    @patch("pybuilder.pip_utils._pip_disallows_insecure_packages_by_default",
           return_value=True)
    @patch(
        "pybuilder.plugins.python.install_dependencies_plugin.execute_command",
        return_value=0)
    def test_should_install_dependency_insecurely_when_property_is_set(
            self, exec_command, _, get_package_version):
        dependency = Dependency("spam")
        self.project.set_property("install_dependencies_insecure_installation",
                                  ["spam"])

        install_dependency(self.logger, self.project, dependency)

        exec_command(PIP_EXEC_STANZA + [
            "install", "--allow-unverified", "spam", "--allow-external",
            "spam", 'spam'
        ],
                     ANY,
                     env=ANY,
                     shell=False)

    @patch(
        "pybuilder.plugins.python.install_dependencies_plugin.get_package_version",
        return_value={})
    @patch("pybuilder.pip_utils._pip_disallows_insecure_packages_by_default",
           return_value=True)
    @patch(
        "pybuilder.plugins.python.install_dependencies_plugin.execute_command",
        return_value=0)
    def test_should_install_dependency_securely_when_property_is_not_set_to_dependency(
            self, exec_command, _, get_package_version):
        dependency = Dependency("spam")
        self.project.set_property("install_dependencies_insecure_installation",
                                  ["some-other-dependency"])

        install_dependency(self.logger, self.project, dependency)

        exec_command(PIP_EXEC_STANZA + [
            "install", "--allow-unverified", "some-other-dependency",
            "--allow-external", "some-other-dependency", 'spam'
        ],
                     ANY,
                     env=ANY,
                     shell=False)
        #  some-other-dependency might be a dependency of 'spam'
        #  so we always have to put the insecure dependencies in the command line :-(

    @patch(
        "pybuilder.plugins.python.install_dependencies_plugin.get_package_version",
        return_value={})
    @patch("pybuilder.pip_utils._pip_disallows_insecure_packages_by_default",
           return_value=False)
    @patch(
        "pybuilder.plugins.python.install_dependencies_plugin.execute_command",
        return_value=0)
    def test_should_not_use_insecure_flags_when_pip_version_is_too_low(
            self, exec_command, _, get_package_version):
        dependency = Dependency("spam")
        self.project.set_property("install_dependencies_insecure_installation",
                                  ["spam"])

        install_dependency(self.logger, self.project, dependency)

        exec_command(PIP_EXEC_STANZA + ["install", 'spam'],
                     ANY,
                     env=ANY,
                     shell=False)

    @patch(
        "pybuilder.plugins.python.install_dependencies_plugin.get_package_version",
        return_value={})
    @patch(
        "pybuilder.plugins.python.install_dependencies_plugin.execute_command",
        return_value=0)
    def test_should_install_dependency_using_custom_index_url(
            self, exec_command, get_package_version):
        self.project.set_property("install_dependencies_index_url",
                                  "some_index_url")
        dependency = Dependency("spam")

        install_dependency(self.logger, self.project, dependency)

        exec_command(PIP_EXEC_STANZA +
                     ["install", "--index-url", "some_index_url", 'spam'],
                     ANY,
                     env=ANY,
                     shell=False)

    @patch(
        "pybuilder.plugins.python.install_dependencies_plugin.get_package_version",
        return_value={})
    @patch(
        "pybuilder.plugins.python.install_dependencies_plugin.execute_command",
        return_value=0)
    def test_should_use_extra_index_url_when_index_url_is_not_set(
            self, exec_command, get_package_version):
        self.project.set_property("install_dependencies_extra_index_url",
                                  "some_extra_index_url")
        dependency = Dependency("spam")

        install_dependency(self.logger, self.project, dependency)

        exec_command(
            PIP_EXEC_STANZA +
            ["install", "--extra-index-url", "some_extra_index_url", 'spam'],
            ANY,
            env=ANY,
            shell=False)

    @patch(
        "pybuilder.plugins.python.install_dependencies_plugin.get_package_version",
        return_value={})
    @patch(
        "pybuilder.plugins.python.install_dependencies_plugin.execute_command",
        return_value=0)
    def test_should_use_index_and_extra_index_url_when_index_and_extra_index_url_are_set(
            self, exec_command, get_package_version):
        self.project.set_property("install_dependencies_index_url",
                                  "some_index_url")
        self.project.set_property("install_dependencies_extra_index_url",
                                  "some_extra_index_url")
        dependency = Dependency("spam")

        install_dependency(self.logger, self.project, dependency)

        exec_command(PIP_EXEC_STANZA + [
            "install", "--index-url", "some_index_url", "--extra-index-url",
            "some_extra_index_url", 'spam'
        ],
                     ANY,
                     env=ANY,
                     shell=False)

    @patch(
        "pybuilder.plugins.python.install_dependencies_plugin.get_package_version",
        return_value={})
    @patch(
        "pybuilder.plugins.python.install_dependencies_plugin.execute_command",
        return_value=0)
    def test_should_upgrade_dependencies(self, exec_command,
                                         get_package_version):
        self.project.set_property("install_dependencies_upgrade", True)
        dependency = Dependency("spam")

        install_dependency(self.logger, self.project, dependency)

        exec_command(PIP_EXEC_STANZA + ["install", "--upgrade", 'spam'],
                     ANY,
                     env=ANY,
                     shell=False)

    @patch(
        "pybuilder.plugins.python.install_dependencies_plugin.get_package_version",
        return_value={})
    @patch(
        "pybuilder.plugins.python.install_dependencies_plugin.execute_command",
        return_value=0)
    def test_should_install_dependency_with_version(self, exec_command,
                                                    get_package_version):
        dependency = Dependency("spam", "0.1.2")

        install_dependency(self.logger, self.project, dependency)

        exec_command(PIP_EXEC_STANZA + ["install", 'spam>=0.1.2'],
                     ANY,
                     env=ANY,
                     shell=False)

    @patch(
        "pybuilder.plugins.python.install_dependencies_plugin.get_package_version",
        return_value={})
    @patch(
        "pybuilder.plugins.python.install_dependencies_plugin.execute_command",
        return_value=0)
    def test_should_install_dependency_with_version_and_operator(
            self, exec_command, get_package_version):
        dependency = Dependency("spam", "==0.1.2")

        install_dependency(self.logger, self.project, dependency)

        exec_command(PIP_EXEC_STANZA + ["install", 'spam==0.1.2'],
                     ANY,
                     env=ANY,
                     shell=False)

    @patch(
        "pybuilder.plugins.python.install_dependencies_plugin.get_package_version",
        return_value={})
    @patch(
        "pybuilder.plugins.python.install_dependencies_plugin.execute_command",
        return_value=0)
    def test_should_install_dependency_with_url(self, exec_command,
                                                get_package_version):
        dependency = Dependency("spam", url="some_url")

        install_dependency(self.logger, self.project, dependency)

        exec_command(PIP_EXEC_STANZA +
                     ["install", "--force-reinstall", 'some_url'],
                     ANY,
                     env=ANY,
                     shell=False)

    @patch(
        "pybuilder.plugins.python.install_dependencies_plugin.get_package_version",
        return_value={})
    @patch(
        "pybuilder.plugins.python.install_dependencies_plugin.execute_command",
        return_value=0)
    def test_should_install_dependency_with_url_even_if_version_is_given(
            self, exec_command, get_package_version):
        dependency = Dependency("spam", version="0.1.2", url="some_url")

        install_dependency(self.logger, self.project, dependency)

        exec_command(PIP_EXEC_STANZA +
                     ["install", "--force-reinstall", 'some_url'],
                     ANY,
                     env=ANY,
                     shell=False)

    class InstallRuntimeDependenciesTest(unittest.TestCase):
        def setUp(self):
            self.project = Project("unittest", ".")
            self.project.set_property("dir_install_logs", "any_directory")
            self.logger = Mock(Logger)
            initialize_install_dependencies_plugin(self.project)

        @patch(
            "pybuilder.plugins.python.install_dependencies_plugin.execute_command",
            return_value=0)
        def test_should_install_multiple_dependencies(self, exec_command,
                                                      get_package_version):
            self.project.depends_on("spam")
            self.project.depends_on("eggs")
            self.project.depends_on_requirements("requirements.txt")

            install_runtime_dependencies(self.logger, self.project)

            exec_command(PIP_EXEC_STANZA + ["install", 'spam'],
                         ANY,
                         shell=False)
            exec_command(PIP_EXEC_STANZA + ["install", 'eggs'],
                         ANY,
                         shell=False)
            exec_command(PIP_EXEC_STANZA +
                         ["install", '-r', 'requirements.txt'],
                         ANY,
                         shell=False)

        @patch(
            "pybuilder.plugins.python.install_dependencies_plugin.execute_command",
            return_value=0)
        def test_should_install_multiple_dependencies_locally(
                self, exec_command, get_package_version):
            self.project.depends_on("spam")
            self.project.depends_on("eggs")
            self.project.depends_on("foo")
            self.project.set_property("install_dependencies_local_mapping", {
                "spam": "any-dir",
                "eggs": "any-other-dir"
            })

            install_runtime_dependencies(self.logger, self.project)

            exec_command(PIP_EXEC_STANZA +
                         ["install", "-t", "any-dir", 'spam'],
                         ANY,
                         shell=False)
            exec_command(PIP_EXEC_STANZA +
                         ["install", "-t", "any-other-dir", 'eggs'],
                         ANY,
                         shell=False)
            exec_command(PIP_EXEC_STANZA + ["install", 'foo'],
                         ANY,
                         shell=False)

    class InstallBuildDependenciesTest(unittest.TestCase):
        def setUp(self):
            self.project = Project("unittest", ".")
            self.project.set_property("dir_install_logs", "any_directory")
            self.logger = Mock(Logger)
            initialize_install_dependencies_plugin(self.project)

        @patch(
            "pybuilder.plugins.python.install_dependencies_plugin.execute_command",
            return_value=0)
        def test_should_install_multiple_dependencies(self, exec_command,
                                                      get_package_version):
            self.project.build_depends_on("spam")
            self.project.build_depends_on("eggs")
            self.project.build_depends_on_requirements("requirements-dev.txt")

            install_build_dependencies(self.logger, self.project)

            exec_command(PIP_EXEC_STANZA + ["install", "spam"],
                         ANY,
                         shell=False)
            exec_command(PIP_EXEC_STANZA + ["install", "eggs"],
                         ANY,
                         shell=False)
            exec_command(PIP_EXEC_STANZA +
                         ["install", '-r', 'requirements-dev.txt'],
                         ANY,
                         shell=False)

    class InstallDependenciesTest(unittest.TestCase):
        def setUp(self):
            self.project = Project("unittest", ".")
            self.project.set_property("dir_install_logs", "any_directory")
            self.logger = Mock(Logger)
            initialize_install_dependencies_plugin(self.project)

        @patch(
            "pybuilder.plugins.python.install_dependencies_plugin.execute_command",
            return_value=0)
        def test_should_install_single_dependency_without_version(
                self, exec_command, get_package_version):
            self.project.depends_on("spam")
            self.project.build_depends_on("eggs")

            install_dependencies(self.logger, self.project)

            exec_command(PIP_EXEC_STANZA + ["install", 'spam'],
                         ANY,
                         shell=False)
            exec_command(PIP_EXEC_STANZA + ["install", 'eggs'],
                         ANY,
                         shell=False)
Example #34
0
def set_properties(project: Project):
    # Dependencies
    project.depends_on("kombu", "4.0.2")

    project.build_depends_on("sqlalchemy")
    project.build_depends_on("django")

    # Cram Configuration
    project.set_property("cram_fail_if_no_tests", False)

    # Disable flake8
    project.set_property("flake8_break_build", False)

    # Integration Tests Coverage is disabled since there are no integration tests
    project.set_property("unittest_coverage_threshold_warn", 0)
    project.set_property("unittest_coverage_branch_threshold_warn", 0)
    project.set_property("unittest_coverage_branch_partial_threshold_warn", 0)
    project.set_property("unittest_coverage_allow_non_imported_modules", True)
    project.set_property("integrationtest_coverage_threshold_warn", 0)
    project.set_property("integrationtest_coverage_branch_threshold_warn", 0)
    project.set_property("integrationtest_coverage_branch_partial_threshold_warn", 0)
    project.set_property("integrationtest_coverage_allow_non_imported_modules", True)

    project.set_property("pybuilder_header_plugin_break_build", False)

    project.set_property("copy_resources_target", "$dir_dist/karellen")
    project.get_property("copy_resources_glob").append("LICENSE.bsd3")
    project.get_property("copy_resources_glob").append("LICENSE.apache")
    project.include_file("karellen", "LICENSE.bsd3")
    project.include_file("karellen", "LICENSE.apache")

    # Distutils
    project.set_property("distutils_classifiers", project.get_property("distutils_classifiers") + [
        'Programming Language :: Python :: 3.3',
        'Programming Language :: Python :: 3.4',
        'Topic :: Software Development :: Libraries',
        'Topic :: Software Development :: Libraries :: Python Modules',
        'Topic :: Internet',
    ])

    project.set_property("pdoc_module_name", "karellen.kombu")