Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alternative Badge SVG File as report for use in Gitlab and private Repositories #1915

Open
GameFixxer opened this issue Feb 20, 2024 · 9 comments

Comments

@GameFixxer
Copy link

Since the company I am working for is using a private Gitlab Repository and my supervisor did not want to use Stryker for the badge, I came up with a different way of displaying a badge with the MSI score. I created a svg badge file which gets updated with the score calculated. This could be used as an alternative way of displaying a badge and could be hooked into the existing logic of choosing between report and badge, adding a local badge file option.

If accepted I would be willing to integrate this feature request, by myself.

I would be grateful for any feedback.

@theofidry
Copy link
Member

Thanks for the proposal! It's a bit hard to decide on that like that, would it be possible to have a rough idea of what the code and result looks like?

@GameFixxer
Copy link
Author

GameFixxer commented Feb 20, 2024

badge
Of course! Sorry, I should have provided it in the first place.
So it will be a svg file like this, the value will be written from the MSI score.

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="160" height="20" role="img" aria-label="Mutation Score: $msi_score"><title>Mutation Score: $msi_score</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="160" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="100" height="20" fill="#555"/><rect x="93" width="90" height="20" fill="#4c1"/><rect width="160" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="465" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="810">Mutation Score</text><text x="465" y="140" transform="scale(.1)" fill="#fff" textLength="810">Mutation Score</text><text aria-hidden="true" x="1270" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="550">$msi_score%</text><text x="1270" y="140" transform="scale(.1)" fill="#fff" textLength="550">$msi_score%</text></g></svg>

This must not be the final styling, if you have another style in mind, feel free to share your idea and I would be willing to change it.

Regarding the other part of the code:
(At the company I work for, I had a custom shell script extracting the msi score ant writing this file for the gitlab badge system to use, but I am sure it should be easy to implement that logic in an additional logger class.

So I would write a new logger class, add it to the FileLoggerFactory.class (Basically the same, Infection\Logger\SummaryJsonLogger). I also need to add a variable to the Configuration\Logs.php dto parsing the filePath the same way it is done for the other logs.
I definitely will need to add a svg file writer, which takes the value from the logger class and places it in the svg string at the variable placeholder.

I hope that clarifies the approach I am thinking about.

@theofidry
Copy link
Member

So the logger would write this SVG into a file and then you can include this file content or extract it to display the badge?

@GameFixxer
Copy link
Author

Exactly. So you have control about your data and no need for using a third party service in order to display it.

@theofidry
Copy link
Member

Sounds like a good idea to me; But let's wait another team member opinion before getting started :)

@GameFixxer
Copy link
Author

I'm eagerly looking forward to discovering the response, and I appreciate your input. Thank you :)

@maks-rafalko
Copy link
Member

maks-rafalko commented Feb 20, 2024

Hello, I have a question: can't you just use already existing SummaryLogger (see original PR) and extract MSI from it and generate SVG string?

So, instead of Infection being responsible for SVG generation, your userland code will be responsible for SVG generation, getting MSI score from generated by Infection JSON file.

Probably I missed the benefit of creating specific SVG logger, could you please explain?

@GameFixxer
Copy link
Author

GameFixxer commented Feb 20, 2024

Thank you for your feedback and for engaging with my proposal. I see the merit in the point regarding leveraging existing functionalities like the SummaryLogger for extracting the MSI score and generating the SVG badge externally. This approach indeed aligns with the principle of keeping InfectionPHP focused on its core functionalities without branching into badge generation.

This is the original shell script I used, which illustrates how I've been extracting the MSI score from the JSON file generated by infection and using it to update the badge file.


json_file="$CI_PROJECT_DIR/build/mutation/summary.json"

if [ -e "$json_file" ]; then
  msi_score=$(jq -r '.stats.msi' "$json_file")

  echo "MSI score from JSON: $msi_score"

  if [ "$msi_score" = "null" ] || [ -z "$msi_score" ]; then
    msi_score="N/A"
  fi
else
  msi_score="File not found"
fi

svg_content=$(cat <<EOF
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="160" height="20" role="img" aria-label="Mutation Score: $msi_score"><title>Mutation Score: $msi_score</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="160" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="100" height="20" fill="#555"/><rect x="93" width="90" height="20" fill="#4c1"/><rect width="160" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="465" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="810">Mutation Score</text><text x="465" y="140" transform="scale(.1)" fill="#fff" textLength="810">Mutation Score</text><text aria-hidden="true" x="1270" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="550">$msi_score%</text><text x="1270" y="140" transform="scale(.1)" fill="#fff" textLength="550">$msi_score%</text></g></svg>
EOF
)

echo "$svg_content" > build/mutation/badge_url.svg

While this method was a quick solution for my specific use case, I recognize the potential inefficiency of generating an additional JSON file in case the ultimate requirement is just the badge. My initial thought was that incorporating badge generation into InfectionPHP could streamline processes for users with similar needs. This approach would have been particularly beneficial for projects hosted in private repositories, where external badge generation services might not be accessible or preferred due to privacy concerns.

However, I also understand the importance of maintaining a clear separation of concerns and avoiding feature creep that could detract from the tool's primary objectives. So if my suggestion is beyond the scope of responsibilities of InfectionPHP, I am open to exploring other methods or tools that can achieve the desired functionality without imposing additional burdens on the core project.

Thank you once again for taking the time to consider my proposal and engage in such constructive dialogue. I'm looking forward to any more thoughts or suggestions on how we can address this need in a manner that stays true to InfectionPHP's objectives.

@maks-rafalko
Copy link
Member

maks-rafalko commented Feb 20, 2024

Ok, that makes sense, thanks for the detailed answer.

I'm fine with adding it to Infection. The only one thing I would ask is to properly document it, so future readers can benefit from this new SVG logger as well, understanding why it's needed and how it can be used.

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants