{"action":"created","comment":{"url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/pulls/comments/169239572","pull_request_review_id":97677419,"id":169239572,"diff_hunk":"@@ -128,6 +131,76 @@ def _output_keys(self):\n         \"\"\"Return a list of the output keys.\"\"\"\n         return [n for n, d in self.G.out_degree() if d == 0]\n \n+    def _need_update(self):\n+        \"\"\"Yield all files that need to be updated.\"\"\"\n+        visited = set()\n+\n+        for key in nx.topological_sort(self.G):\n+            assert key not in visited\n+            need_update = []\n+            node = self.G.nodes[key]\n+            latest = node.get('latest')\n+            if latest:\n+                need_update.append(key)\n+\n+            for parent, _ in self.G.in_edges(key):\n+                assert parent in visited\n+                need_update.extend(self.G.nodes[parent]['_need_update'])\n+\n+            if not latest and need_update:\n+                need_update.append(key)\n+\n+            self.G.nodes[key]['_need_update'] = need_update\n+            visited.add(key)\n+\n+    def build_status(self, revision='HEAD'):\n+        \"\"\"Return files from the revision groupped by their status.\"\"\"\n+        index = self.repo.git.index if revision == 'HEAD' \\\n+            else IndexFile.from_tree(repo.git, revision)\n+\n+        current_files = set()\n+\n+        for filepath, _ in index.entries.keys():\n+            if not filepath.startswith('.renga') and \\\n+                    filepath not in {'.gitignore', }:\n+                self.add_file(filepath, revision=revision)\n+                current_files.add(filepath)\n+\n+        # Prepare status info for each file.\n+        self._need_update()\n+\n+        graph_files = list(sorted(\n+            ((commit, filepath) for (commit, filepath) in self.G\n+             if filepath in current_files),\n+            key=itemgetter(1)\n+        ))\n+\n+        status = {'up-to-date': {}, 'outdated': {}, 'multiple-versions': {}}\n+\n+        for filepath, files in groupby(graph_files, itemgetter(1)):","path":"renga/cli/_graph.py","position":64,"original_position":64,"commit_id":"cc75ab3c34b668563c2a22103558b62465ec3113","original_commit_id":"cc75ab3c34b668563c2a22103558b62465ec3113","user":{"login":"rokroskar","id":3353586,"avatar_url":"https://avatars3.githubusercontent.com/u/3353586?v=4","gravatar_id":"","url":"https://api.github.com/users/rokroskar","html_url":"https://github.com/rokroskar","followers_url":"https://api.github.com/users/rokroskar/followers","following_url":"https://api.github.com/users/rokroskar/following{/other_user}","gists_url":"https://api.github.com/users/rokroskar/gists{/gist_id}","starred_url":"https://api.github.com/users/rokroskar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rokroskar/subscriptions","organizations_url":"https://api.github.com/users/rokroskar/orgs","repos_url":"https://api.github.com/users/rokroskar/repos","events_url":"https://api.github.com/users/rokroskar/events{/privacy}","received_events_url":"https://api.github.com/users/rokroskar/received_events","type":"User","site_admin":false},"body":"isn't `files` actually `commits` or `shas`? ","created_at":"2018-02-20T08:03:37Z","updated_at":"2018-02-20T08:04:43Z","html_url":"https://github.com/SwissDataScienceCenter/renga-python/pull/111#discussion_r169239572","pull_request_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/pulls/111","author_association":"OWNER","_links":{"self":{"href":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/pulls/comments/169239572"},"html":{"href":"https://github.com/SwissDataScienceCenter/renga-python/pull/111#discussion_r169239572"},"pull_request":{"href":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/pulls/111"}}},"pull_request":{"url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/pulls/111","id":170054309,"html_url":"https://github.com/SwissDataScienceCenter/renga-python/pull/111","diff_url":"https://github.com/SwissDataScienceCenter/renga-python/pull/111.diff","patch_url":"https://github.com/SwissDataScienceCenter/renga-python/pull/111.patch","issue_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/issues/111","number":111,"state":"open","locked":false,"title":"cli: add status command","user":{"login":"jirikuncar","id":189798,"avatar_url":"https://avatars1.githubusercontent.com/u/189798?v=4","gravatar_id":"","url":"https://api.github.com/users/jirikuncar","html_url":"https://github.com/jirikuncar","followers_url":"https://api.github.com/users/jirikuncar/followers","following_url":"https://api.github.com/users/jirikuncar/following{/other_user}","gists_url":"https://api.github.com/users/jirikuncar/gists{/gist_id}","starred_url":"https://api.github.com/users/jirikuncar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jirikuncar/subscriptions","organizations_url":"https://api.github.com/users/jirikuncar/orgs","repos_url":"https://api.github.com/users/jirikuncar/repos","events_url":"https://api.github.com/users/jirikuncar/events{/privacy}","received_events_url":"https://api.github.com/users/jirikuncar/received_events","type":"User","site_admin":false},"body":"- [ ] add tests\r\n\r\n![image](https://user-images.githubusercontent.com/189798/36397413-f9af2dda-15c2-11e8-80e4-73fa3b88c22e.png)\r\n\r\n(closes #107)","created_at":"2018-02-19T21:18:47Z","updated_at":"2018-02-20T08:04:43Z","closed_at":null,"merged_at":null,"merge_commit_sha":"de3d5e1341a33821829f7d47b9ce3d6c0c84c14c","assignee":{"login":"jirikuncar","id":189798,"avatar_url":"https://avatars1.githubusercontent.com/u/189798?v=4","gravatar_id":"","url":"https://api.github.com/users/jirikuncar","html_url":"https://github.com/jirikuncar","followers_url":"https://api.github.com/users/jirikuncar/followers","following_url":"https://api.github.com/users/jirikuncar/following{/other_user}","gists_url":"https://api.github.com/users/jirikuncar/gists{/gist_id}","starred_url":"https://api.github.com/users/jirikuncar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jirikuncar/subscriptions","organizations_url":"https://api.github.com/users/jirikuncar/orgs","repos_url":"https://api.github.com/users/jirikuncar/repos","events_url":"https://api.github.com/users/jirikuncar/events{/privacy}","received_events_url":"https://api.github.com/users/jirikuncar/received_events","type":"User","site_admin":false},"assignees":[{"login":"jirikuncar","id":189798,"avatar_url":"https://avatars1.githubusercontent.com/u/189798?v=4","gravatar_id":"","url":"https://api.github.com/users/jirikuncar","html_url":"https://github.com/jirikuncar","followers_url":"https://api.github.com/users/jirikuncar/followers","following_url":"https://api.github.com/users/jirikuncar/following{/other_user}","gists_url":"https://api.github.com/users/jirikuncar/gists{/gist_id}","starred_url":"https://api.github.com/users/jirikuncar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jirikuncar/subscriptions","organizations_url":"https://api.github.com/users/jirikuncar/orgs","repos_url":"https://api.github.com/users/jirikuncar/repos","events_url":"https://api.github.com/users/jirikuncar/events{/privacy}","received_events_url":"https://api.github.com/users/jirikuncar/received_events","type":"User","site_admin":false}],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/pulls/111/commits","review_comments_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/pulls/111/comments","review_comment_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/pulls/comments{/number}","comments_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/issues/111/comments","statuses_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/statuses/cc75ab3c34b668563c2a22103558b62465ec3113","head":{"label":"jirikuncar:107-cli-status","ref":"107-cli-status","sha":"cc75ab3c34b668563c2a22103558b62465ec3113","user":{"login":"jirikuncar","id":189798,"avatar_url":"https://avatars1.githubusercontent.com/u/189798?v=4","gravatar_id":"","url":"https://api.github.com/users/jirikuncar","html_url":"https://github.com/jirikuncar","followers_url":"https://api.github.com/users/jirikuncar/followers","following_url":"https://api.github.com/users/jirikuncar/following{/other_user}","gists_url":"https://api.github.com/users/jirikuncar/gists{/gist_id}","starred_url":"https://api.github.com/users/jirikuncar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jirikuncar/subscriptions","organizations_url":"https://api.github.com/users/jirikuncar/orgs","repos_url":"https://api.github.com/users/jirikuncar/repos","events_url":"https://api.github.com/users/jirikuncar/events{/privacy}","received_events_url":"https://api.github.com/users/jirikuncar/received_events","type":"User","site_admin":false},"repo":{"id":102718705,"name":"renga-python","full_name":"jirikuncar/renga-python","owner":{"login":"jirikuncar","id":189798,"avatar_url":"https://avatars1.githubusercontent.com/u/189798?v=4","gravatar_id":"","url":"https://api.github.com/users/jirikuncar","html_url":"https://github.com/jirikuncar","followers_url":"https://api.github.com/users/jirikuncar/followers","following_url":"https://api.github.com/users/jirikuncar/following{/other_user}","gists_url":"https://api.github.com/users/jirikuncar/gists{/gist_id}","starred_url":"https://api.github.com/users/jirikuncar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jirikuncar/subscriptions","organizations_url":"https://api.github.com/users/jirikuncar/orgs","repos_url":"https://api.github.com/users/jirikuncar/repos","events_url":"https://api.github.com/users/jirikuncar/events{/privacy}","received_events_url":"https://api.github.com/users/jirikuncar/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jirikuncar/renga-python","description":"Python API and CLI for the Renga platform","fork":true,"url":"https://api.github.com/repos/jirikuncar/renga-python","forks_url":"https://api.github.com/repos/jirikuncar/renga-python/forks","keys_url":"https://api.github.com/repos/jirikuncar/renga-python/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jirikuncar/renga-python/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jirikuncar/renga-python/teams","hooks_url":"https://api.github.com/repos/jirikuncar/renga-python/hooks","issue_events_url":"https://api.github.com/repos/jirikuncar/renga-python/issues/events{/number}","events_url":"https://api.github.com/repos/jirikuncar/renga-python/events","assignees_url":"https://api.github.com/repos/jirikuncar/renga-python/assignees{/user}","branches_url":"https://api.github.com/repos/jirikuncar/renga-python/branches{/branch}","tags_url":"https://api.github.com/repos/jirikuncar/renga-python/tags","blobs_url":"https://api.github.com/repos/jirikuncar/renga-python/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jirikuncar/renga-python/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jirikuncar/renga-python/git/refs{/sha}","trees_url":"https://api.github.com/repos/jirikuncar/renga-python/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jirikuncar/renga-python/statuses/{sha}","languages_url":"https://api.github.com/repos/jirikuncar/renga-python/languages","stargazers_url":"https://api.github.com/repos/jirikuncar/renga-python/stargazers","contributors_url":"https://api.github.com/repos/jirikuncar/renga-python/contributors","subscribers_url":"https://api.github.com/repos/jirikuncar/renga-python/subscribers","subscription_url":"https://api.github.com/repos/jirikuncar/renga-python/subscription","commits_url":"https://api.github.com/repos/jirikuncar/renga-python/commits{/sha}","git_commits_url":"https://api.github.com/repos/jirikuncar/renga-python/git/commits{/sha}","comments_url":"https://api.github.com/repos/jirikuncar/renga-python/comments{/number}","issue_comment_url":"https://api.github.com/repos/jirikuncar/renga-python/issues/comments{/number}","contents_url":"https://api.github.com/repos/jirikuncar/renga-python/contents/{+path}","compare_url":"https://api.github.com/repos/jirikuncar/renga-python/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jirikuncar/renga-python/merges","archive_url":"https://api.github.com/repos/jirikuncar/renga-python/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jirikuncar/renga-python/downloads","issues_url":"https://api.github.com/repos/jirikuncar/renga-python/issues{/number}","pulls_url":"https://api.github.com/repos/jirikuncar/renga-python/pulls{/number}","milestones_url":"https://api.github.com/repos/jirikuncar/renga-python/milestones{/number}","notifications_url":"https://api.github.com/repos/jirikuncar/renga-python/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jirikuncar/renga-python/labels{/name}","releases_url":"https://api.github.com/repos/jirikuncar/renga-python/releases{/id}","deployments_url":"https://api.github.com/repos/jirikuncar/renga-python/deployments","created_at":"2017-09-07T09:30:42Z","updated_at":"2017-09-07T09:30:43Z","pushed_at":"2018-02-19T21:18:21Z","git_url":"git://github.com/jirikuncar/renga-python.git","ssh_url":"git@github.com:jirikuncar/renga-python.git","clone_url":"https://github.com/jirikuncar/renga-python.git","svn_url":"https://github.com/jirikuncar/renga-python","homepage":null,"size":517,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":null,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"SwissDataScienceCenter:development","ref":"development","sha":"d8b45cab15abe8669b713f7fa8b980b00873ef35","user":{"login":"SwissDataScienceCenter","id":25008760,"avatar_url":"https://avatars3.githubusercontent.com/u/25008760?v=4","gravatar_id":"","url":"https://api.github.com/users/SwissDataScienceCenter","html_url":"https://github.com/SwissDataScienceCenter","followers_url":"https://api.github.com/users/SwissDataScienceCenter/followers","following_url":"https://api.github.com/users/SwissDataScienceCenter/following{/other_user}","gists_url":"https://api.github.com/users/SwissDataScienceCenter/gists{/gist_id}","starred_url":"https://api.github.com/users/SwissDataScienceCenter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SwissDataScienceCenter/subscriptions","organizations_url":"https://api.github.com/users/SwissDataScienceCenter/orgs","repos_url":"https://api.github.com/users/SwissDataScienceCenter/repos","events_url":"https://api.github.com/users/SwissDataScienceCenter/events{/privacy}","received_events_url":"https://api.github.com/users/SwissDataScienceCenter/received_events","type":"Organization","site_admin":false},"repo":{"id":100947017,"name":"renga-python","full_name":"SwissDataScienceCenter/renga-python","owner":{"login":"SwissDataScienceCenter","id":25008760,"avatar_url":"https://avatars3.githubusercontent.com/u/25008760?v=4","gravatar_id":"","url":"https://api.github.com/users/SwissDataScienceCenter","html_url":"https://github.com/SwissDataScienceCenter","followers_url":"https://api.github.com/users/SwissDataScienceCenter/followers","following_url":"https://api.github.com/users/SwissDataScienceCenter/following{/other_user}","gists_url":"https://api.github.com/users/SwissDataScienceCenter/gists{/gist_id}","starred_url":"https://api.github.com/users/SwissDataScienceCenter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SwissDataScienceCenter/subscriptions","organizations_url":"https://api.github.com/users/SwissDataScienceCenter/orgs","repos_url":"https://api.github.com/users/SwissDataScienceCenter/repos","events_url":"https://api.github.com/users/SwissDataScienceCenter/events{/privacy}","received_events_url":"https://api.github.com/users/SwissDataScienceCenter/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/SwissDataScienceCenter/renga-python","description":"A Python library for the Renga collaborative data science platform. It lets you perform any action with renga command or from withing Python apps - create projects, manage buckets, track files, run containers, etc.","fork":false,"url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python","forks_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/forks","keys_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/keys{/key_id}","collaborators_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/teams","hooks_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/hooks","issue_events_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/issues/events{/number}","events_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/events","assignees_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/assignees{/user}","branches_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/branches{/branch}","tags_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/tags","blobs_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/git/refs{/sha}","trees_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/git/trees{/sha}","statuses_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/statuses/{sha}","languages_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/languages","stargazers_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/stargazers","contributors_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/contributors","subscribers_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/subscribers","subscription_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/subscription","commits_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/commits{/sha}","git_commits_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/git/commits{/sha}","comments_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/comments{/number}","issue_comment_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/issues/comments{/number}","contents_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/contents/{+path}","compare_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/compare/{base}...{head}","merges_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/merges","archive_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/downloads","issues_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/issues{/number}","pulls_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/pulls{/number}","milestones_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/milestones{/number}","notifications_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/labels{/name}","releases_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/releases{/id}","deployments_url":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/deployments","created_at":"2017-08-21T11:49:21Z","updated_at":"2017-12-07T15:54:06Z","pushed_at":"2018-02-19T23:25:43Z","git_url":"git://github.com/SwissDataScienceCenter/renga-python.git","ssh_url":"git@github.com:SwissDataScienceCenter/renga-python.git","clone_url":"https://github.com/SwissDataScienceCenter/renga-python.git","svn_url":"https://github.com/SwissDataScienceCenter/renga-python","homepage":"https://renga-python.readthedocs.io/","size":516,"stargazers_count":2,"watchers_count":2,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":2,"mirror_url":null,"archived":false,"open_issues_count":10,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"forks":2,"open_issues":10,"watchers":2,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/pulls/111"},"html":{"href":"https://github.com/SwissDataScienceCenter/renga-python/pull/111"},"issue":{"href":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/issues/111"},"comments":{"href":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/issues/111/comments"},"review_comments":{"href":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/pulls/111/comments"},"review_comment":{"href":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/pulls/111/commits"},"statuses":{"href":"https://api.github.com/repos/SwissDataScienceCenter/renga-python/statuses/cc75ab3c34b668563c2a22103558b62465ec3113"}},"author_association":"OWNER"}}
{"actor":{"display_login":"rokroskar"}}