{"action":"created","comment":{"url":"https://api.github.com/repos/diffplug/spotless/pulls/comments/192446564","pull_request_review_id":125231617,"id":192446564,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDE5MjQ0NjU2NA==","diff_hunk":"@@ -0,0 +1,257 @@\n+/*\n+ * Copyright 2016 DiffPlug\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+package com.diffplug.spotless.extra.config;\n+\n+import java.io.File;\n+import java.io.IOException;\n+import java.io.Serializable;\n+import java.net.MalformedURLException;\n+import java.net.URL;\n+import java.nio.file.Path;\n+import java.nio.file.Paths;\n+import java.util.ArrayList;\n+import java.util.Objects;\n+import java.util.Properties;\n+import java.util.TreeSet;\n+import java.util.stream.Collectors;\n+\n+import com.diffplug.spotless.FileSignature;\n+import com.diffplug.spotless.FormatterProperties;\n+import com.diffplug.spotless.JarState;\n+import com.diffplug.spotless.Provisioner;\n+import com.diffplug.spotless.ThrowingEx;\n+\n+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;\n+\n+/**\n+ * Eclipse formatter generic configuration validates the user arguments and creates on request\n+ * a {@link State} of the current values.\n+ */\n+public class EclipseConfiguration implements ThrowingEx.Supplier<EclipseConfiguration.State> {\n+\t/**\n+\t * Resource location of Spotless Eclipse Formatter Maven coordinate lists.\n+\t * <p>\n+\t * Spotless Eclipse Formatter dependencies have fixed transitive versions, since Spotless Eclipse Formatter\n+\t * implementations access internal methods of the Eclipse plugins, which may change with every\n+\t * version change, including minor and patch version changes.\n+\t * At the resource location for each supported Spotless Eclipse Formatter, a text file is provided, containing\n+\t * the fixed versions for the formatter and its transitive dependencies.\n+\t * Each line in the text file corresponds to the {@link MavenCoordinates.Coordinate#FORMAT}.\n+\t * </p>\n+\t */\n+\tprivate static final String ECLIPSE_FORMATTER_RESOURCES = EclipseConfiguration.class.getPackage().getName().replace('.', '/');\n+\n+\tprivate final TreeSet<SemanticVersion> supportedEclipseVersions;\n+\tprivate final URL eclipseConfigContext;\n+\tprivate final Provisioner jarProvisioner;\n+\tprivate URL defaultCoordinatesUrl;\n+\tprivate MavenCoordinates coordinateAdaptations;\n+\tprivate SemanticVersion version;\n+\tprivate Iterable<File> settingsFiles;\n+\tprivate EclipseConfiguration.State state;\n+\n+\t/** Initialize valid default configuration, taking latest version */\n+\tpublic EclipseConfiguration(String formatterName, Provisioner jarProvisioner, String... supportedEclipseVersions) {\n+\t\tObjects.requireNonNull(formatterName, \"formatterName\");\n+\t\tObjects.requireNonNull(jarProvisioner, \"jarProvisioner\");\n+\t\tObjects.requireNonNull(supportedEclipseVersions, \"supportedEclipseVersions\");\n+\t\tif (supportedEclipseVersions.length < 1) {\n+\t\t\tthrow new IllegalArgumentException(\"At lease one version must be allowed.\");\n+\t\t}\n+\n+\t\tPath relativeFormatterResourcePath = Paths.get(ECLIPSE_FORMATTER_RESOURCES, formatterName.replace(' ', '_'));\n+\t\teclipseConfigContext = getClass().getClassLoader().getResource(relativeFormatterResourcePath.toString());\n+\t\tif (null == eclipseConfigContext) {\n+\t\t\tthrow new IllegalArgumentException(String.format(\"Eclipse configuration context resource path '%s' not found.\", relativeFormatterResourcePath));\n+\t\t}\n+\n+\t\tthis.supportedEclipseVersions = new TreeSet<SemanticVersion>();\n+\t\tfor (String allowedVersion : supportedEclipseVersions) {\n+\t\t\tthis.supportedEclipseVersions.add(new SemanticVersion(allowedVersion));\n+\t\t}\n+\t\tversion = this.supportedEclipseVersions.last(); //Use latest version per default\n+\t\tdefaultCoordinatesUrl = getDefaultCoordinatesUrl(eclipseConfigContext, version);\n+\t\tthis.jarProvisioner = jarProvisioner;\n+\n+\t\tcoordinateAdaptations = new MavenCoordinates(); //Use default coordinates configured for version\n+\t\tsettingsFiles = new ArrayList<File>(); //Use default preferences\n+\t\tstate = null; //Create state only on demand too speed up initialization\n+\t}\n+\n+\t/** Set Eclipse version */\n+\tpublic void setVersion(String versionOrUrl) {\n+\t\ttry {\n+\t\t\t// For development purpose and patch delivery it is allowed\n+\t\t\t// to specify directly the URL of a M2 coordinates file.\n+\t\t\tdefaultCoordinatesUrl = new URL(versionOrUrl);\n+\t\t\t// The default version is not changed.\n+\t\t} catch (MalformedURLException ignored) {\n+\t\t\tSemanticVersion newVersion = new SemanticVersion(versionOrUrl);\n+\t\t\tif (supportedEclipseVersions.contains(newVersion)) {\n+\t\t\t\tdefaultCoordinatesUrl = getDefaultCoordinatesUrl(eclipseConfigContext, newVersion);\n+\t\t\t\tversion = newVersion;\n+\t\t\t} else {\n+\t\t\t\tthrow new UserArgumentException(versionOrUrl,\n+\t\t\t\t\t\tString.format(\"Version is not part of the supported versions '%s'.\",\n+\t\t\t\t\t\t\t\tsupportedEclipseVersions.stream().map(v -> v.toString()).collect(Collectors.joining(\", \"))));\n+\t\t\t}\n+\t\t}\n+\t\tinvalidateState();\n+\t}\n+\n+\tprivate static URL getDefaultCoordinatesUrl(URL eclipseConfigContext, SemanticVersion version) {\n+\t\ttry {\n+\t\t\tPath filePath = Paths.get(eclipseConfigContext.getPath(), String.format(\"v%s.txt\", version.toString()));\n+\t\t\treturn new URL(eclipseConfigContext.getProtocol(), eclipseConfigContext.getHost(), filePath.toString());\n+\t\t} catch (MalformedURLException e) {\n+\t\t\t/*\n+\t\t\t *  This exception must be prevented by the strict syntax checking of\n+\t\t\t *  SemanticVersion and unit-tests of all allowed versions.\n+\t\t\t */\n+\t\t\tthrow new RuntimeException(e);\n+\t\t}\n+\t}\n+\n+\t/**\n+\t * Modify default Maven dependencies configured for the formatter.\n+\t * The default dependencies are located in {@link #ECLIPSE_FORMATTER_RESOURCES}.\n+\t */\n+\tpublic void setDepenencies(String... coordinates) {\n+\t\tcoordinateAdaptations = new MavenCoordinates();\n+\t\tcoordinateAdaptations.update(coordinates);\n+\t\tinvalidateState();\n+\t}\n+\n+\t/** Set settings files containing Eclipse preferences */\n+\tpublic void setPreferences(Iterable<File> settingsFiles) {\n+\t\tthis.settingsFiles = settingsFiles;\n+\t\tinvalidateState();\n+\t}\n+\n+\t/** The current state becomes invalid in case a configuration item has successfully changed */\n+\tprivate void invalidateState() {\n+\t\tstate = null;\n+\t}\n+\n+\t/** Creates the state of the configuration */\n+\tpublic EclipseConfiguration.State get() {\n+\t\tif (null == state) {\n+\t\t\tstate = new State(\n+\t\t\t\t\tjarProvisioner,\n+\t\t\t\t\tcreateMavenCoordinates(),\n+\t\t\t\t\tversion,\n+\t\t\t\t\tsettingsFiles);\n+\t\t}\n+\t\treturn state;\n+\t}\n+\n+\tprivate MavenCoordinates createMavenCoordinates() {\n+\t\tMavenCoordinates coordinates = new MavenCoordinates();\n+\t\tcoordinates.add(defaultCoordinatesUrl);\n+\t\tcoordinates.update(coordinateAdaptations);\n+\t\treturn coordinates;\n+\t}\n+\n+\t/**\n+\t * State of Eclipse configuration items, providing functionality to derived information\n+\t * based on the state.\n+\t */\n+\tpublic static class State implements Serializable {\n+\t\t// Not used, only the serialization output is required to determine whether the object has changed\n+\t\tprivate static final long serialVersionUID = 1L;\n+\n+\t\tprivate final FileSignature settingsFiles;\n+\t\tprivate final MavenCoordinates coordinates;\n+\t\tprivate final SemanticVersion version;\n+\n+\t\t/*\n+\t\t * Fields are transient because not needed to uniquely identify a Eclipse configuration state, and also because\n+\t\t * Gradle only needs this class to be serializable so it can compare its members for incremental builds.\n+\t\t */\n+\t\tprivate transient ClassLoader lazyClassLoader;\n+\t\t@SuppressFBWarnings(\"SE_TRANSIENT_FIELD_NOT_RESTORED\")\n+\t\tprivate final transient Provisioner jarProvisioner;\n+\n+\t\t/** State constructor expects that all passed items are not modified afterwards */\n+\t\tprotected State(Provisioner jarProvisioner, MavenCoordinates coordinates, SemanticVersion version, Iterable<File> settingsFiles) {\n+\t\t\tthis.jarProvisioner = jarProvisioner;\n+\t\t\tthis.coordinates = coordinates;\n+\t\t\tthis.version = version;\n+\t\t\tlazyClassLoader = null;\n+\n+\t\t\ttry {\n+\t\t\t\tthis.settingsFiles = FileSignature.signAsList(settingsFiles);\n+\t\t\t} catch (NullPointerException e) {\n+\t\t\t\tthrow new UserArgumentException(null, \"Configuration file settings\", e);\n+\t\t\t} catch (IOException e) {\n+\t\t\t\tthrow new RuntimeException(e); //Canonical path problems are not user argument problems\n+\t\t\t}\n+\t\t}\n+","path":"lib-extra/src/main/java/com/diffplug/spotless/extra/config/EclipseConfiguration.java","position":203,"original_position":203,"commit_id":"3890fbd4952a7fc3181688919fefc93b9c4c1e94","original_commit_id":"3890fbd4952a7fc3181688919fefc93b9c4c1e94","user":{"login":"fvgh","id":10271755,"node_id":"MDQ6VXNlcjEwMjcxNzU1","avatar_url":"https://avatars0.githubusercontent.com/u/10271755?v=4","gravatar_id":"","url":"https://api.github.com/users/fvgh","html_url":"https://github.com/fvgh","followers_url":"https://api.github.com/users/fvgh/followers","following_url":"https://api.github.com/users/fvgh/following{/other_user}","gists_url":"https://api.github.com/users/fvgh/gists{/gist_id}","starred_url":"https://api.github.com/users/fvgh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fvgh/subscriptions","organizations_url":"https://api.github.com/users/fvgh/orgs","repos_url":"https://api.github.com/users/fvgh/repos","events_url":"https://api.github.com/users/fvgh/events{/privacy}","received_events_url":"https://api.github.com/users/fvgh/received_events","type":"User","site_admin":false},"body":"Thanks for the hint with the dependency lock files generated by Gradle. Did not know about the feature, but this is exactly what I need to generate initial default locks for the Eclipse formatter implementations. So I will modify the current solution to cope with these files.\r\nThe workflow for providing new Eclipse formatter implementation version will in that case be:\r\n- Go to `_ext` and call a build\r\n- If all tests are passing with the new versions and additional tests prove that the new formatting feature (what ever the reason for the update is) is applied, generate the locks and make it available in `extra` \r\n- If the tests failing with the new Eclipse dependency versions, a new version of the formatter implementation is required.But I hope, with some more experience, that the framework and the formatter adaptations will once be generic enough so that a modification will seldom required.","created_at":"2018-06-01T16:20:13Z","updated_at":"2018-06-01T16:20:14Z","html_url":"https://github.com/diffplug/spotless/pull/253#discussion_r192446564","pull_request_url":"https://api.github.com/repos/diffplug/spotless/pulls/253","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/diffplug/spotless/pulls/comments/192446564"},"html":{"href":"https://github.com/diffplug/spotless/pull/253#discussion_r192446564"},"pull_request":{"href":"https://api.github.com/repos/diffplug/spotless/pulls/253"}},"in_reply_to_id":192228643},"pull_request":{"url":"https://api.github.com/repos/diffplug/spotless/pulls/253","id":191567890,"node_id":"MDExOlB1bGxSZXF1ZXN0MTkxNTY3ODkw","html_url":"https://github.com/diffplug/spotless/pull/253","diff_url":"https://github.com/diffplug/spotless/pull/253.diff","patch_url":"https://github.com/diffplug/spotless/pull/253.patch","issue_url":"https://api.github.com/repos/diffplug/spotless/issues/253","number":253,"state":"open","locked":false,"title":"Refactored Eclipse formatter configuration and step creation","user":{"login":"fvgh","id":10271755,"node_id":"MDQ6VXNlcjEwMjcxNzU1","avatar_url":"https://avatars0.githubusercontent.com/u/10271755?v=4","gravatar_id":"","url":"https://api.github.com/users/fvgh","html_url":"https://github.com/fvgh","followers_url":"https://api.github.com/users/fvgh/followers","following_url":"https://api.github.com/users/fvgh/following{/other_user}","gists_url":"https://api.github.com/users/fvgh/gists{/gist_id}","starred_url":"https://api.github.com/users/fvgh/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fvgh/subscriptions","organizations_url":"https://api.github.com/users/fvgh/orgs","repos_url":"https://api.github.com/users/fvgh/repos","events_url":"https://api.github.com/users/fvgh/events{/privacy}","received_events_url":"https://api.github.com/users/fvgh/received_events","type":"User","site_admin":false},"body":"Refactored Eclipse formatter configuration and step creation to support dependency version locks and version dependent implementation interfaces.\r\n\r\nDependency version locks are required in case Eclipse formatters dependencies are (partly) no longer part of a single fat JAR.\r\nSupport of version dependent interface implementation shall ensure flexibility for future interfaces changes (renaming, adding logging options, ...).\r\nAs part of the refactoring, user data checks have been added for Eclipse formatter configurations.\r\nAdded support of user dependency modifications of Eclipse formatters.\r\nChanged JarState to cope with multiple coordinates.\r\nAdded hash comparison to FileSignature.","created_at":"2018-05-30T20:15:08Z","updated_at":"2018-06-01T16:20:14Z","closed_at":null,"merged_at":null,"merge_commit_sha":null,"assignee":null,"assignees":[],"requested_reviewers":[{"login":"lutovich","id":1638145,"node_id":"MDQ6VXNlcjE2MzgxNDU=","avatar_url":"https://avatars2.githubusercontent.com/u/1638145?v=4","gravatar_id":"","url":"https://api.github.com/users/lutovich","html_url":"https://github.com/lutovich","followers_url":"https://api.github.com/users/lutovich/followers","following_url":"https://api.github.com/users/lutovich/following{/other_user}","gists_url":"https://api.github.com/users/lutovich/gists{/gist_id}","starred_url":"https://api.github.com/users/lutovich/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lutovich/subscriptions","organizations_url":"https://api.github.com/users/lutovich/orgs","repos_url":"https://api.github.com/users/lutovich/repos","events_url":"https://api.github.com/users/lutovich/events{/privacy}","received_events_url":"https://api.github.com/users/lutovich/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/diffplug/spotless/pulls/253/commits","review_comments_url":"https://api.github.com/repos/diffplug/spotless/pulls/253/comments","review_comment_url":"https://api.github.com/repos/diffplug/spotless/pulls/comments{/number}","comments_url":"https://api.github.com/repos/diffplug/spotless/issues/253/comments","statuses_url":"https://api.github.com/repos/diffplug/spotless/statuses/3890fbd4952a7fc3181688919fefc93b9c4c1e94","head":{"label":"diffplug:lib_extra_dep_config","ref":"lib_extra_dep_config","sha":"3890fbd4952a7fc3181688919fefc93b9c4c1e94","user":{"login":"diffplug","id":6572898,"node_id":"MDEyOk9yZ2FuaXphdGlvbjY1NzI4OTg=","avatar_url":"https://avatars2.githubusercontent.com/u/6572898?v=4","gravatar_id":"","url":"https://api.github.com/users/diffplug","html_url":"https://github.com/diffplug","followers_url":"https://api.github.com/users/diffplug/followers","following_url":"https://api.github.com/users/diffplug/following{/other_user}","gists_url":"https://api.github.com/users/diffplug/gists{/gist_id}","starred_url":"https://api.github.com/users/diffplug/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/diffplug/subscriptions","organizations_url":"https://api.github.com/users/diffplug/orgs","repos_url":"https://api.github.com/users/diffplug/repos","events_url":"https://api.github.com/users/diffplug/events{/privacy}","received_events_url":"https://api.github.com/users/diffplug/received_events","type":"Organization","site_admin":false},"repo":{"id":34685800,"node_id":"MDEwOlJlcG9zaXRvcnkzNDY4NTgwMA==","name":"spotless","full_name":"diffplug/spotless","owner":{"login":"diffplug","id":6572898,"node_id":"MDEyOk9yZ2FuaXphdGlvbjY1NzI4OTg=","avatar_url":"https://avatars2.githubusercontent.com/u/6572898?v=4","gravatar_id":"","url":"https://api.github.com/users/diffplug","html_url":"https://github.com/diffplug","followers_url":"https://api.github.com/users/diffplug/followers","following_url":"https://api.github.com/users/diffplug/following{/other_user}","gists_url":"https://api.github.com/users/diffplug/gists{/gist_id}","starred_url":"https://api.github.com/users/diffplug/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/diffplug/subscriptions","organizations_url":"https://api.github.com/users/diffplug/orgs","repos_url":"https://api.github.com/users/diffplug/repos","events_url":"https://api.github.com/users/diffplug/events{/privacy}","received_events_url":"https://api.github.com/users/diffplug/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/diffplug/spotless","description":"Keep your code spotless","fork":false,"url":"https://api.github.com/repos/diffplug/spotless","forks_url":"https://api.github.com/repos/diffplug/spotless/forks","keys_url":"https://api.github.com/repos/diffplug/spotless/keys{/key_id}","collaborators_url":"https://api.github.com/repos/diffplug/spotless/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/diffplug/spotless/teams","hooks_url":"https://api.github.com/repos/diffplug/spotless/hooks","issue_events_url":"https://api.github.com/repos/diffplug/spotless/issues/events{/number}","events_url":"https://api.github.com/repos/diffplug/spotless/events","assignees_url":"https://api.github.com/repos/diffplug/spotless/assignees{/user}","branches_url":"https://api.github.com/repos/diffplug/spotless/branches{/branch}","tags_url":"https://api.github.com/repos/diffplug/spotless/tags","blobs_url":"https://api.github.com/repos/diffplug/spotless/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/diffplug/spotless/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/diffplug/spotless/git/refs{/sha}","trees_url":"https://api.github.com/repos/diffplug/spotless/git/trees{/sha}","statuses_url":"https://api.github.com/repos/diffplug/spotless/statuses/{sha}","languages_url":"https://api.github.com/repos/diffplug/spotless/languages","stargazers_url":"https://api.github.com/repos/diffplug/spotless/stargazers","contributors_url":"https://api.github.com/repos/diffplug/spotless/contributors","subscribers_url":"https://api.github.com/repos/diffplug/spotless/subscribers","subscription_url":"https://api.github.com/repos/diffplug/spotless/subscription","commits_url":"https://api.github.com/repos/diffplug/spotless/commits{/sha}","git_commits_url":"https://api.github.com/repos/diffplug/spotless/git/commits{/sha}","comments_url":"https://api.github.com/repos/diffplug/spotless/comments{/number}","issue_comment_url":"https://api.github.com/repos/diffplug/spotless/issues/comments{/number}","contents_url":"https://api.github.com/repos/diffplug/spotless/contents/{+path}","compare_url":"https://api.github.com/repos/diffplug/spotless/compare/{base}...{head}","merges_url":"https://api.github.com/repos/diffplug/spotless/merges","archive_url":"https://api.github.com/repos/diffplug/spotless/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/diffplug/spotless/downloads","issues_url":"https://api.github.com/repos/diffplug/spotless/issues{/number}","pulls_url":"https://api.github.com/repos/diffplug/spotless/pulls{/number}","milestones_url":"https://api.github.com/repos/diffplug/spotless/milestones{/number}","notifications_url":"https://api.github.com/repos/diffplug/spotless/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/diffplug/spotless/labels{/name}","releases_url":"https://api.github.com/repos/diffplug/spotless/releases{/id}","deployments_url":"https://api.github.com/repos/diffplug/spotless/deployments","created_at":"2015-04-27T19:10:58Z","updated_at":"2018-06-01T15:59:05Z","pushed_at":"2018-06-01T16:08:21Z","git_url":"git://github.com/diffplug/spotless.git","ssh_url":"git@github.com:diffplug/spotless.git","clone_url":"https://github.com/diffplug/spotless.git","svn_url":"https://github.com/diffplug/spotless","homepage":"","size":14736,"stargazers_count":324,"watchers_count":324,"language":"Java","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":54,"mirror_url":null,"archived":false,"open_issues_count":41,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":54,"open_issues":41,"watchers":324,"default_branch":"master"}},"base":{"label":"diffplug:master","ref":"master","sha":"c346971673336d4256b1ae8837701b0ff6d809ab","user":{"login":"diffplug","id":6572898,"node_id":"MDEyOk9yZ2FuaXphdGlvbjY1NzI4OTg=","avatar_url":"https://avatars2.githubusercontent.com/u/6572898?v=4","gravatar_id":"","url":"https://api.github.com/users/diffplug","html_url":"https://github.com/diffplug","followers_url":"https://api.github.com/users/diffplug/followers","following_url":"https://api.github.com/users/diffplug/following{/other_user}","gists_url":"https://api.github.com/users/diffplug/gists{/gist_id}","starred_url":"https://api.github.com/users/diffplug/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/diffplug/subscriptions","organizations_url":"https://api.github.com/users/diffplug/orgs","repos_url":"https://api.github.com/users/diffplug/repos","events_url":"https://api.github.com/users/diffplug/events{/privacy}","received_events_url":"https://api.github.com/users/diffplug/received_events","type":"Organization","site_admin":false},"repo":{"id":34685800,"node_id":"MDEwOlJlcG9zaXRvcnkzNDY4NTgwMA==","name":"spotless","full_name":"diffplug/spotless","owner":{"login":"diffplug","id":6572898,"node_id":"MDEyOk9yZ2FuaXphdGlvbjY1NzI4OTg=","avatar_url":"https://avatars2.githubusercontent.com/u/6572898?v=4","gravatar_id":"","url":"https://api.github.com/users/diffplug","html_url":"https://github.com/diffplug","followers_url":"https://api.github.com/users/diffplug/followers","following_url":"https://api.github.com/users/diffplug/following{/other_user}","gists_url":"https://api.github.com/users/diffplug/gists{/gist_id}","starred_url":"https://api.github.com/users/diffplug/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/diffplug/subscriptions","organizations_url":"https://api.github.com/users/diffplug/orgs","repos_url":"https://api.github.com/users/diffplug/repos","events_url":"https://api.github.com/users/diffplug/events{/privacy}","received_events_url":"https://api.github.com/users/diffplug/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/diffplug/spotless","description":"Keep your code spotless","fork":false,"url":"https://api.github.com/repos/diffplug/spotless","forks_url":"https://api.github.com/repos/diffplug/spotless/forks","keys_url":"https://api.github.com/repos/diffplug/spotless/keys{/key_id}","collaborators_url":"https://api.github.com/repos/diffplug/spotless/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/diffplug/spotless/teams","hooks_url":"https://api.github.com/repos/diffplug/spotless/hooks","issue_events_url":"https://api.github.com/repos/diffplug/spotless/issues/events{/number}","events_url":"https://api.github.com/repos/diffplug/spotless/events","assignees_url":"https://api.github.com/repos/diffplug/spotless/assignees{/user}","branches_url":"https://api.github.com/repos/diffplug/spotless/branches{/branch}","tags_url":"https://api.github.com/repos/diffplug/spotless/tags","blobs_url":"https://api.github.com/repos/diffplug/spotless/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/diffplug/spotless/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/diffplug/spotless/git/refs{/sha}","trees_url":"https://api.github.com/repos/diffplug/spotless/git/trees{/sha}","statuses_url":"https://api.github.com/repos/diffplug/spotless/statuses/{sha}","languages_url":"https://api.github.com/repos/diffplug/spotless/languages","stargazers_url":"https://api.github.com/repos/diffplug/spotless/stargazers","contributors_url":"https://api.github.com/repos/diffplug/spotless/contributors","subscribers_url":"https://api.github.com/repos/diffplug/spotless/subscribers","subscription_url":"https://api.github.com/repos/diffplug/spotless/subscription","commits_url":"https://api.github.com/repos/diffplug/spotless/commits{/sha}","git_commits_url":"https://api.github.com/repos/diffplug/spotless/git/commits{/sha}","comments_url":"https://api.github.com/repos/diffplug/spotless/comments{/number}","issue_comment_url":"https://api.github.com/repos/diffplug/spotless/issues/comments{/number}","contents_url":"https://api.github.com/repos/diffplug/spotless/contents/{+path}","compare_url":"https://api.github.com/repos/diffplug/spotless/compare/{base}...{head}","merges_url":"https://api.github.com/repos/diffplug/spotless/merges","archive_url":"https://api.github.com/repos/diffplug/spotless/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/diffplug/spotless/downloads","issues_url":"https://api.github.com/repos/diffplug/spotless/issues{/number}","pulls_url":"https://api.github.com/repos/diffplug/spotless/pulls{/number}","milestones_url":"https://api.github.com/repos/diffplug/spotless/milestones{/number}","notifications_url":"https://api.github.com/repos/diffplug/spotless/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/diffplug/spotless/labels{/name}","releases_url":"https://api.github.com/repos/diffplug/spotless/releases{/id}","deployments_url":"https://api.github.com/repos/diffplug/spotless/deployments","created_at":"2015-04-27T19:10:58Z","updated_at":"2018-06-01T15:59:05Z","pushed_at":"2018-06-01T16:08:21Z","git_url":"git://github.com/diffplug/spotless.git","ssh_url":"git@github.com:diffplug/spotless.git","clone_url":"https://github.com/diffplug/spotless.git","svn_url":"https://github.com/diffplug/spotless","homepage":"","size":14736,"stargazers_count":324,"watchers_count":324,"language":"Java","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":54,"mirror_url":null,"archived":false,"open_issues_count":41,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":54,"open_issues":41,"watchers":324,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/diffplug/spotless/pulls/253"},"html":{"href":"https://github.com/diffplug/spotless/pull/253"},"issue":{"href":"https://api.github.com/repos/diffplug/spotless/issues/253"},"comments":{"href":"https://api.github.com/repos/diffplug/spotless/issues/253/comments"},"review_comments":{"href":"https://api.github.com/repos/diffplug/spotless/pulls/253/comments"},"review_comment":{"href":"https://api.github.com/repos/diffplug/spotless/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/diffplug/spotless/pulls/253/commits"},"statuses":{"href":"https://api.github.com/repos/diffplug/spotless/statuses/3890fbd4952a7fc3181688919fefc93b9c4c1e94"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"fvgh"}}