Esempio n. 1
0
def _venv_python_executable(env_dir, platform):
    """Binary Python executable for a specific virtual environment"""
    if is_windows(platform):
        candidate = jp(env_dir, "Scripts", _venv_python_exename)

        # On Windows python.exe could be in PythonXY/ or venv/Scripts/
        if not os.path.exists(candidate):
            alternative = jp(env_dir, _venv_python_exename)
            if os.path.exists(alternative):
                candidate = alternative
    else:
        candidate = jp(env_dir, "bin", _venv_python_exename)

    return np(candidate)
    def test_should_generate_sphinx_build_command_builder_dir(self):
        self.project.set_property("sphinx_config_path", "docs/")
        self.project.set_property("sphinx_source_dir", "docs/")
        self.project.set_property("sphinx_output_dir", "docs/_build/")
        self.project.set_property("sphinx_doc_builder", ["JSONx", "pdf"])

        sphinx_build_command = get_sphinx_build_command(
            self.project, Mock(), "JSONx")

        self.assertEqual(sphinx_build_command, [
            ANY, "-b", "JSONx",
            np(jp(self.project.basedir, "docs/")),
            np(jp(self.project.basedir, "docs/_build/JSONx"))
        ])
Esempio n. 3
0
    def test_running_plugin_fails(
        self,
        read_file_mock,
        report_mock,
        find_files_mock,
        command_mock,
        tail_mock,
    ):
        project = Project('.')
        project.set_property('verbose', False)
        project.set_property('dir_source_main_python', 'python')
        project.set_property('dir_source_main_scripts', 'scripts')

        logger = Mock()
        reactor = Mock()
        reactor.python_env_registry = {}
        reactor.python_env_registry["pybuilder"] = pyb_env = Mock()
        reactor.pybuilder_venv = pyb_env
        pyb_env.environ = {}
        pyb_env.executable = ["a/b"]
        execute_mock = pyb_env.execute_command = Mock()

        command_mock.return_value = ['cram']
        find_files_mock.return_value = ['test1.cram', 'test2.cram']
        report_mock.return_value = 'report_file'
        read_file_mock.return_value = ['test failes for file', '# results']
        execute_mock.return_value = 1
        tail_mock.return_value = "tail data"

        self.assertRaises(BuildFailedException, run_cram_tests, project,
                          logger, reactor)
        execute_mock.assert_called_once_with(
            ['a/b', 'cram', 'test1.cram', 'test2.cram'],
            'report_file',
            error_file_name='report_file',
            env={
                'PYTHONPATH': np(jp(project.basedir, 'python')) + pathsep,
                'PATH': np(jp(project.basedir, 'scripts')) + pathsep
            })
        expected_info_calls = [
            call('Running Cram command line tests'),
        ]
        expected_error_calls = [
            call(
                'Cram tests failed! See report_file for full details:\ntail data'
            ),
        ]
        self.assertEqual(expected_info_calls, logger.info.call_args_list)
        self.assertEqual(expected_error_calls, logger.error.call_args_list)
Esempio n. 4
0
 def test_expand_path_should_return_expanded_path_and_additional_parts_when_additional_parts_are_given(
         self):
     self.project.set_property("spam", "spam")
     self.project.set_property("eggs", "eggs")
     self.assertEqual(
         np(jp(self.project.basedir, "spam", "eggs", "foo", "bar")),
         self.project.expand_path("$spam/$eggs", "foo", "bar"))
Esempio n. 5
0
def _optimize_omit_module_files(module_files, omit_module_files):
    # This is a stupid implementation but given the number of entries it'll do (until it won't)

    omf_lookup = set(omit_module_files)
    result_omit = set()

    def has_modules_in_dir_not_omitted(od):
        for mf in module_files:
            if mf.startswith(od) and mf not in omf_lookup:
                return True

    for omit in omit_module_files:
        already_omitted = False
        for ro in result_omit:
            if fnmatch(omit, ro):
                already_omitted = True
                break
        if already_omitted:
            continue

        prev_omit = omit
        omit_dir = dirname(omit)
        while prev_omit != omit_dir:
            if has_modules_in_dir_not_omitted(omit_dir):
                result_omit.add(
                    jp(prev_omit, "*") if prev_omit != omit else prev_omit)
                break
            prev_omit = omit_dir
            omit_dir = dirname(omit_dir)

    return sorted(result_omit)
