github.com/freiheit-com/kuberpult@v1.24.2-0.20240328135542-315d5630abe6/services/cd-service/pkg/event/reader.go (about) 1 /*This file is part of kuberpult. 2 3 Kuberpult is free software: you can redistribute it and/or modify 4 it under the terms of the Expat(MIT) License as published by 5 the Free Software Foundation. 6 7 Kuberpult is distributed in the hope that it will be useful, 8 but WITHOUT ANY WARRANTY; without even the implied warranty of 9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 MIT License for more details. 11 12 You should have received a copy of the MIT License 13 along with kuberpult. If not, see <https://directory.fsf.org/wiki/License:Expat>. 14 15 Copyright 2023 freiheit.com*/ 16 17 package event 18 19 import ( 20 "errors" 21 "fmt" 22 fserr "io/fs" 23 "reflect" 24 25 "github.com/go-git/go-billy/v5" 26 "github.com/go-git/go-billy/v5/util" 27 ) 28 29 func read( 30 filesystem billy.Filesystem, 31 dir string, 32 val any, 33 ) error { 34 v := reflect.ValueOf(val) 35 return readFile(filesystem, dir, v.Elem(), v.Elem().Type(), encodingDefault) 36 } 37 38 func readFile( 39 fs billy.Filesystem, 40 file string, 41 value reflect.Value, 42 tp reflect.Type, 43 encoding encoding, 44 ) error { 45 switch tp.Kind() { 46 case reflect.Pointer: 47 _, err := fs.Stat(file) 48 if err != nil { 49 if errors.Is(err, fserr.ErrNotExist) { 50 return nil 51 } 52 return err 53 } 54 if value.IsNil() { 55 value.Set(reflect.New(tp.Elem())) 56 } 57 return readFile(fs, file, value.Elem(), tp.Elem(), encoding) 58 case reflect.String: 59 cont, err := util.ReadFile(fs, file) 60 if err != nil { 61 return err 62 } 63 value.SetString(string(cont)) 64 return nil 65 case reflect.Struct: 66 for i := 0; i < tp.NumField(); i++ { 67 f := tp.Field(i) 68 name, enc := parseTag(f.Tag.Get("fs")) 69 if name == "" { 70 name = f.Name 71 } 72 if err := readFile(fs, 73 fs.Join(file, name), 74 value.Field(i), 75 f.Type, 76 enc, 77 ); err != nil { 78 return err 79 } 80 } 81 return nil 82 case reflect.Map: 83 if tp.Key().Kind() != reflect.String { 84 return fmt.Errorf("can only use maps with strings as keys") 85 } 86 files, err := fs.ReadDir(file) 87 if err != nil { 88 return err 89 } 90 if value.IsNil() { 91 value.Set(reflect.MakeMapWithSize(tp, len(files))) 92 } 93 for _, sub := range files { 94 if sub.Name() == ".gitkeep" { 95 continue 96 } 97 val := reflect.New(tp.Elem()).Elem() 98 if err := readFile(fs, 99 fs.Join(file, sub.Name()), 100 val, 101 tp.Elem(), 102 encodingDefault, 103 ); err != nil { 104 return err 105 } 106 value.SetMapIndex(reflect.ValueOf(sub.Name()), val) 107 } 108 return nil 109 default: 110 return fmt.Errorf("cannot read type %v", tp) 111 } 112 }