code: func (ix *Index) populateDir(ctx context.Context, fetcher blob.Fetcher, b *schema.Blob, mm *mutationMap) error {
  	blobRef := b.BlobRef()
  	// TODO(bradfitz): move the NewDirReader and FileName method off *schema.Blob and onto
  	// StaticFile/StaticDirectory or something.
  
  	tf := &trackErrorsFetcher{f: fetcher.(*missTrackFetcher)}
  	dr, err := b.NewDirReader(ctx, tf)
  	if err != nil {
  		// TODO(bradfitz): propagate up a transient failure
  		// error type, so we can retry indexing files in the
  		// future if blobs are only temporarily unavailable.
  		log.Printf("index: error indexing directory, creating NewDirReader %s: %v", blobRef, err)
  		return nil
  	}
  	sts, err := dr.StaticSet(ctx)
  	if err != nil {
  		if tf.hasErrNotExist() {
  			return errMissingDep
  		}
  		log.Printf("index: error indexing directory: can't get StaticSet: %v\n", err)
  		return nil
  	}
  
  	mm.Set(keyFileInfo.Key(blobRef), keyFileInfo.Val(len(sts), b.FileName(), "", blob.Ref{}))
  	for _, br := range sts {
  		mm.Set(keyStaticDirChild.Key(blobRef, br.String()), "1")
  	}
  	return nil
  }
docs: // b: the parsed file schema blob
  // mm: keys to populate