Lock clone preference updates · Entire

Lock clone preference updates

6c8f798→main·

dipree·3w ago·4 files·+88 added/-80 removed

Sessions

f47b5f818fbeView transcript

Changes

4

return fmt.Errorf("review settings migration prompt: %w", err)
}
if !migrate {
    if prefs == nil {
        prefs = &settings.ClonePreferences{}
    }
    prefs.ReviewMigrationDismissed = true
    if err := settings.SaveClonePreferences(ctx, prefs); err != nil {
        if err := settings.ModifyClonePreferences(ctx, func(prefs *settings.ClonePreferences) error {
            prefs.ReviewMigrationDismissed = true
            return nil
        }); err != nil {
            return fmt.Errorf("save migration dismissal: %w", err)
        }
    }
    return nil
}

prefs, err := settings.LoadClonePreferences(ctx)
if err != nil {
    return false, fmt.Errorf("load review preferences for migration: %w", err)
}
if prefs == nil {
    prefs = &settings.ClonePreferences{}
}

preferencesChanged := false
if project.hasReview && !isJSONNull(project.review) {
    var projectReview map[string]settings.ReviewConfig
    if err := json.Unmarshal(project.review, &projectReview); err != nil {
        return false, fmt.Errorf("parsing project review settings: %w", err)
    }
    if len(projectReview) > 0 {
        merged, mergedOK, conflicts := mergeProjectReviewIntoPrefs(prefs.Review, projectReview)
        if len(conflicts) > 0 {
            return false, fmt.Errorf(
                "review settings exist in both %s and clone-local preferences for agent(s) %v; "+
                "reconcile manually by removing the redundant keys from %s, then re-run `entire review`",
                project.path, conflicts, project.path,
            )
        }
        if mergedOK {
            prefs.Review = merged
            preferencesChanged = true
        }
    }
}
if project.hasFixAgent && !isJSONNull(project.fixAgent) {
    var fixAgent string
    if err := json.Unmarshal(project.fixAgent, &fixAgent); err != nil {
        return false, fmt.Errorf("parsing project review_fix_agent: %w", err)
    }
    if fixAgent != "" {
        if prefs.ReviewFixAgent != "" && prefs.ReviewFixAgent != fixAgent {
            return false, fmt.Errorf(
                "review_fix_agent differs between %s (%q) and clone-local preferences (%q); "+
                "reconcile manually by removing review_fix_agent from %s, then re-run `entire review`",
                project.path, fixAgent, prefs.ReviewFixAgent, project.path,
            )
        }
        if prefs.ReviewFixAgent == "" {
            prefs.ReviewFixAgent = fixAgent
            preferencesChanged = true
        }
    }
}
return nil
}); err != nil {
    return false, fmt.Errorf("save review preferences for migration: %w", err)
}

if preferencesChanged {
    if err := settings.SaveClonePreferences(ctx, prefs); err != nil {
        return false, fmt.Errorf("save review preferences for migration: %w", err)
    }
}

delete(project.raw, "review")
delete(project.raw, "review_fix_agent")
if err := settings.SaveProjectRaw(project.path, project.raw); err != nil {
return fmt.Errorf("load review preferences before save: %w", err)
if prefs == nil {
    prefs = &settings.ClonePreferences{}
}
prefs.ReviewFixAgent = agentName
if err := settings.SaveClonePreferences(ctx, prefs); err != nil {
    if err := settings.ModifyClonePreferences(ctx, func(prefs *settings.ClonePreferences) error {
        prefs.ReviewFixAgent = agentName
        return nil
    }); err != nil {
        return fmt.Errorf("save review preferences: %w", err)
    }
}
return nil
}

func saveReviewConfigAndFixAgent(ctx context.Context, review map[string]settings.ReviewConfig, fixAgent string) error {
prefs, err := settings.LoadClonePreferences(ctx)
if err != nil {
    return fmt.Errorf("load review preferences before save: %w", err)
}
if prefs == nil {
    prefs = &settings.ClonePreferences{}
}
prefs.Review = review
prefs.ReviewFixAgent = fixAgent
if err := settings.SaveClonePreferences(ctx, prefs); err != nil {
    if err := settings.ModifyClonePreferences(ctx, func(prefs *settings.ClonePreferences) error {
        prefs.Review = review
        prefs.ReviewFixAgent = fixAgent
        return nil
    }); err != nil {
        return fmt.Errorf("save review preferences: %w", err)
    }
}
return saveClonePreferencesToFile(prefs, path)
}

func ModifyClonePreferences(ctx context.Context, fn func(*ClonePreferences) error) error {
    path, err := ClonePreferencesPath(ctx)
    if err != nil {
        return err
    }
    return modifyClonePreferencesFile(path, fn)
}

func LoadFromBytes(data []byte) (*EntireSettings, error) {
return nil
}

func modifyClonePreferencesFile(filePath string, fn func(*ClonePreferences) error) error {
    if err := os.MkdirAll(filepath.Dir(filePath), 0o750); err != nil {
        return fmt.Errorf("creating preferences directory: %w", err)
    }
    release, err := flock.Acquire(filePath + ".lock")
    if err != nil {
        return fmt.Errorf("lock preferences file: %w", err)
    }
    defer release()

prefs, err := loadClonePreferencesFromFile(filePath)
    if err != nil {
        return err
    }
    if err := fn(prefs); err != nil {
        return err
    }
    return saveClonePreferencesToFile(prefs, filePath)
}

func applyClonePreferences(settings *EntireSettings, prefs *ClonePreferences) {
    if prefs == nil {
        return
    }
prefs.TrailsEnabled = &enabledCopy
prefs.TrailsEnabledCheckedAt = &checkedAtUTC
prefs.TrailsEnabledRepoKey = scope.RepoKey
prefs.TrailsEnabledAPIBase = scope.APIBase
prefs.TrailsEnabledAuthKey = scope.AuthKey
if err := settings.SaveClonePreferences(ctx, prefs); err != nil {
    if err := settings.ModifyClonePreferences(ctx, func(prefs *settings.ClonePreferences) error {
        prefs.TrailsEnabled = &enabledCopy
        prefs.TrailsEnabledCheckedAt = &checkedAtUTC
        prefs.TrailsEnabledRepoKey = scope.RepoKey
        prefs.TrailsEnabledAPIBase = scope.APIBase
        prefs.TrailsEnabledAuthKey = scope.AuthKey
        return nil
    }); err != nil {
        return fmt.Errorf("save clone preferences: %w", err)
    }
}
return nil