74 votes

Comment obtenir le chemin du script en cours d'exécution dans groovy ?

J'écris un script groovy que je veux contrôler via un fichier de propriétés stocké dans le même dossier. Cependant, je veux pouvoir appeler ce script de n'importe où. Lorsque j'exécute le script, il recherche toujours le fichier de propriétés en fonction de l'endroit d'où il est exécuté, et non de l'endroit où se trouve le script.

Comment puis-je accéder au chemin du fichier script à partir du script ?

88voto

seansand Points 803

Vous avez raison de dire que new File(".").getCanonicalPath() ne fonctionne pas. Cela renvoie le répertoire de travail .

Pour obtenir le répertoire script, procédez comme suit

scriptDir = new File(getClass().protectionDomain.codeSource.location.path).parent

Pour obtenir le chemin d'accès au fichier script, procédez comme suit

scriptFile = getClass().protectionDomain.codeSource.location.path

1 votes

Intéressant. Il ne fonctionne pas comme je m'y attendais. Mais cela est dû au fait que j'exécute un script de gant. Donc le codeSource est en fait là où se trouve gant, pas là où se trouve mon script.

1 votes

Cela ne fonctionne pas pour moi. getClass().protectionDomain.codeSource renvoie un résultat nul. J'utilise Groovy 2.0.1.

0 votes

Ne fonctionne pas non plus sur la version 1.11, et renvoie quelque chose comme : .gradle/caches/1.11/scripts/build_189dc3r2nd588m3657jv5d36h7

22voto

M. Justin Points 911

Depuis Groovy 2.3.0, l'option @SourceURI peut être utilisée pour remplir une variable avec l'URI de l'emplacement du script. Cet URI peut ensuite être utilisé pour obtenir le chemin d'accès au script :

import groovy.transform.SourceURI
import java.nio.file.Path
import java.nio.file.Paths

@SourceURI
URI sourceUri

Path scriptLocation = Paths.get(sourceUri)

Notez que cela ne fonctionnera que si l'URI est un file: URI (ou un autre type de schéma URI avec un Fournisseur de système de fichiers ), sinon a Exception FileSystemNotFound sera lancé par l'outil Paths.get(URI) appel. En particulier, certaines exécutions Groovy telles que groovyshell et nextflow renvoient une valeur de data: qui ne correspondra généralement pas à un URI installé. FileSystemProvider .

11voto

Joshua Davis Points 1616

Cela a du sens si vous exécutez le code Groovy comme un script. Sinon, l'idée devient un peu confuse, IMO. La solution de contournement se trouve ici : https://issues.apache.org/jira/browse/GROOVY-1642

Il s'agit essentiellement de modifier startGroovy.sh pour qu'il transmette l'emplacement du script en tant que variable d'environnement.

Tant que cette information n'est pas fournie directement par Groovy, il est possible de modifier le script groovy.(sh|bat) starter script pour rendre cette propriété disponible en tant que propriété système : Pour les systèmes unix, il suffit de modifier $GROOVY_HOME/bin/groovy (le script de sh) pour qu'il fasse

export JAVA_OPTS="$JAVA_OPTS -Dscript.name=$0"

avant d'appeler startGroovy Pour Windows : Dans startGroovy.bat ajoutez les 2 lignes suivantes juste après la ligne avec l'étiquette :init (juste avant le début de l'utilisation des paramètres) :

@rem get name of script to launch with full path
set GROOVY_SCRIPT_NAME=%~f1

Un peu plus bas dans le fichier batch, après la ligne qui dit "set JAVA_OPTS=%JAVA_OPTS% -Dgroovy.starter.conf="%STARTER_CONF%", ajoutez la ligne suivante ligne

set JAVA_OPTS=%JAVA_OPTS% -Dscript.name="%GROOVY_SCRIPT_NAME%" 

1voto

Liem Le Points 128

Pour les utilisateurs de gradle

J'ai le même problème lorsque je commence à travailler avec gradle. Je veux compiler mon thrift par un compilateur thrift distant (personnalisé par ma société).

Voici comment j'ai résolu mon problème :

task compileThrift {
doLast {
        def projectLocation = projectDir.getAbsolutePath(); // HERE is what you've been looking for.
        ssh.run {
            session(remotes.compilerServer) {
                // Delete existing thrift file.
                cleanGeneratedFiles()
                new File("$projectLocation/thrift/").eachFile() { f ->
                    def fileName=f.getName()
                    if(f.absolutePath.endsWith(".thrift")){
                        put from: f, into: "$compilerLocation/$fileName"
                    }
                }
                execute "mkdir -p $compilerLocation/gen-java"
                def compileResult = execute "bash $compilerLocation/genjar $serviceName", logging: 'stdout', pty: true
                assert compileResult.contains('SUCCESSFUL')
                get from: "$compilerLocation/$serviceName" + '.jar', into: "$projectLocation/libs/"
            }
        }
    }
}

1voto

Naeel Maqsudov Points 206

Encore une solution. Cela fonctionne parfaitement même si vous exécutez le script à l'aide de GrovyConsole

File getScriptFile(){
    new File(this.class.classLoader.getResourceLoader().loadGroovySource(this.class.name).toURI())
}

println getScriptFile()

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X