{"action":"created","comment":{"url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/pulls/comments/36787337","id":36787337,"diff_hunk":"@@ -0,0 +1,210 @@\n+#!/usr/bin/env python\n+\n+# Copyright 2015 The Kubernetes Authors All rights reserved.\n+#\n+# Licensed under the Apache License, Version 2.0 (the \"License\");\n+# you may not use this file except in compliance with the License.\n+# You may obtain a copy of the License at\n+#\n+#     http://www.apache.org/licenses/LICENSE-2.0\n+#\n+# Unless required by applicable law or agreed to in writing, software\n+# distributed under the License is distributed on an \"AS IS\" BASIS,\n+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+# See the License for the specific language governing permissions and\n+# limitations under the License.\n+\n+from __future__ import print_function\n+\n+import json\n+import mmap\n+import os\n+import re\n+import sys\n+import argparse\n+\n+parser = argparse.ArgumentParser()\n+parser.add_argument(\"filenames\", help=\"list of files to check, all files if unspecified\", nargs='*')\n+parser.add_argument(\"-e\", \"--skip-exceptions\", help=\"ignore hack/verify-flags/exceptions.txt and print all output\", action=\"store_true\")\n+args = parser.parse_args()\n+\n+\n+dashRE = re.compile('[-_]')\n+\n+# Cargo culted from http://stackoverflow.com/questions/898669/how-can-i-detect-if-a-file-is-binary-non-text-in-python\n+def is_binary(pathname):\n+    \"\"\"Return true if the given filename is binary.\n+    @raise EnvironmentError: if the file does not exist or cannot be accessed.\n+    @attention: found @ http://bytes.com/topic/python/answers/21222-determine-file-type-binary-text on 6/08/2010\n+    @author: Trent Mick <TrentM@ActiveState.com>\n+    @author: Jorge Orpinel <jorge@orpinel.com>\"\"\"\n+    try:\n+        f = open(pathname, 'r')\n+        CHUNKSIZE = 1024\n+        while 1:\n+            chunk = f.read(CHUNKSIZE)\n+            if '\\0' in chunk: # found null byte\n+                return True\n+            if len(chunk) < CHUNKSIZE:\n+                break # done\n+    except:\n+        return True\n+    finally:\n+        f.close()\n+    return False\n+\n+def get_all_files(rootdir):\n+    all_files = []\n+    for root, dirs, files in os.walk(rootdir):\n+        # don't visit certain dirs\n+        if 'Godeps' in dirs:\n+            dirs.remove('Godeps')\n+        if 'third_party' in dirs:\n+            dirs.remove('third_party')\n+        if '.git' in dirs:\n+            dirs.remove('.git')\n+        if 'exceptions.txt' in files:\n+            files.remove('exceptions.txt')\n+        if 'known-flags.txt' in files:\n+            files.remove('known-flags.txt')\n+\n+        for name in files:\n+            if name.endswith(\".svg\"):\n+                continue\n+            if name.endswith(\".gliffy\"):\n+                continue\n+            pathname = os.path.join(root, name)\n+            if is_binary(pathname):\n+                continue\n+            all_files.append(pathname)\n+    return all_files\n+\n+def normalize_files(rootdir, files):\n+    newfiles = []\n+    a = ['Godeps', 'third_party', 'exceptions.txt', 'known-flags.txt']\n+    for f in files:\n+        if any(x in f for x in a):\n+            continue\n+        if f.endswith(\".svg\"):\n+            continue\n+        if f.endswith(\".gliffy\"):\n+            continue\n+        newfiles.append(f)\n+    for i, f in enumerate(newfiles):\n+        if not os.path.isabs(f):\n+            newfiles[i] = os.path.join(rootdir, f)\n+    return newfiles\n+\n+def line_has_bad_flag(line, flagre):\n+    m  = flagre.search(line)\n+    if not m:\n+        return False\n+    if \"_\" in m.group(0):\n+        return True\n+    return False\n+\n+# The list of files might not be the whole repo. If someone only changed a\n+# couple of files we don't want to run all of the golang files looking for\n+# flags. Instead load the list of flags from hack/verify-flags/known-flags.txt\n+# If running the golang files finds a new flag not in that file, return an\n+# error and tell the user to add the flag to the flag list.\n+def get_flags(rootdir, files):\n+    # use a dict for uniqueness\n+    flags = {}\n+\n+    # preload the 'known' flags\n+    pathname = os.path.join(rootdir, \"hack/verify-flags/known-flags.txt\")\n+    f = open(pathname, 'r')\n+    for line in f.read().splitlines():\n+        flags[line] = True\n+    f.close()\n+\n+    fre = re.compile('Var[P]?\\([^,]*, \"([^\"]*)\"')\n+\n+    new_flags = []\n+    # walk all the files looking for any flags being declared\n+    for pathname in files:\n+        if not pathname.endswith(\".go\"):\n+            continue\n+        f = open(pathname, 'r')\n+        for line in f.read().splitlines():\n+            match = fre.search(line)\n+            if not match:\n+                continue\n+            flag = match.group(1)\n+            # if the flag doesn't have a - or _ it is not interesting\n+            if not dashRE.search(flag):\n+                continue\n+            if flag not in flags:\n+                new_flags.append(flag)\n+        f.close()\n+    if len(new_flags) != 0:\n+        print(\"Found flags in golang files not in the list of known flags. Please add these to hack/verify-flags/known-flags.txt\")\n+        print(\"%s\" % \"\\n\".join(new_flags))\n+        sys.exit(1)\n+    # change from dict to list\n+    flags = flags.keys()\n+    return flags\n+\n+def flags_to_re(flags):\n+    # turn the list of all flags we found into a regex string which will find both - and _ version\n+    flagREs = []\n+    for flag in flags:\n+        # turn all flag names into regexs which will find both types\n+        newre = dashRE.sub('[-_]', flag)\n+        flagREs.append(newre)\n+    # turn that list of regex strings into a single large RE\n+    flagRE = \"|\".join(flagREs)\n+    flagRE = re.compile(flagRE)\n+    return flagRE\n+\n+def load_exceptions(rootdir):\n+    exceptions = {}\n+    if args.skip_exceptions:\n+        return exceptions\n+    exception_filename = os.path.join(rootdir, \"hack/verify-flags/exceptions.txt\")\n+    exception_file = open(exception_filename, 'r')\n+    for exception in exception_file.read().splitlines():\n+        out = exception.split(\":\", 1)\n+        if len(out) != 2:\n+            printf(\"Invalid line in exceptions file: %s\" % exception)\n+            continue\n+        filename = out[0]\n+        line = out[1]\n+        exceptions[(filename, line)] = True","path":"hack/verify-flags-underscore.py","position":179,"original_position":174,"commit_id":"84866c10efefb4dcafbd7bc29e8cf1349adc7840","original_commit_id":"b9abb322dde3f68c21a600087e4b418d7bfefec0","user":{"login":"krousey","id":157083,"avatar_url":"https://avatars.githubusercontent.com/u/157083?v=3","gravatar_id":"","url":"https://api.github.com/users/krousey","html_url":"https://github.com/krousey","followers_url":"https://api.github.com/users/krousey/followers","following_url":"https://api.github.com/users/krousey/following{/other_user}","gists_url":"https://api.github.com/users/krousey/gists{/gist_id}","starred_url":"https://api.github.com/users/krousey/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/krousey/subscriptions","organizations_url":"https://api.github.com/users/krousey/orgs","repos_url":"https://api.github.com/users/krousey/repos","events_url":"https://api.github.com/users/krousey/events{/privacy}","received_events_url":"https://api.github.com/users/krousey/received_events","type":"User","site_admin":false},"body":"You could use a `set` instead of `dict` here.","created_at":"2015-08-11T19:25:03Z","updated_at":"2015-08-11T19:25:03Z","html_url":"https://github.com/GoogleCloudPlatform/kubernetes/pull/12419#discussion_r36787337","pull_request_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/pulls/12419","_links":{"self":{"href":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/pulls/comments/36787337"},"html":{"href":"https://github.com/GoogleCloudPlatform/kubernetes/pull/12419#discussion_r36787337"},"pull_request":{"href":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/pulls/12419"}}},"pull_request":{"url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/pulls/12419","id":41937567,"html_url":"https://github.com/GoogleCloudPlatform/kubernetes/pull/12419","diff_url":"https://github.com/GoogleCloudPlatform/kubernetes/pull/12419.diff","patch_url":"https://github.com/GoogleCloudPlatform/kubernetes/pull/12419.patch","issue_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/issues/12419","number":12419,"state":"open","locked":false,"title":"WIP: hack/verify-flags-underscore.sh","user":{"login":"eparis","id":8093535,"avatar_url":"https://avatars.githubusercontent.com/u/8093535?v=3","gravatar_id":"","url":"https://api.github.com/users/eparis","html_url":"https://github.com/eparis","followers_url":"https://api.github.com/users/eparis/followers","following_url":"https://api.github.com/users/eparis/following{/other_user}","gists_url":"https://api.github.com/users/eparis/gists{/gist_id}","starred_url":"https://api.github.com/users/eparis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/eparis/subscriptions","organizations_url":"https://api.github.com/users/eparis/orgs","repos_url":"https://api.github.com/users/eparis/repos","events_url":"https://api.github.com/users/eparis/events{/privacy}","received_events_url":"https://api.github.com/users/eparis/received_events","type":"User","site_admin":false},"body":"This is NOT ready to be merged. It depends on a number of other PRs to actually run clean. But this is the basic idea. The place I know it fails now if is flags are declared without using the \"Var\" version.  such as `cmd.Flags.().String()`. You can also see the number of 'false positives' in the repo\r\n\r\nThis works by defining two 'static' lists in hack. The first is the list\r\nof all flags in the project which use a `-` or an `_` in their name. All\r\nfiles being processed by verify-flags-underscore.py (or all files in the\r\nrepo if no filename arguments are given) will be searched for flag\r\ndeclaration using a simple regex. Its not super smart. If a flag is\r\nfound which is not in the static list it will complain/reject the commit\r\nuntil a human adds it to the list. If we do not keep a static list of\r\nflags it takes >.2 seconds to find them 'all' at runtime. Since this is\r\nrun in pre-commit saving every part of a second helps.\r\n\r\nAfter it finds all of the flags it runs all of the arguments (or all\r\nfiles in repo if no arguments) looking for usage of those flags which\r\nincludes an `_`. There are lots of places where these are false\r\npositives. For example we have a flag named oom-adj-score but the kernel\r\ncalls it oom_adj_score. To handle this we keep a second 'whitelist' of\r\nlines which are allowed to use these flag names with an `_`.\r\n\r\nRunning the entire git repo looking for flags in every golang file and\r\nlooking in every single file for bad usage takes about 8.75 seconds.\r\n\r\nRunning it in the precommit hook where we only check things that changed\r\ntakes about .06 seconds.","created_at":"2015-08-07T22:02:24Z","updated_at":"2015-08-11T19:25:03Z","closed_at":null,"merged_at":null,"merge_commit_sha":"aa040b3a1eed22c88a94f55861a4ea3a2d9cbf79","assignee":{"login":"krousey","id":157083,"avatar_url":"https://avatars.githubusercontent.com/u/157083?v=3","gravatar_id":"","url":"https://api.github.com/users/krousey","html_url":"https://github.com/krousey","followers_url":"https://api.github.com/users/krousey/followers","following_url":"https://api.github.com/users/krousey/following{/other_user}","gists_url":"https://api.github.com/users/krousey/gists{/gist_id}","starred_url":"https://api.github.com/users/krousey/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/krousey/subscriptions","organizations_url":"https://api.github.com/users/krousey/orgs","repos_url":"https://api.github.com/users/krousey/repos","events_url":"https://api.github.com/users/krousey/events{/privacy}","received_events_url":"https://api.github.com/users/krousey/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/pulls/12419/commits","review_comments_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/pulls/12419/comments","review_comment_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/pulls/comments{/number}","comments_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/issues/12419/comments","statuses_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/statuses/84866c10efefb4dcafbd7bc29e8cf1349adc7840","head":{"label":"eparis:verify-dash-wip","ref":"verify-dash-wip","sha":"84866c10efefb4dcafbd7bc29e8cf1349adc7840","user":{"login":"eparis","id":8093535,"avatar_url":"https://avatars.githubusercontent.com/u/8093535?v=3","gravatar_id":"","url":"https://api.github.com/users/eparis","html_url":"https://github.com/eparis","followers_url":"https://api.github.com/users/eparis/followers","following_url":"https://api.github.com/users/eparis/following{/other_user}","gists_url":"https://api.github.com/users/eparis/gists{/gist_id}","starred_url":"https://api.github.com/users/eparis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/eparis/subscriptions","organizations_url":"https://api.github.com/users/eparis/orgs","repos_url":"https://api.github.com/users/eparis/repos","events_url":"https://api.github.com/users/eparis/events{/privacy}","received_events_url":"https://api.github.com/users/eparis/received_events","type":"User","site_admin":false},"repo":{"id":21580815,"name":"kubernetes","full_name":"eparis/kubernetes","owner":{"login":"eparis","id":8093535,"avatar_url":"https://avatars.githubusercontent.com/u/8093535?v=3","gravatar_id":"","url":"https://api.github.com/users/eparis","html_url":"https://github.com/eparis","followers_url":"https://api.github.com/users/eparis/followers","following_url":"https://api.github.com/users/eparis/following{/other_user}","gists_url":"https://api.github.com/users/eparis/gists{/gist_id}","starred_url":"https://api.github.com/users/eparis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/eparis/subscriptions","organizations_url":"https://api.github.com/users/eparis/orgs","repos_url":"https://api.github.com/users/eparis/repos","events_url":"https://api.github.com/users/eparis/events{/privacy}","received_events_url":"https://api.github.com/users/eparis/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/eparis/kubernetes","description":"Container Cluster Manager","fork":true,"url":"https://api.github.com/repos/eparis/kubernetes","forks_url":"https://api.github.com/repos/eparis/kubernetes/forks","keys_url":"https://api.github.com/repos/eparis/kubernetes/keys{/key_id}","collaborators_url":"https://api.github.com/repos/eparis/kubernetes/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/eparis/kubernetes/teams","hooks_url":"https://api.github.com/repos/eparis/kubernetes/hooks","issue_events_url":"https://api.github.com/repos/eparis/kubernetes/issues/events{/number}","events_url":"https://api.github.com/repos/eparis/kubernetes/events","assignees_url":"https://api.github.com/repos/eparis/kubernetes/assignees{/user}","branches_url":"https://api.github.com/repos/eparis/kubernetes/branches{/branch}","tags_url":"https://api.github.com/repos/eparis/kubernetes/tags","blobs_url":"https://api.github.com/repos/eparis/kubernetes/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/eparis/kubernetes/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/eparis/kubernetes/git/refs{/sha}","trees_url":"https://api.github.com/repos/eparis/kubernetes/git/trees{/sha}","statuses_url":"https://api.github.com/repos/eparis/kubernetes/statuses/{sha}","languages_url":"https://api.github.com/repos/eparis/kubernetes/languages","stargazers_url":"https://api.github.com/repos/eparis/kubernetes/stargazers","contributors_url":"https://api.github.com/repos/eparis/kubernetes/contributors","subscribers_url":"https://api.github.com/repos/eparis/kubernetes/subscribers","subscription_url":"https://api.github.com/repos/eparis/kubernetes/subscription","commits_url":"https://api.github.com/repos/eparis/kubernetes/commits{/sha}","git_commits_url":"https://api.github.com/repos/eparis/kubernetes/git/commits{/sha}","comments_url":"https://api.github.com/repos/eparis/kubernetes/comments{/number}","issue_comment_url":"https://api.github.com/repos/eparis/kubernetes/issues/comments{/number}","contents_url":"https://api.github.com/repos/eparis/kubernetes/contents/{+path}","compare_url":"https://api.github.com/repos/eparis/kubernetes/compare/{base}...{head}","merges_url":"https://api.github.com/repos/eparis/kubernetes/merges","archive_url":"https://api.github.com/repos/eparis/kubernetes/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/eparis/kubernetes/downloads","issues_url":"https://api.github.com/repos/eparis/kubernetes/issues{/number}","pulls_url":"https://api.github.com/repos/eparis/kubernetes/pulls{/number}","milestones_url":"https://api.github.com/repos/eparis/kubernetes/milestones{/number}","notifications_url":"https://api.github.com/repos/eparis/kubernetes/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/eparis/kubernetes/labels{/name}","releases_url":"https://api.github.com/repos/eparis/kubernetes/releases{/id}","created_at":"2014-07-07T17:57:31Z","updated_at":"2015-05-11T19:55:26Z","pushed_at":"2015-08-11T19:23:06Z","git_url":"git://github.com/eparis/kubernetes.git","ssh_url":"git@github.com:eparis/kubernetes.git","clone_url":"https://github.com/eparis/kubernetes.git","svn_url":"https://github.com/eparis/kubernetes","homepage":null,"size":98309,"stargazers_count":1,"watchers_count":1,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":1,"forks":1,"open_issues":1,"watchers":1,"default_branch":"master"}},"base":{"label":"GoogleCloudPlatform:master","ref":"master","sha":"389b9657b271d023724c305ce1c1e9b29751aaef","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":20580498,"name":"kubernetes","full_name":"GoogleCloudPlatform/kubernetes","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/kubernetes","description":"Container Cluster Manager from Google","fork":false,"url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes","forks_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/forks","keys_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/keys{/key_id}","collaborators_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/teams","hooks_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/hooks","issue_events_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/issues/events{/number}","events_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/events","assignees_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/assignees{/user}","branches_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/branches{/branch}","tags_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/tags","blobs_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/git/refs{/sha}","trees_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/git/trees{/sha}","statuses_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/statuses/{sha}","languages_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/languages","stargazers_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/stargazers","contributors_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/contributors","subscribers_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/subscribers","subscription_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/subscription","commits_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/commits{/sha}","git_commits_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/git/commits{/sha}","comments_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/comments{/number}","issue_comment_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/issues/comments{/number}","contents_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/contents/{+path}","compare_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/compare/{base}...{head}","merges_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/merges","archive_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/downloads","issues_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/issues{/number}","pulls_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/pulls{/number}","milestones_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/milestones{/number}","notifications_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/labels{/name}","releases_url":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/releases{/id}","created_at":"2014-06-06T22:56:04Z","updated_at":"2015-08-11T18:15:12Z","pushed_at":"2015-08-11T19:23:16Z","git_url":"git://github.com/GoogleCloudPlatform/kubernetes.git","ssh_url":"git@github.com:GoogleCloudPlatform/kubernetes.git","clone_url":"https://github.com/GoogleCloudPlatform/kubernetes.git","svn_url":"https://github.com/GoogleCloudPlatform/kubernetes","homepage":"http://kubernetes.io","size":342326,"stargazers_count":9632,"watchers_count":9632,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":2302,"mirror_url":null,"open_issues_count":1731,"forks":2302,"open_issues":1731,"watchers":9632,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/pulls/12419"},"html":{"href":"https://github.com/GoogleCloudPlatform/kubernetes/pull/12419"},"issue":{"href":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/issues/12419"},"comments":{"href":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/issues/12419/comments"},"review_comments":{"href":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/pulls/12419/comments"},"review_comment":{"href":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/pulls/12419/commits"},"statuses":{"href":"https://api.github.com/repos/GoogleCloudPlatform/kubernetes/statuses/84866c10efefb4dcafbd7bc29e8cf1349adc7840"}}}}