GitHub PullRequestReviewCommentEvent at 2014-09-19 03:06:34
Repository: docker
Actor: duglin
Payload: {"action":"created","comment":{"url":"https://api.github.com/repos/docker/docker/pulls/comments/17767353","id":17767353,"diff_hunk":"@@ -104,148 +104,180 @@ func (b *Builder) runContextCommand(args []string, allowRemote bool, allowDecomp\n \t\treturn fmt.Errorf(\"No context given. Impossible to use %s\", cmdName)\n \t}\n \n-\tif len(args) != 2 {\n-\t\treturn fmt.Errorf(\"Invalid %s format\", cmdName)\n+\tif len(args) < 2 {\n+\t\treturn fmt.Errorf(\"Invalid %s format - at least two arguments required\", cmdName)\n \t}\n \n-\torig := args[0]\n-\tdest := args[1]\n+\tdest := args[len(args)-1] // last one is always the dest\n \n-\tcmd := b.Config.Cmd\n-\tb.Config.Cmd = []string{\"/bin/sh\", \"-c\", fmt.Sprintf(\"#(nop) %s %s in %s\", cmdName, orig, dest)}\n-\tdefer func(cmd []string) { b.Config.Cmd = cmd }(cmd)\n-\tb.Config.Image = b.image\n+\tif len(args) > 2 && dest[len(dest)-1] != '/' {\n+\t\treturn fmt.Errorf(\"When using %s with more than one source file, the destination must be a directory and end with a /\", cmdName)\n+\t}\n \n \tvar (\n-\t\torigPath   = orig\n-\t\tdestPath   = dest\n-\t\tremoteHash string\n-\t\tisRemote   bool\n-\t\tdecompress = true\n+\t\torigPaths    = []string{}\n+\t\tdestPaths    = []string{}\n+\t\thashPaths    = []string{}\n+\t\tdecompresses = []bool{}\n+\t\thasHash      = false\n \t)\n \n-\tisRemote = utils.IsURL(orig)\n-\tif isRemote && !allowRemote {\n-\t\treturn fmt.Errorf(\"Source can't be an URL for %s\", cmdName)\n-\t} else if utils.IsURL(orig) {\n-\t\t// Initiate the download\n-\t\tresp, err := utils.Download(orig)\n-\t\tif err != nil {\n-\t\t\treturn err\n-\t\t}\n+\t// Loop through each src file and calculate the info we need to\n+\t// do the copy (e.g. hash value if cached).  Don't actually do\n+\t// the copy until we've looked at all src files\n+\tfor _, orig := range args[0 : len(args)-1] {\n+\t\tb.Config.Image = b.image\n \n-\t\t// Create a tmp dir\n-\t\ttmpDirName, err := ioutil.TempDir(b.contextPath, \"docker-remote\")\n-\t\tif err != nil {\n-\t\t\treturn err\n-\t\t}\n+\t\tvar (\n+\t\t\torigPath   = orig\n+\t\t\tdestPath   = dest\n+\t\t\tremoteHash string\n+\t\t\tisRemote   bool\n+\t\t\tdecompress = true\n+\t\t\thash       string\n+\t\t)\n \n-\t\t// Create a tmp file within our tmp dir\n-\t\ttmpFileName := path.Join(tmpDirName, \"tmp\")\n-\t\ttmpFile, err := os.OpenFile(tmpFileName, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)\n-\t\tif err != nil {\n-\t\t\treturn err\n-\t\t}\n-\t\tdefer os.RemoveAll(tmpDirName)\n+\t\tisRemote = utils.IsURL(orig)\n+\t\tif isRemote && !allowRemote {\n+\t\t\treturn fmt.Errorf(\"Source can't be an URL for %s\", cmdName)\n+\t\t} else if utils.IsURL(orig) {\n+\t\t\t// Initiate the download\n+\t\t\tresp, err := utils.Download(orig)\n+\t\t\tif err != nil {\n+\t\t\t\treturn err\n+\t\t\t}\n \n-\t\t// Download and dump result to tmp file\n-\t\tif _, err := io.Copy(tmpFile, utils.ProgressReader(resp.Body, int(resp.ContentLength), b.OutOld, b.StreamFormatter, true, \"\", \"Downloading\")); err != nil {\n-\t\t\ttmpFile.Close()\n-\t\t\treturn err\n-\t\t}\n-\t\tfmt.Fprintf(b.OutStream, \"\\n\")\n-\t\ttmpFile.Close()\n+\t\t\t// Create a tmp dir\n+\t\t\ttmpDirName, err := ioutil.TempDir(b.contextPath, \"docker-remote\")\n+\t\t\tif err != nil {\n+\t\t\t\treturn err\n+\t\t\t}\n \n-\t\t// Remove the mtime of the newly created tmp file\n-\t\tif err := system.UtimesNano(tmpFileName, make([]syscall.Timespec, 2)); err != nil {\n-\t\t\treturn err\n-\t\t}\n+\t\t\t// Create a tmp file within our tmp dir\n+\t\t\ttmpFileName := path.Join(tmpDirName, \"tmp\")\n+\t\t\ttmpFile, err := os.OpenFile(tmpFileName, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)\n+\t\t\tif err != nil {\n+\t\t\t\treturn err\n+\t\t\t}\n+\t\t\tdefer os.RemoveAll(tmpDirName)\n \n-\t\torigPath = path.Join(filepath.Base(tmpDirName), filepath.Base(tmpFileName))\n+\t\t\t// Download and dump result to tmp file\n+\t\t\tif _, err := io.Copy(tmpFile, utils.ProgressReader(resp.Body, int(resp.ContentLength), b.OutOld, b.StreamFormatter, true, \"\", \"Downloading\")); err != nil {\n+\t\t\t\ttmpFile.Close()\n+\t\t\t\treturn err\n+\t\t\t}\n+\t\t\tfmt.Fprintf(b.OutStream, \"\\n\")\n+\t\t\ttmpFile.Close()\n \n-\t\t// Process the checksum\n-\t\tr, err := archive.Tar(tmpFileName, archive.Uncompressed)\n-\t\tif err != nil {\n-\t\t\treturn err\n-\t\t}\n-\t\ttarSum, err := tarsum.NewTarSum(r, true, tarsum.Version0)\n-\t\tif err != nil {\n-\t\t\treturn err\n-\t\t}\n-\t\tif _, err := io.Copy(ioutil.Discard, tarSum); err != nil {\n-\t\t\treturn err\n-\t\t}\n-\t\tremoteHash = tarSum.Sum(nil)\n-\t\tr.Close()\n+\t\t\t// Remove the mtime of the newly created tmp file\n+\t\t\tif err := system.UtimesNano(tmpFileName, make([]syscall.Timespec, 2)); err != nil {\n+\t\t\t\treturn err\n+\t\t\t}\n \n-\t\t// If the destination is a directory, figure out the filename.\n-\t\tif strings.HasSuffix(dest, \"/\") {\n-\t\t\tu, err := url.Parse(orig)\n+\t\t\torigPath = path.Join(filepath.Base(tmpDirName), filepath.Base(tmpFileName))\n+\n+\t\t\t// Process the checksum\n+\t\t\tr, err := archive.Tar(tmpFileName, archive.Uncompressed)\n+\t\t\tif err != nil {\n+\t\t\t\treturn err\n+\t\t\t}\n+\t\t\ttarSum, err := tarsum.NewTarSum(r, true, tarsum.Version0)\n \t\t\tif err != nil {\n \t\t\t\treturn err\n \t\t\t}\n-\t\t\tpath := u.Path\n-\t\t\tif strings.HasSuffix(path, \"/\") {\n-\t\t\t\tpath = path[:len(path)-1]\n+\t\t\tif _, err := io.Copy(ioutil.Discard, tarSum); err != nil {\n+\t\t\t\treturn err\n \t\t\t}\n-\t\t\tparts := strings.Split(path, \"/\")\n-\t\t\tfilename := parts[len(parts)-1]\n-\t\t\tif filename == \"\" {\n-\t\t\t\treturn fmt.Errorf(\"cannot determine filename from url: %s\", u)\n+\t\t\tremoteHash = tarSum.Sum(nil)\n+\t\t\tr.Close()\n+\n+\t\t\t// If the destination is a directory, figure out the filename.\n+\t\t\tif strings.HasSuffix(dest, \"/\") {\n+\t\t\t\tu, err := url.Parse(orig)","path":"builder/internals.go","position":null,"original_position":163,"commit_id":"7cc498a18287afa601b577dcb7231215111b8829","original_commit_id":"19325c1564f7f61cd48fad4f704cbb29c6b3ddca","user":{"login":"duglin","id":1944671,"avatar_url":"https://avatars.githubusercontent.com/u/1944671?v=2","gravatar_id":"3ec19e556669394d7d6a5dfdef853ad8","url":"https://api.github.com/users/duglin","html_url":"https://github.com/duglin","followers_url":"https://api.github.com/users/duglin/followers","following_url":"https://api.github.com/users/duglin/following{/other_user}","gists_url":"https://api.github.com/users/duglin/gists{/gist_id}","starred_url":"https://api.github.com/users/duglin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/duglin/subscriptions","organizations_url":"https://api.github.com/users/duglin/orgs","repos_url":"https://api.github.com/users/duglin/repos","events_url":"https://api.github.com/users/duglin/events{/privacy}","received_events_url":"https://api.github.com/users/duglin/received_events","type":"User","site_admin":false},"body":"While this was in the original, I'm curious... why do you think it can't be a URL?  The source of a copy/add can be a URL.","created_at":"2014-09-19T03:06:34Z","updated_at":"2014-09-19T03:06:34Z","html_url":"https://github.com/docker/docker/pull/8076#discussion_r17767353","pull_request_url":"https://api.github.com/repos/docker/docker/pulls/8076","_links":{"self":{"href":"https://api.github.com/repos/docker/docker/pulls/comments/17767353"},"html":{"href":"https://github.com/docker/docker/pull/8076#discussion_r17767353"},"pull_request":{"href":"https://api.github.com/repos/docker/docker/pulls/8076"}}},"pull_request":{"url":"https://api.github.com/repos/docker/docker/pulls/8076","id":21334451,"html_url":"https://github.com/docker/docker/pull/8076","diff_url":"https://github.com/docker/docker/pull/8076.diff","patch_url":"https://github.com/docker/docker/pull/8076.patch","issue_url":"https://api.github.com/repos/docker/docker/issues/8076","number":8076,"state":"open","locked":false,"title":"Add support for copy/add with multiple src files","user":{"login":"duglin","id":1944671,"avatar_url":"https://avatars.githubusercontent.com/u/1944671?v=2","gravatar_id":"3ec19e556669394d7d6a5dfdef853ad8","url":"https://api.github.com/users/duglin","html_url":"https://github.com/duglin","followers_url":"https://api.github.com/users/duglin/followers","following_url":"https://api.github.com/users/duglin/following{/other_user}","gists_url":"https://api.github.com/users/duglin/gists{/gist_id}","starred_url":"https://api.github.com/users/duglin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/duglin/subscriptions","organizations_url":"https://api.github.com/users/duglin/orgs","repos_url":"https://api.github.com/users/duglin/repos","events_url":"https://api.github.com/users/duglin/events{/privacy}","received_events_url":"https://api.github.com/users/duglin/received_events","type":"User","site_admin":false},"body":"Part one of solution for issue #6820\r\n\r\nSigned-off-by: Doug Davis <dug@us.ibm.com>","created_at":"2014-09-16T22:47:33Z","updated_at":"2014-09-19T03:06:34Z","closed_at":null,"merged_at":null,"merge_commit_sha":"c48641c56462e802bd91ae6e2847b63c80b17d58","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/docker/docker/pulls/8076/commits","review_comments_url":"https://api.github.com/repos/docker/docker/pulls/8076/comments","review_comment_url":"https://api.github.com/repos/docker/docker/pulls/comments/{number}","comments_url":"https://api.github.com/repos/docker/docker/issues/8076/comments","statuses_url":"https://api.github.com/repos/docker/docker/statuses/7cc498a18287afa601b577dcb7231215111b8829","head":{"label":"duglin:MultiCopyAdd","ref":"MultiCopyAdd","sha":"7cc498a18287afa601b577dcb7231215111b8829","user":{"login":"duglin","id":1944671,"avatar_url":"https://avatars.githubusercontent.com/u/1944671?v=2","gravatar_id":"3ec19e556669394d7d6a5dfdef853ad8","url":"https://api.github.com/users/duglin","html_url":"https://github.com/duglin","followers_url":"https://api.github.com/users/duglin/followers","following_url":"https://api.github.com/users/duglin/following{/other_user}","gists_url":"https://api.github.com/users/duglin/gists{/gist_id}","starred_url":"https://api.github.com/users/duglin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/duglin/subscriptions","organizations_url":"https://api.github.com/users/duglin/orgs","repos_url":"https://api.github.com/users/duglin/repos","events_url":"https://api.github.com/users/duglin/events{/privacy}","received_events_url":"https://api.github.com/users/duglin/received_events","type":"User","site_admin":false},"repo":{"id":22769065,"name":"docker","full_name":"duglin/docker","owner":{"login":"duglin","id":1944671,"avatar_url":"https://avatars.githubusercontent.com/u/1944671?v=2","gravatar_id":"3ec19e556669394d7d6a5dfdef853ad8","url":"https://api.github.com/users/duglin","html_url":"https://github.com/duglin","followers_url":"https://api.github.com/users/duglin/followers","following_url":"https://api.github.com/users/duglin/following{/other_user}","gists_url":"https://api.github.com/users/duglin/gists{/gist_id}","starred_url":"https://api.github.com/users/duglin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/duglin/subscriptions","organizations_url":"https://api.github.com/users/duglin/orgs","repos_url":"https://api.github.com/users/duglin/repos","events_url":"https://api.github.com/users/duglin/events{/privacy}","received_events_url":"https://api.github.com/users/duglin/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/duglin/docker","description":"Docker - the open-source application container engine","fork":true,"url":"https://api.github.com/repos/duglin/docker","forks_url":"https://api.github.com/repos/duglin/docker/forks","keys_url":"https://api.github.com/repos/duglin/docker/keys{/key_id}","collaborators_url":"https://api.github.com/repos/duglin/docker/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/duglin/docker/teams","hooks_url":"https://api.github.com/repos/duglin/docker/hooks","issue_events_url":"https://api.github.com/repos/duglin/docker/issues/events{/number}","events_url":"https://api.github.com/repos/duglin/docker/events","assignees_url":"https://api.github.com/repos/duglin/docker/assignees{/user}","branches_url":"https://api.github.com/repos/duglin/docker/branches{/branch}","tags_url":"https://api.github.com/repos/duglin/docker/tags","blobs_url":"https://api.github.com/repos/duglin/docker/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/duglin/docker/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/duglin/docker/git/refs{/sha}","trees_url":"https://api.github.com/repos/duglin/docker/git/trees{/sha}","statuses_url":"https://api.github.com/repos/duglin/docker/statuses/{sha}","languages_url":"https://api.github.com/repos/duglin/docker/languages","stargazers_url":"https://api.github.com/repos/duglin/docker/stargazers","contributors_url":"https://api.github.com/repos/duglin/docker/contributors","subscribers_url":"https://api.github.com/repos/duglin/docker/subscribers","subscription_url":"https://api.github.com/repos/duglin/docker/subscription","commits_url":"https://api.github.com/repos/duglin/docker/commits{/sha}","git_commits_url":"https://api.github.com/repos/duglin/docker/git/commits{/sha}","comments_url":"https://api.github.com/repos/duglin/docker/comments{/number}","issue_comment_url":"https://api.github.com/repos/duglin/docker/issues/comments/{number}","contents_url":"https://api.github.com/repos/duglin/docker/contents/{+path}","compare_url":"https://api.github.com/repos/duglin/docker/compare/{base}...{head}","merges_url":"https://api.github.com/repos/duglin/docker/merges","archive_url":"https://api.github.com/repos/duglin/docker/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/duglin/docker/downloads","issues_url":"https://api.github.com/repos/duglin/docker/issues{/number}","pulls_url":"https://api.github.com/repos/duglin/docker/pulls{/number}","milestones_url":"https://api.github.com/repos/duglin/docker/milestones{/number}","notifications_url":"https://api.github.com/repos/duglin/docker/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/duglin/docker/labels{/name}","releases_url":"https://api.github.com/repos/duglin/docker/releases{/id}","created_at":"2014-08-08T19:24:58Z","updated_at":"2014-08-12T13:50:40Z","pushed_at":"2014-09-19T02:49:59Z","git_url":"git://github.com/duglin/docker.git","ssh_url":"git@github.com:duglin/docker.git","clone_url":"https://github.com/duglin/docker.git","svn_url":"https://github.com/duglin/docker","homepage":"http://www.docker.com","size":33801,"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":"docker:master","ref":"master","sha":"72e901559177a4a49f82779dbaa108487dce086d","user":{"login":"docker","id":5429470,"avatar_url":"https://avatars.githubusercontent.com/u/5429470?v=2","gravatar_id":null,"url":"https://api.github.com/users/docker","html_url":"https://github.com/docker","followers_url":"https://api.github.com/users/docker/followers","following_url":"https://api.github.com/users/docker/following{/other_user}","gists_url":"https://api.github.com/users/docker/gists{/gist_id}","starred_url":"https://api.github.com/users/docker/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/docker/subscriptions","organizations_url":"https://api.github.com/users/docker/orgs","repos_url":"https://api.github.com/users/docker/repos","events_url":"https://api.github.com/users/docker/events{/privacy}","received_events_url":"https://api.github.com/users/docker/received_events","type":"Organization","site_admin":false},"repo":{"id":7691631,"name":"docker","full_name":"docker/docker","owner":{"login":"docker","id":5429470,"avatar_url":"https://avatars.githubusercontent.com/u/5429470?v=2","gravatar_id":null,"url":"https://api.github.com/users/docker","html_url":"https://github.com/docker","followers_url":"https://api.github.com/users/docker/followers","following_url":"https://api.github.com/users/docker/following{/other_user}","gists_url":"https://api.github.com/users/docker/gists{/gist_id}","starred_url":"https://api.github.com/users/docker/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/docker/subscriptions","organizations_url":"https://api.github.com/users/docker/orgs","repos_url":"https://api.github.com/users/docker/repos","events_url":"https://api.github.com/users/docker/events{/privacy}","received_events_url":"https://api.github.com/users/docker/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/docker/docker","description":"Docker - the open-source application container engine","fork":false,"url":"https://api.github.com/repos/docker/docker","forks_url":"https://api.github.com/repos/docker/docker/forks","keys_url":"https://api.github.com/repos/docker/docker/keys{/key_id}","collaborators_url":"https://api.github.com/repos/docker/docker/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/docker/docker/teams","hooks_url":"https://api.github.com/repos/docker/docker/hooks","issue_events_url":"https://api.github.com/repos/docker/docker/issues/events{/number}","events_url":"https://api.github.com/repos/docker/docker/events","assignees_url":"https://api.github.com/repos/docker/docker/assignees{/user}","branches_url":"https://api.github.com/repos/docker/docker/branches{/branch}","tags_url":"https://api.github.com/repos/docker/docker/tags","blobs_url":"https://api.github.com/repos/docker/docker/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/docker/docker/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/docker/docker/git/refs{/sha}","trees_url":"https://api.github.com/repos/docker/docker/git/trees{/sha}","statuses_url":"https://api.github.com/repos/docker/docker/statuses/{sha}","languages_url":"https://api.github.com/repos/docker/docker/languages","stargazers_url":"https://api.github.com/repos/docker/docker/stargazers","contributors_url":"https://api.github.com/repos/docker/docker/contributors","subscribers_url":"https://api.github.com/repos/docker/docker/subscribers","subscription_url":"https://api.github.com/repos/docker/docker/subscription","commits_url":"https://api.github.com/repos/docker/docker/commits{/sha}","git_commits_url":"https://api.github.com/repos/docker/docker/git/commits{/sha}","comments_url":"https://api.github.com/repos/docker/docker/comments{/number}","issue_comment_url":"https://api.github.com/repos/docker/docker/issues/comments/{number}","contents_url":"https://api.github.com/repos/docker/docker/contents/{+path}","compare_url":"https://api.github.com/repos/docker/docker/compare/{base}...{head}","merges_url":"https://api.github.com/repos/docker/docker/merges","archive_url":"https://api.github.com/repos/docker/docker/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/docker/docker/downloads","issues_url":"https://api.github.com/repos/docker/docker/issues{/number}","pulls_url":"https://api.github.com/repos/docker/docker/pulls{/number}","milestones_url":"https://api.github.com/repos/docker/docker/milestones{/number}","notifications_url":"https://api.github.com/repos/docker/docker/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/docker/docker/labels{/name}","releases_url":"https://api.github.com/repos/docker/docker/releases{/id}","created_at":"2013-01-18T18:10:57Z","updated_at":"2014-09-19T03:02:10Z","pushed_at":"2014-09-19T01:33:45Z","git_url":"git://github.com/docker/docker.git","ssh_url":"git@github.com:docker/docker.git","clone_url":"https://github.com/docker/docker.git","svn_url":"https://github.com/docker/docker","homepage":"http://www.docker.com","size":141227,"stargazers_count":15154,"watchers_count":15154,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2868,"mirror_url":null,"open_issues_count":780,"forks":2868,"open_issues":780,"watchers":15154,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/docker/docker/pulls/8076"},"html":{"href":"https://github.com/docker/docker/pull/8076"},"issue":{"href":"https://api.github.com/repos/docker/docker/issues/8076"},"comments":{"href":"https://api.github.com/repos/docker/docker/issues/8076/comments"},"review_comments":{"href":"https://api.github.com/repos/docker/docker/pulls/8076/comments"},"review_comment":{"href":"https://api.github.com/repos/docker/docker/pulls/comments/{number}"},"commits":{"href":"https://api.github.com/repos/docker/docker/pulls/8076/commits"},"statuses":{"href":"https://api.github.com/repos/docker/docker/statuses/7cc498a18287afa601b577dcb7231215111b8829"}}}}