@@ -169,39 +169,38 @@ func updateCustomPatchAndUpdateGenLock(ctx context.Context, wf *workflow.Workflo
169169 }
170170 logger .Info ("Created commit with custom code changes" , zap .String ("commit_hash" , customCodeCommitHash ))
171171
172- // Step 11: Update gen.lock with full combined patch and commit hash
173- if err := updateGenLockWithPatch (getTargetOutput (target ), targetPatches [targetName ], customCodeCommitHash ); err != nil {
174- return fmt .Errorf ("failed to update gen.lock : %w" , err )
172+ // Step 11: Save custom code patch and update gen.lock with commit hash
173+ if err := saveCustomCodePatch (getTargetOutput (target ), targetPatches [targetName ], customCodeCommitHash ); err != nil {
174+ return fmt .Errorf ("failed to save custom code patch : %w" , err )
175175 }
176176
177- // Step 12: Commit just gen.lock with new patch
178- if err := commitGenLock (getTargetOutput (target )); err != nil {
179- return fmt .Errorf ("failed to commit gen.lock : %w" , err )
177+ // Step 12: Commit gen.lock and patch file
178+ if err := commitCustomCodeRegistration (getTargetOutput (target )); err != nil {
179+ return fmt .Errorf ("failed to commit custom code registration : %w" , err )
180180 }
181181 return nil
182182}
183183
184- // ShowCustomCodePatch displays the custom code patch stored in the gen.lock file
184+ // ShowCustomCodePatch displays the custom code patch stored in the patch file
185185func ShowCustomCodePatch (ctx context.Context , target workflow.Target ) error {
186186 logger := log .From (ctx ).With (zap .String ("method" , "ShowCustomCodePatch" ))
187187
188188 outDir := getTargetOutput (target )
189189
190- cfg , err := config .Load (outDir )
190+ // Read patch from file
191+ patchStr , err := readPatchFile (outDir )
191192 if err != nil {
192- return fmt .Errorf ("failed to load config : %w" , err )
193+ return fmt .Errorf ("failed to read patch file : %w" , err )
193194 }
194-
195- customCodePatch , exists := cfg .LockFile .Management .AdditionalProperties ["customCodePatch" ]
196- if ! exists {
195+ if patchStr == "" {
197196 logger .Warn ("No existing custom code patch found" )
198197 return nil
199198 }
200199
201- patchStr , ok := customCodePatch .( string )
202- if ! ok || patchStr == "" {
203- logger . Warn ( "No existing custom code patch found" )
204- return nil
200+ // Load config to get commit hash
201+ cfg , err := config . Load ( outDir )
202+ if err != nil {
203+ return fmt . Errorf ( "failed to load config: %w" , err )
205204 }
206205
207206 // Check if there's a commit hash associated with this patch
@@ -258,23 +257,16 @@ func ResolveCustomCodeConflicts(ctx context.Context) error {
258257 for targetName , target := range wf .Targets {
259258 outDir := getTargetOutput (target )
260259
261- // Check if patch exists in gen.lock
262- cfg , err := config . Load (outDir )
260+ // Check if patch file exists
261+ patchStr , err := readPatchFile (outDir )
263262 if err != nil {
264- return fmt .Errorf ("failed to load config for target %s: %w" , targetName , err )
263+ return fmt .Errorf ("failed to read patch file for target %s: %w" , targetName , err )
265264 }
266-
267- customCodePatch , exists := cfg .LockFile .Management .AdditionalProperties ["customCodePatch" ]
268- if ! exists {
265+ if patchStr == "" {
269266 logger .Info (fmt .Sprintf ("No custom code patch for target %s, skipping" , targetName ))
270267 continue
271268 }
272269
273- patchStr , ok := customCodePatch .(string )
274- if ! ok || patchStr == "" {
275- continue
276- }
277-
278270 logger .Info (fmt .Sprintf ("Resolving conflicts for target %s" , targetName ))
279271
280272 // Step 1: Undo patch application - extract clean new generation from "ours" side
@@ -734,49 +726,49 @@ func commitCustomCodeChanges() (string, error) {
734726 return commitHash , nil
735727}
736728
737- func commitGenLock (outDir string ) error {
738- // Add only the gen.lock file
739- cmd := exec .Command ("git" , "add" , fmt .Sprintf ("%v/.speakeasy/gen.lock" , outDir ))
729+ func commitCustomCodeRegistration (outDir string ) error {
730+ // Add gen.lock and patch file
731+ genLockPath := fmt .Sprintf ("%v/.speakeasy/gen.lock" , outDir )
732+ patchPath := getPatchFilePath (outDir )
733+
734+ cmd := exec .Command ("git" , "add" , genLockPath , patchPath )
740735 if err := cmd .Run (); err != nil {
741- return fmt .Errorf ("failed to add gen.lock: %w" , err )
736+ return fmt .Errorf ("failed to add gen.lock and patch file : %w" , err )
742737 }
743738
744739 // Commit with a descriptive message
745740 commitMsg := "Register custom code changes"
746741 cmd = exec .Command ("git" , "commit" , "-m" , commitMsg )
747742 if output , err := cmd .CombinedOutput (); err != nil {
748- return fmt .Errorf ("failed to commit gen.lock : %w\n Output: %s" , err , string (output ))
743+ return fmt .Errorf ("failed to commit custom code registration : %w\n Output: %s" , err , string (output ))
749744 }
750745
751746 return nil
752747}
753748
754749func ApplyCustomCodePatch (ctx context.Context , target workflow.Target ) error {
755750 outDir := getTargetOutput (target )
756- // Load the current configuration and lock file
757- cfg , err := config .Load (outDir )
751+
752+ // Check if patch file exists
753+ if ! patchFileExists (outDir ) {
754+ return nil // No patch to apply
755+ }
756+
757+ // Read patch content to verify it's not empty
758+ patchContent , err := readPatchFile (outDir )
758759 if err != nil {
759- return fmt .Errorf ("failed to load config: %w" , err )
760+ return fmt .Errorf ("failed to read patch file: %w" , err )
761+ }
762+ if patchContent == "" {
763+ return nil // Empty patch, nothing to apply
760764 }
761765
762- // Check if there's a custom code patch in the management section
763- if customCodePatch , exists := cfg .LockFile .Management .AdditionalProperties ["customCodePatch" ]; exists {
764- if patchStr , ok := customCodePatch .(string ); ok && patchStr != "" {
765- // Create a temporary patch file
766- patchFile := filepath .Join (outDir , ".speakeasy" , "temp_patch.patch" )
767- if err := os .WriteFile (patchFile , []byte (patchStr ), 0644 ); err != nil {
768- return fmt .Errorf ("failed to write patch file: %w" , err )
769- }
770- // defer os.Remove(patchFile)
771-
772- // Apply the patch with 3-way merge
773- args := []string {"apply" , "--3way" , "--index" }
774- args = append (args , patchFile )
775- cmd := exec .Command ("git" , args ... )
776- if output , err := cmd .CombinedOutput (); err != nil {
777- return fmt .Errorf ("failed to apply patch: %w\n Output: %s" , err , string (output ))
778- }
779- }
766+ // Apply the patch directly from file with 3-way merge
767+ patchFile := getPatchFilePath (outDir )
768+ args := []string {"apply" , "--3way" , "--index" , patchFile }
769+ cmd := exec .Command ("git" , args ... )
770+ if output , err := cmd .CombinedOutput (); err != nil {
771+ return fmt .Errorf ("failed to apply patch: %w\n Output: %s" , err , string (output ))
780772 }
781773
782774 return nil
@@ -788,7 +780,7 @@ func applyNewPatch(customCodeDiff string) error {
788780 }
789781
790782 // Create a temporary patch file
791- patchFile := ".speakeasy/temp_new_patch.patch "
783+ patchFile := ".speakeasy/temp_new_patch.diff "
792784 if err := os .WriteFile (patchFile , []byte (customCodeDiff ), 0644 ); err != nil {
793785 return fmt .Errorf ("failed to write new patch file: %w" , err )
794786 }
@@ -803,7 +795,69 @@ func applyNewPatch(customCodeDiff string) error {
803795 return nil
804796}
805797
806- func updateGenLockWithPatch (outDir , patchset , commitHash string ) error {
798+ // Patch file helper functions
799+
800+ // getPatchFilePath returns the standardized path for the custom code patch file
801+ func getPatchFilePath (outDir string ) string {
802+ return filepath .Join (outDir , ".speakeasy" , "patches" , "custom-code.diff" )
803+ }
804+
805+ // ensurePatchesDirectoryExists creates the patches directory if it doesn't exist
806+ func ensurePatchesDirectoryExists (outDir string ) error {
807+ patchesDir := filepath .Join (outDir , ".speakeasy" , "patches" )
808+ if err := os .MkdirAll (patchesDir , 0755 ); err != nil {
809+ return fmt .Errorf ("failed to create patches directory: %w" , err )
810+ }
811+ return nil
812+ }
813+
814+ // writePatchFile writes the patch content to the custom code patch file
815+ func writePatchFile (outDir , patchContent string ) error {
816+ if err := ensurePatchesDirectoryExists (outDir ); err != nil {
817+ return err
818+ }
819+
820+ patchPath := getPatchFilePath (outDir )
821+ if err := os .WriteFile (patchPath , []byte (patchContent ), 0644 ); err != nil {
822+ return fmt .Errorf ("failed to write patch file: %w" , err )
823+ }
824+
825+ return nil
826+ }
827+
828+ // readPatchFile reads the patch content from the custom code patch file
829+ // Returns empty string if file doesn't exist (not an error)
830+ func readPatchFile (outDir string ) (string , error ) {
831+ patchPath := getPatchFilePath (outDir )
832+
833+ content , err := os .ReadFile (patchPath )
834+ if err != nil {
835+ if os .IsNotExist (err ) {
836+ return "" , nil // No patch found
837+ }
838+ return "" , fmt .Errorf ("failed to read patch file: %w" , err )
839+ }
840+
841+ return string (content ), nil
842+ }
843+
844+ // deletePatchFile deletes the custom code patch file
845+ func deletePatchFile (outDir string ) error {
846+ patchPath := getPatchFilePath (outDir )
847+ if err := os .Remove (patchPath ); err != nil && ! os .IsNotExist (err ) {
848+ return fmt .Errorf ("failed to delete patch file: %w" , err )
849+ }
850+ return nil
851+ }
852+
853+ // patchFileExists checks if the custom code patch file exists
854+ func patchFileExists (outDir string ) bool {
855+ patchPath := getPatchFilePath (outDir )
856+ _ , err := os .Stat (patchPath )
857+ return err == nil
858+ }
859+
860+ func saveCustomCodePatch (outDir , patchset , commitHash string ) error {
807861 // Load the current configuration and lock file
808862 cfg , err := config .Load (outDir )
809863 if err != nil {
@@ -815,16 +869,20 @@ func updateGenLockWithPatch(outDir, patchset, commitHash string) error {
815869 cfg .LockFile .Management .AdditionalProperties = make (map [string ]any )
816870 }
817871
818- // Store single patch (replaces any existing patch)
872+ // Write patch to file
819873 if patchset != "" {
820- cfg .LockFile .Management .AdditionalProperties ["customCodePatch" ] = patchset
821- // Store the commit hash that contains the custom code application
874+ if err := writePatchFile (outDir , patchset ); err != nil {
875+ return fmt .Errorf ("failed to write patch file: %w" , err )
876+ }
877+ // Store the commit hash in gen.lock
822878 if commitHash != "" {
823879 cfg .LockFile .Management .AdditionalProperties ["customCodeCommitHash" ] = commitHash
824880 }
825881 } else {
826- // Remove the patch and commit hash if empty
827- delete (cfg .LockFile .Management .AdditionalProperties , "customCodePatch" )
882+ // Remove patch file and commit hash if empty
883+ if err := deletePatchFile (outDir ); err != nil {
884+ return fmt .Errorf ("failed to delete patch file: %w" , err )
885+ }
828886 delete (cfg .LockFile .Management .AdditionalProperties , "customCodeCommitHash" )
829887 }
830888
0 commit comments