1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
use clap::ValueEnum;
/// A project that this tool can generate and analyze mutants for.
#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
pub enum Project {
/// Bitcoin Core (https://github.com/bitcoin/bitcoin)
#[value(name = "bitcoin-core")]
BitcoinCore,
/// libsecp256k1 (https://github.com/bitcoin-core/secp256k1)
#[value(name = "secp256k1")]
Secp256k1,
}
impl Default for Project {
fn default() -> Self {
Project::BitcoinCore
}
}
impl Project {
/// The upstream repository URL for this project.
pub fn repository_url(&self) -> &'static str {
match self {
Project::BitcoinCore => "https://github.com/bitcoin/bitcoin",
Project::Secp256k1 => "https://github.com/bitcoin-core/secp256k1",
}
}
/// The name used for this project in the SQLite `projects` table.
pub fn db_name(&self) -> &'static str {
match self {
Project::BitcoinCore => "Bitcoin Core",
Project::Secp256k1 => "secp256k1",
}
}
/// Returns true if the given changed-file path should be excluded from
/// mutation. Documentation, tooling, benchmarks and other non-source
/// files are not worth mutating, and the exact set differs per project
/// because each repository has its own layout and auxiliary files.
pub fn should_skip_file(&self, path: &str) -> bool {
self.skip_substrings().iter().any(|s| path.contains(s))
|| self.skip_suffixes().iter().any(|s| path.ends_with(s))
}
/// Path substrings that mark a file as non-source for this project.
fn skip_substrings(&self) -> &'static [&'static str] {
match self {
Project::BitcoinCore => &[
"doc",
"contrib",
"fuzz",
"bench",
"util",
"sanitizer_supressions",
"test_framework.py",
],
Project::Secp256k1 => &[
// e.g. tests_impl and bench_impl
"tests_",
"bench_",
"doc",
"contrib",
"examples",
"ci",
"tools",
"bench",
],
}
}
/// File suffixes that mark a file as non-source for this project.
fn skip_suffixes(&self) -> &'static [&'static str] {
match self {
Project::BitcoinCore => &[".txt"],
// CMakeLists.txt, *.md, configure.ac, Makefile.am, etc.
Project::Secp256k1 => &[".txt", ".md", ".ac", ".am"],
}
}
}