Fold internalbridge into the root package · Entire

Fold internalbridge into the root package

a0136e7·

Soph·2w ago·8 files·+427 added/-616 removed

internal/internalbridge was a pure pass-through layer: it mirrored the public request types field-for-field, wrapped syncer.Config in an opaque struct, and forwarded Probe/Run calls verbatim. The root client had to convert every request through bridge mirror types, and unstable/client.go round-tripped through them just to build a syncer.Endpoint literal.

Define the public result types (RefResult, Stats, ProbeResult, SyncResult, ...) directly in the root package instead of aliasing internal types -- this also makes their godoc visible on pkg.go.dev and exports SideBytes, which was previously reachable through Stats.Sides but not nameable by callers. Build syncer.Config directly in the client, matching what unstable/client.go already does. Field sets and JSON tags are unchanged, so the published API surface is identical.

Co-Authored-By: Claude Fable 5 noreply@anthropic.com

Sessions

f27edbb5033dView transcript

Changes

8

5 unmodified lines

6  
7  
8  
9  
9  
10  
11  
12  
23 unmodified lines

36  
37  
38  
39  
39  
40  
41  
42  
43  
43  
44  
45  
46  
1 unmodified line

48  
49  
50  
51  
51  
52  
53  
54  
55  
55  
56  
57  
58  
59  
59  
60  
61  
62  
1 unmodified line

64  
65  
66  
67  
67  
68  
69  
70  
71  
71  
72  
73  
74  
75  
75  
76  
77  
78  
2 unmodified lines

81  
82  
83  
84  
84  
85  
86  
87  
87  
88  
89  
90  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
92  
99  
100  
94  
101  
102  
96  
97  
103  
104  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
105  
106  
107  
113  
114  
108  
109  
110  
116  
111  
112  
118  
113  
114  
120  
115  
116  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
52 unmodified lines

191  
192  
193  
191  
192  
194  
195  
196  
197  
198  
199  
200  
201  
202  
203  
204  
198  
199  
200  
201  
202  
203  
205  
206  
207  
208  
209  
210  
211  
207  
208  
209  
210  
211  
212  
213  
212  
213  
214  
215  
215  
216  
217  
218  
219  
220  
221  
222  
223  
224  
225  
226  
227  
228  
229  
230  
231  
232  
216  
217  
218  
219  
5 unmodified lines

225  
226  
227  
244  
245  
246  
247  
228  
229  
230

5 unmodified lines

"fmt"  
    "net/http"

"entire.io/entire/git-sync/internal/internalbridge"  
    "entire.io/entire/git-sync/internal/syncer"  
    "entire.io/entire/git-sync/internal/validation"  
}

if err != nil {
    return ProbeResult{}, err
}
result, err := internalbridge.Probe(ctx, cfg)
result, err := syncer.Probe(ctx, cfg)
if err != nil {
    return ProbeResult{}, fmt.Errorf("probe: %w", err)
}
return internalbridge.FromProbeResult(result), nil
return fromProbeResult(result), nil
}

// Plan computes ref actions without pushing.
1 unmodified line

if err := req.Validate(); err != nil {
    return PlanResult{}, err
}
cfg, err := c.buildSyncConfig(ctx, req.Source, req.Target, req.Scope, req.Policy, req.CollectStats, true)
cfg, err := c.buildSyncConfig(ctx, SyncRequest(req), true)
if err != nil {
    return PlanResult{}, err
}
result, err := internalbridge.Run(ctx, cfg)
result, err := syncer.Run(ctx, cfg)
if err != nil {
    return PlanResult{}, fmt.Errorf("plan: %w", err)
}
return internalbridge.FromSyncResult(result), nil
return fromSyncResult(result), nil
}

// Sync executes a sync between two remotes.
1 unmodified line

if err := req.Validate(); err != nil {
    return SyncResult{}, err
}
cfg, err := c.buildSyncConfig(ctx, req.Source, req.Target, req.Scope, req.Policy, req.CollectStats, false)
cfg, err := c.buildSyncConfig(ctx, req, false)
if err != nil {
    return SyncResult{}, err
}
result, err := internalbridge.Run(ctx, cfg)
result, err := syncer.Run(ctx, cfg)
if err != nil {
    return SyncResult{}, fmt.Errorf("sync: %w", err)
}
return internalbridge.FromSyncResult(result), nil
return fromSyncResult(result), nil
}

// Replicate executes source-authoritative relay-only replication between two remotes.
2 unmodified lines

return c.Sync(ctx, req)
}

