Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
*
* @author Phillip Webb
* @author Yong-Hyun Kim
* @author Philemon Hilscher
* @since 1.0.0
*/
public abstract class AnsiOutput {
Expand All @@ -43,8 +44,6 @@ public abstract class AnsiOutput {

private static @Nullable Boolean ansiCapable;

private static final String OPERATING_SYSTEM_NAME = System.getProperty("os.name").toLowerCase(Locale.ENGLISH);

private static final String ENCODE_START = "\033[";

private static final String ENCODE_END = "m";
Expand Down Expand Up @@ -171,13 +170,35 @@ private static boolean detectIfAnsiCapable() {
}
}
}
return !(OPERATING_SYSTEM_NAME.contains("win"));
if (isWindows(System.getProperty("os.name"))) {
return isWindowsAnsiCapable(System.getProperty("os.version"));
}
return true;
}
catch (Throwable ex) {
return false;
}
}

static boolean isWindows(String osName) {
return osName.toLowerCase(Locale.ENGLISH).contains("win");
}

static boolean isWindowsAnsiCapable(String osVersion) {
String[] parts = osVersion.split("\\.");
if (parts.length >= 2) {
try {
int major = Integer.parseInt(parts[0]);
int minor = Integer.parseInt(parts[1]);
// ANSI support on Windows 10 = 10.0, Build 10586+
return (major > 10) || (major == 10 && minor >= 0);
} catch (NumberFormatException ex) {
return false;
}
}
return false;
}

/**
* Possible values to pass to {@link AnsiOutput#setEnabled}. Determines when to output
* ANSI escape sequences for coloring application output.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,25 @@

package org.springframework.boot.ansi;

import java.util.stream.Stream;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import org.springframework.boot.ansi.AnsiOutput.Enabled;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;

/**
* Tests for {@link AnsiOutput}.
*
* @author Phillip Webb
* @author Philemon Hilscher
*/
class AnsiOutputTests {

Expand All @@ -48,4 +55,42 @@ void encoding() {
assertThat(encoded).isEqualTo("ABDEF");
}

private static Stream<Arguments> provideOsNames() {
return Stream.of(
Arguments.of("", false),
Arguments.of("Windows 7", true),
Arguments.of("Windows 8", true),
Arguments.of("Windows 8.1", true),
Arguments.of("Windows 10", true),
Arguments.of("Windows 11", true),
Arguments.of("Linux", false),
Arguments.of("Mac OS X", false),
Arguments.of("Mac OS", false)
);
}

@ParameterizedTest
@MethodSource("provideOsNames")
void testDetectIfIsWindows(String osName, boolean expected) {
boolean actual = AnsiOutput.isWindows(osName);
assertEquals(expected, actual);
}

private static Stream<Arguments> provideOsVersionNumbers() {
return Stream.of(
Arguments.of("", false),
Arguments.of("6.1", false), // Windows 7 / Server 2008 R2
Arguments.of("6.2", false), // Windows 8 / Server 2012
Arguments.of("6.3", false), // Windows 8.1 / Server 2012 R2
Arguments.of("10.0", true) // Windows 10 / 11 / Server 2016+
);
}

@ParameterizedTest
@MethodSource("provideOsVersionNumbers")
void testDetectIfIsWindowsAnsiCapable(String osVersion, boolean expected) {
boolean actual = AnsiOutput.isWindowsAnsiCapable(osVersion);
assertEquals(expected, actual);
}

}