ontodev / robot

ROBOT is an OBO Tool
http://robot.obolibrary.org
BSD 3-Clause "New" or "Revised" License
257 stars 71 forks source link

Add option to for ANSI colors in robot output for better github actions experience #1006

Open cmungall opened 2 years ago

cmungall commented 2 years ago

This idea came from @krchristie

Ontology editors would find it easier if errors and warnings were appropriately color highlighted in GitHub actions

GitHub supports use of ANSI color output on the terminal:

See also:

I can see two ways of making this work:

  1. robot takes an option to add ANSI colors to all output - or at least reason and report
  2. a post-processing script bundled with ODK performs post-processing of output

2 would be relatively easy to do with simple text processing, but it would involve building in certain assumptions about text output structure in robot. It could be done in a more robust way by taking in json outputs from robot but (a) only a subset of commands support this (b) it is just harder overall, harder to stream.

It is however slightly fiddly because you want to generically wrap all your Makefile commands with this, ensuring stdout and stderr streams are properly wrapped.

If we prefer 2 we can close this and move to the ODK tracker, but I thought this is the best place to start.

Either way, having some central OBO standards about textual reporting will go a long way here and having robot be a standard here would help. E.g. other kinds of reporting could follow https://robot.obolibrary.org/report and use standard codes like ERROR as the first characters on a line, followed by a delimiter like colon or tab.

I am tending towards this simple approach. Here is an example of how:

pref = "\033["
reset = f"{pref}0m"

class colors:
    black = "30m"
    red = "31m"
    green = "32m"
    yellow = "33m"
    blue = "34m"
    magenta = "35m"
    cyan = "36m"
    white = "37m"

mappings = {
    'ERROR': (colors.red, True),
    'WARNING': (colors.yellow, True)
    }

with open('text.txt') as stream:
    for line in stream.readlines():
        line = line.strip()
        for tag, (color, is_bold) in mappings.items():
            if line.startswith(tag):
                line = line.replace(tag, f'{pref}{1 if is_bold else 0};{color}' + tag + reset)
                break
        print(line)

running this one:

ERROR: you did a bad
WARNING: you did a small bad
INFO: you did good

gives:

image
krchristie commented 2 years ago

In the scheme @cmungall suggests for three categories: ERROR, WARNING, & INFO, the label on the RHEA ID issues should probably all be WARNING, instead of some with WARN & some with ERROR, but where neither class of RHEA ID issue causes the build to fail. 20220525-TravisErrors

cmungall commented 2 years ago

Great feedback, thanks!

So it looks like that particular report is coming from @balhoff's ammonite script rather than robot itself, so this speaks to having this be post-processing. But it will be hard to come up with regexes that work for all the different tools people use in their QC pipelines. It may be easier for us to implement a local solution for GO just now, and to move towards broad standards that ODK-compliant tools can implement

krchristie commented 2 years ago

Great feedback, thanks!

So it looks like that particular report is coming from @balhoff's ammonite script rather than robot itself, so this speaks to having this be post-processing. But it will be hard to come up with regexes that work for all the different tools people use in their QC pipelines. It may be easier for us to implement a local solution for GO just now, and to move towards broad standards that ODK-compliant tools can implement

If Jim's other script is using the word ERROR, we could consider using a different word, e.g. FAIL for the label. Part of my problem today was that one of my mistakes was labeled with "ERROR", and I found that one and fixed it. However, the other one was labeled "FAIL". A single consistent label that is only used for issues that cause the build to fail would be really helpful, both for curators and for the consistency needed for post-processing to add colored highlighting.

jamesaoverton commented 2 years ago

Colours are certainly helpful.

  1. ROBOT report outputs to files, not the terminal (although there is the --print option).
  2. ROBOT sends all logs through the slf4j facade, implemented by logback configured here. I guess you can add colours to that: https://logback.qos.ch/manual/layouts.html#coloring. As usual, I'm worried about backwards compatibility. Every time I've had to mess with Java logging, it was miserable.

I'd have to see an actual implementation before I could make a good judgement. Maybe a filter at the ODK level would be easier and more general.