canonical / craft-cli

https://canonical-craft-cli.readthedocs-hosted.com/en/latest/
GNU Lesser General Public License v3.0
9 stars 13 forks source link

Brief Emitter mode still appears to be verbose when plugins are called ? #243

Open flotter opened 4 months ago

flotter commented 4 months ago

What needs to get done

I am not 100% sure if my observation is correct, but hopefully an expert could help me out ?

I am starting the Emitter with streaming_brief=False

In fact the CLI startup code in some secret craft project looks like this:

    for lib_name in ("craft_providers", "craft_parts"):
        logger = logging.getLogger(lib_name)
        logger.setLevel(logging.DEBUG)

    emit.init(
        EmitterMode.BRIEF,
        "XXXcraft",
        f"Starting XXXcraft version {__version__}",
        log_filepath=logpath,
        streaming_brief=False,
    )

and then inside my lifecycle code (not using craft-application, but doing the same thing)

            with self._lcm.action_executor() as aex:
                emit.message("Processing firmware parts ...")
                for act in actions:
                    emit.progress(
                        f"{step_to_action(act.step, True)} {act.part_name!r} ..."
                    )
                    with emit.open_stream() as stream:
                        aex.execute([act], stdout=stream, stderr=stream)

However when I look at the plugin handler code, it looks like we are passing the stdout / stderr to the script so that whatever is processed by the script, will result in each shell line being echoed, and as a result, I see lots of lines:

+ ln ... ....
+ cp x .. y

See: craft-parts/craft_part/_create_and_run_script _create_and_run_script(..)

I see the same detailed output from the autotools plugin.

Why it needs to get done

Am I missing a trick to suppress the detailed output while running a progress runner in BRIEF emitter mode ?

lengau commented 3 months ago

If I'm understanding correctly, the following would be a minimal reproducer:

import subprocess
import craft_cli

craft_cli.emit.init(
    craft_cli.EmitterMode.BRIEF,
    "testcraft",
    "doing a thing",
    streaming_brief=False
)

for outer_count in range(3):
    craft_cli.emit.progress(f"Attempt {outer_count}")
    with craft_cli.emit.open_stream() as stream:
        subprocess.run(["echo", "-n", *(f"{i}\n" for i in range(10))], stdout=stream)

However, when I try this for myself it works as intended (replacing each line after it gets printed).

Does that reproducer reproduce the issue for you, and if so what terminal app are you using?

flotter commented 3 months ago

What I see is that the progress message is temporarily replaced by the output from your running processes (I do not want this in brief mode).

What I expected was that only the top level progress message is shown, with all output on the stream suppressed.

Is my expectation invalid ?

lengau commented 3 months ago

I've moved this over to craft-cli since from conversation I think this is about expectations in this library rather than craft-parts.

I'm not sure what the correct behaviour here is, though comparing to the behaviour with streaming_brief=True it doesn't match my expectations either. @tigarmo I think you're probably the right person to answer this 🙂

flotter commented 2 months ago

@lengau The reason I created it in craft-parts, which could be wrong, was because I do not believe there is an issue with craft-cli. I believe the craft-parts plugin itself is not honouring the streaming_brief=True request, but dumping plugin internals to the stream channel (unlike the rest of the code that gets its output suppressed correctly).

Perhaps we could quickly have a meeting which includes @tigarmo to confirm if my interpretation is correct, just to save you time here?

lengau commented 2 months ago

@flotter craft-parts isn't aware of craft-cli - it just knows to write outputs to generic Python streams.

I've scheduled a meeting for Monday (welcome back @tigarmo!) so we can all get on the same page.