{"action":"created","comment":{"url":"https://api.github.com/repos/src-d/siva-java/pulls/comments/134397950","pull_request_review_id":57435695,"id":134397950,"diff_hunk":"@@ -0,0 +1,135 @@\n+package tech.sourced.siva;\n+\n+import org.apache.commons.io.IOUtils;\n+\n+import java.io.Closeable;\n+import java.io.File;\n+import java.io.FileNotFoundException;\n+import java.io.FileOutputStream;\n+import java.io.IOException;\n+import java.io.InputStream;\n+import java.io.OutputStream;\n+import java.nio.file.Files;\n+import java.nio.file.Paths;\n+import java.nio.file.attribute.PosixFilePermission;\n+import java.util.List;\n+import java.util.Set;\n+import java.util.zip.CRC32;\n+\n+/**\n+ * This is a high-level API for extracting bare git repository\n+ * (content of .git) from a given .siva file.\n+ * <p>\n+ * Actual reading is done by SivaReader\n+ *\n+ * @see SivaReader#getEntry(IndexEntry)\n+ */\n+public class SivaUnpacker {\n+    private SivaReader reader;\n+    private Boolean ignorePerms = true;\n+\n+    public SivaUnpacker(SivaReader reader) {\n+        this.reader = reader;\n+    }\n+\n+    public SivaUnpacker(SivaReader reader, Boolean ignorePermissions) {\n+        this(reader);\n+        this.ignorePerms = ignorePermissions;\n+    }\n+\n+    public SivaUnpacker(String sivaFilePath) throws SivaException {\n+        try {\n+            this.reader = new SivaReader(new File(sivaFilePath));\n+        } catch (FileNotFoundException e) {\n+            throw new SivaException(\"Could not read \" + sivaFilePath, e);\n+        }\n+    }\n+\n+    public SivaUnpacker(String sivaFilePath, Boolean ignorePermissions) throws SivaException {\n+        this(sivaFilePath);\n+        this.ignorePerms = ignorePermissions;\n+    }\n+\n+    public void unpack(String dstDir) throws SivaException {\n+        File dst = new File(dstDir);\n+        if (!dst.exists()) {\n+            System.out.println(\"Directory \" + dstDir + \" does not exist, creating \" + dst.getAbsolutePath());\n+            if (!dst.mkdirs()) {\n+                throw new SivaException(\"Failed to created a directory: \" + dst.getAbsolutePath());\n+            }\n+        }\n+\n+        List<IndexEntry> entries = this.reader.getIndex().getFilteredIndex().getEntries();\n+        for (IndexEntry entry : entries) {\n+            this.extractEntry(entry, dstDir);\n+        }\n+        this.reader.close();\n+    }\n+\n+    private void extractEntry(IndexEntry entry, String dstDir) throws SivaException {\n+        this.extractEntry(entry, dstDir, null);\n+    }\n+\n+    private void extractEntry(IndexEntry entry, String dstDir, CRC32 crc32) throws SivaException {\n+        File dstFile = Paths.get(dstDir, entry.getName()).toAbsolutePath().toFile();\n+\n+        InputStream src = this.reader.getEntry(entry);\n+        OutputStream dst = null;\n+        try {\n+            dst = createFileFor(dstFile);\n+            IOUtils.copy(src, dst);\n+\n+            if (!this.ignorePerms) {\n+                Set<PosixFilePermission> perms = entry.getFileMode();\n+                Files.setPosixFilePermissions(dstFile.toPath(), perms);\n+            }\n+        } catch (FileNotFoundException e) {\n+            System.out.println(\"Failed to create \" + entry.getName() + \" in \" + dstDir);","path":"src/main/java/tech/sourced/siva/SivaUnpacker.java","position":87,"original_position":87,"commit_id":"f65d3077eae872978bc1520fcd066477b2c9bd82","original_commit_id":"f65d3077eae872978bc1520fcd066477b2c9bd82","user":{"login":"ajnavarro","id":1196465,"avatar_url":"https://avatars3.githubusercontent.com/u/1196465?v=4","gravatar_id":"","url":"https://api.github.com/users/ajnavarro","html_url":"https://github.com/ajnavarro","followers_url":"https://api.github.com/users/ajnavarro/followers","following_url":"https://api.github.com/users/ajnavarro/following{/other_user}","gists_url":"https://api.github.com/users/ajnavarro/gists{/gist_id}","starred_url":"https://api.github.com/users/ajnavarro/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ajnavarro/subscriptions","organizations_url":"https://api.github.com/users/ajnavarro/orgs","repos_url":"https://api.github.com/users/ajnavarro/repos","events_url":"https://api.github.com/users/ajnavarro/events{/privacy}","received_events_url":"https://api.github.com/users/ajnavarro/received_events","type":"User","site_admin":false},"body":"just return the Exception. Do not use Stdout.","created_at":"2017-08-22T06:57:01Z","updated_at":"2017-08-22T06:59:16Z","html_url":"https://github.com/src-d/siva-java/pull/3#discussion_r134397950","pull_request_url":"https://api.github.com/repos/src-d/siva-java/pulls/3","_links":{"self":{"href":"https://api.github.com/repos/src-d/siva-java/pulls/comments/134397950"},"html":{"href":"https://github.com/src-d/siva-java/pull/3#discussion_r134397950"},"pull_request":{"href":"https://api.github.com/repos/src-d/siva-java/pulls/3"}}},"pull_request":{"url":"https://api.github.com/repos/src-d/siva-java/pulls/3","id":135122650,"html_url":"https://github.com/src-d/siva-java/pull/3","diff_url":"https://github.com/src-d/siva-java/pull/3.diff","patch_url":"https://github.com/src-d/siva-java/pull/3.patch","issue_url":"https://api.github.com/repos/src-d/siva-java/issues/3","number":3,"state":"open","locked":false,"title":"Java unpacker implementation","user":{"login":"bzz","id":5582506,"avatar_url":"https://avatars3.githubusercontent.com/u/5582506?v=4","gravatar_id":"","url":"https://api.github.com/users/bzz","html_url":"https://github.com/bzz","followers_url":"https://api.github.com/users/bzz/followers","following_url":"https://api.github.com/users/bzz/following{/other_user}","gists_url":"https://api.github.com/users/bzz/gists{/gist_id}","starred_url":"https://api.github.com/users/bzz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bzz/subscriptions","organizations_url":"https://api.github.com/users/bzz/orgs","repos_url":"https://api.github.com/users/bzz/repos","events_url":"https://api.github.com/users/bzz/events{/privacy}","received_events_url":"https://api.github.com/users/bzz/received_events","type":"User","site_admin":false},"body":"`./siva-unpack` is analog to `siva unpack`\r\n\r\n - [x] `SivaUnpacker` API\r\n - [x] `./siva-unpack`\r\n - [x] apply file permissions\r\n","created_at":"2017-08-10T13:20:31Z","updated_at":"2017-08-22T06:59:16Z","closed_at":null,"merged_at":null,"merge_commit_sha":"5ce103d3feb88faac37689e5edc2aaaf4b1c7a88","assignee":null,"assignees":[],"requested_reviewers":[],"milestone":null,"commits_url":"https://api.github.com/repos/src-d/siva-java/pulls/3/commits","review_comments_url":"https://api.github.com/repos/src-d/siva-java/pulls/3/comments","review_comment_url":"https://api.github.com/repos/src-d/siva-java/pulls/comments{/number}","comments_url":"https://api.github.com/repos/src-d/siva-java/issues/3/comments","statuses_url":"https://api.github.com/repos/src-d/siva-java/statuses/f65d3077eae872978bc1520fcd066477b2c9bd82","head":{"label":"bzz:feature/siva-unpacker","ref":"feature/siva-unpacker","sha":"f65d3077eae872978bc1520fcd066477b2c9bd82","user":{"login":"bzz","id":5582506,"avatar_url":"https://avatars3.githubusercontent.com/u/5582506?v=4","gravatar_id":"","url":"https://api.github.com/users/bzz","html_url":"https://github.com/bzz","followers_url":"https://api.github.com/users/bzz/followers","following_url":"https://api.github.com/users/bzz/following{/other_user}","gists_url":"https://api.github.com/users/bzz/gists{/gist_id}","starred_url":"https://api.github.com/users/bzz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bzz/subscriptions","organizations_url":"https://api.github.com/users/bzz/orgs","repos_url":"https://api.github.com/users/bzz/repos","events_url":"https://api.github.com/users/bzz/events{/privacy}","received_events_url":"https://api.github.com/users/bzz/received_events","type":"User","site_admin":false},"repo":{"id":99919152,"name":"siva-java","full_name":"bzz/siva-java","owner":{"login":"bzz","id":5582506,"avatar_url":"https://avatars3.githubusercontent.com/u/5582506?v=4","gravatar_id":"","url":"https://api.github.com/users/bzz","html_url":"https://github.com/bzz","followers_url":"https://api.github.com/users/bzz/followers","following_url":"https://api.github.com/users/bzz/following{/other_user}","gists_url":"https://api.github.com/users/bzz/gists{/gist_id}","starred_url":"https://api.github.com/users/bzz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bzz/subscriptions","organizations_url":"https://api.github.com/users/bzz/orgs","repos_url":"https://api.github.com/users/bzz/repos","events_url":"https://api.github.com/users/bzz/events{/privacy}","received_events_url":"https://api.github.com/users/bzz/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/bzz/siva-java","description":"siva format implemented in Java","fork":true,"url":"https://api.github.com/repos/bzz/siva-java","forks_url":"https://api.github.com/repos/bzz/siva-java/forks","keys_url":"https://api.github.com/repos/bzz/siva-java/keys{/key_id}","collaborators_url":"https://api.github.com/repos/bzz/siva-java/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/bzz/siva-java/teams","hooks_url":"https://api.github.com/repos/bzz/siva-java/hooks","issue_events_url":"https://api.github.com/repos/bzz/siva-java/issues/events{/number}","events_url":"https://api.github.com/repos/bzz/siva-java/events","assignees_url":"https://api.github.com/repos/bzz/siva-java/assignees{/user}","branches_url":"https://api.github.com/repos/bzz/siva-java/branches{/branch}","tags_url":"https://api.github.com/repos/bzz/siva-java/tags","blobs_url":"https://api.github.com/repos/bzz/siva-java/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/bzz/siva-java/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/bzz/siva-java/git/refs{/sha}","trees_url":"https://api.github.com/repos/bzz/siva-java/git/trees{/sha}","statuses_url":"https://api.github.com/repos/bzz/siva-java/statuses/{sha}","languages_url":"https://api.github.com/repos/bzz/siva-java/languages","stargazers_url":"https://api.github.com/repos/bzz/siva-java/stargazers","contributors_url":"https://api.github.com/repos/bzz/siva-java/contributors","subscribers_url":"https://api.github.com/repos/bzz/siva-java/subscribers","subscription_url":"https://api.github.com/repos/bzz/siva-java/subscription","commits_url":"https://api.github.com/repos/bzz/siva-java/commits{/sha}","git_commits_url":"https://api.github.com/repos/bzz/siva-java/git/commits{/sha}","comments_url":"https://api.github.com/repos/bzz/siva-java/comments{/number}","issue_comment_url":"https://api.github.com/repos/bzz/siva-java/issues/comments{/number}","contents_url":"https://api.github.com/repos/bzz/siva-java/contents/{+path}","compare_url":"https://api.github.com/repos/bzz/siva-java/compare/{base}...{head}","merges_url":"https://api.github.com/repos/bzz/siva-java/merges","archive_url":"https://api.github.com/repos/bzz/siva-java/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/bzz/siva-java/downloads","issues_url":"https://api.github.com/repos/bzz/siva-java/issues{/number}","pulls_url":"https://api.github.com/repos/bzz/siva-java/pulls{/number}","milestones_url":"https://api.github.com/repos/bzz/siva-java/milestones{/number}","notifications_url":"https://api.github.com/repos/bzz/siva-java/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/bzz/siva-java/labels{/name}","releases_url":"https://api.github.com/repos/bzz/siva-java/releases{/id}","deployments_url":"https://api.github.com/repos/bzz/siva-java/deployments","created_at":"2017-08-10T12:11:27Z","updated_at":"2017-08-11T08:42:37Z","pushed_at":"2017-08-17T19:12:51Z","git_url":"git://github.com/bzz/siva-java.git","ssh_url":"git@github.com:bzz/siva-java.git","clone_url":"https://github.com/bzz/siva-java.git","svn_url":"https://github.com/bzz/siva-java","homepage":"","size":31,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"src-d:master","ref":"master","sha":"d97db40e916666b6da109561dc041eae92de5a93","user":{"login":"src-d","id":15128793,"avatar_url":"https://avatars2.githubusercontent.com/u/15128793?v=4","gravatar_id":"","url":"https://api.github.com/users/src-d","html_url":"https://github.com/src-d","followers_url":"https://api.github.com/users/src-d/followers","following_url":"https://api.github.com/users/src-d/following{/other_user}","gists_url":"https://api.github.com/users/src-d/gists{/gist_id}","starred_url":"https://api.github.com/users/src-d/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/src-d/subscriptions","organizations_url":"https://api.github.com/users/src-d/orgs","repos_url":"https://api.github.com/users/src-d/repos","events_url":"https://api.github.com/users/src-d/events{/privacy}","received_events_url":"https://api.github.com/users/src-d/received_events","type":"Organization","site_admin":false},"repo":{"id":99225077,"name":"siva-java","full_name":"src-d/siva-java","owner":{"login":"src-d","id":15128793,"avatar_url":"https://avatars2.githubusercontent.com/u/15128793?v=4","gravatar_id":"","url":"https://api.github.com/users/src-d","html_url":"https://github.com/src-d","followers_url":"https://api.github.com/users/src-d/followers","following_url":"https://api.github.com/users/src-d/following{/other_user}","gists_url":"https://api.github.com/users/src-d/gists{/gist_id}","starred_url":"https://api.github.com/users/src-d/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/src-d/subscriptions","organizations_url":"https://api.github.com/users/src-d/orgs","repos_url":"https://api.github.com/users/src-d/repos","events_url":"https://api.github.com/users/src-d/events{/privacy}","received_events_url":"https://api.github.com/users/src-d/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/src-d/siva-java","description":"siva format implemented in Java","fork":false,"url":"https://api.github.com/repos/src-d/siva-java","forks_url":"https://api.github.com/repos/src-d/siva-java/forks","keys_url":"https://api.github.com/repos/src-d/siva-java/keys{/key_id}","collaborators_url":"https://api.github.com/repos/src-d/siva-java/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/src-d/siva-java/teams","hooks_url":"https://api.github.com/repos/src-d/siva-java/hooks","issue_events_url":"https://api.github.com/repos/src-d/siva-java/issues/events{/number}","events_url":"https://api.github.com/repos/src-d/siva-java/events","assignees_url":"https://api.github.com/repos/src-d/siva-java/assignees{/user}","branches_url":"https://api.github.com/repos/src-d/siva-java/branches{/branch}","tags_url":"https://api.github.com/repos/src-d/siva-java/tags","blobs_url":"https://api.github.com/repos/src-d/siva-java/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/src-d/siva-java/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/src-d/siva-java/git/refs{/sha}","trees_url":"https://api.github.com/repos/src-d/siva-java/git/trees{/sha}","statuses_url":"https://api.github.com/repos/src-d/siva-java/statuses/{sha}","languages_url":"https://api.github.com/repos/src-d/siva-java/languages","stargazers_url":"https://api.github.com/repos/src-d/siva-java/stargazers","contributors_url":"https://api.github.com/repos/src-d/siva-java/contributors","subscribers_url":"https://api.github.com/repos/src-d/siva-java/subscribers","subscription_url":"https://api.github.com/repos/src-d/siva-java/subscription","commits_url":"https://api.github.com/repos/src-d/siva-java/commits{/sha}","git_commits_url":"https://api.github.com/repos/src-d/siva-java/git/commits{/sha}","comments_url":"https://api.github.com/repos/src-d/siva-java/comments{/number}","issue_comment_url":"https://api.github.com/repos/src-d/siva-java/issues/comments{/number}","contents_url":"https://api.github.com/repos/src-d/siva-java/contents/{+path}","compare_url":"https://api.github.com/repos/src-d/siva-java/compare/{base}...{head}","merges_url":"https://api.github.com/repos/src-d/siva-java/merges","archive_url":"https://api.github.com/repos/src-d/siva-java/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/src-d/siva-java/downloads","issues_url":"https://api.github.com/repos/src-d/siva-java/issues{/number}","pulls_url":"https://api.github.com/repos/src-d/siva-java/pulls{/number}","milestones_url":"https://api.github.com/repos/src-d/siva-java/milestones{/number}","notifications_url":"https://api.github.com/repos/src-d/siva-java/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/src-d/siva-java/labels{/name}","releases_url":"https://api.github.com/repos/src-d/siva-java/releases{/id}","deployments_url":"https://api.github.com/repos/src-d/siva-java/deployments","created_at":"2017-08-03T11:22:43Z","updated_at":"2017-08-11T08:01:23Z","pushed_at":"2017-08-21T08:44:06Z","git_url":"git://github.com/src-d/siva-java.git","ssh_url":"git@github.com:src-d/siva-java.git","clone_url":"https://github.com/src-d/siva-java.git","svn_url":"https://github.com/src-d/siva-java","homepage":"","size":14,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":true,"has_projects":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2,"mirror_url":null,"open_issues_count":3,"forks":2,"open_issues":3,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/src-d/siva-java/pulls/3"},"html":{"href":"https://github.com/src-d/siva-java/pull/3"},"issue":{"href":"https://api.github.com/repos/src-d/siva-java/issues/3"},"comments":{"href":"https://api.github.com/repos/src-d/siva-java/issues/3/comments"},"review_comments":{"href":"https://api.github.com/repos/src-d/siva-java/pulls/3/comments"},"review_comment":{"href":"https://api.github.com/repos/src-d/siva-java/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/src-d/siva-java/pulls/3/commits"},"statuses":{"href":"https://api.github.com/repos/src-d/siva-java/statuses/f65d3077eae872978bc1520fcd066477b2c9bd82"}}}}
{"actor":{"display_login":"ajnavarro"}}