Gradle or Groovy - how to convert URL to file? - gradle

In Gradle I have a file stored on the Internet that I would like to access. But I can't figure out how to convert a URL to a File in Gradle. I need the url to be converted to a file so I can pass it to tasks as a file. Here is what I have so far:
allprojects {
afterEvaluate { project ->
String file = new URL('http://techslides.com/demos/samples/sample.json').file
}
}
this is definetly not what i want. The file variable ends up being: demos/samples/sample.json so it looks like it's just taking the path from the url itself.
I need the actual sample.json to be stored in a File object. I would also prefer if possible to not have to write the file to local storage where it is accessible to other people as its a secure file.

The simplest way to do this:
def fileLocation = 'file://techslides.com/demos/samples/sample.json'
def fileURL = new URL(fileLocation)
def remoteFile = new File(fileURL.toURI())
See: File(URI uri)
Replace fileLocation with valid value for your task.

As of May 4, 2018, Gradle 4.8 RC1 or later, if you are facing this problem using checkstyle, you can use
checkstyle {
toolVersion = "8.13"
config project.resources.text.fromUri("${someUrl}/checkstyle.xml")
}
See https://github.com/gradle/gradle/issues/2663

Related

How do you access gradle.ext properties in Plugin Java source code?

I need a property to (one) be available when a plugin is applied and (two) allow for a calculated override value in the settings.gradle file. A project property would be ideal as it can have a default set in gradle.properties:
# gradle.properties
myProp=originalValue
This is great because it can be overrode with a command line argument like -PmyProp=newValue, but I was not able to find a good way to override the property in the settings.gradle file before the build.gradle executes (i.e. before the plugins are applied).
For instance all of these leave rootProject.myProp unaltered at plugin application:
// settings.gradle
rootProject.getProperties.put("myProp", "overrideValue")
settings.ext.myProp = "overrideValue"
settings.extensions.myProp = "overrideValue"
gradle.startParameters.projectProperties.myProp = "overrideValue"
We cannot do any magic in the build.gradle either because no logic can exist before the plugins block:
// build.gradle
plugins {
id 'com.myCompany.myPlugin' version 1.0.0 // 'myProp' must be set by now
}
One workaround I can think of would be to use:
// settings.gradle
gradle.ext.myProp = "overrideValue"
... but there doesn't seem to be a good way to access gradle.ext properties in Java source code (for a plugin), or is there?
This seems to work for the gradle.ext.myProp use case, but it is surprising to me that the only workable approach is to cast the Gradle object to an ExtensionAware object:
// MyPlugin.java
String myProp = (String) project.getRootProject().getProperties().getOrDefault("myProp", null);
Gradle gradle = project.getRootProject().getGradle();
if ((myProp == null) && (gradle instanceof ExtensionAware)) {
ExtensionAware gradleExtensions = (ExtensionAware) gradle;
myProp = (String) gradleExtensions.getExtensions().getExtraProperties().get("myProp");
}
It seems like what I'm trying to do should be commonplace, so is there a better way like solely using project properties?
If so, then how do you change the values in the settings.gradle file?
This is probably not what you’re looking for but maybe it still helps: have you considered an initialization script? In such a script it is possible to override a project property.
Example:
$ ./gradlew -PmyProp=originalValue properties | grep myProp
myProp: originalValue
$ ./gradlew -PmyProp=originalValue -I init.gradle properties | grep myProp
myProp: overrideValue
… where init.gradle is the following:
allprojects {
project.ext.myProp = 'overrideValue'
}
Note that there are also other ways of specifying the init script.

createStartScripts change script name

In an attempt to follow the doc, I added a task like this to my build.gradle file:
task createStartScripts(type: CreateStartScripts) {
applicationName = 'dc-coverage-calculator'
}
I then executed
./gradlew clean installDist
at which point I expected to find a file at build/install/dc-coverage-calculator/bin/dc-coverage-calculator, but no files with dc-coverage-calculator were created anywhere the build folder. Instead, gradle continued to use the default application name, based on the mainClassName.
I also tried removing the hyphens from the app name.
Unfortunately it doesn't work this way. You've added a new task whereas yo need to modify the existing one, which will be done this way:
startScripts {
applicationName = 'dc-coverage-calculator'
}
Grab a demo here.

