{"action":"created","comment":{"url":"https://api.github.com/repos/jrperritt/rack/pulls/comments/34432833","id":34432833,"diff_hunk":"@@ -0,0 +1,235 @@\n+package objectcommands\n+\n+import (\n+\t\"fmt\"\n+\t\"io\"\n+\t\"os\"\n+\t\"path/filepath\"\n+\t\"runtime\"\n+\t\"strings\"\n+\t\"sync\"\n+\t\"time\"\n+\n+\t\"github.com/jrperritt/rack/handler\"\n+\t\"github.com/jrperritt/rack/internal/github.com/cenkalti/backoff\"\n+\t\"github.com/jrperritt/rack/internal/github.com/codegangsta/cli\"\n+\t\"github.com/jrperritt/rack/internal/github.com/dustin/go-humanize\"\n+\t\"github.com/jrperritt/rack/internal/github.com/rackspace/gophercloud/openstack/objectstorage/v1/objects\"\n+\t\"github.com/jrperritt/rack/util\"\n+)\n+\n+var uploadDir = cli.Command{\n+\tName:        \"upload-dir\",\n+\tUsage:       util.Usage(commandPrefix, \"upload-dir\", \"--container <containerName> --dir <dirName>\"),\n+\tDescription: \"Uploads the contents of a local directory to a container\",\n+\tAction:      actionUploadDir,\n+\tFlags:       util.CommandFlags(flagsUploadDir, keysUploadDir),\n+\tBashComplete: func(c *cli.Context) {\n+\t\tutil.CompleteFlags(util.CommandFlags(flagsUploadDir, keysUploadDir))\n+\t},\n+}\n+\n+func flagsUploadDir() []cli.Flag {\n+\treturn []cli.Flag{\n+\t\tcli.StringFlag{\n+\t\t\tName:  \"container\",\n+\t\t\tUsage: \"[required] The name of the container to upload the object upload\",\n+\t\t},\n+\t\tcli.StringFlag{\n+\t\t\tName:  \"dir\",\n+\t\t\tUsage: \"[required] The name the local directory which will be uploaded\",\n+\t\t},\n+\t\tcli.StringFlag{\n+\t\t\tName:  \"content-type\",\n+\t\t\tUsage: \"[optional] The Content-Type header that will be set on all objects.\",\n+\t\t},\n+\t\tcli.IntFlag{\n+\t\t\tName:  \"content-length\",\n+\t\t\tUsage: \"[optional] The Content-Length header that will be set on all objects.\",\n+\t\t},\n+\t\tcli.StringFlag{\n+\t\t\tName:  \"content-encoding\",\n+\t\t\tUsage: \"[optional] The Content-Encoding header that will be set on all objects. By default, the uploaded content will be gzipped.\",\n+\t\t},\n+\t\tcli.IntFlag{\n+\t\t\tName:  \"concurrency\",\n+\t\t\tUsage: \"[optional] The amount of concurrent workers that will upload the directory.\",\n+\t\t},\n+\t\tcli.BoolFlag{\n+\t\t\tName:  \"quiet\",\n+\t\t\tUsage: \"[optional] By default every file upload will be outputted. If --quiet is provided, only a final summary will be outputted.\",\n+\t\t},\n+\t}\n+}\n+\n+var keysUploadDir = []string{}\n+\n+type paramsUploadDir struct {\n+\tcontainer   string\n+\tdir         string\n+\tstream      io.ReadSeeker\n+\topts        objects.CreateOpts\n+\tconcurrency int\n+\tquiet       bool\n+}\n+\n+type commandUploadDir handler.Command\n+\n+func actionUploadDir(c *cli.Context) {\n+\tcommand := &commandUploadDir{\n+\t\tCtx: &handler.Context{\n+\t\t\tCLIContext: c,\n+\t\t},\n+\t}\n+\thandler.Handle(command)\n+}\n+\n+func (command *commandUploadDir) Context() *handler.Context {\n+\treturn command.Ctx\n+}\n+\n+func (command *commandUploadDir) Keys() []string {\n+\treturn keysUploadDir\n+}\n+\n+func (command *commandUploadDir) ServiceClientType() string {\n+\treturn serviceClientType\n+}\n+\n+func (command *commandUploadDir) HandleFlags(resource *handler.Resource) error {\n+\tif err := command.Ctx.CheckFlagsSet([]string{\"container\", \"dir\"}); err != nil {\n+\t\treturn err\n+\t}\n+\n+\tc := command.Ctx.CLIContext\n+\n+\topts := objects.CreateOpts{\n+\t\tContentLength: int64(c.Int(\"content-length\")),\n+\t\tContentType:   c.String(\"content-type\"),\n+\t}\n+\n+\tif c.IsSet(\"content-encoding\") && c.String(\"content-encoding\") != \"gzip\" {\n+\t\topts.ContentEncoding = c.String(\"content-encoding\")\n+\t}\n+\n+\tconc := c.Int(\"concurrency\")\n+\tif conc <= 0 {\n+\t\tconc = 5\n+\t}\n+\n+\tresource.Params = &paramsUploadDir{\n+\t\tcontainer:   c.String(\"container\"),\n+\t\tdir:         c.String(\"dir\"),\n+\t\topts:        opts,\n+\t\tconcurrency: c.Int(\"concurrency\"),\n+\t\tquiet:       c.Bool(\"quiet\"),\n+\t}\n+\n+\treturn nil\n+}\n+\n+func (command *commandUploadDir) StdinField() string {\n+\treturn \"dir\"\n+}\n+\n+func (command *commandUploadDir) HandlePipe(resource *handler.Resource, item string) error {\n+\tresource.Params.(*paramsUploadDir).dir = item\n+\treturn nil\n+}\n+\n+func (command *commandUploadDir) HandleSingle(resource *handler.Resource) error {\n+\terr := command.Ctx.CheckFlagsSet([]string{\"dir\"})\n+\tif err != nil {\n+\t\treturn err\n+\t}\n+\tresource.Params.(*paramsUploadDir).dir = command.Ctx.CLIContext.String(\"dir\")\n+\treturn nil\n+}\n+\n+func (command *commandUploadDir) Execute(resource *handler.Resource) {\n+\t// bump thread count to number of available CPUs\n+\truntime.GOMAXPROCS(runtime.NumCPU())\n+\n+\tparams := resource.Params.(*paramsUploadDir)\n+\tjobs := make(chan string)\n+\tresults := make(chan *handler.Resource)\n+\n+\tvar wg sync.WaitGroup\n+\tvar totalSize uint64\n+\tstart := time.Now()\n+\n+\tgo func() {\n+\t\tfor r := range results {\n+\t\t\tcommand.Ctx.WaitGroup.Add(1)\n+\t\t\tcommand.Ctx.Results <- r\n+\t\t}\n+\t\tcommand.Ctx.WaitGroup.Wait()\n+\t}()\n+\n+\tfor i := 0; i < params.concurrency; i++ {\n+\t\twg.Add(1)\n+\t\tgo func(totalSize *uint64) {\n+\t\t\tfor p := range jobs {\n+\t\t\t\tvar re *handler.Resource\n+\n+\t\t\t\tticker := backoff.NewTicker(backoff.NewExponentialBackOff())\n+\t\t\t\tfor _ = range ticker.C {\n+\t\t\t\t\tre = command.handle(p, params)\n+\t\t\t\t\tif re.Err != nil {\n+\t\t\t\t\t\tcontinue\n+\t\t\t\t\t}\n+\n+\t\t\t\t\tticker.Stop()\n+\t\t\t\t\tbreak\n+\t\t\t\t}\n+\n+\t\t\t\tfi, err := os.Stat(p)\n+\t\t\t\tif err == nil {\n+\t\t\t\t\t*totalSize += uint64(fi.Size())\n+\t\t\t\t}\n+\n+\t\t\t\tresults <- re\n+\t\t\t}\n+\t\t\twg.Done()\n+\t\t}(&totalSize)\n+\t}\n+\n+\tfilepath.Walk(params.dir, func(path string, info os.FileInfo, err error) error {\n+\t\tif !info.IsDir() {\n+\t\t\tjobs <- path\n+\t\t}\n+\t\treturn nil\n+\t})\n+\tclose(jobs)\n+\n+\twg.Wait()\n+\tclose(results)\n+\n+\tresource.Result = fmt.Sprintf(\"Finished! %s uploaded in %s\\n\", humanize.Bytes(totalSize), humanize.RelTime(start, time.Now(), \"\", \"\"))\n+}\n+\n+func (command *commandUploadDir) handle(p string, params *paramsUploadDir) *handler.Resource {\n+\tre := &handler.Resource{}\n+\n+\tfile, err := os.Open(p)\n+\tdefer file.Close()\n+\n+\tif err != nil {\n+\t\tre.Err = err\n+\t\treturn re\n+\t}\n+\n+\ton := strings.TrimPrefix(p, params.dir+\"/\")\n+\tres := objects.Create(command.Ctx.ServiceClient, params.container, on, file, params.opts)\n+\tre.Err = res.Err\n+\n+\tif res.Err == nil {\n+\t\tif params.quiet == true {\n+\t\t\tre.Result = \"\"\n+\t\t} else {\n+\t\t\tre.Result = fmt.Sprintf(\"Uploaded %s to %s\\n\", on, params.container)","path":"commands/filescommands/objectcommands/uploaddir.go","position":230,"original_position":230,"commit_id":"4746a40ace9797b0555071c146f2d22c34fa204a","original_commit_id":"4746a40ace9797b0555071c146f2d22c34fa204a","user":{"login":"jrperritt","id":1733222,"avatar_url":"https://avatars.githubusercontent.com/u/1733222?v=3","gravatar_id":"","url":"https://api.github.com/users/jrperritt","html_url":"https://github.com/jrperritt","followers_url":"https://api.github.com/users/jrperritt/followers","following_url":"https://api.github.com/users/jrperritt/following{/other_user}","gists_url":"https://api.github.com/users/jrperritt/gists{/gist_id}","starred_url":"https://api.github.com/users/jrperritt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jrperritt/subscriptions","organizations_url":"https://api.github.com/users/jrperritt/orgs","repos_url":"https://api.github.com/users/jrperritt/repos","events_url":"https://api.github.com/users/jrperritt/events{/privacy}","received_events_url":"https://api.github.com/users/jrperritt/received_events","type":"User","site_admin":false},"body":"Good point. Putting it in Gophercloud is a better idea.","created_at":"2015-07-13T04:31:36Z","updated_at":"2015-07-13T04:31:36Z","html_url":"https://github.com/jrperritt/rack/pull/181#discussion_r34432833","pull_request_url":"https://api.github.com/repos/jrperritt/rack/pulls/181","_links":{"self":{"href":"https://api.github.com/repos/jrperritt/rack/pulls/comments/34432833"},"html":{"href":"https://github.com/jrperritt/rack/pull/181#discussion_r34432833"},"pull_request":{"href":"https://api.github.com/repos/jrperritt/rack/pulls/181"}}},"pull_request":{"url":"https://api.github.com/repos/jrperritt/rack/pulls/181","id":39675702,"html_url":"https://github.com/jrperritt/rack/pull/181","diff_url":"https://github.com/jrperritt/rack/pull/181.diff","patch_url":"https://github.com/jrperritt/rack/pull/181.patch","issue_url":"https://api.github.com/repos/jrperritt/rack/issues/181","number":181,"state":"open","locked":false,"title":"Add `upload-dir` command","user":{"login":"jamiehannaford","id":1867202,"avatar_url":"https://avatars.githubusercontent.com/u/1867202?v=3","gravatar_id":"","url":"https://api.github.com/users/jamiehannaford","html_url":"https://github.com/jamiehannaford","followers_url":"https://api.github.com/users/jamiehannaford/followers","following_url":"https://api.github.com/users/jamiehannaford/following{/other_user}","gists_url":"https://api.github.com/users/jamiehannaford/gists{/gist_id}","starred_url":"https://api.github.com/users/jamiehannaford/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jamiehannaford/subscriptions","organizations_url":"https://api.github.com/users/jamiehannaford/orgs","repos_url":"https://api.github.com/users/jamiehannaford/repos","events_url":"https://api.github.com/users/jamiehannaford/events{/privacy}","received_events_url":"https://api.github.com/users/jamiehannaford/received_events","type":"User","site_admin":false},"body":"","created_at":"2015-07-10T11:32:44Z","updated_at":"2015-07-13T04:31:36Z","closed_at":null,"merged_at":null,"merge_commit_sha":"ea47afab34a335ffdbef1f174bb7a2ba56b20c3d","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/jrperritt/rack/pulls/181/commits","review_comments_url":"https://api.github.com/repos/jrperritt/rack/pulls/181/comments","review_comment_url":"https://api.github.com/repos/jrperritt/rack/pulls/comments{/number}","comments_url":"https://api.github.com/repos/jrperritt/rack/issues/181/comments","statuses_url":"https://api.github.com/repos/jrperritt/rack/statuses/4746a40ace9797b0555071c146f2d22c34fa204a","head":{"label":"jamiehannaford:upload-dir","ref":"upload-dir","sha":"4746a40ace9797b0555071c146f2d22c34fa204a","user":{"login":"jamiehannaford","id":1867202,"avatar_url":"https://avatars.githubusercontent.com/u/1867202?v=3","gravatar_id":"","url":"https://api.github.com/users/jamiehannaford","html_url":"https://github.com/jamiehannaford","followers_url":"https://api.github.com/users/jamiehannaford/followers","following_url":"https://api.github.com/users/jamiehannaford/following{/other_user}","gists_url":"https://api.github.com/users/jamiehannaford/gists{/gist_id}","starred_url":"https://api.github.com/users/jamiehannaford/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jamiehannaford/subscriptions","organizations_url":"https://api.github.com/users/jamiehannaford/orgs","repos_url":"https://api.github.com/users/jamiehannaford/repos","events_url":"https://api.github.com/users/jamiehannaford/events{/privacy}","received_events_url":"https://api.github.com/users/jamiehannaford/received_events","type":"User","site_admin":false},"repo":{"id":38739330,"name":"rack","full_name":"jamiehannaford/rack","owner":{"login":"jamiehannaford","id":1867202,"avatar_url":"https://avatars.githubusercontent.com/u/1867202?v=3","gravatar_id":"","url":"https://api.github.com/users/jamiehannaford","html_url":"https://github.com/jamiehannaford","followers_url":"https://api.github.com/users/jamiehannaford/followers","following_url":"https://api.github.com/users/jamiehannaford/following{/other_user}","gists_url":"https://api.github.com/users/jamiehannaford/gists{/gist_id}","starred_url":"https://api.github.com/users/jamiehannaford/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jamiehannaford/subscriptions","organizations_url":"https://api.github.com/users/jamiehannaford/orgs","repos_url":"https://api.github.com/users/jamiehannaford/repos","events_url":"https://api.github.com/users/jamiehannaford/events{/privacy}","received_events_url":"https://api.github.com/users/jamiehannaford/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jamiehannaford/rack","description":"A CLI for OpenStack-based clouds using Gophercloud","fork":true,"url":"https://api.github.com/repos/jamiehannaford/rack","forks_url":"https://api.github.com/repos/jamiehannaford/rack/forks","keys_url":"https://api.github.com/repos/jamiehannaford/rack/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jamiehannaford/rack/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jamiehannaford/rack/teams","hooks_url":"https://api.github.com/repos/jamiehannaford/rack/hooks","issue_events_url":"https://api.github.com/repos/jamiehannaford/rack/issues/events{/number}","events_url":"https://api.github.com/repos/jamiehannaford/rack/events","assignees_url":"https://api.github.com/repos/jamiehannaford/rack/assignees{/user}","branches_url":"https://api.github.com/repos/jamiehannaford/rack/branches{/branch}","tags_url":"https://api.github.com/repos/jamiehannaford/rack/tags","blobs_url":"https://api.github.com/repos/jamiehannaford/rack/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jamiehannaford/rack/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jamiehannaford/rack/git/refs{/sha}","trees_url":"https://api.github.com/repos/jamiehannaford/rack/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jamiehannaford/rack/statuses/{sha}","languages_url":"https://api.github.com/repos/jamiehannaford/rack/languages","stargazers_url":"https://api.github.com/repos/jamiehannaford/rack/stargazers","contributors_url":"https://api.github.com/repos/jamiehannaford/rack/contributors","subscribers_url":"https://api.github.com/repos/jamiehannaford/rack/subscribers","subscription_url":"https://api.github.com/repos/jamiehannaford/rack/subscription","commits_url":"https://api.github.com/repos/jamiehannaford/rack/commits{/sha}","git_commits_url":"https://api.github.com/repos/jamiehannaford/rack/git/commits{/sha}","comments_url":"https://api.github.com/repos/jamiehannaford/rack/comments{/number}","issue_comment_url":"https://api.github.com/repos/jamiehannaford/rack/issues/comments{/number}","contents_url":"https://api.github.com/repos/jamiehannaford/rack/contents/{+path}","compare_url":"https://api.github.com/repos/jamiehannaford/rack/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jamiehannaford/rack/merges","archive_url":"https://api.github.com/repos/jamiehannaford/rack/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jamiehannaford/rack/downloads","issues_url":"https://api.github.com/repos/jamiehannaford/rack/issues{/number}","pulls_url":"https://api.github.com/repos/jamiehannaford/rack/pulls{/number}","milestones_url":"https://api.github.com/repos/jamiehannaford/rack/milestones{/number}","notifications_url":"https://api.github.com/repos/jamiehannaford/rack/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jamiehannaford/rack/labels{/name}","releases_url":"https://api.github.com/repos/jamiehannaford/rack/releases{/id}","created_at":"2015-07-08T07:38:38Z","updated_at":"2015-07-08T07:38:39Z","pushed_at":"2015-07-10T14:56:09Z","git_url":"git://github.com/jamiehannaford/rack.git","ssh_url":"git@github.com:jamiehannaford/rack.git","clone_url":"https://github.com/jamiehannaford/rack.git","svn_url":"https://github.com/jamiehannaford/rack","homepage":null,"size":876,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"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":"jrperritt:master","ref":"master","sha":"c1b9efabf797598d41803e5d95926fa13af40c9e","user":{"login":"jrperritt","id":1733222,"avatar_url":"https://avatars.githubusercontent.com/u/1733222?v=3","gravatar_id":"","url":"https://api.github.com/users/jrperritt","html_url":"https://github.com/jrperritt","followers_url":"https://api.github.com/users/jrperritt/followers","following_url":"https://api.github.com/users/jrperritt/following{/other_user}","gists_url":"https://api.github.com/users/jrperritt/gists{/gist_id}","starred_url":"https://api.github.com/users/jrperritt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jrperritt/subscriptions","organizations_url":"https://api.github.com/users/jrperritt/orgs","repos_url":"https://api.github.com/users/jrperritt/repos","events_url":"https://api.github.com/users/jrperritt/events{/privacy}","received_events_url":"https://api.github.com/users/jrperritt/received_events","type":"User","site_admin":false},"repo":{"id":33959631,"name":"rack","full_name":"jrperritt/rack","owner":{"login":"jrperritt","id":1733222,"avatar_url":"https://avatars.githubusercontent.com/u/1733222?v=3","gravatar_id":"","url":"https://api.github.com/users/jrperritt","html_url":"https://github.com/jrperritt","followers_url":"https://api.github.com/users/jrperritt/followers","following_url":"https://api.github.com/users/jrperritt/following{/other_user}","gists_url":"https://api.github.com/users/jrperritt/gists{/gist_id}","starred_url":"https://api.github.com/users/jrperritt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jrperritt/subscriptions","organizations_url":"https://api.github.com/users/jrperritt/orgs","repos_url":"https://api.github.com/users/jrperritt/repos","events_url":"https://api.github.com/users/jrperritt/events{/privacy}","received_events_url":"https://api.github.com/users/jrperritt/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jrperritt/rack","description":"A CLI for Rackspace","fork":false,"url":"https://api.github.com/repos/jrperritt/rack","forks_url":"https://api.github.com/repos/jrperritt/rack/forks","keys_url":"https://api.github.com/repos/jrperritt/rack/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jrperritt/rack/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jrperritt/rack/teams","hooks_url":"https://api.github.com/repos/jrperritt/rack/hooks","issue_events_url":"https://api.github.com/repos/jrperritt/rack/issues/events{/number}","events_url":"https://api.github.com/repos/jrperritt/rack/events","assignees_url":"https://api.github.com/repos/jrperritt/rack/assignees{/user}","branches_url":"https://api.github.com/repos/jrperritt/rack/branches{/branch}","tags_url":"https://api.github.com/repos/jrperritt/rack/tags","blobs_url":"https://api.github.com/repos/jrperritt/rack/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jrperritt/rack/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jrperritt/rack/git/refs{/sha}","trees_url":"https://api.github.com/repos/jrperritt/rack/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jrperritt/rack/statuses/{sha}","languages_url":"https://api.github.com/repos/jrperritt/rack/languages","stargazers_url":"https://api.github.com/repos/jrperritt/rack/stargazers","contributors_url":"https://api.github.com/repos/jrperritt/rack/contributors","subscribers_url":"https://api.github.com/repos/jrperritt/rack/subscribers","subscription_url":"https://api.github.com/repos/jrperritt/rack/subscription","commits_url":"https://api.github.com/repos/jrperritt/rack/commits{/sha}","git_commits_url":"https://api.github.com/repos/jrperritt/rack/git/commits{/sha}","comments_url":"https://api.github.com/repos/jrperritt/rack/comments{/number}","issue_comment_url":"https://api.github.com/repos/jrperritt/rack/issues/comments{/number}","contents_url":"https://api.github.com/repos/jrperritt/rack/contents/{+path}","compare_url":"https://api.github.com/repos/jrperritt/rack/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jrperritt/rack/merges","archive_url":"https://api.github.com/repos/jrperritt/rack/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jrperritt/rack/downloads","issues_url":"https://api.github.com/repos/jrperritt/rack/issues{/number}","pulls_url":"https://api.github.com/repos/jrperritt/rack/pulls{/number}","milestones_url":"https://api.github.com/repos/jrperritt/rack/milestones{/number}","notifications_url":"https://api.github.com/repos/jrperritt/rack/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jrperritt/rack/labels{/name}","releases_url":"https://api.github.com/repos/jrperritt/rack/releases{/id}","created_at":"2015-04-14T22:08:59Z","updated_at":"2015-07-13T04:24:08Z","pushed_at":"2015-07-10T14:56:10Z","git_url":"git://github.com/jrperritt/rack.git","ssh_url":"git@github.com:jrperritt/rack.git","clone_url":"https://github.com/jrperritt/rack.git","svn_url":"https://github.com/jrperritt/rack","homepage":"","size":1670,"stargazers_count":13,"watchers_count":13,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":8,"mirror_url":null,"open_issues_count":28,"forks":8,"open_issues":28,"watchers":13,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/jrperritt/rack/pulls/181"},"html":{"href":"https://github.com/jrperritt/rack/pull/181"},"issue":{"href":"https://api.github.com/repos/jrperritt/rack/issues/181"},"comments":{"href":"https://api.github.com/repos/jrperritt/rack/issues/181/comments"},"review_comments":{"href":"https://api.github.com/repos/jrperritt/rack/pulls/181/comments"},"review_comment":{"href":"https://api.github.com/repos/jrperritt/rack/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/jrperritt/rack/pulls/181/commits"},"statuses":{"href":"https://api.github.com/repos/jrperritt/rack/statuses/4746a40ace9797b0555071c146f2d22c34fa204a"}}}}