diff --git a/0001-Bring-back-the-AnsiRenderer-fixes-184.patch b/0001-Bring-back-the-AnsiRenderer-fixes-184.patch new file mode 100644 index 0000000..4389e81 --- /dev/null +++ b/0001-Bring-back-the-AnsiRenderer-fixes-184.patch @@ -0,0 +1,436 @@ +From faf93318be3cda0b3a3894ae9d2032835601bc73 Mon Sep 17 00:00:00 2001 +From: Guillaume Nodet +Date: Wed, 20 Jan 2021 12:08:59 +0100 +Subject: [PATCH] Bring back the AnsiRenderer, fixes #184 + +--- + src/main/java/org/fusesource/jansi/Ansi.java | 27 ++ + .../org/fusesource/jansi/AnsiRenderer.java | 253 ++++++++++++++++++ + .../fusesource/jansi/AnsiRendererTest.java | 115 ++++++++ + 3 files changed, 395 insertions(+) + create mode 100644 src/main/java/org/fusesource/jansi/AnsiRenderer.java + create mode 100644 src/test/java/org/fusesource/jansi/AnsiRendererTest.java + +diff --git a/src/main/java/org/fusesource/jansi/Ansi.java b/src/main/java/org/fusesource/jansi/Ansi.java +index 84976e0..a882705 100644 +--- a/src/main/java/org/fusesource/jansi/Ansi.java ++++ b/src/main/java/org/fusesource/jansi/Ansi.java +@@ -818,6 +818,33 @@ public class Ansi implements Appendable { + return this; + } + ++ /** ++ * Uses the {@link AnsiRenderer} ++ * to generate the ANSI escape sequences for the supplied text. ++ * ++ * @param text text ++ * @return this ++ * @since 2.2 ++ */ ++ public Ansi render(final String text) { ++ a(AnsiRenderer.render(text)); ++ return this; ++ } ++ ++ /** ++ * String formats and renders the supplied arguments. Uses the {@link AnsiRenderer} ++ * to generate the ANSI escape sequences. ++ * ++ * @param text format ++ * @param args arguments ++ * @return this ++ * @since 2.2 ++ */ ++ public Ansi render(final String text, Object... args) { ++ a(String.format(AnsiRenderer.render(text), args)); ++ return this; ++ } ++ + @Override + public String toString() { + flushAttributes(); +diff --git a/src/main/java/org/fusesource/jansi/AnsiRenderer.java b/src/main/java/org/fusesource/jansi/AnsiRenderer.java +new file mode 100644 +index 0000000..7565ae4 +--- /dev/null ++++ b/src/main/java/org/fusesource/jansi/AnsiRenderer.java +@@ -0,0 +1,253 @@ ++/* ++ * Copyright (C) 2009-2021 the original author(s). ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ */ ++package org.fusesource.jansi; ++ ++import java.io.IOException; ++import java.util.Locale; ++ ++import org.fusesource.jansi.Ansi.Attribute; ++import org.fusesource.jansi.Ansi.Color; ++ ++/** ++ * Renders ANSI color escape-codes in strings by parsing out some special syntax to pick up the correct fluff to use. ++ * ++ * The syntax for embedded ANSI codes is: ++ * ++ *
++ *   @|code(,code)* text|@
++ * 
++ * ++ * Examples: ++ * ++ *
++ *   @|bold Hello|@
++ * 
++ * ++ *
++ *   @|bold,red Warning!|@
++ * 
++ * ++ * @since 2.2 ++ */ ++public class AnsiRenderer { ++ ++ public static final String BEGIN_TOKEN = "@|"; ++ ++ public static final String END_TOKEN = "|@"; ++ ++ public static final String CODE_TEXT_SEPARATOR = " "; ++ ++ public static final String CODE_LIST_SEPARATOR = ","; ++ ++ private static final int BEGIN_TOKEN_LEN = 2; ++ ++ private static final int END_TOKEN_LEN = 2; ++ ++ public static String render(final String input) throws IllegalArgumentException { ++ try { ++ return render(input, new StringBuilder()).toString(); ++ } catch (IOException e) { ++ // Cannot happen because StringBuilder does not throw IOException ++ throw new IllegalArgumentException(e); ++ } ++ } ++ ++ /** ++ * Renders the given input to the target Appendable. ++ * ++ * @param input ++ * source to render ++ * @param target ++ * render onto this target Appendable. ++ * @return the given Appendable ++ * @throws IOException ++ * If an I/O error occurs ++ */ ++ public static Appendable render(final String input, Appendable target) throws IOException { ++ ++ int i = 0; ++ int j, k; ++ ++ while (true) { ++ j = input.indexOf(BEGIN_TOKEN, i); ++ if (j == -1) { ++ if (i == 0) { ++ target.append(input); ++ return target; ++ } ++ target.append(input.substring(i)); ++ return target; ++ } ++ target.append(input.substring(i, j)); ++ k = input.indexOf(END_TOKEN, j); ++ ++ if (k == -1) { ++ target.append(input); ++ return target; ++ } ++ j += BEGIN_TOKEN_LEN; ++ String spec = input.substring(j, k); ++ ++ String[] items = spec.split(CODE_TEXT_SEPARATOR, 2); ++ if (items.length == 1) { ++ target.append(input); ++ return target; ++ } ++ String replacement = render(items[1], items[0].split(CODE_LIST_SEPARATOR)); ++ ++ target.append(replacement); ++ ++ i = k + END_TOKEN_LEN; ++ } ++ } ++ ++ public static String render(final String text, final String... codes) { ++ return render(Ansi.ansi(), codes) ++ .a(text).reset().toString(); ++ } ++ ++ /** ++ * Renders {@link Code} names as an ANSI escape string. ++ * @param codes The code names to render ++ * @return an ANSI escape string. ++ */ ++ public static String renderCodes(final String... codes) { ++ return render(Ansi.ansi(), codes).toString(); ++ } ++ ++ /** ++ * Renders {@link Code} names as an ANSI escape string. ++ * @param codes A space separated list of code names to render ++ * @return an ANSI escape string. ++ */ ++ public static String renderCodes(final String codes) { ++ return renderCodes(codes.split("\\s")); ++ } ++ ++ private static Ansi render(Ansi ansi, String... names) { ++ for (String name : names) { ++ Code code = Code.valueOf(name.toUpperCase(Locale.ENGLISH)); ++ if (code.isColor()) { ++ if (code.isBackground()) { ++ ansi.bg(code.getColor()); ++ } else { ++ ansi.fg(code.getColor()); ++ } ++ } else if (code.isAttribute()) { ++ ansi.a(code.getAttribute()); ++ } ++ } ++ return ansi; ++ } ++ ++ public static boolean test(final String text) { ++ return text != null && text.contains(BEGIN_TOKEN); ++ } ++ ++ @SuppressWarnings("unused") ++ public enum Code { ++ // ++ // TODO: Find a better way to keep Code in sync with Color/Attribute/Erase ++ // ++ ++ // Colors ++ BLACK(Color.BLACK), ++ RED(Color.RED), ++ GREEN(Color.GREEN), ++ YELLOW(Color.YELLOW), ++ BLUE(Color.BLUE), ++ MAGENTA(Color.MAGENTA), ++ CYAN(Color.CYAN), ++ WHITE(Color.WHITE), ++ ++ // Foreground Colors ++ FG_BLACK(Color.BLACK, false), ++ FG_RED(Color.RED, false), ++ FG_GREEN(Color.GREEN, false), ++ FG_YELLOW(Color.YELLOW, false), ++ FG_BLUE(Color.BLUE, false), ++ FG_MAGENTA(Color.MAGENTA, false), ++ FG_CYAN(Color.CYAN, false), ++ FG_WHITE(Color.WHITE, false), ++ ++ // Background Colors ++ BG_BLACK(Color.BLACK, true), ++ BG_RED(Color.RED, true), ++ BG_GREEN(Color.GREEN, true), ++ BG_YELLOW(Color.YELLOW, true), ++ BG_BLUE(Color.BLUE, true), ++ BG_MAGENTA(Color.MAGENTA, true), ++ BG_CYAN(Color.CYAN, true), ++ BG_WHITE(Color.WHITE, true), ++ ++ // Attributes ++ RESET(Attribute.RESET), ++ INTENSITY_BOLD(Attribute.INTENSITY_BOLD), ++ INTENSITY_FAINT(Attribute.INTENSITY_FAINT), ++ ITALIC(Attribute.ITALIC), ++ UNDERLINE(Attribute.UNDERLINE), ++ BLINK_SLOW(Attribute.BLINK_SLOW), ++ BLINK_FAST(Attribute.BLINK_FAST), ++ BLINK_OFF(Attribute.BLINK_OFF), ++ NEGATIVE_ON(Attribute.NEGATIVE_ON), ++ NEGATIVE_OFF(Attribute.NEGATIVE_OFF), ++ CONCEAL_ON(Attribute.CONCEAL_ON), ++ CONCEAL_OFF(Attribute.CONCEAL_OFF), ++ UNDERLINE_DOUBLE(Attribute.UNDERLINE_DOUBLE), ++ UNDERLINE_OFF(Attribute.UNDERLINE_OFF), ++ ++ // Aliases ++ BOLD(Attribute.INTENSITY_BOLD), ++ FAINT(Attribute.INTENSITY_FAINT),; ++ ++ private final Enum n; ++ ++ private final boolean background; ++ ++ Code(final Enum n, boolean background) { ++ this.n = n; ++ this.background = background; ++ } ++ ++ Code(final Enum n) { ++ this(n, false); ++ } ++ ++ public boolean isColor() { ++ return n instanceof Ansi.Color; ++ } ++ ++ public Ansi.Color getColor() { ++ return (Ansi.Color) n; ++ } ++ ++ public boolean isAttribute() { ++ return n instanceof Attribute; ++ } ++ ++ public Attribute getAttribute() { ++ return (Attribute) n; ++ } ++ ++ public boolean isBackground() { ++ return background; ++ } ++ } ++ ++ private AnsiRenderer() { ++ } ++ ++} +\ No newline at end of file +diff --git a/src/test/java/org/fusesource/jansi/AnsiRendererTest.java b/src/test/java/org/fusesource/jansi/AnsiRendererTest.java +new file mode 100644 +index 0000000..590a96b +--- /dev/null ++++ b/src/test/java/org/fusesource/jansi/AnsiRendererTest.java +@@ -0,0 +1,115 @@ ++/* ++ * Copyright (C) 2009-2021 the original author(s). ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ */ ++package org.fusesource.jansi; ++ ++import org.junit.jupiter.api.BeforeAll; ++import org.junit.jupiter.api.Test; ++ ++import static org.fusesource.jansi.Ansi.*; ++import static org.fusesource.jansi.Ansi.Attribute.*; ++import static org.fusesource.jansi.Ansi.Color.*; ++import static org.fusesource.jansi.AnsiRenderer.*; ++import static org.junit.jupiter.api.Assertions.assertEquals; ++import static org.junit.jupiter.api.Assertions.assertFalse; ++import static org.junit.jupiter.api.Assertions.assertTrue; ++ ++/** ++ * Tests for the {@link AnsiRenderer} class. ++ * ++ * @author Jason Dillon ++ */ ++public class AnsiRendererTest { ++ ++ @BeforeAll ++ static void setUp() { ++ Ansi.setEnabled(true); ++ } ++ ++ @Test ++ public void testTest() throws Exception { ++ assertFalse(test("foo")); ++ assertTrue(test("@|foo|")); ++ assertTrue(test("@|foo")); ++ } ++ ++ @Test ++ public void testRender() { ++ String str = render("@|bold foo|@"); ++ System.out.println(str); ++ assertEquals(ansi().a(INTENSITY_BOLD).a("foo").reset().toString(), str); ++ assertEquals(ansi().bold().a("foo").reset().toString(), str); ++ } ++ ++ @Test ++ public void testRenderCodes() { ++ String str = renderCodes("bold red"); ++ System.out.println(str); ++ assertEquals(ansi().bold().fg(Color.RED).toString(), str); ++ } ++ ++ @Test ++ public void testRender2() { ++ String str = render("@|bold,red foo|@"); ++ System.out.println(str); ++ assertEquals(Ansi.ansi().a(INTENSITY_BOLD).fg(RED).a("foo").reset().toString(), str); ++ assertEquals(Ansi.ansi().bold().fgRed().a("foo").reset().toString(), str); ++ } ++ ++ @Test ++ public void testRender3() { ++ String str = render("@|bold,red foo bar baz|@"); ++ System.out.println(str); ++ assertEquals(ansi().a(INTENSITY_BOLD).fg(RED).a("foo bar baz").reset().toString(), str); ++ assertEquals(ansi().bold().fgRed().a("foo bar baz").reset().toString(), str); ++ } ++ ++ @Test ++ public void testRender4() { ++ String str = render("@|bold,red foo bar baz|@ ick @|bold,red foo bar baz|@"); ++ System.out.println(str); ++ assertEquals(ansi() ++ .a(INTENSITY_BOLD).fg(RED).a("foo bar baz").reset() ++ .a(" ick ") ++ .a(INTENSITY_BOLD).fg(RED).a("foo bar baz").reset() ++ .toString(), str); ++ } ++ ++ @Test ++ public void testRender5() { ++ // Check the ansi() render method. ++ String str = ansi().render("@|bold Hello|@").toString(); ++ System.out.println(str); ++ assertEquals(ansi().a(INTENSITY_BOLD).a("Hello").reset().toString(), str); ++ } ++ ++ ++ @Test ++ public void testRenderNothing() { ++ assertEquals("foo", render("foo")); ++ } ++ ++ @Test ++ public void testRenderInvalidMissingEnd() { ++ String str = render("@|bold foo"); ++ assertEquals("@|bold foo", str); ++ } ++ ++ @Test ++ public void testRenderInvalidMissingText() { ++ String str = render("@|bold|@"); ++ assertEquals("@|bold|@", str); ++ } ++} +\ No newline at end of file +-- +2.33.1 + diff --git a/jansi.spec b/jansi.spec index cdc9647..1d55757 100644 --- a/jansi.spec +++ b/jansi.spec @@ -1,6 +1,6 @@ Name: jansi Version: 2.1.1 -Release: 3%{?dist} +Release: 4%{?dist} Summary: Generate and interpret ANSI escape sequences in Java License: ASL 2.0 @@ -8,6 +8,10 @@ URL: http://fusesource.github.io/jansi/ Source0: https://github.com/fusesource/jansi/archive/jansi-%{version}.tar.gz # Change the location of the native artifact to where Fedora wants it Patch0: %{name}-jni.patch +# Bring back AnsiRenderer +# https://github.com/fusesource/jansi/commit/faf9331 +# Needed to build newer log4j +Patch1: 0001-Bring-back-the-AnsiRenderer-fixes-184.patch BuildRequires: gcc BuildRequires: maven-local @@ -92,6 +96,9 @@ cp -p src/main/native/libjansi.so %{buildroot}%{_libdir}/%{name} %license license.txt %changelog +* Mon Dec 13 2021 Adam Williamson - 2.1.1-4 +- Backport patch to bring back AnsiRenderer + * Tue Jan 26 2021 Fedora Release Engineering - 2.1.1-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild