[artifacts] Add the ability to write files

We need this to implement ResultStore uploads. RS only accepts
URLs from GCS with the format `gs://bucket/object`.

IN-888 #comment

TEST=ran the commands in artifacts/main.go by hand.

Change-Id: If65ab587befc9aaba870649ab9675add9939a43b
diff --git a/artifacts/artifacts.go b/artifacts/artifacts.go
index dba0950..995e178 100644
--- a/artifacts/artifacts.go
+++ b/artifacts/artifacts.go
@@ -29,19 +29,27 @@
 }
 
 // List lists all objects in the artifact directory for the given build. bucket is the
-// Cloud Storage bucket the builder uploaded artifacts to.
+// Cloud Storage bucket for the given build.
 func (c *ArtifactsClient) List(ctx context.Context, bucket, build string) ([]string, error) {
 	dir := c.openDir(ctx, bucket, build)
 	return dir.list(ctx)
 }
 
 // Open returns a reader for an object in the artifact directory for the given build.
-// bucket is the Cloud Storage bucket the builder uploaded artifacts to.
+// bucket is the Cloud Storage bucket for the given build.
 func (c *ArtifactsClient) Open(ctx context.Context, bucket, build, path string) (io.Reader, error) {
 	dir := c.openDir(ctx, bucket, build)
 	return dir.open(ctx, path)
 }
 
+// Create returns a storage.Writer for an object in the artifact directory. bucket is the
+// Cloud Storage bucket for the given build. build is the string Buildbucket build ID.
+// path is the object path relative to the root of the build artifact directory.
+func (c *ArtifactsClient) Create(ctx context.Context, bucket, build, path string) *storage.Writer {
+	dir := c.openDir(ctx, bucket, build)
+	return dir.create(ctx, path)
+}
+
 // openDir returns a Handle to a build's artifact directory within some bucket.
 func (c *ArtifactsClient) openDir(ctx context.Context, bucket, build string) *directory {
 	handle := c.client.Bucket(bucket)
@@ -62,12 +70,18 @@
 	build  string
 }
 
-// openDir returns an io.Reader for the object at the given object in this directory.
+// open returns an io.Reader for the given object in this directory.
 func (d *directory) open(ctx context.Context, object string) (io.Reader, error) {
 	object = strings.Join([]string{"builds", d.build, object}, "/")
 	return d.bucket.Object(object).NewReader(ctx)
 }
 
+// create returns a storage.Writer for the given object in this directory.
+func (d *directory) create(ctx context.Context, object string) *storage.Writer {
+	object = strings.Join([]string{"builds", d.build, object}, "/")
+	return d.bucket.Object(object).NewWriter(ctx)
+}
+
 // List lists all of the objects in this directory.
 func (d *directory) list(ctx context.Context) ([]string, error) {
 	prefix := strings.Join([]string{"builds", d.build}, "/")