-
-
Save progrium/d782e574bb2e97d5ebdc to your computer and use it in GitHub Desktop.
curl -s "$url" | tar -zxC "$dest" |
func downloadAndInstall(url, dest string) error { | |
resp, err := http.Get(url) | |
if err != nil { | |
return error | |
} | |
defer resp.Body.Close() | |
zip, err := gzip.NewReader(resp.Body) | |
if err != nil { | |
return error | |
} | |
defer zip.Close() | |
archive := tar.NewReader(zip) | |
for { | |
header, err := archive.Next() | |
if err == io.EOF { | |
break | |
} | |
if err != nil { | |
return err | |
} | |
filename := fmt.Sprintf("%s/%s", dest, header.Name) | |
file, err := os.Create(filename) | |
if err != nil { | |
return err | |
} | |
defer file.Close() | |
_, err := io.Copy(file, archive) | |
if err != nil { | |
return err | |
} | |
} | |
} |
Would like to see examples of how the Go version could be improved, using the typical practices of an experienced Go programmer. Any takers?
The bash example would need 'set -o pipefail' to replicate the error handling in the Go version through the HTTP download.
This is what I struggle with in Go. I feel it has some interesting ideas, but it's not very nice to read.
This is I prefer Python. But I'd be curious to see how to improve the Go code to make it more succinct.
@cablehead set -o pipefail
just deals with error code propagation. You can't replicate the immediate abort-on-failure of the Go code using just pipes (i.e. tar
will still run no matter what w/ a pipes solution). You'd have to write a full script w/ separate commands to avoid running tar
if curl
errored.
@abevoelker Thanks for the clarification. Oof, yeah, my understanding was that set -o pipefail
would abort if the curl fails, before the tar runs. You're right though:
andy@hop:~/tmp$ cat 1.sh
#!/bin/bash
false | echo "foo"
echo $?
andy@hop:~/tmp$ ./1.sh
foo
0
andy@hop:~/tmp$ cat 2.sh
#!/bin/bash
set -o pipefail
false | echo "foo"
echo $?
andy@hop:~/tmp$ ./2.sh
foo
1
I definitely see @progrium's point, but in that case, once both versions are safe, the bash version wouldn't be as clearly terse.
@msabramo Python's concurrency story is woeful though, and I fear that asyncio is a long winded wrong turn.
I respectfully submit that you should write the corresponding program in C. That is the comparison that I think about most often when using Go 😉