1

I generated the SonarQube generic code coverage with the following script:

#!/usr/bin/env bash
set -euo pipefail

function convert_file {
  local xccovarchive_file="$1"
  local file_name="$2"
  local xccov_options="$3"
  echo "  <file path=\"$file_name\">"
  xcrun xccov view $xccov_options --file "$file_name" "$xccovarchive_file" | \
    sed -n '
    s/^ *\([0-9][0-9]*\): 0.*$/    <lineToCover lineNumber="\1" covered="false"\/>/p;
    s/^ *\([0-9][0-9]*\): [1-9].*$/    <lineToCover lineNumber="\1" covered="true"\/>/p
    '
  echo '  </file>'
}

function xccov_to_generic {
  echo '<coverage version="1">'
  for xccovarchive_file in "$@"; do
    local xccov_options=""
    if [[ $xccovarchive_file == *".xcresult"* ]]; then
      xccov_options="--archive"
    fi
    xcrun xccov view $xccov_options --file-list "$xccovarchive_file" | while read -r file_name; do
      convert_file "$xccovarchive_file" "$file_name" "$xccov_options"
    done
  done
  echo '</coverage>'
}

xccov_to_generic "$@"

The report is being generated successfully but the file paths are absolute

What's being generated: /Users/daniyal/MyApp/AccountStore/AccountStore/AccountProvider.swift

What I want AccountStore/AccountStore/AccountProvider.swift

Excerpt from sonarqube-generic-coverage.xml currently being generated

<coverage version="1">
  <file path="/Users/daniyal/MyApp/AccountStore/AccountStore/AccountProvider.swift">
    <lineToCover lineNumber="27" covered="true"/>
    <lineToCover lineNumber="28" covered="true"/>
    <lineToCover lineNumber="29" covered="true"/>
    <lineToCover lineNumber="30" covered="true"/>
    <lineToCover lineNumber="31" covered="true"/>
    <lineToCover lineNumber="33" covered="true"/>
    <lineToCover lineNumber="34" covered="true"/>
    <lineToCover lineNumber="35" covered="true"/>
    <lineToCover lineNumber="38" covered="true"/>
    <lineToCover lineNumber="39" covered="true"/>
  </file>
</coverage>
dimo414
  • 47,227
  • 18
  • 148
  • 244
Daniyal Raza
  • 352
  • 3
  • 13
  • It's not really clear how your parameter $2 to the function convert_file varies to give a clear answer. In any case I would alter the file name on line 8 directly or introduce a new local var in this function to do calculate the file name/ path as you wish. – Adrian Zaugg May 12 '20 at 01:04
  • Are you allowed to modify the script ? change the function `convert_file()` as required? – Inian May 12 '20 at 07:21

2 Answers2

1

What's being generated: /Users/daniyal/MyApp/AccountStore/AccountStore/AccountProvider.swift

What I want AccountStore/AccountStore/AccountProvider.swift

To trim a prefix from a variable use the # expansion operator:

$ echo "$PWD" # PWD is set by the shell
/home/me

$ my_absolute_path=/home/me/some/file.txt

$ echo "Relative path: ${my_absolute_path#${PWD}/}"
Relative path: some/file.txt

This trims ${PWD}/ from the start of ${my_absolute_path}, what's left over is the file's path relative to the current working directory.

So in your case, try:

echo "  <file path=\"${file_name#${PWD}/}\">"

For more advanced relative-path handling I'd recommend this approach, but if you're starting with an absolute path the above is all you need.


Consider also using printf to output formatted text; something like this will be more readable and likely easier to work with than escaping quotes and echo-ing:

printf '  <file path="%s">\n' "${file_name#${PWD}/}"
dimo414
  • 47,227
  • 18
  • 148
  • 244
-1

In that script

Change this line from:

  convert_file "$xccovarchive_file" "$file_name" "$xccov_options"

to the following:

 convert_file "$xccovarchive_file" "$(echo ${file_name} | cut -d'/' -f5-)" "$xccov_options"

You can tweak the number from 5 to something else you want.


Alternative approach:

You can pass: "AccountStore${file_name#*AccountStore}"

--or-- You can change line: local file_name="$2" like local file_name="AccountStore${2#*AccountStore}"

AKS
  • 16,482
  • 43
  • 166
  • 258