https://github.com/conan-io/conan/blob/1.59.0/conans/client/cmd/export.py#L169-L176

    # Compute the revision for the recipe
revision = _update_revision_in_metadata(package_layout=package_layout,
revisions_enabled=revisions_enabled,
output=output,
path=os.path.dirname(conanfile_path),
manifest=manifest,
revision_mode=conanfile.revision_mode)

https://github.com/conan-io/conan/blob/1.59.0/conans/client/cmd/export.py#L402-L431

def _update_revision_in_metadata(package_layout, revisions_enabled, output, path, manifest,
revision_mode):
if revision_mode not in ["scm", "hash"]:
raise ConanException("Revision mode should be one of 'hash' (default) or 'scm'")
# Use the proper approach depending on 'revision_mode'
if revision_mode == "hash":
revision = manifest.summary_hash
if revisions_enabled:
output.info("Using the exported files summary hash as the recipe"
" revision: {} ".format(revision))
else:
try:
rev_detected, repo_type, is_pristine = _detect_scm_revision(path)
except Exception as exc:
error_msg = "Cannot detect revision using '{}' mode from repository at " \
"'{}'".format(revision_mode, path)
raise ConanException("{}: {}".format(error_msg, exc))
revision = rev_detected
if revisions_enabled:
output.info("Using %s commit as the recipe revision: %s" % (repo_type, revision))
if not is_pristine:
output.warn("Repo status is not pristine: there might be modified files")
with package_layout.update_metadata() as metadata:
metadata.recipe.revision = revision
return revision

https://github.com/conan-io/conan/blob/1.59.0/conans/model/manifest.py#L63-L67

    @property
def summary_hash(self):
s = ["%s: %s" % (f, fmd5) for f, fmd5 in sorted(self.file_sums.items())]
s.append("")
return md5("\n".join(s))

https://github.com/conan-io/conan/blob/1.59.0/conans/model/manifest.py#L55-L58

    def __init__(self, the_time, file_sums):
"""file_sums is a dict with filepaths and md5's: {filepath/to/file.txt: md5}"""
self.time = the_time
self.file_sums = file_sums

https://github.com/conan-io/conan/blob/1.59.0/conans/model/manifest.py#L119-L138

    def create(cls, folder, exports_sources_folder=None):
""" Walks a folder and create a FileTreeManifest for it, reading file contents
from disk, and capturing current time
"""
files, _ = gather_files(folder)
for f in (PACKAGE_TGZ_NAME, EXPORT_TGZ_NAME, CONAN_MANIFEST, EXPORT_SOURCES_TGZ_NAME):
files.pop(f, None)
file_dict = {}
for name, filepath in files.items():
file_dict[name] = md5sum(filepath)
if exports_sources_folder:
export_files, _ = gather_files(exports_sources_folder)
for name, filepath in export_files.items():
file_dict["export_source/%s" % name] = md5sum(filepath)
date = timestamp_now()
return cls(date, file_dict)

https://github.com/conan-io/conan/blob/1.59.0/conans/client/cmd/export.py#L158-L167

        # Compute the new digest
manifest = FileTreeManifest.create(export_folder, export_src_folder)
modified_recipe |= not previous_manifest or previous_manifest != manifest
if modified_recipe:
output.success('A new %s version was exported' % CONANFILE)
output.info('Folder: %s' % export_folder)
else:
output.info("The stored package has not changed")
manifest = previous_manifest  # Use the old one, keep old timestamp
manifest.save(export_folder)

通过上面流程可以看出,Recipe Resivion 是对 export 和 export_sources 里每个文件进行 md5,再将这些 md5 值合起来再 md5 得到的值。

https://github.com/conan-io/conan/blob/1.59.0/conans/client/packager.py#L28-L36

    manifest = FileTreeManifest.create(conanfile.package_folder)
manifest.save(conanfile.package_folder)
report_files_from_manifest(output, manifest)
output.success("Package '%s' created" % package_id)
prev = manifest.summary_hash
output.info("Created package revision %s" % prev)
return prev

通过上面流程可以看出,Package Resivion 是对 package_folder 里每个文件进行 md5,再将这些 md5 值合起来再 md5 得到的值。

发表回复

您的电子邮箱地址不会被公开。