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
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
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)
def add_client(doctest_namespace): """Add Renku client to doctest namespace.""" from renku.api import LocalClient doctest_namespace['client'] = LocalClient(path=tempfile.mkdtemp())
def client(project): """Return a Renku repository.""" from renku.api import LocalClient yield LocalClient(path=project)
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