Example #1
0
        def prefixes_should_apply_to_run(self, Local):
            runner = Local.return_value
            ctx = Context()
            with ctx.prefix('cd foo'):
                ctx.run('whoami')

            cmd = "cd foo && whoami"
            ok_(runner.run.called, "run() never called runner.run()!")
            eq_(runner.run.call_args[0][0], cmd)
Example #2
0
        def prefixes_should_apply_to_run(self, Local):
            runner = Local.return_value
            ctx = Context()
            with ctx.prefix('cd foo'):
                ctx.run('whoami')

            cmd = "cd foo && whoami"
            ok_(runner.run.called, "run() never called runner.run()!")
            eq_(runner.run.call_args[0][0], cmd)
Example #3
0
        def prefixes_should_apply_to_sudo(self, Local):
            runner = Local.return_value
            ctx = Context()
            with ctx.prefix('cd foo'):
                ctx.sudo('whoami')

            cmd = "sudo -S -p '[sudo] password: ' cd foo && whoami"
            ok_(runner.run.called, "sudo() never called runner.run()!")
            eq_(runner.run.call_args[0][0], cmd)
Example #4
0
        def prefixes_should_apply_to_run(self, Local):
            runner = Local.return_value
            c = Context()
            with c.prefix("cd foo"):
                c.run("whoami")

            cmd = "cd foo && whoami"
            assert runner.run.called, "run() never called runner.run()!"
            assert runner.run.call_args[0][0] == cmd
Example #5
0
        def prefixes_should_apply_to_sudo(self, Local):
            runner = Local.return_value
            ctx = Context()
            with ctx.prefix('cd foo'):
                ctx.sudo('whoami')

            cmd = "sudo -S -p '[sudo] password: ' cd foo && whoami"
            ok_(runner.run.called, "sudo() never called runner.run()!")
            eq_(runner.run.call_args[0][0], cmd)
Example #6
0
        def prefixes_should_apply_to_sudo(self, Local):
            runner = Local.return_value
            c = Context()
            with c.prefix("cd foo"):
                c.sudo("whoami")

            cmd = "sudo -S -p '[sudo] password: ' cd foo && whoami"
            assert runner.run.called, "sudo() never called runner.run()!"
            assert runner.run.call_args[0][0] == cmd
Example #7
0
        def cd_should_occur_before_prefixes(self, Local):
            runner = Local.return_value
            ctx = Context()
            with ctx.prefix('source venv'):
                with ctx.cd('foo'):
                    ctx.run('whoami')

            cmd = "cd foo && source venv && whoami"
            ok_(runner.run.called, "run() never called runner.run()!")
            eq_(runner.run.call_args[0][0], cmd)
Example #8
0
        def cd_should_occur_before_prefixes(self, Local):
            runner = Local.return_value
            c = Context()
            with c.prefix("source venv"):
                with c.cd("foo"):
                    c.run("whoami")

            cmd = "cd foo && source venv && whoami"
            assert runner.run.called, "run() never called runner.run()!"
            assert runner.run.call_args[0][0] == cmd
Example #9
0
        def cd_should_occur_before_prefixes(self, Local):
            runner = Local.return_value
            ctx = Context()
            with ctx.prefix('source venv'):
                with ctx.cd('foo'):
                    ctx.run('whoami')

            cmd = "cd foo && source venv && whoami"
            ok_(runner.run.called, "run() never called runner.run()!")
            eq_(runner.run.call_args[0][0], cmd)
Example #10
0
        def nesting_should_retain_order(self, Local):
            runner = Local.return_value
            c = Context()
            with c.prefix('cd foo'):
                with c.prefix('cd bar'):
                    c.run('whoami')
                    cmd = "cd foo && cd bar && whoami"
                    assert runner.run.called, "run() never called runner.run()!"  # noqa
                    assert runner.run.call_args[0][0] == cmd

                c.run('whoami')
                cmd = "cd foo && whoami"
                assert runner.run.called, "run() never called runner.run()!"
                assert runner.run.call_args[0][0] == cmd

            # also test that prefixes do not persist
            c.run('whoami')
            cmd = "whoami"
            assert runner.run.called, "run() never called runner.run()!"
            assert runner.run.call_args[0][0] == cmd
Example #11
0
        def nesting_should_retain_order(self, Local):
            runner = Local.return_value
            ctx = Context()
            with ctx.prefix('cd foo'):
                with ctx.prefix('cd bar'):
                    ctx.run('whoami')
                    cmd = "cd foo && cd bar && whoami"
                    ok_(runner.run.called, "run() never called runner.run()!")
                    eq_(runner.run.call_args[0][0], cmd)

                ctx.run('whoami')
                cmd = "cd foo && whoami"
                ok_(runner.run.called, "run() never called runner.run()!")
                eq_(runner.run.call_args[0][0], cmd)

            # also test that prefixes do not persist
            ctx.run('whoami')
            cmd = "whoami"
            ok_(runner.run.called, "run() never called runner.run()!")
            eq_(runner.run.call_args[0][0], cmd)