Esempio n. 6
0
def list_modules(project):
    source_path = project.expand_path("$" + PYTHON_SOURCES_PROPERTY)
    for potential_module_file in listdir(source_path):
        potential_module_path = np(jp(source_path, potential_module_file))
        if isfile(potential_module_path) and potential_module_file.endswith(
                ".py"):
            yield potential_module_file[:-len(".py")]
Esempio n. 7
0
def list_scripts(project):
    scripts_dir = project.expand_path("$" + SCRIPTS_SOURCES_PROPERTY)
    if not exists(scripts_dir):
        return
    for script in listdir(scripts_dir):
        if isfile(jp(scripts_dir,
                     script)) and not HIDDEN_FILE_NAME_PATTERN.match(script):
            yield np(script)
def _list_top_level_packages(vendorized_path):
    vendorized_packages = set()
    for name in _list_metadata_dirs(vendorized_path):
        top_level_path = jp(vendorized_path, name, "top_level.txt")
        if exists(top_level_path):
            with open(top_level_path) as f:
                for p in filter(None, map(lambda line: line.strip(), f)):
                    vendorized_packages.add(p)
    return vendorized_packages
Esempio n. 9
0
 def test_find_files(self, discover_mock):
     project = Project('.')
     project.set_property('dir_source_cmdlinetest', np('any/dir'))
     project.set_property('cram_test_file_glob', '*.t')
     expected = [np(jp(project.basedir, './any/dir/test.cram'))]
     discover_mock.return_value = expected
     received = _find_files(project)
     self.assertEqual(expected, received)
     discover_mock.assert_called_once_with(np('any/dir'), '*.t')
Esempio n. 10
0
def list_modules(project):
    source_path = project.expand_path("$" + PYTHON_SOURCES_PROPERTY)
    result = []
    for potential_module_file in listdir(source_path):
        potential_module_path = np(jp(source_path, potential_module_file))
        if isfile(potential_module_path) and potential_module_file.endswith(".py"):
            result.append(potential_module_file[:-3])

    return sorted(result)
    def test_should_generate_sphinx_build_command_debug(self):
        self.project.set_property("sphinx_config_path", "docs/")
        self.project.set_property("sphinx_source_dir", "docs/")
        self.project.set_property("sphinx_output_dir", "docs/_build/")
        self.project.set_property("sphinx_doc_builder", "JSONx")

        logger = Mock()
        logger.level = 1
        logger.DEBUG = 1

        sphinx_build_command = get_sphinx_build_command(
            self.project, logger, "JSONx")

        self.assertEqual(sphinx_build_command, [
            ANY, "-b", "JSONx", "-vvvv",
            np(jp(self.project.basedir, "docs/")),
            np(jp(self.project.basedir, "docs/_build/"))
        ])
Esempio n. 12
0
def vendorize(project, reactor, logger):
    target_dir = project.expand_path("$vendorize_target_dir")
    packages = [
        Dependency(p)
        for p in as_list(project.get_property("vendorize_packages"))
    ]
    clean = project.get_property("vendorize_clean_target_dir")
    logfile = project.expand_path("$dir_logs", "vendorize.log")

    logger.info("Will vendorize packages %r into %r%s", packages, target_dir,
                " (cleaning)" if clean else "")

    if clean:
        rmtree(target_dir, ignore_errors=False)
    makedirs(target_dir, exist_ok=True)

    reactor.pybuilder_venv.install_dependencies(packages,
                                                install_log_path=logfile,
                                                package_type="vendorized",
                                                target_dir=target_dir,
                                                ignore_installed=True)

    # Vendorize
    _vendorize(target_dir)

    # Cleanup globs
    for g in project.get_property("vendorize_cleanup_globs"):
        for p in iglob(jp(target_dir, g)):
            if isdir(p):
                rmtree(p)
            else:
                unlink(p)

    # Populate names after cleanup
    cleaned_up_packages = _list_top_level_packages(target_dir)
    with open(jp(target_dir, "__init__.py"), "wt") as init_py:
        init_py.write("__names__ = %r\n" % sorted(cleaned_up_packages))

    # Cleanup metadata
    for p in _list_metadata_dirs(target_dir):
        if isdir(p):
            rmtree(p)
        else:
            unlink(p)
