From 8f9726c6e47c2c722137f2d2aabe4c507ece5c14 Mon Sep 17 00:00:00 2001 From: Castor Gemini Date: Fri, 22 Aug 2025 03:45:34 -0500 Subject: [PATCH] refactor(add): Create dedicated addFile function - Move all file reading and content-inlining logic into a new 'addFile' function in its own 'add.go' file. - The main function now calls this to parse a log file and then appends the returned chats to the main session. - This improves separation of concerns and makes the main loop cleaner. --- add.go | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ main.go | 22 ++++++++++---------- 2 files changed, 74 insertions(+), 11 deletions(-) create mode 100644 add.go diff --git a/add.go b/add.go new file mode 100644 index 0000000..02b42a6 --- /dev/null +++ b/add.go @@ -0,0 +1,63 @@ +package main + +import ( + "fmt" + "os" + "path/filepath" + + "go.wit.com/lib/protobuf/chatpb" + "go.wit.com/log" +) + +// addFile reads a protobuf text file, inlines all external content, and returns +// a self-contained *chatpb.Chats object. +func addFile(filename string) (*chatpb.Chats, error) { + data, err := os.ReadFile(filename) + if err != nil { + return nil, fmt.Errorf("failed to read file %s: %w", filename, err) + } + + logData, err := chatpb.UnmarshalChatsTEXT(data) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal log file %s: %w", filename, err) + } + + log.Infof("Successfully parsed log file: %s", filename) + + // Get the directory of the log file to resolve relative content paths. + logDir := filepath.Dir(filename) + + // Iterate through the structure to inline all external content. + for _, chat := range logData.GetChats() { + for _, entry := range chat.GetEntries() { + // Inline main content from ContentFile + if contentFile := entry.GetContentFile(); contentFile != "" { + contentPath := filepath.Join(logDir, contentFile) + contentBytes, err := os.ReadFile(contentPath) + if err != nil { + entry.Content = fmt.Sprintf("--- ERROR: Could not read content file %s: %v ---", contentPath, err) + } else { + entry.Content = string(contentBytes) + } + } + + // Inline snippet content from snippet files + if snippets := entry.GetSnippets(); snippets != nil { + for _, snippet := range snippets { + if snippetFile := snippet.GetFilename(); snippetFile != "" { + snippetPath := filepath.Join(logDir, snippetFile) + contentBytes, err := os.ReadFile(snippetPath) + if err != nil { + snippet.Content = fmt.Sprintf("--- ERROR: Could not read snippet file %s: %v ---", snippetPath, err) + } else { + snippet.Content = string(contentBytes) + } + } + } + } + } + } + + log.Info("Successfully inlined all external content.") + return logData, nil +} diff --git a/main.go b/main.go index 880c211..7d294f1 100644 --- a/main.go +++ b/main.go @@ -54,19 +54,19 @@ func main() { } if argv.Add != "" { - me.chats.AddFile(argv.Add) - - // --- Start Diagnostic Check --- - // This loop will check for nil entries in the slice before marshaling. - for i, chat := range me.chats.GetChats() { - if chat == nil { - log.Fatalf("Found a nil *Chat pointer at index %d before calling ConfigSave(). This is the cause of the panic.", i) - } + newChats, err := addFile(argv.Add) + if err != nil { + badExit(err) + } + for _, newChat := range newChats.GetChats() { + me.chats.AppendByUuid(newChat) } - log.Info("Sanity check passed: No nil entries found in the Chats slice.") - // --- End Diagnostic Check --- - me.chats.ConfigSave() + // The verifyUuids function should be run on the main chats object + // after adding the new chats. + if verifyUuids(me.chats) { + me.chats.ConfigSave() + } okExit("") }