Skip to content
This repository has been archived by the owner on Jul 31, 2019. It is now read-only.

Commit

Permalink
Resolves GH-37: Allow loading dependency versions from a properties file
Browse files Browse the repository at this point in the history
  • Loading branch information
romeara committed Jul 10, 2019
1 parent 8aee21e commit a005441
Show file tree
Hide file tree
Showing 17 changed files with 284 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGE_LOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased]
### Added
- (GH-35) Added ability to specify credentials and their load sources within Gradle builds
- (GH-37) Added ability to load dependency version constraints from a properties file

### Changed
- (GH-33) Update minimum required Gradle version to 5.0
Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
* [org.starchartlabs.flare.merge-coverage-reports](#org.starchartlabs.flare.merge-coverage-reports)
* [org.starchartlabs.flare.increase-test-logging](#org.starchartlabs.flare.increase-test-logging)
* [org.starchartlabs.flare.dependency-insight](#org.starchartlabs.flare.dependency-insight)
* [org.starchartlabs.flare.dependency-insight](#org.starchartlabs.flare.dependency-reporting)
* [org.starchartlabs.flare.dependency-insight](#org.starchartlabs.flare.managed-credentials)
* [org.starchartlabs.flare.dependency-insight](#org.starchartlabs.flare.dependency-versions)

Contains plug-ins for the Gradle build system which simplify configuration or reduce boilerplate for commonly-used conventions

Expand Down Expand Up @@ -92,6 +95,12 @@ Introduces standard domain-specific language to Gradle builds for defining crede

See the [usage documentation](./docs/managed-credentials.md) for information and requirements for applying the plug-in

### org.starchartlabs.flare.dependency-versions

Introduces standard domain-specific language to Gradle builds for defining dependency constraints in a properties file

See the [usage documentation](./docs/dependency-versions.md) for information and requirements for applying the plug-in

### org.starchartlabs.flare.dependency-insight

*This plug-in is DEPRECATED - use `org.starchartlabs.flare.dependency-insight` instead*
Expand Down
9 changes: 5 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ buildscript {
maven { url 'https://plugins.gradle.org/m2/' }
}
dependencies {
classpath 'com.netflix.nebula:nebula-dependency-recommender:4.2.0'
classpath 'com.netflix.nebula:nebula-publishing-plugin:4.2.0'
classpath 'com.netflix.nebula:nebula-dependency-recommender:7.5.6'
classpath 'com.netflix.nebula:nebula-publishing-plugin:9.0.1'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4'
classpath 'org.starchartlabs.flare:flare-operations-plugins:2.0.0'
classpath 'org.starchartlabs.flare:flare-publishing-plugins:2.0.0'
Expand All @@ -18,8 +18,7 @@ apply plugin: 'checkstyle'
apply plugin: 'maven-publish'
apply plugin: 'nebula.dependency-recommender'
apply plugin: 'nebula.maven-resolved-dependencies'
apply plugin: 'nebula.maven-base-publish'
apply plugin: 'nebula.maven-dependencies'
apply plugin: 'nebula.maven-publish'
apply plugin: 'com.jfrog.bintray'
apply plugin: 'org.starchartlabs.flare.increase-test-logging'
apply plugin: 'org.starchartlabs.flare.published-project'
Expand Down Expand Up @@ -49,6 +48,8 @@ repositories {
dependencies {
compile gradleApi()

compile 'org.starchartlabs.alloy:alloy-core'

testCompile gradleTestKit()

testCompile 'org.testng:testng'
Expand Down
2 changes: 2 additions & 0 deletions dependencies.properties
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
org.starchartlabs.alloy:alloy-core=0.4.1

org.testng:testng=6.9.10
34 changes: 34 additions & 0 deletions docs/dependency-versions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# org.starchartlabs.flare.dependency-versions

The `dependency-versions` plug-in is a configuration plug-in which adds a standard DSL extension `dependencyVersions` to allow loading dependency version constraints from a properties file

## Application

Apply the plug-in via the buildscript classpath:

```
buildscript {
repositories {
jcenter()
}
dependencies {
classpath group: 'org.starchartlabs.flare', name: 'flare-operations-plugins', version: '3.0.0'
}
}
apply plugin: 'org.starchartlabs.flare.dependency-versions'
```

## Use

To specify the publication information:

```
dependencyVersions {
propertiesFile file('...')
}
```

The file referenced is expected to be a properties file with lines in the form of

`group:artifact=version`
7 changes: 6 additions & 1 deletion flare-ops-gradle-test/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ credentials {
println "${credentials.bintray.username}"

allprojects{
apply plugin: 'java'
apply plugin: 'org.starchartlabs.flare.dependency-insight'
apply plugin: 'org.starchartlabs.flare.dependency-reporting'

Expand All @@ -32,8 +31,14 @@ allprojects{
}

subprojects{
apply plugin: 'java'
apply plugin: 'jacoco'
apply plugin: 'org.starchartlabs.flare.increase-test-logging'
apply plugin: 'org.starchartlabs.flare.dependency-versions'

dependencyVersions{
propertiesFile file("${rootDir}/dependencies.properties")
}

test {
useTestNG() {
Expand Down
3 changes: 3 additions & 0 deletions flare-ops-gradle-test/dependencies.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
org.starchartlabs.alloy:alloy-core=0.4.1

org.testng:testng=6.9.10
Binary file modified flare-ops-gradle-test/gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#Wed Jun 19 21:06:27 EDT 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.0-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.0-bin.zip
8 changes: 4 additions & 4 deletions flare-ops-gradle-test/gradlew
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,16 @@ APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
DEFAULT_JVM_OPTS='"-Xmx64m"'

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"

warn ( ) {
warn () {
echo "$*"
}

die ( ) {
die () {
echo
echo "$*"
echo
Expand Down Expand Up @@ -155,7 +155,7 @@ if $cygwin ; then
fi

# Escape application args
save ( ) {
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
Expand Down
2 changes: 1 addition & 1 deletion flare-ops-gradle-test/gradlew.bat
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DEFAULT_JVM_OPTS="-Xmx64m"

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* Copyright (C) 2019 [email protected] Authors
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
package org.starchartlabs.flare.operations.model;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.AbstractMap;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.stream.Collectors;

import org.gradle.api.GradleException;
import org.gradle.api.Project;
import org.gradle.api.artifacts.dsl.DependencyConstraintHandler;
import org.starchartlabs.alloy.core.Preconditions;
import org.starchartlabs.alloy.core.Strings;

/**
* Represents configuration for loading dependency version constraints from simple files
*
* @author romeara
* @since 3.0.0
*/
public class DependencyVersions {

private final Project project;

private Map<String, String> versionsByGroupArtifact;

public DependencyVersions(Project project) {
this.project = Objects.requireNonNull(project);

versionsByGroupArtifact = new HashMap<>();
}

public DependencyVersions propertiesFile(File propertiesFile) {
Objects.requireNonNull(propertiesFile);
Preconditions.checkArgument(propertiesFile.exists(),
Strings.format("Dependencies properties file %s does not exist", propertiesFile.getAbsolutePath()));

try {
// Can't load via Java Properties class, as it considers the ':' character the same way as '='
Map<String, String> dependencies = Files.lines(propertiesFile.toPath())
.map(String::trim)
.filter(line -> !line.isEmpty())
.filter(line -> !isCommentLine(line))
.map(this::parseVersions)
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));

versionsByGroupArtifact.putAll(dependencies);
} catch (IOException e) {
throw new GradleException(
Strings.format("Error loading properties file %s", propertiesFile.getAbsolutePath()));
}

project.getPluginManager().withPlugin("java-library", plugin -> {
project.getConfigurations().all(configuration -> {
apply(project.getDependencies().getConstraints(), configuration.getName());
});
});

project.getPluginManager().withPlugin("java", plugin -> {
project.getConfigurations().all(configuration -> {
apply(project.getDependencies().getConstraints(), configuration.getName());
});
});

return this;
}

private void apply(DependencyConstraintHandler constraintHandler, String configuration) {
versionsByGroupArtifact.entrySet().stream()
.map(entry -> entry.getKey() + ":" + entry.getValue())
.forEach(dependency -> constraintHandler.add(configuration, dependency));

versionsByGroupArtifact.entrySet().stream()
.forEach(entry -> project.getLogger().info("Applied {} dependency constraint: {}:{}",
configuration, entry.getKey(), entry.getValue()));
}

private boolean isCommentLine(String line) {
Objects.requireNonNull(line);

return line.startsWith("#");
}

private Entry<String, String> parseVersions(String line) {
Objects.requireNonNull(line);

// Handle lines with comments on the end
String propertyLine = line.split("#")[0].trim();

String[] parts = propertyLine.split("=");

Preconditions.checkArgument(parts.length == 2,
Strings.format("Invalid properties line format - expect format 'group:artifact=version' (%s)", line));

return new AbstractMap.SimpleEntry<>(parts[0], parts[1]);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright (C) 2019 [email protected] Authors
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
package org.starchartlabs.flare.operations.plugin;

import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.starchartlabs.flare.operations.model.DependencyVersions;

/**
* Configuration plug-in that adds structures for defining dependency constraints
*
* @author romeara
* @since 3.0.0
*/
public class DependencyVersionsPlugin implements Plugin<Project> {

@Override
public void apply(Project project) {
project.getExtensions().add("dependencyVersions", new DependencyVersions(project));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
implementation-class=org.starchartlabs.flare.operations.plugin.DependencyVersionsPlugin
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (C) 2019 [email protected] Authors
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
package org.starchartlabs.flare.test.operations.plugin;

import java.io.File;
import java.net.URL;

import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.GradleRunner;
import org.gradle.testkit.runner.TaskOutcome;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

public class DependencyVersionsPluginIntegrationTest {

private File testProjectDirectory;

@BeforeClass
public void setup() throws Exception {
URL directory = this.getClass().getClassLoader()
.getResource("org/starchartlabs/flare/test/dependency/versions");

testProjectDirectory = new File(directory.toURI());
}

@Test
public void appliesWithoutError() throws Exception {
BuildResult result = GradleRunner.create()
.withPluginClasspath()
.withProjectDir(testProjectDirectory)
.withArguments("clean")
.build();

TaskOutcome outcome = result.task(":clean").getOutcome();
Assert.assertTrue(TaskOutcome.SUCCESS.equals(outcome) || TaskOutcome.UP_TO_DATE.equals(outcome));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (C) 2019 [email protected] Authors
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
package org.starchartlabs.flare.test.operations.plugin;

import org.gradle.api.Project;
import org.gradle.testfixtures.ProjectBuilder;
import org.starchartlabs.flare.operations.model.DependencyVersions;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

public class DependencyVersionsPluginTest {

private static final String PLUGIN_ID = "org.starchartlabs.flare.dependency-versions";

private Project project;

@BeforeClass
public void setupProject() {
project = ProjectBuilder.builder().build();
project.getPluginManager().apply(PLUGIN_ID);
}

@Test
public void configurationApplied() throws Exception {
Object found = project.getExtensions().findByName("dependencyVersions");

Assert.assertNotNull(found);
Assert.assertTrue(found instanceof DependencyVersions);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
plugins {
id 'java'
id 'org.starchartlabs.flare.dependency-versions'
}

0 comments on commit a005441

Please sign in to comment.