-
-
Notifications
You must be signed in to change notification settings - Fork 110
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
Kcov zig 4merge (for discussion) #424
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
{ | ||
// Use IntelliSense to learn about possible attributes. | ||
// Hover to view descriptions of existing attributes. | ||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 | ||
"version": "0.2.0", | ||
"configurations": [ | ||
{ | ||
"type": "lldb", | ||
"request": "launch", | ||
"name": "Debug", | ||
"program": "${workspaceFolder}/build/src/kcov", | ||
"args": [ | ||
"./cov", | ||
"--include-path=/Users/bytedance/DevCamp/jstring", | ||
"--clean", | ||
"/Users/bytedance/DevCamp/jstring/zig-out/bin/pcre_test" | ||
], | ||
"cwd": "${workspaceFolder}/../jstring" | ||
} | ||
] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,62 @@ | ||
# A fork of `kcov` for better covering Zig | ||
|
||
This is a rather than naive fork of wonderful `kcov` for better supporting Zig projects. | ||
|
||
## It adds the ability to auto recognize Zig's `unreachable` and `@panic` for auto ignoring. | ||
|
||
Here is a screenshot of auto ignoring `unreachable`. | ||
|
||
![zig-unreachable-example](https://github.com/liyu1981/kcov/blob/master/nocover/zig-unreachable.png?raw=true) | ||
|
||
Here is another screenshot of auto ignoring `@panic`. | ||
|
||
![zig-panic-example](https://github.com/liyu1981/kcov/blob/master/nocover/zig-panic.png?raw=true) | ||
|
||
## It also adds the ability in c/c++ source file of using `/* no-cover */` to mark a line to be ignored. | ||
|
||
Here is a screenshot of manual ignoring by placing `/* no-cover */` in c source file. | ||
|
||
![c-no-cover example](https://github.com/liyu1981/kcov/blob/master/nocover/c-nocover.png?raw=true) | ||
|
||
## Usage | ||
|
||
There is no change of original `kcov` usage, it will just work. Please follow the below original Kcov README. | ||
|
||
### But how can I get the binary? | ||
|
||
The best way is to compile from source. It can be done as follows (you will need `cmake`, `ninja`, `llvm@>16` as I tried) | ||
|
||
``` | ||
git clone https://github.com/liyu1981/kcov.git | ||
cd kcov | ||
mkdir build | ||
cd build | ||
CC="clang" CXX="clang++" cmake -G Ninja .. | ||
ninja | ||
``` | ||
|
||
after building is done. The binary is at `build/src/kcov`. Copy somewhere and use it. | ||
|
||
(Or you can download a copy of Apple Silicon version binary from the release section.) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we can make a release shortly after merge of this, and then the osx homebrew is usually updated quite quickly. I suppose that can be added to the README, or another documentation file. Since not all distributions are up to date, I don't want to in general recommend installing from there. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same to above |
||
|
||
## File Support | ||
|
||
- for Zig, support source file with `.zig` extension. | ||
- for C/C++, support source file with `.c/.cpp/.cc` extension. | ||
|
||
## Original Kcov Readme | ||
|
||
[![Coveralls coverage status](https://img.shields.io/coveralls/SimonKagstrom/kcov.svg)](https://coveralls.io/r/SimonKagstrom/kcov?branch=master) | ||
[![Codecov coverage status](https://codecov.io/gh/SimonKagstrom/kcov/branch/master/graph/badge.svg)](https://codecov.io/gh/SimonKagstrom/kcov) | ||
[![Coverity Scan Build Status](https://scan.coverity.com/projects/2844/badge.svg)](https://scan.coverity.com/projects/2844) | ||
![Docker Pulls](https://img.shields.io/docker/pulls/kcov/kcov.svg) | ||
|
||
[![PayPal Donate](https://img.shields.io/badge/paypal-donate-blue.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=simon.kagstrom%40gmail%2ecom&lc=US&item_name=Simon%20Kagstrom&item_number=kcov¤cy_code=USD&bn=PP%2dDonationsBF%3abtn_donate_LG%2egif%3aNonHosted) [![Github All Releases](https://img.shields.io/github/downloads/atom/atom/total.svg)](https://github.com/SimonKagstrom/kcov/) | ||
|
||
## *kcov* | ||
## _kcov_ | ||
|
||
Kcov is a FreeBSD/Linux/OSX code coverage tester for compiled languages, Python | ||
and Bash. Kcov was originally a fork of [Bcov](http://bcov.sf.net), but has | ||
and Bash. Kcov was originally a fork of [Bcov](http://bcov.sf.net), but has | ||
since evolved to support a large feature set in addition to that of Bcov. | ||
|
||
Kcov, like Bcov, uses DWARF debugging information for compiled programs to | ||
|
@@ -16,28 +65,27 @@ switches. | |
|
||
For a video introduction, [look at this presentation from SwedenCPP](https://www.youtube.com/watch?v=1QMHbp5LUKg) | ||
|
||
Installing | ||
---------- | ||
## Installing | ||
|
||
Refer to the [INSTALL](INSTALL.md) file for build instructions, or use our official Docker images: | ||
|
||
* [kcov/kcov](https://hub.docker.com/r/kcov/kcov/) for releases since v31. | ||
- [kcov/kcov](https://hub.docker.com/r/kcov/kcov/) for releases since v31. | ||
|
||
## How to use it | ||
|
||
How to use it | ||
------------- | ||
Basic usage is straight-forward: | ||
|
||
``` | ||
kcov /path/to/outdir executable [args for the executable] | ||
``` | ||
|
||
*/path/to/outdir* will contain lcov-style HTML output generated | ||
_/path/to/outdir_ will contain lcov-style HTML output generated | ||
continuously while the application runs. Kcov will also write cobertura- | ||
compatible XML output and generic JSON coverage information and can easily | ||
be integrated in various CI systems. | ||
|
||
Filtering output | ||
---------------- | ||
## Filtering output | ||
|
||
It's often useful to filter output, since e.g., /usr/include is seldom of interest. | ||
This can be done in two ways: | ||
|
||
|
@@ -47,8 +95,8 @@ kcov --exclude-pattern=/usr/include --include-pattern=part/of/path,other/path \ | |
``` | ||
|
||
which will do a string-comparison and include everything which contains | ||
*part/of/path* or *other/path* but exclude everything that has the | ||
*/usr/include* string in it. | ||
_part/of/path_ or _other/path_ but exclude everything that has the | ||
_/usr/include_ string in it. | ||
|
||
``` | ||
kcov --include-path=/my/src/path /path/to/outdir executable | ||
|
@@ -57,8 +105,8 @@ kcov --exclude-path=/usr/include /path/to/outdir executable | |
|
||
Does the same thing, but with proper path lookups. | ||
|
||
Merging multiple kcov runs | ||
-------------------------- | ||
## Merging multiple kcov runs | ||
|
||
Kcov can also merge the results of multiple earlier runs. To use this mode, | ||
call kcov with `--merge`, an output path and one or more paths to an earlier | ||
run, e.g., | ||
|
@@ -68,20 +116,20 @@ kcov --merge /tmp/merged-output /tmp/kcov-output1 /tmp/kcov-output2 | |
kcov --merge /tmp/merged-output /tmp/kcov-output* # With a wildcard | ||
``` | ||
|
||
Use from continuous integration systems | ||
--------------------------------------- | ||
## Use from continuous integration systems | ||
|
||
kcov is easy to integrate with [travis-ci](http://travis-ci.org) together with | ||
[coveralls.io](http://coveralls.io) or [codecov.io](http://codecov.io). It can also | ||
be used from Jenkins, [SonarQube](http://sonarqube.org) and [GitLab CI](http://gitlab.com). | ||
Refer to | ||
|
||
* [coveralls](doc/coveralls.md) for details about travis-ci + coveralls, or | ||
* [codecov](doc/codecov.md) for details about travis-ci + codecov | ||
* [jenkins](doc/jenkins.md) for details about how to integrate in Jenkins | ||
* [sonarqube](doc/sonarqube.md) for how to use kcov and sonarqube together | ||
* [gitlab](doc/gitlab.md) for use with GitLab | ||
- [coveralls](doc/coveralls.md) for details about travis-ci + coveralls, or | ||
- [codecov](doc/codecov.md) for details about travis-ci + codecov | ||
- [jenkins](doc/jenkins.md) for details about how to integrate in Jenkins | ||
- [sonarqube](doc/sonarqube.md) for how to use kcov and sonarqube together | ||
- [gitlab](doc/gitlab.md) for use with GitLab | ||
|
||
## More information | ||
|
||
More information | ||
---------------- | ||
kcov is written by Simon Kagstrom <[email protected]> and more | ||
information can be found at [the web page](http://simonkagstrom.github.io/kcov/index.html) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,7 @@ class type_info; | |
#include <sstream> | ||
|
||
#include "writer-base.hh" | ||
#include "nocover.hh" | ||
|
||
namespace kcov | ||
{ | ||
|
@@ -134,6 +135,12 @@ class CodecovWriter : public WriterBase | |
IReporter::LineExecutionCount cnt = m_reporter.getLineExecutionCount(file->m_name, n); | ||
std::string hitScore = "0"; | ||
|
||
std::string& line_str = file->m_lineMap.at(n); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Kcov now builds with c++17, so you can use auto & for these. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. got it. |
||
std::string& file_name = file->m_fileName; | ||
if (!shouldCover(line_str, file_name)) { | ||
continue; | ||
} | ||
|
||
if (m_maxPossibleHits == IFileParser::HITS_UNLIMITED || m_maxPossibleHits == IFileParser::HITS_SINGLE) | ||
{ | ||
if (cnt.m_hits) { | ||
|
@@ -167,7 +174,7 @@ class CodecovWriter : public WriterBase | |
linesBlock += "\n"; | ||
|
||
|
||
std::string out = | ||
std::string out = | ||
" \"" + filename + "\": {\n" + | ||
linesBlock + | ||
" }"; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,6 +16,7 @@ | |
#include <fstream> | ||
|
||
#include "writer-base.hh" | ||
#include "nocover.hh" | ||
|
||
using namespace kcov; | ||
|
||
|
@@ -72,6 +73,11 @@ class HtmlWriter : public WriterBase | |
"\"line\":\"", n); | ||
outJson << escape_json(line) << "\""; | ||
|
||
std::string& line_str = file->m_lineMap[n]; | ||
std::string& file_name = file->m_name; | ||
bool should_cover = shouldCover(line_str, file_name); | ||
const std::string& no_cover_class = "lineNoCov"; | ||
|
||
if (m_reporter.lineIsCode(file->m_name, n)) | ||
{ | ||
IReporter::LineExecutionCount cnt = m_reporter.getLineExecutionCount(file->m_name, n); | ||
|
@@ -90,18 +96,21 @@ class HtmlWriter : public WriterBase | |
lineClass = "linePartCov"; | ||
} | ||
|
||
outJson << fmt(",\"class\":\"%s\"," | ||
"\"hits\":\"%u\",", lineClass.c_str(), cnt.m_hits); | ||
|
||
// Don't report order for zeroes | ||
if (cnt.m_order) | ||
outJson << fmt("\"order\":\"%llu\",", (unsigned long long) cnt.m_order); | ||
if (lineClass == no_cover_class && !should_cover) { | ||
// should not cover, so skip, but if there are some hits (when lineClass is not no cov), go else for normal marking | ||
} else { | ||
outJson << fmt(",\"class\":\"%s\"," | ||
"\"hits\":\"%u\",", lineClass.c_str(), cnt.m_hits); | ||
// Don't report order for zeroes | ||
if (cnt.m_order) | ||
outJson << fmt("\"order\":\"%llu\",", (unsigned long long) cnt.m_order); | ||
|
||
if (m_maxPossibleHits != IFileParser::HITS_SINGLE) | ||
outJson << fmt("\"possible_hits\":\"%u\",", cnt.m_possibleHits); | ||
if (m_maxPossibleHits != IFileParser::HITS_SINGLE) | ||
outJson << fmt("\"possible_hits\":\"%u\",", cnt.m_possibleHits); | ||
|
||
nExecutedLines += !!cnt.m_hits; | ||
nCodeLines++; | ||
nExecutedLines += !!cnt.m_hits; | ||
nCodeLines++; | ||
} | ||
} | ||
outJson << "},\n"; | ||
|
||
|
@@ -252,15 +261,29 @@ class HtmlWriter : public WriterBase | |
if (!res) | ||
continue; | ||
|
||
// since we may ignored some from previous individual writeOne functions for each file, here use the sum from | ||
// files instead of summary | ||
int inFilesTotalCodeLines = 0; | ||
int inFilesTotalExecutedLines = 0; | ||
for (FileMap_t::const_iterator it = m_files.begin(); it != m_files.end(); ++it) | ||
{ | ||
inFilesTotalCodeLines += it->second->m_codeLines; | ||
inFilesTotalExecutedLines += it->second->m_executedLines; | ||
} | ||
|
||
// Skip entries (merged ones) that shouldn't be included in the totals | ||
if (summary.m_includeInTotals) | ||
{ | ||
nTotalCodeLines += summary.m_lines; | ||
nTotalExecutedLines += summary.m_executedLines; | ||
nTotalCodeLines += inFilesTotalCodeLines; | ||
nTotalExecutedLines += inFilesTotalExecutedLines; | ||
// nTotalCodeLines += summary.m_lines; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove the comment There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. will do |
||
// nTotalExecutedLines += summary.m_executedLines; | ||
} | ||
|
||
std::string datum = getIndexHeader(fmt("%s/index.html", de->d_name), name, name, summary.m_lines, | ||
summary.m_executedLines); | ||
std::string datum = getIndexHeader(fmt("%s/index.html", de->d_name), name, name, inFilesTotalCodeLines, | ||
inFilesTotalExecutedLines); | ||
// std::string datum = getIndexHeader(fmt("%s/index.html", de->d_name), name, name, summary.m_lines, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ... also here |
||
// summary.m_executedLines); | ||
|
||
if (name == conf.keyAsString("merged-name")) | ||
merged += datum; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,6 +16,7 @@ class type_info; | |
#include <fstream> | ||
|
||
#include "writer-base.hh" | ||
#include "nocover.hh" | ||
|
||
using namespace kcov; | ||
|
||
|
@@ -61,12 +62,21 @@ class JsonWriter : public WriterBase | |
for (unsigned int n = 1; n < file->m_lastLineNr; n++) | ||
{ | ||
IReporter::LineExecutionCount cnt = m_reporter.getLineExecutionCount(file->m_name, n); | ||
|
||
const std::string& line_str = file->m_lineMap[n]; | ||
const std::string& file_name = it->first; | ||
bool should_cover = shouldCover(line_str, file_name); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that all these can probably be moved to reporter.cc instead, to the At least it's something to try out. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. good suggestion, will do |
||
|
||
if (m_reporter.lineIsCode(file->m_name, n)) | ||
{ | ||
nExecutedLines += !!cnt.m_hits; | ||
nCodeLines++; | ||
nTotalExecutedLines += !!cnt.m_hits; | ||
nTotalCodeLines++; | ||
if (should_cover) { | ||
nExecutedLines += !!cnt.m_hits; | ||
nCodeLines++; | ||
nTotalExecutedLines += !!cnt.m_hits; | ||
nTotalCodeLines++; | ||
} else { | ||
// skip this from counting | ||
} | ||
} | ||
} | ||
if (nCodeLines > 0) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All this is nice information, but when "native" kcov supports it, I think it won't be needed (as it's shown in the output anyway).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agree, I will remove this in later cleaned up PR.