xaizek / uncov (License: AGPLv3+) (since 2018-12-07)
Uncov(er) is a tool that collects and processes code coverage reports.
Commit 8234e1356ff9a43fd4bf7a583ae143da0c4108d8

Add --prefix option to new-gcovi subcommand
It allows specifying prefix to be added to relative path of sources.
Author: xaizek
Author date (UTC): 2018-11-30 18:01
Committer name: xaizek
Committer date (UTC): 2018-11-30 18:01
Parent(s): 5b5e7b89bf923af4c055c7cbf57ae6eb4c52a830
Signing key: 99DC5E4DB05F6BE2
Tree: 96e6d0708e89e2edb5144e5b28fed950f26f1b29
File Lines added Lines deleted
docs/uncov.1 4 1
docs/uncov/06-subcommand-list.md 2 0
src/GcovImporter.cpp 11 3
src/GcovImporter.hpp 5 1
src/sub_commands.cpp 6 1
tests/sub_commands.cpp 30 0
File docs/uncov.1 changed (mode: 100644) (index 588777f..8b7000b)
1 1 .\" Automatically generated by Pandoc 1.17.0.3 .\" Automatically generated by Pandoc 1.17.0.3
2 2 .\" .\"
3 .TH "uncov" "1" "November 11, 2018" "uncov v0.2" ""
3 .TH "uncov" "1" "November 30, 2018" "uncov v0.2" ""
4 4 .hy .hy
5 5 .SH NAME .SH NAME
6 6 .PP .PP
 