func (c *Client) buildProbeConfig(ctx context.Context, req ProbeRequest) (internalbridge.Config, error) {
func (c *Client) buildProbeConfig(ctx context.Context, req ProbeRequest) (syncer.Config, error) {
sourceAuth, err := c.authFor(ctx, req.Source, SourceRole)
if err != nil {
    return internalbridge.Config{}, err
    return syncer.Config{}, err
}
var target *internalbridge.Endpoint
targetAuth := internalbridge.EndpointAuth{}
cfg := syncer.Config{
    Source:             syncerEndpoint(req.Source, sourceAuth),
    HTTPClient:         c.httpClient,
    IncludeTags:        req.IncludeTags,
    AllRefs:            req.AllRefs,
    ExcludeRefPrefixes: append([]string(nil), req.ExcludeRefPrefixes...),
    ShowStats:          req.CollectStats,
    ProtocolMode:       protocolString(req.Protocol),
}
if req.Target != nil {
    resolvedTargetAuth, err := c.authFor(ctx, *req.Target, TargetRole)
targetAuth, err := c.authFor(ctx, *req.Target, TargetRole)
if err != nil {
    return internalbridge.Config{}, err
    return syncer.Config{}, err
}
target = ptr(bridgeEndpoint(*req.Target))
targetAuth = bridgeEndpointAuth(resolvedTargetAuth)
cfg.Target = syncerEndpoint(*req.Target, targetAuth)
}
return internalbridge.ProbeConfig(
    bridgeEndpoint(req.Source),
    bridgeEndpointAuth(sourceAuth),
    target,
    targetAuth,
    internalbridge.ProtocolMode(req.Protocol),
    req.IncludeTags,
    req.AllRefs,
    req.CollectStats,
    req.ExcludeRefPrefixes,
    c.httpClient,
), nil
return cfg, nil
}

func (c *Client) buildSyncConfig(ctx context.Context, source Endpoint, target Endpoint, scope RefScope, policy SyncPolicy, collectStats, dryRun bool) (internalbridge.Config, error) {
sourceAuth, err := c.authFor(ctx, source, SourceRole)
func (c *Client) buildSyncConfig(ctx context.Context, req SyncRequest, dryRun bool) (syncer.Config, error) {
sourceAuth, err := c.authFor(ctx, req.Source, SourceRole)
if err != nil {
    return internalbridge.Config{}, err
    return syncer.Config{}, err
}
targetAuth, err := c.authFor(ctx, target, TargetRole)
targetAuth, err := c.authFor(ctx, req.Target, TargetRole)
if err != nil {
    return internalbridge.Config{}, err
    return syncer.Config{}, err
}
return internalbridge.SyncConfig(
    bridgeEndpoint(source),
    bridgeEndpointAuth(sourceAuth),
    bridgeEndpoint(target),
    bridgeEndpointAuth(targetAuth),
    bridgeScope(scope),
    bridgePolicy(policy),
    collectStats,
    dryRun,
    c.httpClient,
), nil
return syncer.Config{
    Source:                 syncerEndpoint(req.Source, sourceAuth),
    Target:                 syncerEndpoint(req.Target, targetAuth),
    HTTPClient:             c.httpClient,
    Branches:               append([]string(nil), req.Scope.Branches...),
    Mappings:               validationMappings(req.Scope.Mappings),
    AllRefs:                req.Scope.AllRefs,
    ExcludeRefPrefixes:     append([]string(nil), req.Scope.ExcludeRefPrefixes...),
    IncludeTags:            req.Policy.IncludeTags,
    DryRun:                 dryRun,
    ShowStats:              req.CollectStats,
    Mode:                   operationModeString(req.Policy.Mode),
    ForceWithLease:         req.Policy.ForceWithLease,
    ForceBlind:             req.Policy.ForceBlind,
    Prune:                  req.Policy.Prune,
    BestEffort:             req.Policy.BestEffort,
    ProtocolMode:           protocolString(req.Policy.Protocol),
    MaterializedMaxObjects: syncer.DefaultMaterializedMaxObjects,
}, nil
}

func (c *Client) authFor(ctx context.Context, endpoint Endpoint, role EndpointRole) (EndpointAuth, error) {
52 unmodified lines

return nil
}

func bridgeEndpoint(ep Endpoint) internalbridge.Endpoint {
return internalbridge.Endpoint{
func syncerEndpoint(ep Endpoint, auth EndpointAuth) syncer.Endpoint {
return syncer.Endpoint{
    URL:                    ep.URL,
    Username:               auth.Username,
    Token:                  auth.Token,
    BearerToken:            auth.BearerToken,
    SkipTLSVerify:          auth.SkipTLSVerify,
    FollowInfoRefsRedirect: ep.FollowInfoRefsRedirect,
}
}

func bridgeEndpointAuth(auth EndpointAuth) internalbridge.EndpointAuth {
return internalbridge.EndpointAuth{
    Username:      auth.Username,
    Token:         auth.Token,
    BearerToken:   auth.BearerToken,
    SkipTLSVerify: auth.SkipTLSVerify,
func protocolString(mode ProtocolMode) string {
if mode == "" {
    return string(ProtocolAuto)
}
return string(mode)
}

func bridgeScope(scope RefScope) internalbridge.RefScope {
mappings := make([]internalbridge.RefMapping, 0, len(scope.Mappings))
for _, mapping := range scope.Mappings {
mappings = append(mappings, internalbridge.RefMapping{
    Source: mapping.Source,
    Target: mapping.Target,
})
}
return internalbridge.RefScope{
    Branches:           append([]string(nil), scope.Branches...),
    Mappings:           mappings,
    AllRefs:            scope.AllRefs,
    ExcludeRefPrefixes: append([]string(nil), scope.ExcludeRefPrefixes...),
}
}

func bridgePolicy(policy SyncPolicy) internalbridge.SyncPolicy {
return internalbridge.SyncPolicy{
    Mode:           internalbridge.OperationMode(policy.Mode),
    IncludeTags:    policy.IncludeTags,
    ForceWithLease: policy.ForceWithLease,
    ForceBlind:     policy.ForceBlind,
    Prune:          policy.Prune,
    BestEffort:     policy.BestEffort,
    Protocol:       internalbridge.ProtocolMode(policy.Protocol),
}
}

func validateOperationMode(mode OperationMode) error {
5 unmodified lines

}

func ptr[T any](v T) *T {
return &v
}

func validationMappings(mappings []RefMapping) []validation.RefMapping {
out := make([]validation.RefMapping, 0, len(mappings))
for _, mapping := range mappings {

}