Esempio n. 13
0
    def include_file(self, package_name, filename):
        package_name = package_name or ""

        if not filename or filename.strip() == "":
            raise ValueError("Missing argument filename.")

        full_filename = np(jp(package_name.replace(".", sep), filename))
        self._manifest_include(full_filename)

        self._add_package_data(package_name, filename)
Esempio n. 14
0
def list_scripts(project):
    scripts_dir = project.expand_path("$" + SCRIPTS_SOURCES_PROPERTY)
    result = []
    if not exists(scripts_dir):
        return result
    for script in listdir(scripts_dir):
        if isfile(jp(scripts_dir, script)) and not HIDDEN_FILE_NAME_PATTERN.match(script):
            result.append(np(script))

    return sorted(result)
Esempio n. 15
0
    def test_should_add_pattern_to_list_of_included_filed_for_package_spam(
            self, walk):
        walk.return_value = [
            [
                jp(self.project.basedir, "spam"), ("foo", "bar"),
                ("bacon.eggs", "bacon.noeggs")
            ],
        ]
        self.project.include_directory("spam", "*.eggs")

        self.assertEqual({"spam": ["bacon.eggs"]}, self.project.package_data)
Esempio n. 16
0
def use_bldsup(build_support_dir="bldsup"):
    """Specify a local build support directory for build specific extensions.

    use_plugin(name) and import will look for python modules in BUILD_SUPPORT_DIR.

    WARNING: The BUILD_SUPPORT_DIR must exist and must have an __init__.py file in it.
    """
    assert isdir(build_support_dir), "use_bldsup('{0}'): The {0} directory must exist!".format(
        build_support_dir)
    init_file = jp(build_support_dir, "__init__.py")
    assert isfile(init_file), "use_bldsup('{0}'): The {1} file must exist!".format(build_support_dir, init_file)
    sys.path.insert(0, build_support_dir)
    def test_get_sphinx_apidoc_command_enabled(self):
        sphinx_mock = Mock()
        sys.modules["sphinx"] = sphinx_mock

        try:
            sphinx_mock.version_info = (1, 2, 3, 4, 5)

            self.project.set_property("sphinx_run_apidoc", True)
            self.project.set_property("dir_target", "dir_target")
            self.project.set_property("dir_source_main_python", "dir_source")
            self.project.set_property("sphinx_project_name", "project_name")

            self.assertEqual(
                get_sphinx_apidoc_command(self.project, self.reactor), [
                    ANY, "-H", "project_name", "-o",
                    np(jp(self.project.basedir,
                          "dir_target/sphinx_pyb/apidoc")),
                    np(jp(self.project.basedir, "dir_source"))
                ])
        finally:
            del sys.modules["sphinx"]
    def test_should_generate_sphinx_quickstart_command_with_project_properties(
            self):
        self.project.set_property("sphinx_doc_author", "bar")
        self.project.set_property("sphinx_project_name", "foo")
        self.project.set_property("sphinx_project_version", "3")
        self.project.set_property("sphinx_source_dir", "docs/")

        sphinx_quickstart_command = get_sphinx_quickstart_command(self.project)

        self.assertEqual(sphinx_quickstart_command, [
            ANY, "-q", "-p", "foo", "-a", "bar", "-v", "3",
            np(jp(self.project.basedir, "docs/"))
        ])
Esempio n. 19
0
 def __init__(self,
              env_dir,
              reactor,
              platform=None,
              install_log_name="install.log"):
     self._env_dir = env_dir
     self._reactor = reactor
     self._platform = platform or sys.platform
     self._long_desc = "Unpopulated"
     self._site_paths = None
     self._venv_symlinks = os.name == "posix"
     self._install_log_path = jp(self._env_dir, install_log_name)
     self._populated = False
