{"action":"created","comment":{"url":"https://api.github.com/repos/uber/okbuck/pulls/comments/182628175","pull_request_review_id":113460667,"id":182628175,"diff_hunk":"@@ -0,0 +1,202 @@\n+package com.uber.okbuck.core.model.base;\n+\n+\n+import com.google.common.collect.ImmutableList;\n+import com.google.common.collect.ImmutableMap;\n+import com.google.common.collect.ImmutableSet;\n+import com.uber.okbuck.composer.java.JavaAnnotationProcessorRuleComposer;\n+import com.uber.okbuck.core.dependency.DependencyCache;\n+import com.uber.okbuck.core.dependency.DependencyUtils;\n+import com.uber.okbuck.core.util.FileUtil;\n+import com.uber.okbuck.template.core.Rule;\n+\n+import org.gradle.api.Project;\n+import org.gradle.api.artifacts.Configuration;\n+import org.gradle.api.artifacts.Dependency;\n+import org.gradle.api.artifacts.DependencySet;\n+\n+import java.io.File;\n+import java.io.FileOutputStream;\n+import java.io.IOException;\n+import java.io.OutputStream;\n+import java.util.HashMap;\n+import java.util.List;\n+import java.util.Map;\n+import java.util.Set;\n+import java.util.function.Function;\n+\n+/**\n+ * Keeps a cache of the annotation processor dependencies and its scope.\n+ */\n+public class AnnotationProcessorCache {\n+    private final static String AUTO_VALUE_GROUP = \"com.google.auto.value\";\n+    private final static String AUTO_VALUE_NAME = \"auto-value\";\n+\n+    private final Project project;\n+    private final String processorBuckFile;\n+\n+    private Map<Set<Dependency>, Scope> dependencyToScopeMap = new HashMap<>();\n+\n+    public AnnotationProcessorCache(Project project, String processorBuckFile) {\n+        this.project = project;\n+        this.processorBuckFile = processorBuckFile;\n+    }\n+\n+    /**\n+     * Get all the scopes for the specified configuration. Returns one configuration per\n+     * dependency. Will group auto value and its extensions together into one scope as well.\n+     *\n+     * @param project project on which the configuration is defined.\n+     * @param configurationString Configuration string which is used to query the deps.\n+     * @return A list of scopes generated by the configuration.\n+     */\n+    public List<Scope> getAnnotationProcessorScopes(Project project, String configurationString) {\n+        Configuration configuration = getConfiguration(project, configurationString);\n+        return getAnnotationProcessorScopes(project, configuration);\n+    }\n+\n+    /**\n+     * Get all the scopes for the specified configuration. Returns one configuration per\n+     * dependency. Will group auto value and its extensions together into one scope as well.\n+     *\n+     * @param project project on which the configuration is defined.\n+     * @param configuration Configuration which is used to query the deps.\n+     * @return A list of scopes generated by the configuration.\n+     */\n+    public List<Scope> getAnnotationProcessorScopes(Project project, Configuration configuration) {\n+        ImmutableList.Builder<Scope> scopesBuilder = ImmutableList.builder();\n+        ImmutableSet.Builder<Dependency> autoValueDependencyBuilder = ImmutableSet.builder();\n+\n+        Map<Set<Dependency>, Scope> depToScope = composeProcessors(\n+                project, configuration.getAllDependencies(), false);\n+\n+        for(Set<Dependency> dependencySet : depToScope.keySet()) {\n+            // Initialize with whether the dependency set contains any\n+            // auto value or auto-value.* dependency.\n+            boolean autoValueDependency =\n+                    dependencySet\n+                            .stream()\n+                            .anyMatch(dependency ->\n+                                    dependency.getGroup() != null &&\n+                                            dependency.getGroup().equals(AUTO_VALUE_GROUP) &&\n+                                            dependency.getName().startsWith(AUTO_VALUE_NAME));\n+\n+            Scope scope = depToScope.get(dependencySet);\n+\n+            // Whether the scope of the dependency set has any auto value extensions.\n+            if (scope.hasAutoValueExtensions()) {\n+                autoValueDependency = true;\n+            }\n+\n+            // If an auto value dependency add it to the auto value dependency builder or\n+            // add the corresponding scope to the scope builder which will be returned.\n+            if (autoValueDependency) {\n+                autoValueDependencyBuilder.addAll(dependencySet);\n+            } else {\n+                scopesBuilder.add(scope);\n+            }\n+        }\n+\n+        // Compute new scope using the auto value dependencies and add it to the scope builder.\n+        ImmutableSet<Dependency> autoValueDependencies = autoValueDependencyBuilder.build();\n+        if (autoValueDependencies.size() > 0) {\n+            scopesBuilder.addAll(composeProcessors(\n+                    project, autoValueDependencies, true).values());\n+        }\n+\n+        return scopesBuilder.build();\n+    }\n+\n+    /**\n+     * Checks if the configuration has any empty annotation processors.\n+     *\n+     * @param project project on which the configuration is defined.\n+     * @param configurationString ConfigurationString which is used to query the deps.\n+     * @return A boolean whether the configuration has any empty annotation processors.\n+     */\n+    public boolean hasEmptyAnnotationProcessors(Project project, String configurationString) {\n+        Configuration configuration = getConfiguration(project, configurationString);\n+        return hasEmptyAnnotationProcessors(project, configuration);\n+    }\n+\n+    /**\n+     * Checks if the configuration has any empty annotation processors.\n+     *\n+     * @param project project on which the configuration is defined.\n+     * @param configuration Configuration which is used to query the deps.\n+     * @return A boolean whether the configuration has any empty annotation processors.\n+     */\n+    public boolean hasEmptyAnnotationProcessors(Project project, Configuration configuration) {\n+        Map<Set<Dependency>, Scope> depToScope = composeProcessors(\n+                project, configuration.getAllDependencies(), false);\n+\n+        return depToScope\n+                .values()\n+                .stream()\n+                .anyMatch(scope -> scope.getAnnotationProcessors().isEmpty());\n+    }\n+\n+    private Map<Set<Dependency>, Scope> composeProcessors(Project project,\n+            Set<Dependency> dependencies, boolean groupDependencies) {\n+\n+        ImmutableMap.Builder<Set<Dependency>, Scope> currentBuilder = new ImmutableMap.Builder<>();\n+\n+        // Creates a scope using a detached configuration and the dependency set.\n+        Function<Set<Dependency>, Scope> computeScope = depSet -> {\n+            Dependency[] depArray = depSet.toArray(new Dependency[depSet.size()]);\n+            Configuration detached = project.getConfigurations().detachedConfiguration(depArray);\n+            return Scope.from(project, detached);\n+        };\n+\n+        if (groupDependencies) {\n+            ImmutableSet<Dependency> dependencySet = ImmutableSet.copyOf(dependencies);\n+            Scope scope = dependencyToScopeMap.computeIfAbsent(dependencySet, computeScope);\n+            currentBuilder.put(dependencySet, scope);\n+\n+        } else {\n+            dependencies.forEach(dependency -> {\n+                ImmutableSet<Dependency> dependencySet = ImmutableSet.of(dependency);\n+                Scope scope = dependencyToScopeMap.computeIfAbsent(dependencySet, computeScope);\n+                currentBuilder.put(dependencySet, scope);\n+            });\n+        }\n+        return currentBuilder.build();\n+    }\n+\n+    private Configuration getConfiguration(Project project, String configurationString) {\n+        Configuration configuration = DependencyUtils.useful(project, configurationString);\n+\n+        if (configuration == null) {\n+            throw new IllegalStateException(\n+                    String.format(\"No valid configuration found for '%s' in project '%s'\",\n+                            configurationString, project.getDisplayName()));\n+        }\n+        return configuration;\n+    }\n+\n+    /**\n+     * Write the buck file for the java_annotation_processor rules.\n+     */\n+    public void finalizeProcessors() {","path":"buildSrc/src/main/groovy/com/uber/okbuck/core/model/base/AnnotationProcessorCache.java","position":139,"original_position":180,"commit_id":"2c773cfc31147d6b32b7cafd091860a411dfe5f7","original_commit_id":"6a8bc7ab4f0ba0ed58a7f9e8c85b11472b613cc6","user":{"login":"raviagarwal7","id":1913956,"avatar_url":"https://avatars1.githubusercontent.com/u/1913956?v=4","gravatar_id":"","url":"https://api.github.com/users/raviagarwal7","html_url":"https://github.com/raviagarwal7","followers_url":"https://api.github.com/users/raviagarwal7/followers","following_url":"https://api.github.com/users/raviagarwal7/following{/other_user}","gists_url":"https://api.github.com/users/raviagarwal7/gists{/gist_id}","starred_url":"https://api.github.com/users/raviagarwal7/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/raviagarwal7/subscriptions","organizations_url":"https://api.github.com/users/raviagarwal7/orgs","repos_url":"https://api.github.com/users/raviagarwal7/repos","events_url":"https://api.github.com/users/raviagarwal7/events{/privacy}","received_events_url":"https://api.github.com/users/raviagarwal7/received_events","type":"User","site_admin":false},"body":"done","created_at":"2018-04-19T03:56:20Z","updated_at":"2018-04-19T03:56:21Z","html_url":"https://github.com/uber/okbuck/pull/626#discussion_r182628175","pull_request_url":"https://api.github.com/repos/uber/okbuck/pulls/626","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/uber/okbuck/pulls/comments/182628175"},"html":{"href":"https://github.com/uber/okbuck/pull/626#discussion_r182628175"},"pull_request":{"href":"https://api.github.com/repos/uber/okbuck/pulls/626"}},"in_reply_to_id":182596489},"pull_request":{"url":"https://api.github.com/repos/uber/okbuck/pulls/626","id":181669985,"html_url":"https://github.com/uber/okbuck/pull/626","diff_url":"https://github.com/uber/okbuck/pull/626.diff","patch_url":"https://github.com/uber/okbuck/pull/626.patch","issue_url":"https://api.github.com/repos/uber/okbuck/issues/626","number":626,"state":"open","locked":false,"title":"Add support for java_annotation_processor rule.","user":{"login":"raviagarwal7","id":1913956,"avatar_url":"https://avatars1.githubusercontent.com/u/1913956?v=4","gravatar_id":"","url":"https://api.github.com/users/raviagarwal7","html_url":"https://github.com/raviagarwal7","followers_url":"https://api.github.com/users/raviagarwal7/followers","following_url":"https://api.github.com/users/raviagarwal7/following{/other_user}","gists_url":"https://api.github.com/users/raviagarwal7/gists{/gist_id}","starred_url":"https://api.github.com/users/raviagarwal7/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/raviagarwal7/subscriptions","organizations_url":"https://api.github.com/users/raviagarwal7/orgs","repos_url":"https://api.github.com/users/raviagarwal7/repos","events_url":"https://api.github.com/users/raviagarwal7/events{/privacy}","received_events_url":"https://api.github.com/users/raviagarwal7/received_events","type":"User","site_admin":false},"body":"[java_annotation_processor](https://github.com/facebook/buck/blob/master/src/com/facebook/buck/jvm/java/JavaAnnotationProcessorDescription.java) rule allows to share classloaders across different runs for improved build times.\r\n\r\nGenerates processors rules in `.okbuck/cache/processor/BUCK` file. \r\n\r\nBuild rules gets populated with `plugins` parameter instead of `annotation_processors`.\r\n\r\nEnable using the experimental extension:\r\n```\r\nokuck {\r\n  experimental {\r\n    useAnnotationProcessorPlugin = true\r\n  }\r\n}\r\n```\r\n\r\nVerified that the buck files remains the same before and after the change with `useAnnotationProcessorPlugin` set to false.","created_at":"2018-04-14T22:22:43Z","updated_at":"2018-04-19T03:56:21Z","closed_at":null,"merged_at":null,"merge_commit_sha":"6174ae49de2b21b11eb27cbffdaf473f2ce6cad1","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/uber/okbuck/pulls/626/commits","review_comments_url":"https://api.github.com/repos/uber/okbuck/pulls/626/comments","review_comment_url":"https://api.github.com/repos/uber/okbuck/pulls/comments{/number}","comments_url":"https://api.github.com/repos/uber/okbuck/issues/626/comments","statuses_url":"https://api.github.com/repos/uber/okbuck/statuses/2c773cfc31147d6b32b7cafd091860a411dfe5f7","head":{"label":"uber:ravi/annotation","ref":"ravi/annotation","sha":"2c773cfc31147d6b32b7cafd091860a411dfe5f7","user":{"login":"uber","id":538264,"avatar_url":"https://avatars3.githubusercontent.com/u/538264?v=4","gravatar_id":"","url":"https://api.github.com/users/uber","html_url":"https://github.com/uber","followers_url":"https://api.github.com/users/uber/followers","following_url":"https://api.github.com/users/uber/following{/other_user}","gists_url":"https://api.github.com/users/uber/gists{/gist_id}","starred_url":"https://api.github.com/users/uber/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uber/subscriptions","organizations_url":"https://api.github.com/users/uber/orgs","repos_url":"https://api.github.com/users/uber/repos","events_url":"https://api.github.com/users/uber/events{/privacy}","received_events_url":"https://api.github.com/users/uber/received_events","type":"Organization","site_admin":false},"repo":{"id":43598554,"name":"okbuck","full_name":"uber/okbuck","owner":{"login":"uber","id":538264,"avatar_url":"https://avatars3.githubusercontent.com/u/538264?v=4","gravatar_id":"","url":"https://api.github.com/users/uber","html_url":"https://github.com/uber","followers_url":"https://api.github.com/users/uber/followers","following_url":"https://api.github.com/users/uber/following{/other_user}","gists_url":"https://api.github.com/users/uber/gists{/gist_id}","starred_url":"https://api.github.com/users/uber/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uber/subscriptions","organizations_url":"https://api.github.com/users/uber/orgs","repos_url":"https://api.github.com/users/uber/repos","events_url":"https://api.github.com/users/uber/events{/privacy}","received_events_url":"https://api.github.com/users/uber/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/uber/okbuck","description":"OkBuck is a gradle plugin that lets developers utilize the Buck build system on a gradle project.","fork":false,"url":"https://api.github.com/repos/uber/okbuck","forks_url":"https://api.github.com/repos/uber/okbuck/forks","keys_url":"https://api.github.com/repos/uber/okbuck/keys{/key_id}","collaborators_url":"https://api.github.com/repos/uber/okbuck/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/uber/okbuck/teams","hooks_url":"https://api.github.com/repos/uber/okbuck/hooks","issue_events_url":"https://api.github.com/repos/uber/okbuck/issues/events{/number}","events_url":"https://api.github.com/repos/uber/okbuck/events","assignees_url":"https://api.github.com/repos/uber/okbuck/assignees{/user}","branches_url":"https://api.github.com/repos/uber/okbuck/branches{/branch}","tags_url":"https://api.github.com/repos/uber/okbuck/tags","blobs_url":"https://api.github.com/repos/uber/okbuck/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/uber/okbuck/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/uber/okbuck/git/refs{/sha}","trees_url":"https://api.github.com/repos/uber/okbuck/git/trees{/sha}","statuses_url":"https://api.github.com/repos/uber/okbuck/statuses/{sha}","languages_url":"https://api.github.com/repos/uber/okbuck/languages","stargazers_url":"https://api.github.com/repos/uber/okbuck/stargazers","contributors_url":"https://api.github.com/repos/uber/okbuck/contributors","subscribers_url":"https://api.github.com/repos/uber/okbuck/subscribers","subscription_url":"https://api.github.com/repos/uber/okbuck/subscription","commits_url":"https://api.github.com/repos/uber/okbuck/commits{/sha}","git_commits_url":"https://api.github.com/repos/uber/okbuck/git/commits{/sha}","comments_url":"https://api.github.com/repos/uber/okbuck/comments{/number}","issue_comment_url":"https://api.github.com/repos/uber/okbuck/issues/comments{/number}","contents_url":"https://api.github.com/repos/uber/okbuck/contents/{+path}","compare_url":"https://api.github.com/repos/uber/okbuck/compare/{base}...{head}","merges_url":"https://api.github.com/repos/uber/okbuck/merges","archive_url":"https://api.github.com/repos/uber/okbuck/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/uber/okbuck/downloads","issues_url":"https://api.github.com/repos/uber/okbuck/issues{/number}","pulls_url":"https://api.github.com/repos/uber/okbuck/pulls{/number}","milestones_url":"https://api.github.com/repos/uber/okbuck/milestones{/number}","notifications_url":"https://api.github.com/repos/uber/okbuck/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/uber/okbuck/labels{/name}","releases_url":"https://api.github.com/repos/uber/okbuck/releases{/id}","deployments_url":"https://api.github.com/repos/uber/okbuck/deployments","created_at":"2015-10-03T12:36:22Z","updated_at":"2018-04-19T01:55:12Z","pushed_at":"2018-04-19T03:54:24Z","git_url":"git://github.com/uber/okbuck.git","ssh_url":"git@github.com:uber/okbuck.git","clone_url":"https://github.com/uber/okbuck.git","svn_url":"https://github.com/uber/okbuck","homepage":"","size":16684,"stargazers_count":1192,"watchers_count":1192,"language":"Java","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":117,"mirror_url":null,"archived":false,"open_issues_count":23,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit"},"forks":117,"open_issues":23,"watchers":1192,"default_branch":"master"}},"base":{"label":"uber:master","ref":"master","sha":"75ae6d6baedb99b72fe577e50b867d718de7faab","user":{"login":"uber","id":538264,"avatar_url":"https://avatars3.githubusercontent.com/u/538264?v=4","gravatar_id":"","url":"https://api.github.com/users/uber","html_url":"https://github.com/uber","followers_url":"https://api.github.com/users/uber/followers","following_url":"https://api.github.com/users/uber/following{/other_user}","gists_url":"https://api.github.com/users/uber/gists{/gist_id}","starred_url":"https://api.github.com/users/uber/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uber/subscriptions","organizations_url":"https://api.github.com/users/uber/orgs","repos_url":"https://api.github.com/users/uber/repos","events_url":"https://api.github.com/users/uber/events{/privacy}","received_events_url":"https://api.github.com/users/uber/received_events","type":"Organization","site_admin":false},"repo":{"id":43598554,"name":"okbuck","full_name":"uber/okbuck","owner":{"login":"uber","id":538264,"avatar_url":"https://avatars3.githubusercontent.com/u/538264?v=4","gravatar_id":"","url":"https://api.github.com/users/uber","html_url":"https://github.com/uber","followers_url":"https://api.github.com/users/uber/followers","following_url":"https://api.github.com/users/uber/following{/other_user}","gists_url":"https://api.github.com/users/uber/gists{/gist_id}","starred_url":"https://api.github.com/users/uber/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uber/subscriptions","organizations_url":"https://api.github.com/users/uber/orgs","repos_url":"https://api.github.com/users/uber/repos","events_url":"https://api.github.com/users/uber/events{/privacy}","received_events_url":"https://api.github.com/users/uber/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/uber/okbuck","description":"OkBuck is a gradle plugin that lets developers utilize the Buck build system on a gradle project.","fork":false,"url":"https://api.github.com/repos/uber/okbuck","forks_url":"https://api.github.com/repos/uber/okbuck/forks","keys_url":"https://api.github.com/repos/uber/okbuck/keys{/key_id}","collaborators_url":"https://api.github.com/repos/uber/okbuck/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/uber/okbuck/teams","hooks_url":"https://api.github.com/repos/uber/okbuck/hooks","issue_events_url":"https://api.github.com/repos/uber/okbuck/issues/events{/number}","events_url":"https://api.github.com/repos/uber/okbuck/events","assignees_url":"https://api.github.com/repos/uber/okbuck/assignees{/user}","branches_url":"https://api.github.com/repos/uber/okbuck/branches{/branch}","tags_url":"https://api.github.com/repos/uber/okbuck/tags","blobs_url":"https://api.github.com/repos/uber/okbuck/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/uber/okbuck/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/uber/okbuck/git/refs{/sha}","trees_url":"https://api.github.com/repos/uber/okbuck/git/trees{/sha}","statuses_url":"https://api.github.com/repos/uber/okbuck/statuses/{sha}","languages_url":"https://api.github.com/repos/uber/okbuck/languages","stargazers_url":"https://api.github.com/repos/uber/okbuck/stargazers","contributors_url":"https://api.github.com/repos/uber/okbuck/contributors","subscribers_url":"https://api.github.com/repos/uber/okbuck/subscribers","subscription_url":"https://api.github.com/repos/uber/okbuck/subscription","commits_url":"https://api.github.com/repos/uber/okbuck/commits{/sha}","git_commits_url":"https://api.github.com/repos/uber/okbuck/git/commits{/sha}","comments_url":"https://api.github.com/repos/uber/okbuck/comments{/number}","issue_comment_url":"https://api.github.com/repos/uber/okbuck/issues/comments{/number}","contents_url":"https://api.github.com/repos/uber/okbuck/contents/{+path}","compare_url":"https://api.github.com/repos/uber/okbuck/compare/{base}...{head}","merges_url":"https://api.github.com/repos/uber/okbuck/merges","archive_url":"https://api.github.com/repos/uber/okbuck/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/uber/okbuck/downloads","issues_url":"https://api.github.com/repos/uber/okbuck/issues{/number}","pulls_url":"https://api.github.com/repos/uber/okbuck/pulls{/number}","milestones_url":"https://api.github.com/repos/uber/okbuck/milestones{/number}","notifications_url":"https://api.github.com/repos/uber/okbuck/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/uber/okbuck/labels{/name}","releases_url":"https://api.github.com/repos/uber/okbuck/releases{/id}","deployments_url":"https://api.github.com/repos/uber/okbuck/deployments","created_at":"2015-10-03T12:36:22Z","updated_at":"2018-04-19T01:55:12Z","pushed_at":"2018-04-19T03:54:24Z","git_url":"git://github.com/uber/okbuck.git","ssh_url":"git@github.com:uber/okbuck.git","clone_url":"https://github.com/uber/okbuck.git","svn_url":"https://github.com/uber/okbuck","homepage":"","size":16684,"stargazers_count":1192,"watchers_count":1192,"language":"Java","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":117,"mirror_url":null,"archived":false,"open_issues_count":23,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit"},"forks":117,"open_issues":23,"watchers":1192,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/uber/okbuck/pulls/626"},"html":{"href":"https://github.com/uber/okbuck/pull/626"},"issue":{"href":"https://api.github.com/repos/uber/okbuck/issues/626"},"comments":{"href":"https://api.github.com/repos/uber/okbuck/issues/626/comments"},"review_comments":{"href":"https://api.github.com/repos/uber/okbuck/pulls/626/comments"},"review_comment":{"href":"https://api.github.com/repos/uber/okbuck/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/uber/okbuck/pulls/626/commits"},"statuses":{"href":"https://api.github.com/repos/uber/okbuck/statuses/2c773cfc31147d6b32b7cafd091860a411dfe5f7"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"raviagarwal7"}}