Skip to content

Commit

Permalink
Add STDOut Consumer
Browse files Browse the repository at this point in the history
Add an STDOut consumer for usecases where streaming the bytes to another
process is appropriate. If the consumer is STDOUT we are restricted to a
single file download concurrently in multifile mode.
  • Loading branch information
tempusfrangit committed Mar 21, 2024
1 parent 4916726 commit d84009f
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 2 deletions.
2 changes: 1 addition & 1 deletion cmd/multifile/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func parseManifest(file io.Reader) (pget.Manifest, error) {
// and make the consumer responsible for knowing if this
// is allowed/not allowed/etc
consumer := viper.GetString(config.OptOutputConsumer)
if consumer != config.ConsumerNull {
if consumer != config.ConsumerNull && consumer != config.ConsumerSTDOUT {
err = checkSeenDestinations(seenDestinations, dest, url)
if err != nil {
if errors.Is(err, errDupeURLDestCombo) {
Expand Down
10 changes: 9 additions & 1 deletion cmd/multifile/multifile.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ func maxConcurrentFiles() int {
}

func multifileExecute(ctx context.Context, manifest pget.Manifest) error {
logger := logging.GetLogger()

chunkSize, err := humanize.ParseBytes(viper.GetString(config.OptChunkSize))
if err != nil {
return err
Expand Down Expand Up @@ -131,6 +133,13 @@ func multifileExecute(ctx context.Context, manifest pget.Manifest) error {
return fmt.Errorf("error getting consumer: %w", err)
}

// Special case, if we're writing to stdout, we only want to download one file at a time, since we can only stream
// a single bytestream to STDOUT
if viper.GetString(config.OptOutputConsumer) == config.ConsumerSTDOUT {
logger.Info().Msg("Using single file mode for STDOUT consumer")
pgetOpts.MaxConcurrentFiles = 1
}

getter := &pget.Getter{
Downloader: download.GetBufferMode(downloadOpts),
Consumer: consumer,
Expand Down Expand Up @@ -158,7 +167,6 @@ func multifileExecute(ctx context.Context, manifest pget.Manifest) error {
}

throughput := float64(totalFileSize) / elapsedTime.Seconds()
logger := logging.GetLogger()
logger.Info().
Int("file_count", len(manifest)).
Str("total_bytes_downloaded", humanize.Bytes(uint64(totalFileSize))).
Expand Down
3 changes: 3 additions & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const (
ConsumerFile = "file"
ConsumerTarExtractor = "tar-extractor"
ConsumerNull = "null"
ConsumerSTDOUT = "stdout"
)

var (
Expand Down Expand Up @@ -153,6 +154,8 @@ func GetConsumer() (consumer.Consumer, error) {
return &consumer.TarExtractor{Overwrite: enableOverwrite}, nil
case ConsumerNull:
return &consumer.NullWriter{}, nil
case ConsumerSTDOUT:
return &consumer.StdoutConsumer{}, nil
default:
return nil, fmt.Errorf("invalid consumer specified: %s", consumerName)
}
Expand Down
20 changes: 20 additions & 0 deletions pkg/consumer/stdout.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package consumer

import (
"fmt"
"io"
"os"
)

var _ Consumer = &StdoutConsumer{}

type StdoutConsumer struct {
}

func (s StdoutConsumer) Consume(reader io.Reader, destPath string) error {
_, err := io.Copy(os.Stdout, reader)
if err != nil {
return fmt.Errorf("error writing to stdout: %w", err)
}
return nil
}

0 comments on commit d84009f

Please sign in to comment.