pretty-git 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +51 -0
- data/README.md +11 -10
- data/README.ru.md +427 -0
- data/lib/pretty_git/analytics/languages.rb +80 -23
- data/lib/pretty_git/cli.rb +1 -1
- data/lib/pretty_git/cli_helpers.rb +19 -3
- data/lib/pretty_git/filters.rb +1 -0
- data/lib/pretty_git/git/provider.rb +8 -10
- data/lib/pretty_git/render/csv_renderer.rb +3 -1
- data/lib/pretty_git/render/languages_section.rb +7 -4
- data/lib/pretty_git/render/markdown_renderer.rb +5 -1
- data/lib/pretty_git/version.rb +1 -1
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2200709c51eb32592b4fe79a3acea35178fab498dbd781edcc4237ceabfa00c7
|
4
|
+
data.tar.gz: c83bdd9cb01c5b345dfa52f0f1d35a03ed167a78307a6a085819453d96c88293
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1d23439b48405024896bec5e173a8573ce0b8fb1b8d1872b98d0201d4cceb85bd07f246f0d2e0a406d1c9f25d40f903280536b32e8dd030dfb04f801bc617d32
|
7
|
+
data.tar.gz: 3137c6d5b19ecbc496f14c9db9395a598d7e7bb8f33f5863db6eb8f3bf9141db141bd2429b8346101a53d79b4a4d687a4b430ad252e1f99bc58f1f2ea0bc6ac4
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
|
6
|
+
|
7
|
+
## [Unreleased]
|
8
|
+
|
9
|
+
|
10
|
+
## [0.1.2] - 2025-08-13
|
11
|
+
### Added
|
12
|
+
- Languages report: support multiple metrics — `bytes`, `files`, `loc`; dynamic columns in Console/CSV/Markdown; color and percent fields in output.
|
13
|
+
- CLI: `--metric` option for the `languages` report with value validation.
|
14
|
+
|
15
|
+
### Changed
|
16
|
+
- Languages: JSON language reinstated in the mapping and color scheme; sorting and percent calculations are based on the selected metric; percentages rounded to two decimals.
|
17
|
+
- Renderers: updated `csv`, `markdown`, and console renderers to work with dynamic metrics.
|
18
|
+
- Internal specs updated: `specs/output_formats.md`, `specs/cli_spec.md`, `specs/languages_map.md`.
|
19
|
+
|
20
|
+
### Fixed
|
21
|
+
- Git provider: correct commit counting — emit a new commit when a header is read and remove the record separator from the subject (`lib/pretty_git/git/provider.rb`).
|
22
|
+
- RuboCop: targeted suppressions for complex methods/classes and style fixes in `cli_helpers.rb`.
|
23
|
+
|
24
|
+
## [0.1.1] - 2025-08-13
|
25
|
+
### Changed
|
26
|
+
- Release automation: added GitHub Actions workflow to publish gem on tags and open PR to Homebrew tap (`.github/workflows/release.yml`).
|
27
|
+
- Documentation: README badges and installation instructions for Homebrew and RubyGems in `README.md` and `README.ru.md`.
|
28
|
+
- Gemspec: bounded runtime dependencies for `csv` and `rexml` to satisfy RubyGems recommendations.
|
29
|
+
|
30
|
+
### Fixed
|
31
|
+
- Homebrew formula installation stability: formula installs gem into `libexec/vendor` and wraps `pretty-git` binary to avoid file collisions on reinstall.
|
32
|
+
|
33
|
+
## [0.1.0] - 2025-08-13
|
34
|
+
### Added
|
35
|
+
- Languages report: bytes per language, percentages, sorting, limit.
|
36
|
+
- Console: colorized languages section; terminal width handling via `TerminalWidth`.
|
37
|
+
- Export: languages in Markdown/CSV/JSON/YAML/XML.
|
38
|
+
- CLI: `languages` report wired into App and renderers.
|
39
|
+
- Tests: analytics/languages specs (aggregation, globs, filename detection, limit).
|
40
|
+
- Docs: English primary `README.md` + `README.ru.md` with language switcher.
|
41
|
+
- Docs: Ignored directories and binary extensions list.
|
42
|
+
- Docs: Added screenshot `PrettyGitConsoleLanguages.png`.
|
43
|
+
|
44
|
+
### Changed
|
45
|
+
- Analytics: exclude JSON from language mapping by default to avoid data skew.
|
46
|
+
- Analytics: ignore Python env/cache directories by default.
|
47
|
+
- Refactor: `ConsoleRenderer` split (LanguagesSection, TerminalWidth); reduced complexity.
|
48
|
+
- App: extracted `analytics_for` from `App#run`.
|
49
|
+
|
50
|
+
### Fixed
|
51
|
+
- RuboCop violations in new specs and minor guard clause spacing.
|
data/README.md
CHANGED
@@ -61,19 +61,19 @@ Generator of rich reports for a local Git repository: summary, activity, authors
|
|
61
61
|
|
62
62
|
## Installation
|
63
63
|
|
64
|
-
### Homebrew (recommended)
|
64
|
+
### 🍺 Homebrew (recommended)
|
65
65
|
```bash
|
66
66
|
brew tap MikoMikocchi/tap
|
67
67
|
brew install pretty-git
|
68
68
|
```
|
69
69
|
|
70
|
-
### RubyGems
|
70
|
+
### ♦️ RubyGems
|
71
71
|
```bash
|
72
72
|
gem install pretty-git
|
73
73
|
```
|
74
74
|
Choose one:
|
75
75
|
|
76
|
-
1) From source (recommended for development)
|
76
|
+
1) 🛠️ From source (recommended for development)
|
77
77
|
|
78
78
|
```bash
|
79
79
|
git clone <repo_url>
|
@@ -83,14 +83,14 @@ bin/setup
|
|
83
83
|
bundle exec bin/pretty-git --help
|
84
84
|
```
|
85
85
|
|
86
|
-
2) As a gem (after the first release)
|
86
|
+
2) ♦️ As a gem (after the first release)
|
87
87
|
|
88
88
|
```bash
|
89
89
|
gem install pretty-git
|
90
90
|
pretty-git --version
|
91
91
|
```
|
92
92
|
|
93
|
-
3) Via Bundler
|
93
|
+
3) 📦 Via Bundler
|
94
94
|
|
95
95
|
```ruby
|
96
96
|
# Gemfile
|
@@ -134,6 +134,7 @@ Key options:
|
|
134
134
|
* **--path/--exclude-path** Filter by paths (comma-separated or repeated option)
|
135
135
|
* **--no-color** Disable colors in console
|
136
136
|
* **--theme** `basic|bright|mono` — console theme (default `basic`; `mono` forces monochrome)
|
137
|
+
* **--metric** `bytes|files|loc` — metric for `languages` report (default `bytes`)
|
137
138
|
|
138
139
|
Examples with multiple values:
|
139
140
|
|
@@ -234,7 +235,7 @@ dow,hour,commits
|
|
234
235
|
```bash
|
235
236
|
pretty-git languages . --format md --limit 10
|
236
237
|
```
|
237
|
-
Determines language distribution in a repository
|
238
|
+
Determines language distribution in a repository. Supports multiple metrics: `bytes`, `files`, `loc` (default: `bytes`). Output includes language, selected metric column, and percent share; console shows language colors.
|
238
239
|
|
239
240
|
Console example:
|
240
241
|
```text
|
@@ -252,7 +253,7 @@ Markdown 1200 1.7
|
|
252
253
|
Notes:
|
253
254
|
- **Detection**: by file extensions and certain filenames (`Makefile`, `Dockerfile`).
|
254
255
|
- **Exclusions**: binary files and "vendor"-like directories are ignored. By default `vendor/`, `node_modules/`, `.git/`, build artifacts and caches are skipped. For Python projects additional directories are skipped: `.venv/`, `venv/`, `env/`, `__pycache__/`, `.mypy_cache/`, `.pytest_cache/`, `.tox/`, `.eggs/`, `.ruff_cache/`, `.ipynb_checkpoints/`.
|
255
|
-
- **JSON**: JSON is
|
256
|
+
- **JSON**: JSON is included as a language. If large data files skew results, consider narrowing with `--path/--exclude-path`.
|
256
257
|
- **Path filters**: use `--path/--exclude-path` (glob patterns supported) to focus on relevant areas.
|
257
258
|
- **Limit**: `--limit N` restricts number of rows; `0`/`all` — no limit.
|
258
259
|
- **Console colors**: language names use approximate GitHub colors; `--no-color` disables, `--theme mono` makes output monochrome.
|
@@ -260,8 +261,8 @@ Notes:
|
|
260
261
|
See also: [Ignored directories and files](#ignored-directories-and-files).
|
261
262
|
|
262
263
|
Export:
|
263
|
-
- CSV/MD: columns — `language
|
264
|
-
- JSON/YAML/XML: full report structure including metadata (`report`, `generated_at`, `repo_path`).
|
264
|
+
- CSV/MD: columns are dynamic — `language,<metric>,percent`. Markdown also includes a `color` column.
|
265
|
+
- JSON/YAML/XML: full report structure including per-language `color` and metadata (`report`, `generated_at`, `repo_path`).
|
265
266
|
|
266
267
|
## Exports
|
267
268
|
|
@@ -291,7 +292,7 @@ _Example terminal output (theme: basic)._
|
|
291
292
|
{"report":"summary","generated_at":"2025-01-31T00:00:00Z","totals":{"commits":123}}
|
292
293
|
```
|
293
294
|
|
294
|
-
### CSV
|
295
|
+
### CSV
|
295
296
|
* **Structure**: flat table, first line is header.
|
296
297
|
* **Encoding**: UTF‑8 without BOM.
|
297
298
|
* **Delimiter**: comma `,`.
|
data/README.ru.md
ADDED
@@ -0,0 +1,427 @@
|
|
1
|
+
# Pretty Git
|
2
|
+
|
3
|
+
[](https://github.com/MikoMikocchi/pretty-git/actions/workflows/ci.yml)
|
4
|
+
[](https://rubygems.org/gems/pretty-git)
|
5
|
+
[](LICENSE)
|
6
|
+

|
7
|
+
|
8
|
+
<p align="right">
|
9
|
+
<a href="./README.md">English</a> | <b>Русский</b>
|
10
|
+
</p>
|
11
|
+
|
12
|
+
<p align="center">
|
13
|
+
<img src="docs/images/PrettyGitIcon.png" alt="Pretty Git Logo" width="200">
|
14
|
+
<br>
|
15
|
+
</p>
|
16
|
+
|
17
|
+
Генератор отчётов по локальному Git-репозиторию: сводка, активность, авторы, файлы, тепловая карта. Вывод в консоль и форматы: JSON, CSV, Markdown, YAML, XML.
|
18
|
+
|
19
|
+
— Лицензия: MIT.
|
20
|
+
|
21
|
+
## Содержание
|
22
|
+
- [Возможности](#возможности)
|
23
|
+
- [Требования](#требования)
|
24
|
+
- [Установка](#установка)
|
25
|
+
- [Быстрый старт](#быстрый-старт)
|
26
|
+
- [CLI и параметры](#cli-и-параметры)
|
27
|
+
- [Фильтры](#фильтры)
|
28
|
+
- [Формат вывода](#формат-вывода)
|
29
|
+
- [Вывод в файл](#вывод-в-файл)
|
30
|
+
- [Коды возврата](#коды-возврата)
|
31
|
+
- [Отчёты и примеры](#отчёты-и-примеры)
|
32
|
+
- [summary — сводка](#summary--сводка)
|
33
|
+
- [activity — активность (day/week/month)](#activity--активность-dayweekmonth)
|
34
|
+
- [authors — по авторам](#authors--по-авторам)
|
35
|
+
- [files — по файлам](#files--по-файлам)
|
36
|
+
- [heatmap — тепловая карта](#heatmap--тепловая-карта)
|
37
|
+
- [languages — языки](#languages--языки)
|
38
|
+
- [Экспорт в форматы](#экспорт-в-форматы)
|
39
|
+
- [Console](#console)
|
40
|
+
- [JSON](#json)
|
41
|
+
- [CSV (DR-001)](#csv-dr-001)
|
42
|
+
- [Markdown](#markdown)
|
43
|
+
- [YAML](#yaml)
|
44
|
+
- [XML](#xml)
|
45
|
+
- [Детерминизм и сортировка](#детерминизм-и-сортировка)
|
46
|
+
- [Советы по Windows](#советы-по-windows)
|
47
|
+
- [Диагностика и ошибки](#диагностика-и-ошибки)
|
48
|
+
- [FAQ](#faq)
|
49
|
+
- [Разработка](#разработка)
|
50
|
+
- [Лицензия](#лицензия)
|
51
|
+
|
52
|
+
## Возможности
|
53
|
+
* __Отчёты__: `summary`, `activity`, `authors`, `files`, `heatmap`, `languages`.
|
54
|
+
* __Фильтры__: ветки, авторы, пути, период времени.
|
55
|
+
* __Экспорт__: `console`, `json`, `csv`, `md`, `yaml`, `xml`.
|
56
|
+
* __Вывод__: в stdout или файл через `--out`.
|
57
|
+
|
58
|
+
## Требования
|
59
|
+
* __Ruby__: >= 3.4 (рекомендуется 3.4.x)
|
60
|
+
* __Git__: установлен и доступен в `PATH`
|
61
|
+
|
62
|
+
## Установка
|
63
|
+
|
64
|
+
### 🍺 Homebrew (рекомендуется)
|
65
|
+
```bash
|
66
|
+
brew tap MikoMikocchi/tap
|
67
|
+
brew install pretty-git
|
68
|
+
```
|
69
|
+
|
70
|
+
### ♦️ RubyGems
|
71
|
+
```bash
|
72
|
+
gem install pretty-git
|
73
|
+
```
|
74
|
+
Выберите один из вариантов:
|
75
|
+
|
76
|
+
1) 🛠️ Локально из исходников (рекомендуется для разработки)
|
77
|
+
|
78
|
+
```bash
|
79
|
+
git clone <repo_url>
|
80
|
+
cd pretty-git
|
81
|
+
bin/setup
|
82
|
+
# запуск:
|
83
|
+
bundle exec bin/pretty-git --help
|
84
|
+
```
|
85
|
+
|
86
|
+
2) ♦️ Как gem (после первого релиза)
|
87
|
+
|
88
|
+
```bash
|
89
|
+
gem install pretty-git
|
90
|
+
pretty-git --version
|
91
|
+
```
|
92
|
+
|
93
|
+
3) 📦 Использование через Bundler
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
# Gemfile
|
97
|
+
gem 'pretty-git', '~> 0.1'
|
98
|
+
```
|
99
|
+
```bash
|
100
|
+
bundle install
|
101
|
+
bundle exec pretty-git --help
|
102
|
+
```
|
103
|
+
|
104
|
+
## Быстрый старт
|
105
|
+
```bash
|
106
|
+
# Сводка репозитория в консоль
|
107
|
+
bundle exec bin/pretty-git summary .
|
108
|
+
|
109
|
+
# Авторы в JSON и запись в файл
|
110
|
+
bundle exec bin/pretty-git authors . --format json --out authors.json
|
111
|
+
|
112
|
+
# Активность по неделям за период и только по указанным путям
|
113
|
+
bundle exec bin/pretty-git activity . --time-bucket week --since 2025-01-01 \
|
114
|
+
--paths app,lib --format csv --out activity.csv
|
115
|
+
```
|
116
|
+
|
117
|
+
## CLI и параметры
|
118
|
+
Общий вид:
|
119
|
+
|
120
|
+
```bash
|
121
|
+
pretty-git <report> <repo_path> [options]
|
122
|
+
```
|
123
|
+
|
124
|
+
Доступные отчёты: `summary`, `activity`, `authors`, `files`, `heatmap`, `languages`.
|
125
|
+
|
126
|
+
Ключевые опции:
|
127
|
+
* __--format, -f__ `console|json|csv|md|yaml|xml` (по умолчанию `console`)
|
128
|
+
* __--out, -o__ Путь для записи в файл
|
129
|
+
* __--limit, -l__ Число элементов в топах/выводе; `all` или `0` — без ограничения
|
130
|
+
* __--time-bucket__ `day|week|month` (для `activity`)
|
131
|
+
* __--since/--until__ Дата/время в ISO8601 или `YYYY-MM-DD` (DR-005)
|
132
|
+
* __--branch__ Мульти-опция, можно указывать несколько веток
|
133
|
+
* __--author/--exclude-author__ Фильтрация по авторам
|
134
|
+
* __--path/--exclude-path__ Фильтрация по путям (через запятую или повтор опции)
|
135
|
+
* __--no-color__ Отключить цвета в консоли
|
136
|
+
* __--theme__ `basic|bright|mono` — тема оформления консольного вывода (по умолчанию `basic`; `mono` принудительно отключает цвета)
|
137
|
+
* __--metric__ `bytes|files|loc` — метрика для отчёта `languages` (по умолчанию `bytes`)
|
138
|
+
|
139
|
+
Примеры значений с несколькими параметрами:
|
140
|
+
|
141
|
+
```bash
|
142
|
+
# Несколько веток
|
143
|
+
pretty-git summary . --branch main --branch develop
|
144
|
+
|
145
|
+
# Фильтрация по авторам (включая/исключая)
|
146
|
+
pretty-git authors . --author alice@example.com --exclude-author bot@company
|
147
|
+
|
148
|
+
# Фильтрация по путям
|
149
|
+
pretty-git files . --path app,lib --exclude-path vendor,node_modules
|
150
|
+
```
|
151
|
+
|
152
|
+
### Фильтры
|
153
|
+
Фильтры применяются на этапе выборки коммитов и последующей агрегации. Формат дат: ISO8601 или `YYYY-MM-DD`. Если часовой пояс не указан — используется локальная зона пользователя; на выводе время нормализуется к UTC.
|
154
|
+
|
155
|
+
### Формат вывода
|
156
|
+
Задаётся через `--format`. Для файловых форматов рекомендуется использовать `--out`.
|
157
|
+
|
158
|
+
### Вывод в файл
|
159
|
+
```bash
|
160
|
+
pretty-git authors . --format csv --out authors.csv
|
161
|
+
```
|
162
|
+
|
163
|
+
### Коды возврата
|
164
|
+
* `0` — успех
|
165
|
+
* `1` — ошибка пользователя (неизвестный отчёт/формат, неверные аргументы)
|
166
|
+
* `2` — системная ошибка (ошибка Git и пр.)
|
167
|
+
|
168
|
+
## Отчёты и примеры
|
169
|
+
|
170
|
+
### summary — сводка
|
171
|
+
```bash
|
172
|
+
pretty-git summary . --format json
|
173
|
+
```
|
174
|
+
Содержит totals (commits, authors, additions, deletions) и топы по авторам/файлам.
|
175
|
+
|
176
|
+
### activity — активность (day/week/month)
|
177
|
+
```bash
|
178
|
+
pretty-git activity . --time-bucket week --format csv
|
179
|
+
```
|
180
|
+
CSV-колонки: `bucket,timestamp,commits,additions,deletions`.
|
181
|
+
Пример JSON:
|
182
|
+
```json
|
183
|
+
[
|
184
|
+
{"bucket":"week","timestamp":"2025-06-02T00:00:00Z","commits":120,"additions":3456,"deletions":2100},
|
185
|
+
{"bucket":"week","timestamp":"2025-06-09T00:00:00Z","commits":98,"additions":2890,"deletions":1760}
|
186
|
+
]
|
187
|
+
```
|
188
|
+
|
189
|
+
### authors — по авторам
|
190
|
+
```bash
|
191
|
+
pretty-git authors . --format md --limit 10
|
192
|
+
```
|
193
|
+
CSV-колонки: `author,author_email,commits,additions,deletions,avg_commit_size`.
|
194
|
+
Пример Markdown:
|
195
|
+
```markdown
|
196
|
+
| author | author_email | commits | additions | deletions | avg_commit_size |
|
197
|
+
|---|---|---:|---:|---:|---:|
|
198
|
+
| Alice | a@example.com | 2 | 5 | 1 | 3.0 |
|
199
|
+
| Bob | b@example.com | 1 | 2 | 0 | 2.0 |
|
200
|
+
```
|
201
|
+
|
202
|
+
### files — по файлам
|
203
|
+
```bash
|
204
|
+
pretty-git files . --paths app,lib --format csv
|
205
|
+
```
|
206
|
+
CSV-колонки: `path,commits,additions,deletions,changes`.
|
207
|
+
Пример XML:
|
208
|
+
```xml
|
209
|
+
<files>
|
210
|
+
<item path="app/models/user.rb" commits="42" additions="2100" deletions="1400" changes="3500" />
|
211
|
+
<item path="app/services/auth.rb" commits="35" additions="1500" deletions="900" changes="2400" />
|
212
|
+
<generated_at>2025-01-31T00:00:00Z</generated_at>
|
213
|
+
<repo_path>/abs/path/to/repo</repo_path>
|
214
|
+
<report>files</report>
|
215
|
+
<period>
|
216
|
+
<since/>
|
217
|
+
<until/>
|
218
|
+
</period>
|
219
|
+
</files>
|
220
|
+
```
|
221
|
+
|
222
|
+
### heatmap — тепловая карта
|
223
|
+
```bash
|
224
|
+
pretty-git heatmap . --format json
|
225
|
+
```
|
226
|
+
JSON: массив бакетов по (день недели × час) с числом коммитов.
|
227
|
+
Пример CSV:
|
228
|
+
```csv
|
229
|
+
dow,hour,commits
|
230
|
+
1,10,5
|
231
|
+
1,11,7
|
232
|
+
```
|
233
|
+
|
234
|
+
### languages — языки
|
235
|
+
```bash
|
236
|
+
pretty-git languages . --format md --limit 10
|
237
|
+
```
|
238
|
+
Определяет распределение языков в репозитории. Поддерживаются несколько метрик: `bytes`, `files`, `loc` (по умолчанию: `bytes`). Вывод включает язык, выбранную метрику и долю в процентах; в консоли отображаются цвета языков.
|
239
|
+
|
240
|
+
Пример консольного вывода:
|
241
|
+
```text
|
242
|
+
Languages for .
|
243
|
+
|
244
|
+
language bytes percent
|
245
|
+
-------- ---------- -------
|
246
|
+
Ruby 123456 60.0
|
247
|
+
JavaScript 78901 38.3
|
248
|
+
Markdown 1200 1.7
|
249
|
+
```
|
250
|
+
|
251
|
+

|
252
|
+
|
253
|
+
Замечания:
|
254
|
+
- __Определение языка__: по расширениям файлов и некоторым именам файлов (`Makefile`, `Dockerfile`).
|
255
|
+
- __Исключения__: бинарные файлы и "vendor"‑директории игнорируются. По умолчанию пропускаются `vendor/`, `node_modules/`, `.git/`, артефакты сборки и кэши. Для Python дополнительно исключаются `.venv/`, `venv/`, `env/`, `__pycache__/`, `.mypy_cache/`, `.pytest_cache/`, `.tox/`, `.eggs/`, `.ruff_cache/`, `.ipynb_checkpoints/`.
|
256
|
+
- __JSON__: JSON включён как язык. Если крупные файлы данных искажают картину, сузьте область `--path/--exclude-path`.
|
257
|
+
- __Фильтры путей__: используйте `--path/--exclude-path` (поддерживаются glob‑маски), чтобы сосредоточиться на соответствующих директориях.
|
258
|
+
- __Лимит__: `--limit N` ограничивает число строк в итоговой таблице; `0`/`all` — без ограничения.
|
259
|
+
- __Цвета в консоли__: имена языков подсвечиваются приблизительными цветами GitHub; `--no-color` отключает, `--theme mono` делает монохром.
|
260
|
+
|
261
|
+
Экспорт:
|
262
|
+
- CSV/MD: колонки динамические — `language,<metric>,percent`. В Markdown дополнительно присутствует колонка `color`.
|
263
|
+
- JSON/YAML/XML: полная структура отчёта, включая `color` на язык и метаданные (`report`, `generated_at`, `repo_path`).
|
264
|
+
|
265
|
+
## Игнорируемые директории и файлы
|
266
|
+
|
267
|
+
Чтобы статистика по языкам оставалась релевантной, некоторые директории и типы файлов пропускаются по умолчанию.
|
268
|
+
|
269
|
+
**Игнорируемые директории** (если сегмент пути совпадает):
|
270
|
+
|
271
|
+
```
|
272
|
+
vendor, node_modules, .git, .bundle, dist, build, out, target, coverage,
|
273
|
+
.venv, venv, env, __pycache__, .mypy_cache, .pytest_cache, .tox, .eggs, .ruff_cache,
|
274
|
+
.ipynb_checkpoints
|
275
|
+
```
|
276
|
+
|
277
|
+
**Игнорируемые бинарные/данные расширения**:
|
278
|
+
|
279
|
+
```
|
280
|
+
.png, .jpg, .jpeg, .gif, .svg, .webp, .ico, .bmp,
|
281
|
+
.pdf, .zip, .tar, .gz, .tgz, .bz2, .7z, .rar,
|
282
|
+
.mp3, .ogg, .wav, .mp4, .mov, .avi, .mkv,
|
283
|
+
.woff, .woff2, .ttf, .otf, .eot,
|
284
|
+
.jar, .class, .dll, .so, .dylib,
|
285
|
+
.exe, .bin, .dat
|
286
|
+
```
|
287
|
+
|
288
|
+
Списки соответствуют реализации в `lib/pretty_git/analytics/languages.rb` и могут изменяться.
|
289
|
+
|
290
|
+
## Экспорт в форматы
|
291
|
+
|
292
|
+
Ниже — точные правила сериализации для каждого формата, чтобы обеспечивалась совместимость с популярными инструментами (Excel, BI, CI и т.п.).
|
293
|
+
|
294
|
+
### Console
|
295
|
+

|
296
|
+
_Пример вывода в терминале (тема: basic)._
|
297
|
+
* __Цвета__: заголовки и шапки таблиц подсвечены; суммы: `commits` — жёлтым, `+additions` — зелёным, `-deletions` — красным. `--no-color` полностью отключает раскраску.
|
298
|
+
* __Темы__: `--theme basic|bright|mono`. `bright` — более насыщенные заголовки, `mono` — монохром (аналогично `--no-color`).
|
299
|
+
* __Выделение максимума__: на числовых колонках максимальные значения подчёркиваются жирным для быстрого сканирования.
|
300
|
+
* __Ширина терминала__: при выводе таблиц автоматически учитывается ширина терминала. Если ширины не хватает, первый столбец аккуратно обрезается с многоточием `…`.
|
301
|
+
* __Кодировка__: UTF‑8, переводы строк LF.
|
302
|
+
* __Назначение__: человекочитаемый вывод в терминал.
|
303
|
+
* __Оформление__: таблицы с границами, авто-обрезка длинных значений.
|
304
|
+
* __Цвета__: включены, если есть TTY; отключаются `--no-color`.
|
305
|
+
* __Пустые наборы__: печатается `No data`.
|
306
|
+
* __Кодировка/переводы строк__: UTF‑8, LF (`\n`).
|
307
|
+
|
308
|
+
### JSON
|
309
|
+
* __Ключи__: `snake_case`.
|
310
|
+
* __Числа__: целые/вещественные без локализации (точка как разделитель).
|
311
|
+
* __Булевы__: `true/false`; __null__: `null`.
|
312
|
+
* __Даты/время__: ISO8601 в UTC, например `2025-01-31T00:00:00Z`.
|
313
|
+
* __Порядок__: поля в объектах стабильно упорядочены логически (например, `report`, `generated_at`, `repo_path`, затем данные).
|
314
|
+
* __Кодировка/переводы строк__: UTF‑8, LF.
|
315
|
+
* __Рекомендуемое расширение__: `.json`.
|
316
|
+
* __Пример__:
|
317
|
+
```json
|
318
|
+
{"report":"summary","generated_at":"2025-01-31T00:00:00Z","totals":{"commits":123}}
|
319
|
+
```
|
320
|
+
|
321
|
+
### CSV
|
322
|
+
* __Структура__: плоская таблица, первая строка — заголовок.
|
323
|
+
* __Кодировка__: UTF‑8, без BOM.
|
324
|
+
* __Разделитель__: запятая `,`.
|
325
|
+
* __Экранирование__: по RFC 4180 — поля с запятыми/кавычками/переводами строк заключаются в двойные кавычки, двойные кавычки внутри поля удваиваются.
|
326
|
+
* __Пустые значения__: пустая ячейка (не `null`).
|
327
|
+
* __Числа__: без тысячных разделителей, десятичная точка.
|
328
|
+
* __Даты/время__: ISO8601 UTC.
|
329
|
+
* __Порядок колонок__: фиксирован на отчёт и стабилен.
|
330
|
+
* __Переводы строк__: LF.
|
331
|
+
* __Рекомендуемое расширение__: `.csv`.
|
332
|
+
* __Открытие в Excel__: указывайте кодировку UTF‑8 при импорте.
|
333
|
+
* __Пример__:
|
334
|
+
```csv
|
335
|
+
author,author_email,commits,additions,deletions,avg_commit_size
|
336
|
+
Alice,a@example.com,2,5,1,3.0
|
337
|
+
Bob,b@example.com,1,2,0,2.0
|
338
|
+
```
|
339
|
+
|
340
|
+
### Markdown
|
341
|
+
* __Таблицы__: стандартный синтаксис GitHub Flavored Markdown.
|
342
|
+
* __Выравнивание__: числовые колонки выравниваются по правому краю (`---:`).
|
343
|
+
* __Кодировка/переводы строк__: UTF‑8, LF.
|
344
|
+
* __Рекомендуемое расширение__: `.md`.
|
345
|
+
* __Пустые наборы__: таблица с заголовком и без строк либо краткое сообщение `No data` (в зависимости от отчёта).
|
346
|
+
* __Пример__:
|
347
|
+
```markdown
|
348
|
+
| path | commits | additions | deletions |
|
349
|
+
|---|---:|---:|---:|
|
350
|
+
| app/models/user.rb | 42 | 2100 | 1400 |
|
351
|
+
```
|
352
|
+
|
353
|
+
### YAML
|
354
|
+
* __Структура__: полная иерархия результата.
|
355
|
+
* __Ключи__: сериализуются строками.
|
356
|
+
* __Числа/булевы/null__: стандарт YAML (`123`, `true/false`, `null`).
|
357
|
+
* __Даты/время__: ISO8601 UTC как строки.
|
358
|
+
* __Кодировка/переводы строк__: UTF‑8, LF.
|
359
|
+
* __Рекомендуемое расширение__: `.yml` или `.yaml`.
|
360
|
+
* __Пример__:
|
361
|
+
```yaml
|
362
|
+
report: authors
|
363
|
+
generated_at: "2025-01-31T00:00:00Z"
|
364
|
+
items:
|
365
|
+
- author: Alice
|
366
|
+
author_email: a@example.com
|
367
|
+
commits: 2
|
368
|
+
- author: Bob
|
369
|
+
author_email: b@example.com
|
370
|
+
commits: 1
|
371
|
+
```
|
372
|
+
|
373
|
+
### XML
|
374
|
+
* __Структура__: элементы соответствуют ключам; массивы — повторяющиеся `<item>` или специализированные теги.
|
375
|
+
* __Атрибуты__: для компактных записей (например, строк файлового отчёта) основные поля могут быть атрибутами элемента.
|
376
|
+
* __Текстовые узлы__: применяются для скалярных значений при необходимости.
|
377
|
+
* __Экранирование__: `& < > " ' ` по правилам XML, при необходимости CDATA для произвольного текста.
|
378
|
+
* __Даты/время__: ISO8601 UTC.
|
379
|
+
* __Кодировка/переводы строк__: UTF‑8, LF; декларация `<?xml version="1.0" encoding="UTF-8"?>` может добавляться генератором.
|
380
|
+
* __Рекомендуемое расширение__: `.xml`.
|
381
|
+
* __Пример__:
|
382
|
+
```xml
|
383
|
+
<authors>
|
384
|
+
<item author="Alice" author_email="a@example.com" commits="2" />
|
385
|
+
<item author="Bob" author_email="b@example.com" commits="1" />
|
386
|
+
<generated_at>2025-01-31T00:00:00Z</generated_at>
|
387
|
+
<repo_path>/abs/path</repo_path>
|
388
|
+
</authors>
|
389
|
+
```
|
390
|
+
|
391
|
+
## Детерминизм и сортировка
|
392
|
+
Вывод детерминирован при одинаковых входных данных. Сортировка для файлов/авторов: по количеству изменений (desc), затем по числу коммитов (desc), затем по пути/имени (asc). Лимиты применяются поверх отсортированного списка; значение `all` или `0` означает отсутствие ограничения.
|
393
|
+
|
394
|
+
## Советы по Windows
|
395
|
+
Целевая платформа — macOS/Linux. Windows поддерживается в режиме best‑effort:
|
396
|
+
* Запуск через Git Bash/WSL допустим
|
397
|
+
* Цвета можно отключить `--no-color`
|
398
|
+
* Аккуратное квотирование аргументов при работе с путями
|
399
|
+
|
400
|
+
## Диагностика и ошибки
|
401
|
+
Типичные ошибки и решения:
|
402
|
+
|
403
|
+
* __Неизвестный отчёт/формат__ — проверьте значение первого аргумента и `--format`.
|
404
|
+
* __Неверный формат даты__ — используйте ISO8601 или `YYYY-MM-DD` (например, `2025-01-31` или `2025-01-31T12:00:00Z`).
|
405
|
+
* __Git недоступен__ — убедитесь, что `git` установлен и доступен в `PATH`.
|
406
|
+
* __Пустой результат__ — проверьте фильтры (`--since/--until`, `--branch`, `--path`), возможно, выборка слишком узкая.
|
407
|
+
* __Проблемы с кодировкой CSV__ — файлы сохраняются в UTF‑8, при открытии в Excel выбирайте UTF‑8.
|
408
|
+
|
409
|
+
## FAQ
|
410
|
+
* __Почему Ruby 3.4+?__ Проект использует зависимости, согласованные с версией 3.4+, и ориентируется на актуальную экосистему.
|
411
|
+
* __Можно ли добавить новые форматы?__ Да, добавьте рендерер в `lib/pretty_git/render/` и зарегистрируйте его в приложении.
|
412
|
+
* __Откуда берутся данные?__ Из системного `git` через вызовы CLI.
|
413
|
+
|
414
|
+
## Разработка
|
415
|
+
```bash
|
416
|
+
# Установка зависимостей
|
417
|
+
bin/setup
|
418
|
+
|
419
|
+
# Запуск тестов и линтера
|
420
|
+
bundle exec rspec
|
421
|
+
bundle exec rubocop
|
422
|
+
```
|
423
|
+
|
424
|
+
Стиль — RuboCop без ошибок. Тесты покрывают агрегаторы, рендереры, CLI и интеграционные сценарии (детерминизм, корректность форматов).
|
425
|
+
|
426
|
+
## Лицензия
|
427
|
+
MIT © Contributors
|
@@ -15,7 +15,7 @@ module PrettyGit
|
|
15
15
|
'.sh' => 'Shell', '.bash' => 'Shell', '.zsh' => 'Shell',
|
16
16
|
'.ps1' => 'PowerShell', '.psm1' => 'PowerShell',
|
17
17
|
'.bat' => 'Batchfile', '.cmd' => 'Batchfile',
|
18
|
-
|
18
|
+
'.json' => 'JSON',
|
19
19
|
'.yml' => 'YAML', '.yaml' => 'YAML', '.toml' => 'TOML', '.ini' => 'INI', '.xml' => 'XML',
|
20
20
|
'.html' => 'HTML', '.htm' => 'HTML', '.css' => 'CSS', '.scss' => 'SCSS', '.sass' => 'SCSS',
|
21
21
|
'.md' => 'Markdown', '.markdown' => 'Markdown',
|
@@ -43,6 +43,25 @@ module PrettyGit
|
|
43
43
|
'Dockerfile' => 'Dockerfile'
|
44
44
|
}.freeze
|
45
45
|
|
46
|
+
# Language → HEX color (without leading #) for exports (CSV/JSON/YAML/XML)
|
47
|
+
LANG_HEX_COLORS = {
|
48
|
+
'Ruby' => 'cc342d',
|
49
|
+
'JavaScript' => 'f1e05a', 'TypeScript' => '3178c6',
|
50
|
+
'JSX' => 'f1e05a', 'TSX' => '3178c6',
|
51
|
+
'Python' => '3572a5', 'Go' => '00add8', 'Rust' => 'dea584', 'Java' => 'b07219',
|
52
|
+
'C' => '555555', 'C++' => 'f34b7d', 'C#' => '178600', 'Objective-C' => '438eff', 'Swift' => 'ffac45',
|
53
|
+
'Kotlin' => 'a97bff', 'Scala' => 'c22d40', 'Groovy' => 'e69f56', 'Dart' => '00b4ab',
|
54
|
+
'PHP' => '4f5d95', 'Perl' => '0298c3', 'R' => '198ce7', 'Lua' => '000080', 'Haskell' => '5e5086',
|
55
|
+
'Elixir' => '6e4a7e', 'Erlang' => 'b83998',
|
56
|
+
'Shell' => '89e051', 'PowerShell' => '012456', 'Batchfile' => 'c1f12e',
|
57
|
+
'HTML' => 'e34c26', 'CSS' => '563d7c', 'SCSS' => 'c6538c',
|
58
|
+
'JSON' => 'eeeeee',
|
59
|
+
'YAML' => 'cb171e', 'TOML' => '9c4221', 'INI' => '6b7280', 'XML' => '0060ac',
|
60
|
+
'Markdown' => '083fa1', 'Makefile' => '427819', 'Dockerfile' => '384d54',
|
61
|
+
'SQL' => 'e38c00', 'GraphQL' => 'e10098', 'Proto' => '3b5998',
|
62
|
+
'Svelte' => 'ff3e00', 'Vue' => '41b883'
|
63
|
+
}.freeze
|
64
|
+
|
46
65
|
VENDOR_DIRS = %w[
|
47
66
|
vendor node_modules .git .bundle dist build out target coverage
|
48
67
|
.venv venv env __pycache__ .mypy_cache .pytest_cache .tox .eggs .ruff_cache
|
@@ -56,21 +75,25 @@ module PrettyGit
|
|
56
75
|
.jar .class .dll .so .dylib
|
57
76
|
.exe .bin .dat
|
58
77
|
].freeze
|
59
|
-
# Computes language distribution by
|
60
|
-
#
|
78
|
+
# Computes language distribution by bytes, files, and LOC per language.
|
79
|
+
# Default metric: bytes (similar to GitHub Linguist approach).
|
80
|
+
# rubocop:disable Metrics/ClassLength
|
61
81
|
class Languages
|
62
82
|
def self.call(_enum, filters)
|
63
83
|
repo = filters.repo_path
|
64
84
|
items = calculate(repo, include_globs: filters.paths, exclude_globs: filters.exclude_paths)
|
65
|
-
|
66
|
-
|
67
|
-
items =
|
85
|
+
metric = (filters.metric || 'bytes').to_s
|
86
|
+
totals = compute_totals(items)
|
87
|
+
items = add_percents(items, totals, metric)
|
88
|
+
items = add_colors(items)
|
89
|
+
items = sort_and_limit(items, filters.limit, metric)
|
68
90
|
|
69
|
-
build_result(repo, items,
|
91
|
+
build_result(repo, items, totals, metric)
|
70
92
|
end
|
71
93
|
|
94
|
+
# rubocop:disable Metrics/AbcSize
|
72
95
|
def self.calculate(repo_path, include_globs:, exclude_globs:)
|
73
|
-
by_lang = Hash.new
|
96
|
+
by_lang = Hash.new { |h, k| h[k] = { bytes: 0, files: 0, loc: 0 } }
|
74
97
|
Dir.chdir(repo_path) do
|
75
98
|
each_source_file(include_globs, exclude_globs) do |abs_path|
|
76
99
|
basename = File.basename(abs_path)
|
@@ -78,16 +101,17 @@ module PrettyGit
|
|
78
101
|
lang = FILENAME_TO_LANG[basename] || EXT_TO_LANG[ext]
|
79
102
|
next unless lang
|
80
103
|
|
81
|
-
size =
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
104
|
+
size = safe_file_size(abs_path)
|
105
|
+
lines = safe_count_lines(abs_path)
|
106
|
+
agg = by_lang[lang]
|
107
|
+
agg[:bytes] += size
|
108
|
+
agg[:files] += 1
|
109
|
+
agg[:loc] += lines
|
87
110
|
end
|
88
111
|
end
|
89
|
-
by_lang.map { |lang,
|
112
|
+
by_lang.map { |lang, h| { language: lang, bytes: h[:bytes], files: h[:files], loc: h[:loc] } }
|
90
113
|
end
|
114
|
+
# rubocop:enable Metrics/AbcSize
|
91
115
|
|
92
116
|
def self.each_source_file(include_globs, exclude_globs)
|
93
117
|
# Build list of files under repo respecting includes/excludes
|
@@ -98,6 +122,20 @@ module PrettyGit
|
|
98
122
|
files.each { |rel| yield File.expand_path(rel) }
|
99
123
|
end
|
100
124
|
|
125
|
+
def self.safe_file_size(path)
|
126
|
+
File.size(path)
|
127
|
+
rescue StandardError
|
128
|
+
0
|
129
|
+
end
|
130
|
+
|
131
|
+
def self.safe_count_lines(path)
|
132
|
+
count = 0
|
133
|
+
File.foreach(path) { |_l| count += 1 }
|
134
|
+
count
|
135
|
+
rescue StandardError
|
136
|
+
0
|
137
|
+
end
|
138
|
+
|
101
139
|
def self.filter_includes(files, globs)
|
102
140
|
globs = Array(globs).compact
|
103
141
|
return files if globs.empty?
|
@@ -123,33 +161,52 @@ module PrettyGit
|
|
123
161
|
BINARY_EXTS.include?(File.extname(path).downcase)
|
124
162
|
end
|
125
163
|
|
126
|
-
def self.
|
127
|
-
|
164
|
+
def self.compute_totals(items)
|
165
|
+
{
|
166
|
+
bytes: items.sum { |i| i[:bytes] },
|
167
|
+
files: items.sum { |i| i[:files] },
|
168
|
+
loc: items.sum { |i| i[:loc] }
|
169
|
+
}
|
128
170
|
end
|
129
171
|
|
130
|
-
def self.add_percents(items,
|
172
|
+
def self.add_percents(items, totals, metric)
|
173
|
+
total = totals[metric.to_sym].to_f
|
131
174
|
return items.map { |item| item.merge(percent: 0.0) } unless total.positive?
|
132
175
|
|
133
|
-
items.map
|
176
|
+
items.map do |item|
|
177
|
+
val = item[metric.to_sym].to_f
|
178
|
+
pct = (val * 100.0 / total).round(2)
|
179
|
+
item.merge(percent: pct)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def self.add_colors(items)
|
184
|
+
items.map do |item|
|
185
|
+
color = LANG_HEX_COLORS[item[:language]]
|
186
|
+
item.merge(color: color)
|
187
|
+
end
|
134
188
|
end
|
135
189
|
|
136
|
-
def self.sort_and_limit(items, limit)
|
137
|
-
|
190
|
+
def self.sort_and_limit(items, limit, metric)
|
191
|
+
key = metric.to_sym
|
192
|
+
sorted = items.sort_by { |item| [-item[key], item[:language]] }
|
138
193
|
lim = limit.to_i
|
139
194
|
return sorted if lim <= 0
|
140
195
|
|
141
196
|
sorted.first(lim)
|
142
197
|
end
|
143
198
|
|
144
|
-
def self.build_result(repo, items,
|
199
|
+
def self.build_result(repo, items, totals, metric)
|
145
200
|
{
|
146
201
|
report: 'languages',
|
147
202
|
repo_path: repo,
|
203
|
+
metric: metric,
|
148
204
|
generated_at: Time.now.utc.iso8601,
|
149
|
-
totals:
|
205
|
+
totals: totals.merge(languages: items.size),
|
150
206
|
items: items
|
151
207
|
}
|
152
208
|
end
|
153
209
|
end
|
210
|
+
# rubocop:enable Metrics/ClassLength
|
154
211
|
end
|
155
212
|
end
|
data/lib/pretty_git/cli.rb
CHANGED
@@ -9,7 +9,7 @@ require_relative 'cli_helpers'
|
|
9
9
|
module PrettyGit
|
10
10
|
# Command-line interface entry point.
|
11
11
|
class CLI
|
12
|
-
SUPPORTED_REPORTS = %w[summary activity authors files heatmap].freeze
|
12
|
+
SUPPORTED_REPORTS = %w[summary activity authors files heatmap languages].freeze
|
13
13
|
SUPPORTED_FORMATS = %w[console json csv md yaml xml].freeze
|
14
14
|
|
15
15
|
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
@@ -7,9 +7,11 @@ require_relative 'app'
|
|
7
7
|
module PrettyGit
|
8
8
|
# Helpers extracted from `PrettyGit::CLI` to keep the CLI class small
|
9
9
|
# and RuboCop-compliant. Provides parser configuration and execution utilities.
|
10
|
+
# rubocop:disable Metrics/ModuleLength
|
10
11
|
module CLIHelpers
|
11
12
|
REPORTS = %w[summary activity authors files heatmap languages].freeze
|
12
13
|
FORMATS = %w[console json csv md yaml xml].freeze
|
14
|
+
METRICS = %w[bytes files loc].freeze
|
13
15
|
|
14
16
|
module_function
|
15
17
|
|
@@ -19,6 +21,7 @@ module PrettyGit
|
|
19
21
|
add_time_author_options(opts, options)
|
20
22
|
add_path_limit_options(opts, options)
|
21
23
|
add_format_output_options(opts, options)
|
24
|
+
add_metric_options(opts, options)
|
22
25
|
add_misc_options(opts, options)
|
23
26
|
end
|
24
27
|
|
@@ -48,6 +51,12 @@ module PrettyGit
|
|
48
51
|
opts.on('--theme NAME', 'console color theme: basic|bright|mono') { |val| options[:theme] = val }
|
49
52
|
end
|
50
53
|
|
54
|
+
def add_metric_options(opts, options)
|
55
|
+
opts.on('--metric NAME', 'languages metric: bytes|files|loc (default: bytes)') do |val|
|
56
|
+
options[:metric] = val
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
51
60
|
def add_misc_options(opts, options)
|
52
61
|
opts.on('--version', 'Show version') { options[:_version] = true }
|
53
62
|
opts.on('--help', 'Show help') { options[:_help] = true }
|
@@ -66,7 +75,7 @@ module PrettyGit
|
|
66
75
|
code = handle_version_help(options, parser, out)
|
67
76
|
return code unless code.nil?
|
68
77
|
|
69
|
-
return nil if valid_report?(options[:report]) && valid_theme?(options[:theme])
|
78
|
+
return nil if valid_report?(options[:report]) && valid_theme?(options[:theme]) && valid_metric?(options[:metric])
|
70
79
|
|
71
80
|
print_validation_errors(options, err)
|
72
81
|
1
|
@@ -87,15 +96,20 @@ module PrettyGit
|
|
87
96
|
def valid_report?(report) = REPORTS.include?(report)
|
88
97
|
def valid_theme?(theme) = %w[basic bright mono].include?(theme)
|
89
98
|
|
99
|
+
def valid_metric?(metric)
|
100
|
+
metric.nil? || METRICS.include?(metric)
|
101
|
+
end
|
102
|
+
|
90
103
|
def print_validation_errors(options, err)
|
91
104
|
supported = REPORTS.join(', ')
|
92
105
|
unless valid_report?(options[:report])
|
93
106
|
err.puts "Unknown report: #{options[:report]}."
|
94
107
|
err.puts "Supported: #{supported}"
|
95
108
|
end
|
96
|
-
|
109
|
+
err.puts "Unknown theme: #{options[:theme]}. Supported: basic, bright, mono" unless valid_theme?(options[:theme])
|
110
|
+
return if valid_metric?(options[:metric])
|
97
111
|
|
98
|
-
err.puts "Unknown
|
112
|
+
err.puts "Unknown metric: #{options[:metric]}. Supported: #{METRICS.join(', ')}"
|
99
113
|
end
|
100
114
|
|
101
115
|
def build_filters(options)
|
@@ -109,6 +123,7 @@ module PrettyGit
|
|
109
123
|
paths: options[:paths],
|
110
124
|
exclude_paths: options[:exclude_paths],
|
111
125
|
time_bucket: options[:time_bucket],
|
126
|
+
metric: options[:metric],
|
112
127
|
limit: options[:limit],
|
113
128
|
format: options[:format],
|
114
129
|
out: options[:out],
|
@@ -127,4 +142,5 @@ module PrettyGit
|
|
127
142
|
PrettyGit::App.new.run(report, filters, out: out, err: err)
|
128
143
|
end
|
129
144
|
end
|
145
|
+
# rubocop:enable Metrics/ModuleLength
|
130
146
|
end
|
data/lib/pretty_git/filters.rb
CHANGED
@@ -16,7 +16,7 @@ module PrettyGit
|
|
16
16
|
end
|
17
17
|
|
18
18
|
# Returns Enumerator of PrettyGit::Types::Commit
|
19
|
-
# rubocop:disable Metrics/AbcSize, Metrics/
|
19
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
20
20
|
def each_commit
|
21
21
|
Enumerator.new do |yld|
|
22
22
|
cmd = build_git_command
|
@@ -24,17 +24,15 @@ module PrettyGit
|
|
24
24
|
current = nil
|
25
25
|
stdout.each_line do |line|
|
26
26
|
line = line.chomp
|
27
|
-
|
27
|
+
# Try to start a new commit from header on any line
|
28
|
+
header = start_commit_from_header(line)
|
29
|
+
if header
|
30
|
+
# emit previous commit if any
|
28
31
|
emit_current(yld, current)
|
29
|
-
current =
|
32
|
+
current = header
|
30
33
|
next
|
31
34
|
end
|
32
35
|
|
33
|
-
if current.nil?
|
34
|
-
current = start_commit_from_header(line)
|
35
|
-
next if current
|
36
|
-
end
|
37
|
-
|
38
36
|
next if line.empty?
|
39
37
|
|
40
38
|
append_numstat_line(current, line)
|
@@ -50,7 +48,7 @@ module PrettyGit
|
|
50
48
|
end
|
51
49
|
end
|
52
50
|
end
|
53
|
-
# rubocop:enable Metrics/AbcSize, Metrics/
|
51
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
54
52
|
|
55
53
|
private
|
56
54
|
|
@@ -84,7 +82,7 @@ module PrettyGit
|
|
84
82
|
author_name: author_name,
|
85
83
|
author_email: author_email,
|
86
84
|
authored_at: Time.parse(authored_at).utc.iso8601,
|
87
|
-
message: subject,
|
85
|
+
message: subject.delete(SEP_RECORD),
|
88
86
|
files: []
|
89
87
|
}
|
90
88
|
end
|
@@ -21,7 +21,9 @@ module PrettyGit
|
|
21
21
|
when 'heatmap'
|
22
22
|
write_csv(%w[dow hour commits], result[:items])
|
23
23
|
when 'languages'
|
24
|
-
|
24
|
+
metric = (result[:metric] || 'bytes').to_s
|
25
|
+
headers = ['language', metric, 'percent', 'color']
|
26
|
+
write_csv(headers, result[:items])
|
25
27
|
else
|
26
28
|
raise ArgumentError, "CSV output for report '#{report}' is not supported yet"
|
27
29
|
end
|
@@ -26,9 +26,11 @@ module PrettyGit
|
|
26
26
|
def render(io, table, data, color: true)
|
27
27
|
title(io, data, color)
|
28
28
|
io.puts
|
29
|
-
|
29
|
+
metric = (data[:metric] || 'bytes').to_s
|
30
|
+
table_rows = rows(data[:items], metric)
|
30
31
|
colorizer = ->(row) { LANG_ANSI_COLOR_CODES[row[:language]] }
|
31
|
-
|
32
|
+
headers = ['language', metric, 'percent']
|
33
|
+
table.print(headers, table_rows, highlight_max: false, first_col_colorizer: colorizer)
|
32
34
|
io.puts
|
33
35
|
io.puts "Generated at: #{data[:generated_at]}"
|
34
36
|
end
|
@@ -37,9 +39,10 @@ module PrettyGit
|
|
37
39
|
io.puts Colors.title("Languages for #{data[:repo_path]}", color)
|
38
40
|
end
|
39
41
|
|
40
|
-
def rows(items)
|
42
|
+
def rows(items, metric)
|
43
|
+
key = metric.to_sym
|
41
44
|
items.map do |item|
|
42
|
-
{ language: item[:language],
|
45
|
+
{ language: item[:language], key => item[key], percent: format('%.2f', item[:percent]) }
|
43
46
|
end
|
44
47
|
end
|
45
48
|
end
|
@@ -8,6 +8,7 @@ module PrettyGit
|
|
8
8
|
@io = io
|
9
9
|
end
|
10
10
|
|
11
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
11
12
|
def call(report, result, _filters)
|
12
13
|
case report
|
13
14
|
when 'summary'
|
@@ -21,11 +22,14 @@ module PrettyGit
|
|
21
22
|
when 'heatmap'
|
22
23
|
render_table('Heatmap', %w[dow hour commits], result[:items])
|
23
24
|
when 'languages'
|
24
|
-
|
25
|
+
metric = (result[:metric] || 'bytes').to_s
|
26
|
+
headers = ['language', metric, 'percent', 'color']
|
27
|
+
render_table('Languages', headers, result[:items])
|
25
28
|
else
|
26
29
|
@io.puts result.inspect
|
27
30
|
end
|
28
31
|
end
|
32
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
29
33
|
|
30
34
|
private
|
31
35
|
|
data/lib/pretty_git/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pretty-git
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pretty Git Authors
|
@@ -58,8 +58,10 @@ executables:
|
|
58
58
|
extensions: []
|
59
59
|
extra_rdoc_files: []
|
60
60
|
files:
|
61
|
+
- CHANGELOG.md
|
61
62
|
- LICENSE
|
62
63
|
- README.md
|
64
|
+
- README.ru.md
|
63
65
|
- bin/pretty-git
|
64
66
|
- lib/pretty_git.rb
|
65
67
|
- lib/pretty_git/analytics/activity.rb
|