在 Conan 1.X 中,上传上次 conan install --build=missing 命令从源代码构建的完整包集并非易事。需要编写一些脚本获取命令的输出,然后迭代结果,每次执行一个 conan upload <ref> 命令。

我们很高兴在 Conan 2.0.7 中推出“包列表”功能,该功能内置了此备受期待的功能。

包列表文件的简介

“包列表”是一个 JSON 文件,其中包含 Conan 工件(配方和包二进制文件)的列表。此文件可以通过多个命令的 --format=json 选项生成。例如,以下 conan list 命令

# The output file name is user defined
$ conan list "*:*" --format=json > pkglist.json

将生成一个类似于以下所示的 pkglists.json 文件(已简化,不完整)

{
  "conancenter": {
    "zlib/1.2.12": {
      "revisions": {
        "b1fd071d8a2234a488b3ff74a3526f81": {
          "timestamp": 1667396813.987,
          "packages": {
            "ae9eaf478e918e6470fe64a4d8d4d9552b0b3606": {
              "revisions": {
                "19808a47de859c2408ffcf8e5df1fdaf": {}
              },
              "info": {
                "settings": {
                  "arch": "x86_64",
                  "os": "Windows"
                }
              }
            }
          }
        }
      }
    },
    "zlib/1.2.13": {}
  }
}

pkglist.json 中的第一级是“位置”,可以是远程位置或本地缓存。在本例中,我们列出了缓存中的包,因此源头是“本地缓存”。

conan removeconan uploadconan download 命令也可以使用 --format=json 格式化程序生成“包列表”。例如,conan upload ... -r=myremote --format=json 将生成一个包列表,其中“myremote”位置作为结果 JSON 文件中的第一级。

此外,还可以从 conan createconan installconan graph info 命令的结果生成包列表,我们将在下面的示例中看到。

包列表文件的一个优点是,它们可以用作输入,以便在多个命令中执行批量操作。

$ conan upload --list=pkgs_to_upload.json -r=myremote
$ conan download --list=download.json -r=myremote
$ conan remove --list=pkglists.json  # From the cache or -r=remote

让我们看看一些更完整且有用的示例。

从一个远程下载并上传到另一个远程

这在填充或**提升**隔离环境中的包时非常有用,其中有两个服务器。一个服务器是包含我们希望引入隔离环境(经过尽职调查)的某些包的公共服务器。这在企业环境中相当常见。

例如,假设我们希望从 ConanCenter 下载一些包,断开与互联网的连接,在本地检查包,最后将它们上传到我们自己的私有内部服务器。(注意:这是一个示例,对于 ConanCenter 包,当安全、可重复性和鲁棒性非常重要时,更好的方法是从源代码构建包,从 conan-center-index 分支构建)

Conan 2.0 graphic demonstrating Promoting packages in air-gapped environments or where network access is limited/forbidden with download upload and upload commands

使用 conan download 命令,我们可以下载一些包,例如,zlib/1.2.12 的所有 Windows 二进制文件(默认情况下仅下载最新的修订版本),并生成一个 downloaded.json 包列表文件。

$ conan download zlib/1.2.12:* -p "os=Windows" -r=conancenter --format=json > downloaded.json

生成的 downloaded.json 文件将如下所示:

{
   "Local Cache": {
        "zlib/1.2.12": {
            "revisions": {
                "b1fd071d8a2234a488b3ff74a3526f81": {
                    "timestamp": 1667396813.987,
                    "packages": {
                        // full list of package binaries (Windows)
                    }
                }
            }
        }
    }
}

这意味着我们现在可以将这同一组配方和二进制文件上传到不同的远程服务器。

$ conan upload --list=downloaded.json -r=myremote -c
# Upload the artifacts listed in the "Local Cache" location to my own remote

其中一个要点是,这与缓存内容无关。本地缓存中是否包含来自其他命令的其他工件无关紧要。上传到 myremote 存储库的包将仅是 downloaded.json 中列出的那些包。

请注意,这将是运行不同服务器存储库之间提升的**缓慢**机制。某些服务器提供了一种方法,可以直接将包从一个存储库复制到另一个存储库,而无需使用客户端,这由于文件重复数据删除而快得多,因此如果两个存储库可以直接相互通信,则建议使用此方法。

从源代码构建并上传包

“包列表”最有趣的应用之一是,当某些包使用 conan createconan install --build=xxx 命令在本地缓存中构建时。通常,我们希望将本地构建的包上传到服务器,这样其他人就不必重新构建它们。但我们可能只想上传构建的二进制文件,而不是所有其他传递依赖项或我们之前在本地缓存中的其他包。

Build from source and upload newly built packages with Conan 2.0 using conan create or conan install build missing and the new graph binary and package list JSON formats supported with 2.0.7

可以使用来自任何 conan installconan createconan graph info 命令的图来计算包列表,然后可以使用该列表与上传命令一起使用。然后,可以使用该包列表进行上传。

例如,我们可以使用以下命令从源代码构建 spdlog 的最新版本及其传递依赖项(包括 fmt):

$ conan install --requires="spdlog/[*]" --build="*" --format=json > build.json

这将创建图的 JSON 表示形式,其中包含已构建的包的信息(即,它们包含 "binary": "Build"),build.json 将如下所示(已简化):

{
  "graph": {
    "nodes": {
        "0": {
            "ref": "conanfile",
            "recipe": "Cli",
            "dependencies": { "1": {"ref": "spdlog/1.11.0"} }
        },
        "1": {
            "ref": "spdlog/1.11.0#d0fdbaa523550b89156084bf42b41c90",
            "binary": "Build",
            "dependencies": { "2": {"ref": "fmt/9.1.0"}}
        },
        "2": {
            "ref": "fmt/9.1.0#44302d39c5a4bf7de8a39adc50bb4568",
            "binary": "Build"
        }
    }
  }
}

我们可以从此文件中计算一个包列表,然后使用以下命令将这些工件上传到服务器:

$ conan list --graph=build.json --graph-binaries=build --format=json > pkglist.json

生成的 pkglist.json 将包含 spdlogfmt 的配方和构建的二进制文件,我们现在可以使用此列表将这些确切的包(而不是缓存中存在的其他包,或我的 install 命令中未从源代码构建的其他内容)上传到我自己的服务器。

$ conan upload --list=pkglist.json -r=myremote -c

结论

新的 Conan 2.0 架构的优点之一是,它能够快速开发所需的功能。这个新的“包列表”功能是 Conan CLI 的一个强大的新增功能,允许对包集执行批量操作,这些操作以前需要用户自定义自动化(脚本文件或持续集成作业),现在方便地作为内置功能提供。

非常欢迎您的反馈,如有任何疑问、评论或建议,请在 Github 上创建问题