Skip to content

Commit 47754d9

Browse files
committed
Add colors to terminal output
1 parent b4ad0c8 commit 47754d9

4 files changed

Lines changed: 74 additions & 15 deletions

File tree

README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,23 @@ It also sets some configuration options useful for development work and system a
77

88
Current actions that can be applied (each needs to be confirmed first):
99

10-
1. Install RPMFusion repositories.
10+
1. **Install RPMFusion repositories.**
1111
Adds free and nonfree RPMFusion repos and imports their GPG keys.
1212

13-
2. Install additional packages with DNF.
13+
2. **Install additional packages with DNF.**
1414
Installs extra packages listed in [dnf-install.cf](https://github.com/lfir/fedora-setup-script/blob/main/src/main/resources/dnf-install.cf), with the
1515
option to skip selected packages interactively.
1616

17-
3. Remove unnecessary packages.
17+
3. **Remove unnecessary packages.**
1818
Removes unwanted packages from [dnf-remove.cf](https://github.com/lfir/fedora-setup-script/blob/main/src/main/resources/dnf-remove.cf) and performs autoremove.
1919

20-
4. Install Flatpak applications.
20+
4. **Install Flatpak applications.**
2121
Adds the Flathub remote and installs Flatpaks from [flatpak-install.cf](https://github.com/lfir/fedora-setup-script/blob/main/src/main/resources/flatpak-install.cf).
2222

23-
5. Ensure groups exist and add user.
23+
5. **Ensure groups exist and add user.**
2424
Creates and assigns admin-related groups such as _docker_, _libvirt_, and _vboxusers_.
2525

26-
6. Enable and start Cockpit.
26+
6. **Enable and start Cockpit.**
2727
Enables and starts the systemd service of the Cockpit web-based management interface.
2828

2929
### Run commands

src/main/java/cf/maybelambda/fedora/PostInstallUpdater.java

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package cf.maybelambda.fedora;
22

33
import java.io.BufferedReader;
4+
import java.io.Console;
45
import java.io.IOException;
56
import java.io.InputStreamReader;
67
import java.util.ArrayList;
@@ -33,8 +34,11 @@ public class PostInstallUpdater {
3334
private static final String FLATPAK_INSTALL_FILE = "flatpak-install.cf";
3435
private static final String HELP_FILE = "help.txt";
3536

36-
private static final String RESET = "\u001B[0m";
37-
private static final String YELLOW = "\u001B[33m";
37+
static final String RESET = "\u001B[0m";
38+
static final String YELLOW = "\u001B[33m";
39+
static final String GREEN = "\u001B[32m";
40+
private static final String RED = "\u001B[31m";
41+
private static final String BLUE = "\u001B[34m";
3842

3943
private static boolean dryRun = false;
4044

@@ -49,10 +53,10 @@ public static void main(String[] args) {
4953
List<String> flatpakInstallPackages = ConfigManager.loadPackageNamesFrom(FLATPAK_INSTALL_FILE);
5054
Scanner scanner = new Scanner(System.in);
5155

52-
System.out.println("Fedora Post Install Actions\n");
56+
System.out.println(color("Fedora Post Install Actions\n", GREEN));
5357
setDryRun(Arrays.asList(args).contains("--dry-run"));
5458
if (isDryRun()) {
55-
System.out.println("---[Dry Run Mode] Shell Commands will not be executed.---\n");
59+
System.out.println(color("---[Dry Run Mode] Shell Commands will not be executed.---\n", RED));
5660
}
5761

5862
if (confirm(scanner, "Install RPMFusion repos?")) {
@@ -130,7 +134,7 @@ public static void main(String[] args) {
130134
runCommand(new String[]{"sudo", "systemctl", "enable", "--now", "cockpit.socket"});
131135
}
132136

133-
System.out.println("\nAll actions completed. Goodbye.");
137+
System.out.println(color("\nAll actions completed. Goodbye.", GREEN));
134138
}
135139

136140
static boolean isDryRun() {
@@ -152,9 +156,9 @@ static ProcessBuilder createProcessBuilder(String[] cmd) {
152156
}
153157

154158
static int runCommand(String[] command) {
155-
System.out.println("Executing shell command: " + String.join(" ", command));
159+
System.out.println("Executing shell command: " + color(String.join(" ", command), BLUE));
156160
if (isDryRun()) {
157-
System.out.println("Dry-run: command not executed.");
161+
System.out.println(color("Dry-run: command not executed.", YELLOW));
158162
return 0;
159163
}
160164

@@ -167,7 +171,7 @@ static int runCommand(String[] command) {
167171
System.out.println("Command output:");
168172
String line;
169173
while ((line = reader.readLine()) != null) {
170-
System.out.println(YELLOW + line + RESET);
174+
System.out.println(color(line, YELLOW));
171175
}
172176
exitCode = process.waitFor();
173177
System.out.println("Command exited with code: " + exitCode);
@@ -214,4 +218,12 @@ static void printHelp() {
214218
System.err.println("Error reading help file: " + e.getMessage());
215219
}
216220
}
221+
222+
static String color(String str, String ansiColorCode) {
223+
return isANSISupported(System.getenv("TERM"), System.console()) ? ansiColorCode + str + RESET : str;
224+
}
225+
226+
static boolean isANSISupported(String term, Console console) {
227+
return console != null && term != null && !"dumb".equals(term);
228+
}
217229
}

src/test/java/cf/maybelambda/fedora/ConfigManagerTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ void readResourceLinesThrowsIOExceptionWhenResourceMissing() {
5454
}
5555

5656
@Test
57-
void loadPackageNamesFromValidFileParsesPackageNamesAndOmitsComments() throws IOException {
57+
void loadPackageNamesFromValidFileParsesPackageNamesAndOmitsComments() {
5858
try (MockedStatic<ConfigManager> updaterMock = Mockito.mockStatic(ConfigManager.class, CALLS_REAL_METHODS)) {
5959
updaterMock.when(() -> ConfigManager.readResourceLines(any(String.class)))
6060
.thenReturn(List.of("# Comment", "nano", "vim", "", "htop"));

src/test/java/cf/maybelambda/fedora/PostInstallUpdaterTests.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,16 @@
55
import org.mockito.Mockito;
66

77
import java.io.ByteArrayInputStream;
8+
import java.io.Console;
89
import java.io.IOException;
910
import java.nio.charset.StandardCharsets;
1011
import java.util.List;
1112
import java.util.Scanner;
1213

14+
import static cf.maybelambda.fedora.PostInstallUpdater.GREEN;
15+
import static cf.maybelambda.fedora.PostInstallUpdater.RESET;
16+
import static cf.maybelambda.fedora.PostInstallUpdater.YELLOW;
17+
import static cf.maybelambda.fedora.PostInstallUpdater.isANSISupported;
1318
import static org.junit.jupiter.api.Assertions.assertEquals;
1419
import static org.junit.jupiter.api.Assertions.assertFalse;
1520
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -141,4 +146,46 @@ void helpOptionDisplaysHelpTextAndExits() {
141146
filesMock.verify(() -> ConfigManager.readResourceLines(any(String.class)), Mockito.times(2));
142147
}
143148
}
149+
150+
@Test
151+
void colorAppliesAnsiWhenisANSISupportedTrue() {
152+
try (MockedStatic<PostInstallUpdater> mocked = mockStatic(PostInstallUpdater.class, CALLS_REAL_METHODS)) {
153+
mocked.when(() -> isANSISupported(any(), any())).thenReturn(true);
154+
155+
String result = PostInstallUpdater.color("Hello", YELLOW);
156+
157+
assertEquals(YELLOW + "Hello" + RESET, result);
158+
}
159+
}
160+
161+
@Test
162+
void colorReturnsPlainTextWhenisANSISupportedFalse() {
163+
try (MockedStatic<PostInstallUpdater> mocked = mockStatic(PostInstallUpdater.class, CALLS_REAL_METHODS)) {
164+
mocked.when(() -> isANSISupported(any(), any())).thenReturn(false);
165+
166+
String result = PostInstallUpdater.color("World", GREEN);
167+
168+
assertEquals("World", result);
169+
}
170+
}
171+
172+
@Test
173+
void isANSISupportedReturnsTrueWhenConsolePresentAndTermValid() {
174+
assertTrue(isANSISupported("xterm-256color", mock(Console.class)));
175+
}
176+
177+
@Test
178+
void isANSISupportedReturnsFalseWhenConsoleNull() {
179+
assertFalse(isANSISupported("xterm-256color", null));
180+
}
181+
182+
@Test
183+
void isANSISupportedReturnsFalseWhenTermNull() {
184+
assertFalse(isANSISupported(null, mock(Console.class)));
185+
}
186+
187+
@Test
188+
void isANSISupportedReturnsFalseWhenTermIsDumb() {
189+
assertFalse(isANSISupported("dumb", mock(Console.class)));
190+
}
144191
}

0 commit comments

Comments
 (0)