In several Tasks, I reference jars in my home folder.
Is there a better way to get Environment Variables than
ENV = System.getenv()
HOME = ENV['HOME']
task copyToServer(dependsOn: 'jar', type: Copy) {
from 'build/libs/'
into HOME + "/something/plugins/"
}
This sets $HOME but I was hoping that I missed some magic from the documentation.
Well; this works as well:
home = "$System.env.HOME"
It's not clear what you're aiming for.
I couldn't get the form suggested by #thoredge to work in Gradle 1.11, but this works for me:
home = System.getenv('HOME')
It helps to keep in mind that anything that works in pure Java will work in Gradle too.
In android gradle 0.4.0 you can just do:
println System.env.HOME
classpath com.android.tools.build:gradle-experimental:0.4.0
This is for Kotlin DSL (build.gradle.kts):
val myVariable = System.getenv("MY_VARIABLE_NAME") ?: "my default value"
OR
val myVariable = System.getenv("MY_VARIABLE_NAME") ?: error("Env variable not found")
OR
val environment = System.getenv()
val myVariable = environment["MY_VARIABLE_NAME"] ?: "my default value"
// OR val myVariable = environment["MY_VARIABLE_NAME"] ?: error("Env variable not found")
Related
So I am sure this is something very dumb mistake, but I need your help since I am not a gradle expert.
TASK:
read versionCode from file add +1 to it and save it back.
task executeOrderSixtySix {
def versionPropsFile = file('versionCodes.properties')
if (versionPropsFile.canRead()) {
def Properties versionProps = new Properties()
versionProps.load(new FileInputStream(versionPropsFile))
def versionNumber = versionProps['DEV_VERSION'].toInteger() + 1
versionProps['DEV_VERSION'] = versionNumber.toString()
versionProps.store(versionPropsFile.newWriter(), null)
// 'assembleDebug'
} else {
throw new GradleException("Nyeeeh on versionCodes.properties!")
}}
So when I have to do an internal drop I would like to run this task first, increase the devVersion number by 1 and then run the 'assemble' task to build all artifacts.
PROBLEM:
This task executes itself, even if I just sync the cradle file causing increased versionCode all the time.
I don't want to increase the versionCode during sync, development build only just for QAdrop, when I also have to assemble every APK.
Could you please help me out and tell me why is this task getting called/executed and who can I prevent it?
You need a doLast block inside of your task block. build.gradle file is a configuration script so it reads as declare the task when on configuration and declare the action on the execution.
Anything done in the task either before or after the doLast block would be run during configuration time. The code in the doLast block itself runs at execution time.
task executeOrderSixtySix {
doLast {
def versionPropsFile = file('versionCodes.properties')
if (versionPropsFile.canRead()) {
def Properties versionProps = new Properties()
versionProps.load(new FileInputStream(versionPropsFile))
def versionNumber = versionProps['DEV_VERSION'].toInteger() + 1
versionProps['DEV_VERSION'] = versionNumber.toString()
versionProps.store(versionPropsFile.newWriter(), null)
// 'assembleDebug'
} else {
throw new GradleException("Nyeeeh on versionCodes.properties!")
}
}
}
Ref: https://www.oreilly.com/learning/write-your-own-custom-tasks-in-gradle
I have been reading as many posts as possible about this topic but none of them suggest working solutions for me, so, throwing it again to the community:
In a Jenkinsfile pipeline I have
steps {
(...)
sh script: '''
$pkgname #existing var
export report_filename=$pkgname'_report.txt'
(stuff is being written to the $report_filename file...)
'''
}
post {
always {
script {
//want to read the file with name carried by $report_filename
def report = readFile(file: env.report_filename, encoding: 'utf-8').trim()
buildDescription(report)
}
}
}
I don't manage to pass the value of the report_filename bash var on to the post > always > script section. Tried ${env.report_filename} (with/without single/double quotes), with/without env. and some other crazy things.
What am I doing wrong here?
Thanks.
May by it little bit not right.
create variable def var
use options returnStdout: true. And parse output. var = sh ( script " echo #existing var", returnStdout: true).split("\n")
use var[0] in stage readFile(file: var[0]...)
If u can use env, add:
environment {
VAR = sh (script " echo #existing var", returnStdout: true).split("\n") [0]
}
script {
//want to read the file with name carried by $report_filename
def report = readFile(file: env.VAR , encoding: 'utf-8').trim()
buildDescription(report)
}
I don't see why you don't simply declare the variables in Groovy right at the start.
I'm not too familiar with the language, and don't currently have a way to test this; but something like this:
def pkgname = "gunk"
def report_filename = "${pkgname}_report.txt"
steps {
(...)
sh script: """
# use triple double quotes so that Groovy variables are interpolated
# $pkgname #syntax error, take it out
(stuff is being written to the $report_filename file...)
"""
}
post {
always {
script {
//want to read the file with name carried by $report_filename
def report = readFile(file: env.report_filename, encoding: 'utf-8').trim()
buildDescription(report)
}
}
}
I'm using Quamotion and Pester to test my mobile app.
Right now, I find myself having to repeat a lot of parameters (such as usernames and passwords) which I use in my tests.
Is there any way to use global variables in Quamotion/Pester tests?
You define global variables in Pester by prefixing them with $script:. Global variables are normally defined at the top of your script.
For example, here's a test which logs in to your app and stores the username as a variable:
$script:username = "myuser"
Describe "My App" {
it "Login" {
$usernameTextField = Find-Element -xpath "//XCUIElementTypeTextField[#name='username']"
Set-Value -elementId $usernameTextField -value $script:username
$loginButton = Find-Element -xpath "//XCUIElementTypeButton[#name='Login']"
Click-Element -elementId $loginButton
}
}
Hope it helps!
This question explains how to use System.in when running a task to run a specific class in a project.
But for me currently it's not working: although I have included the application plugin and the following lines in build.gradle:
mainClassName = "misc.StreamsExp"
run{
standardInput = System.in
}
task stream( type: JavaExec, dependsOn: assemble ){
classpath sourceSets.main.runtimeClasspath
main = "misc.StreamsExp"
}
the line with readLine in the app code below should be blocking but it's not:
BufferedReader br = new BufferedReader(new InputStreamReader( System.in ));
String enteredLine = "";
while( enteredLine == null || ! enteredLine.equals( "q" )){
System.out.println( "spuds");
enteredLine = br.readLine();
}
... instead the thing just spins on forever:
spuds
spuds
spuds
...
NB I am on a Windows 10 OS, with Java 8.91. I have tried both the Windows DOS console and Cygwin.
NB2 The same thing occurs when I run this stream task inside Eclipse (Gradle STS Eclipse plugin)... but not when I do Run as --> Java application: then the blocking occurs as expected.
Hah... one of those sits where you think you're gonna be stumped forever and you find the solution 2 mins after posting to SO! I'll leave it here for anyone else...
The answer is to put the line standardInput = in the task you're running, like so:
task stream( type: JavaExec, dependsOn: assemble ){
standardInput = System.in
classpath sourceSets.main.runtimeClasspath
main = "misc.StreamsExp"
}
Strangely, the prompt "spuds" is followed in the Windows DOS terminal by
> Building 88% > :stream
... which is a known "bug" referred to in the question I referenced. In Cygwin this bug does not happen.
CAVEAT: this works in the Windows DOS terminal and the Cygwin terminal... it does NOT solve the problem when running the bespoke stream task in Eclipse!
If I have a java jar or class file which is launched by the user (assuming java path is set in environment variables), so how can i from within the code, figure out absolute path of java.exe/javaw.exe from which this file is being launched.
Like on ubuntu we can run: % which java and it shows the path.
However on windows, if i check System.getenv() it may happen that there are multiple path's found e.g for old or new version. If through cmd line, I run java -version it does not show the path.
Can you tell me either through pure java or command line on windows how is it possible to find out the location of javaw.exe?
String javaHome = System.getProperty("java.home");
Can you tell me either through pure Java ... on windows how is it possible to find out the location of javaw.exe?
E.G.
import java.io.File;
class JavawLocation {
public static void main(String[] args) {
String javaHome = System.getProperty("java.home");
File f = new File(javaHome);
f = new File(f, "bin");
f = new File(f, "javaw.exe");
System.out.println(f + " exists: " + f.exists());
}
}
Output
C:\Program Files (x86)\Java\jdk1.6.0_29\jre\bin\javaw.exe exists: true
Press any key to continue . . .
And yes, I am confident that will work in a JRE.
On Windows, the java.library.path System Property begins with the path to the bin directory containing whichever java.exe was used to run your jar file.
This makes sense, because on Windows the first place any executable looks for DLL files is the directory containing the executable itself. So naturally, when the JVM runs, the first place it looks for DLLs is the directory containing java.exe.
You can acquire the path to java.exe as follows:
final String javaLibraryPath = System.getProperty("java.library.path");
final File javaExeFile = new File(
javaLibraryPath.substring(0, javaLibraryPath.indexOf(';')) + "\\java.exe"
);
final String javaExePath =
javaExeFile.exists() ? javaExeFile.getAbsolutePath() : "java";
This code is Windows-specific - I hard-coded the path separator (;) and the file separator (). I also put in a fallback to just "java" in case the library path trick somehow doesn't work.
I have tested this with Java 6 and 7 on Windows 7. I tried a 32-bit and 64-bit version of Java.
Here's a slightly more generalised solution that I came up with. Maybe useful:
private static String javaExe()
{
final String JAVA_HOME = System.getProperty("java.home");
final File BIN = new File(JAVA_HOME, "bin");
File exe = new File(BIN, "java");
if (!exe.exists())
{
// We might be on Windows, which needs an exe extension
exe = new File(BIN, "java.exe");
}
if (exe.exists())
{
return exe.getAbsolutePath();
}
try
{
// Just try invoking java from the system path; this of course
// assumes "java[.exe]" is /actually/ Java
final String NAKED_JAVA = "java";
new ProcessBuilder(NAKED_JAVA).start();
return NAKED_JAVA;
}
catch (IOException e)
{
return null;
}
}
an issue with using "System.getProperty("java.home");", is that it is not always the java exe that the jar is running on, if you want to get that, you can use "System.getProperty("sun.boot.library.path");", from there you can find "java", "java.exe", "javaw", or "javaw.exe"... However there is still an issue with this, java will run just fine if the executable has been renamed, and the actual java executable's structure changes from different JRE's/JDKS's, so there is not much way to find the java exe if it has been renamed. unless someone else has a method ofc, in which case, can you share? :)
(Also, I have seen some people suggest using the first index of System.getProperty("java.library.path");, note, this might not work if the user/launcher has manually set the library path, something which is not too uncommon)
Compilation of All above methods
static String getJavaPath(){
String tmp1 = System.getProperty("java.home") + "\\bin\\java.exe";
String tmp2 = System.getProperty("sun.boot.library.path") + "\\java.exe";
String tmp3 = System.getProperty("java.library.path")+ "\\java.exe";
if(new File(tmp1).exists()) {
return tmp1;
}else if(new File(tmp2).exists()){
return tmp2;
}else if(new File(tmp3).exists()) {
return tmp3;
}else{
String[] paths = System.getenv("PATH").split(";");
for(String path:paths){
if(new File(path + "\\java.exe").exists()){
return path + "\\java.exe";
}
}
}
return "";
}