Comment détecter le système d'exploitation actuel de Gradle

98

J'ai trouvé cette réponse sur la façon de le faire avec Groovy:

Détection de la plateforme (Windows ou Linux) par Groovy / Grails :

if (System.properties['os.name'].toLowerCase().contains('windows')) {
    println "it's Windows"
} else {
    println "it's not Windows"
}

Y a-t-il un meilleur moyen?

Daniel Sperry
la source
c'est ce que j'utilise, sans la toLowerCase().contains()pièce, car j'ai juste besoin du nom.
Kevin Welker
Vous pouvez également obtenir la version OS, avecSystem.getProperty('os.arch')
Kevin Welker
13
"WINDOWS".toLowerCase()dépend de la locale et retournera wındows(notez le i sans point) sur les machines où la locale est turque. Utilisez toLowerCase(Locale.ROOT)plutôt pour être du bon côté.
Matthias Braun

Réponses:

125

En fait, j'ai regardé le projet Gradle, et cela semble un peu plus propre car il utilise la structure existante d'Ant :

import org.apache.tools.ant.taskdefs.condition.Os

task checkWin() << {
    if (Os.isFamily(Os.FAMILY_WINDOWS)) {
        println "*** Windows "
    }
}

J'ai trouvé cela dans la branche Gradle suivante, et cela semble bien fonctionner. gradle / gradle-core / branches / RB-0.3 / build.gradle