Esempio n. 20
0
    def test_running_plugin_cram_from_target(self, read_file_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)
        project._plugin_env = {}
        logger = Mock()

        reactor = Mock()
        reactor.python_env_registry = {}
        reactor.python_env_registry["pybuilder"] = pyb_env = Mock()
        reactor.pybuilder_venv = pyb_env
        pyb_env.environ = {}
        pyb_env.executable = ["a/b"]
        execute_mock = pyb_env.execute_command = Mock()

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

        run_cram_tests(project, logger, reactor)
        execute_mock.assert_called_once_with(
            ['a/b', 'cram', 'test1.cram', 'test2.cram'],
            'report_file',
            error_file_name='report_file',
            env={
                'PYTHONPATH': np(jp(project.basedir, 'python')) + pathsep,
                'PATH': np(jp(project.basedir, 'python/scripts')) + pathsep
            })
        expected_info_calls = [
            call('Running Cram command line tests'),
            call('Cram tests were fine'),
            call('results'),
        ]
        self.assertEqual(expected_info_calls, logger.info.call_args_list)
    def test_sphinx_pyb_quickstart_generate(self, symlink, mkdir, exists,
                                            rmtree, open):
        exists.return_value = False

        self.project.set_property("sphinx_source_dir", "sphinx_source_dir")
        self.project.set_property("sphinx_config_path", "sphinx_config_path")
        self.project.set_property("dir_target", "dir_target")
        self.project.set_property("dir_source_main_python", "dir_source")
        self.project.set_property("sphinx_project_name", "project_name")

        sphinx_pyb_quickstart_generate(self.project, Mock(), self.reactor)

        open().__enter__().write.assert_called_with("""\
# Automatically generated by PyB
import sys
from os.path import normcase as nc, normpath as np, join as jp, dirname, exists

sphinx_pyb_dir = nc(np(jp(dirname(__file__) if __file__ else '.', %r)))
sphinx_pyb_module = 'sphinx_pyb_conf'
sphinx_pyb_module_file = nc(np(jp(sphinx_pyb_dir, sphinx_pyb_module + '.py')))

sys.path.insert(0, sphinx_pyb_dir)

if not exists(sphinx_pyb_module_file):
    raise RuntimeError("No PyB-based Sphinx configuration found in " + sphinx_pyb_module_file)

from sphinx_pyb_conf import *

# Overwrite PyB-settings here statically if that's the thing that you want
""" % relpath(np(jp(self.project.basedir, "../dir_target/sphinx_pyb")),
              self.project.basedir))
        symlink.assert_called_with(relpath(
            np(jp(self.project.basedir, "../dir_target/sphinx_pyb/apidoc")),
            self.project.basedir),
                                   np(
                                       jp(self.project.basedir,
                                          "sphinx_source_dir/apidoc")),
                                   target_is_directory=True)
Esempio n. 22
0
 def test_iglob(self):
     self.assertEqual(list(iglob(jp(self.tmp_dir, "*.py"))),
                      [jp(self.tmp_dir, "x.py")])
     self.assertEqual(
         list(iglob(jp(self.tmp_dir, "**", "*.py"), recursive=True)), [
             jp(self.tmp_dir, "x.py"),
             jp(self.tmp_dir, "a", "y.py"),
             jp(self.tmp_dir, "a", "b", "z.py")
         ])
Esempio n. 23
0
def _override_python_env_for_coverage(current_python_env, coverage_config,
                                      source_path, omit_patterns):
    import coverage as cov_module
    cov_parent_dir = ap(jp(dirname(cov_module.__file__), ".."))

    new_python_env = copy.copy(current_python_env)
    new_python_env.overwrite(
        "executable",
        tuple(
            current_python_env.executable + [
                ap(
                    jp(
                        dirname(sys.modules[_override_python_env_for_coverage.
                                            __module__].__file__),
                        "_coverage_shim.py")),
                repr(
                    {
                        "cov_parent_dir": cov_parent_dir,
                        "cov_kwargs": coverage_config,
                        "cov_source_path": source_path,
                        "cov_omit_patterns": omit_patterns,
                    }, )
            ], ))
    return new_python_env
Esempio n. 24
0
def _vendorize(vendorized_path):
    vendorized_packages = _list_top_level_packages(vendorized_path)
    for root, dirs, files in walk(vendorized_path):
        for py_path in files:
            if not py_path.endswith(".py"):
                continue
            py_path = np(jp(root, py_path))
            with open(py_path, "rt") as source_file:
                source = source_file.read()
            parsed_ast = ast.parse(source, filename=py_path)
            it = ImportTransformer(py_path, source, vendorized_path,
                                   vendorized_packages, [])
            it.visit(parsed_ast)
            with open(py_path, "wt") as source_file:
                source_file.write(it.transformed_source)

    return vendorized_packages
