2016-11-03 23:16:01 +01:00
// Copyright 2015 The Gogs Authors. All rights reserved.
2022-11-27 13:20:29 -05:00
// SPDX-License-Identifier: MIT
2016-11-03 23:16:01 +01:00
package git
import (
2024-05-20 23:12:50 +08:00
"crypto/sha1"
"encoding/hex"
2016-11-03 23:16:01 +01:00
"fmt"
2020-12-17 14:00:47 +00:00
"io"
2016-11-03 23:16:01 +01:00
"os"
2019-10-16 14:42:42 +01:00
"strconv"
2016-11-03 23:16:01 +01:00
"strings"
"sync"
)
2021-07-08 07:38:13 -04:00
// ObjectCache provides thread-safe cache operations.
2024-11-20 11:26:12 -08:00
type ObjectCache [ T any ] struct {
2016-11-03 23:16:01 +01:00
lock sync . RWMutex
2024-11-20 11:26:12 -08:00
cache map [ string ] T
2016-11-03 23:16:01 +01:00
}
2024-11-20 11:26:12 -08:00
func newObjectCache [ T any ] ( ) * ObjectCache [ T ] {
return & ObjectCache [ T ] { cache : make ( map [ string ] T , 10 ) }
2016-11-03 23:16:01 +01:00
}
2024-11-20 11:26:12 -08:00
// Set adds obj to cache
func ( oc * ObjectCache [ T ] ) Set ( id string , obj T ) {
2016-11-03 23:16:01 +01:00
oc . lock . Lock ( )
defer oc . lock . Unlock ( )
oc . cache [ id ] = obj
}
2024-11-20 11:26:12 -08:00
// Get gets cached obj by id
func ( oc * ObjectCache [ T ] ) Get ( id string ) ( T , bool ) {
2016-11-03 23:16:01 +01:00
oc . lock . RLock ( )
defer oc . lock . RUnlock ( )
obj , has := oc . cache [ id ]
return obj , has
}
// isDir returns true if given path is a directory,
// or returns false when it's a file or does not exist.
func isDir ( dir string ) bool {
f , e := os . Stat ( dir )
if e != nil {
return false
}
return f . IsDir ( )
}
// isFile returns true if given path is a file,
// or returns false when it's a directory or does not exist.
func isFile ( filePath string ) bool {
f , e := os . Stat ( filePath )
if e != nil {
return false
}
return ! f . IsDir ( )
}
// isExist checks whether a file or directory exists.
// It returns false when the file or directory does not exist.
func isExist ( path string ) bool {
_ , err := os . Stat ( path )
return err == nil || os . IsExist ( err )
}
2020-12-17 14:00:47 +00:00
// ConcatenateError concatenats an error with stderr string
func ConcatenateError ( err error , stderr string ) error {
2016-11-03 23:16:01 +01:00
if len ( stderr ) == 0 {
return err
}
2020-12-17 14:00:47 +00:00
return fmt . Errorf ( "%w - %s" , err , stderr )
2016-11-03 23:16:01 +01:00
}
2019-10-16 14:42:42 +01:00
// ParseBool returns the boolean value represented by the string as per git's git_config_bool
// true will be returned for the result if the string is empty, but valid will be false.
// "true", "yes", "on" are all true, true
// "false", "no", "off" are all false, true
// 0 is false, true
// Any other integer is true, true
// Anything else will return false, false
2021-12-20 05:41:31 +01:00
func ParseBool ( value string ) ( result , valid bool ) {
2019-10-16 14:42:42 +01:00
// Empty strings are true but invalid
if len ( value ) == 0 {
return true , false
}
// These are the git expected true and false values
if strings . EqualFold ( value , "true" ) || strings . EqualFold ( value , "yes" ) || strings . EqualFold ( value , "on" ) {
return true , true
}
if strings . EqualFold ( value , "false" ) || strings . EqualFold ( value , "no" ) || strings . EqualFold ( value , "off" ) {
return false , true
}
// Try a number
intValue , err := strconv . ParseInt ( value , 10 , 32 )
if err != nil {
return false , false
}
return intValue != 0 , true
}
2020-12-17 14:00:47 +00:00
// LimitedReaderCloser is a limited reader closer
type LimitedReaderCloser struct {
R io . Reader
C io . Closer
N int64
}
// Read implements io.Reader
func ( l * LimitedReaderCloser ) Read ( p [ ] byte ) ( n int , err error ) {
if l . N <= 0 {
_ = l . C . Close ( )
return 0 , io . EOF
}
if int64 ( len ( p ) ) > l . N {
p = p [ 0 : l . N ]
}
n , err = l . R . Read ( p )
l . N -= int64 ( n )
2022-06-20 12:02:49 +02:00
return n , err
2020-12-17 14:00:47 +00:00
}
// Close implements io.Closer
func ( l * LimitedReaderCloser ) Close ( ) error {
return l . C . Close ( )
}
2024-05-20 23:12:50 +08:00
func HashFilePathForWebUI ( s string ) string {
h := sha1 . New ( )
_ , _ = h . Write ( [ ] byte ( s ) )
return hex . EncodeToString ( h . Sum ( nil ) )
}