{"action":"created","comment":{"url":"https://api.github.com/repos/firebase/firebase-tools/pulls/comments/115048934","pull_request_review_id":36565418,"id":115048934,"diff_hunk":"@@ -0,0 +1,103 @@\n+'use strict';\n+\n+var _ = require('lodash');\n+var chalk = require('chalk');\n+var path = require('path');\n+var RSVP = require('rsvp');\n+var getProjectId = require('../getProjectId');\n+var logger = require('../logger');\n+var utils = require('../utils');\n+var parseTriggers = require('../parseTriggers');\n+var EmulatorController;\n+var controller;\n+\n+function _pollOperation(service, operation) {\n+  return new RSVP.Promise(function(resolve, reject) {\n+    var poll = function() {\n+      service.operations.get({\n+        name: operation[0].name\n+      }, function(err, _operation) {\n+        if (err) {\n+          reject(err);\n+        } else if (_operation.done) {\n+        // TODO: handle deploy failures\n+          resolve(_operation.response.value);\n+        } else {\n+          setTimeout(poll, 500);\n+        }\n+      });\n+    };\n+    poll();\n+  });\n+}\n+\n+function _startEmulator(options) {\n+  try {\n+    EmulatorController = require('@google-cloud/functions-emulator/src/cli/controller');\n+  } catch (err) {\n+    var msg = err;\n+    if (process.version !== 'v6.9.1') {\n+      msg = 'Please use Node version v6.9.1, you have ' + process.version + '\\n';\n+    }\n+    utils.logWarning('Cannot start functions emulator. ' + msg);\n+    return RSVP.reject();\n+  }\n+  if (process.version !== 'v6.9.1') {\n+    utils.logWarning('The functions emulator works best with Node version v6.9.1, you have ' + process.version + '\\n');\n+  }\n+  var functionsDir = path.join(options.config.projectDir, options.config.get('functions.source'));\n+  controller = new EmulatorController({verbose: true});\n+  // TODO: pipe logs to console\n+  logger.info(chalk.bold('Functions Directory:'), options.config.get('functions.source'), '\\n');\n+\n+  return controller.start().then(function() {\n+    return controller.clear();\n+  }).then(function() {\n+    return parseTriggers(getProjectId(options), options.instance, functionsDir);\n+  // TODO: display helpful message when there are errors from trigger parsing\n+  }).then(function(triggers) {\n+    var promises = _.map(triggers, function(trigger) {\n+      if (trigger.httpsTrigger) {\n+        return controller.deploy(trigger.name, {","path":"lib/serve/functions.js","position":61,"original_position":61,"commit_id":"f78414bc3f16b4363911c710ef528c7d1c67da2e","original_commit_id":"f78414bc3f16b4363911c710ef528c7d1c67da2e","user":{"login":"mbleigh","id":1022,"avatar_url":"https://avatars3.githubusercontent.com/u/1022?v=3","gravatar_id":"","url":"https://api.github.com/users/mbleigh","html_url":"https://github.com/mbleigh","followers_url":"https://api.github.com/users/mbleigh/followers","following_url":"https://api.github.com/users/mbleigh/following{/other_user}","gists_url":"https://api.github.com/users/mbleigh/gists{/gist_id}","starred_url":"https://api.github.com/users/mbleigh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mbleigh/subscriptions","organizations_url":"https://api.github.com/users/mbleigh/orgs","repos_url":"https://api.github.com/users/mbleigh/repos","events_url":"https://api.github.com/users/mbleigh/events{/privacy}","received_events_url":"https://api.github.com/users/mbleigh/received_events","type":"User","site_admin":false},"body":"Cool! I think that's definitely worth exploring for our use case in the Firebase CLI.","created_at":"2017-05-05T17:30:21Z","updated_at":"2017-05-05T17:30:21Z","html_url":"https://github.com/firebase/firebase-tools/pull/309#discussion_r115048934","pull_request_url":"https://api.github.com/repos/firebase/firebase-tools/pulls/309","_links":{"self":{"href":"https://api.github.com/repos/firebase/firebase-tools/pulls/comments/115048934"},"html":{"href":"https://github.com/firebase/firebase-tools/pull/309#discussion_r115048934"},"pull_request":{"href":"https://api.github.com/repos/firebase/firebase-tools/pulls/309"}}},"pull_request":{"url":"https://api.github.com/repos/firebase/firebase-tools/pulls/309","id":115634217,"html_url":"https://github.com/firebase/firebase-tools/pull/309","diff_url":"https://github.com/firebase/firebase-tools/pull/309.diff","patch_url":"https://github.com/firebase/firebase-tools/pull/309.patch","issue_url":"https://api.github.com/repos/firebase/firebase-tools/issues/309","number":309,"state":"open","locked":false,"title":"Locally emulate HTTPS functions with 'firebase serve'","user":{"login":"laurenzlong","id":3990804,"avatar_url":"https://avatars3.githubusercontent.com/u/3990804?v=3","gravatar_id":"","url":"https://api.github.com/users/laurenzlong","html_url":"https://github.com/laurenzlong","followers_url":"https://api.github.com/users/laurenzlong/followers","following_url":"https://api.github.com/users/laurenzlong/following{/other_user}","gists_url":"https://api.github.com/users/laurenzlong/gists{/gist_id}","starred_url":"https://api.github.com/users/laurenzlong/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/laurenzlong/subscriptions","organizations_url":"https://api.github.com/users/laurenzlong/orgs","repos_url":"https://api.github.com/users/laurenzlong/repos","events_url":"https://api.github.com/users/laurenzlong/events{/privacy}","received_events_url":"https://api.github.com/users/laurenzlong/received_events","type":"User","site_admin":false},"body":"This PR modifies the 'firebase serve' command to not only run a local hosting server, but to also serve up HTTPS functions locally (other function trigger types coming later). It makes use of the [Google Cloud Functions Emulator](https://github.com/GoogleCloudPlatform/cloud-functions-emulator/issues/73)\r\n\r\nUsage:\r\n'firebase serve'\r\n'firebase serve --only hosting'\r\n'firebase serve --only functions'\r\n'firebase serve --except hosting'\r\n'firebase serve --except functions'\r\n\r\nLogs from emulated functions are saved in a file logs/cloud-functions-emulator.log, relative to the directory where the firebase-tools is installed. (Same behavior as [Cloud Functions Emulator](https://github.com/GoogleCloudPlatform/cloud-functions-emulator)). I will explore streaming logs in the future.\r\n\r\nThe Cloud Functions Emulator officially supports Node v6.9.1. Anything lower will not work at all, and anything above will work but may not work for certain edge case features ([example](https://github.com/GoogleCloudPlatform/cloud-functions-emulator/issues/73)). Therefore the CLI will not emulate functions if Node version is below 6.9.1, but will give a warning and still emulate the functions if the Node version is above. \r\n\r\nAttached is a screenshot of what the experience looks like. Please note that since the serve operations are kicked off in parallel, the lines may appear in different orders than they do in the screenshot, that's why I attached a line break after each line, so that no matter what order they end up being displayed in, it'll look OK. \r\n\r\nThanks @jamesdaniels for the initial exploratory work on this! \r\n\r\n![screen shot 2017-04-12 at 1 54 57 pm](https://cloud.githubusercontent.com/assets/3990804/24979046/a83b34ee-1f87-11e7-83a9-b6d42d2b3b13.png)\r\n","created_at":"2017-04-12T20:57:21Z","updated_at":"2017-05-05T17:30:21Z","closed_at":null,"merged_at":null,"merge_commit_sha":"9664807700441aea94aa057f5ded688efa133967","assignee":{"login":"mbleigh","id":1022,"avatar_url":"https://avatars3.githubusercontent.com/u/1022?v=3","gravatar_id":"","url":"https://api.github.com/users/mbleigh","html_url":"https://github.com/mbleigh","followers_url":"https://api.github.com/users/mbleigh/followers","following_url":"https://api.github.com/users/mbleigh/following{/other_user}","gists_url":"https://api.github.com/users/mbleigh/gists{/gist_id}","starred_url":"https://api.github.com/users/mbleigh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mbleigh/subscriptions","organizations_url":"https://api.github.com/users/mbleigh/orgs","repos_url":"https://api.github.com/users/mbleigh/repos","events_url":"https://api.github.com/users/mbleigh/events{/privacy}","received_events_url":"https://api.github.com/users/mbleigh/received_events","type":"User","site_admin":false},"assignees":[{"login":"mbleigh","id":1022,"avatar_url":"https://avatars3.githubusercontent.com/u/1022?v=3","gravatar_id":"","url":"https://api.github.com/users/mbleigh","html_url":"https://github.com/mbleigh","followers_url":"https://api.github.com/users/mbleigh/followers","following_url":"https://api.github.com/users/mbleigh/following{/other_user}","gists_url":"https://api.github.com/users/mbleigh/gists{/gist_id}","starred_url":"https://api.github.com/users/mbleigh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mbleigh/subscriptions","organizations_url":"https://api.github.com/users/mbleigh/orgs","repos_url":"https://api.github.com/users/mbleigh/repos","events_url":"https://api.github.com/users/mbleigh/events{/privacy}","received_events_url":"https://api.github.com/users/mbleigh/received_events","type":"User","site_admin":false}],"milestone":null,"commits_url":"https://api.github.com/repos/firebase/firebase-tools/pulls/309/commits","review_comments_url":"https://api.github.com/repos/firebase/firebase-tools/pulls/309/comments","review_comment_url":"https://api.github.com/repos/firebase/firebase-tools/pulls/comments{/number}","comments_url":"https://api.github.com/repos/firebase/firebase-tools/issues/309/comments","statuses_url":"https://api.github.com/repos/firebase/firebase-tools/statuses/f78414bc3f16b4363911c710ef528c7d1c67da2e","head":{"label":"firebase:functions-emulator","ref":"functions-emulator","sha":"f78414bc3f16b4363911c710ef528c7d1c67da2e","user":{"login":"firebase","id":1335026,"avatar_url":"https://avatars1.githubusercontent.com/u/1335026?v=3","gravatar_id":"","url":"https://api.github.com/users/firebase","html_url":"https://github.com/firebase","followers_url":"https://api.github.com/users/firebase/followers","following_url":"https://api.github.com/users/firebase/following{/other_user}","gists_url":"https://api.github.com/users/firebase/gists{/gist_id}","starred_url":"https://api.github.com/users/firebase/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/firebase/subscriptions","organizations_url":"https://api.github.com/users/firebase/orgs","repos_url":"https://api.github.com/users/firebase/repos","events_url":"https://api.github.com/users/firebase/events{/privacy}","received_events_url":"https://api.github.com/users/firebase/received_events","type":"Organization","site_admin":false},"repo":{"id":15402300,"name":"firebase-tools","full_name":"firebase/firebase-tools","owner":{"login":"firebase","id":1335026,"avatar_url":"https://avatars1.githubusercontent.com/u/1335026?v=3","gravatar_id":"","url":"https://api.github.com/users/firebase","html_url":"https://github.com/firebase","followers_url":"https://api.github.com/users/firebase/followers","following_url":"https://api.github.com/users/firebase/following{/other_user}","gists_url":"https://api.github.com/users/firebase/gists{/gist_id}","starred_url":"https://api.github.com/users/firebase/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/firebase/subscriptions","organizations_url":"https://api.github.com/users/firebase/orgs","repos_url":"https://api.github.com/users/firebase/repos","events_url":"https://api.github.com/users/firebase/events{/privacy}","received_events_url":"https://api.github.com/users/firebase/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/firebase/firebase-tools","description":"The Firebase Command Line Tools","fork":false,"url":"https://api.github.com/repos/firebase/firebase-tools","forks_url":"https://api.github.com/repos/firebase/firebase-tools/forks","keys_url":"https://api.github.com/repos/firebase/firebase-tools/keys{/key_id}","collaborators_url":"https://api.github.com/repos/firebase/firebase-tools/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/firebase/firebase-tools/teams","hooks_url":"https://api.github.com/repos/firebase/firebase-tools/hooks","issue_events_url":"https://api.github.com/repos/firebase/firebase-tools/issues/events{/number}","events_url":"https://api.github.com/repos/firebase/firebase-tools/events","assignees_url":"https://api.github.com/repos/firebase/firebase-tools/assignees{/user}","branches_url":"https://api.github.com/repos/firebase/firebase-tools/branches{/branch}","tags_url":"https://api.github.com/repos/firebase/firebase-tools/tags","blobs_url":"https://api.github.com/repos/firebase/firebase-tools/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/firebase/firebase-tools/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/firebase/firebase-tools/git/refs{/sha}","trees_url":"https://api.github.com/repos/firebase/firebase-tools/git/trees{/sha}","statuses_url":"https://api.github.com/repos/firebase/firebase-tools/statuses/{sha}","languages_url":"https://api.github.com/repos/firebase/firebase-tools/languages","stargazers_url":"https://api.github.com/repos/firebase/firebase-tools/stargazers","contributors_url":"https://api.github.com/repos/firebase/firebase-tools/contributors","subscribers_url":"https://api.github.com/repos/firebase/firebase-tools/subscribers","subscription_url":"https://api.github.com/repos/firebase/firebase-tools/subscription","commits_url":"https://api.github.com/repos/firebase/firebase-tools/commits{/sha}","git_commits_url":"https://api.github.com/repos/firebase/firebase-tools/git/commits{/sha}","comments_url":"https://api.github.com/repos/firebase/firebase-tools/comments{/number}","issue_comment_url":"https://api.github.com/repos/firebase/firebase-tools/issues/comments{/number}","contents_url":"https://api.github.com/repos/firebase/firebase-tools/contents/{+path}","compare_url":"https://api.github.com/repos/firebase/firebase-tools/compare/{base}...{head}","merges_url":"https://api.github.com/repos/firebase/firebase-tools/merges","archive_url":"https://api.github.com/repos/firebase/firebase-tools/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/firebase/firebase-tools/downloads","issues_url":"https://api.github.com/repos/firebase/firebase-tools/issues{/number}","pulls_url":"https://api.github.com/repos/firebase/firebase-tools/pulls{/number}","milestones_url":"https://api.github.com/repos/firebase/firebase-tools/milestones{/number}","notifications_url":"https://api.github.com/repos/firebase/firebase-tools/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/firebase/firebase-tools/labels{/name}","releases_url":"https://api.github.com/repos/firebase/firebase-tools/releases{/id}","deployments_url":"https://api.github.com/repos/firebase/firebase-tools/deployments","created_at":"2013-12-23T18:53:04Z","updated_at":"2017-05-05T05:57:18Z","pushed_at":"2017-05-04T23:59:52Z","git_url":"git://github.com/firebase/firebase-tools.git","ssh_url":"git@github.com:firebase/firebase-tools.git","clone_url":"https://github.com/firebase/firebase-tools.git","svn_url":"https://github.com/firebase/firebase-tools","homepage":"","size":820,"stargazers_count":448,"watchers_count":448,"language":"JavaScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":84,"mirror_url":null,"open_issues_count":66,"forks":84,"open_issues":66,"watchers":448,"default_branch":"master"}},"base":{"label":"firebase:master","ref":"master","sha":"fea7722ef3b73ab66a8250d9f067fc59684ff4f6","user":{"login":"firebase","id":1335026,"avatar_url":"https://avatars1.githubusercontent.com/u/1335026?v=3","gravatar_id":"","url":"https://api.github.com/users/firebase","html_url":"https://github.com/firebase","followers_url":"https://api.github.com/users/firebase/followers","following_url":"https://api.github.com/users/firebase/following{/other_user}","gists_url":"https://api.github.com/users/firebase/gists{/gist_id}","starred_url":"https://api.github.com/users/firebase/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/firebase/subscriptions","organizations_url":"https://api.github.com/users/firebase/orgs","repos_url":"https://api.github.com/users/firebase/repos","events_url":"https://api.github.com/users/firebase/events{/privacy}","received_events_url":"https://api.github.com/users/firebase/received_events","type":"Organization","site_admin":false},"repo":{"id":15402300,"name":"firebase-tools","full_name":"firebase/firebase-tools","owner":{"login":"firebase","id":1335026,"avatar_url":"https://avatars1.githubusercontent.com/u/1335026?v=3","gravatar_id":"","url":"https://api.github.com/users/firebase","html_url":"https://github.com/firebase","followers_url":"https://api.github.com/users/firebase/followers","following_url":"https://api.github.com/users/firebase/following{/other_user}","gists_url":"https://api.github.com/users/firebase/gists{/gist_id}","starred_url":"https://api.github.com/users/firebase/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/firebase/subscriptions","organizations_url":"https://api.github.com/users/firebase/orgs","repos_url":"https://api.github.com/users/firebase/repos","events_url":"https://api.github.com/users/firebase/events{/privacy}","received_events_url":"https://api.github.com/users/firebase/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/firebase/firebase-tools","description":"The Firebase Command Line Tools","fork":false,"url":"https://api.github.com/repos/firebase/firebase-tools","forks_url":"https://api.github.com/repos/firebase/firebase-tools/forks","keys_url":"https://api.github.com/repos/firebase/firebase-tools/keys{/key_id}","collaborators_url":"https://api.github.com/repos/firebase/firebase-tools/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/firebase/firebase-tools/teams","hooks_url":"https://api.github.com/repos/firebase/firebase-tools/hooks","issue_events_url":"https://api.github.com/repos/firebase/firebase-tools/issues/events{/number}","events_url":"https://api.github.com/repos/firebase/firebase-tools/events","assignees_url":"https://api.github.com/repos/firebase/firebase-tools/assignees{/user}","branches_url":"https://api.github.com/repos/firebase/firebase-tools/branches{/branch}","tags_url":"https://api.github.com/repos/firebase/firebase-tools/tags","blobs_url":"https://api.github.com/repos/firebase/firebase-tools/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/firebase/firebase-tools/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/firebase/firebase-tools/git/refs{/sha}","trees_url":"https://api.github.com/repos/firebase/firebase-tools/git/trees{/sha}","statuses_url":"https://api.github.com/repos/firebase/firebase-tools/statuses/{sha}","languages_url":"https://api.github.com/repos/firebase/firebase-tools/languages","stargazers_url":"https://api.github.com/repos/firebase/firebase-tools/stargazers","contributors_url":"https://api.github.com/repos/firebase/firebase-tools/contributors","subscribers_url":"https://api.github.com/repos/firebase/firebase-tools/subscribers","subscription_url":"https://api.github.com/repos/firebase/firebase-tools/subscription","commits_url":"https://api.github.com/repos/firebase/firebase-tools/commits{/sha}","git_commits_url":"https://api.github.com/repos/firebase/firebase-tools/git/commits{/sha}","comments_url":"https://api.github.com/repos/firebase/firebase-tools/comments{/number}","issue_comment_url":"https://api.github.com/repos/firebase/firebase-tools/issues/comments{/number}","contents_url":"https://api.github.com/repos/firebase/firebase-tools/contents/{+path}","compare_url":"https://api.github.com/repos/firebase/firebase-tools/compare/{base}...{head}","merges_url":"https://api.github.com/repos/firebase/firebase-tools/merges","archive_url":"https://api.github.com/repos/firebase/firebase-tools/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/firebase/firebase-tools/downloads","issues_url":"https://api.github.com/repos/firebase/firebase-tools/issues{/number}","pulls_url":"https://api.github.com/repos/firebase/firebase-tools/pulls{/number}","milestones_url":"https://api.github.com/repos/firebase/firebase-tools/milestones{/number}","notifications_url":"https://api.github.com/repos/firebase/firebase-tools/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/firebase/firebase-tools/labels{/name}","releases_url":"https://api.github.com/repos/firebase/firebase-tools/releases{/id}","deployments_url":"https://api.github.com/repos/firebase/firebase-tools/deployments","created_at":"2013-12-23T18:53:04Z","updated_at":"2017-05-05T05:57:18Z","pushed_at":"2017-05-04T23:59:52Z","git_url":"git://github.com/firebase/firebase-tools.git","ssh_url":"git@github.com:firebase/firebase-tools.git","clone_url":"https://github.com/firebase/firebase-tools.git","svn_url":"https://github.com/firebase/firebase-tools","homepage":"","size":820,"stargazers_count":448,"watchers_count":448,"language":"JavaScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":84,"mirror_url":null,"open_issues_count":66,"forks":84,"open_issues":66,"watchers":448,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/firebase/firebase-tools/pulls/309"},"html":{"href":"https://github.com/firebase/firebase-tools/pull/309"},"issue":{"href":"https://api.github.com/repos/firebase/firebase-tools/issues/309"},"comments":{"href":"https://api.github.com/repos/firebase/firebase-tools/issues/309/comments"},"review_comments":{"href":"https://api.github.com/repos/firebase/firebase-tools/pulls/309/comments"},"review_comment":{"href":"https://api.github.com/repos/firebase/firebase-tools/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/firebase/firebase-tools/pulls/309/commits"},"statuses":{"href":"https://api.github.com/repos/firebase/firebase-tools/statuses/f78414bc3f16b4363911c710ef528c7d1c67da2e"}}}}
{"actor":{"display_login":"mbleigh"}}