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

text/template: add support for io.Reader #29165

Open
empijei opened this Issue Dec 9, 2018 · 2 comments

Comments

Projects
None yet
4 participants
@empijei
Copy link
Contributor

empijei commented Dec 9, 2018

What version of Go are you using (go version)?

$ go version
go version go1.9.4 linux/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/clap/go"
GORACE=""
GOROOT="/usr/lib/go-1.9"
GOTOOLDIR="/usr/lib/go-1.9/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build114129408=/tmp/go-build -gno-record-gcc-switches"
CXX="g++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"

What did you do?

	tpl := template.Must(template.New("").Parse("{{.}}"))
	tpl.Execute(os.Stdout, strings.NewReader("gopher"))

https://play.golang.org/p/QZvPZjmezPU

What did you expect to see?

"gopher"

What did you see instead?

"{gopher 0 -1}"

Rationale

Most IO operations in go are executed on io.ReadWriters and it is very frequent to open streams, pass them around, wrap them and so on, all the way from data sources to data sinks.

One exception to this rule seems to be templates: the only way to take some text blob from a file and output it in the template is to copy the entire file in a string and then pass the string to Execute.

It would be nice to be able to use io.Readers with templates and avoid the unnecessary buffering.

A CL for the proposed change can be found here.

A previous bug mentioning this need: #25160.

@mvdan

This comment has been minimized.

Copy link
Member

mvdan commented Dec 9, 2018

Sounds reasonable, given that there's no simple way to currently work around buffering all the data in memory.

I wonder how often this comes up, though. I've used templates for multiple years and I've never had the need to print an io.Reader with them. Do you have example use cases?

/cc @robpike @rogpeppe

@mvdan mvdan added the NeedsDecision label Dec 9, 2018

@empijei

This comment has been minimized.

Copy link
Contributor

empijei commented Dec 9, 2018

Sadly, none that I can link, but I've encountered this problem in several situations, mostly because I dealt a lot with net conns and external data sources that my code was just transforming (wrapping readers).

I ended up writing my own kind of templates that interleaved (*text.Template).Execute calls with io.Copy calls.

I just found the previous bug and created a small patch to support this use case for me and other people that might incur in the same issue.

Also, since most of the stdlib passes io.Readers around, it just seemed more natural and fitting to print the content of the reader instead of the reflection of its fields values, which seems like a very edge case for templates.

@ianlancetaylor ianlancetaylor added this to the Go1.13 milestone Dec 10, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment