在 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 上创建问题,提出任何问题、评论或建议