{"action":"created","comment":{"url":"https://api.github.com/repos/Ericsson/codechecker/pulls/comments/111133367","pull_request_review_id":32355656,"id":111133367,"diff_hunk":"@@ -0,0 +1,434 @@\n+# -------------------------------------------------------------------------\n+#                     The CodeChecker Infrastructure\n+#   This file is distributed under the University of Illinois Open Source\n+#   License. See LICENSE.TXT for details.\n+# -------------------------------------------------------------------------\n+\"\"\"\n+Parsers for the analyzer output formats (plist ...) should create this\n+Report which will be stored.\n+\n+Multiple bug identification hash-es can be generated.\n+All hash generation algorithms should be documented and implemented here.\n+\n+\"\"\"\n+import hashlib\n+import linecache\n+import os\n+\n+from libcodechecker.logger import LoggerFactory\n+\n+LOG = LoggerFactory.get_new_logger('REPORT')\n+\n+\n+class Report(object):\n+    \"\"\"\n+    The report with all information parsed from the analyzers output files.\n+    One reports includes multiple diagnostic sections.\n+\n+    The diagnostic sections can build up a bug path or can be standalone.\n+\n+    There should be at least a main diagnostic section in each report.\n+\n+    There are multiple ids to identify a report.\n+\n+    report_id\n+      * Should be unique it is a combination of the bug hash and the path hash.\n+\n+    report_hash\n+      * A unique identifier should be generate by the analyzer if not this\n+        module generates an identifier based on the bug path if available.\n+\n+    obsolate_report_hash\n+      * There is already an algorithm to generate a unique identifier which\n+        should be changed and not used after v6.0.\n+\n+    \"\"\"\n+\n+    def __init__(self, checker_name, report_hash=None,\n+                 category=None, type=None):\n+\n+        self.checker_name = checker_name\n+        self.category = category\n+        self.type = type\n+        self.__hash_value = report_hash\n+\n+        # The main diag section for the report.\n+        self.__main_section = None\n+        # Diag sections without a path.\n+        self.__diag_sections = []\n+        # An optional bug path.\n+        self.__bug_path = None\n+\n+    def diag_sections(self):\n+        return self.__diag_sections\n+\n+    @property\n+    def file_path(self):\n+        self.__main_section.start_range.begin.file_path\n+\n+    @property\n+    def main_section(self):\n+        \"\"\"\n+        Main section after v6.0.\n+        \"\"\"\n+        return self.__main_section\n+\n+    @main_section.setter\n+    def main_section(self, main_section):\n+        self.__main_section = main_section\n+\n+    @property\n+    def obsolate_main_section(self):\n+        \"\"\"\n+        Main section before v6.0.\n+        \"\"\"\n+        return self.__bug_path.get_diag_sections()[-1]\n+\n+    def add_diag_section(self, section):\n+        self.__diag_sections.append(section)\n+\n+    def set_path(self, bug_path):\n+        self.__bug_path = bug_path\n+\n+    def get_path(self):\n+        return self.__bug_path\n+\n+    def report_id(self):\n+        return self.hash_value + \"||\" + self.__bug_path.path_hash\n+\n+    @property\n+    def report_hash(self):\n+        \"\"\"\n+        If hash value is not set in the analyzers output generate a new.\n+        \"\"\"\n+        if not self.__hash_value:\n+            # NOTE  uses a different algorithm compared to obsolate hash.\n+            self.__hash_value = self.__gen_report_hash()\n+\n+        return self.__hash_value\n+\n+    def events(self):\n+        # TODO: FOR STORAGE BACKWARD COMPATIBILITY REMOVE AFTER v6.0\n+        return [x for x in self.__bug_path.get_diag_sections() if\n+                x.kind == \"event\"]\n+\n+    def paths(self):\n+        # TODO: FOR STORAGE BACKWARD COMPATIBILITY REMOVE AFTER v6.0\n+        return [x for x in self.__bug_path.get_diag_sections() if\n+                x.kind == \"control\"]\n+\n+    @property\n+    def hash_value(self):\n+        # TODO: FOR STORAGE BACKWARD COMPATIBILITY REMOVE AFTER v6.0\n+        hash = self.__hash_value\n+        if not hash:\n+            hash = self.__obsolate_hash()\n+        return hash\n+\n+    def __obsolate_hash(self):\n+        \"\"\"\n+        !!! Compatible with the old hash before v6.0\n+\n+        Keep this until needed for transformation tools from the old\n+        hash to the new hash.\n+\n+        Hash generation algoritm for older plist versions where no\n+        issue hash was generated or for the plists generated\n+        from clang-tidy where the issue hash generation feature\n+        is still missing.\n+\n+        As the main diagnositc section the last element from the\n+        bug path is used.\n+\n+        Hash content:\n+         * file_name from the main diag section.\n+         * checker name\n+         * checker message\n+         * line content from the source file if can be read up\n+         * column numbers from the main diag section\n+         * range column numbers only from the control diag sections if\n+           column number in the range is not the same as the previous\n+           control diag section number in the bug path\n+\n+        \"\"\"\n+        # The last diag section from the bug path used as a main\n+        # diagnostic section.\n+        mds = self.__bug_path.get_diag_sections()[-1]\n+\n+        source_file = mds.location.file_path\n+        source_line = mds.location.line\n+\n+        from_col = mds.location.col\n+        until_col = mds.location.col\n+\n+        line_content = linecache.getline(source_file, source_line)\n+\n+        if line_content == '' and not os.path.isfile(source_file):\n+            LOG.debug(\"Failed to generate report hash.\")\n+            LOG.debug('%s does not exists!' % source_file)\n+\n+        file_name = os.path.basename(source_file)\n+        msg = mds.msg\n+\n+        hash_content = [file_name,\n+                        self.checker_name,\n+                        msg,\n+                        line_content,\n+                        str(from_col),\n+                        str(until_col)]\n+\n+        diag_sections = self.__bug_path.get_diag_sections()\n+\n+        ctrl_sections = [x for x in diag_sections if x.kind == \"control\"]\n+\n+        for i, diag_section in enumerate(ctrl_sections):\n+            ds_start_range = diag_section.start_range\n+            if i > 0:\n+                prev = ctrl_sections[i-1]\n+                if ds_start_range.begin != prev.end_range.begin and \\\n+                        ds_start_range.end != prev.end_range.end:\n+                    hash_content.append(str(ds_start_range.begin.col))\n+                    hash_content.append(str(ds_start_range.end.col))\n+            else:\n+                hash_content.append(str(ds_start_range.begin.col))\n+                hash_content.append(str(ds_start_range.end.col))\n+\n+            hash_content.append(str(diag_section.end_range.begin.col))\n+            hash_content.append(str(diag_section.end_range.end.col))\n+\n+        string_to_hash = '|||'.join(hash_content)\n+\n+        return hashlib.md5(string_to_hash.encode()).hexdigest()\n+\n+    def __gen_report_hash(self):\n+        \"\"\"\n+        Generate a report hash if the analyzer failed to generate\n+        or not supported by the analyzer.\n+        \"\"\"\n+        # TODO: REVIEW IS NEEDED WHAT TO INCLUDE IN THE HASH.\n+        # NOTE: DO NOT USE UNTIL COMMENT IS REMOVED!\n+\n+        source_file = self.main_section.start_range.begin.file_path\n+        source_line = self.main_section.start_range.begin.line\n+\n+        from_col = self.main_section.start_range.begin.col\n+        until_col = self.main_section.end_range.begin.col\n+\n+        from_col = self.main_section.location.col\n+        until_col = self.main_section.location.col\n+\n+        line_content = linecache.getline(source_file, source_line)\n+\n+        if line_content == '' and not os.path.isfile(source_file):\n+            LOG.error(\"Failed to generate report hash.\")\n+            LOG.error('%s does not exists!' % source_file)\n+\n+        file_name = os.path.basename(source_file)\n+        msg = self.main_section.msg\n+\n+        # Add the main diag section for the hash content.\n+        hash_content = [file_name,\n+                        self.checker_name,\n+                        msg,\n+                        line_content,\n+                        str(from_col),\n+                        str(until_col)]\n+\n+        diag_sections = self.__bug_path.get_diag_sections()\n+\n+        # Add only the control diag section column numbers to the hash content.\n+        ctrl_sections = [x for x in diag_sections if x.kind == \"control\"]\n+\n+        for diag_section in ctrl_sections:\n+            hash_content.append(str(diag_section.start_range.begin.col))\n+            hash_content.append(str(diag_section.start_range.end.col))\n+            hash_content.append(str(diag_section.end_range.begin.col))\n+            hash_content.append(str(diag_section.end_range.end.col))\n+\n+        string_to_hash = '|||'.join(hash_content)\n+\n+        bug_hash = hashlib.md5(string_to_hash.encode()).hexdigest()\n+        return bug_hash\n+\n+\n+class GenericEquality(object):\n+\n+    def __eq__(self, other):\n+        return (isinstance(other, self.__class__) and\n+                self.__dict__ == other.__dict__)\n+\n+    def __ne__(self, other):\n+        return not self.__eq__(other)\n+\n+\n+class Position(GenericEquality):\n+    \"\"\"\n+    Represent a postion in a source file.\n+    \"\"\"\n+\n+    def __init__(self, line, col, filepath):\n+        self.line = line\n+        self.col = col\n+        self.file_path = filepath\n+\n+    def __str__(self):\n+        msg = \"@\"+str(self.line)+\":\"+str(self.col)+\"::\"+str(self.file_path)\n+        return msg\n+\n+\n+class Range(object):\n+    \"\"\"\n+    Two positions build a range.\n+    \"\"\"\n+    def __init__(self, begin, end=None):\n+        self.__begin = begin\n+        if end:\n+            self.__end = end\n+        else:\n+            self.__end = begin\n+\n+    def __str__(self):\n+        msg = \"[\"+str(self.__begin) + \"][\" + str(self.__end)+\"]\"\n+        return msg\n+\n+    @property\n+    def begin(self):\n+        return self.__begin\n+\n+    @property\n+    def end(self):\n+        return self.__end\n+\n+\n+class BugPath(object):\n+    \"\"\"\n+    Represents a bug path which contains multiple DiagSections.\n+    The order of the diagnostic sections in the bug path matters, and\n+    needed for the storage in the database and for the UI to\n+    render arrows properly.\n+    \"\"\"\n+    def __init__(self, diag_sections):\n+        self.__diag_sections = diag_sections\n+        self.__path_length = 0\n+        # Initialize path positions.\n+        for i, ds in enumerate(self.__diag_sections):\n+            self.__diag_sections[i].path_position = i\n+\n+    def get_diag_sections(self):\n+        return self.__diag_sections\n+\n+    def len(self):\n+        \"\"\"\n+        Contains all the control and event diag sections!\n+        \"\"\"\n+        return len(self.__diag_sections)\n+\n+    @property\n+    def path_hash(self):\n+        \"\"\"\n+        Generate a unique id for a bug path.\n+\n+        * Used to identify a bug path if the report_hash is not unique enough.\n+        * It is possible that the same hash is generated for different reports\n+          where the bug paths are different to identify these cases a\n+          separate path hash is generated (starts in separate cpp files but\n+          ends in the same header).\n+        \"\"\"\n+        # TODO: Review hash generation method this is just an initial version.\n+        # Hash is generated now based on columm numbers from the diag sections\n+        # in a bug path.\n+        # At least one event should be in the bug path.\n+        # NOTE: Events might only have only a location and\n+        # no range information.\n+        if not self.__path_hash:\n+            path = \"\"\n+            for ds in self.__diag_sections:\n+                path += str(ds.start_range.begin.col) + \\\n+                    str(ds.end_range.begin.col) + \\\n+                    ds.msg + ds.start_range.begin.file_path\n+            self.__path_length = hashlib.sha1(path).hexdigest()\n+\n+        return self.__path_hash\n+\n+\n+class DiagSection(GenericEquality):\n+    \"\"\"\n+    Diagnostic section can have a start and an end position.\n+    If position_in_path is set this section belongs to a BugPath.\n+    It is possible that a DiagSection is a standalone \"message\" or\n+    \"warning\" by the analyzer and does not belong to BugPath.\n+\n+    See storage thrift api desctiption for kinds.\n+    \"\"\"\n+\n+    def __init__(self, kind='', msg=''):\n+\n+        self.__start_range = None\n+        self.__end_range = None\n+        self.__msg = msg\n+        self.__extended_msg = ''\n+        self.__kind = kind\n+\n+        # One Position.\n+        self.__location = None  # Optional in some cases only range is\n+        # available\n+\n+        # Position in the path is just and integer if\n+        # not set DiagSection is not part of a path.\n+        self.__position_in_path = None\n+\n+    @property\n+    def kind(self):\n+        return self.__kind\n+\n+    @property\n+    def start_range(self):\n+        return self.__start_range\n+\n+    @start_range.setter\n+    def start_range(self, range):\n+        self.__start_range = range\n+\n+    @property\n+    def end_range(self):","path":"libcodechecker/report.py","position":393,"original_position":393,"commit_id":"e1d8f4ded1a76231d6b2d18c541a8e536b622bcb","original_commit_id":"e1d8f4ded1a76231d6b2d18c541a8e536b622bcb","user":{"login":"Xazax-hun","id":922897,"avatar_url":"https://avatars2.githubusercontent.com/u/922897?v=3","gravatar_id":"","url":"https://api.github.com/users/Xazax-hun","html_url":"https://github.com/Xazax-hun","followers_url":"https://api.github.com/users/Xazax-hun/followers","following_url":"https://api.github.com/users/Xazax-hun/following{/other_user}","gists_url":"https://api.github.com/users/Xazax-hun/gists{/gist_id}","starred_url":"https://api.github.com/users/Xazax-hun/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Xazax-hun/subscriptions","organizations_url":"https://api.github.com/users/Xazax-hun/orgs","repos_url":"https://api.github.com/users/Xazax-hun/repos","events_url":"https://api.github.com/users/Xazax-hun/events{/privacy}","received_events_url":"https://api.github.com/users/Xazax-hun/received_events","type":"User","site_admin":false},"body":"do we want to have getters/setter for these trivial members?","created_at":"2017-04-12T12:18:51Z","updated_at":"2017-04-12T12:18:51Z","html_url":"https://github.com/Ericsson/codechecker/pull/628#discussion_r111133367","pull_request_url":"https://api.github.com/repos/Ericsson/codechecker/pulls/628","_links":{"self":{"href":"https://api.github.com/repos/Ericsson/codechecker/pulls/comments/111133367"},"html":{"href":"https://github.com/Ericsson/codechecker/pull/628#discussion_r111133367"},"pull_request":{"href":"https://api.github.com/repos/Ericsson/codechecker/pulls/628"}}},"pull_request":{"url":"https://api.github.com/repos/Ericsson/codechecker/pulls/628","id":115149894,"html_url":"https://github.com/Ericsson/codechecker/pull/628","diff_url":"https://github.com/Ericsson/codechecker/pull/628.diff","patch_url":"https://github.com/Ericsson/codechecker/pull/628.patch","issue_url":"https://api.github.com/repos/Ericsson/codechecker/issues/628","number":628,"state":"open","locked":false,"title":"Extend/refactor plist parser module","user":{"login":"gyorb","id":10214062,"avatar_url":"https://avatars1.githubusercontent.com/u/10214062?v=3","gravatar_id":"","url":"https://api.github.com/users/gyorb","html_url":"https://github.com/gyorb","followers_url":"https://api.github.com/users/gyorb/followers","following_url":"https://api.github.com/users/gyorb/following{/other_user}","gists_url":"https://api.github.com/users/gyorb/gists{/gist_id}","starred_url":"https://api.github.com/users/gyorb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gyorb/subscriptions","organizations_url":"https://api.github.com/users/gyorb/orgs","repos_url":"https://api.github.com/users/gyorb/repos","events_url":"https://api.github.com/users/gyorb/events{/privacy}","received_events_url":"https://api.github.com/users/gyorb/received_events","type":"User","site_admin":false},"body":"* Intoduce new types for Reports, Ranges, Positions, DiagSections\r\n\r\n* The main event is handled separately from the other events in a\r\n  bug path. Main event should be always available.\r\n\r\n* DiagSections store diagnostic related informations from the\r\n  analyzers (can be part of a path or a standalone information).\r\n  Usually a position/range in the source file and optional message.\r\n\r\n* Multiple hash generation options introduced for later versions.\r\n  Old hash generation is still supported for backward compatibility.\r\n\r\n* New unit test files for Clang 4.0 and 5.0 plist formats Resolves: #445","created_at":"2017-04-10T17:18:40Z","updated_at":"2017-04-12T12:18:51Z","closed_at":null,"merged_at":null,"merge_commit_sha":"0f9d408cfd6f4bddd5af948d830ec76fb86df3e6","assignee":null,"assignees":[],"milestone":{"url":"https://api.github.com/repos/Ericsson/codechecker/milestones/32","html_url":"https://github.com/Ericsson/codechecker/milestone/32","labels_url":"https://api.github.com/repos/Ericsson/codechecker/milestones/32/labels","id":2240725,"number":32,"title":"release 5.8","description":"","creator":{"login":"gyorb","id":10214062,"avatar_url":"https://avatars1.githubusercontent.com/u/10214062?v=3","gravatar_id":"","url":"https://api.github.com/users/gyorb","html_url":"https://github.com/gyorb","followers_url":"https://api.github.com/users/gyorb/followers","following_url":"https://api.github.com/users/gyorb/following{/other_user}","gists_url":"https://api.github.com/users/gyorb/gists{/gist_id}","starred_url":"https://api.github.com/users/gyorb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gyorb/subscriptions","organizations_url":"https://api.github.com/users/gyorb/orgs","repos_url":"https://api.github.com/users/gyorb/repos","events_url":"https://api.github.com/users/gyorb/events{/privacy}","received_events_url":"https://api.github.com/users/gyorb/received_events","type":"User","site_admin":false},"open_issues":17,"closed_issues":18,"state":"open","created_at":"2017-01-10T13:55:48Z","updated_at":"2017-04-11T10:10:45Z","due_on":null,"closed_at":null},"commits_url":"https://api.github.com/repos/Ericsson/codechecker/pulls/628/commits","review_comments_url":"https://api.github.com/repos/Ericsson/codechecker/pulls/628/comments","review_comment_url":"https://api.github.com/repos/Ericsson/codechecker/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Ericsson/codechecker/issues/628/comments","statuses_url":"https://api.github.com/repos/Ericsson/codechecker/statuses/e1d8f4ded1a76231d6b2d18c541a8e536b622bcb","head":{"label":"gyorb:plist_parser","ref":"plist_parser","sha":"e1d8f4ded1a76231d6b2d18c541a8e536b622bcb","user":{"login":"gyorb","id":10214062,"avatar_url":"https://avatars1.githubusercontent.com/u/10214062?v=3","gravatar_id":"","url":"https://api.github.com/users/gyorb","html_url":"https://github.com/gyorb","followers_url":"https://api.github.com/users/gyorb/followers","following_url":"https://api.github.com/users/gyorb/following{/other_user}","gists_url":"https://api.github.com/users/gyorb/gists{/gist_id}","starred_url":"https://api.github.com/users/gyorb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gyorb/subscriptions","organizations_url":"https://api.github.com/users/gyorb/orgs","repos_url":"https://api.github.com/users/gyorb/repos","events_url":"https://api.github.com/users/gyorb/events{/privacy}","received_events_url":"https://api.github.com/users/gyorb/received_events","type":"User","site_admin":false},"repo":{"id":39376421,"name":"codechecker","full_name":"gyorb/codechecker","owner":{"login":"gyorb","id":10214062,"avatar_url":"https://avatars1.githubusercontent.com/u/10214062?v=3","gravatar_id":"","url":"https://api.github.com/users/gyorb","html_url":"https://github.com/gyorb","followers_url":"https://api.github.com/users/gyorb/followers","following_url":"https://api.github.com/users/gyorb/following{/other_user}","gists_url":"https://api.github.com/users/gyorb/gists{/gist_id}","starred_url":"https://api.github.com/users/gyorb/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gyorb/subscriptions","organizations_url":"https://api.github.com/users/gyorb/orgs","repos_url":"https://api.github.com/users/gyorb/repos","events_url":"https://api.github.com/users/gyorb/events{/privacy}","received_events_url":"https://api.github.com/users/gyorb/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/gyorb/codechecker","description":"CodeChecker is a defect database and viewer extension for Clang Static Analyzer","fork":true,"url":"https://api.github.com/repos/gyorb/codechecker","forks_url":"https://api.github.com/repos/gyorb/codechecker/forks","keys_url":"https://api.github.com/repos/gyorb/codechecker/keys{/key_id}","collaborators_url":"https://api.github.com/repos/gyorb/codechecker/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/gyorb/codechecker/teams","hooks_url":"https://api.github.com/repos/gyorb/codechecker/hooks","issue_events_url":"https://api.github.com/repos/gyorb/codechecker/issues/events{/number}","events_url":"https://api.github.com/repos/gyorb/codechecker/events","assignees_url":"https://api.github.com/repos/gyorb/codechecker/assignees{/user}","branches_url":"https://api.github.com/repos/gyorb/codechecker/branches{/branch}","tags_url":"https://api.github.com/repos/gyorb/codechecker/tags","blobs_url":"https://api.github.com/repos/gyorb/codechecker/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/gyorb/codechecker/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/gyorb/codechecker/git/refs{/sha}","trees_url":"https://api.github.com/repos/gyorb/codechecker/git/trees{/sha}","statuses_url":"https://api.github.com/repos/gyorb/codechecker/statuses/{sha}","languages_url":"https://api.github.com/repos/gyorb/codechecker/languages","stargazers_url":"https://api.github.com/repos/gyorb/codechecker/stargazers","contributors_url":"https://api.github.com/repos/gyorb/codechecker/contributors","subscribers_url":"https://api.github.com/repos/gyorb/codechecker/subscribers","subscription_url":"https://api.github.com/repos/gyorb/codechecker/subscription","commits_url":"https://api.github.com/repos/gyorb/codechecker/commits{/sha}","git_commits_url":"https://api.github.com/repos/gyorb/codechecker/git/commits{/sha}","comments_url":"https://api.github.com/repos/gyorb/codechecker/comments{/number}","issue_comment_url":"https://api.github.com/repos/gyorb/codechecker/issues/comments{/number}","contents_url":"https://api.github.com/repos/gyorb/codechecker/contents/{+path}","compare_url":"https://api.github.com/repos/gyorb/codechecker/compare/{base}...{head}","merges_url":"https://api.github.com/repos/gyorb/codechecker/merges","archive_url":"https://api.github.com/repos/gyorb/codechecker/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/gyorb/codechecker/downloads","issues_url":"https://api.github.com/repos/gyorb/codechecker/issues{/number}","pulls_url":"https://api.github.com/repos/gyorb/codechecker/pulls{/number}","milestones_url":"https://api.github.com/repos/gyorb/codechecker/milestones{/number}","notifications_url":"https://api.github.com/repos/gyorb/codechecker/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/gyorb/codechecker/labels{/name}","releases_url":"https://api.github.com/repos/gyorb/codechecker/releases{/id}","deployments_url":"https://api.github.com/repos/gyorb/codechecker/deployments","created_at":"2015-07-20T09:58:49Z","updated_at":"2016-01-19T18:56:32Z","pushed_at":"2017-04-12T12:11:29Z","git_url":"git://github.com/gyorb/codechecker.git","ssh_url":"git@github.com:gyorb/codechecker.git","clone_url":"https://github.com/gyorb/codechecker.git","svn_url":"https://github.com/gyorb/codechecker","homepage":null,"size":4767,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_projects":true,"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":"Ericsson:master","ref":"master","sha":"d3e53ff1254509770a7cc535a4a58b53bd9be31c","user":{"login":"Ericsson","id":4161311,"avatar_url":"https://avatars0.githubusercontent.com/u/4161311?v=3","gravatar_id":"","url":"https://api.github.com/users/Ericsson","html_url":"https://github.com/Ericsson","followers_url":"https://api.github.com/users/Ericsson/followers","following_url":"https://api.github.com/users/Ericsson/following{/other_user}","gists_url":"https://api.github.com/users/Ericsson/gists{/gist_id}","starred_url":"https://api.github.com/users/Ericsson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Ericsson/subscriptions","organizations_url":"https://api.github.com/users/Ericsson/orgs","repos_url":"https://api.github.com/users/Ericsson/repos","events_url":"https://api.github.com/users/Ericsson/events{/privacy}","received_events_url":"https://api.github.com/users/Ericsson/received_events","type":"Organization","site_admin":false},"repo":{"id":37459110,"name":"codechecker","full_name":"Ericsson/codechecker","owner":{"login":"Ericsson","id":4161311,"avatar_url":"https://avatars0.githubusercontent.com/u/4161311?v=3","gravatar_id":"","url":"https://api.github.com/users/Ericsson","html_url":"https://github.com/Ericsson","followers_url":"https://api.github.com/users/Ericsson/followers","following_url":"https://api.github.com/users/Ericsson/following{/other_user}","gists_url":"https://api.github.com/users/Ericsson/gists{/gist_id}","starred_url":"https://api.github.com/users/Ericsson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Ericsson/subscriptions","organizations_url":"https://api.github.com/users/Ericsson/orgs","repos_url":"https://api.github.com/users/Ericsson/repos","events_url":"https://api.github.com/users/Ericsson/events{/privacy}","received_events_url":"https://api.github.com/users/Ericsson/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Ericsson/codechecker","description":"CodeChecker is a defect database and viewer extension for the Clang Static Analyzer and Clang Tidy","fork":false,"url":"https://api.github.com/repos/Ericsson/codechecker","forks_url":"https://api.github.com/repos/Ericsson/codechecker/forks","keys_url":"https://api.github.com/repos/Ericsson/codechecker/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Ericsson/codechecker/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Ericsson/codechecker/teams","hooks_url":"https://api.github.com/repos/Ericsson/codechecker/hooks","issue_events_url":"https://api.github.com/repos/Ericsson/codechecker/issues/events{/number}","events_url":"https://api.github.com/repos/Ericsson/codechecker/events","assignees_url":"https://api.github.com/repos/Ericsson/codechecker/assignees{/user}","branches_url":"https://api.github.com/repos/Ericsson/codechecker/branches{/branch}","tags_url":"https://api.github.com/repos/Ericsson/codechecker/tags","blobs_url":"https://api.github.com/repos/Ericsson/codechecker/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Ericsson/codechecker/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Ericsson/codechecker/git/refs{/sha}","trees_url":"https://api.github.com/repos/Ericsson/codechecker/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Ericsson/codechecker/statuses/{sha}","languages_url":"https://api.github.com/repos/Ericsson/codechecker/languages","stargazers_url":"https://api.github.com/repos/Ericsson/codechecker/stargazers","contributors_url":"https://api.github.com/repos/Ericsson/codechecker/contributors","subscribers_url":"https://api.github.com/repos/Ericsson/codechecker/subscribers","subscription_url":"https://api.github.com/repos/Ericsson/codechecker/subscription","commits_url":"https://api.github.com/repos/Ericsson/codechecker/commits{/sha}","git_commits_url":"https://api.github.com/repos/Ericsson/codechecker/git/commits{/sha}","comments_url":"https://api.github.com/repos/Ericsson/codechecker/comments{/number}","issue_comment_url":"https://api.github.com/repos/Ericsson/codechecker/issues/comments{/number}","contents_url":"https://api.github.com/repos/Ericsson/codechecker/contents/{+path}","compare_url":"https://api.github.com/repos/Ericsson/codechecker/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Ericsson/codechecker/merges","archive_url":"https://api.github.com/repos/Ericsson/codechecker/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Ericsson/codechecker/downloads","issues_url":"https://api.github.com/repos/Ericsson/codechecker/issues{/number}","pulls_url":"https://api.github.com/repos/Ericsson/codechecker/pulls{/number}","milestones_url":"https://api.github.com/repos/Ericsson/codechecker/milestones{/number}","notifications_url":"https://api.github.com/repos/Ericsson/codechecker/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Ericsson/codechecker/labels{/name}","releases_url":"https://api.github.com/repos/Ericsson/codechecker/releases{/id}","deployments_url":"https://api.github.com/repos/Ericsson/codechecker/deployments","created_at":"2015-06-15T10:38:51Z","updated_at":"2017-04-08T17:32:10Z","pushed_at":"2017-04-12T12:11:30Z","git_url":"git://github.com/Ericsson/codechecker.git","ssh_url":"git@github.com:Ericsson/codechecker.git","clone_url":"https://github.com/Ericsson/codechecker.git","svn_url":"https://github.com/Ericsson/codechecker","homepage":"","size":4682,"stargazers_count":318,"watchers_count":318,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":29,"mirror_url":null,"open_issues_count":82,"forks":29,"open_issues":82,"watchers":318,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Ericsson/codechecker/pulls/628"},"html":{"href":"https://github.com/Ericsson/codechecker/pull/628"},"issue":{"href":"https://api.github.com/repos/Ericsson/codechecker/issues/628"},"comments":{"href":"https://api.github.com/repos/Ericsson/codechecker/issues/628/comments"},"review_comments":{"href":"https://api.github.com/repos/Ericsson/codechecker/pulls/628/comments"},"review_comment":{"href":"https://api.github.com/repos/Ericsson/codechecker/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Ericsson/codechecker/pulls/628/commits"},"statuses":{"href":"https://api.github.com/repos/Ericsson/codechecker/statuses/e1d8f4ded1a76231d6b2d18c541a8e536b622bcb"}}}}
{"actor":{"display_login":"Xazax-hun"}}