Example #12
0
        def nesting_should_retain_order(self, Local):
            runner = Local.return_value
            ctx = Context()
            with ctx.prefix('cd foo'):
                with ctx.prefix('cd bar'):
                    ctx.run('whoami')
                    cmd = "cd foo && cd bar && whoami"
                    ok_(runner.run.called, "run() never called runner.run()!")
                    eq_(runner.run.call_args[0][0], cmd)

                ctx.run('whoami')
                cmd = "cd foo && whoami"
                ok_(runner.run.called, "run() never called runner.run()!")
                eq_(runner.run.call_args[0][0], cmd)

            # also test that prefixes do not persist
            ctx.run('whoami')
            cmd = "whoami"
            ok_(runner.run.called, "run() never called runner.run()!")
            eq_(runner.run.call_args[0][0], cmd)
Example #13
0
        def nesting_should_retain_order(self, Local):
            runner = Local.return_value
            c = Context()
            with c.prefix('cd foo'):
                with c.prefix('cd bar'):
                    c.run('whoami')
                    cmd = "cd foo && cd bar && whoami"
                    assert runner.run.called, "run() never called runner.run()!" # noqa
                    assert runner.run.call_args[0][0] == cmd

                c.run('whoami')
                cmd = "cd foo && whoami"
                assert runner.run.called, "run() never called runner.run()!"
                assert runner.run.call_args[0][0] == cmd

            # also test that prefixes do not persist
            c.run('whoami')
            cmd = "whoami"
            assert runner.run.called, "run() never called runner.run()!"
            assert runner.run.call_args[0][0] == cmd
Example #14
0
def _run_task(
    ctx: Context,
    connector_string: str,
    task_name: str,
    multi_envs: bool = True,
    module_path: Optional[str] = None,
    task_commands: Dict = TASK_COMMANDS,
    **kwargs: Any,
) -> int:
    """
    Run task in its own environment.
    """
    cur_dir = os.getcwd()
    if multi_envs:
        if module_path:
            os.chdir(module_path)
            source_path = connector_string
        else:
            os.chdir(os.path.join(CONNECTORS_DIR,
                                  f"source-{connector_string}"))
            source_path = f"source_{connector_string.replace('-', '_')}"

    else:
        source_path = connector_string

    venv_name = tempfile.mkdtemp(dir=os.curdir)
    virtualenv.cli_run([venv_name])
    activator = os.path.join(os.path.abspath(venv_name), "bin", "activate")

    commands = []

    commands.extend([
        cmd.format(source_path=source_path, venv=venv_name, **kwargs)
        for cmd in task_commands[task_name]
    ])

    exit_code: int = 0

    try:
        with ctx.prefix(f"source {activator}"):
            for command in commands:
                result = ctx.run(command, echo=True, warn=True)
                if result.return_code:
                    exit_code = 1
                    break
    finally:
        shutil.rmtree(venv_name, ignore_errors=True)

    if module_path:
        os.chdir(cur_dir)

    return exit_code
Example #15
0
        def should_use_finally_to_revert_changes_on_exceptions(self, Local):
            class Oops(Exception):
                pass

            runner = Local.return_value
            c = Context()
            try:
                with c.prefix("cd foo"):
                    c.run("whoami")
                    assert runner.run.call_args[0][0] == "cd foo && whoami"
                    raise Oops
            except Oops:
                pass
            c.run("ls")
            # When bug present, this would be "cd foo && ls"
            assert runner.run.call_args[0][0] == "ls"
Example #16
0
def docs(ctx: Context, html: Boolean = True, pdf: Boolean = True):
    """Build the documentation.

    Parameters
    ----------
    ctx
        Context.
    html
        Whether to build the *HTML* documentation.
    pdf
        Whether to build the *PDF* documentation.
    """

    with ctx.prefix("export COLOUR_SCIENCE__DOCUMENTATION_BUILD=True"):
        with ctx.cd("docs"):
            if html:
                message_box('Building "HTML" documentation...')
                ctx.run("make html")

            if pdf:
                message_box('Building "PDF" documentation...')
                ctx.run("make latexpdf")
