34 #include <cstring> |
34 #include <cstring> |
35 #include <cerrno> |
35 #include <cerrno> |
36 |
36 |
37 using namespace std::chrono; |
37 using namespace std::chrono; |
38 |
38 |
|
39 static constexpr auto program_version = "1.0.0"; |
|
40 |
39 static void print_help() { |
41 static void print_help() { |
40 fputs( |
42 fputs( |
41 "Usage: repoheat [OPTION]... [PATH]...\n\n" |
43 "Usage: repoheat [OPTION]... [PATH]...\n\n" |
42 "Options:\n" |
44 "Options:\n" |
43 " -a, --author <name> Only report this author\n" |
45 " -a, --author <name> Only report this author\n" |
46 " -d, --depth <num> The search depth (default: 1, max: 255)\n" |
48 " -d, --depth <num> The search depth (default: 1, max: 255)\n" |
47 " -f, --fragment Output as fragment\n" |
49 " -f, --fragment Output as fragment\n" |
48 " -h, --help Print this help message\n" |
50 " -h, --help Print this help message\n" |
49 " -p, --pull Try to pull the repositories\n" |
51 " -p, --pull Try to pull the repositories\n" |
50 " -s, --separate Output a separate heat map for each repository\n" |
52 " -s, --separate Output a separate heat map for each repository\n" |
|
53 " -V, --version Output the version of this program and exit\n" |
51 " -y, --year <year> The year for which to create the heat map\n" |
54 " -y, --year <year> The year for which to create the heat map\n" |
52 " --hg <path> Path to hg binary (default: /usr/bin/hg)\n" |
55 " --hg <path> Path to hg binary (default: /usr/bin/hg)\n" |
53 " --git <path> Path to git binary (default: /usr/bin/git)\n\n" |
56 " --git <path> Path to git binary (default: /usr/bin/git)\n\n" |
54 "Scans all specified paths recursively for Mercurial and Git repositories and\n" |
57 "Scans all specified paths recursively for Mercurial and Git repositories and\n" |
55 "creates a commit heat map for the specified \033[1myear\033[22m or the current year.\n" |
58 "creates a commit heat map for the specified \033[1myear\033[22m or the current year.\n" |
105 |
108 |
106 static int parse_args(fm::settings &settings, int argc, char *argv[]) { |
109 static int parse_args(fm::settings &settings, int argc, char *argv[]) { |
107 for (int i = 1; i < argc; i++) { |
110 for (int i = 1; i < argc; i++) { |
108 if (chk_arg(argv[i], "-h", "--help")) { |
111 if (chk_arg(argv[i], "-h", "--help")) { |
109 print_help(); |
112 print_help(); |
110 return -1; |
113 return 1; |
111 } else if (chk_arg(argv[i], "-d", "--depth")) { |
114 } else if (chk_arg(argv[i], "-d", "--depth")) { |
112 if (i + 1 >= argc || parse_unsigned(argv[++i], &settings.depth, 256)) { |
115 if (i + 1 >= argc || parse_unsigned(argv[++i], &settings.depth, 256)) { |
113 fputs("missing or invalid depth\n", stderr); |
116 fputs("missing or invalid depth\n", stderr); |
114 return -1; |
117 return -1; |
115 } |
118 } |
139 } |
142 } |
140 } else { |
143 } else { |
141 fputs("missing filename for authormap\n", stderr); |
144 fputs("missing filename for authormap\n", stderr); |
142 return -1; |
145 return -1; |
143 } |
146 } |
|
147 } else if (chk_arg(argv[i], "-V", "--version")) { |
|
148 printf("repoheat version %s\n", program_version); |
|
149 return 1; |
144 } else if (chk_arg(argv[i], "--hg", nullptr)) { |
150 } else if (chk_arg(argv[i], "--hg", nullptr)) { |
145 if (i + 1 < argc) { |
151 if (i + 1 < argc) { |
146 settings.hg.assign(argv[++i]); |
152 settings.hg.assign(argv[++i]); |
147 } else { |
153 } else { |
148 fputs("--hg is expecting a path\n", stderr); |
154 fputs("--hg is expecting a path\n", stderr); |
171 } |
177 } |
172 |
178 |
173 int main(int argc, char *argv[]) { |
179 int main(int argc, char *argv[]) { |
174 // parse settings |
180 // parse settings |
175 fm::settings settings; |
181 fm::settings settings; |
176 if (parse_args(settings, argc, argv)) { |
182 if (int result = parse_args(settings, argc, argv); result != 0) { |
177 return EXIT_FAILURE; |
183 return result < 0 ? EXIT_FAILURE : EXIT_SUCCESS; |
178 } |
184 } |
179 |
185 |
180 // check hg and git |
186 // check hg and git |
181 fm::process proc; |
187 fm::process proc; |
182 proc.setbin(settings.hg); |
188 proc.setbin(settings.hg); |