Как определить текущую ОС из Gradle


99

Я нашел этот ответ о том, как это сделать с 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)Вместо этого используйте на всякий случай.
Маттиас Браун,

Ответы:


128

На самом деле, я посмотрел на проект Gradle, и он выглядит немного чище, поскольку он использует существующую структуру Ant :

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

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

Я нашел это в следующей ветке Gradle, и, похоже, он отлично работает. Градл / ядро-градиент / ветви / RB-0.3 / build.gradle


8
будьте осторожны, Os.isFamily (Os.FAMILY_UNIX) вернет true как для unix, так и для Mac (в то время как Os.isFamily (Os.FAMILY_MAC) также действителен
shabunc

3
Будьте осторожны, это действительно ОС и ничего не говорится о запущенной оболочке gradle (например, это может быть Mingw, Cygwin или другая оболочка bash). Поэтому будьте осторожны, если вы используете это для чтения переменных среды, они могут быть не такими, как вы ожидаете.
Estani

2
У @shabunc есть лучшее решение, использующее org.gradle.internal.os.OperatingSystem
Питер Кан

task checkWin() << {Зачем тебе это? вы можете просто написатьif (Os.isFamily(Os.FAMILY_WINDOWS)) { println "*** WINDOWS " }
user25 09

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

70

Обновление середины 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"
}

Но это ничего не изменит, поскольку операционная система работает точно так же, как ваш код:

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.