Beispiel #1
0
def test_modified_tool(runner, project, capsys):
    """Test detection of modified tool."""
    from renku.api import LocalClient

    client = LocalClient(project)
    repo = client.git
    greeting = client.path / 'greeting.txt'

    with capsys.disabled():
        with greeting.open('wb') as stdout:
            try:
                old_stdout = sys.stdout
                sys.stdout = stdout
                try:
                    cli.cli.main(args=('run', 'echo', 'hello'), )
                except SystemExit as e:
                    assert e.code in {None, 0}
            finally:
                sys.stdout = old_stdout

    cmd = ['status']
    result = runner.invoke(cli.cli, cmd)
    assert result.exit_code == 0

    # There should be only one command line tool.
    tools = list(client.workflow_path.glob('*_echo.cwl'))
    assert 1 == len(tools)

    tool_path = tools[0]
    with tool_path.open('r') as f:
        command_line_tool = CWLClass.from_cwl(yaml.load(f))

    # Simulate a manual edit.
    command_line_tool.inputs[0].default = 'ahoj'
    command_line_tool.stdout = 'pozdrav.txt'

    with tool_path.open('w') as f:
        yaml.dump(ascwl(
            command_line_tool,
            filter=lambda _, x: x is not None,
            basedir=client.workflow_path,
        ),
                  stream=f,
                  default_flow_style=False)

    repo.git.add('--all')
    repo.index.commit('Modified tool', skip_hooks=True)

    assert 0 == _run_update(runner, capsys)

    output = client.path / 'pozdrav.txt'
    assert output.exists()
    with output.open('r') as f:
        assert 'ahoj\n' == f.read()

    cmd = ['status']
    result = runner.invoke(cli.cli, cmd)
    assert 0 == result.exit_code
Beispiel #2
0
    def add_file(self, path, revision='HEAD'):
        """Add a file node to the graph."""
        file_commits = list(self.client.git.iter_commits(revision, paths=path))

        if not file_commits:
            raise KeyError('Could not find a file {0} in range {1}'.format(
                path, revision))

        commit = file_commits[0]

        cwl = self.find_cwl(commit)
        if cwl is not None:
            file_key = self.add_node(commit, path)
            self.add_tool(commit, cwl, file_key=file_key)
            return file_key
        else:
            #: Does not have a parent CWL.
            root_node = self.add_node(commit, path)
            parent_commit, parent_path = root_node

            #: Capture information about the submodule in a submodule.
            root_submodule = self.G.nodes[root_node].get('submodule', [])

            #: Resolve Renku based submodules.
            original_path = Path(parent_path)
            if original_path.is_symlink() or str(original_path).startswith(
                    '.renku/vendors'):
                original_path = original_path.resolve()

                for submodule in Submodule.iter_items(
                        self.client.git, parent_commit=parent_commit):
                    try:
                        subpath = original_path.relative_to(
                            Path(submodule.path).resolve())
                        subgraph = Graph(client=LocalClient(
                            path=submodule.path))
                        subnode = subgraph.add_file(str(subpath),
                                                    revision=submodule.hexsha)

                        #: Extend node metadata.
                        for _, data in subgraph.G.nodes(data=True):
                            data['submodule'] = root_submodule + [
                                submodule.name
                            ]

                        #: Merge file node with it's symlinked version.
                        self.G = nx.contracted_nodes(
                            nx.compose(self.G, subgraph.G),
                            root_node,
                            subnode,
                        )  # TODO optionally it can be changed to an edge.
                        break
                    except ValueError:
                        continue

            return root_node
Beispiel #3
0
def client():
    """Return a Renku repository."""
    from renku import cli
    from renku.api import LocalClient
    runner = CliRunner()

    with runner.isolated_filesystem() as project_path:
        result = runner.invoke(cli.cli, ['init', '.'], catch_exceptions=False)
        assert result.exit_code == 0

        yield LocalClient(path=project_path)
Beispiel #4
0
def add_client(doctest_namespace):
    """Add Renku client to doctest namespace."""
    from renku.api import LocalClient
    doctest_namespace['client'] = LocalClient(path=tempfile.mkdtemp())
Beispiel #5
0
def client(project):
    """Return a Renku repository."""
    from renku.api import LocalClient

    yield LocalClient(path=project)
Beispiel #6
0
    def default_inputs(self):
        """Guess default inputs from a process."""
        basedir = os.path.dirname(self.path)
        commit = self.commit
        client = self.client
        process = self.process
        hierarchy = self.submodules

        inputs = {}
        revision = '{0}^'.format(commit)

        try:
            from git import Submodule

            submodules = [
                submodule
                for submodule in Submodule.iter_items(client.git,
                                                      parent_commit=commit)
            ]
        except (RuntimeError, ValueError):
            # There are no submodules assiciated with the given commit.
            submodules = []

        subclients = {
            submodule: LocalClient(
                path=(client.path / submodule.path).resolve(),
                parent=client,
            )
            for submodule in submodules
        }

        def resolve_submodules(file_, **kwargs):
            original_path = client.path / file_
            if original_path.is_symlink() or file_.startswith(
                    '.renku/vendors'):
                original_path = original_path.resolve()
                for submodule, subclient in subclients.items():
                    try:
                        subpath = original_path.relative_to(subclient.path)
                        return Usage.from_revision(client=subclient,
                                                   path=str(subpath),
                                                   revision=submodule.hexsha,
                                                   submodules=hierarchy +
                                                   [submodule.name],
                                                   **kwargs)
                    except ValueError:
                        pass

        for input_id, input_path in process.iter_input_files(basedir):
            try:
                usage_id = self._id + '/inputs/' + input_id
                dependency = resolve_submodules(
                    input_path,
                    role=input_id,
                    id=usage_id,
                )
                if dependency is None:
                    dependency = Usage.from_revision(
                        client=client,
                        path=input_path,
                        role=input_id,
                        revision=revision,
                        id=usage_id,
                    )
                inputs[input_path] = dependency
            except KeyError:
                continue

        return inputs