-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
464 additions
and
54 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
# If Git Diff | ||
<!---freshmark shields | ||
output = [ | ||
link(shield('Gradle plugin', 'plugins.gradle.org', 'com.diffplug.if-git-diff', 'blue'), 'https://plugins.gradle.org/plugin/com.diffplug.if-git-diff'), | ||
link(shield('Maven central', 'mavencentral', 'available', 'blue'), 'https://search.maven.org/search?q=g:com.diffplug.spotless-changelog'), | ||
link(shield('Apache 2.0', 'license', 'apache-2.0', 'blue'), 'https://tldrlegal.com/license/apache-license-2.0-(apache-2.0)'), | ||
'', | ||
link(shield('Changelog', 'changelog', versionLast, 'brightgreen'), 'CHANGELOG.md'), | ||
link(shield('Javadoc', 'javadoc', 'yes', 'brightgreen'), 'https://javadoc.jitpack.io/com/github/diffplug/spotless-changelog/spotless-changelog-agg/release~{{versionLast}}/javadoc/'), | ||
link(shield('Live chat', 'gitter', 'chat', 'brightgreen'), 'https://gitter.im/diffplug/spotless-changelog'), | ||
link(image('CircleCI', 'https://circleci.com/gh/diffplug/spotless-changelog.svg?style=shield'), 'https://circleci.com/gh/diffplug/spotless-changelog') | ||
].join('\n'); | ||
--> | ||
[![Gradle plugin](https://img.shields.io/badge/plugins.gradle.org-com.diffplug.if--git--diff-blue.svg)](https://plugins.gradle.org/plugin/com.diffplug.if-git-diff) | ||
[![Maven central](https://img.shields.io/badge/mavencentral-available-blue.svg)](https://search.maven.org/search?q=g:com.diffplug.spotless-changelog) | ||
[![Apache 2.0](https://img.shields.io/badge/license-apache--2.0-blue.svg)](https://tldrlegal.com/license/apache-license-2.0-(apache-2.0)) | ||
|
||
[![Changelog](https://img.shields.io/badge/changelog-2.3.2-brightgreen.svg)](CHANGELOG.md) | ||
[![Javadoc](https://img.shields.io/badge/javadoc-yes-brightgreen.svg)](https://javadoc.jitpack.io/com/github/diffplug/spotless-changelog/spotless-changelog-agg/release~2.3.2/javadoc/) | ||
[![Live chat](https://img.shields.io/badge/gitter-chat-brightgreen.svg)](https://gitter.im/diffplug/spotless-changelog) | ||
[![CircleCI](https://circleci.com/gh/diffplug/spotless-changelog.svg?style=shield)](https://circleci.com/gh/diffplug/spotless-changelog) | ||
<!---freshmark /shields --> | ||
|
||
This plugin can be applied in `settings.gradle` or `build.gradle`, and it lets you execute a block of code contingent on whether there are changes in the given folder relative to a given baseline git ref. | ||
|
||
```gradle | ||
plugins { | ||
id 'com.diffplug.if-git-diff' | ||
} | ||
ifGitDiff { | ||
baseline 'origin/main' // default value | ||
inFolder 'a', { include 'a' } | ||
inFolder 'b', { include 'b' } | ||
} | ||
``` | ||
|
||
## Limitations | ||
|
||
This plugin does not work well with the configuration cache. Using the example above: | ||
|
||
- run `gradlew test` on a clean checkout of `origin/main`, and you would see that `:test` ran but `:a:test` and `:b:test` did not; so far so good. | ||
- now add a file `a/blah` | ||
- now if you run `gradlew test` | ||
- without configuration-cache -> `:test` and `:a:test` -> good! | ||
- with configuration-cache -> only `:test` -> bad, cached configuration doesn't know that `a/blah` was added | ||
|
||
A different approach which could work with configuration-cache is to mark tasks as up-to-date based on git status, see the [`GitDiffUpToDatePlugin`](https://github.com/thahnen/GitDiffUpToDatePlugin) for that. | ||
|
||
## Roadmap | ||
|
||
This plugin was built to solve [a fairly specific problem in the Spotless build](https://github.com/diffplug/spotless-changelog/issues/30). It is packaged with `spotless-changelog` because it's vaguely related, and it might make sense someday for `spotless-changelog` to assert "if files changed in X dir, then changelog Y must be updated". | ||
|
||
## Reference | ||
|
||
<!---freshmark version | ||
output = prefixDelimiterReplace(input, "id 'com.diffplug.spotless-changelog' version '", "'", versionLast) | ||
output = prefixDelimiterReplace(output, 'https://github.com/diffplug/spotless-changelog/blob/release/', '/spotless', versionLast) | ||
output = prefixDelimiterReplace(output, 'https://javadoc.io/static/com.diffplug.spotless-changelog/spotless-changelog-plugin-gradle/', '/', versionLast) | ||
--> | ||
|
||
[Plugin DSL javadoc](https://javadoc.io/static/com.diffplug.spotless-changelog/spotless-changelog-plugin-gradle/2.3.2/com/diffplug/spotless/changelog/gradle/IfGitDiffExtension.html). For requirements see [spotless-changelog](https://github.com/diffplug/spotless-changelog#requirements). | ||
|
||
<!---freshmark /version --> | ||
|
||
## Acknowledgments | ||
|
||
- Git stuff by [jgit](https://www.eclipse.org/jgit/). | ||
- Built by [gradle](https://gradle.org/). | ||
- Maintained by [DiffPlug](https://www.diffplug.com/). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
distributionBase=GRADLE_USER_HOME | ||
distributionPath=wrapper/dists | ||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip | ||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip | ||
zipStoreBase=GRADLE_USER_HOME | ||
zipStorePath=wrapper/dists |
131 changes: 131 additions & 0 deletions
131
...lugin-gradle/src/main/java/com/diffplug/spotless/changelog/gradle/IfGitDiffExtension.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
/* | ||
* Copyright (C) 2022 DiffPlug | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package com.diffplug.spotless.changelog.gradle; | ||
|
||
|
||
import com.diffplug.common.base.Preconditions; | ||
import java.io.File; | ||
import java.io.IOException; | ||
import java.util.List; | ||
import org.eclipse.jgit.api.Git; | ||
import org.eclipse.jgit.api.errors.GitAPIException; | ||
import org.eclipse.jgit.diff.DiffEntry; | ||
import org.eclipse.jgit.lib.ObjectId; | ||
import org.eclipse.jgit.lib.ObjectReader; | ||
import org.eclipse.jgit.lib.Repository; | ||
import org.eclipse.jgit.revwalk.RevWalk; | ||
import org.eclipse.jgit.storage.file.FileRepositoryBuilder; | ||
import org.eclipse.jgit.treewalk.CanonicalTreeParser; | ||
import org.eclipse.jgit.treewalk.filter.PathFilter; | ||
import org.eclipse.jgit.treewalk.filter.TreeFilter; | ||
import org.gradle.api.Action; | ||
import org.gradle.api.GradleException; | ||
import org.gradle.api.Project; | ||
import org.gradle.api.initialization.Settings; | ||
|
||
public abstract class IfGitDiffExtension<T> { | ||
static final String NAME = "ifGitDiff"; | ||
|
||
public static class ForProject extends IfGitDiffExtension<Project> { | ||
public ForProject(Project owner) { | ||
super(owner); | ||
} | ||
|
||
@Override | ||
protected File file(Object fileArg) { | ||
return owner.file(fileArg); | ||
} | ||
} | ||
|
||
public static class ForSettings extends IfGitDiffExtension<Settings> { | ||
public ForSettings(Settings owner) { | ||
super(owner); | ||
} | ||
|
||
@Override | ||
protected File file(Object fileArg) { | ||
if (fileArg instanceof File) { | ||
return (File) fileArg; | ||
} else if (fileArg instanceof String) { | ||
return new File(owner.getRootDir(), (String) fileArg); | ||
} else { | ||
throw new IllegalArgumentException("We only support String or File, this was " + fileArg.getClass()); | ||
} | ||
} | ||
} | ||
|
||
final T owner; | ||
|
||
IfGitDiffExtension(T owner) { | ||
this.owner = owner; | ||
} | ||
|
||
private String baseline = "origin/main"; | ||
|
||
public void setBaseline(String baseline) { | ||
this.baseline = baseline; | ||
} | ||
|
||
public String getBaseline() { | ||
return baseline; | ||
} | ||
|
||
protected abstract File file(Object fileArg); | ||
|
||
private TreeFilter filterTo(Repository repo, File child) { | ||
String rootAbs = repo.getWorkTree().getAbsolutePath(); | ||
String childAbs = child.getAbsolutePath(); | ||
if (rootAbs.equals(childAbs)) { | ||
return TreeFilter.ALL; | ||
} else if (childAbs.startsWith(rootAbs)) { | ||
String filter = childAbs.substring(rootAbs.length()).replace('\\', '/'); | ||
Preconditions.checkState(filter.charAt(0) == '/'); | ||
return PathFilter.create(filter.substring(1)); | ||
} else { | ||
throw new GradleException(childAbs + " is not contained within the git repo " + rootAbs); | ||
} | ||
} | ||
|
||
public void inFolder(Object folder, Action<T> onChanged) { | ||
try (Repository repo = new FileRepositoryBuilder() | ||
.findGitDir(file("")) | ||
.build()) { | ||
ObjectId baselineSha = repo.resolve(baseline); | ||
if (baselineSha == null) { | ||
throw new GradleException("Unable to resolve " + baseline); | ||
} | ||
|
||
CanonicalTreeParser baselineTree = new CanonicalTreeParser(); | ||
try (ObjectReader reader = repo.newObjectReader()) { | ||
RevWalk walk = new RevWalk(reader); | ||
baselineTree.reset(reader, walk.parseCommit(baselineSha).getTree()); | ||
} | ||
Git git = new Git(repo); | ||
List<DiffEntry> changes = git.diff() | ||
.setOldTree(baselineTree) | ||
.setShowNameAndStatusOnly(true) | ||
.setPathFilter(filterTo(repo, file(folder))) | ||
.call(); | ||
if (!changes.isEmpty()) { | ||
onChanged.execute(owner); | ||
} | ||
} catch (IOException e) { | ||
throw new GradleException("Unable to find git repository", e); | ||
} catch (GitAPIException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
} |
38 changes: 38 additions & 0 deletions
38
...g-plugin-gradle/src/main/java/com/diffplug/spotless/changelog/gradle/IfGitDiffPlugin.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/* | ||
* Copyright (C) 2019-2022 DiffPlug | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package com.diffplug.spotless.changelog.gradle; | ||
|
||
|
||
import org.gradle.api.Plugin; | ||
import org.gradle.api.Project; | ||
import org.gradle.api.initialization.Settings; | ||
import org.gradle.api.plugins.ExtensionAware; | ||
|
||
/** @see IfGitDiffExtension */ | ||
public class IfGitDiffPlugin implements Plugin<ExtensionAware> { | ||
@Override | ||
public void apply(ExtensionAware projectOrSettings) { | ||
if (projectOrSettings instanceof Project) { | ||
Project project = (Project) projectOrSettings; | ||
projectOrSettings.getExtensions().create(IfGitDiffExtension.NAME, IfGitDiffExtension.ForProject.class, project); | ||
} else if (projectOrSettings instanceof Settings) { | ||
Settings settings = (Settings) projectOrSettings; | ||
projectOrSettings.getExtensions().create(IfGitDiffExtension.NAME, IfGitDiffExtension.ForSettings.class, settings); | ||
} else { | ||
throw new IllegalArgumentException("We support build.gradle and settings.gradle, this was " + projectOrSettings.getClass()); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.