{"action":"created","comment":{"url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/pulls/comments/28638184","id":28638184,"diff_hunk":"@@ -723,68 +734,255 @@ Bucket.prototype.setMetadata = function(metadata, callback) {\n  *\n  * bucket.upload('local-img.png', options, function(err, newFile) {\n  *   // Your bucket now contains:\n- *   // - \"existing-file.png\" (with the contents of `local-img.png')\n+ *   //   - \"existing-file.png\" (with the contents of `local-img.png')\n  *\n  *   // Note:\n- *   // The `newFile` parameter is equal to `file`.\n+ *   // The `newFile` parameter is equal to `options.destination`.\n+ * });\n+ *\n+ * //-\n+ * // For the power users, glob patterns are also supported, using\n+ * // <a href=\"https://github.com/sindresorhus/globby\">sindresorhus/globby</a>\n+ * // under the hood.\n+ * //\n+ * // NOTE: All of the options globby accepts can be provided with\n+ * // `options.globOptions`. For a full list of options, see\n+ * // <a href=\"http://goo.gl/14UhaI\">node-glob's options object</a>.\n+ * //-\n+ * bucket.upload('/Users/stephen/Desktop/*.{jpg|png}', function(errors, files) {\n+ *   // `errors` will always be an array.\n+ *   // `files` is an array of all successfully uploaded files that the glob\n+ *   // pattern matched.\n+ * });\n+ *\n+ * //-\n+ * // If you're uploading many files, you may wish to suppress errors until all\n+ * // of the files have been processed.\n+ * //-\n+ * var options = {\n+ *   force: true\n+ * };\n+ *\n+ * bucket.upload('/Users/stephen/Photos/*', options, function(errors, files) {\n+ *   // `errors` will always be an array.\n+ *   // `files` is an array of all successfully uploaded files that the glob\n+ *   // pattern matched.\n  * });\n  */\n-Bucket.prototype.upload = function(localPath, options, callback) {\n+Bucket.prototype.upload = function(pattern, options, callback) {\n+  var self = this;\n+\n   if (util.is(options, 'function')) {\n     callback = options;\n     options = {};\n   }\n \n-  var newFile;\n-  if (options.destination instanceof File) {\n-    newFile = options.destination;\n-  } else if (util.is(options.destination, 'string')) {\n-    // Use the string as the name of the file.\n-    newFile = this.file(options.destination);\n-  } else {\n-    // Resort to using the name of the incoming file.\n-    newFile = this.file(path.basename(localPath));\n+  options = options || {};\n+\n+  var errors = [];\n+  var files = [];\n+\n+  var globOptions = extend({}, options.globOptions, { nodir: true });\n+\n+  globby(pattern, globOptions, function(err, filePaths) {\n+    if (err) {\n+      callback(err);\n+      return;\n+    }\n+\n+    var uploadFileFns = filePaths.map(function(filePath) {\n+      return function(next) {\n+        var fileName;\n+\n+        if (options.basePath) {\n+          fileName = path.relative(options.basePath, filePath);\n+        } else {\n+          fileName = path.basename(filePath);\n+        }\n+\n+        var opts = extend({}, options, { destination: fileName });\n+\n+        self.uploadFile(filePath, opts, function(err, file) {\n+          if (err) {\n+            errors.push(err);\n+          } else {\n+            files.push(file);\n+          }\n+\n+          next(options.force ? null : err);\n+        });\n+      };\n+    });\n+\n+    async.parallelLimit(uploadFileFns, MAX_PARALLEL_UPLOADS, function() {\n+      callback(errors, files);\n+    });\n+  });\n+};\n+\n+/**\n+ * Upload the contents of a directory to the root of your bucket. The structure\n+ * of the given directory will be maintained.\n+ *\n+ * @param {string} directoryPath - Path to the directory you wish to upload.\n+ * @param {object=} options - Configuration object.\n+ * @param {string} options.basePath - A parent directory to use as the tip of\n+ *     the resulting hierarchy in your bucket. File names are determined using\n+ *     this value, which defaults to the given `directoryPath`. See the example\n+ *     below for more.\n+ * @param {boolean} options.resumable - Force a resumable upload. (default:\n+ *     true for files larger than 5MB). Read more about resumable uploads\n+ *     [here](http://goo.gl/1JWqCF). NOTE: This behavior is only possible with\n+ *     this method, and not {module:storage/file#createWriteStream}. When\n+ *     working with streams, the file format and size is unknown until it's\n+ *     completely consumed. Because of this, it's best for you to be explicit\n+ *     for what makes sense given your input.\n+ * @param {string|boolean} options.validation - Possible values: `\"md5\"`,\n+ *     `\"crc32c\"`, or `false`. By default, data integrity is validated with an\n+ *     MD5 checksum for maximum reliability. CRC32c will provide better\n+ *     performance with less reliability. You may also choose to skip validation\n+ *     completely, however this is **not recommended**.\n+ * @param {function} callback - The callback function.\n+ *\n+ * @example\n+ * var zooPhotosPath = '/Users/stephen/Photos/zoo';\n+ *\n+ * bucket.uploadDirectory(zooPhotosPath, function(err, files) {\n+ *   // Your bucket now contains:\n+ *   //   - \"monkeys/monkey-1.jpg\"\n+ *   //   - \"zebras/zebra-1.jpg\"\n+ *   //   - \"sleeping-panda.jpg\"\n+ * });\n+ *\n+ * //-\n+ * // You can also specify a `basePath` if you need more control.\n+ * //-\n+ * var options = {\n+ *   basePath: '/Users/stephen/Photos';\n+ * };\n+ *\n+ * bucket.uploadDirectory(zooPhotosPath, options, function(err, files) {","path":"lib/storage/bucket.js","position":241,"original_position":241,"commit_id":"9b774617447438aff43b793e3577007d189a6190","original_commit_id":"9b774617447438aff43b793e3577007d189a6190","user":{"login":"stephenplusplus","id":723048,"avatar_url":"https://avatars.githubusercontent.com/u/723048?v=3","gravatar_id":"","url":"https://api.github.com/users/stephenplusplus","html_url":"https://github.com/stephenplusplus","followers_url":"https://api.github.com/users/stephenplusplus/followers","following_url":"https://api.github.com/users/stephenplusplus/following{/other_user}","gists_url":"https://api.github.com/users/stephenplusplus/gists{/gist_id}","starred_url":"https://api.github.com/users/stephenplusplus/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stephenplusplus/subscriptions","organizations_url":"https://api.github.com/users/stephenplusplus/orgs","repos_url":"https://api.github.com/users/stephenplusplus/repos","events_url":"https://api.github.com/users/stephenplusplus/events{/privacy}","received_events_url":"https://api.github.com/users/stephenplusplus/received_events","type":"User","site_admin":false},"body":"Methods that deal with multiple files don't accept destination, since that [historically] refers to a single file. So, uploadDirectory and upload just accept basePath, while uploadFile accepts destination.\r\n\r\nAt the end of the day, a user might want to handle all of this logic on their own, directly using uploadFile or even the bare-bones createWriteStream. It's not too late to scrap the PR and just let the user handle all this themselves :)","created_at":"2015-04-17T23:54:52Z","updated_at":"2015-04-17T23:54:52Z","html_url":"https://github.com/GoogleCloudPlatform/gcloud-node/pull/492#discussion_r28638184","pull_request_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/pulls/492","_links":{"self":{"href":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/pulls/comments/28638184"},"html":{"href":"https://github.com/GoogleCloudPlatform/gcloud-node/pull/492#discussion_r28638184"},"pull_request":{"href":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/pulls/492"}}},"pull_request":{"url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/pulls/492","id":33161993,"html_url":"https://github.com/GoogleCloudPlatform/gcloud-node/pull/492","diff_url":"https://github.com/GoogleCloudPlatform/gcloud-node/pull/492.diff","patch_url":"https://github.com/GoogleCloudPlatform/gcloud-node/pull/492.patch","issue_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/issues/492","number":492,"state":"open","locked":false,"title":"support uploading directories","user":{"login":"stephenplusplus","id":723048,"avatar_url":"https://avatars.githubusercontent.com/u/723048?v=3","gravatar_id":"","url":"https://api.github.com/users/stephenplusplus","html_url":"https://github.com/stephenplusplus","followers_url":"https://api.github.com/users/stephenplusplus/followers","following_url":"https://api.github.com/users/stephenplusplus/following{/other_user}","gists_url":"https://api.github.com/users/stephenplusplus/gists{/gist_id}","starred_url":"https://api.github.com/users/stephenplusplus/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stephenplusplus/subscriptions","organizations_url":"https://api.github.com/users/stephenplusplus/orgs","repos_url":"https://api.github.com/users/stephenplusplus/repos","events_url":"https://api.github.com/users/stephenplusplus/events{/privacy}","received_events_url":"https://api.github.com/users/stephenplusplus/received_events","type":"User","site_admin":false},"body":"Fixes #412\r\n\r\n#### To Dos\r\n\r\n- [x] Unit Tests\r\n- [x] System Tests\r\n- [x] Docs\r\n\r\nThis is a work in progress, but is an attempt to make a sane API for uploading directories.\r\n\r\n```\r\nzoo/\r\n  chipmunks/\r\n    chipmunk-1.jpg\r\n  pandas/\r\n    panda-1.jpg\r\n  zoo-photos.zip\r\n```\r\n```js\r\nbucket.uploadDirectory(\"zoo\", function (err, files) {\r\n  files = [\r\n    File(\"chipmunks/chipmunk-1.jpg\"),\r\n    File(\"pandas/panda-1.jpg\"),\r\n    File(\"zoo-photos.jpg\")\r\n  ]\r\n})\r\n```\r\n\r\n#### Globs\r\n\r\n`bucket.uploadDirectory` is a wrapper around `bucket.upload`, which now supports globs:\r\n\r\n```js\r\nbucket.upload(\"zoo/**/*.jpg\", function (err, files) {\r\n  files = [\r\n    File(\"chipmunk-1.jpg\"),\r\n    File(\"panda-1.jpg\")\r\n  ]\r\n})\r\n```\r\n\r\nNote that the resulting file names aren't prefixed with a directory path (e.g. \"chipmunks/chipmunk-1.jpg\" vs \"chipmunk-1.jpg\"). Since a glob can include several files and directories in various locations on a hard drive, by default, just the filename is used as the uploaded file's name.\r\n\r\nBy specifying `options.basePath`, a user can tell us the common parent of all of the locations their glob matches, which is then used as a prefix for the file. This is how `bucket.uploadDirectory` works (simplified):\r\n\r\n```js\r\nBucket.prototype.uploadDirectory = function (directoryPath) {\r\n  bucket.upload(path.join(directoryPath, \"**/*\"), { basePath: directoryPath })\r\n}\r\n```\r\n\r\n#### Extending globs\r\n\r\nbucket.upload accepts either a single glob or array of globs. It's passed directly to [sindresorhus/globby](https://github.com/sindresorhus/globby), which uses [isaacs/minimatch](https://github.com/isaacs/minimatch) and [isaacs/node-glob](https://github.com/isaacs/node-glob) to return the matching paths. All [minimatch glob patterns](https://github.com/sindresorhus/globby#globbing-patterns) are accepted, as well as [node-glob options](https://github.com/isaacs/node-glob#options) via `options.globOptions`.\r\n","created_at":"2015-04-13T13:13:04Z","updated_at":"2015-04-17T23:54:52Z","closed_at":null,"merged_at":null,"merge_commit_sha":"f3e05f2e48bdf8df0cfc22765dd86e9b3f4e90eb","assignee":null,"milestone":{"url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/milestones/7","html_url":"https://github.com/GoogleCloudPlatform/gcloud-node/milestones/Storage%20Future","labels_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/milestones/7/labels","id":961393,"number":7,"title":"Storage Future","description":"","creator":{"login":"jgeewax","id":112928,"avatar_url":"https://avatars.githubusercontent.com/u/112928?v=3","gravatar_id":"","url":"https://api.github.com/users/jgeewax","html_url":"https://github.com/jgeewax","followers_url":"https://api.github.com/users/jgeewax/followers","following_url":"https://api.github.com/users/jgeewax/following{/other_user}","gists_url":"https://api.github.com/users/jgeewax/gists{/gist_id}","starred_url":"https://api.github.com/users/jgeewax/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jgeewax/subscriptions","organizations_url":"https://api.github.com/users/jgeewax/orgs","repos_url":"https://api.github.com/users/jgeewax/repos","events_url":"https://api.github.com/users/jgeewax/events{/privacy}","received_events_url":"https://api.github.com/users/jgeewax/received_events","type":"User","site_admin":false},"open_issues":7,"closed_issues":2,"state":"open","created_at":"2015-02-02T13:30:53Z","updated_at":"2015-04-17T21:41:10Z","due_on":null,"closed_at":null},"commits_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/pulls/492/commits","review_comments_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/pulls/492/comments","review_comment_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/pulls/comments{/number}","comments_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/issues/492/comments","statuses_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/statuses/9b774617447438aff43b793e3577007d189a6190","head":{"label":"stephenplusplus:spp--storage-globs","ref":"spp--storage-globs","sha":"9b774617447438aff43b793e3577007d189a6190","user":{"login":"stephenplusplus","id":723048,"avatar_url":"https://avatars.githubusercontent.com/u/723048?v=3","gravatar_id":"","url":"https://api.github.com/users/stephenplusplus","html_url":"https://github.com/stephenplusplus","followers_url":"https://api.github.com/users/stephenplusplus/followers","following_url":"https://api.github.com/users/stephenplusplus/following{/other_user}","gists_url":"https://api.github.com/users/stephenplusplus/gists{/gist_id}","starred_url":"https://api.github.com/users/stephenplusplus/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stephenplusplus/subscriptions","organizations_url":"https://api.github.com/users/stephenplusplus/orgs","repos_url":"https://api.github.com/users/stephenplusplus/repos","events_url":"https://api.github.com/users/stephenplusplus/events{/privacy}","received_events_url":"https://api.github.com/users/stephenplusplus/received_events","type":"User","site_admin":false},"repo":{"id":22482767,"name":"gcloud-node","full_name":"stephenplusplus/gcloud-node","owner":{"login":"stephenplusplus","id":723048,"avatar_url":"https://avatars.githubusercontent.com/u/723048?v=3","gravatar_id":"","url":"https://api.github.com/users/stephenplusplus","html_url":"https://github.com/stephenplusplus","followers_url":"https://api.github.com/users/stephenplusplus/followers","following_url":"https://api.github.com/users/stephenplusplus/following{/other_user}","gists_url":"https://api.github.com/users/stephenplusplus/gists{/gist_id}","starred_url":"https://api.github.com/users/stephenplusplus/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stephenplusplus/subscriptions","organizations_url":"https://api.github.com/users/stephenplusplus/orgs","repos_url":"https://api.github.com/users/stephenplusplus/repos","events_url":"https://api.github.com/users/stephenplusplus/events{/privacy}","received_events_url":"https://api.github.com/users/stephenplusplus/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/stephenplusplus/gcloud-node","description":"Google Cloud Node Client Library","fork":true,"url":"https://api.github.com/repos/stephenplusplus/gcloud-node","forks_url":"https://api.github.com/repos/stephenplusplus/gcloud-node/forks","keys_url":"https://api.github.com/repos/stephenplusplus/gcloud-node/keys{/key_id}","collaborators_url":"https://api.github.com/repos/stephenplusplus/gcloud-node/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/stephenplusplus/gcloud-node/teams","hooks_url":"https://api.github.com/repos/stephenplusplus/gcloud-node/hooks","issue_events_url":"https://api.github.com/repos/stephenplusplus/gcloud-node/issues/events{/number}","events_url":"https://api.github.com/repos/stephenplusplus/gcloud-node/events","assignees_url":"https://api.github.com/repos/stephenplusplus/gcloud-node/assignees{/user}","branches_url":"https://api.github.com/repos/stephenplusplus/gcloud-node/branches{/branch}","tags_url":"https://api.github.com/repos/stephenplusplus/gcloud-node/tags","blobs_url":"https://api.github.com/repos/stephenplusplus/gcloud-node/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/stephenplusplus/gcloud-node/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/stephenplusplus/gcloud-node/git/refs{/sha}","trees_url":"https://api.github.com/repos/stephenplusplus/gcloud-node/git/trees{/sha}","statuses_url":"https://api.github.com/repos/stephenplusplus/gcloud-node/statuses/{sha}","languages_url":"https://api.github.com/repos/stephenplusplus/gcloud-node/languages","stargazers_url":"https://api.github.com/repos/stephenplusplus/gcloud-node/stargazers","contributors_url":"https://api.github.com/repos/stephenplusplus/gcloud-node/contributors","subscribers_url":"https://api.github.com/repos/stephenplusplus/gcloud-node/subscribers","subscription_url":"https://api.github.com/repos/stephenplusplus/gcloud-node/subscription","commits_url":"https://api.github.com/repos/stephenplusplus/gcloud-node/commits{/sha}","git_commits_url":"https://api.github.com/repos/stephenplusplus/gcloud-node/git/commits{/sha}","comments_url":"https://api.github.com/repos/stephenplusplus/gcloud-node/comments{/number}","issue_comment_url":"https://api.github.com/repos/stephenplusplus/gcloud-node/issues/comments{/number}","contents_url":"https://api.github.com/repos/stephenplusplus/gcloud-node/contents/{+path}","compare_url":"https://api.github.com/repos/stephenplusplus/gcloud-node/compare/{base}...{head}","merges_url":"https://api.github.com/repos/stephenplusplus/gcloud-node/merges","archive_url":"https://api.github.com/repos/stephenplusplus/gcloud-node/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/stephenplusplus/gcloud-node/downloads","issues_url":"https://api.github.com/repos/stephenplusplus/gcloud-node/issues{/number}","pulls_url":"https://api.github.com/repos/stephenplusplus/gcloud-node/pulls{/number}","milestones_url":"https://api.github.com/repos/stephenplusplus/gcloud-node/milestones{/number}","notifications_url":"https://api.github.com/repos/stephenplusplus/gcloud-node/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/stephenplusplus/gcloud-node/labels{/name}","releases_url":"https://api.github.com/repos/stephenplusplus/gcloud-node/releases{/id}","created_at":"2014-07-31T19:55:20Z","updated_at":"2014-07-31T19:55:38Z","pushed_at":"2015-04-17T21:03:53Z","git_url":"git://github.com/stephenplusplus/gcloud-node.git","ssh_url":"git@github.com:stephenplusplus/gcloud-node.git","clone_url":"https://github.com/stephenplusplus/gcloud-node.git","svn_url":"https://github.com/stephenplusplus/gcloud-node","homepage":"","size":12040,"stargazers_count":0,"watchers_count":0,"language":"JavaScript","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"GoogleCloudPlatform:master","ref":"master","sha":"f8a554165c0382512b9e24a6bcf3793523435036","user":{"login":"GoogleCloudPlatform","id":2810941,"avatar_url":"https://avatars.githubusercontent.com/u/2810941?v=3","gravatar_id":"","url":"https://api.github.com/users/GoogleCloudPlatform","html_url":"https://github.com/GoogleCloudPlatform","followers_url":"https://api.github.com/users/GoogleCloudPlatform/followers","following_url":"https://api.github.com/users/GoogleCloudPlatform/following{/other_user}","gists_url":"https://api.github.com/users/GoogleCloudPlatform/gists{/gist_id}","starred_url":"https://api.github.com/users/GoogleCloudPlatform/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/GoogleCloudPlatform/subscriptions","organizations_url":"https://api.github.com/users/GoogleCloudPlatform/orgs","repos_url":"https://api.github.com/users/GoogleCloudPlatform/repos","events_url":"https://api.github.com/users/GoogleCloudPlatform/events{/privacy}","received_events_url":"https://api.github.com/users/GoogleCloudPlatform/received_events","type":"Organization","site_admin":false},"repo":{"id":19483273,"name":"gcloud-node","full_name":"GoogleCloudPlatform/gcloud-node","owner":{"login":"GoogleCloudPlatform","id":2810941,"avatar_url":"https://avatars.githubusercontent.com/u/2810941?v=3","gravatar_id":"","url":"https://api.github.com/users/GoogleCloudPlatform","html_url":"https://github.com/GoogleCloudPlatform","followers_url":"https://api.github.com/users/GoogleCloudPlatform/followers","following_url":"https://api.github.com/users/GoogleCloudPlatform/following{/other_user}","gists_url":"https://api.github.com/users/GoogleCloudPlatform/gists{/gist_id}","starred_url":"https://api.github.com/users/GoogleCloudPlatform/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/GoogleCloudPlatform/subscriptions","organizations_url":"https://api.github.com/users/GoogleCloudPlatform/orgs","repos_url":"https://api.github.com/users/GoogleCloudPlatform/repos","events_url":"https://api.github.com/users/GoogleCloudPlatform/events{/privacy}","received_events_url":"https://api.github.com/users/GoogleCloudPlatform/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/GoogleCloudPlatform/gcloud-node","description":"Google Cloud Client Library for Node.js","fork":false,"url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node","forks_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/forks","keys_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/keys{/key_id}","collaborators_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/teams","hooks_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/hooks","issue_events_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/issues/events{/number}","events_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/events","assignees_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/assignees{/user}","branches_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/branches{/branch}","tags_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/tags","blobs_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/git/refs{/sha}","trees_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/git/trees{/sha}","statuses_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/statuses/{sha}","languages_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/languages","stargazers_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/stargazers","contributors_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/contributors","subscribers_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/subscribers","subscription_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/subscription","commits_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/commits{/sha}","git_commits_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/git/commits{/sha}","comments_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/comments{/number}","issue_comment_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/issues/comments{/number}","contents_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/contents/{+path}","compare_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/compare/{base}...{head}","merges_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/merges","archive_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/downloads","issues_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/issues{/number}","pulls_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/pulls{/number}","milestones_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/milestones{/number}","notifications_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/labels{/name}","releases_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/releases{/id}","created_at":"2014-05-06T06:18:00Z","updated_at":"2015-04-17T21:41:10Z","pushed_at":"2015-04-17T21:41:10Z","git_url":"git://github.com/GoogleCloudPlatform/gcloud-node.git","ssh_url":"git@github.com:GoogleCloudPlatform/gcloud-node.git","clone_url":"https://github.com/GoogleCloudPlatform/gcloud-node.git","svn_url":"https://github.com/GoogleCloudPlatform/gcloud-node","homepage":"https://googlecloudplatform.github.io/gcloud-node","size":13663,"stargazers_count":465,"watchers_count":465,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":63,"mirror_url":null,"open_issues_count":39,"forks":63,"open_issues":39,"watchers":465,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/pulls/492"},"html":{"href":"https://github.com/GoogleCloudPlatform/gcloud-node/pull/492"},"issue":{"href":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/issues/492"},"comments":{"href":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/issues/492/comments"},"review_comments":{"href":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/pulls/492/comments"},"review_comment":{"href":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/pulls/492/commits"},"statuses":{"href":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/statuses/9b774617447438aff43b793e3577007d189a6190"}}}}