Як виявити поточну ОС від Gradle


98

Я знайшов цю відповідь про те, як це зробити за допомогою Groovy:

Виявлення платформи (Window або Linux) за допомогою Groovy / Grails :

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

Чи є кращий спосіб?


це те, що я використовую без toLowerCase().contains()частини, оскільки мені просто потрібна назва.
Кевін Велкер,

Ви також можете отримати версію ОС, зSystem.getProperty('os.arch')
Кевін Велкер

13
"WINDOWS".toLowerCase()залежить від мови і повернеться wındows(зверніть увагу на безкрайній i) на машинах, де мова є турецькою. toLowerCase(Locale.ROOT)Натомість використовуйте, щоб бути в безпеці.
Маттіас Браун,

Відповіді:


125

Насправді, я подивився проект Gradle, і він виглядає трохи чистішим, оскільки використовує існуючу структуру Ant :

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

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

Я знайшов це в наступній гілці Gradle, і, здається, це працює добре. gradle / gradle-core / branch / RB-0.3 / build.gradle


7
будьте попереджені, Os.isFamily (Os.FAMILY_UNIX) поверне істину як для unix, так і для mac (тоді як Os.isFamily (Os.FAMILY_MAC) також діє
shabunc

3
Будьте обережні, це справді ОС і нічого не говорить про розпочате програму оболонки (наприклад, це може бути Mingw, Cygwin чи інша оболонка bash). Тому будьте обережні, якщо ви використовуєте це для зчитування змінних середовища, вони можуть бути не такими, як ви очікуєте.
estani

2
@shabunc має краще рішення, використовуючи org.gradle.internal.os.OperatingSystem
Пітер Кан,

task checkWin() << {навіщо це потрібно? Ви можете просто написатиif (Os.isFamily(Os.FAMILY_WINDOWS)) { println "*** WINDOWS " }
user25

також краще використовувати org.gradle.internal.os.OperatingSystemі if (OperatingSystem.current() == OperatingSystem.WINDOWS)(якщо ми говоримо про Gradle, чому б не використовувати власні реалізації)
user25,

67

Оновлення в середині 2020 року : все ще інкубується:

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

Оновлення на початку 2019 року : current()вилучено.

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

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

Майте на увазі, що це все ще інкубує .

Оновлення в середині 2018 року : так само, як це було згадано в коментарях, тепер цей клас перейшов на інший пакет, тому його слід використовуватиorg.gradle.nativeplatform.platform.OperatingSystem.current()


Станом на середину 2015 року відповідь Пітера Кана все ще діє. Активація профілів на основі середовища все ще робиться порівняно простіше у Maven. Але майте на увазі, що org.apache.tools.ant.taskdefs.condition.Os.isFamilyце не ексклюзивно в тому сенсі, що якщо воно повертає true з одним конкретним параметром, це не обов'язково означає, що воно повертає false для будь-якого іншого параметра. Наприклад:

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))
    }
}

Вона повертає істину як для Os.FAMILY_MACі Os.FAMILY_UNIXна MacOS. Зазвичай це не те, що потрібно у сценаріях побудови.

Існує хоч інший спосіб досягти цього за допомогою API Gradle 2+, а саме:

import org.gradle.internal.os.OperatingSystem;

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

Ознайомтеся з документацією щодо інтерфейсу org.gradle.nativeplatform.platform.OperatingSystem . Варто зазначити, що цей інтерфейс позначений інкубаційними анотаціями, тобто "функція в даний час знаходиться в стадії розробки і може змінитися в будь-який час". "Внутрішній" простір імен у реалізації також дає нам підказку, що ми повинні використовувати це, знаючи, що це може змінитися.

Але особисто я б погодився з цим рішенням. Просто краще написати клас обгортки, щоб не псувати, якщо щось зміниться в майбутньому.


8
Чи змінилося? Використання Gradle 2.5 OperatingSystem, здається, не було.current()
Росс Дрю

6
майте на увазі внутрішній пакет:org.gradle.internal.os.OperatingSystem.current()
Брайан

@danblack як ти отримуєш екземпляр OperatingSystemбез current()?
TWiStErRob

1
Знайдено один: OperatingSystem os = org.gradle.nativeplatform.platform.internal.DefaultNativePlatform.currentOperatingSystem; хотів би бути загальнодоступним @PeterNiederwieser
TWiStErRob

Оскільки Mac OS, Windows та Linux не є єдиними операційними системами, було б непогано, якщо б включили z / OS. Хоча в найменшій мірі, зробити вибір як не когось із інших міг би спрацювати.
Джон Чуккерманн,

18

Можна розрізнити середовище збірки між Linux, Unix, Windows та OS X - тоді як Gradle nativeplatform.platform.OperatingSystem диференціює цільове середовище (включаючи FreeBSD та 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.
}

Можна також використовувати завдання Ant ( джерело ):

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

task checkWin() << {
    if (Os.isFamily(Os.FAMILY_WINDOWS)) {
        // Consider Windows.
    }
}

7

Gradle не надає загальнодоступний API для виявлення операційної системи. Отже, os.властивості системи - це найкращий вибір.


7

Або ви можете визначити osName як рядок ...

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;
}

... і використовувати його пізніше - для включення власної бібліотеки, наприклад:

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

Але це нічого не змінить, оскільки OperatingSystem працює точно так само, як ваш код:

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;
    }
}

Джерело: https://github.com/gradle/gradle/blob/master/subprojects/base-services/src/main/java/org/gradle/internal/os/OperatingSystem.java

Редагувати:

Ви можете зробити те ж саме для архітектури:

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

і:

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

Тільки майте на увазі, що getArch () поверне:

  • "ppc" на PowerPC
  • "amd64" на 64b
  • "i386" АБО "x86" на 32b.

getArch () поверне "x86" на Solaris або "i386" для будь-якої іншої платформи.

Редагувати 2:

Або якщо ви хочете уникнути будь-якого імпорту, ви можете просто зробити це самостійно:

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);
}

4

Мені не подобається виявляти ОС у Gradle за допомогою властивостей або завдання Ant, і OperatingSystemклас більше не містить current()методу.

Отже, на мій погляд, найчистішим способом виявлення ОС буде:

Імпортувати DefaultNativePlatform:

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

Тоді використовуйте DefaultNativePlatformу своєму завданні:

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

Пам’ятайте, що цей метод не є ідеальним, оскільки він використовує внутрішній API Gradle.

Це тестували за допомогою Gradle 4.10.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.