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
Provide Go template functions to format table output #3488
Comments
Looking through the built-in formatting more, I wonder if this could instead be used for built-in command output rather than manually formatting the output. The crux of Docker's |
@heaths I'd be interested in having a table template function!
If our templating support gets full-featured enough, we could theoretically switch built-in output to the template approach. That would also serve as a starting template for someone who would like to tweak the output in their own scripts. But for now, I'd propose expanding |
I am +1 on these ideas but defer to @mislav on the details as he is the one who's been thinking most about programmatic output like this. |
@heaths You are welcome to send a PR adding a |
I'll try to take a look this weekend. I need to play around with things a little (probably just a scratch program) to see if |
After playing around with a few options last night, I think this might be better served by a PR to the text/template package itself. Docker's "function" is really just a hack: if the template starts with "table" (or a couple others like "raw"), that prefix is stripped from the template and it does some simple string transforms on the remaining pipeline. It works well when your output is already an array, but if you're array is arbitrarily nested (like a GraphQL query might often end up), it wouldn't work. Even if we scanned the string for any occurrence of "table" (or similar), there's no obvious end. The For now, let me see if there's any interest in a change to the text/template package. I think it could be an all-around useful addition. |
Thanks for exploring all this! I have little faith that the proposal to
|
I've been considering some similar approaches under the assumption it won't be accepted because it actually emits formatted text, which seems out of scope. One idea was similar to what you suggested, but the problem is that you can't pass fields to functions if, for example, you wanted to color text. Maybe some was to do that would be more acceptable, like inline pipelines via syntax like (partial) If not even that, I've been thinking that we could pre-parse the template and, like Docker CLI, manipulate it to make another named template internally. I'll continue to play around with this in my scratch program. Edit: updated proposal with this alternative suggestion: golang/go#45752 (comment) |
Apparently parenthesis already work. While perusing through the text/template/parse code and making a few preliminary changes to support my proposal, I failed to see how parsed parenthesis were used. This commit shows my idea above already works: I'll proceed with this course of action, but would also like to add a couple more helper functions that I think will also help in the future if we wanted to replace the built-in formatting with this new set of functions, e.g. |
After further consideration I propose support for multiple tables, which could be beneficial down the road. Effectively, this:
We could use
|
@heaths Looks pretty good! I think you're definitely on to something here. Does |
C-style escape sequences within the text won't be interpreted, but literal escapes will. While the web forms appear to prevent this (or at least make it harder), I was able to add an issue with literal escapes in both the title and text. Seems I'll have to create a replacer that perhaps JS-encodes all but |
Actually, looks like this shouldn't be a problem: $ gh api graphql -f query='query {
repository(name: "templ", owner: "heaths") {
issue(number: 1) {
number
title
bodyText
}
}
}' {
"data": {
"repository": {
"issue": {
"number": 1,
"title": "Title:\u0008 with escape",
"bodyText": "This\tbody has\nescape sequences"
}
}
}
} |
Working on some tests and docs, but a preview of using a table template for bin/gh issue list --json number,title,labels,updatedAt --template '{{table}}{{range .}}{{row (.number | printf "#%v" | color "green") (.title | ellipsis 50) (.labels | pluck "name" | join ", " | printf "(%s)" | color "gray") (timeago .updatedAt | color "gray")}}{{end}}{{endTable}}' |
For those wondering what gh template ended as. Here is an example:
Hope that helps. PS: It would be awesome to add that to the doc here and there. |
I did add that to the
Also, you don't need |
Thanks @heaths :) |
How would I add, for example, a comma-separated list of label names into a
but get:
I've also tried various forms of nesting |
Go templates don't expand slices like that. But you can use some scope operator like https://gist.github.com/heaths/5c7ba9dda978b3f8cb306be3a899c926#file-config-yml-L7 |
@heaths Thank you, that worked great. |
Describe the feature or problem you’d like to solve
Related to #3487 there was no great way to provide table output like you do for most (or perhaps all) your other commands like
gh issue list
. You expose acolor
function and I can useprintf
to align and pad strings, but what would be really great is atable
function.Proposed solution
The Docker CLI lets you specify a
table
function that works like this:docker images --format "table {{.Repository}}\t{{.Tag}}"
It would then output something like:
This is done via, mostly, https://github.com/docker/cli/blob/daf5f126ad698f34548c21f672450afa5754b7a2/cli/command/formatter/formatter.go. It is effectively like
{{range}}
but splits on tabs and determines optimal width automatically.Alternatively, if there was some way to declare the scope of nodes to format as a table automatically, perhaps you could - when specified - format that with survey as you do your own table output.
The text was updated successfully, but these errors were encountered: