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 得到的值。

发表回复

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