Peter Kahn
la source
7
être averti, Os.isFamily (Os.FAMILY_UNIX) retournera true à la fois pour unix et mac (tandis que Os.isFamily (Os.FAMILY_MAC) est également valide
shabunc
3
Attention, il s'agit bien du système d'exploitation et ne dit rien sur le shell gradle démarré (par exemple, il peut s'agir de Mingw, Cygwin ou autre shell bash). Faites donc attention si vous l'utilisez pour lire des variables d'environnement, elles ne correspondent peut-être pas à vos attentes.
estani
2
@shabunc a une meilleure solution en utilisant org.gradle.internal.os.OperatingSystem
Peter Kahn
task checkWin() << {Pourquoi en avez-vous besoin? vous pouvez juste écrireif (Os.isFamily(Os.FAMILY_WINDOWS)) { println "*** WINDOWS " }
user25
il est également préférable d'utiliser org.gradle.internal.os.OperatingSystemet if (OperatingSystem.current() == OperatingSystem.WINDOWS)(si nous parlons de Gradle, pourquoi ne pas utiliser leurs propres implémentations)
user25
67

Mise à jour mi-2020 : toujours en incubation:

OperatingSystem os = org.gradle.nativeplatform.platform.internal.DefaultNativePlatform.currentOperatingSystem; 

Mise à jour début 2019 : current()supprimée.

org.gradle.nativeplatform.platform.OperatingSystem.getDisplayName()

org.gradle.nativeplatform.platform.OperatingSystem.isLinux()

Gardez à l'esprit qu'il est toujours en incubation .

Mise à jour mi-2018 : tout comme cela a été mentionné dans les commentaires, cette classe est maintenant déplacée vers un package différent, il faut donc utiliserorg.gradle.nativeplatform.platform.OperatingSystem.current()


À la mi-2015, la réponse de Peter Kahn est toujours valable. L'activation de profil basée sur l'environnement est toujours quelque chose de relativement plus facile dans Maven. Mais gardez à l'esprit que ce org.apache.tools.ant.taskdefs.condition.Os.isFamilyn'est pas exclusif dans le sens où s'il renvoie true avec un paramètre particulier, cela ne signifie pas nécessairement qu'il renvoie false pour tout autre paramètre. Par exemple:

import org.apache.tools.ant.taskdefs.condition.Os
task detect {
    doLast {
        println(Os.isFamily(Os.FAMILY_WINDOWS))
        println(Os.isFamily(Os.FAMILY_MAC))
        println(Os.isFamily(Os.FAMILY_UNIX))
    }
}

Cela reviendra vrai à la fois pour Os.FAMILY_MACet Os.FAMILY_UNIXsur MacOS. Ce n'est généralement pas quelque chose dont vous avez besoin dans les scripts de construction.

Il existe cependant un autre moyen d'y parvenir en utilisant l'API Gradle 2+, à savoir:

import org.gradle.internal.os.OperatingSystem;

task detect {
    doLast {
        println(OperatingSystem.current().isMacOsX())
        println(OperatingSystem.current().isLinux())
    }
}

Consultez la documentation de l' interface org.gradle.nativeplatform.platform.OperatingSystem . Il convient de mentionner que cette interface est marquée d'une annotation d' incubation , c'est-à-dire que "la fonctionnalité est actuellement en cours de travail et peut changer à tout moment". L'espace de noms "interne" dans l'implémentation nous donne également une indication que nous devrions l'utiliser en sachant que cela peut changer.

Mais personnellement, j'irais avec cette solution. C'est juste qu'il vaut mieux écrire une classe wrapper pour ne pas gâcher au cas où quelque chose changerait dans le futur.

shabunc
la source
8
Cela a-t-il changé? L'utilisation de Gradle 2.5 OperatingSystemne semble pas avoir.current()
Ross Drew
6
attention au paquet interne:org.gradle.internal.os.OperatingSystem.current()
Brian
@danblack comment obtenir une instance de OperatingSystemsans current()?
TWiStErRob
1
Trouvé un: OperatingSystem os = org.gradle.nativeplatform.platform.internal.DefaultNativePlatform.currentOperatingSystem; souhaite qu'il y en ait un public @PeterNiederwieser
TWiStErRob
Étant donné que Mac OS, Windows et Linux ne sont pas les seuls systèmes d'exploitation, ce serait bien si z / OS était inclus. Bien que dans une pincée, faire le choix comme n'étant aucun des autres pourrait fonctionner.
John Czukkermann
18

On peut différencier l' environnement de construction entre Linux, Unix, Windows et OS X - tandis que Gradle nativeplatform.platform.OperatingSystem différencie l' environnement cible (y compris FreeBSD et Solaris ).

import org.gradle.internal.os.OperatingSystem

String osName = OperatingSystem.current().getName();
String osVersion = OperatingSystem.current().getVersion();
println "*** $osName $osVersion was detected."

if (OperatingSystem.current().isLinux()) {
    // Consider Linux.
} else if (OperatingSystem.current().isUnix()) {
    // Consider UNIX.
} else if (OperatingSystem.current().isWindows()) {
    // Consider Windows.
} else if (OperatingSystem.current().isMacOsX()) {
    // Consider OS X.
} else {
    // Unknown OS.
}

On peut également utiliser une tâche Ant ( source ):

import org.apache.tools.ant.taskdefs.condition.Os

task checkWin() << {
    if (Os.isFamily(Os.FAMILY_WINDOWS)) {
        // Consider Windows.
    }
}
Martin Zeitler
la source
7

Gradle ne fournit pas d'API publique pour détecter le système d'exploitation. Par conséquent, les os.propriétés du système sont votre meilleur choix.

Peter Niederwieser
la source
7

Ou vous pouvez définir osName comme une chaîne ...

import org.gradle.internal.os.OperatingSystem

switch (OperatingSystem.current()) {
    case OperatingSystem.LINUX:
        project.ext.osName = "Linux";
        break;
    case OperatingSystem.MAC_OS:
        project.ext.osName = "macOS";
        break;
    case OperatingSystem.WINDOWS:
        project.ext.osName = "Windows";
        break;
}

... et l'utiliser plus tard - pour inclure une bibliothèque native par exemple:

run {
    systemProperty "java.library.path", "lib/$osName"
}

Mais cela ne changerait rien puisque OperatingSystem fonctionne exactement comme votre code:

public static OperatingSystem forName(String os) {
    String osName = os.toLowerCase();
    if (osName.contains("Windows")) {
        return WINDOWS;
    } else if (osName.contains("mac os x") || osName.contains("darwin") || osName.contains("osx")) {
        return MAC_OS;
    } else if (osName.contains("sunos") || osName.contains("solaris")) {
        return SOLARIS;
    } else if (osName.contains("linux")) {
        return LINUX;
    } else if (osName.contains("freebsd")) {
        return FREE_BSD;
    } else {
        // Not strictly true
        return UNIX;
    }
}

Source: https://github.com/gradle/gradle/blob/master/subprojects/base-services/src/main/java/org/gradle/internal/os/OperatingSystem.java

Éditer:

Vous pouvez faire de même pour l'architecture:

project.ext.osArch = OperatingSystem.current().getArch();
if ("x86".equals(project.ext.osArch)) {
    project.ext.osArch = "i386";
}

et:

run {
    systemProperty "java.library.path", "lib/$osName/$osArch"
}

Sachez simplement que getArch () retournera:

  • "ppc" sur PowerPC
  • "amd64" sur 64b
  • "i386" OU "x86" sur 32b.

getArch () retournera "x86" sur Solaris ou "i386" pour toute autre plate-forme.

Modifier 2:

Ou si vous souhaitez éviter toute importation, vous pouvez simplement le faire vous-même:

def getOsName(project) {
    final String osName = System.getProperty("os.name").toLowerCase();

    if (osName.contains("linux")) {
        return ("linux");
    } else if (osName.contains("mac os x") || osName.contains("darwin") || osName.contains("osx")) {
        return ("macos");
    } else if (osName.contains("windows")) {
        return ("windows");
    } else if (osName.contains("sunos") || osName.contains("solaris")) {
        return ("solaris");
    } else if (osName.contains("freebsd")) {
        return ("freebsd");
    }
    return ("unix");
}

def getOsArch(project) {
    final String osArch = System.getProperty("os.arch");

    if ("x86".equals(osArch)) {
        return ("i386");
    }
    else if ("x86_64".equals(osArch)) {
        return ("amd64");
    }
    else if ("powerpc".equals(osArch)) {
        return ("ppc");
    }
    return (osArch);
}
tirz
la source
4

Je n'aime pas détecter le système d'exploitation dans Gradle via des propriétés ou une tâche Ant, et la OperatingSystemclasse ne contient plus la current()méthode.

Donc, à mon avis, le moyen le plus propre de détecter le système d'exploitation serait:

Importer DefaultNativePlatform:

import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform

Ensuite, utilisez DefaultNativePlatformdans votre tâche:

if (DefaultNativePlatform.getCurrentOperatingSystem().isWindows()) {
   println 'Windows'
}

Gardez à l'esprit que cette méthode n'est pas idéale car elle utilise l'API interne de Gradle.

Il a été testé avec Gradle 4.10.

Ruslan Pilin
la source