Open jsejcksn opened 4 years ago
Thanks for opening this issue. I think we should limit line lengths to 80 characters so they can fit on terminals of the traditional size.
I'm usually working on a 15 inch screen or smaller, and like to have two terminals side by side, which means lines need to be less than 90-100 characters to not wrap.
A bash utility that handled this and the column issue in https://github.com/asdf-vm/asdf/issues/661 would be amazing.
Wouldn't the util need to be aware of all of the indentation formats used by all of the commands in order to automatically wrap them?
For example, the help
command output above looks like it uses a static indent of 41 characters for the descriptions. Are all the other output types in this format?
Or is there maybe an existing tool for generating tabular text content wrapped at 80 chars?
@jsejcksn https://github.com/asdf-vm/asdf/pull/742 should resolve the wrapping issue for the asdf help
command. Though I am looking to revamp our output formatting for all content that is >1 column of information.
How do we feel about not necessarily a hard cap at 80 chars, but a solution that wraps by terminal width at the time of execution?
Additionally, how do we feel about rendering multiple columns as alternating rows, eg:
➜ asdf plugin list --urls
PLUGIN URL
deno https://github.com/asdf-community/asdf-deno.git
firebase https://github.com/jthegedus/asdf-firebase.git
gcloud https://github.com/jthegedus/asdf-gcloud.git
golang https://github.com/kennyp/asdf-golang.git
gradle https://github.com/rfrancis/asdf-gradle.git
hadolint https://github.com/looztra/asdf-hadolint.git
java https://github.com/halcyon/asdf-java.git
maven https://github.com/halcyon/asdf-maven.git
nodejs https://github.com/asdf-vm/asdf-nodejs.git
ocaml https://github.com/asdf-community/asdf-ocaml.git
python https://github.com/danhper/asdf-python.git
shellcheck https://github.com/luizm/asdf-shellcheck.git
terraform https://github.com/Banno/asdf-hashicorp.git
Becoming
➜ asdf plugin list --urls
PLUGIN
URL
deno
https://github.com/asdf-community/asdf-deno.git
firebase
https://github.com/jthegedus/asdf-firebase.git
gcloud
https://github.com/jthegedus/asdf-gcloud.git
golang
https://github.com/kennyp/asdf-golang.git
gradle
https://github.com/rfrancis/asdf-gradle.git
hadolint
https://github.com/looztra/asdf-hadolint.git
java
https://github.com/halcyon/asdf-java.git
maven
https://github.com/halcyon/asdf-maven.git
nodejs
https://github.com/asdf-vm/asdf-nodejs.git
ocaml
https://github.com/asdf-community/asdf-ocaml.git
python
https://github.com/danhper/asdf-python.git
shellcheck
https://github.com/luizm/asdf-shellcheck.git
terraform
https://github.com/Banno/asdf-hashicorp.git
on terminals where the screen width is less than required for horizontal layout?
How do we feel about not necessarily a hard cap at 80 chars, but a solution that wraps by terminal width at the time of execution?
If, by that, you mean a responsively-formatted output in which "it will wrap the contents to 80 chars if the terminal is 80 columns, or 90 chars if the terminal is 90 columns, etc." then I think that's a fantastic idea. I'm very curious how you plan to accomplish this if you are doing it in a POSIX-compliant way, and there are many projects which would benefit from such a formatter.
Alternating rows:
...on terminals where the screen width is less than required for horizontal layout?
I think that a consistently-formatted output might be important for parsers. I have used the output of various asdf
commands to guide automated scripts (extracting versions, URLs, etc.). If you decide to use the alternating format, I think an extra newline character before each name will improve readability greatly.
Finally, this makes me wonder: Is all of this data available in a machine-readable format somewhere? Or it is the responsibility of each plugin to source and correctly format the output of commands like asdf list all <plugin>
?
If, by that, you mean a responsively-formatted output in which "it will wrap the contents to 80 chars if the terminal is 80 columns, or 90 chars if the terminal is 90 columns, etc."
Yes, that is the idea. It would not be an external package, just some more complex awk
. Looking at our formatting, we only have a few instances where we render multiple columns of data, the issue I have with columns is wrapping within a column. I would like our help.txt
to not be formatted inline (2nd column wraps within the column of text). Given we have a known set of outputs, we don't need to be generic as tools like column
are, and thus, have no need to build a new tool or increase our dependency list. Just have more complex code here.
To be clear, I would like line wrapping to be mostly handled by the terminal. There's just times, like with the help text, where wrapping within a column is what is desired, not wrapping to the start of the next line as would happen with multiple columns where there's overflow. If the content can be wrapped in a better way without inline formatting, then (I think) we should. For instance, 80 cols is a standard width and is a fine starting point, but by wrapping at 80 our help.txt
is now 18 rows taller (totaling 55 rows) than without wrapping. I personally use a wide terminal that is not very tall, so this is cumbersome. If there's an opportunity to be flexible, then I think we should discuss it.
I think that a consistently-formatted output might be important for parsers.
I had not considered this. Good point. POSIX [:space:]
character class is apparently all whitespace, including newlines, so perhaps REGEX-based parsing wouldn't be affected by such a formatting change. :thinking:
I will spend more time thinking on this as I do have ideas for outputs with more columns of information that would not be 80 col friendly by default, perhaps I could use a --less
flag instead of changing the format.
Is all of this data available in a machine-readable format somewhere? Or it is the responsibility of each plugin to source and correctly format the output of commands like asdf list all
?
Each plugin needs to follow specific output guidelines for each command and then the core asdf
takes that data and renders it. So the terminal output formatting would be within the core.
I think headings are useful.
➜ asdf list
deno
1.0.0
1.0.5
firebase
8.4.1
I don’t think that first example is weird. This example seems odd though:
➜ asdf list
deno
1.0.0
1.0.5
firebase
8.4.1
Does asdf
strictly require semver version strings? If not, then how do I know that firebase
and 8.4.1
aren’t deno
versions? Unique visual formatting (fixed indentation / relative positioning / etc.) of different data types is important, I think.
@jsejcksn
Does asdf strictly require semver version strings? If not, then how do I know that firebase and 8.4.1 aren’t deno versions?
EDITED below here:
It doesn't require semver version strings. EG:
java adopt-openjdk-11.0.6+10 (set by /home/jthegedus/.tool-versions)
Good points again, thanks for you input.
I think headings are useful.
For clarity, I meant column headings, not the weird list with indentation:
PLUGIN VERSION
deno 1.0.0
deno 1.0.5
firebase 8.4.1
I've been saying weird, but I mean inconsistent. Cols with headings is explicit and better uses both horizontal and vertical space
Ironically, GitHub comments are now capped at ~120 chars instead of 80 :wink:
Couple thoughts:
git
provide a --porcelain
flag that causes commands to format output in an easy to parse format. Typically this is used by scripts that want to parse the output of a git command with another command in Bash. We could implement a similar feature. With the --porcelain
flag things like indentation and column headers would be omitted.+1 for a machine-readable-formatted option using a flag. I suggest JSON.
I also think that a flag to indicate output useful for scripting would be good.
I do not like --porcelain
as the flag name because in Git the option --porcelain
can designate inverting the command output format target. That is, if the command would output human-readable information then --porcelain
will output a machine-readable format. If the command was "porcelain" by default and output machine-readable by default, then --porcelain
will output human-readable.
@jsejcksn what I've meant with machine-readable is that there's a standard, known format sent to stdout/stderr. That is, no headers, no forced wrapping of content. I don't think we'll be tackling outputting in JSON. If each row of data is predictably formatted, then simple Shell scripting tools like grep
,sed
,awk
, cut
etc is what I would be expecting people to use.
What I am thinking is this:
--some-flag
: output machine-readable, no char limit per row, no headers.I'm leaning away from wrapping content within columns as I initially proposed.
Thinking out loud, but perhaps in the default human-readable output we don't limit to 80 char and instead also introduce a flag for limiting to 80 char width. I say this because some of the command output we have is very difficult to limit to 80 chars. As an example, asdf current
outputs 3 columns of data, the second of which is a version of a plugin installed. In the case of Java, the average length of a version is 30 chars, with the longest being 48 chars alone. The third column is a Path to the tool-versions
file or debug information. All data sources for these columns, except the debug information, come from the user (plugin name can be anything they want) or the plugin itself.
With printf
we can truncate output in columns easily and achieve some semblance of 80 char limit while still outputting useful information, but the users would need to understand we're truncating the output and how to get the actual values.
Ultimately, I'm leaning more towards not truncating the data, letting the rows be as wide as they want, and then if provided a flag (or ASDF config value, or we detect Shell columns) we can use a different printf
format that does truncate. Essentially, swapping out the format arg to printf
. The flag --less
comes to mind.
a standard, known format
Does this mean something like TSV with variable-length whitespace instead of single tabs?
JSON was just a suggestion, but if it's machine-readable I think adhering to any standard with a specification would be preferable to a consistent, arbitrary format. That way, no one has to write a new parser.
Does this mean something like TSV with variable-length whitespace instead of single tabs?
Yes, TSV or space-delimited with variable-length whitespace. Again, my proposal is to make it essentially the same as the human readable without header rows and a known number of cols and separator. Though we could investigate a separate output just for machines along the lines of git --porcelain
That way, no one has to write a new parser.
Our goal here would be to align with existing shell applications that allow simple scripting and piping. I wouldn't put that in the same bucket as parsing nor --porcelain
in the same bucket as defining yet another JSON spec. Targeting simple scripting and piping is pedestrian IMO.
As an example, here is what git status --porcelain
outputs when run against a repo with an untracked file:
asdf-jthegedus on fix/update-all-plugins [?]
➜ git status
On branch fix/update-all-plugins
Your branch is up to date with 'origin/fix/update-all-plugins'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
test.txt
nothing added to commit but untracked files present (use "git add" to track)
asdf-jthegedus on fix/update-all-plugins [?]
➜ git status --porcelain
?? test.txt
The output is intended to be machine-readable, but certainly not a data-interchange format like JSON
Thanks for explaining; I understand better.
Since there are two modes:
...is there any disadvantage to utilizing a standardized interchange format (like TSV, JSON, etc.) for the latter?
I was leaning towards simple TSV for the --porcelain
flag.
Scannability would be improved greatly if lines were wrapped at 80 characters.
Here is example terminal output from the command
asdf help
. The longest unwrapped line is 125 characters: