{"action":"created","comment":{"url":"https://api.github.com/repos/haskell-nix/hnix-store/pulls/comments/188160701","pull_request_review_id":120081172,"id":188160701,"diff_hunk":"@@ -0,0 +1,261 @@\n+{-# LANGUAGE FlexibleContexts    #-}\n+{-# LANGUAGE KindSignatures      #-}\n+{-# LANGUAGE OverloadedStrings   #-}\n+{-# LANGUAGE ScopedTypeVariables #-}\n+{-# LANGUAGE TupleSections       #-}\n+{-# LANGUAGE TypeApplications    #-}\n+\n+{-|\n+Description : Allowed effects for interacting with Nar files.\n+Maintainer  : Shea Levy <shea@shealevy.com>\n+|-}\n+module System.Nix.Nar (\n+    FileSystemObject(..)\n+  , IsExecutable (..)\n+  , Nar(..)\n+  , getNar\n+  , localPackNar\n+  , localUnpackNar\n+  , narEffectsIO\n+  , putNar\n+  ) where\n+\n+import           Control.Applicative\n+import           Control.Monad              (replicateM, replicateM_, (<=<))\n+import qualified Data.Binary                as B\n+import qualified Data.Binary.Get            as B\n+import qualified Data.Binary.Put            as B\n+import           Data.Bool                  (bool)\n+import qualified Data.ByteString.Lazy       as BSL\n+import           Data.Foldable              (forM_)\n+import qualified Data.Map                   as Map\n+import           Data.Maybe                 (fromMaybe)\n+import           Data.Monoid                ((<>))\n+import qualified Data.Text                  as T\n+import qualified Data.Text.Encoding         as E\n+import           Data.Traversable           (forM)\n+import           GHC.Int                    (Int64)\n+import           System.Directory\n+import           System.FilePath\n+import           System.Posix.Files         (createSymbolicLink, fileSize, getFileStatus,\n+                                             isDirectory, readSymbolicLink)\n+\n+import           System.Nix.Path\n+\n+data NarEffects (m :: * -> *) = NarEffects {\n+    narReadFile   :: FilePath -> m BSL.ByteString\n+  , narWriteFile  :: FilePath -> BSL.ByteString -> m ()\n+  , narListDir    :: FilePath -> m [FilePath]\n+  , narCreateDir  :: FilePath -> m ()\n+  , narCreateLink :: FilePath -> FilePath -> m ()\n+  , narGetPerms   :: FilePath -> m Permissions\n+  , narSetPerms   :: FilePath -> Permissions ->  m ()\n+  , narIsDir      :: FilePath -> m Bool\n+  , narIsSymLink  :: FilePath -> m Bool\n+  , narFileSize   :: FilePath -> m Int64\n+  , narReadLink   :: FilePath -> m FilePath\n+}\n+\n+\n+-- Directly taken from Eelco thesis\n+-- https://nixos.org/%7Eeelco/pubs/phd-thesis.pdf\n+\n+data Nar = Nar { narFile :: FileSystemObject }\n+    deriving (Eq, Show)\n+\n+data FileSystemObject =\n+    Regular IsExecutable Int64 BSL.ByteString\n+  | Directory (Map.Map FilePathPart FileSystemObject)\n+  | SymLink T.Text\n+  deriving (Eq, Show)\n+\n+\n+data IsExecutable = NonExecutable | Executable\n+    deriving (Eq, Show)\n+\n+\n+instance B.Binary Nar where\n+  get = getNar\n+  put = putNar\n+\n+------------------------------------------------------------------------------\n+-- | Serialize Nar to lazy ByteString\n+putNar :: Nar -> B.Put\n+putNar (Nar file) = header <> parens (putFile file)\n+    where\n+\n+        header   = str \"nix-archive-1\"\n+\n+        putFile (Regular isExec fSize contents) =\n+               strs [\"type\", \"regular\"]\n+            >> (if isExec == Executable\n+               then strs [\"executable\", \"\"]\n+               else return ())\n+            >> putContents fSize contents\n+\n+        putFile (SymLink target) =\n+               strs [\"type\", \"symlink\", \"target\", BSL.fromStrict $ E.encodeUtf8 target]\n+\n+        -- toList sorts the entries by FilePathPart before serializing\n+        putFile (Directory entries) =\n+               strs [\"type\", \"directory\"]\n+            <> mapM_ putEntry (Map.toList entries)\n+\n+        putEntry (FilePathPart name, fso) = do\n+            str \"entry\"\n+            parens $ do\n+              str \"name\"\n+              str (BSL.fromStrict $ E.encodeUtf8 name)\n+              str \"node\"\n+              parens (putFile fso)\n+\n+        parens m = str \"(\" >> m >> str \")\"\n+\n+        -- Do not use this for file contents\n+        str :: BSL.ByteString -> B.Put\n+        str t = let len = BSL.length t\n+            in int len <> pad len t\n+\n+        putContents :: Int64 -> BSL.ByteString -> B.Put\n+        putContents fSize bs = str \"contents\" <> int fSize <> (pad fSize bs)\n+        -- putContents fSize bs = str \"contents\" <> int (BSL.length bs) <> (pad fSize bs)\n+\n+        int :: Integral a => a -> B.Put\n+        int n = B.putInt64le $ fromIntegral n\n+\n+        pad :: Int64 -> BSL.ByteString -> B.Put\n+        pad strSize bs = do\n+          B.putLazyByteString bs\n+          B.putLazyByteString (BSL.replicate (padLen strSize) 0)\n+\n+        strs :: [BSL.ByteString] -> B.Put\n+        strs = mapM_ str\n+\n+\n+------------------------------------------------------------------------------\n+-- | Deserialize a Nar from lazy ByteString\n+getNar :: B.Get Nar\n+getNar = fmap Nar $ header >> parens getFile\n+    where\n+\n+      header   = assertStr \"nix-archive-1\"\n+\n+\n+      -- Fetch a FileSystemObject\n+      getFile = getRegularFile <|> getDirectory <|> getSymLink\n+\n+      getRegularFile = do\n+          assertStr \"type\"\n+          assertStr \"regular\"\n+          mExecutable <- optional $ Executable <$ (assertStr \"executable\"\n+                                                   >> assertStr \"\")\n+          assertStr \"contents\"\n+          (fSize, contents) <- sizedStr\n+          return $ Regular (fromMaybe NonExecutable mExecutable) fSize contents\n+\n+      getDirectory = do\n+          assertStr \"type\"\n+          assertStr \"directory\"\n+          fs <- many getEntry\n+          return $ Directory (Map.fromList fs)\n+\n+      getSymLink = do\n+          assertStr \"type\"\n+          assertStr \"symlink\"\n+          assertStr \"target\"\n+          fmap (SymLink . E.decodeUtf8 . BSL.toStrict) str\n+\n+      getEntry = do\n+          assertStr \"entry\"\n+          parens $ do\n+              assertStr \"name\"\n+              mname <- E.decodeUtf8 . BSL.toStrict <$> str","path":"hnix-store-core/src/System/Nix/Nar.hs","position":null,"original_position":172,"commit_id":"ab1861b0f490b8ec582f980df7ab5035fc4b6109","original_commit_id":"30ea340b810fb9345bb9b9d59e39a5b38c0b0e64","user":{"login":"imalsogreg","id":993484,"avatar_url":"https://avatars3.githubusercontent.com/u/993484?v=4","gravatar_id":"","url":"https://api.github.com/users/imalsogreg","html_url":"https://github.com/imalsogreg","followers_url":"https://api.github.com/users/imalsogreg/followers","following_url":"https://api.github.com/users/imalsogreg/following{/other_user}","gists_url":"https://api.github.com/users/imalsogreg/gists{/gist_id}","starred_url":"https://api.github.com/users/imalsogreg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/imalsogreg/subscriptions","organizations_url":"https://api.github.com/users/imalsogreg/orgs","repos_url":"https://api.github.com/users/imalsogreg/repos","events_url":"https://api.github.com/users/imalsogreg/events{/privacy}","received_events_url":"https://api.github.com/users/imalsogreg/received_events","type":"User","site_admin":false},"body":"Used to be a `Maybe`. Fixed name no reflect pureness.","created_at":"2018-05-15T04:08:58Z","updated_at":"2018-05-15T04:08:59Z","html_url":"https://github.com/haskell-nix/hnix-store/pull/7#discussion_r188160701","pull_request_url":"https://api.github.com/repos/haskell-nix/hnix-store/pulls/7","author_association":"COLLABORATOR","_links":{"self":{"href":"https://api.github.com/repos/haskell-nix/hnix-store/pulls/comments/188160701"},"html":{"href":"https://github.com/haskell-nix/hnix-store/pull/7#discussion_r188160701"},"pull_request":{"href":"https://api.github.com/repos/haskell-nix/hnix-store/pulls/7"}},"in_reply_to_id":187822451},"pull_request":{"url":"https://api.github.com/repos/haskell-nix/hnix-store/pulls/7","id":184920002,"html_url":"https://github.com/haskell-nix/hnix-store/pull/7","diff_url":"https://github.com/haskell-nix/hnix-store/pull/7.diff","patch_url":"https://github.com/haskell-nix/hnix-store/pull/7.patch","issue_url":"https://api.github.com/repos/haskell-nix/hnix-store/issues/7","number":7,"state":"open","locked":false,"title":"NAR parser/generator","user":{"login":"imalsogreg","id":993484,"avatar_url":"https://avatars3.githubusercontent.com/u/993484?v=4","gravatar_id":"","url":"https://api.github.com/users/imalsogreg","html_url":"https://github.com/imalsogreg","followers_url":"https://api.github.com/users/imalsogreg/followers","following_url":"https://api.github.com/users/imalsogreg/following{/other_user}","gists_url":"https://api.github.com/users/imalsogreg/gists{/gist_id}","starred_url":"https://api.github.com/users/imalsogreg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/imalsogreg/subscriptions","organizations_url":"https://api.github.com/users/imalsogreg/orgs","repos_url":"https://api.github.com/users/imalsogreg/repos","events_url":"https://api.github.com/users/imalsogreg/events{/privacy}","received_events_url":"https://api.github.com/users/imalsogreg/received_events","type":"User","site_admin":false},"body":"NAR parser and generator. Moved `Path` types and functions into `Paths.hs` module.\r\n\r\n### Todo\r\n - [x] cleanup\r\n - [x] test the generator manually\r\n - [x] create tests (parse . gen === id)\r\n - [x] finish the `binary` instance\r\n - [x] test encoding/decoding for large NARs (tried 10 and 12 Mb - found problems at 12)\r\n   - can we stream in constant space? (moved to its own ticket)\r\n   - what do we do with NARs beyond using them as intermediate form between download and unpack for computing store path hash? Provide API for doing these things (moved to its own ticket)\r\n - [x] factor IO out of `localUnpackNar` - use `NarEffects` monad instead\r\n - [x] Write an IO instance for `NarEffects`\r\n\r\n### Testing Done\r\n\r\nOur encoder and decoder, filesystem packer and filesystem unpacker are all checked against each other and against the output of `nix-store --dump`.\r\n\r\nSome of our tests use generated files about 8MB in size, and a realistic directory (the `src` directory of this project) for head-to-head comparisons with `nix-store --dump`.\r\n\r\n```\r\n*NarFormat Main> main\r\ntests/Driver.hs\r\n  narEncoding\r\n    parser-roundtrip\r\n      roundtrips regular:    OK\r\n      roundtrips regular 2:  OK\r\n      roundtrips executable: OK\r\n      roundtrips symlink:    OK\r\n      roundtrips directory:  OK\r\n    matches-nix-store fixture\r\n      matches regular:       OK\r\n      matches regular':      OK\r\n      matches executable:    OK\r\n      matches symlink:       OK\r\n      matches directory:     OK\r\n  nixStoreRegular:           OK (0.03s)\r\n  nixStoreDirectory:         OK (0.03s)\r\n  nixStoreDirectory':        OK (0.03s)\r\n  nixStoreBigFile:           OK (0.15s)\r\n  nixStoreBigDir:            OK (0.34s)\r\n  narEncodingArbitrary:      OK (0.18s)\r\n    +++ OK, passed 100 tests.\r\n  packSelfSrcDir:            OK (0.03s)\r\n\r\nAll 17 tests passed (0.80s)\r\n```\r\n","created_at":"2018-04-30T10:10:57Z","updated_at":"2018-05-15T04:08:59Z","closed_at":null,"merged_at":null,"merge_commit_sha":"ca8e100ba4a7876fa75d67ca1fdae69a819748c1","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/haskell-nix/hnix-store/pulls/7/commits","review_comments_url":"https://api.github.com/repos/haskell-nix/hnix-store/pulls/7/comments","review_comment_url":"https://api.github.com/repos/haskell-nix/hnix-store/pulls/comments{/number}","comments_url":"https://api.github.com/repos/haskell-nix/hnix-store/issues/7/comments","statuses_url":"https://api.github.com/repos/haskell-nix/hnix-store/statuses/ab1861b0f490b8ec582f980df7ab5035fc4b6109","head":{"label":"imalsogreg:master","ref":"master","sha":"ab1861b0f490b8ec582f980df7ab5035fc4b6109","user":{"login":"imalsogreg","id":993484,"avatar_url":"https://avatars3.githubusercontent.com/u/993484?v=4","gravatar_id":"","url":"https://api.github.com/users/imalsogreg","html_url":"https://github.com/imalsogreg","followers_url":"https://api.github.com/users/imalsogreg/followers","following_url":"https://api.github.com/users/imalsogreg/following{/other_user}","gists_url":"https://api.github.com/users/imalsogreg/gists{/gist_id}","starred_url":"https://api.github.com/users/imalsogreg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/imalsogreg/subscriptions","organizations_url":"https://api.github.com/users/imalsogreg/orgs","repos_url":"https://api.github.com/users/imalsogreg/repos","events_url":"https://api.github.com/users/imalsogreg/events{/privacy}","received_events_url":"https://api.github.com/users/imalsogreg/received_events","type":"User","site_admin":false},"repo":{"id":131580487,"name":"hnix-store","full_name":"imalsogreg/hnix-store","owner":{"login":"imalsogreg","id":993484,"avatar_url":"https://avatars3.githubusercontent.com/u/993484?v=4","gravatar_id":"","url":"https://api.github.com/users/imalsogreg","html_url":"https://github.com/imalsogreg","followers_url":"https://api.github.com/users/imalsogreg/followers","following_url":"https://api.github.com/users/imalsogreg/following{/other_user}","gists_url":"https://api.github.com/users/imalsogreg/gists{/gist_id}","starred_url":"https://api.github.com/users/imalsogreg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/imalsogreg/subscriptions","organizations_url":"https://api.github.com/users/imalsogreg/orgs","repos_url":"https://api.github.com/users/imalsogreg/repos","events_url":"https://api.github.com/users/imalsogreg/events{/privacy}","received_events_url":"https://api.github.com/users/imalsogreg/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/imalsogreg/hnix-store","description":"Haskell implementation of the nix store API","fork":true,"url":"https://api.github.com/repos/imalsogreg/hnix-store","forks_url":"https://api.github.com/repos/imalsogreg/hnix-store/forks","keys_url":"https://api.github.com/repos/imalsogreg/hnix-store/keys{/key_id}","collaborators_url":"https://api.github.com/repos/imalsogreg/hnix-store/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/imalsogreg/hnix-store/teams","hooks_url":"https://api.github.com/repos/imalsogreg/hnix-store/hooks","issue_events_url":"https://api.github.com/repos/imalsogreg/hnix-store/issues/events{/number}","events_url":"https://api.github.com/repos/imalsogreg/hnix-store/events","assignees_url":"https://api.github.com/repos/imalsogreg/hnix-store/assignees{/user}","branches_url":"https://api.github.com/repos/imalsogreg/hnix-store/branches{/branch}","tags_url":"https://api.github.com/repos/imalsogreg/hnix-store/tags","blobs_url":"https://api.github.com/repos/imalsogreg/hnix-store/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/imalsogreg/hnix-store/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/imalsogreg/hnix-store/git/refs{/sha}","trees_url":"https://api.github.com/repos/imalsogreg/hnix-store/git/trees{/sha}","statuses_url":"https://api.github.com/repos/imalsogreg/hnix-store/statuses/{sha}","languages_url":"https://api.github.com/repos/imalsogreg/hnix-store/languages","stargazers_url":"https://api.github.com/repos/imalsogreg/hnix-store/stargazers","contributors_url":"https://api.github.com/repos/imalsogreg/hnix-store/contributors","subscribers_url":"https://api.github.com/repos/imalsogreg/hnix-store/subscribers","subscription_url":"https://api.github.com/repos/imalsogreg/hnix-store/subscription","commits_url":"https://api.github.com/repos/imalsogreg/hnix-store/commits{/sha}","git_commits_url":"https://api.github.com/repos/imalsogreg/hnix-store/git/commits{/sha}","comments_url":"https://api.github.com/repos/imalsogreg/hnix-store/comments{/number}","issue_comment_url":"https://api.github.com/repos/imalsogreg/hnix-store/issues/comments{/number}","contents_url":"https://api.github.com/repos/imalsogreg/hnix-store/contents/{+path}","compare_url":"https://api.github.com/repos/imalsogreg/hnix-store/compare/{base}...{head}","merges_url":"https://api.github.com/repos/imalsogreg/hnix-store/merges","archive_url":"https://api.github.com/repos/imalsogreg/hnix-store/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/imalsogreg/hnix-store/downloads","issues_url":"https://api.github.com/repos/imalsogreg/hnix-store/issues{/number}","pulls_url":"https://api.github.com/repos/imalsogreg/hnix-store/pulls{/number}","milestones_url":"https://api.github.com/repos/imalsogreg/hnix-store/milestones{/number}","notifications_url":"https://api.github.com/repos/imalsogreg/hnix-store/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/imalsogreg/hnix-store/labels{/name}","releases_url":"https://api.github.com/repos/imalsogreg/hnix-store/releases{/id}","deployments_url":"https://api.github.com/repos/imalsogreg/hnix-store/deployments","created_at":"2018-04-30T10:00:12Z","updated_at":"2018-05-15T04:08:39Z","pushed_at":"2018-05-15T04:08:38Z","git_url":"git://github.com/imalsogreg/hnix-store.git","ssh_url":"git@github.com:imalsogreg/hnix-store.git","clone_url":"https://github.com/imalsogreg/hnix-store.git","svn_url":"https://github.com/imalsogreg/hnix-store","homepage":null,"size":79,"stargazers_count":0,"watchers_count":0,"language":"Haskell","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"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":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"haskell-nix:master","ref":"master","sha":"da0f19a65f1aeca72ac3ac1b3ad9cb52874a354f","user":{"login":"haskell-nix","id":38674962,"avatar_url":"https://avatars3.githubusercontent.com/u/38674962?v=4","gravatar_id":"","url":"https://api.github.com/users/haskell-nix","html_url":"https://github.com/haskell-nix","followers_url":"https://api.github.com/users/haskell-nix/followers","following_url":"https://api.github.com/users/haskell-nix/following{/other_user}","gists_url":"https://api.github.com/users/haskell-nix/gists{/gist_id}","starred_url":"https://api.github.com/users/haskell-nix/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/haskell-nix/subscriptions","organizations_url":"https://api.github.com/users/haskell-nix/orgs","repos_url":"https://api.github.com/users/haskell-nix/repos","events_url":"https://api.github.com/users/haskell-nix/events{/privacy}","received_events_url":"https://api.github.com/users/haskell-nix/received_events","type":"Organization","site_admin":false},"repo":{"id":21681581,"name":"hnix-store","full_name":"haskell-nix/hnix-store","owner":{"login":"haskell-nix","id":38674962,"avatar_url":"https://avatars3.githubusercontent.com/u/38674962?v=4","gravatar_id":"","url":"https://api.github.com/users/haskell-nix","html_url":"https://github.com/haskell-nix","followers_url":"https://api.github.com/users/haskell-nix/followers","following_url":"https://api.github.com/users/haskell-nix/following{/other_user}","gists_url":"https://api.github.com/users/haskell-nix/gists{/gist_id}","starred_url":"https://api.github.com/users/haskell-nix/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/haskell-nix/subscriptions","organizations_url":"https://api.github.com/users/haskell-nix/orgs","repos_url":"https://api.github.com/users/haskell-nix/repos","events_url":"https://api.github.com/users/haskell-nix/events{/privacy}","received_events_url":"https://api.github.com/users/haskell-nix/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/haskell-nix/hnix-store","description":"Haskell implementation of the nix store API","fork":false,"url":"https://api.github.com/repos/haskell-nix/hnix-store","forks_url":"https://api.github.com/repos/haskell-nix/hnix-store/forks","keys_url":"https://api.github.com/repos/haskell-nix/hnix-store/keys{/key_id}","collaborators_url":"https://api.github.com/repos/haskell-nix/hnix-store/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/haskell-nix/hnix-store/teams","hooks_url":"https://api.github.com/repos/haskell-nix/hnix-store/hooks","issue_events_url":"https://api.github.com/repos/haskell-nix/hnix-store/issues/events{/number}","events_url":"https://api.github.com/repos/haskell-nix/hnix-store/events","assignees_url":"https://api.github.com/repos/haskell-nix/hnix-store/assignees{/user}","branches_url":"https://api.github.com/repos/haskell-nix/hnix-store/branches{/branch}","tags_url":"https://api.github.com/repos/haskell-nix/hnix-store/tags","blobs_url":"https://api.github.com/repos/haskell-nix/hnix-store/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/haskell-nix/hnix-store/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/haskell-nix/hnix-store/git/refs{/sha}","trees_url":"https://api.github.com/repos/haskell-nix/hnix-store/git/trees{/sha}","statuses_url":"https://api.github.com/repos/haskell-nix/hnix-store/statuses/{sha}","languages_url":"https://api.github.com/repos/haskell-nix/hnix-store/languages","stargazers_url":"https://api.github.com/repos/haskell-nix/hnix-store/stargazers","contributors_url":"https://api.github.com/repos/haskell-nix/hnix-store/contributors","subscribers_url":"https://api.github.com/repos/haskell-nix/hnix-store/subscribers","subscription_url":"https://api.github.com/repos/haskell-nix/hnix-store/subscription","commits_url":"https://api.github.com/repos/haskell-nix/hnix-store/commits{/sha}","git_commits_url":"https://api.github.com/repos/haskell-nix/hnix-store/git/commits{/sha}","comments_url":"https://api.github.com/repos/haskell-nix/hnix-store/comments{/number}","issue_comment_url":"https://api.github.com/repos/haskell-nix/hnix-store/issues/comments{/number}","contents_url":"https://api.github.com/repos/haskell-nix/hnix-store/contents/{+path}","compare_url":"https://api.github.com/repos/haskell-nix/hnix-store/compare/{base}...{head}","merges_url":"https://api.github.com/repos/haskell-nix/hnix-store/merges","archive_url":"https://api.github.com/repos/haskell-nix/hnix-store/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/haskell-nix/hnix-store/downloads","issues_url":"https://api.github.com/repos/haskell-nix/hnix-store/issues{/number}","pulls_url":"https://api.github.com/repos/haskell-nix/hnix-store/pulls{/number}","milestones_url":"https://api.github.com/repos/haskell-nix/hnix-store/milestones{/number}","notifications_url":"https://api.github.com/repos/haskell-nix/hnix-store/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/haskell-nix/hnix-store/labels{/name}","releases_url":"https://api.github.com/repos/haskell-nix/hnix-store/releases{/id}","deployments_url":"https://api.github.com/repos/haskell-nix/hnix-store/deployments","created_at":"2014-07-10T05:59:13Z","updated_at":"2018-05-14T02:09:19Z","pushed_at":"2018-05-15T04:08:39Z","git_url":"git://github.com/haskell-nix/hnix-store.git","ssh_url":"git@github.com:haskell-nix/hnix-store.git","clone_url":"https://github.com/haskell-nix/hnix-store.git","svn_url":"https://github.com/haskell-nix/hnix-store","homepage":null,"size":81,"stargazers_count":17,"watchers_count":17,"language":"Haskell","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":3,"mirror_url":null,"archived":false,"open_issues_count":4,"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":3,"open_issues":4,"watchers":17,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/haskell-nix/hnix-store/pulls/7"},"html":{"href":"https://github.com/haskell-nix/hnix-store/pull/7"},"issue":{"href":"https://api.github.com/repos/haskell-nix/hnix-store/issues/7"},"comments":{"href":"https://api.github.com/repos/haskell-nix/hnix-store/issues/7/comments"},"review_comments":{"href":"https://api.github.com/repos/haskell-nix/hnix-store/pulls/7/comments"},"review_comment":{"href":"https://api.github.com/repos/haskell-nix/hnix-store/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/haskell-nix/hnix-store/pulls/7/commits"},"statuses":{"href":"https://api.github.com/repos/haskell-nix/hnix-store/statuses/ab1861b0f490b8ec582f980df7ab5035fc4b6109"}},"author_association":"COLLABORATOR"}}
{"actor":{"display_login":"imalsogreg"}}