jenkins - 将文件中的每个文件路径替换为符号链接后面的路径
问题描述
我正在使用 Typescript 使用 Jenkins 构建项目。它使用“jest”生成包含代码覆盖率数据的“lcov.info”文件。工作区有一些符号链接。“lcov.info”文件中的结果路径代表链接的“源”,而不是目标。这应该没问题,假设工具链中的所有内容都理解符号链接。
不幸的是,我还在使用稍旧版本的 SonarQube,它使用的是稍旧版本的 SonarTS 插件,它不理解符号链接,因此找不到所有路径。
我不知道 SonarTS 中的错误是否已在未来版本中修复。等待升级是不可能的。
我之前为此编写了一个头脑简单的 sed 脚本,当时我对符号链接后面的实际绝对路径所做的假设是正确的。这个假设现在不正确,所以我必须在 Jenkins 管道脚本中构建一个更复杂的 bash 命令行。
我的第一次尝试看起来像这样:
sh "cat coverage/lcov.info | sed -e 's/^SF:(.*)/SF:`ls -L \\1`/g' > /tmp/lcov.info"
我的意图是用符号链接后面的“ls -L”结果替换文件路径。这不起作用,因为...
脚本获取字符串“\1”,而不是我想要的。我可以理解为什么会这样,因为反引号表达式可能是在构建正则表达式之前构建的。
我宁愿不构建多行脚本并将其存储在构建中,而是内联编写它。
我猜想用 awk 来做这件事可能更实用,但是我已经有一段时间没有 awk-ed 一些不平凡的东西了。
更新:
尽管我为此找到了一个粗糙的 bash 解决方案,但我发现 perl 解决方案很有吸引力,因为它更简单。但是,我实际上无法让它工作。
我创建了一个名为“dir1”的目录,并在其中放置了一个名为“stuff”的空文件。我创建了一个名为“dir2”的符号链接,它指向“dir1”。我创建了一个名为“junk1”的文件,其内容如下:
SF:dir2/stuff
SF:dir2/stuff
另请注意:
% ls -lt dir2
lrwxrwxrwx 1 dk068x dk068x 4 Dec 16 13:22 dir2 -> dir1/
然后我运行以下命令并得到指示的结果:
% cat junk1 | perl -pe 's/^(SF:)(.*)/ $1 . readlink $2 /ge'
SF:
SF:
我在 Cygwin 和 Ubuntu VM 上都对此进行了测试。
解决方案
如果Perl
是您的选择,请尝试:
perl -pe 's/^(SF:)(.*)/ $1 . readlink $2 /ge' < coverage/lcov.info > /tmp/lcov.info
- 该
readlink
函数返回符号链接的值。 - 运算符的
e
选项s/pattern/replacement/
使替换成为 的表达式Perl
。
[更新]
现在脚本分析info
文件中描述的路径以递归查找符号链接子字符串。
#!/bin/bash
perl -lne '
use strict;
use warnings;
my $col1; # 1st column of the info file
my $col2; # 2nd column of the info file
my $real_path; # resolved path (final)
my $link_substr; # substring of $path which is a symlink
my $link_result; # output of readlink
# return substring which is a symlink
sub checklink() {
my $path = shift;
while (1) {
return $path if -l $path; # $path is a symlink
return "" if $path !~ m#/#; # return "" if $path contains no symlink
$path =~ s#/[^/]*$##; # remove the rightmost "/" and following substring
}
}
if (/^(SF:)(.*)/) {
$col1 = $1; $col2 = $2;
$link_substr = &checklink($col2);
if ($link_substr ne "") {
$link_result = readlink($link_substr);
$link_result =~ s#/$##; # remove trailing "/" if any
$real_path = $link_result . substr($col2, length($link_substr));
} else {
$real_path = $col2;
}
print $col1, $real_path;
}
' coverage/lcov.info > /tmp/lcov.info
推荐阅读
- c - 验证双指针函数参数中 const 的正确使用
- php - 如何分隔字符串并将其插入关联数组
- python-3.x - 即使在关注 effbot 后图像也不显示
- python - 如何处理使用 selenium python 时出现的过滤框?
- android - react-native-tus-client 没有这样的文件或目录错误
- raspberry-pi - 桌面和移动应用程序的最佳开发框架,也可以连接到树莓派
- angular - 致命错误:堆限制附近的无效标记压缩分配失败 - JavaScript 堆内存不足,同时构建 Angular 8 项目
- mongodb - 恢复分片的 Mongodb 不包括分片信息
- junit - 测试java应用、数据库层、嵌入db、执行sql脚本
- ios - 如何使用 UIWebView 的弃用 API 解决 Flurry iOS SDK 问题?