How to upload file to artifactory generic repository with gradle?

I build app distribution with gradle, which a tar file contains everything needed. I created a generic repository in artifactory. I want to upload the tarball to the generic repository.
By looking up this documentation
http://www.jfrog.com/confluence/display/RTF/Gradle+Artifactory+Plugin
I didn't find a way to do so.
I am a new gradle and artifactory user, can anyone give me guide.
task uploadDistroTar(type: org._10ne.gradle.rest.RestTask) {
httpMethod = 'PUT'
uri = 'http://x.x.x.x:8081/artifactory/repo/foo.tar'
username = 'admin'
password = 'passwd'
requestContentType = groovyx.net.http.ContentType.BINARY
requestBody = new File("build/distributions/foo.tar").bytes
}
The easiest way will be to use the Gradle REST plugin. Just use the PUT request to upload the file to the repository you want.
More modern solution is to use Artifactory Java Client:
Artifactory artifactory = ArtifactoryClientBuilder.create()
.setUrl("ArtifactoryUrl")
.setUsername("username")
.setPassword("password")
.build();
java.io.File file = new java.io.File("fileToUpload.txt");
File result = artifactory.repository("RepoName").upload("path/to/newName.txt", file).doUpload();
Finally I find the solution by read the plugin's source code,
just set:
preemptiveAuth = true

Gradle: add config file to classpath

In a simple gradle project I have under the projects root a config folder with a config.json in it. I want to put this file on the path to read it.
def myconfigfile = new File("config", "config.json")
def configset = files(myconfigfile)
task runExample ( dependsOn: 'classes', type: JavaExec ) {
main = 'com.example.LoadConfigExample'
classpath = sourceSets.main.runtimeClasspath
classpath.add(configset)
args 'ARG1'
}
In the Java file I'm using the following to load the file:
URL u = LoadConfigExample.class.getResource("config.json");
Would it be better just to use relative paths and load via the file system? I don't want to put the file under src/main/resources.
If I understood well the best option seems to refer to the config.json via project.file method, for docs see here.
It will be:
project.file("confif${File.separator}config.json")

Test for created file with Spock in Gradle

I have task which generates picture, so I want to write test for it that compares this picture binary with picture previously generated in the resource folder.
def setupSpec() {
project = ProjectBuilder.builder().build()
generatePicTask = project.tasks.create(SomePlugin.GENERATE_PIC_TASK_NAME, GeneratePicTask)
}
def 'create Picture test'() {
when:
File fileName = new File("Info")
then:
generatePicTask.createPicture(fileName)
expect:
fileName.exists()==true
}
But there is error that
C:\Users\User\AppData\Local\Temp\gradle1393280218367058727projectDir\build\Info.PNG
(The system cannot find the path specified)
The picture is generated in the the action closure in the task generatePicTask.
The project object is dummy project so I don't know even it was executed. How I can fix this?
I see 3 problems with your current approach:
Your test shouldn't rely on the current working directory. Therefore instead of creating a file like this:
File fileName = new File("Info")
use a junit TemporaryFolder rule for example. have a look at
with using e.g. http://garygregory.wordpress.com/2010/01/20/junit-tip-use-rules-to-manage-temporary-files-and-folders/ for more details
It seems GeneratePicTask task not generate the 'build' directory
Ensure that the output directory (the parent folder of the created image exists). You can use gradle annotations e.g. #OuputDirectory to let gradle take care of that. otherwise before generating your image do something like 'fileName.parentfile.mkdirs'
In general the way to go is to split the configuration of your task and task execution:
generatePicTask.setPicture(fileName)
generatePicTask.create() // your #TaskAction annotated method
cheers,
René

Resources