... ... Generates coverage via \f[C]gcov\f[] and imports it.
381 381 be repeated), paths are taken to be relative to the root of the be repeated), paths are taken to be relative to the root of the
382 382 repository; repository;
383 383 .IP \[bu] 2 .IP \[bu] 2
384 \f[B]\-\-prefix arg\f[] \-\- prefix to be added to relative path of
385 sources
386 .IP \[bu] 2
384 387 \f[B]\-\-ref\-name arg\f[] \-\- forces custom ref name; \f[B]\-\-ref\-name arg\f[] \-\- forces custom ref name;
385 388 .IP \[bu] 2 .IP \[bu] 2
386 389 \f[B]\-c [ \-\-capture\-worktree ]\f[] \-\- make a dangling commit if \f[B]\-c [ \-\-capture\-worktree ]\f[] \-\- make a dangling commit if
File docs/uncov/06-subcommand-list.md changed (mode: 100644) (index 5943572..c594775)
... ... Generates coverage via `gcov` and imports it.
199 199 * **-e [ --exclude ] arg** -- specifies a path to exclude (can be * **-e [ --exclude ] arg** -- specifies a path to exclude (can be
200 200 repeated), paths are taken to be relative to repeated), paths are taken to be relative to
201 201 the root of the repository; the root of the repository;
202 * **--prefix arg** -- prefix to be added to relative path of
203 sources
202 204 * **--ref-name arg** -- forces custom ref name; * **--ref-name arg** -- forces custom ref name;
203 205 * **-c [ --capture-worktree ]** -- make a dangling commit if working directory * **-c [ --capture-worktree ]** -- make a dangling commit if working directory
204 206 is dirty. is dirty.
File src/GcovImporter.cpp changed (mode: 100644) (index bd989ee..86ea0a5)
... ... GcovImporter::setRunner(std::function<runner_f> runner)
46 46
47 47 GcovImporter::GcovImporter(const std::string &root, GcovImporter::GcovImporter(const std::string &root,
48 48 const std::string &covoutRoot, const std::string &covoutRoot,
49 const std::vector<std::string> &exclude)
50 : rootDir(normalizePath(fs::absolute(root)))
49 const std::vector<std::string> &exclude,
50 const std::string &prefix)
51 : rootDir(normalizePath(fs::absolute(root))),
52 prefix(prefix)
51 53 { {
52 54 for (const fs::path &p : exclude) { for (const fs::path &p : exclude) {
53 55 skipPaths.insert(normalizePath(fs::absolute(p, root))); skipPaths.insert(normalizePath(fs::absolute(p, root)));
 
... ... GcovImporter::parseGcov(const std::string &path)
159 161 if (type == "file") { if (type == "file") {
160 162 coverage = nullptr; coverage = nullptr;
161 163
162 fs::path sourcePath = normalizePath(fs::absolute(value, rootDir));
164 fs::path filePath = value;
165 if (!filePath.is_absolute()) {
166 filePath = prefix / filePath;
167 }
168
169 fs::path sourcePath = normalizePath(fs::absolute(filePath,
170 rootDir));
163 171 if (!pathIsInSubtree(rootDir, sourcePath) || if (!pathIsInSubtree(rootDir, sourcePath) ||
164 172 isExcluded(sourcePath)) { isExcluded(sourcePath)) {
165 173 continue; continue;
File src/GcovImporter.hpp changed (mode: 100644) (index 0c4aa20..145383e)
... ... public:
56 56 * @param root Root of the source repository. * @param root Root of the source repository.
57 57 * @param covoutRoot Root of subtree containing coverage data. * @param covoutRoot Root of subtree containing coverage data.
58 58 * @param exclude List of paths to exclude. * @param exclude List of paths to exclude.
59 * @param prefix Prefix to be added to relative path of sources.
59 60 */ */
60 61 GcovImporter(const std::string &root, const std::string &covoutRoot, GcovImporter(const std::string &root, const std::string &covoutRoot,
61 const std::vector<std::string> &exclude);
62 const std::vector<std::string> &exclude,
63 const std::string &prefix);
62 64
63 65 public: public:
64 66 /** /**
 
... ... private:
97 99 std::unordered_map<std::string, std::vector<int>> mapping; std::unordered_map<std::string, std::vector<int>> mapping;
98 100 //! Final coverage information. //! Final coverage information.
99 101 std::vector<File> files; std::vector<File> files;
102 //! Prefix to add to relative paths to source files.
103 std::string prefix;
100 104 }; };
101 105
102 106 #endif // UNCOV__GCOVIMPORTER_HPP__ #endif // UNCOV__GCOVIMPORTER_HPP__
File src/sub_commands.cpp changed (mode: 100644) (index 7c58cd0..1349b96)
... ... public:
792 792 ("exclude,e", po::value<std::vector<std::string>>() ("exclude,e", po::value<std::vector<std::string>>()
793 793 ->default_value({}, ""), ->default_value({}, ""),
794 794 "specifies a path to exclude (can be repeated)") "specifies a path to exclude (can be repeated)")
795 ("prefix", po::value<std::string>()->default_value({}, ""),
796 "prefix to be added to relative path of sources")
795 797 ("ref-name", po::value<std::string>(), ("ref-name", po::value<std::string>(),
796 798 "forces custom ref name") "forces custom ref name")
797 799 ("capture-worktree,c", ("capture-worktree,c",
 
... ... private:
828 830 fs::absolute(varMap["covoutroot"].as<std::string>()).string(); fs::absolute(varMap["covoutroot"].as<std::string>()).string();
829 831 auto exclude = varMap["exclude"].as<std::vector<std::string>>(); auto exclude = varMap["exclude"].as<std::vector<std::string>>();
830 832 bool shouldCapture = varMap.count("capture-worktree"); bool shouldCapture = varMap.count("capture-worktree");
833 auto prefix = varMap["prefix"].as<std::string>();
831 834 verbose = varMap.count("verbose"); verbose = varMap.count("verbose");
832 835
836 // XXX: this doesn't account for worktrees.
833 837 absRepoRoot = fs::absolute(normalizePath(repo->getGitPath())) absRepoRoot = fs::absolute(normalizePath(repo->getGitPath()))
834 838 .parent_path().string(); .parent_path().string();
835 839
836 840 std::vector<File> importedFiles = GcovImporter(absRepoRoot, std::vector<File> importedFiles = GcovImporter(absRepoRoot,
837 841 covoutRoot, covoutRoot,
838 exclude).getFiles();
842 exclude,
843 prefix).getFiles();
839 844
840 845 std::string ref, refName; std::string ref, refName;
841 846 if (!shouldCapture || !capture(importedFiles, ref, refName)) { if (!shouldCapture || !capture(importedFiles, ref, refName)) {
File tests/sub_commands.cpp changed (mode: 100644) (index 3699987..f0abc5a)
... ... TEST_CASE("Unexecuted files can be excluded",
1132 1132 CHECK(build->getPaths().size() == 2U); CHECK(build->getPaths().size() == 2U);
1133 1133 } }
1134 1134
1135 TEST_CASE("new-gcovi --prefix", "[subcommands][new-gcovi-subcommand]")
1136 {
1137 const std::string newBuildInfo =
1138 "Build: #4, 100.00%(0/0), 0.0000%(-2/ 0/ -2), master\n";
1139
1140 Repository repo("tests/test-repo");
1141 const std::string dbPath = repo.getGitPath() + "/uncov.sqlite";
1142 FileRestorer databaseRestorer(dbPath, dbPath + "_original");
1143 DB db(dbPath);
1144 BuildHistory bh(db);
1145
1146 auto runner = [](std::vector<std::string> &&/*cmd*/,
1147 const std::string &dir) {
1148 std::ofstream{dir + "/subdir#file.gcov"}
1149 << "file:file.cpp\n";
1150 };
1151 GcovImporter::setRunner(runner);
1152
1153 StreamCapture coutCapture(std::cout), cerrCapture(std::cerr);
1154 CHECK(getCmd("new-gcovi")->exec(getSettings(), bh, repo, "new-gcovi",
1155 { "--prefix=subdir",
1156 "tests/test-repo" }) == EXIT_SUCCESS);
1157 CHECK(coutCapture.get() == newBuildInfo);
1158 CHECK(cerrCapture.get() == std::string());
1159
1160 boost::optional<Build> build = bh.getBuild(4);
1161 REQUIRE(build);
1162 CHECK(build->getPaths().size() == 3U);
1163 }
1164
1135 1165 TEST_CASE("Executed files can be excluded", TEST_CASE("Executed files can be excluded",
1136 1166 "[subcommands][new-gcovi-subcommand]") "[subcommands][new-gcovi-subcommand]")
1137 1167 { {
Hints

Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://code.reversed.top/user/xaizek/uncov

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/uncov

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master