code.gitea.io/gitea@v1.22.3/modules/git/utils.go (about)

     1  // Copyright 2015 The Gogs Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package git
     5  
     6  import (
     7  	"crypto/sha1"
     8  	"encoding/hex"
     9  	"fmt"
    10  	"io"
    11  	"os"
    12  	"strconv"
    13  	"strings"
    14  	"sync"
    15  )
    16  
    17  // ObjectCache provides thread-safe cache operations.
    18  type ObjectCache struct {
    19  	lock  sync.RWMutex
    20  	cache map[string]any
    21  }
    22  
    23  func newObjectCache() *ObjectCache {
    24  	return &ObjectCache{
    25  		cache: make(map[string]any, 10),
    26  	}
    27  }
    28  
    29  // Set add obj to cache
    30  func (oc *ObjectCache) Set(id string, obj any) {
    31  	oc.lock.Lock()
    32  	defer oc.lock.Unlock()
    33  
    34  	oc.cache[id] = obj
    35  }
    36  
    37  // Get get cached obj by id
    38  func (oc *ObjectCache) Get(id string) (any, bool) {
    39  	oc.lock.RLock()
    40  	defer oc.lock.RUnlock()
    41  
    42  	obj, has := oc.cache[id]
    43  	return obj, has
    44  }
    45  
    46  // isDir returns true if given path is a directory,
    47  // or returns false when it's a file or does not exist.
    48  func isDir(dir string) bool {
    49  	f, e := os.Stat(dir)
    50  	if e != nil {
    51  		return false
    52  	}
    53  	return f.IsDir()
    54  }
    55  
    56  // isFile returns true if given path is a file,
    57  // or returns false when it's a directory or does not exist.
    58  func isFile(filePath string) bool {
    59  	f, e := os.Stat(filePath)
    60  	if e != nil {
    61  		return false
    62  	}
    63  	return !f.IsDir()
    64  }
    65  
    66  // isExist checks whether a file or directory exists.
    67  // It returns false when the file or directory does not exist.
    68  func isExist(path string) bool {
    69  	_, err := os.Stat(path)
    70  	return err == nil || os.IsExist(err)
    71  }
    72  
    73  // ConcatenateError concatenats an error with stderr string
    74  func ConcatenateError(err error, stderr string) error {
    75  	if len(stderr) == 0 {
    76  		return err
    77  	}
    78  	return fmt.Errorf("%w - %s", err, stderr)
    79  }
    80  
    81  // ParseBool returns the boolean value represented by the string as per git's git_config_bool
    82  // true will be returned for the result if the string is empty, but valid will be false.
    83  // "true", "yes", "on" are all true, true
    84  // "false", "no", "off" are all false, true
    85  // 0 is false, true
    86  // Any other integer is true, true
    87  // Anything else will return false, false
    88  func ParseBool(value string) (result, valid bool) {
    89  	// Empty strings are true but invalid
    90  	if len(value) == 0 {
    91  		return true, false
    92  	}
    93  	// These are the git expected true and false values
    94  	if strings.EqualFold(value, "true") || strings.EqualFold(value, "yes") || strings.EqualFold(value, "on") {
    95  		return true, true
    96  	}
    97  	if strings.EqualFold(value, "false") || strings.EqualFold(value, "no") || strings.EqualFold(value, "off") {
    98  		return false, true
    99  	}
   100  	// Try a number
   101  	intValue, err := strconv.ParseInt(value, 10, 32)
   102  	if err != nil {
   103  		return false, false
   104  	}
   105  	return intValue != 0, true
   106  }
   107  
   108  // LimitedReaderCloser is a limited reader closer
   109  type LimitedReaderCloser struct {
   110  	R io.Reader
   111  	C io.Closer
   112  	N int64
   113  }
   114  
   115  // Read implements io.Reader
   116  func (l *LimitedReaderCloser) Read(p []byte) (n int, err error) {
   117  	if l.N <= 0 {
   118  		_ = l.C.Close()
   119  		return 0, io.EOF
   120  	}
   121  	if int64(len(p)) > l.N {
   122  		p = p[0:l.N]
   123  	}
   124  	n, err = l.R.Read(p)
   125  	l.N -= int64(n)
   126  	return n, err
   127  }
   128  
   129  // Close implements io.Closer
   130  func (l *LimitedReaderCloser) Close() error {
   131  	return l.C.Close()
   132  }
   133  
   134  func HashFilePathForWebUI(s string) string {
   135  	h := sha1.New()
   136  	_, _ = h.Write([]byte(s))
   137  	return hex.EncodeToString(h.Sum(nil))
   138  }