github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/release/update/util.go (about)

     1  // Copyright 2015 Keybase, Inc. All rights reserved. Use of
     2  // this source code is governed by the included BSD license.
     3  
     4  package update
     5  
     6  import (
     7  	"crypto/rand"
     8  	"encoding/base32"
     9  	"fmt"
    10  	"net/url"
    11  	"os"
    12  	"path/filepath"
    13  	"strings"
    14  )
    15  
    16  func urlStringForKey(key string, bucketName string, prefix string) (string, string) {
    17  	name := key[len(prefix):]
    18  	return fmt.Sprintf("https://s3.amazonaws.com/%s/%s%s", bucketName, prefix, url.QueryEscape(name)), name
    19  }
    20  
    21  func urlString(bucketName string, prefix string, name string) string {
    22  	if prefix == "" {
    23  		return fmt.Sprintf("https://s3.amazonaws.com/%s/%s", bucketName, url.QueryEscape(name))
    24  	}
    25  	return fmt.Sprintf("https://s3.amazonaws.com/%s/%s%s", bucketName, prefix, url.QueryEscape(name))
    26  }
    27  
    28  func urlStringNoEscape(bucketName string, name string) string {
    29  	return fmt.Sprintf("https://s3.amazonaws.com/%s/%s", bucketName, name)
    30  }
    31  
    32  func makeParentDirs(filename string) error {
    33  	dir, _ := filepath.Split(filename)
    34  	exists, err := fileExists(dir)
    35  	if err != nil {
    36  		return err
    37  	}
    38  
    39  	if !exists {
    40  		err = os.MkdirAll(dir, 0755)
    41  		if err != nil {
    42  			return err
    43  		}
    44  	}
    45  	return nil
    46  }
    47  
    48  func fileExists(path string) (bool, error) {
    49  	_, err := os.Stat(path)
    50  	if err == nil {
    51  		return true, nil
    52  	}
    53  	if os.IsNotExist(err) {
    54  		return false, nil
    55  	}
    56  	return false, err
    57  }
    58  
    59  // CombineErrors returns a single error for multiple errors, or nil if none
    60  func CombineErrors(errs ...error) error {
    61  	errs = RemoveNilErrors(errs)
    62  	if len(errs) == 0 {
    63  		return nil
    64  	} else if len(errs) == 1 {
    65  		return errs[0]
    66  	}
    67  
    68  	msgs := []string{}
    69  	for _, err := range errs {
    70  		msgs = append(msgs, err.Error())
    71  	}
    72  	return fmt.Errorf("There were multiple errors: %s", strings.Join(msgs, "; "))
    73  }
    74  
    75  // RemoveNilErrors returns error slice with nil errors removed
    76  func RemoveNilErrors(errs []error) []error {
    77  	var r []error
    78  	for _, err := range errs {
    79  		if err != nil {
    80  			r = append(r, err)
    81  		}
    82  	}
    83  	return r
    84  }
    85  
    86  // RandomID returns a random identifier
    87  func RandomID() (string, error) {
    88  	buf, err := RandBytes(32)
    89  	if err != nil {
    90  		return "", err
    91  	}
    92  	str := base32.StdEncoding.EncodeToString(buf)
    93  	str = strings.ReplaceAll(str, "=", "")
    94  	return str, nil
    95  }
    96  
    97  var randRead = rand.Read
    98  
    99  // RandBytes returns random bytes of length
   100  func RandBytes(length int) ([]byte, error) {
   101  	buf := make([]byte, length)
   102  	if _, err := randRead(buf); err != nil {
   103  		return nil, err
   104  	}
   105  	return buf, nil
   106  }