Do not use terminal escape sequences in non-interactive terminals or the Windows command prompt.#2327
Conversation
…the Windows command prompt.
Naatan
left a comment
There was a problem hiding this comment.
Interactivity isn't the issue here. My forgetting to address cmd.exe when I implemented this is. There's a lib I found that should handle it cross-platform:
https://github.com/atomicgo/cursor
BUT it has the same issue as your code; it assumes windows==cmd.exe, whereas in reality windows also runs bash, and it's not an uncommon use-case.
That said; you can probably use the lib above to figure out how to do it with cmd.exe. I realize this is more of a missed functionality issue than a bug though, so if this turns into a timesink we could descope the windows implementation and utilize interactive=false for windows for the bug (but please only if it turns into a timesink).
Regardless of which route we go; it's not the job of the output package to assert interactive or detect shells. So we'll want to find a way to pass that in externally, this seems like a reasonable location:
For shell detection we can use the logic here:
I suggest splitting that out into its own function so we don't have to do subshell.New().
There's a lot in my response here.. happy to jump on zoom to go over things in greater detail.
1646927 to
a734da7
Compare
a734da7 to
2bca7c2
Compare
6666627 to
44da254
Compare
|
I ended up using |
| // Set up our output formatter/writer | ||
| outFlags := parseOutputFlags(os.Args) | ||
| out, err := initOutput(outFlags, "") | ||
| out, err := initOutput(outFlags, "", subshell.New(cfg).Shell()) |
There was a problem hiding this comment.
I'd still like to advocate splitting the shell detection logic out. It's true that New() isn't very costly, but it's still doing more than we need it to. Plus we don't know how it will evolve in the future, nor will we be sensitive to this use-case in the future unless we make it explicit.
| package output | ||
|
|
||
| func (d *Spinner) moveCaretBackInCommandPrompt(n int) { | ||
| // No-op |
There was a problem hiding this comment.
Let's send a rollbar error if this happens, since it should never happen.
There was a problem hiding this comment.
I thought about that, but then we'll hammer rollbar on every tick in a worst-case scenario.
There was a problem hiding this comment.
Could just only send it the first time. Record it to something like Spinner.recorded = true.
There was a problem hiding this comment.
Aye, but is there a chance we'll be creating a large number of these progress objects? We'd still be in the same boat.
This allows the current shell name/path to be found without creating a new subshell.
|
Let me know if I missed something extracting the shell detection logic into its own function. |
Naatan
left a comment
There was a problem hiding this comment.
Please also see my replies to previous comments.
| } | ||
| binary = resolveBinaryPath(binary) | ||
|
|
||
| } |
There was a problem hiding this comment.
This should be part of the shell detection.
Naatan
left a comment
There was a problem hiding this comment.
Nice, the subshell stuff looks much more readable!
Uh oh!
There was an error while loading. Please reload this page.