{"action":"created","comment":{"url":"https://api.github.com/repos/pantsbuild/pants/pulls/comments/181956007","pull_request_review_id":112670202,"id":181956007,"diff_hunk":"@@ -0,0 +1,120 @@\n+use bazel_protos;\n+use bytes;\n+use digest::FixedOutput;\n+use hashing;\n+use protobuf::Message;\n+use sha2::{self, Digest};\n+\n+pub struct TestData {\n+  string: String,\n+}\n+\n+impl TestData {\n+  pub fn roland() -> TestData {\n+    TestData::new(\"European Burmese\")\n+  }\n+\n+  pub fn catnip() -> TestData {\n+    TestData::new(\"catnip\")\n+  }\n+\n+  pub fn new(s: &str) -> TestData {\n+    TestData {\n+      string: s.to_owned(),\n+    }\n+  }\n+\n+  pub fn bytes(&self) -> bytes::Bytes {\n+    bytes::Bytes::from(self.string.as_str())\n+  }\n+\n+  pub fn fingerprint(&self) -> hashing::Fingerprint {\n+    hash(&self.bytes())\n+  }\n+\n+  pub fn digest(&self) -> hashing::Digest {\n+    hashing::Digest(self.fingerprint(), self.string.len())\n+  }\n+}\n+\n+pub struct TestDirectory {\n+  directory: bazel_protos::remote_execution::Directory,\n+}\n+\n+impl TestDirectory {\n+  pub fn containing_roland() -> TestDirectory {\n+    let mut directory = bazel_protos::remote_execution::Directory::new();\n+    directory.mut_files().push({\n+      let mut file = bazel_protos::remote_execution::FileNode::new();\n+      file.set_name(\"roland\".to_owned());\n+      file.set_digest((&TestData::roland().digest()).into());\n+      file.set_is_executable(false);\n+      file\n+    });\n+    TestDirectory { directory }\n+  }\n+\n+  pub fn recursive() -> TestDirectory {\n+    let mut directory = bazel_protos::remote_execution::Directory::new();\n+    directory.mut_directories().push({\n+      let mut subdir = bazel_protos::remote_execution::DirectoryNode::new();\n+      subdir.set_name(\"cats\".to_string());\n+      subdir.set_digest((&TestDirectory::containing_roland().digest()).into());\n+      subdir\n+    });\n+    directory.mut_files().push({\n+      let mut file = bazel_protos::remote_execution::FileNode::new();\n+      file.set_name(\"treats\".to_string());\n+      file.set_digest((&TestData::catnip().digest()).into());\n+      file.set_is_executable(false);\n+      file\n+    });\n+    TestDirectory { directory }\n+  }\n+\n+  pub fn with_mixed_executable_files() -> TestDirectory {\n+    let mut directory = bazel_protos::remote_execution::Directory::new();\n+    directory.mut_files().push({\n+      let mut file = bazel_protos::remote_execution::FileNode::new();\n+      file.set_name(\"feed\".to_string());\n+      file.set_digest((&TestData::catnip().digest()).into());\n+      file.set_is_executable(true);\n+      file\n+    });\n+    directory.mut_files().push({\n+      let mut file = bazel_protos::remote_execution::FileNode::new();\n+      file.set_name(\"food\".to_string());\n+      file.set_digest((&TestData::catnip().digest()).into());\n+      file.set_is_executable(false);\n+      file\n+    });\n+    TestDirectory { directory }\n+  }\n+\n+  pub fn directory(&self) -> &bazel_protos::remote_execution::Directory {","path":"src/rust/engine/testutil/src/data.rs","position":94,"original_position":94,"commit_id":"d9187b1d974d646994e1fa4e1f0a4a63c5bd0db4","original_commit_id":"d9187b1d974d646994e1fa4e1f0a4a63c5bd0db4","user":{"login":"dotordogh","id":28027359,"avatar_url":"https://avatars2.githubusercontent.com/u/28027359?v=4","gravatar_id":"","url":"https://api.github.com/users/dotordogh","html_url":"https://github.com/dotordogh","followers_url":"https://api.github.com/users/dotordogh/followers","following_url":"https://api.github.com/users/dotordogh/following{/other_user}","gists_url":"https://api.github.com/users/dotordogh/gists{/gist_id}","starred_url":"https://api.github.com/users/dotordogh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotordogh/subscriptions","organizations_url":"https://api.github.com/users/dotordogh/orgs","repos_url":"https://api.github.com/users/dotordogh/repos","events_url":"https://api.github.com/users/dotordogh/events{/privacy}","received_events_url":"https://api.github.com/users/dotordogh/received_events","type":"User","site_admin":false},"body":"This is all really cool! Thank you for doing it!","created_at":"2018-04-17T05:33:53Z","updated_at":"2018-04-17T05:38:46Z","html_url":"https://github.com/pantsbuild/pants/pull/5705#discussion_r181956007","pull_request_url":"https://api.github.com/repos/pantsbuild/pants/pulls/5705","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/pantsbuild/pants/pulls/comments/181956007"},"html":{"href":"https://github.com/pantsbuild/pants/pull/5705#discussion_r181956007"},"pull_request":{"href":"https://api.github.com/repos/pantsbuild/pants/pulls/5705"}}},"pull_request":{"url":"https://api.github.com/repos/pantsbuild/pants/pulls/5705","id":181798889,"html_url":"https://github.com/pantsbuild/pants/pull/5705","diff_url":"https://github.com/pantsbuild/pants/pull/5705.diff","patch_url":"https://github.com/pantsbuild/pants/pull/5705.patch","issue_url":"https://api.github.com/repos/pantsbuild/pants/issues/5705","number":5705,"state":"open","locked":false,"title":"WIP: brfs: FUSE filesystem exposing the Store and remote CAS","user":{"login":"illicitonion","id":1131704,"avatar_url":"https://avatars0.githubusercontent.com/u/1131704?v=4","gravatar_id":"","url":"https://api.github.com/users/illicitonion","html_url":"https://github.com/illicitonion","followers_url":"https://api.github.com/users/illicitonion/followers","following_url":"https://api.github.com/users/illicitonion/following{/other_user}","gists_url":"https://api.github.com/users/illicitonion/gists{/gist_id}","starred_url":"https://api.github.com/users/illicitonion/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/illicitonion/subscriptions","organizations_url":"https://api.github.com/users/illicitonion/orgs","repos_url":"https://api.github.com/users/illicitonion/repos","events_url":"https://api.github.com/users/illicitonion/events{/privacy}","received_events_url":"https://api.github.com/users/illicitonion/received_events","type":"User","site_admin":false},"body":"NOTE: This has some TODOs in that should definitely be addressed before merging (most significantly, writing a bunch of tests which verify particular syscalls behave as expected), but I figured I'd send out the proof of concept I put together :)\r\n\r\nExposes:\r\n * `${mount_point}/digest` - contains a file named sha256-length for each\r\n   file digest. Does not show anything in response to `readdir`, but\r\n   opening any particular file (of a known digest) will work.\r\n * `${mount_point}/directory` - contains a directory named sha256-length\r\n   for each directory digest. Does not show anything in response to\r\n   `readdir`, but `readdir` on any particular directory (of a known\r\n   digest) will work.\r\n\r\nCaveats:\r\n * Not at all performance optimised. In particular, all filesystem\r\n   operations happen single-threaded, including performing expensive I/O\r\n   operations like fetching from a remote CAS or reading from LMDB.\r\n   The underlying implementation is Futures-based, and the expensive\r\n   operations are easily parallelisable, it just hasn't been done yet :)\r\n\r\nThis uses the low-level https://github.com/zargony/rust-fuse which\r\nrequires manual inode management.\r\n\r\nThere is also a higher-level https://github.com/wfraser/fuse-mt which I\r\ndiscovered after putting this together, but which I'm consciously not\r\nusing. Its benefits would be:\r\n 1. It operates on paths rather than inodes. This would be pretty\r\n    convenient, as the inode cache in this implementation is a little\r\n    annoying.\r\n 2. It runs some operations in parallel by not having every function\r\n    take a &mut self. I haven't looked at how parallel it ends up being.\r\n 3. Its readdir API avoids needing to think about pagination. I ended up\r\n    coincidentally re-inventing their API here :)\r\n\r\nBut its big drawback is that functions are required to return values\r\n(e.g. from read) rather than call callbacks, which means that it's hard\r\nfor us to take advantage of our Futurey implementation in Store, as\r\nwe'd need to block in every call.\r\n\r\nBoth projects have talked about wanting to support Futures as a more\r\nfirst-class concept at some point in a nebulous future, but neither has\r\na concrete plan for doing so.","created_at":"2018-04-16T09:20:16Z","updated_at":"2018-04-17T05:38:46Z","closed_at":null,"merged_at":null,"merge_commit_sha":"54bd84ac2ccb8ed2c13c55e2bacc1bc4e999020f","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/pantsbuild/pants/pulls/5705/commits","review_comments_url":"https://api.github.com/repos/pantsbuild/pants/pulls/5705/comments","review_comment_url":"https://api.github.com/repos/pantsbuild/pants/pulls/comments{/number}","comments_url":"https://api.github.com/repos/pantsbuild/pants/issues/5705/comments","statuses_url":"https://api.github.com/repos/pantsbuild/pants/statuses/d9187b1d974d646994e1fa4e1f0a4a63c5bd0db4","head":{"label":"twitter:dwagnerhall/brfs","ref":"dwagnerhall/brfs","sha":"d9187b1d974d646994e1fa4e1f0a4a63c5bd0db4","user":{"login":"twitter","id":50278,"avatar_url":"https://avatars1.githubusercontent.com/u/50278?v=4","gravatar_id":"","url":"https://api.github.com/users/twitter","html_url":"https://github.com/twitter","followers_url":"https://api.github.com/users/twitter/followers","following_url":"https://api.github.com/users/twitter/following{/other_user}","gists_url":"https://api.github.com/users/twitter/gists{/gist_id}","starred_url":"https://api.github.com/users/twitter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/twitter/subscriptions","organizations_url":"https://api.github.com/users/twitter/orgs","repos_url":"https://api.github.com/users/twitter/repos","events_url":"https://api.github.com/users/twitter/events{/privacy}","received_events_url":"https://api.github.com/users/twitter/received_events","type":"Organization","site_admin":false},"repo":{"id":29317658,"name":"pants","full_name":"twitter/pants","owner":{"login":"twitter","id":50278,"avatar_url":"https://avatars1.githubusercontent.com/u/50278?v=4","gravatar_id":"","url":"https://api.github.com/users/twitter","html_url":"https://github.com/twitter","followers_url":"https://api.github.com/users/twitter/followers","following_url":"https://api.github.com/users/twitter/following{/other_user}","gists_url":"https://api.github.com/users/twitter/gists{/gist_id}","starred_url":"https://api.github.com/users/twitter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/twitter/subscriptions","organizations_url":"https://api.github.com/users/twitter/orgs","repos_url":"https://api.github.com/users/twitter/repos","events_url":"https://api.github.com/users/twitter/events{/privacy}","received_events_url":"https://api.github.com/users/twitter/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/twitter/pants","description":"Pants Build System","fork":true,"url":"https://api.github.com/repos/twitter/pants","forks_url":"https://api.github.com/repos/twitter/pants/forks","keys_url":"https://api.github.com/repos/twitter/pants/keys{/key_id}","collaborators_url":"https://api.github.com/repos/twitter/pants/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/twitter/pants/teams","hooks_url":"https://api.github.com/repos/twitter/pants/hooks","issue_events_url":"https://api.github.com/repos/twitter/pants/issues/events{/number}","events_url":"https://api.github.com/repos/twitter/pants/events","assignees_url":"https://api.github.com/repos/twitter/pants/assignees{/user}","branches_url":"https://api.github.com/repos/twitter/pants/branches{/branch}","tags_url":"https://api.github.com/repos/twitter/pants/tags","blobs_url":"https://api.github.com/repos/twitter/pants/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/twitter/pants/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/twitter/pants/git/refs{/sha}","trees_url":"https://api.github.com/repos/twitter/pants/git/trees{/sha}","statuses_url":"https://api.github.com/repos/twitter/pants/statuses/{sha}","languages_url":"https://api.github.com/repos/twitter/pants/languages","stargazers_url":"https://api.github.com/repos/twitter/pants/stargazers","contributors_url":"https://api.github.com/repos/twitter/pants/contributors","subscribers_url":"https://api.github.com/repos/twitter/pants/subscribers","subscription_url":"https://api.github.com/repos/twitter/pants/subscription","commits_url":"https://api.github.com/repos/twitter/pants/commits{/sha}","git_commits_url":"https://api.github.com/repos/twitter/pants/git/commits{/sha}","comments_url":"https://api.github.com/repos/twitter/pants/comments{/number}","issue_comment_url":"https://api.github.com/repos/twitter/pants/issues/comments{/number}","contents_url":"https://api.github.com/repos/twitter/pants/contents/{+path}","compare_url":"https://api.github.com/repos/twitter/pants/compare/{base}...{head}","merges_url":"https://api.github.com/repos/twitter/pants/merges","archive_url":"https://api.github.com/repos/twitter/pants/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/twitter/pants/downloads","issues_url":"https://api.github.com/repos/twitter/pants/issues{/number}","pulls_url":"https://api.github.com/repos/twitter/pants/pulls{/number}","milestones_url":"https://api.github.com/repos/twitter/pants/milestones{/number}","notifications_url":"https://api.github.com/repos/twitter/pants/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/twitter/pants/labels{/name}","releases_url":"https://api.github.com/repos/twitter/pants/releases{/id}","deployments_url":"https://api.github.com/repos/twitter/pants/deployments","created_at":"2015-01-15T20:51:58Z","updated_at":"2018-04-12T18:49:55Z","pushed_at":"2018-04-16T13:25:58Z","git_url":"git://github.com/twitter/pants.git","ssh_url":"git@github.com:twitter/pants.git","clone_url":"https://github.com/twitter/pants.git","svn_url":"https://github.com/twitter/pants","homepage":"http://pantsbuild.github.io/","size":116168,"stargazers_count":59,"watchers_count":59,"language":"Python","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":19,"mirror_url":null,"archived":false,"open_issues_count":0,"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":19,"open_issues":0,"watchers":59,"default_branch":"master"}},"base":{"label":"pantsbuild:master","ref":"master","sha":"e20b205fa8d065222c03f47b16187a65ddf60efa","user":{"login":"pantsbuild","id":3065172,"avatar_url":"https://avatars0.githubusercontent.com/u/3065172?v=4","gravatar_id":"","url":"https://api.github.com/users/pantsbuild","html_url":"https://github.com/pantsbuild","followers_url":"https://api.github.com/users/pantsbuild/followers","following_url":"https://api.github.com/users/pantsbuild/following{/other_user}","gists_url":"https://api.github.com/users/pantsbuild/gists{/gist_id}","starred_url":"https://api.github.com/users/pantsbuild/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pantsbuild/subscriptions","organizations_url":"https://api.github.com/users/pantsbuild/orgs","repos_url":"https://api.github.com/users/pantsbuild/repos","events_url":"https://api.github.com/users/pantsbuild/events{/privacy}","received_events_url":"https://api.github.com/users/pantsbuild/received_events","type":"Organization","site_admin":false},"repo":{"id":7209075,"name":"pants","full_name":"pantsbuild/pants","owner":{"login":"pantsbuild","id":3065172,"avatar_url":"https://avatars0.githubusercontent.com/u/3065172?v=4","gravatar_id":"","url":"https://api.github.com/users/pantsbuild","html_url":"https://github.com/pantsbuild","followers_url":"https://api.github.com/users/pantsbuild/followers","following_url":"https://api.github.com/users/pantsbuild/following{/other_user}","gists_url":"https://api.github.com/users/pantsbuild/gists{/gist_id}","starred_url":"https://api.github.com/users/pantsbuild/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pantsbuild/subscriptions","organizations_url":"https://api.github.com/users/pantsbuild/orgs","repos_url":"https://api.github.com/users/pantsbuild/repos","events_url":"https://api.github.com/users/pantsbuild/events{/privacy}","received_events_url":"https://api.github.com/users/pantsbuild/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/pantsbuild/pants","description":"The Pants Build System","fork":false,"url":"https://api.github.com/repos/pantsbuild/pants","forks_url":"https://api.github.com/repos/pantsbuild/pants/forks","keys_url":"https://api.github.com/repos/pantsbuild/pants/keys{/key_id}","collaborators_url":"https://api.github.com/repos/pantsbuild/pants/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/pantsbuild/pants/teams","hooks_url":"https://api.github.com/repos/pantsbuild/pants/hooks","issue_events_url":"https://api.github.com/repos/pantsbuild/pants/issues/events{/number}","events_url":"https://api.github.com/repos/pantsbuild/pants/events","assignees_url":"https://api.github.com/repos/pantsbuild/pants/assignees{/user}","branches_url":"https://api.github.com/repos/pantsbuild/pants/branches{/branch}","tags_url":"https://api.github.com/repos/pantsbuild/pants/tags","blobs_url":"https://api.github.com/repos/pantsbuild/pants/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/pantsbuild/pants/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/pantsbuild/pants/git/refs{/sha}","trees_url":"https://api.github.com/repos/pantsbuild/pants/git/trees{/sha}","statuses_url":"https://api.github.com/repos/pantsbuild/pants/statuses/{sha}","languages_url":"https://api.github.com/repos/pantsbuild/pants/languages","stargazers_url":"https://api.github.com/repos/pantsbuild/pants/stargazers","contributors_url":"https://api.github.com/repos/pantsbuild/pants/contributors","subscribers_url":"https://api.github.com/repos/pantsbuild/pants/subscribers","subscription_url":"https://api.github.com/repos/pantsbuild/pants/subscription","commits_url":"https://api.github.com/repos/pantsbuild/pants/commits{/sha}","git_commits_url":"https://api.github.com/repos/pantsbuild/pants/git/commits{/sha}","comments_url":"https://api.github.com/repos/pantsbuild/pants/comments{/number}","issue_comment_url":"https://api.github.com/repos/pantsbuild/pants/issues/comments{/number}","contents_url":"https://api.github.com/repos/pantsbuild/pants/contents/{+path}","compare_url":"https://api.github.com/repos/pantsbuild/pants/compare/{base}...{head}","merges_url":"https://api.github.com/repos/pantsbuild/pants/merges","archive_url":"https://api.github.com/repos/pantsbuild/pants/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/pantsbuild/pants/downloads","issues_url":"https://api.github.com/repos/pantsbuild/pants/issues{/number}","pulls_url":"https://api.github.com/repos/pantsbuild/pants/pulls{/number}","milestones_url":"https://api.github.com/repos/pantsbuild/pants/milestones{/number}","notifications_url":"https://api.github.com/repos/pantsbuild/pants/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/pantsbuild/pants/labels{/name}","releases_url":"https://api.github.com/repos/pantsbuild/pants/releases{/id}","deployments_url":"https://api.github.com/repos/pantsbuild/pants/deployments","created_at":"2012-12-17T17:39:04Z","updated_at":"2018-04-16T17:43:37Z","pushed_at":"2018-04-17T05:27:11Z","git_url":"git://github.com/pantsbuild/pants.git","ssh_url":"git@github.com:pantsbuild/pants.git","clone_url":"https://github.com/pantsbuild/pants.git","svn_url":"https://github.com/pantsbuild/pants","homepage":"http://pantsbuild.org/","size":83425,"stargazers_count":940,"watchers_count":940,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":270,"mirror_url":null,"archived":false,"open_issues_count":614,"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":270,"open_issues":614,"watchers":940,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/pantsbuild/pants/pulls/5705"},"html":{"href":"https://github.com/pantsbuild/pants/pull/5705"},"issue":{"href":"https://api.github.com/repos/pantsbuild/pants/issues/5705"},"comments":{"href":"https://api.github.com/repos/pantsbuild/pants/issues/5705/comments"},"review_comments":{"href":"https://api.github.com/repos/pantsbuild/pants/pulls/5705/comments"},"review_comment":{"href":"https://api.github.com/repos/pantsbuild/pants/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/pantsbuild/pants/pulls/5705/commits"},"statuses":{"href":"https://api.github.com/repos/pantsbuild/pants/statuses/d9187b1d974d646994e1fa4e1f0a4a63c5bd0db4"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"dotordogh"}}