@@ -13,17 +13,14 @@ import (
1313 "github.com/microsoft/azure-linux-dev-tools/internal/app/azldev/core/sources"
1414 "github.com/microsoft/azure-linux-dev-tools/internal/fingerprint"
1515 "github.com/microsoft/azure-linux-dev-tools/internal/projectconfig"
16- "github.com/microsoft/azure-linux-dev-tools/internal/utils/git"
17- "github.com/microsoft/azure-linux-dev-tools/internal/utils/retry"
16+ "github.com/microsoft/azure-linux-dev-tools/internal/providers/sourceproviders"
1817 "github.com/spf13/cobra"
1918)
2019
2120// Options for computing component identity fingerprints.
2221type IdentityComponentOptions struct {
2322 // Standard filter for selecting components.
2423 ComponentFilter components.ComponentFilter
25- // Strict causes the command to fail if any upstream commit cannot be resolved.
26- Strict bool
2724}
2825
2926func identityOnAppInit (_ * azldev.App , parentCmd * cobra.Command ) {
@@ -66,9 +63,6 @@ rebuilding between two commits.`,
6663 azldev .ExportAsMCPTool (cmd )
6764 components .AddComponentFilterOptionsToCommand (cmd , & options .ComponentFilter )
6865
69- cmd .Flags ().BoolVar (& options .Strict , "strict" , false ,
70- "fail if any upstream commit cannot be resolved (recommended for CI)" )
71-
7266 return cmd
7367}
7468
@@ -95,23 +89,20 @@ func ComputeComponentIdentities(
9589
9690 distroRef := env .Config ().Project .DefaultDistro
9791
98- // Set up upstream resolver for floating upstream specs .
99- gitProvider , err := git . NewGitProviderImpl (env , env )
92+ // Resolve the distro definition (fills in default version) .
93+ distroRef , distro , err := resolveDistroForIdentity (env , distroRef )
10094 if err != nil {
101- return nil , fmt . Errorf ( "creating git provider: \n %w " , err )
95+ slog . Debug ( "Could not resolve distro" , "error " , err )
10296 }
10397
104- upstreamResolver := fingerprint .NewUpstreamResolver (gitProvider )
105-
106- // Resolve the upstream distro definition for upstream commit resolution.
107- distroRef , distroDef , distroVersionDef , err := resolveDistroForIdentity (env , distroRef )
98+ // Create a source manager — it handles provider construction and dispatch.
99+ srcManager , err := sourceproviders .NewSourceManager (env , distro )
108100 if err != nil {
109- slog .Debug ("Could not resolve distro for upstream commit resolution" ,
110- "error" , err )
101+ return nil , fmt .Errorf ("creating source manager:\n %w" , err )
111102 }
112103
113104 return computeIdentitiesParallel (
114- env , comps .Components (), distroRef , distroDef , distroVersionDef , upstreamResolver , options . Strict ,
105+ env , comps .Components (), distroRef , srcManager ,
115106 )
116107}
117108
@@ -120,15 +111,12 @@ func ComputeComponentIdentities(
120111const maxConcurrentIdentity = 32
121112
122113// computeIdentitiesParallel computes fingerprints for all components concurrently,
123- // including upstream commit resolution, affects count, and file hashing.
114+ // including source identity resolution, affects count, and overlay file hashing.
124115func computeIdentitiesParallel (
125116 env * azldev.Env ,
126117 comps []components.Component ,
127118 distroRef projectconfig.DistroReference ,
128- distroDef projectconfig.DistroDefinition ,
129- distroVersionDef projectconfig.DistroVersionDefinition ,
130- upstreamResolver * fingerprint.UpstreamResolver ,
131- strict bool ,
119+ srcManager sourceproviders.SourceManager ,
132120) ([]ComponentIdentityResult , error ) {
133121 progressEvent := env .StartEvent ("Computing component identities" ,
134122 "count" , len (comps ))
@@ -142,7 +130,6 @@ func computeIdentitiesParallel(
142130
143131 resultsChan := make (chan indexedResult , len (comps ))
144132 semaphore := make (chan struct {}, maxConcurrentIdentity )
145- retryCfg := retry .DefaultConfig ()
146133
147134 var waitGroup sync.WaitGroup
148135
@@ -163,7 +150,7 @@ func computeIdentitiesParallel(
163150 }
164151
165152 result , computeErr := computeSingleIdentity (
166- env , comp , distroRef , distroDef , distroVersionDef , upstreamResolver , retryCfg , strict ,
153+ env , comp , distroRef , srcManager ,
167154 )
168155
169156 resultsChan <- indexedResult {index : compIdx , result : result , err : computeErr }
@@ -197,16 +184,12 @@ func computeIdentitiesParallel(
197184}
198185
199186// computeSingleIdentity computes the identity for a single component, including
200- // upstream commit resolution (with retry) and affects commit counting .
187+ // source identity resolution, affects commit counting, and overlay file hashing .
201188func computeSingleIdentity (
202189 env * azldev.Env ,
203190 comp components.Component ,
204191 distroRef projectconfig.DistroReference ,
205- distroDef projectconfig.DistroDefinition ,
206- distroVersionDef projectconfig.DistroVersionDefinition ,
207- upstreamResolver * fingerprint.UpstreamResolver ,
208- retryCfg retry.Config ,
209- strict bool ,
192+ srcManager sourceproviders.SourceManager ,
210193) (ComponentIdentityResult , error ) {
211194 config := comp .GetConfig ()
212195 componentName := comp .GetName ()
@@ -215,20 +198,16 @@ func computeSingleIdentity(
215198 AffectsCommitCount : countAffectsCommits (config , componentName ),
216199 }
217200
218- // Resolve upstream commit for upstream specs (with retry for transient failures).
219- if config .Spec .SourceType == projectconfig .SpecSourceTypeUpstream {
220- resolvedCommit , resolveErr := resolveUpstreamWithRetry (
221- env , upstreamResolver , componentName , config , distroDef , distroVersionDef , retryCfg ,
222- )
223- if resolveErr != nil && strict {
224- return ComponentIdentityResult {}, fmt .Errorf (
225- "upstream commit resolution failed for %#q (--strict mode):\n %w" ,
226- componentName , resolveErr )
227- }
228-
229- identityOpts .ResolvedUpstreamCommit = resolvedCommit
201+ // Resolve source identity via the source manager (handles local/upstream dispatch + retry).
202+ sourceIdentity , resolveErr := srcManager .ResolveSourceIdentity (env , comp )
203+ if resolveErr != nil {
204+ return ComponentIdentityResult {}, fmt .Errorf (
205+ "source identity resolution failed for %#q:\n %w" ,
206+ componentName , resolveErr )
230207 }
231208
209+ identityOpts .SourceIdentity = sourceIdentity
210+
232211 identity , err := fingerprint .ComputeIdentity (env .FS (), * config , distroRef , identityOpts )
233212 if err != nil {
234213 return ComponentIdentityResult {}, fmt .Errorf ("computing identity for component %#q:\n %w" ,
@@ -242,53 +221,14 @@ func computeSingleIdentity(
242221 }, nil
243222}
244223
245- // resolveUpstreamWithRetry resolves an upstream commit with retry logic, returning
246- // the resolved commit or empty string and an error on failure.
247- func resolveUpstreamWithRetry (
248- env * azldev.Env ,
249- resolver * fingerprint.UpstreamResolver ,
250- componentName string ,
251- config * projectconfig.ComponentConfig ,
252- distroDef projectconfig.DistroDefinition ,
253- distroVersionDef projectconfig.DistroVersionDefinition ,
254- retryCfg retry.Config ,
255- ) (string , error ) {
256- var resolvedCommit string
257-
258- retryErr := retry .Do (env , retryCfg , func () error {
259- var resolveErr error
260-
261- resolvedCommit , resolveErr = resolver .ResolveCommit (
262- env ,
263- componentName ,
264- config .Spec ,
265- resolveUpstreamDistro (config .Spec , env .Config (), distroDef ),
266- resolveUpstreamDistroVersion (config .Spec , env .Config (), distroVersionDef ),
267- )
268- if resolveErr != nil {
269- return fmt .Errorf ("resolving commit:\n %w" , resolveErr )
270- }
271-
272- return nil
273- })
274- if retryErr != nil {
275- slog .Warn ("Could not resolve upstream commit; fingerprint may be incomplete" ,
276- "component" , componentName , "error" , retryErr )
277-
278- return "" , fmt .Errorf ("resolving upstream commit for %#q:\n %w" , componentName , retryErr )
279- }
280-
281- return resolvedCommit , nil
282- }
283-
284- // resolveDistroForIdentity resolves the default distro reference for upstream commit resolution.
285- // Returns the distro ref with version populated if it was initially empty.
224+ // resolveDistroForIdentity resolves the default distro reference and returns a
225+ // [sourceproviders.ResolvedDistro] for constructing a source manager.
286226func resolveDistroForIdentity (
287227 env * azldev.Env , distroRef projectconfig.DistroReference ,
288- ) (projectconfig.DistroReference , projectconfig. DistroDefinition , projectconfig. DistroVersionDefinition , error ) {
228+ ) (projectconfig.DistroReference , sourceproviders. ResolvedDistro , error ) {
289229 distroDef , distroVersionDef , err := env .ResolveDistroRef (distroRef )
290230 if err != nil {
291- return distroRef , distroDef , distroVersionDef ,
231+ return distroRef , sourceproviders. ResolvedDistro {} ,
292232 fmt .Errorf ("resolving distro %#q:\n %w" , distroRef .Name , err )
293233 }
294234
@@ -297,53 +237,11 @@ func resolveDistroForIdentity(
297237 distroRef .Version = distroDef .DefaultVersion
298238 }
299239
300- return distroRef , distroDef , distroVersionDef , nil
301- }
302-
303- // resolveUpstreamDistro returns the distro definition for the component's upstream distro,
304- // falling back to the default project distro if the component doesn't specify one.
305- func resolveUpstreamDistro (
306- spec projectconfig.SpecSource ,
307- config * projectconfig.ProjectConfig ,
308- defaultDef projectconfig.DistroDefinition ,
309- ) projectconfig.DistroDefinition {
310- if spec .UpstreamDistro .Name == "" {
311- return defaultDef
312- }
313-
314- if upstreamDef , found := config .Distros [spec .UpstreamDistro .Name ]; found {
315- return upstreamDef
316- }
317-
318- return defaultDef
319- }
320-
321- // resolveUpstreamDistroVersion returns the distro version definition for the upstream distro,
322- // falling back to the default if not found.
323- func resolveUpstreamDistroVersion (
324- spec projectconfig.SpecSource ,
325- config * projectconfig.ProjectConfig ,
326- defaultVersionDef projectconfig.DistroVersionDefinition ,
327- ) projectconfig.DistroVersionDefinition {
328- if spec .UpstreamDistro .Name == "" {
329- return defaultVersionDef
330- }
331-
332- upstreamDef , found := config .Distros [spec .UpstreamDistro .Name ]
333- if ! found {
334- return defaultVersionDef
335- }
336-
337- version := spec .UpstreamDistro .Version
338- if version == "" {
339- version = upstreamDef .DefaultVersion
340- }
341-
342- if versionDef , vFound := upstreamDef .Versions [version ]; vFound {
343- return versionDef
344- }
345-
346- return defaultVersionDef
240+ return distroRef , sourceproviders.ResolvedDistro {
241+ Ref : distroRef ,
242+ Definition : distroDef ,
243+ Version : distroVersionDef ,
244+ }, nil
347245}
348246
349247// countAffectsCommits counts the number of "Affects: <componentName>" commits in the
0 commit comments