@@ -161,134 +161,77 @@ func (a *addedModule) ToModule(
161161 }
162162 return moduleData .V1Beta1OrV1BufLockObjectData ()
163163 }
164- // Imagine the following scenario:
164+ // getDepModuleKeysB5 gets the dependencies for the specific Module.
165165 //
166- // module-a (local)
167- // README.md
168- // a.proto
169- // b.proto
170- // module-b:c1
171- // README.md
172- // c.proto
173- // d.proto
174- // module-b:c2
175- // README.md
176- // c.proto
177- // d.proto
178- // module-c:c1
179- // e.proto
180- // f.proto
181- // module-c:c2
182- // e.proto
183- // f.proto
184- // g.proto
166+ // This is needed to calculate the digest for the Module. A Module constructed from this
167+ // ModuleData as the target will require all Modules referenced by its DepModuleKeys to
168+ // be present in the ModuleSet.
185169 //
186- // Then, you have this dependency graph:
170+ // Modules that depend on this remote Module will include this Module and its data.
171+ // However all the dependencies of the remote Module may not be present in the parents ModuleSet.
172+ // As the target Module will use its direct dependencies to resolve the dependencies required.
173+ // The digest of the remote Module is however, unchanged. It is calculated based on the contents
174+ // and its dependencies, not the dependencies of the parent ModuleSet.
187175 //
188- // module-a -> module-b:c1, module-c:c2
189- // module-b:c1 -> module-c:c1
176+ // In contrast, a local Module dependency can be thought of as a ModuleKey at the latest commit.
177+ // It will always use the bucket and dependencies, which may be resolved recursively for
178+ // dependencies on other local Modules, to calculate its digest.
179+ // This is the difference between the ModuleData digest calculation and the Module
180+ // digest calculation. As remote Modules are required to have all their dependencies as
181+ // ModuleKeys, they can calculate their digest directly from the contents and dependencies,
182+ // without needing to recursively resolve the digest as local Modules do.
190183 //
191- // Note that module-b depends on an earlier commit of module-c than module-a does.
184+ // For example, consider the following modules at commits with their dependencies:
185+ // ```
186+ // X:C1 (X has no dependencies)
187+ // A:C1 -> X:C1 (A depends on X)
188+ // B:C1 -> A:C1 ~> X:C1 (B depends on A, transitive dependency on X)
189+ // A:C2 (A removes the dependency on X)
190+ // C:C1 -> A:C2, B:C1 (C depends on A and B, X is not a dependency)
191+ // ```
192+ // The ModuleSet for C:C1 will include B:C1 and A:C2, but not A:C1 or X:C1.
193+ // This is because for C:C1 it will use the direct dependencies to resolve its dependencies.
194+ // A is required by both B:C1 and C:C1, the latest A:C2 is chosen.
192195 //
193- // If we were to just use the dependencies in the ModuleSet to compute the digest, the following
194- // would happen as a calculation:
196+ // The ModuleSet for B:C1 will include A:C1 and X:C1.
197+ // When calculating the digest for B:C1 in the ModuleSet of C:C1, the ModuleSet
198+ // ModuleDeps cannot be used to resolve the dependencies of B:C1. It must use
199+ // the dependencies of B:C1, which are A:C1 and X:C1, not A:C2.
195200 //
196- // DIGEST(module-a) = digest(
197- // // module-a contents
198- // README.md,
199- // a.proto,
200- // b.proto,
201- // // module-b:c1 digest
202- // DIGEST(
203- // README.md,
204- // c.proto,
205- // d.proto,
206- // // module-c:c2 digest
207- // DIGEST(
208- // README.md,
209- // e.proto,
210- // f.proto,
211- // g.proto,
212- // ),
213- // ),
214- // // module-c:c2 digest
215- // DIGEST(
216- // README.md,
217- // e.proto,
218- // f.proto,
219- // g.proto,
220- // ),
221- // )
222- //
223- // Note that to compute the digest of module-b:c1, we would actually use the digest of
224- // module-c:c2, as opposed to module-c:c1, since within the ModuleSet, we would resolve
225- // to use module-c:c2 instead of module-c:c1.
226- //
227- // We should be using module-c:c1 to compute the digest of module-b:c1:
228- //
229- // DIGEST(module-a) = digest(
230- // // module-a contents
231- // README.md,
232- // a.proto,
233- // b.proto,
234- // // module-b:c1 digest
235- // DIGEST(
236- // README.md,
237- // c.proto,
238- // d.proto,
239- // // module-c:c1 digest
240- // DIGEST(
241- // README.md,
242- // e.proto,
243- // f.proto,
244- // ),
245- // ),
246- // // module-c:c2 digest
247- // DIGEST(
248- // README.md,
249- // e.proto,
250- // f.proto,
251- // g.proto,
252- // ),
253- // )
254- //
255- // To accomplish this, we need to take the dependencies of the declared ModuleKeys (ie what
256- // the Module actually says is in its buf.lock). This function enables us to do that for
257- // digest calculations. Within the Module, we say that if we get a remote Module, use the
258- // declared ModuleKeys instead of whatever Module we have resolved to for a given FullName.
259- getDeclaredDepModuleKeysB5 := func () ([]ModuleKey , error ) {
201+ // This is used for digest calculations. It is not used otherwise.
202+ getDepModuleKeysB5 := func () ([]ModuleKey , error ) {
260203 moduleData , err := getModuleData ()
261204 if err != nil {
262205 return nil , err
263206 }
264- declaredDepModuleKeys , err := moduleData .DeclaredDepModuleKeys ()
207+ depModuleKeys , err := moduleData .DepModuleKeys ()
265208 if err != nil {
266209 return nil , err
267210 }
268- if len (declaredDepModuleKeys ) == 0 {
211+ if len (depModuleKeys ) == 0 {
269212 return nil , nil
270213 }
271214 var digestType DigestType
272- for i , moduleKey := range declaredDepModuleKeys {
215+ for i , moduleKey := range depModuleKeys {
273216 digest , err := moduleKey .Digest ()
274217 if err != nil {
275218 return nil , err
276219 }
277220 if i == 0 {
278221 digestType = digest .Type ()
279222 } else if digestType != digest .Type () {
280- return nil , syserror .Newf ("multiple digest types found in DeclaredDepModuleKeys : %v, %v" , digestType , digest .Type ())
223+ return nil , syserror .Newf ("multiple digest types found in DepModuleKeys : %v, %v" , digestType , digest .Type ())
281224 }
282225 }
283226 switch digestType {
284227 case DigestTypeB4 :
285- // The declared ModuleKey dependencies for a commit may be stored in v1 buf.lock file,
228+ // The ModuleKey dependencies for a commit may be stored in v1 buf.lock file,
286229 // in which case they will use B4 digests. B4 digests aren't allowed to be used as
287230 // input to the B5 digest calculation, so we perform a call to convert all ModuleKeys
288231 // from B4 to B5 by using the commit provider.
289- commitKeysToFetch := make ([]CommitKey , len (declaredDepModuleKeys ))
290- for i , declaredDepModuleKey := range declaredDepModuleKeys {
291- commitKey , err := NewCommitKey (declaredDepModuleKey .FullName ().Registry (), declaredDepModuleKey .CommitID (), DigestTypeB5 )
232+ commitKeysToFetch := make ([]CommitKey , len (depModuleKeys ))
233+ for i , depModuleKey := range depModuleKeys {
234+ commitKey , err := NewCommitKey (depModuleKey .FullName ().Registry (), depModuleKey .CommitID (), DigestTypeB5 )
292235 if err != nil {
293236 return nil , err
294237 }
@@ -305,8 +248,8 @@ func (a *addedModule) ToModule(
305248 return commit .ModuleKey ()
306249 }), nil
307250 case DigestTypeB5 :
308- // No need to fetch b5 digests - we've already got them stored in the module's declared dependencies.
309- return declaredDepModuleKeys , nil
251+ // No need to fetch b5 digests - we've already got them stored in the module's dependencies.
252+ return depModuleKeys , nil
310253 default :
311254 return nil , syserror .Newf ("unsupported digest type: %v" , digestType )
312255 }
@@ -322,7 +265,7 @@ func (a *addedModule) ToModule(
322265 false ,
323266 getV1BufYAMLObjectData ,
324267 getV1BufLockObjectData ,
325- getDeclaredDepModuleKeysB5 ,
268+ getDepModuleKeysB5 ,
326269 a .remoteTargetPaths ,
327270 a .remoteTargetExcludePaths ,
328271 "" ,
0 commit comments