Skip to content

Commit cdd305d

Browse files
authored
Output release asset contents to standard output (#103)
* Add support for --stdout flag * Update stdout warning decision branches * Update source of stdout io writer * Add integration test for stdout feature
1 parent 625331e commit cdd305d

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

integration_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,43 @@ func TestFetchWithBranchOption(t *testing.T) {
5252
}
5353
}
5454

55+
func TestFetchWithStdoutOption(t *testing.T) {
56+
tmpDownloadPath, err := ioutil.TempDir("", "fetch-stdout-test")
57+
require.NoError(t, err)
58+
59+
repoUrl := "https://github.com/gruntwork-io/fetch-test-public"
60+
releaseTag := "v0.0.4"
61+
releaseAsset := "hello+world.txt"
62+
63+
cmd := fmt.Sprintf("fetch --repo %s --tag %s --release-asset %s --stdout true %s", repoUrl, releaseTag, releaseAsset, tmpDownloadPath)
64+
t.Logf("Testing command: %s", cmd)
65+
stdoutput, _, err := runFetchCommandWithOutput(t, cmd)
66+
require.NoError(t, err)
67+
68+
// Ensure the expected file was downloaded
69+
assert.FileExists(t, JoinPath(tmpDownloadPath, releaseAsset))
70+
71+
// When --stdout is specified, ensure the file contents are piped to the standard output stream
72+
assert.Contains(t, stdoutput, "hello world")
73+
}
74+
75+
func TestFetchWithStdoutOptionMultipleAssets(t *testing.T) {
76+
tmpDownloadPath, err := ioutil.TempDir("", "fetch-stdout-test")
77+
require.NoError(t, err)
78+
79+
repoUrl := SAMPLE_RELEASE_ASSET_GITHUB_REPO_URL
80+
releaseTag := SAMPLE_RELEASE_ASSET_VERSION
81+
releaseAsset := SAMPLE_RELEASE_ASSET_REGEX
82+
83+
cmd := fmt.Sprintf("fetch --repo %s --tag %s --release-asset %s --stdout true %s", repoUrl, releaseTag, releaseAsset, tmpDownloadPath)
84+
t.Logf("Testing command: %s", cmd)
85+
_, stderr, err := runFetchCommandWithOutput(t, cmd)
86+
require.NoError(t, err)
87+
88+
// When --stdout is specified, ensure the file contents are piped to the standard output stream
89+
assert.Contains(t, stderr, "Multiple assets were downloaded. Ignoring --stdout")
90+
}
91+
5592
func runFetchCommandWithOutput(t *testing.T, command string) (string, string, error) {
5693
stdout := bytes.Buffer{}
5794
stderr := bytes.Buffer{}

main.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ type FetchOptions struct {
3030
ReleaseAsset string
3131
ReleaseAssetChecksums map[string]bool
3232
ReleaseAssetChecksumAlgo string
33+
Stdout bool
3334
LocalDownloadPath string
3435
GithubApiVersion string
3536
WithProgress bool
@@ -53,6 +54,7 @@ const optionSourcePath = "source-path"
5354
const optionReleaseAsset = "release-asset"
5455
const optionReleaseAssetChecksum = "release-asset-checksum"
5556
const optionReleaseAssetChecksumAlgo = "release-asset-checksum-algo"
57+
const optionStdout = "stdout"
5658
const optionGithubAPIVersion = "github-api-version"
5759
const optionWithProgress = "progress"
5860
const optionLogLevel = "log-level"
@@ -117,6 +119,10 @@ func CreateFetchCli(version string, writer io.Writer, errwriter io.Writer) *cli.
117119
Name: optionReleaseAssetChecksumAlgo,
118120
Usage: "The algorithm Fetch will use to compute a checksum of the release asset. Acceptable values\n\tare \"sha256\" and \"sha512\".",
119121
},
122+
cli.StringFlag{
123+
Name: optionStdout,
124+
Usage: "If \"true\", the contents of the release asset is sent to standard output so it can be piped to another command.",
125+
},
120126
cli.StringFlag{
121127
Name: optionGithubAPIVersion,
122128
Value: "v3",
@@ -250,6 +256,25 @@ func runFetch(c *cli.Context, logger *logrus.Logger) error {
250256
}
251257
}
252258

259+
if options.Stdout {
260+
// Print to stdout only if a single asset was downloaded
261+
if len(assetPaths) == 1 {
262+
dat, err := os.ReadFile(assetPaths[0])
263+
if err != nil {
264+
return err
265+
}
266+
c.App.Writer.Write(dat) // This should be stdout
267+
} else {
268+
269+
if len(assetPaths) > 1 {
270+
logger.Warn("Multiple assets were downloaded. Ignoring --stdout")
271+
} else {
272+
logger.Warn("No assets were downloaded. Ignoring --stdout")
273+
}
274+
275+
}
276+
}
277+
253278
return nil
254279
}
255280

@@ -282,6 +307,7 @@ func parseOptions(c *cli.Context, logger *logrus.Logger) FetchOptions {
282307
ReleaseAsset: c.String(optionReleaseAsset),
283308
ReleaseAssetChecksums: assetChecksumMap,
284309
ReleaseAssetChecksumAlgo: c.String(optionReleaseAssetChecksumAlgo),
310+
Stdout: c.String(optionStdout) == "true",
285311
LocalDownloadPath: localDownloadPath,
286312
GithubApiVersion: c.String(optionGithubAPIVersion),
287313
WithProgress: c.IsSet(optionWithProgress),

0 commit comments

Comments
 (0)