Implement initial version of fetch_artifact

BUG=121042212

Change-Id: Ib6a701df8c28decd48771c65ca9f618c8d0cf8fe
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..466e248
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+out/
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..e23d01b
--- /dev/null
+++ b/README.md
@@ -0,0 +1,31 @@
+# Fetch Artifact
+
+Fetch artifact is a tool for downloading artifacts from Android's continuous integration service.
+
+
+## Options
+
+* `target`: **Required** - The target you would like to download the artifact from.
+* `build_id`: **Required** - The build_id of the target to download the artifact from.
+* `artifact`: **Required** - The artifact to download.
+* `output`: *Optional* - If you would like the contents of the file to be written to a specific file
+* `-`: *Optional* - If you would like the contents of the file to be written to stdout  (must be the last arg)
+
+
+## Example useage
+
+```
+fetch_artifact -target=aosp_arm64-userdebug -build_id=7000390 -artifact=COPIED
+```
+
+### Streaming contents to stdout
+
+```
+fetch_artifact -target=aosp_arm64-userdebug -build_id=7000390 -artifact=COPIED -
+```
+
+## Development
+
+### Building
+
+OUT_DIR=out ./build
\ No newline at end of file
diff --git a/build.sh b/build.sh
new file mode 100755
index 0000000..2040428
--- /dev/null
+++ b/build.sh
@@ -0,0 +1,18 @@
+#!/bin/bash -ex
+
+# Copyright 2020 Google Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+OUT=${OUT_DIR:-out}  # default to out if not set.
+../prebuilts/go/linux-x86/bin/go build -o ${OUT}/fetch_artifact fetch_artifact.go
diff --git a/fetch_artifact.go b/fetch_artifact.go
new file mode 100644
index 0000000..843864c
--- /dev/null
+++ b/fetch_artifact.go
@@ -0,0 +1,96 @@
+// Copyright 2020 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package main
+
+import (
+	"flag"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"net/http"
+	"os"
+	"path"
+)
+
+var target = flag.String("target", "", "the target to fetch from")
+var buildID = flag.String("build_id", "", "the build id to fetch from")
+var artifact = flag.String("artifact", "", "the artifact to download")
+var output = flag.String("output", "", "the file name to save as")
+var writeToStdout = false
+
+func errPrint(msg string) {
+	fmt.Fprintln(os.Stderr, msg)
+	os.Exit(1)
+}
+
+func main() {
+	flag.Parse()
+	args := flag.Args()
+	// We only support passing 1 argument `-` so if we have more than
+	// one argument this is an error state,
+	if len(args) > 1 {
+		errPrint("Error: Too many arguments passed to fetch_artifact.")
+	}
+
+	if len(args) > 0 {
+		writeToStdout = args[len(args)-1] == "-"
+		if !writeToStdout {
+			errPrint(fmt.Sprintf(
+				"Error: Only supported final argument to fetch_artifact is `-` but got `%s`.", args[len(args)-1]))
+		}
+
+		if len(*output) > 0 && writeToStdout {
+			errPrint("Error: Both '-output' and '-' flags can not be used together.")
+		}
+	}
+
+	url := fmt.Sprintf("https://androidbuildinternal.googleapis.com/android/internal/build/v3/builds/%s/%s/attempts/latest/artifacts/%s/url", *buildID, *target, *artifact)
+
+	req, err := http.NewRequest("GET", url, nil)
+	if err != nil {
+		errPrint(fmt.Sprintf("unable to build request %v", err))
+	}
+	req.Header.Set("Accept", "application/json")
+
+	client := http.Client{}
+	res, err := client.Do(req)
+	if err != nil {
+		errPrint(fmt.Sprintf("Unable to make request %s.", err))
+	}
+	defer res.Body.Close()
+
+	if res.Status != "200 OK" {
+		body, _ := ioutil.ReadAll(res.Body)
+		errPrint(fmt.Sprintf("Unable to download artifact: %s\n %s.", res.Status, body))
+	}
+
+	if writeToStdout {
+		io.Copy(os.Stdout, res.Body)
+		return
+	}
+
+	fileName := *artifact
+	if len(*output) > 0 {
+		fileName = *output
+	}
+
+	f, err := os.Create(path.Base(fileName))
+	if err != nil {
+		errPrint(fmt.Sprintf("Unable to create file %s.", err))
+	}
+	defer f.Close()
+	io.Copy(f, res.Body)
+	fmt.Printf("File %s created.\n", f.Name())
+}