Skip to content

Commit 25f4dd1

Browse files
Ivan GorshkovIvan Gorshkov
authored andcommitted
Saving patches to .diff file instead of gen.lock
1 parent 40895bb commit 25f4dd1

File tree

1 file changed

+118
-60
lines changed

1 file changed

+118
-60
lines changed

internal/registercustomcode/registercustomcode.go

Lines changed: 118 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -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
185185
func 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\nOutput: %s", err, string(output))
743+
return fmt.Errorf("failed to commit custom code registration: %w\nOutput: %s", err, string(output))
749744
}
750745

751746
return nil
752747
}
753748

754749
func 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\nOutput: %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\nOutput: %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

Comments
 (0)