-
Notifications
You must be signed in to change notification settings - Fork 279
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
Separate user and machine output #1175
Separate user and machine output #1175
Conversation
The current "everything goes to stdout" behavior is intended, not a bug. /cc @ras0219-msft |
At least for the commands where it destroys the format of the output it should go to stderr :) |
First, I want to agree with the problem statement that when we are issuing structured machine output, we should separate all "user messages" into stderr. Note though, this is not just when we use For example, take Indeed, the vcpkg codebase emits user-facing messages 99% of the time and machine structured output only in very specific circumstances. Off the top of my head:
For the vast majority of commands, all output is user-facing output and none is considered "machine readable". As an aside, we must note the downside of splitting output streams: you lose synchronization. For example, if we emit One way to do this would be to simply make However, this makes interacting with most of the vcpkg tool more painful than it needs to be; in most cases, we intentionally would print nothing to stdout. I'm not sure what others experiences are, but I'm regularly annoyed by typing Therefore, I think the most reasonable path forward for flags such as I could see some future argument that says the default pipe should always be stderr, but I'd need to discuss that more. |
👍 The only downside is that this is challenging to implement the nice way, at least I have not found one. The "problem" is that there are a lot of prints before the "command selection" is done. So we have to decide which "default" pipe should be used before the normal command selection is done. I will push a solution but maybe someone has a better idea 😅 An simpler to implement solution would be to output the machine readable output to stderr, but that can also be non intuitive, but a message that says you have to redirect stderr could help. |
…rint machine readable output to stdout
2d92048
to
149b1bc
Compare
src/vcpkg/vcpkgcmdarguments.cpp
Outdated
if (*command == "depend-info") | ||
{ | ||
bool found = false; | ||
for (const auto& arg : args.forwardable_arguments) | ||
{ | ||
if (found) | ||
{ | ||
const auto value = Strings::ascii_to_lowercase(arg); | ||
use_stderr = value == "dot" || value == "mermaid" || value == "dgml"; | ||
break; | ||
} | ||
if (Strings::case_insensitive_ascii_starts_with(arg, "--format")) | ||
{ | ||
if (arg.length() > 9) | ||
{ | ||
const auto value = Strings::ascii_to_lowercase(StringView(arg).substr(9)); | ||
use_stderr = value == "dot" || value == "mermaid" || value == "dgml"; | ||
break; | ||
} | ||
found = true; | ||
} | ||
} | ||
} | ||
} | ||
|
||
args.forwardable_arguments = args.parser.get_remaining_args(); | ||
if (use_stderr) | ||
{ | ||
msg::set_default_output_stream(OutputStream::StdErr); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ugly hack is here. But this now also works with vcpkg depend-info 'pcl[core,visualization]' --forMat=dOt --debug > test.dot
src/vcpkg/vcpkgcmdarguments.cpp
Outdated
@@ -388,16 +388,44 @@ namespace vcpkg | |||
if (const auto p = args.debug_env.get()) args.debug = *p; | |||
|
|||
auto maybe_command = args.parser.extract_first_command_like_arg_lowercase(); | |||
args.forwardable_arguments = args.parser.get_remaining_args(); | |||
bool use_stderr = Util::contains(args.forwardable_arguments, "--x-json"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of hard coding stuff like this, can we add a field to CommandMetadata that controls the setting?
Alternately, can we just do it at the top of the command function in question instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem then it is too late. There are Debug print statements before a command is selected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For example here:
Lines 279 to 292 in e658895
VcpkgCmdArguments args = VcpkgCmdArguments::create_from_command_line(real_filesystem, argc, argv); | |
if (const auto p = args.debug.get()) Debug::g_debugging = *p; | |
args.imbue_from_environment(); | |
VcpkgCmdArguments::imbue_or_apply_process_recursion(args); | |
if (const auto p = args.debug_env.get(); p && *p) | |
{ | |
msg::write_unlocalized_text_to_stdout(Color::none, | |
"[DEBUG] The following environment variables are currently set:\n" + | |
get_environment_variables() + '\n'); | |
} | |
else if (Debug::g_debugging) | |
{ | |
Debug::println("To include the environment variables in debug output, pass --debug-env"); | |
} |
After line 283 we already have to know it output should go to stderr or stdout
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But one could argue that we don't care if debug output breaks things
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would like to resolve those as 'debug output always goes to stderr' and 'console parse failures always go to stderr' on the grounds that neither of those types of output should apply to the edge cases @ras0219-msft enumerated above; I'm asking around and will keep you posted.
I think it would be good if console parse errors go directly to stderr too. In that case we generally don't expect the program to continue so synchronization issues and concerns about accidentally causing pipelines to fail should not be concerns. |
@AugP @vicroms @JavierMatosD @data-queue @ras0219-msft and I discussed this today and agreed with the following outcomes:
Do you mind if I morally take over this PR and make those changes? |
No you can do that :) |
…s-to-stderr # Conflicts: # src/vcpkg/commands.build.cpp # src/vcpkg/commands.ci-verify-versions.cpp # src/vcpkg/paragraphs.cpp
…ding to solve a time machine problem. Audit all commands which say 'x-json' and assign their output to stdout or stderr as appropriate.
@autoantwort Can you confirm you are happy with the changes I just pushed? |
@BillyONeal Maybe this warning also must go to stderr by default |
I agree. Hmmm I thought I got that one? Let me check again... |
Ah the sendmetrics one is in vcpkg.cpp rather than vcpkgcmdarguments.cpp |
OK please check again |
msg::write_unlocalized_text_to_stderr( | ||
Color::warning, | ||
LocalizedString::from_raw(WarningPrefix).append(msgVcpkgSendMetricsButDisabled).append_raw('\n')); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe
stderr_sink.println_warnin
msg::write_unlocalized_text_to_stderr( | |
Color::warning, | |
LocalizedString::from_raw(WarningPrefix).append(msgVcpkgSendMetricsButDisabled).append_raw('\n')); | |
stderr_sink.println_warning(msgVcpkgSendMetricsButDisabled); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't want to introduce use of the sinks where the polymorphism is not needed right now but I could see an argument in the future that all console output should be polymorphic like this. (But that seems way outside the scope of this PR)
…s-to-stderr # Conflicts: # src/vcpkg/commands.owns.cpp
Thanks! |
Fixes microsoft/vcpkg#33444, microsoft/vcpkg#30180 and microsoft/vcpkg#34805
I also noticed that when using depend-info and some warnings are destroying the output