Esempio n. 25
0
    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
Esempio n. 26
0
def _filter_covered_modules(logger, module_names, module_file_suffixes,
                            modules_exceptions, source_path):
    result_module_names = []
    result_module_files = []
    omit_module_files = []
    module_files = []

    for idx, module_name in enumerate(module_names):
        module_file = nc(jp(source_path, module_file_suffixes[idx]))
        module_files.append(module_file)

        skip_module = False
        for module_exception in modules_exceptions:
            if module_exception.endswith("*"):
                if module_name.startswith(module_exception[:-1]):
                    skip_module = True
                    break
            else:
                if module_name == module_exception:
                    skip_module = True
                    break

        if not skip_module:
            with open(module_file, "rb") as f:
                try:
                    ast.parse(f.read(), module_file)
                except SyntaxError:
                    logger.warn(
                        "Unable to parse module %r (file %r) due to syntax error and will be excluded"
                        % (module_name, module_file))
                    skip_module = True

        if skip_module:
            logger.debug("Module %r (file %r) was excluded", module_name,
                         module_file)
            omit_module_files.append(module_file)
        else:
            result_module_names.append(module_name)
            result_module_files.append(module_file)

    omit_module_files = _optimize_omit_module_files(module_files,
                                                    omit_module_files)
    return result_module_names, result_module_files, omit_module_files
Esempio n. 27
0
    def _setup_plugin_directory(self, reset_plugins):
        per = self.python_env_registry
        system_env = per["system"]
        plugin_dir = self._plugin_dir = np(
            jp(self.project.basedir, ".pybuilder", "plugins",
               system_env.versioned_dir_name))

        self.logger.debug("Setting up plugins VEnv at '%s'%s", plugin_dir,
                          " (resetting)" if reset_plugins else "")
        plugin_env = per["pybuilder"] = PythonEnv(
            plugin_dir, self).create_venv(with_pip=True,
                                          symlinks=system_env.venv_symlinks,
                                          upgrade=True,
                                          clear=(reset_plugins
                                                 or system_env.is_pypy),
                                          offline=self.project.offline)

        prepend_env_to_path(plugin_env, sys.path)
        patch_mp_pyb_env(plugin_env)
Esempio n. 28
0
    def include_directory(self, package_path, patterns_list, package_root=""):
        if not package_path or package_path.strip() == "":
            raise ValueError("Missing argument package_path.")

        if not patterns_list:
            raise ValueError("Missing argument patterns_list.")
        patterns_list = as_list(patterns_list)

        package_name = PATH_SEP_RE.sub(".", package_path)
        self._manifest_include_directory(package_path, patterns_list)

        package_full_path = self.expand_path(package_root, package_path)

        for root, dirnames, filenames in os.walk(package_full_path):
            filenames = list(fnmatch.filter(filenames, pattern) for pattern in patterns_list)

            for filename in itertools.chain.from_iterable(filenames):
                full_path = np(jp(root, filename))
                relative_path = relpath(full_path, package_full_path)
                self._add_package_data(package_name, relative_path)
    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')
        project.set_property('dir_source_unittest_python',
                             'src/unittest/python')
        project.set_property('dir_source_integrationtest_python',
                             'src/integrationtest/python')
        project.set_property('dir_target', 'build')
        mock_open.return_value = MagicMock(spec=TYPE_FILE)
        os.path.join.side_effect = lambda first, second: first + sep + second

        pycharm_generate(project, Mock())

        mock_open.assert_called_with(
            np(jp(project.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" />
      <sourceFolder url="file://$MODULE_DIR$/src/unittest/python" isTestSource="true" />
      <sourceFolder url="file://$MODULE_DIR$/src/integrationtest/python" isTestSource="true" />
      <excludeFolder url="file://$MODULE_DIR$/.pybuilder" />
      <excludeFolder url="file://$MODULE_DIR$/build" />
    </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>""")
Esempio n. 30
0
 def test_expand_path_should_return_expanded_path(self):
     self.project.set_property("spam", "spam")
     self.project.set_property("eggs", "eggs")
     self.assertEqual(np(jp(self.project.basedir, "spam", "eggs")),
                      self.project.expand_path("$spam/$eggs"))