{"action":"created","comment":{"url":"https://api.github.com/repos/src-d/style-analyzer/pulls/comments/228515120","pull_request_review_id":168806114,"id":228515120,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIyODUxNTEyMA==","diff_hunk":"@@ -0,0 +1,195 @@\n+\"\"\"Module for Smoke dataset evaluation.\"\"\"\n+import csv\n+from difflib import SequenceMatcher\n+import json\n+import logging\n+from pathlib import Path\n+import tempfile\n+from typing import Any, List, Mapping\n+\n+from lookout.core.analyzer import ReferencePointer\n+from lookout.core.api.service_analyzer_pb2 import Comment\n+from lookout.core.api.service_data_pb2_grpc import DataStub\n+from lookout.core.data_requests import with_changed_uasts_and_contents\n+from lookout.core.lib import files_by_language, filter_files, find_new_lines\n+from lookout.core.tests import server\n+from lookout.style.format.analyzer import FormatAnalyzer\n+from lookout.style.format.feature_extractor import FeatureExtractor\n+from lookout.style.format.model import FormatModel\n+from lookout.style.format.tests.test_analyzer_integration import TestAnalyzer\n+\n+\n+def _loss(head_lines, correct_lines, predicted_lines):\n+    def edit_distance(a, b):\n+        err = 0\n+        matcher = SequenceMatcher(a=a, b=b)\n+        matcher.ratio()\n+        for action, _, _, _, _ in matcher.get_opcodes():\n+            if action == \"equal\":\n+                continue\n+            if action == \"delete\":\n+                err += 1\n+            elif action == \"insert\":\n+                err += 1\n+            elif action == \"replace\":\n+                err += 2\n+        return err\n+\n+    return edit_distance(predicted_lines, correct_lines) / \\\n+        edit_distance(head_lines, correct_lines)\n+\n+\n+class SmokeEvalFormatAnalyser(FormatAnalyzer):\n+    \"\"\"\n+    Analyser for Smoke dataset evaluation.\n+    \"\"\"\n+\n+    REPORT_COLNAMES = [\"repo\", \"filepath\", \"style\", \"loss\"]\n+\n+    def __init__(self, model: FormatModel, url: str, config: Mapping[str, Any]) -> None:\n+        \"\"\"\n+        Construct a FormatAnalyzer.\n+\n+        :param model: FormatModel to use during pull request analysis.\n+        :param url: Git repository on which the model was trained.\n+        :param config: Configuration to use to analyze pull requests.\n+        \"\"\"\n+        super().__init__(model, url, config)\n+        self.config = self._load_analyze_config(self.config)\n+        self.report = None\n+\n+    def _dump_report(self, outputpath):\n+        with open(outputpath, \"a\") as f:\n+            writer = csv.DictWriter(f, fieldnames=self.REPORT_COLNAMES)\n+            writer.writerows(self.report)\n+\n+    @with_changed_uasts_and_contents\n+    def analyze(self, ptr_from: ReferencePointer, ptr_to: ReferencePointer,\n+                data_request_stub: DataStub, **data) -> List[Comment]:\n+        \"\"\"\n+        Analyze a set of changes from one revision to another.\n+\n+        :param ptr_from: Git repository state pointer to the base revision.\n+        :param ptr_to: Git repository state pointer to the head revision.\n+        :param data_request_stub: Connection to the Lookout data retrieval service, not used.\n+        :param data: Contains \"changes\" - the list of changes in the pointed state.\n+        :return: List of comments.\n+        \"\"\"\n+        self.report = []\n+        log = self.log\n+        changes = list(data[\"changes\"])\n+        base_files_by_lang = files_by_language(c.base for c in changes)\n+        head_files_by_lang = files_by_language(c.head for c in changes)\n+        for lang, head_files in head_files_by_lang.items():\n+            if lang not in self.model:\n+                log.warning(\"skipped %d written in %s. Rules for %s do not exist in model\",\n+                            len(head_files), lang, lang)\n+                continue\n+            rules = self.model[lang]\n+            for file in filter_files(head_files, rules.origin_config[\"line_length_limit\"], log):\n+                try:\n+                    prev_file = base_files_by_lang[lang][file.path]\n+                except KeyError:\n+                    continue\n+                else:\n+                    lines = [find_new_lines(prev_file, file)]\n+                fe = FeatureExtractor(language=lang, **rules.origin_config[\"feature_extractor\"])\n+                res = fe.extract_features([file], lines)\n+                if res is None:\n+                    log.warning(\"Failed to parse %s\", file.path)\n+                    continue\n+                X, y, vnodes_y, vnodes = res\n+                y_pred, rule_winners = rules.predict(X, vnodes_y, vnodes, lang)\n+                assert len(y) == len(y_pred)\n+\n+                correct_lines = prev_file.content.decode(\"utf-8\", \"replace\").splitlines()\n+                head_lines = file.content.decode(\"utf-8\", \"replace\").splitlines()\n+                try:\n+                    predicted_lines = self.generate_file(vnodes_y, y_pred, vnodes)\n+                    file_loss = _loss(head_lines, correct_lines, predicted_lines)\n+                except NotImplementedError as e:\n+                    self.log.warning(\"generate_file not implemented for indentation change.\")\n+                    file_loss = -1\n+                self.log.debug(\"Loss %d on file %s in the repo %s\" % (\n+                    file_loss, file.path, self.config[\"repo_name\"]))\n+                self.report.append({\"repo\": self.config[\"repo_name\"],\n+                                    \"filepath\": file.path,\n+                                    \"style\": self.config[\"style_name\"],\n+                                    \"loss\": file_loss})\n+        self._dump_report(self.config[\"report_path\"])\n+        return []\n+\n+\n+analyzer_class = SmokeEvalFormatAnalyser\n+\n+\n+def report_summary(reportpath: str) -> None:\n+    \"\"\"\n+    Print to logs report summary.\n+\n+    :param reportpath: path to report generated by `evaluate_smoke_entry`\n+    \"\"\"\n+    log = logging.getLogger(\"report_summary\")\n+    no_results = 0\n+    no_comments = 0\n+    rest_loss = 0\n+    rest_support = 0\n+    cases_number = 0\n+    with open(str(reportpath)) as index:\n+        reader = csv.DictReader(index, fieldnames=SmokeEvalFormatAnalyser.REPORT_COLNAMES)\n+        for row in reader:\n+            cases_number += 1\n+            loss = float(row[\"loss\"])\n+            if loss < 0:\n+                no_results += 1\n+            elif loss == 1:\n+                no_comments += 1\n+            else:\n+                rest_loss += loss\n+                rest_support += 1\n+    log.info(\"Cases number: %d.\", cases_number)\n+    log.info(\"Code generation not implemented for %d cases.\", no_results)\n+    log.info(\"Failed to fix any style violation for %d cases.\", no_comments)\n+    log.info(\"Loss value for the rest cases is %.4f with support %d.\",\n+             rest_loss / rest_support, rest_support)\n+\n+\n+def evaluate_smoke_entry(inputpath: str, reportpath: str) -> None:\n+    \"\"\"\n+    CLI entry point.\n+    \"\"\"\n+    log = logging.getLogger(\"evaluate_smoke\")\n+    port = server.find_port()\n+    db = tempfile.NamedTemporaryFile(dir=inputpath)\n+    fs = tempfile.TemporaryDirectory(dir=inputpath)\n+    context_manager = TestAnalyzer(\n+        port=port, db=db.name, fs=fs.name,\n+        analyzer=\"lookout.style.format.benchmarks.evaluate_smoke\").__enter__()\n+    try:\n+        inputpath = Path(inputpath)\n+        if not server.file.exists():\n+            server.fetch()\n+        index_file = inputpath / \"index.csv\"\n+        with open(str(index_file)) as index:\n+            reader = csv.DictReader(index)\n+            for row in reader:\n+                repopath = inputpath / row[\"repo\"]\n+                config_json = {\n+                    analyzer_class.name: {\n+                        \"repo_name\": row[\"repo\"],\n+                        \"style_name\": row[\"style\"],\n+                        \"report_path\": reportpath\n+                    }\n+                }\n+                server.run(\"push\", fr=row[\"from\"], to=row[\"to\"], port=port,\n+                           git_dir=str(repopath), )\n+                server.run(\"review\", fr=row[\"from\"], to=row[\"to\"], port=port,\n+                           git_dir=str(repopath),\n+                           config_json=json.dumps(config_json))\n+                pass\n+        log.info(\"Quality report saved to %s\", reportpath)\n+    finally:\n+        fs.cleanup()\n+        context_manager.__exit__(None, None, None)","path":"lookout/style/format/benchmarks/evaluate_smoke.py","position":193,"original_position":193,"commit_id":"cfa12374c9182c5095ef6de0100941527be6fccf","original_commit_id":"cfa12374c9182c5095ef6de0100941527be6fccf","user":{"login":"vmarkovtsev","id":2793551,"node_id":"MDQ6VXNlcjI3OTM1NTE=","avatar_url":"https://avatars3.githubusercontent.com/u/2793551?v=4","gravatar_id":"","url":"https://api.github.com/users/vmarkovtsev","html_url":"https://github.com/vmarkovtsev","followers_url":"https://api.github.com/users/vmarkovtsev/followers","following_url":"https://api.github.com/users/vmarkovtsev/following{/other_user}","gists_url":"https://api.github.com/users/vmarkovtsev/gists{/gist_id}","starred_url":"https://api.github.com/users/vmarkovtsev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vmarkovtsev/subscriptions","organizations_url":"https://api.github.com/users/vmarkovtsev/orgs","repos_url":"https://api.github.com/users/vmarkovtsev/repos","events_url":"https://api.github.com/users/vmarkovtsev/events{/privacy}","received_events_url":"https://api.github.com/users/vmarkovtsev/received_events","type":"User","site_admin":false},"body":"why not `with context_manager:`? It should perfectly fit","created_at":"2018-10-26T12:53:29Z","updated_at":"2018-10-26T12:54:48Z","html_url":"https://github.com/src-d/style-analyzer/pull/276#discussion_r228515120","pull_request_url":"https://api.github.com/repos/src-d/style-analyzer/pulls/276","author_association":"COLLABORATOR","_links":{"self":{"href":"https://api.github.com/repos/src-d/style-analyzer/pulls/comments/228515120"},"html":{"href":"https://github.com/src-d/style-analyzer/pull/276#discussion_r228515120"},"pull_request":{"href":"https://api.github.com/repos/src-d/style-analyzer/pulls/276"}}},"pull_request":{"url":"https://api.github.com/repos/src-d/style-analyzer/pulls/276","id":225567164,"node_id":"MDExOlB1bGxSZXF1ZXN0MjI1NTY3MTY0","html_url":"https://github.com/src-d/style-analyzer/pull/276","diff_url":"https://github.com/src-d/style-analyzer/pull/276.diff","patch_url":"https://github.com/src-d/style-analyzer/pull/276.patch","issue_url":"https://api.github.com/repos/src-d/style-analyzer/issues/276","number":276,"state":"open","locked":false,"title":"Add smoke-dataset evaluation part","user":{"login":"zurk","id":516045,"node_id":"MDQ6VXNlcjUxNjA0NQ==","avatar_url":"https://avatars1.githubusercontent.com/u/516045?v=4","gravatar_id":"","url":"https://api.github.com/users/zurk","html_url":"https://github.com/zurk","followers_url":"https://api.github.com/users/zurk/followers","following_url":"https://api.github.com/users/zurk/following{/other_user}","gists_url":"https://api.github.com/users/zurk/gists{/gist_id}","starred_url":"https://api.github.com/users/zurk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zurk/subscriptions","organizations_url":"https://api.github.com/users/zurk/orgs","repos_url":"https://api.github.com/users/zurk/repos","events_url":"https://api.github.com/users/zurk/events{/privacy}","received_events_url":"https://api.github.com/users/zurk/received_events","type":"User","site_admin":false},"body":"Work in progress!\r\nThis PR depends on a bunch of previous ones.\r\n\r\nFor now, there is only approximate architecture. All code needs to be polished.","created_at":"2018-10-24T22:13:35Z","updated_at":"2018-10-26T12:54:48Z","closed_at":null,"merged_at":null,"merge_commit_sha":"7c73c9713c4dbaa40631bd08a207f3356ee7411c","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/src-d/style-analyzer/pulls/276/commits","review_comments_url":"https://api.github.com/repos/src-d/style-analyzer/pulls/276/comments","review_comment_url":"https://api.github.com/repos/src-d/style-analyzer/pulls/comments{/number}","comments_url":"https://api.github.com/repos/src-d/style-analyzer/issues/276/comments","statuses_url":"https://api.github.com/repos/src-d/style-analyzer/statuses/cfa12374c9182c5095ef6de0100941527be6fccf","head":{"label":"zurk:feature/smoke-eval","ref":"feature/smoke-eval","sha":"cfa12374c9182c5095ef6de0100941527be6fccf","user":{"login":"zurk","id":516045,"node_id":"MDQ6VXNlcjUxNjA0NQ==","avatar_url":"https://avatars1.githubusercontent.com/u/516045?v=4","gravatar_id":"","url":"https://api.github.com/users/zurk","html_url":"https://github.com/zurk","followers_url":"https://api.github.com/users/zurk/followers","following_url":"https://api.github.com/users/zurk/following{/other_user}","gists_url":"https://api.github.com/users/zurk/gists{/gist_id}","starred_url":"https://api.github.com/users/zurk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zurk/subscriptions","organizations_url":"https://api.github.com/users/zurk/orgs","repos_url":"https://api.github.com/users/zurk/repos","events_url":"https://api.github.com/users/zurk/events{/privacy}","received_events_url":"https://api.github.com/users/zurk/received_events","type":"User","site_admin":false},"repo":{"id":143881897,"node_id":"MDEwOlJlcG9zaXRvcnkxNDM4ODE4OTc=","name":"style-analyzer","full_name":"zurk/style-analyzer","private":false,"owner":{"login":"zurk","id":516045,"node_id":"MDQ6VXNlcjUxNjA0NQ==","avatar_url":"https://avatars1.githubusercontent.com/u/516045?v=4","gravatar_id":"","url":"https://api.github.com/users/zurk","html_url":"https://github.com/zurk","followers_url":"https://api.github.com/users/zurk/followers","following_url":"https://api.github.com/users/zurk/following{/other_user}","gists_url":"https://api.github.com/users/zurk/gists{/gist_id}","starred_url":"https://api.github.com/users/zurk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zurk/subscriptions","organizations_url":"https://api.github.com/users/zurk/orgs","repos_url":"https://api.github.com/users/zurk/repos","events_url":"https://api.github.com/users/zurk/events{/privacy}","received_events_url":"https://api.github.com/users/zurk/received_events","type":"User","site_admin":false},"html_url":"https://github.com/zurk/style-analyzer","description":"Style analyzer experiments","fork":true,"url":"https://api.github.com/repos/zurk/style-analyzer","forks_url":"https://api.github.com/repos/zurk/style-analyzer/forks","keys_url":"https://api.github.com/repos/zurk/style-analyzer/keys{/key_id}","collaborators_url":"https://api.github.com/repos/zurk/style-analyzer/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/zurk/style-analyzer/teams","hooks_url":"https://api.github.com/repos/zurk/style-analyzer/hooks","issue_events_url":"https://api.github.com/repos/zurk/style-analyzer/issues/events{/number}","events_url":"https://api.github.com/repos/zurk/style-analyzer/events","assignees_url":"https://api.github.com/repos/zurk/style-analyzer/assignees{/user}","branches_url":"https://api.github.com/repos/zurk/style-analyzer/branches{/branch}","tags_url":"https://api.github.com/repos/zurk/style-analyzer/tags","blobs_url":"https://api.github.com/repos/zurk/style-analyzer/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/zurk/style-analyzer/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/zurk/style-analyzer/git/refs{/sha}","trees_url":"https://api.github.com/repos/zurk/style-analyzer/git/trees{/sha}","statuses_url":"https://api.github.com/repos/zurk/style-analyzer/statuses/{sha}","languages_url":"https://api.github.com/repos/zurk/style-analyzer/languages","stargazers_url":"https://api.github.com/repos/zurk/style-analyzer/stargazers","contributors_url":"https://api.github.com/repos/zurk/style-analyzer/contributors","subscribers_url":"https://api.github.com/repos/zurk/style-analyzer/subscribers","subscription_url":"https://api.github.com/repos/zurk/style-analyzer/subscription","commits_url":"https://api.github.com/repos/zurk/style-analyzer/commits{/sha}","git_commits_url":"https://api.github.com/repos/zurk/style-analyzer/git/commits{/sha}","comments_url":"https://api.github.com/repos/zurk/style-analyzer/comments{/number}","issue_comment_url":"https://api.github.com/repos/zurk/style-analyzer/issues/comments{/number}","contents_url":"https://api.github.com/repos/zurk/style-analyzer/contents/{+path}","compare_url":"https://api.github.com/repos/zurk/style-analyzer/compare/{base}...{head}","merges_url":"https://api.github.com/repos/zurk/style-analyzer/merges","archive_url":"https://api.github.com/repos/zurk/style-analyzer/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/zurk/style-analyzer/downloads","issues_url":"https://api.github.com/repos/zurk/style-analyzer/issues{/number}","pulls_url":"https://api.github.com/repos/zurk/style-analyzer/pulls{/number}","milestones_url":"https://api.github.com/repos/zurk/style-analyzer/milestones{/number}","notifications_url":"https://api.github.com/repos/zurk/style-analyzer/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/zurk/style-analyzer/labels{/name}","releases_url":"https://api.github.com/repos/zurk/style-analyzer/releases{/id}","deployments_url":"https://api.github.com/repos/zurk/style-analyzer/deployments","created_at":"2018-08-07T14:04:29Z","updated_at":"2018-10-17T10:33:16Z","pushed_at":"2018-10-26T10:18:24Z","git_url":"git://github.com/zurk/style-analyzer.git","ssh_url":"git@github.com:zurk/style-analyzer.git","clone_url":"https://github.com/zurk/style-analyzer.git","svn_url":"https://github.com/zurk/style-analyzer","homepage":null,"size":80086,"stargazers_count":0,"watchers_count":0,"language":"Jupyter Notebook","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"other","name":"Other","spdx_id":"NOASSERTION","url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"src-d:master","ref":"master","sha":"624a5fc858c5c987ddb656a8d9ff778f232c58f1","user":{"login":"src-d","id":15128793,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE1MTI4Nzkz","avatar_url":"https://avatars2.githubusercontent.com/u/15128793?v=4","gravatar_id":"","url":"https://api.github.com/users/src-d","html_url":"https://github.com/src-d","followers_url":"https://api.github.com/users/src-d/followers","following_url":"https://api.github.com/users/src-d/following{/other_user}","gists_url":"https://api.github.com/users/src-d/gists{/gist_id}","starred_url":"https://api.github.com/users/src-d/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/src-d/subscriptions","organizations_url":"https://api.github.com/users/src-d/orgs","repos_url":"https://api.github.com/users/src-d/repos","events_url":"https://api.github.com/users/src-d/events{/privacy}","received_events_url":"https://api.github.com/users/src-d/received_events","type":"Organization","site_admin":false},"repo":{"id":139746338,"node_id":"MDEwOlJlcG9zaXRvcnkxMzk3NDYzMzg=","name":"style-analyzer","full_name":"src-d/style-analyzer","private":false,"owner":{"login":"src-d","id":15128793,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE1MTI4Nzkz","avatar_url":"https://avatars2.githubusercontent.com/u/15128793?v=4","gravatar_id":"","url":"https://api.github.com/users/src-d","html_url":"https://github.com/src-d","followers_url":"https://api.github.com/users/src-d/followers","following_url":"https://api.github.com/users/src-d/following{/other_user}","gists_url":"https://api.github.com/users/src-d/gists{/gist_id}","starred_url":"https://api.github.com/users/src-d/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/src-d/subscriptions","organizations_url":"https://api.github.com/users/src-d/orgs","repos_url":"https://api.github.com/users/src-d/repos","events_url":"https://api.github.com/users/src-d/events{/privacy}","received_events_url":"https://api.github.com/users/src-d/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/src-d/style-analyzer","description":"Style analyzer experiments","fork":false,"url":"https://api.github.com/repos/src-d/style-analyzer","forks_url":"https://api.github.com/repos/src-d/style-analyzer/forks","keys_url":"https://api.github.com/repos/src-d/style-analyzer/keys{/key_id}","collaborators_url":"https://api.github.com/repos/src-d/style-analyzer/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/src-d/style-analyzer/teams","hooks_url":"https://api.github.com/repos/src-d/style-analyzer/hooks","issue_events_url":"https://api.github.com/repos/src-d/style-analyzer/issues/events{/number}","events_url":"https://api.github.com/repos/src-d/style-analyzer/events","assignees_url":"https://api.github.com/repos/src-d/style-analyzer/assignees{/user}","branches_url":"https://api.github.com/repos/src-d/style-analyzer/branches{/branch}","tags_url":"https://api.github.com/repos/src-d/style-analyzer/tags","blobs_url":"https://api.github.com/repos/src-d/style-analyzer/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/src-d/style-analyzer/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/src-d/style-analyzer/git/refs{/sha}","trees_url":"https://api.github.com/repos/src-d/style-analyzer/git/trees{/sha}","statuses_url":"https://api.github.com/repos/src-d/style-analyzer/statuses/{sha}","languages_url":"https://api.github.com/repos/src-d/style-analyzer/languages","stargazers_url":"https://api.github.com/repos/src-d/style-analyzer/stargazers","contributors_url":"https://api.github.com/repos/src-d/style-analyzer/contributors","subscribers_url":"https://api.github.com/repos/src-d/style-analyzer/subscribers","subscription_url":"https://api.github.com/repos/src-d/style-analyzer/subscription","commits_url":"https://api.github.com/repos/src-d/style-analyzer/commits{/sha}","git_commits_url":"https://api.github.com/repos/src-d/style-analyzer/git/commits{/sha}","comments_url":"https://api.github.com/repos/src-d/style-analyzer/comments{/number}","issue_comment_url":"https://api.github.com/repos/src-d/style-analyzer/issues/comments{/number}","contents_url":"https://api.github.com/repos/src-d/style-analyzer/contents/{+path}","compare_url":"https://api.github.com/repos/src-d/style-analyzer/compare/{base}...{head}","merges_url":"https://api.github.com/repos/src-d/style-analyzer/merges","archive_url":"https://api.github.com/repos/src-d/style-analyzer/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/src-d/style-analyzer/downloads","issues_url":"https://api.github.com/repos/src-d/style-analyzer/issues{/number}","pulls_url":"https://api.github.com/repos/src-d/style-analyzer/pulls{/number}","milestones_url":"https://api.github.com/repos/src-d/style-analyzer/milestones{/number}","notifications_url":"https://api.github.com/repos/src-d/style-analyzer/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/src-d/style-analyzer/labels{/name}","releases_url":"https://api.github.com/repos/src-d/style-analyzer/releases{/id}","deployments_url":"https://api.github.com/repos/src-d/style-analyzer/deployments","created_at":"2018-07-04T16:42:30Z","updated_at":"2018-10-26T11:45:35Z","pushed_at":"2018-10-26T11:51:36Z","git_url":"git://github.com/src-d/style-analyzer.git","ssh_url":"git@github.com:src-d/style-analyzer.git","clone_url":"https://github.com/src-d/style-analyzer.git","svn_url":"https://github.com/src-d/style-analyzer","homepage":null,"size":80088,"stargazers_count":6,"watchers_count":6,"language":"Jupyter Notebook","has_issues":true,"has_projects":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":12,"mirror_url":null,"archived":false,"open_issues_count":23,"license":{"key":"other","name":"Other","spdx_id":"NOASSERTION","url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":12,"open_issues":23,"watchers":6,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/src-d/style-analyzer/pulls/276"},"html":{"href":"https://github.com/src-d/style-analyzer/pull/276"},"issue":{"href":"https://api.github.com/repos/src-d/style-analyzer/issues/276"},"comments":{"href":"https://api.github.com/repos/src-d/style-analyzer/issues/276/comments"},"review_comments":{"href":"https://api.github.com/repos/src-d/style-analyzer/pulls/276/comments"},"review_comment":{"href":"https://api.github.com/repos/src-d/style-analyzer/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/src-d/style-analyzer/pulls/276/commits"},"statuses":{"href":"https://api.github.com/repos/src-d/style-analyzer/statuses/cfa12374c9182c5095ef6de0100941527be6fccf"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"vmarkovtsev"}}