this repo has no description
at main 96 lines 2.4 kB view raw
1package processor 2 3import ( 4 "fmt" 5 "os" 6 7 "github.com/aottr/nox/internal/cache" 8 "github.com/aottr/nox/internal/config" 9 "github.com/aottr/nox/internal/crypto" 10 "github.com/aottr/nox/internal/git" 11 "github.com/aottr/nox/internal/logging" 12 "github.com/aottr/nox/internal/state" 13) 14 15func SyncApp(ctx *config.RuntimeContext) error { 16 17 log := logging.Get() 18 var err error 19 cfg, appName, identities, st := ctx.Config, ctx.App, ctx.Identities, ctx.State 20 21 if appName == "" { 22 return fmt.Errorf("app name is required") 23 } 24 25 // retrieve app config and repository 26 app := cfg.Apps[appName] 27 gitConf := app.GitConfig 28 if !gitConf.IsValid() { 29 gitConf = cfg.GitConfig 30 } 31 32 key := cache.RepoKey{Repo: gitConf.Repo, Branch: gitConf.Branch} 33 repo, err := cache.GlobalCache.GetOrFetch(key) 34 if err != nil { 35 return fmt.Errorf("failed to fetch repo for app %s: %w", appName, err) 36 } 37 38 // iterate over files and decrypt 39 for _, file := range app.Files { 40 content, err := git.GetFileContentFromTree(repo.Tree, file.Path) 41 if err != nil { 42 return fmt.Errorf("failed to get file %s: %w", file, err) 43 } 44 45 hash := state.HashContent(content) 46 cacheKey := state.GenerateKey(appName, file.Path) 47 48 // skip if file is up to date and force is not set 49 if !ctx.Force && !ctx.DryRun { 50 if prevHash, ok := st.Data[cacheKey]; ok && prevHash == hash { 51 log.Debug(fmt.Sprintf("file %s is up to date", file.Path)) 52 continue 53 } 54 } 55 56 // decrypt file 57 plaintext, err := crypto.DecryptBytes(content, identities) 58 if err != nil { 59 log.Warn("failed to decrypt file %s: %v", file.Path, err) 60 continue 61 } 62 63 // skip writing file if dry run is set 64 if ctx.DryRun { 65 log.Debug(fmt.Sprintf("dry run, not writing file %s", file.Output)) 66 os.Stdout.Write(plaintext) 67 continue 68 } 69 if err := WriteToFile(plaintext, file); err != nil { 70 log.Error("failed to write file %s: %v", file.Output, err) 71 continue 72 } 73 74 log.Debug(fmt.Sprintf("decrypted %s for app %s (size: %d bytes)", file, appName, len(plaintext))) 75 76 // update state 77 st.Data[cacheKey] = hash 78 st.Touch() 79 } 80 81 if err := state.Save(st); err != nil { 82 return fmt.Errorf("failed to save state: %w", err) 83 } 84 return nil 85} 86 87func SyncApps(ctx *config.RuntimeContext) error { 88 for appName := range ctx.Config.Apps { 89 ctx.App = appName 90 logging.Get().Debug(fmt.Sprintf("Processing app: %s", appName)) 91 if err := SyncApp(ctx); err != nil { 92 return err 93 } 94 } 95 return nil 96}