Example #17
0
def install_requirements_pip(ctx: Context):
    """Install requirements in the virtual environment."""
    # Collect all parameters determining installation of requirements
    pip_reqs = set([])
    req_fns = set([])
    for _conda_req, pip_req in ctx.project.requirements:
        if pip_req is not None:
            pip_reqs.add(pip_req)
    for package in ctx.project.packages:
        for toolname in package.tools:
            tool = TOOLS[toolname]
            for _conda_req, pip_req in tool.requirements:
                if pip_req is not None:
                    pip_reqs.add(pip_req)
        req_fns.add(os.path.join(package.path, "setup.py"))
    req_hash = compute_req_hash(pip_reqs, req_fns)

    fn_skip = os.path.join(ctx.testenv.path, ".skip_install")
    if check_install_requirements(fn_skip, req_hash):
        with ctx.prefix(ctx.testenv.activate):
            if len(pip_reqs) > 0:
                # Install pip packages for the tools
                ctx.run("pip install -U {}".format(" ".join(
                        "'{}'".format(pip_req) for pip_req in pip_reqs)))
            # Install dependencies for the project.
            for package in ctx.project.packages:
                with ctx.cd(package.path):
                    ctx.run("python setup.py egg_info")
                    fn_requires = os.path.join(
                        package.dist_name.replace("-", "_") + ".egg-info",
                        "requires.txt")
                    with tempfile.TemporaryDirectory() as tmpdir:
                        fn_requirements = os.path.join(tmpdir, "requirements.txt")
                        convert_requires(fn_requires, fn_requirements)
                        ctx.run("pip install -U -r " + fn_requirements)
        # Update the timestamp on the skip file.
        with open(fn_skip, 'w') as f:
            f.write(req_hash + '\n')
Example #18
0
def install_requirements_conda(ctx: Context):
    """Install all requirements, including tools used by Roberto."""
    # Collect all parameters determining the install commands (to good
    # approximation) and turn them into a hash.
    # Some conda requirements are included by default because they must be present:
    # - conda: to make sure it is always up to date.
    # - conda-build: to have conda-render for getting requirements from recipes.
    conda_reqs = set(["conda"])
    pip_reqs = set([])
    recipe_dirs = []
    # Add project as a tool because it also contains requirements.
    tools = [ctx.project]
    for package in ctx.project.packages:
        for toolname in package.tools:
            tools.append(ctx.tools[toolname])
        recipe_dir = os.path.join(package.path, "tools", "conda.recipe")
        if os.path.isdir(recipe_dir):
            recipe_dirs.append(recipe_dir)
        else:
            print("Skipping recipe {}. (directory does not exist)".format(recipe_dir))
    for tool in tools:
        for conda_req, pip_req in tool.get("requirements", []):
            if conda_req is None:
                pip_reqs.add(pip_req)
                conda_reqs.add("pip")
            else:
                conda_reqs.add(conda_req)
    req_hash = compute_req_hash(
        set("conda:" + conda_req for conda_req in conda_reqs) |
        set("pip:" + pip_req for pip_req in pip_reqs),
        sum([glob(os.path.join(recipe_dir, "*")) for recipe_dir in recipe_dirs], [])
    )

    fn_skip = os.path.join(ctx.testenv.path, ".skip_install")
    if check_install_requirements(fn_skip, req_hash):
        with ctx.prefix(ctx.conda.activate_base):
            # Update conda packages in the base env. Conda packages in the dev env
            # tend to be ignored.
            ctx.run("conda install --update-deps -y {}".format(
                " ".join("'{}'".format(conda_req) for conda_req
                         in conda_reqs if conda_req.startswith('conda'))))

        with ctx.prefix(ctx.testenv.activate):
            # Update packages already installed
            ctx.run("conda update --all -y")

            # Update and install other requirements for Roberto, in the dev env.
            ctx.run("conda install --update-deps -y {}".format(" ".join(
                "'{}'".format(conda_req) for conda_req in conda_reqs
                if not conda_req.startswith('conda'))))

            print("Rendering conda package, extracting requirements, which will be installed.")

            # Install dependencies from recipes, excluding own packages.
            own_conda_reqs = [package.dist_name for package in ctx.project.packages]
            for recipe_dir in recipe_dirs:
                # Send the output of conda render to a temporary directory.
                with tempfile.TemporaryDirectory() as tmpdir:
                    rendered_path = os.path.join(tmpdir, "rendered.yml")
                    ctx.run(
                        "conda render -f {} {} --variants {}".format(
                            rendered_path, recipe_dir, ctx.conda.variants))
                    with open(rendered_path) as f:
                        rendered = yaml.safe_load(f)
                # Build a (simplified) list of requirements and install.
                dep_conda_reqs = set([])
                req_sources = [
                    ("requirements", 'build'),
                    ("requirements", 'host'),
                    ("requirements", 'run'),
                    ("test", 'requires'),
                ]
                for req_section, req_type in req_sources:
                    for recipe_req in rendered.get(req_section, {}).get(req_type, []):
                        words = recipe_req.split()
                        if words[0] not in own_conda_reqs:
                            dep_conda_reqs.add(" ".join(words[:2]))
                ctx.run("conda install --update-deps -y {}".format(" ".join(
                    "'{}'".format(conda_req) for conda_req in dep_conda_reqs)))

            # Update and install requirements for Roberto from pip, if any.
            if pip_reqs:
                ctx.run("pip install --upgrade {}".format(" ".join(
                    "'{}'".format(pip_req) for pip_req in pip_reqs)))

        # Update the timestamp on the skip file.
        with open(fn_skip, 'w') as f:
            f.write(req_hash + '\n')