Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Odin Test] Ignore ANSI escape codes for non tty outputs #4100

Open
MrStevns opened this issue Aug 18, 2024 · 3 comments
Open

[Odin Test] Ignore ANSI escape codes for non tty outputs #4100

MrStevns opened this issue Aug 18, 2024 · 3 comments

Comments

@MrStevns
Copy link

Context

When using odin test where the output is not printed to a terminal but say the output window in Sublime Text or in my case, Focus, the output is unnecessarily messy. It would be nice if we could ignore the ANSI escape codes or have a flag to disable them.

Odin report

  • Odin: dev-2024-08:ac483f72e
  • OS: macOS Monterey 12.7.2 (build: 21G1974, kernel: 21.6.0)
  • CPU: Intel(R) Core(TM) i7-5557U CPU @ 3.10GHz
  • RAM: 16384 MiB
  • Backend: LLVM 18.1.8

Expected Behavior

When building a project from either Sublime text or Focus, or any other non tty output, i'd expect something like this:

[INFO ] --- [2024-08-17 07:52:29] Starting test runner with 1 thread. Set with -define:ODIN_TEST_THREADS=n.
[INFO ] --- [2024-08-17 07:52:29] The random seed sent to every test is: 39114654177527. Set with -define:ODIN_TEST_RANDOM_SEED=n.
[INFO ] --- [2024-08-17 07:52:29] Memory tracking is enabled. Tests will log their memory usage if there's an issue.
[INFO ] --- [2024-08-17 07:52:29] < Final Mem/ Total Mem> <  Peak Mem> (#Free/Alloc) :: [package.test_name]
[INFO ] --- [2024-08-17 07:52:29] [rendering.odin:9:example()] Debug test
rendering  [|                       ]         1 :: [package done]

Finished 1 test in 270µs. The test was successful.

Current Behavior

Where as right now the output is this.

�[?25l�[?7lrendering  [�[90m|                       �[0m]    0/   1 :: �[90mexample�[0m
�[?7h1 thread                                 0/   1 :: total
�[2F�[J�]2;Odin test runner (0/1)�\�[?7lrendering  [�[33m|                       �[0m]    0/   1 :: �[33mexample�[0m
�[?7h1 thread                                 0/   1 :: total
�[2F�[J�]2;Odin test runner (1/1)�\�[?7lrendering  [�[32m|                       �[0m]         1 :: [package done]
�[?7h
�[?25h�[0m[INFO ] --- �[0m[2024-08-17 07:53:51] Starting test runner with 1 thread. Set with -define:ODIN_TEST_THREADS=n.
�[0m[INFO ] --- �[0m[2024-08-17 07:53:51] The random seed sent to every test is: 39368671393172. Set with -define:ODIN_TEST_RANDOM_SEED=n.
�[0m[INFO ] --- �[0m[2024-08-17 07:53:51] Memory tracking is enabled. Tests will log their memory usage if there's an issue.
�[0m[INFO ] --- �[0m[2024-08-17 07:53:51] < Final Mem/ Total Mem> <  Peak Mem> (#Free/Alloc) :: [package.test_name]
�[0m[INFO ] --- �[0m[2024-08-17 07:53:51] [rendering.odin:9:example()] Debug test
Finished 1 test in 151µs. The test was �[32msuccessful.�[0m

Steps to Reproduce

To Reproduce

  1. Create a odin project like so:
package mytestproject

import "core:log"
import "core:testing"

@test
example :: proc(t: ^testing.T)
{
    log.info("Debug test")
}
  1. Create a focus-config file so you can run the odin project and get the output like so:
    > odin test /path/to/project/
  2. Run the test project via the command modal in focus

Additional notes

I started out making this a Focus editor issue but as the maintainer responded, shouldn't this be handled by Odin?

@Feoramund
Copy link
Contributor

I've been aware of this since the rewrite. This happens with any core:log interface that redirects a console logger, because the logger's created assuming it can use color output, then it's redirected and that may not be the case anymore. It's an issue that will require more OS-specific terminal-aware functionality.

You can mitigate some of this by using -define:ODIN_TEST_FANCY=false to disable the animation though, which will keep from printing the progress bar lines.

@laytan
Copy link
Sponsor Collaborator

laytan commented Aug 18, 2024

The compiler has this piece of code to determine if it should do colors, is this a good idea to port over and use here?

Odin/src/main.cpp

Lines 2860 to 2905 in f49ebae

gb_internal void init_terminal(void) {
TIME_SECTION("init terminal");
build_context.has_ansi_terminal_colours = false;
gbAllocator a = heap_allocator();
char const *no_color = gb_get_env("NO_COLOR", a);
defer (gb_free(a, cast(void *)no_color));
if (no_color != nullptr) {
return;
}
char const *force_color = gb_get_env("FORCE_COLOR", a);
defer (gb_free(a, cast(void *)force_color));
if (force_color != nullptr) {
build_context.has_ansi_terminal_colours = true;
return;
}
#if defined(GB_SYSTEM_WINDOWS)
HANDLE hnd = GetStdHandle(STD_ERROR_HANDLE);
DWORD mode = 0;
if (GetConsoleMode(hnd, &mode)) {
enum {FLAG_ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004};
if (SetConsoleMode(hnd, mode|FLAG_ENABLE_VIRTUAL_TERMINAL_PROCESSING)) {
build_context.has_ansi_terminal_colours = true;
}
}
#elif defined(GB_SYSTEM_OSX) || defined(GB_SYSTEM_UNIX)
char const *term_ = gb_get_env("TERM", a);
defer (gb_free(a, cast(void *)term_));
String term = make_string_c(term_);
if (!str_eq(term, str_lit("dumb")) && isatty(STDERR_FILENO)) {
build_context.has_ansi_terminal_colours = true;
}
#endif
if (!build_context.has_ansi_terminal_colours) {
char const *odin_terminal_ = gb_get_env("ODIN_TERMINAL", a);
defer (gb_free(a, cast(void *)odin_terminal_));
String odin_terminal = make_string_c(odin_terminal_);
if (str_eq_ignore_case(odin_terminal, str_lit("ansi"))) {
build_context.has_ansi_terminal_colours = true;
}
}
}

@Feoramund
Copy link
Contributor

isatty and GetConsoleMode are the OS parts needed I mentioned. Checking the TERM string and the environment variables is good. I think this could do it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants