发布网友 发布时间:2024-09-27 15:34
共1个回答
热心网友 时间:2024-09-27 22:34
本篇文章将聊聊如何高效的将代码仓库中的提交记录和目录结构,快速转变为“酷炫的视频”。分享如何使用 Docker 在不同 CPU 架构的设备上运行 gource,以及如何基于最新的 M1 Pro 芯片的设备,让制作可视化视频的效率成倍提升。
写在前面前一阵为了庆祝社区项目 Milvus 在 GitHub 获得了一万颗星星,我制作了一个视频,用来动态的展示在过去的时间里,这个项目的具体提交状况和项目组织架构变化状况。
最近有同事聊开源项目的“维护血泪史”时,又提到了这件事。勾起了我当时制作视频的痛苦回忆:当时的视频制作方案是使用 Docker 运行 gource。在针对诸如 Milvus 仓库这种提交量比较大的仓库时(1.4万提交),想要生成可视化视频,使用我手头的 i9 处理器的设备,至少需要跑个把小时。而当我将相同的操作换到 M1 设备(M1 Pro)运行后,或许是因为 docker 中的应用并未针对 ARM 芯片做优化、又或许是 docker 中的程序版本不够新,相同的工作量,甚至需要跑半天才能搞定! 不论如何,这个结果未免太不科学了。
且不说 M1 的运行结果“出乎意料”,但就是个把小时的视频生成时间,也让我感觉挺不舒服的。作为一个追求效率的老程序员,我花了一些时间,终于摸索出了这个问题的“正确答案”:如果使用针对 M1 芯片而编译的程序,整个视频的生成时间可以缩短到半个小时左右,相比较之前提升效果颇为明显。
在展开聊聊我是如何做的之前,我想先介绍一下 gource 这款开源软件。
关于 Gource2009 年,来自新西兰的工程师 Andrew Caudwell,希望能够将各种代码版本管理软件的信息可视化,于是他使用 C++ 编写了 Gource 这个程序。2011 年,项目从 Google Code 迁移至 GitHub 后,项目开启了年更模式。
比较幸运的是,截止本文成文写出的时候,软件已经发布了今年的两个重要更新:包含视网膜屏幕的支持,以及针对字体缩放功能进行了大量修正,并将软件使用的正则库升级为了 PCRE2,程序版本更新到了 0.53 。
因为项目在 GitHub 发布页面中只提供了 Windows 版本的程序,所以如果我们想获取 Linux / macOS 的新版本程序,就只能自己进行编译啦。(Ubuntu APT 仓库中的版本还停留在 2019 年发布的 0.51)
接下来,我们先来聊聊如何进行编译,如果你希望使用 Docker 或 x86 设备,可以阅读本文后面的章节。
在 M1 设备上进行 Gource 的编译为了能够在 macOS 上完成新版本的程序编译,我们需要先完成 gource 的依赖安装:
brew?install?pkg-config?freetype2?pcre2?glow?sdl2?sdl2_image?boost?glm?autoconf如果你没有完成上述依赖的安装,那么在执行 ./configure 的时候,一定会遇到诸如下面的问题:
checking?for?FT2...?configure:?error:?in?`/Users/soulteary/lab/gource-0.53':configure:?error:?The?pkg-config?script?could?not?be?found?or?is?too?old.??Make?sure?itis?in?your?PATH?or?set?the?PKG_CONFIG?environment?variable?to?the?fullpath?to?pkg-config....No?package?'libpcre2-8'?found...当我们安装完毕依赖之后,还需要配置一下编译参数,让程序在编译的时候能够找到我们刚刚安装的依赖。不然,就会出现类似下面的错误:
checking?for?boostlib?>=?1.46?(104600)...?configure:?We?could?not?detect?the?boost?libraries?(version?1.46?or?higher).?If?you?have?a?staged?boost?library?(still?not?installed)?please?specify?$BOOST_ROOT?in?your?environment?and?do?not?give?a?PATH?to?--with-boost?option.??If?you?are?sure?you?have?boost?installed,?then?check?your?version?number?looking?in?<boost/version.hpp>.?See?http://randspringer.de/boost?for?more?documentation.configure:?error:?Boost?Filesystem?>=?1.46?is?required.?Please?see?INSTALL...configure:?error:?GLM?headers?are?required.?Please?see?INSTALL...对于 boost 框架,我们可以通过简单使用 --with-boost 参数来指定依赖的目录,而对于 glm(OpenGL Mathematics),因为它是一个仅包含头文件的数学库,所以我们必须使用 CPPFLAGS 等参数,将路径传递给 configure。
但是我们要如何在 macOS 中获得由 brew 安装的 glm 或 boost 路径呢?这里可以将下面两种方法进行组合使用。
第一种查找路径的方法是使用 brew list 命令,获取我们安装的某个软件的详细目录列表,在输出日志中寻找或尝试出正确的目录。以 boost 举例,当我们执行完毕 brew list boost 之后,能够看到类似下面的输出结果:
/opt/homebrew/Cellar/boost/1.78.0_1/include/boost/?(15026?files)/opt/homebrew/Cellar/boost/1.78.0_1/lib/libboost_atomic-mt.dylib/opt/homebrew/Cellar/boost/1.78.0_1/lib/libboost_chrono-mt.dylib...其中 /opt/homebrew/Cellar/boost/1.78.0_1/ 就是 boost 的根目录,将这个路径拼合为 --with-boost=/opt/homebrew/Cellar/boost/1.78.0_1/ 参数,然后就能够在编译中使用 boost 啦。
第二种路径的查找方法,是使用 pkg-config 工具,输出 C++ 项目编译可以使用的具体目录参数。特别适合 glm 这类项目。我们通过为 pkg-config 添加参数,可以得到命令 pkg-config glm --libs --cflags,当命令执行完毕,就能够得到编译时可以直接使用的目录地址了:
-I/opt/homebrew/Cellar/glm/0.9.9.8/include将上面的参数进行整合,不难得到在 M1 设备上的进行编译配置的完整命令:
./configure?--with-boost=/opt/homebrew/Cellar/boost/1.78.0_1/?CPPFLAGS="-I/opt/homebrew/Cellar/glm/0.9.9.8/include"当命令执行完毕,不出意外,我们将看到类似下面的日志输出:
checking?for?a?BSD-compatible?install...?/usr/bin/install?-cchecking?whether?build?environment?is?sane...?yeschecking?for?a?thread-safe?mkdir?-p...?build-aux/install-sh?-c?-dchecking?for?gawk...?nochecking?for?mawk...?nochecking?for?nawk...?nochecking?for?awk...?awkchecking?whether?make?sets?$(MAKE)...?yeschecking?whether?make?supports?nested?variables...?yeschecking?build?system?type...?arm-apple-darwin21.4.0checking?host?system?type...?arm-apple-darwin21.4.0checking?for?g++...?g++checking?whether?the?C++?compiler?works...?yeschecking?for?C++?compiler?default?output?file?name...?a.outchecking?for?suffix?of?executables...?checking?whether?we?are?cross?compiling...?nochecking?for?suffix?of?object?files...?ochecking?whether?we?are?using?the?GNU?C++?compiler...?yeschecking?whether?g++?accepts?-g...?yeschecking?for?style?of?include?used?by?make...?GNUchecking?dependency?style?of?g++...?gcc3checking?for?timegm...?yeschecking?for?unsetenv...?yeschecking?how?to?run?the?C++?preprocessor...?g++?-Echecking?for?X...?disabledchecking?for?a?sed?that?does?not?truncate?output...?/usr/bin/sedchecking?for?gcc...?gccchecking?whether?we?are?using?the?GNU?C?compiler...?yeschecking?whether?gcc?accepts?-g...?yeschecking?for?gcc?option?to?accept?ISO?C89...?none?neededchecking?whether?gcc?understands?-c?and?-o?together...?yeschecking?dependency?style?of?gcc...?gcc3checking?for?the?pthreads?library?-lpthreads...?nochecking?whether?pthreads?work?without?any?flags...?yeschecking?for?joinable?pthread?attribute...?PTHREAD_CREATE_JOINABLEchecking?if?more?special?flags?are?required?for?pthreads...?-D_THREAD_SAFEchecking?how?to?run?the?C?preprocessor...?gcc?-Echecking?for?grep?that?handles?long?lines?and?-e...?/usr/bin/grepchecking?for?egrep...?/usr/bin/grep?-Echecking?for?ANSI?C?header?files...?yeschecking?for?sys/types.h...?yeschecking?for?sys/stat.h...?yeschecking?for?stdlib.h...?yeschecking?for?string.h...?yeschecking?for?memory.h...?yeschecking?for?strings.h...?yeschecking?for?inttypes.h...?yeschecking?for?stdint.h...?yeschecking?for?unistd.h...?yeschecking?whether?we?are?using?the?Microsoft?C?compiler...?nochecking?windows.h?usability...?nochecking?windows.h?presence...?nochecking?for?windows.h...?nochecking?for?GL/gl.h...?nochecking?for?OpenGL/gl.h...?yeschecking?for?OpenGL?library...?-framework?OpenGLchecking?for?GL/glu.h...?nochecking?for?OpenGL/glu.h...?yeschecking?for?OpenGL?Utility?library...?yeschecking?for?varargs?GLU?tesselator?callback?function?type...?nochecking?for?pkg-config...?/opt/homebrew/bin/pkg-configchecking?pkg-config?is?at?least?version?0.9.0...?yeschecking?for?FT2...?yeschecking?for?PCRE2...?yeschecking?for?GLEW...?yeschecking?for?SDL2...?yeschecking?for?PNG...?yeschecking?for?IMG_LoadPNG_RW...?yeschecking?for?IMG_LoadJPG_RW...?yeschecking?for?boostlib?>=?1.46?(104600)?includes?in?"/opt/homebrew/Cellar/boost/1.78.0_1//include"...?yeschecking?for?boostlib?>=?1.46?(104600)?lib?path?in?"/opt/homebrew/Cellar/boost/1.78.0_1//lib/arm-darwin21.4.0"...?nochecking?for?boostlib?>=?1.46?(104600)?lib?path?in?"/opt/homebrew/Cellar/boost/1.78.0_1//lib"...?yeschecking?for?boostlib?>=?1.46?(104600)...?yeschecking?whether?the?Boost::System?library?is?available...?yeschecking?for?exit?in?-lboost_system...?yeschecking?whether?the?Boost::Filesystem?library?is?available...?yeschecking?for?exit?in?-lboost_filesystem...?yeschecking?glm/glm.hpp?usability...?yeschecking?glm/glm.hpp?presence...?yeschecking?for?glm/glm.hpp...?yeschecking?that?generated?files?are?newer?than?configure...?doneconfigure:?creating?./config.statusconfig.status:?creating?Makefileconfig.status:?executing?depfiles?commands接下来,执行 make ,系统就会开始对 gource 进行编译,在编译完成之后,接着执行 sudo make install,gource 的编译安全就结束啦。
在 M1 设备上使用 Gource 进行代码仓库可视化在使用 gource 制作视频前,我们需要评估项目所需的硬盘空间,生成视频的尺寸和仓库的提交量(commits)、总的文件目录数量、项目维护时间长,都有很大关系,这里以前文中提到的 Milvus 仓库为例。
这个仓库从 2019 年开始维护,截止当前有 1.4 万次提交,如果想我们生成 1280x720 尺寸的视频内容,假设将项目每天的提交数据展示的时间设置为 1 秒,过程中将输出 370 多 GB 的 临时文件(PPM 截图文件),所以在开始进行仓库可视化之前,请确认你的硬盘留有足够的空间。
下载要进行可视化的代码仓库可视化的第一步,是将我们要可视化的仓库下载到本地,比如:
git?clone?https://github.com/milvus-io/milvus.git使用 Gource 进行可视化渲染接下来,我们需要使用 gource 指定我们未来希望得到的视频的最大分辨率,以及一些关键细节:
我们希望这个视频中,每一天的展示时间为多久(本例为1秒)
我们希望这个视频中,视频的最大帧率是多少(本例为30帧)
我们希望输出的文件名和刚刚使用 git clone 下载好的仓库的目录名是什么
gource?--viewport?1280x720?\????--high-dpi?\????--seconds-per-day?1?\????--output-ppm-stream?milvus.ppm?\????--output-framerate?30?\????milvus执行上面的命令,程序将会打开一个预览界面,开始将仓库的每一次提交记录和当时的目录结构进行可视化绘制。
经过相对漫长的等待之后(19分钟左右),当命令执行完毕,我们就得到了包含所有代码仓库提交信息、目录变化信息的临时文件:milvus.ppm。
使用 ffmpeg 生成最终的视频文件我们在上一步得到的文件,足足有 370 GB 之大。为了得到一个方便后续剪辑或在各种网络平台上传播的文件,我们还需要使用 ffmpeg 对其进行格式转换。
如果你没有安装过 ffmpeg,可以考虑使用下面的命令完成安装(本文使用版本为 5.0.1)。
brew?install?ffmpeg想要生成一个兼容性比较好的 H264 格式的 milvus.mp4 文件,可以使用下面的命令:
checking?for?FT2...?configure:?error:?in?`/Users/soulteary/lab/gource-0.53':configure:?error:?The?pkg-config?script?could?not?be?found?or?is?too?old.??Make?sure?itis?in?your?PATH?or?set?the?PKG_CONFIG?environment?variable?to?the?fullpath?to?pkg-config....No?package?'libpcre2-8'?found...0耐心等待命令执行完毕(14分钟左右),我们就能够得到包含酷炫结果的视频文件啦。相比较上一步骤中的 370GB 临时文件,视频文件显得相对小巧,只需要 12GB 左右的空间。
使用 Docker 进行代码仓库的可视化如果你不追求更高的转换效率,可以接受“离线任务”的执行方式,可以考虑使用开源项目 sandrokeil/docker-files/ 中的 gource 镜像。
使用方法非常简单,只需要一条命令:
checking?for?FT2...?configure:?error:?in?`/Users/soulteary/lab/gource-0.53':configure:?error:?The?pkg-config?script?could?not?be?found?or?is?too?old.??Make?sure?itis?in?your?PATH?or?set?the?PKG_CONFIG?environment?variable?to?the?fullpath?to?pkg-config....No?package?'libpcre2-8'?found...1在上面的命令中,我们需要做一些简单的准备:
把我们的代码仓库放置于当前目录下的 repo 目录中。
将我们计划进行替代的用户头像放在 avatars 目录中。
如果你希望程序生成视频的过程中,顺带完成背景音的配乐,可以将 mp3 文件放在 mp3s 目录中。
当命令执行完毕之后,我们就能够在本地的 results 目录中找到我们的可视化视频文件了。
其他除了忠实还原仓库中的每一次提交之外,Gource 还支持根据参数筛选时间启止、筛选生成指定用户的贡献记录、甚至搭配 shell 可以筛选生成指定目录的变化记录。
所以,当我们想进行某个大版本回顾,或者庆祝某位开源社区的用户成为项目 maintainer 时,把这些“混杂着代码的时间碎片”通过视频进行还原呈现,或许是一个不错的主意。
最后希望这篇内容能够帮到有相同需求的你。
下一篇相同主题的内容,我将分享 gource 之外的项目可视化方案,一个相对轻量的方案。
--EOF
我们有一个小小的折腾群,里面聚集了几百位喜欢折腾的小伙伴。
在不发广告的情况下,我们在里面会一起聊聊软硬件、HomeLab、编程上的一些问题,也会在群里不定期的分享一些技术沙龙的资料。
喜欢折腾的小伙伴欢迎扫码添加好友。(添加好友,请备注实名,注明来源和目的,否则不会通过审核)
关于折腾群入群的那些事
本文使用「署名 4.0 国际 (CC BY 4.0)」许可协议,欢迎转载、或重新修改使用,但需要注明来源。 署名 4.0 国际 (CC BY 4.0)
本文作者: 苏洋
创建时间: 2022年05月10日 统计字数: 8873字 阅读时间: 18分钟阅读 本文链接: https://soulteary.io/2022/05/10/lets-talk-about-code-warehouse-visualization-with-gource.html
原文:https://