Я пытаюсь отфильтровать каталоги, которые мы не хотим игнорировать для тестового покрытия. Для этого мы используем Lcov
.
Когда я пытаюсь поместить каталоги, которые нужно игнорировать, в переменную __ignoreinput
, команда #${__lcov} ${__gcovopts} --remove MYCODE.info "${__ignoreinput}" -o MYCODE_filtered.info > /dev/null 2> /dev/null
не работает, ничего не фильтрует. Принимая во внимание, что когда я использую команду без __ignoreinput
, как в
${__lcov} ${__gcovopts} --remove MYCODE.info '/opt/*' '/usr/include/*' '*3rdParty/*' '*Input_API/*' '*Grammars/*' -o MYCODE_filtered.info > /dev/null 2> /dev/null
if [[ ${?} -ne 0 ]] ;then echo "Error *** lcov filtrering failed" && exit 1 ;fi
Фильтр работает нормально. Что я делаю неправильно. Я не понимаю.
#!/bin/bash
__orc=/home/anybody/workspace/project
__buildtype = "local"
__output=/home/anybody/workspace/lcov
#doe not work
#__ignoreinput = "'/opt/*' '/usr/include/*' '*3rdParty/*' '*Input_API/*' '*Grammars/*'"
#__ignoreinput = "/opt/* /usr/include/* *3rdParty/* *Input_API/* *Grammars/* "
#__ignoreinput = "\"/opt/*\" \"/usr/include/*\" \"*3rdParty/*\" \"*Input_API/*\" \"*Grammars/*\""
__gcovopts=--gcov-tool=/opt/1A/x86_64-2.6.32-v2/bin/gcov
__lcov=lcov
if [[ "${__buildtype}" == "docker" ]] ;then
__build=MYCODE/build_x86_64-2.6.32-v2_Gcov
else
__build=MYCODE/cmake-build-coverage
fi
echo "Filter lcov tracefile"
cd ${__orc}/${__build}
#does not work
#${__lcov} ${__gcovopts} --remove MYCODE.info "${__ignoreinput}" -o MYCODE_filtered.info > /dev/null 2> /dev/null
#works
${__lcov} ${__gcovopts} --remove MYCODE.info '/opt/*' '/usr/include/*' '*3rdParty/*' '*Input_API/*' '*Grammars/*' -o MYCODE_filtered.info > /dev/null 2> /dev/null
if [[ ${?} -ne 0 ]] ;then echo "Error *** lcov filtrering failed" && exit 1 ;fi
echo "Generate HTML reports"
cd ${__orc}/${__build}
genhtml --ignore-errors source -o ${__output}/lcov_"$(git rev-list HEAD -n 1)" MYCODE_filtered.info > /dev/null 2> /dev/null
if [[ ${?} -ne 0 ]] ;then echo "Error *** lcov reports failed" && exit 1 ;fi
Одним из простых способов передать __ignoreinput
было бы сохранить выражения glob в массиве в одиночной кавычке, расширить их при передаче к команде lcov
. Запишите ввод игнорирования как
__ignoreinput=( '/opt/*' '/usr/include/*' '*3rdParty/*' '*Input_API/*' '*Grammars/*' )
и выполнение ниже должно работать, как ожидалось.
"${__lcov}" "${__gcovopts}" --remove MYCODE.info "${__ignoreinput[@]}" -o MYCODE_filtered.info 2>&1 > /dev/null
Для всех случаев отказа в вашем описании __ignoreinput
задается как одна целая строка под ".."
, но команда ожидает, что слова будут разделены на одно выражение для каждого. Однако расширение массива "${__ignoreinput[@]}"
помещает каждое слово, определенное в массиве, как отдельное слово, как и ожидалось командой.
Также осторожно заключайте в одинарные/двойные кавычки слова в массиве во время определения, потому что при отсутствии кавычек *
может подвергнуться расширению имени пути и может расшириться до списка имен файлов по каждому из этих путей.
Также посмотрите, как > /dev/null 2> /dev/null
можно минимизировать до > /dev/null 2> /dev/null
или просто &> /dev/null
в bash
.
Also naming variable names prefixed with __
is a bad practice. Like most of the languages out there, the character can itself could be a valid variable identifier. As shown above enclosing the variable name completely around {..}
is the recommended way.
Также осторожно заключайте в одинарные/двойные кавычки слова в массиве во время определения, потому что при отсутствии кавычек * может подвергнуться расширению имени пути и может расшириться до списка имен файлов по каждому из этих путей. Вы правы, у меня действительно была эта проблема, расширение действительно произошло, я не знал, почему раньше
#inian можно еще вопрос задать? новый
Если это тривиально, я могу ответить здесь или если это вообще новый вопрос, задайте отдельный вопрос!
большое спасибо за вашу помощь @Inian. Действительно, это сработало. Я думал, что они расстанутся. Я неправильно подумал лолол