github.com/distbuild/reclient@v0.0.0-20240401075343-3de72e395564/experiments/internal/pkg/gcs/gcs.go (about) 1 // Copyright 2023 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package gcs contains logic relevant to GCS storage. 16 // 17 // TODO(b/170271950): use gcs API instead. 18 package gcs 19 20 import ( 21 "context" 22 "fmt" 23 "os" 24 "os/exec" 25 "strings" 26 27 log "github.com/golang/glog" 28 ) 29 30 // Copy copies a file from/to GCS. 31 func Copy(ctx context.Context, src, dest string) error { 32 log.Infof("Copying %v", src) 33 args := []string{"gsutil", "cp", src, dest} 34 cmd := exec.CommandContext(ctx, args[0], args[1:]...) 35 cmd.Stdin = os.Stdin // Connect stdin to allow gcloud to use gsutil reauth flow 36 if oe, err := cmd.CombinedOutput(); err != nil { 37 return fmt.Errorf("failed to copy files: %v, outerr: %v", err, string(oe)) 38 } 39 log.Infof("Copied %v to %v", src, dest) 40 return nil 41 } 42 43 // List lists the contents of a directory in GCS. 44 func List(ctx context.Context, dir string) ([]string, error) { 45 args := []string{"gsutil", "ls", dir} 46 oe, err := exec.CommandContext(ctx, args[0], args[1:]...).CombinedOutput() 47 if err != nil { 48 return nil, fmt.Errorf("failed to list dir: %v, outerr: %v", err, string(oe)) 49 } 50 return deleteEmpty(strings.Split(string(oe), "\n")), nil 51 } 52 53 func deleteEmpty(s []string) []string { 54 var r []string 55 for _, str := range s { 56 if str != "" { 57 r = append(r, str) 58 } 59 } 60 return r 61 }