utils.go raw

   1  package utils
   2  
   3  import (
   4  	"fmt"
   5  	"io"
   6  	"os"
   7  	"strings"
   8  	"unicode"
   9  )
  10  
  11  func ReadFileTail(filePath string, maxLen int) (data []byte, err error) {
  12  	f, err := os.Open(filePath)
  13  	if err != nil {
  14  		return nil, fmt.Errorf("failed to open file: %w", err)
  15  	}
  16  	defer func() {
  17  		err = f.Close()
  18  		if err != nil {
  19  			err = fmt.Errorf("failed to close file: %w", err)
  20  			data = nil
  21  		}
  22  	}()
  23  
  24  	var dataReader io.Reader = f
  25  
  26  	if maxLen > 0 {
  27  		stat, err := f.Stat()
  28  		if err != nil {
  29  			return nil, fmt.Errorf("failed to stat file: %w", err)
  30  		}
  31  
  32  		if stat.Size() > int64(maxLen) {
  33  			_, err = f.Seek(-int64(maxLen), io.SeekEnd)
  34  			if err != nil {
  35  				return nil, fmt.Errorf("failed to seek file: %w", err)
  36  			}
  37  		}
  38  
  39  		dataReader = io.LimitReader(f, int64(maxLen))
  40  	}
  41  
  42  	data, err = io.ReadAll(dataReader)
  43  	if err != nil {
  44  		return nil, fmt.Errorf("failed to read file: %w", err)
  45  	}
  46  
  47  	return data, nil
  48  }
  49  
  50  // filters values from a slice
  51  func Filter[T any](s []T, f func(T) bool) []T {
  52  	var r []T
  53  	for _, v := range s {
  54  		if f(v) {
  55  			r = append(r, v)
  56  		}
  57  	}
  58  	return r
  59  }
  60  
  61  func ParseCommandLine(s string) ([]string, error) {
  62  	args := make([]string, 0)
  63  	var currentArg strings.Builder
  64  	inQuotes := false
  65  	escaped := false
  66  
  67  	for _, r := range s {
  68  		switch {
  69  		case escaped:
  70  			currentArg.WriteRune(r)
  71  			escaped = false
  72  		case r == '\\':
  73  			escaped = true
  74  		case r == '"':
  75  			inQuotes = !inQuotes
  76  		case unicode.IsSpace(r) && !inQuotes:
  77  			if currentArg.Len() > 0 {
  78  				args = append(args, currentArg.String())
  79  				currentArg.Reset()
  80  			}
  81  		default:
  82  			currentArg.WriteRune(r)
  83  		}
  84  	}
  85  
  86  	if escaped || inQuotes {
  87  		return nil, fmt.Errorf("unexpected end of string")
  88  	}
  89  
  90  	if currentArg.Len() > 0 {
  91  		args = append(args, currentArg.String())
  92  	}
  93  
  94  	return args, nil
  95  }
  96