fcom 0.4.1
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 +7 -0
- data/.github/dependabot.yml +8 -0
- data/.github/workflows/ruby.yml +23 -0
- data/.gitignore +11 -0
- data/.release_assistant.yml +3 -0
- data/.rspec +3 -0
- data/.rubocop.yml +6 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +125 -0
- data/Gemfile +27 -0
- data/Gemfile.lock +122 -0
- data/LICENSE.txt +21 -0
- data/README.md +100 -0
- data/RELEASING.md +7 -0
- data/Rakefile +8 -0
- data/bin/_guard-core +28 -0
- data/bin/console +15 -0
- data/bin/guard +28 -0
- data/bin/release +28 -0
- data/bin/rspec +28 -0
- data/bin/rubocop +28 -0
- data/bin/setup +8 -0
- data/exe/fcom +50 -0
- data/fcom.gemspec +41 -0
- data/lib/fcom/config_file_options.rb +29 -0
- data/lib/fcom/git_helpers.rb +19 -0
- data/lib/fcom/options_helpers.rb +42 -0
- data/lib/fcom/parser.rb +75 -0
- data/lib/fcom/querier.rb +59 -0
- data/lib/fcom/version.rb +7 -0
- data/lib/fcom.rb +83 -0
- metadata +140 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 1a9b5f97f93fe24acc44065291ffb501679421adbbe099a944f4c04288d599e1
|
|
4
|
+
data.tar.gz: 5cf9ee105891ae2a84fd6c46bac5cfe368f7ec1b896c9cdd49ef618c8498c1f7
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: d764a10321efa1264e4d5b9b9a9d51b1e2964789f36a4660017e1c0c0d04edb6859c266649dc922e3374a65f28590ca36d3396eabd1f67ce4dfd125bf7bf4297
|
|
7
|
+
data.tar.gz: 0ed2904a35496b5a8d848f3dfc8adfdcf7af1b3af7bb019df8373ad34930fc142cae5def0af3dae9e43d86c94c36b52e5dde66171a9f0511240e3fe58011c9b3
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
name: Run Rspec Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches:
|
|
6
|
+
- master
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v3
|
|
13
|
+
- uses: ruby/setup-ruby@v1
|
|
14
|
+
with:
|
|
15
|
+
bundler-cache: true
|
|
16
|
+
- name: Run Rubocop
|
|
17
|
+
run: bin/rubocop --format clang
|
|
18
|
+
- name: Run RSpec tests
|
|
19
|
+
run: bin/rspec --format progress
|
|
20
|
+
- name: Ensure alpha version
|
|
21
|
+
run: grep alpha $(find . -type f -name version.rb)
|
|
22
|
+
- name: Ensure no git diff
|
|
23
|
+
run: git diff --exit-code && git diff-index --quiet --cached HEAD
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.2.2
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
## v0.4.1 (2023-05-04)
|
|
2
|
+
[no unreleased changes yet]
|
|
3
|
+
|
|
4
|
+
## v0.4.0 (2022-09-29)
|
|
5
|
+
[no unreleased changes yet]
|
|
6
|
+
|
|
7
|
+
## v0.3.4 (2021-01-26)
|
|
8
|
+
### Dependencies
|
|
9
|
+
- Bump `release_assistant` to `0.1.1.alpha`
|
|
10
|
+
|
|
11
|
+
## v0.3.3 (2021-01-26)
|
|
12
|
+
### Internal
|
|
13
|
+
- Source Rubocop rules/config from `runger_style` gem
|
|
14
|
+
- Use `release_assistant` to manage releases
|
|
15
|
+
- Ensure in PR CI runs that the current version contains "alpha" & that there's no git diff (e.g.
|
|
16
|
+
due to failing to run `bundle` after updating the version)
|
|
17
|
+
|
|
18
|
+
## 0.3.2 - 2020-06-13
|
|
19
|
+
### Tests
|
|
20
|
+
- Extract RSpec performance summary reporting to a gem
|
|
21
|
+
([rspec_performance_summary](https://github.com/davidrunger/rspec_performance_summary/))
|
|
22
|
+
|
|
23
|
+
## 0.3.1 - 2020-06-06
|
|
24
|
+
### Docs
|
|
25
|
+
- Add note to README.md about `--init` option
|
|
26
|
+
|
|
27
|
+
## 0.3.0 - 2020-06-06
|
|
28
|
+
### Added
|
|
29
|
+
- Add `--init` flag to automatically create an `.fcom.yml` file
|
|
30
|
+
|
|
31
|
+
## 0.2.19 - 2020-06-05
|
|
32
|
+
### Docs
|
|
33
|
+
- Add badges to README.md (CI status, dependabot status, tag/version)
|
|
34
|
+
|
|
35
|
+
## 0.2.18 - 2020-06-05
|
|
36
|
+
### Tests
|
|
37
|
+
- Stub `ConfigFileOptions#config_file_exists?` to return `false` in tests
|
|
38
|
+
|
|
39
|
+
## 0.2.17 - 2020-06-05
|
|
40
|
+
### Fixed
|
|
41
|
+
- Print warning about missing `.fcom.yml` config file before executing querier
|
|
42
|
+
|
|
43
|
+
## 0.2.16 - 2020-06-05
|
|
44
|
+
### Tests
|
|
45
|
+
- Don't print debug statement(s) when executing tests
|
|
46
|
+
|
|
47
|
+
## 0.2.15 - 2020-06-05
|
|
48
|
+
### Fixed
|
|
49
|
+
- Don't print empty spaces before the first matching commit
|
|
50
|
+
|
|
51
|
+
## 0.2.14 - 2020-06-05
|
|
52
|
+
### Added
|
|
53
|
+
- Print warning if `.fcom.yml` config file does not exist (or it does not specify a `repo` option)
|
|
54
|
+
|
|
55
|
+
## 0.2.13 - 2020-06-05
|
|
56
|
+
### Added
|
|
57
|
+
- Add support for an `.fcom.yml` config file (supporting only a `repo` option at this time)
|
|
58
|
+
|
|
59
|
+
## 0.2.12 - 2020-06-05
|
|
60
|
+
### Docs
|
|
61
|
+
- Update the illustrated `--help` output in `README.md` to reflect the `-i`/`--ignore-case` and
|
|
62
|
+
`--debug` options.
|
|
63
|
+
|
|
64
|
+
## 0.2.11 - 2020-06-05
|
|
65
|
+
### Tests
|
|
66
|
+
- Added logging of how long each example takes to execute
|
|
67
|
+
- Stubbed `Fcom::GitHelpers#repo` in tests to improve spec performance
|
|
68
|
+
|
|
69
|
+
## 0.2.10 - 2020-06-05
|
|
70
|
+
### Changed
|
|
71
|
+
- Set `Fcom.logger.level` for both querier and parser
|
|
72
|
+
|
|
73
|
+
## 0.2.9 - 2020-06-05
|
|
74
|
+
### Changed
|
|
75
|
+
- Specify dependency versions
|
|
76
|
+
|
|
77
|
+
## 0.2.8 - 2020-06-05
|
|
78
|
+
## Added
|
|
79
|
+
- Add `--debug` option and only print the command(s) being executed if that option is used
|
|
80
|
+
|
|
81
|
+
## Fixed
|
|
82
|
+
- Added `activesupport` as a dependency of the `fcom` gem in the gemspec
|
|
83
|
+
|
|
84
|
+
## Changed
|
|
85
|
+
- Removed version locks for dependencies in gemspec
|
|
86
|
+
|
|
87
|
+
## 0.2.7 - 2020-06-05
|
|
88
|
+
### Maintenance
|
|
89
|
+
- Added release script
|
|
90
|
+
|
|
91
|
+
## 0.2.6 - 2020-06-05
|
|
92
|
+
### Added
|
|
93
|
+
- Allow searching case-insensitively via `-i`/`--ignore-case` option
|
|
94
|
+
|
|
95
|
+
## 0.2.5 - 2020-06-05
|
|
96
|
+
### Added
|
|
97
|
+
- Allow filtering results to a specific path (directory or file) via `-p`/`--path` option
|
|
98
|
+
|
|
99
|
+
### Tests
|
|
100
|
+
- Don't send email notifications about Travis build results
|
|
101
|
+
|
|
102
|
+
## 0.2.4 - 2019-12-31
|
|
103
|
+
### Tests
|
|
104
|
+
- Added tests
|
|
105
|
+
|
|
106
|
+
## 0.2.3 - 2019-12-29
|
|
107
|
+
### Added
|
|
108
|
+
- Determine default repo name from git origin remote, if possible
|
|
109
|
+
|
|
110
|
+
## 0.2.2 - 2019-12-28
|
|
111
|
+
### Changed
|
|
112
|
+
- Improved documentation
|
|
113
|
+
|
|
114
|
+
## 0.2.1 - 2019-12-28
|
|
115
|
+
### Added
|
|
116
|
+
- Add `--repo` option, which is used in the GitHub links that are printed for matching commits
|
|
117
|
+
|
|
118
|
+
## 0.2.0 - 2019-12-28
|
|
119
|
+
### Breaking changes
|
|
120
|
+
- Change how options should be provided to the `fcom` command
|
|
121
|
+
- Parse command argument/options with `slop` gem
|
|
122
|
+
|
|
123
|
+
## 0.1.0 - 2019-12-28
|
|
124
|
+
### Added
|
|
125
|
+
- Initial release
|
data/Gemfile
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
ruby '3.2.2'
|
|
4
|
+
|
|
5
|
+
source 'https://rubygems.org'
|
|
6
|
+
|
|
7
|
+
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
|
8
|
+
|
|
9
|
+
# Specify your gem's dependencies in fcom.gemspec
|
|
10
|
+
gemspec
|
|
11
|
+
|
|
12
|
+
group :development, :test do
|
|
13
|
+
gem 'bundler', require: false
|
|
14
|
+
gem 'pry'
|
|
15
|
+
gem 'pry-byebug'
|
|
16
|
+
gem 'rake', require: false
|
|
17
|
+
gem 'rspec', require: false
|
|
18
|
+
gem 'rubocop', require: false
|
|
19
|
+
gem 'rubocop-performance', require: false
|
|
20
|
+
gem 'rubocop-rake', require: false
|
|
21
|
+
gem 'rubocop-rspec', require: false
|
|
22
|
+
gem 'runger_style', github: 'davidrunger/runger_style', require: false
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
group :development do
|
|
26
|
+
gem 'release_assistant', require: false, github: 'davidrunger/release_assistant'
|
|
27
|
+
end
|
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
GIT
|
|
2
|
+
remote: https://github.com/davidrunger/release_assistant
|
|
3
|
+
revision: 969b3a90264da6ce73275a7240cc7e54ff5a6370
|
|
4
|
+
specs:
|
|
5
|
+
release_assistant (0.3.3.alpha)
|
|
6
|
+
activesupport (>= 6, < 8)
|
|
7
|
+
colorize (~> 0.8)
|
|
8
|
+
memoist (~> 0.16)
|
|
9
|
+
slop (~> 4.8)
|
|
10
|
+
|
|
11
|
+
GIT
|
|
12
|
+
remote: https://github.com/davidrunger/runger_style
|
|
13
|
+
revision: 3d9d3a91cfd39a037ef4b0dbb547d4b652f7bc4e
|
|
14
|
+
specs:
|
|
15
|
+
runger_style (0.2.22.alpha)
|
|
16
|
+
rubocop (>= 1.38.0, < 2)
|
|
17
|
+
|
|
18
|
+
PATH
|
|
19
|
+
remote: .
|
|
20
|
+
specs:
|
|
21
|
+
fcom (0.4.1)
|
|
22
|
+
activesupport (>= 6, < 8)
|
|
23
|
+
colorize (~> 0.8)
|
|
24
|
+
memoist (~> 0.16)
|
|
25
|
+
slop (~> 4.8)
|
|
26
|
+
|
|
27
|
+
GEM
|
|
28
|
+
remote: https://rubygems.org/
|
|
29
|
+
specs:
|
|
30
|
+
activesupport (7.0.4.3)
|
|
31
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
32
|
+
i18n (>= 1.6, < 2)
|
|
33
|
+
minitest (>= 5.1)
|
|
34
|
+
tzinfo (~> 2.0)
|
|
35
|
+
ast (2.4.2)
|
|
36
|
+
byebug (11.1.3)
|
|
37
|
+
coderay (1.1.3)
|
|
38
|
+
colorize (0.8.1)
|
|
39
|
+
concurrent-ruby (1.2.2)
|
|
40
|
+
diff-lcs (1.5.0)
|
|
41
|
+
i18n (1.12.0)
|
|
42
|
+
concurrent-ruby (~> 1.0)
|
|
43
|
+
json (2.6.3)
|
|
44
|
+
memoist (0.16.2)
|
|
45
|
+
method_source (1.0.0)
|
|
46
|
+
minitest (5.18.0)
|
|
47
|
+
parallel (1.23.0)
|
|
48
|
+
parser (3.2.2.1)
|
|
49
|
+
ast (~> 2.4.1)
|
|
50
|
+
pry (0.14.2)
|
|
51
|
+
coderay (~> 1.1)
|
|
52
|
+
method_source (~> 1.0)
|
|
53
|
+
pry-byebug (3.10.1)
|
|
54
|
+
byebug (~> 11.0)
|
|
55
|
+
pry (>= 0.13, < 0.15)
|
|
56
|
+
rainbow (3.1.1)
|
|
57
|
+
rake (13.0.6)
|
|
58
|
+
regexp_parser (2.8.0)
|
|
59
|
+
rexml (3.2.5)
|
|
60
|
+
rspec (3.12.0)
|
|
61
|
+
rspec-core (~> 3.12.0)
|
|
62
|
+
rspec-expectations (~> 3.12.0)
|
|
63
|
+
rspec-mocks (~> 3.12.0)
|
|
64
|
+
rspec-core (3.12.0)
|
|
65
|
+
rspec-support (~> 3.12.0)
|
|
66
|
+
rspec-expectations (3.12.0)
|
|
67
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
68
|
+
rspec-support (~> 3.12.0)
|
|
69
|
+
rspec-mocks (3.12.0)
|
|
70
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
71
|
+
rspec-support (~> 3.12.0)
|
|
72
|
+
rspec-support (3.12.0)
|
|
73
|
+
rubocop (1.50.2)
|
|
74
|
+
json (~> 2.3)
|
|
75
|
+
parallel (~> 1.10)
|
|
76
|
+
parser (>= 3.2.0.0)
|
|
77
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
78
|
+
regexp_parser (>= 1.8, < 3.0)
|
|
79
|
+
rexml (>= 3.2.5, < 4.0)
|
|
80
|
+
rubocop-ast (>= 1.28.0, < 2.0)
|
|
81
|
+
ruby-progressbar (~> 1.7)
|
|
82
|
+
unicode-display_width (>= 2.4.0, < 3.0)
|
|
83
|
+
rubocop-ast (1.28.1)
|
|
84
|
+
parser (>= 3.2.1.0)
|
|
85
|
+
rubocop-capybara (2.18.0)
|
|
86
|
+
rubocop (~> 1.41)
|
|
87
|
+
rubocop-performance (1.17.1)
|
|
88
|
+
rubocop (>= 1.7.0, < 2.0)
|
|
89
|
+
rubocop-ast (>= 0.4.0)
|
|
90
|
+
rubocop-rake (0.6.0)
|
|
91
|
+
rubocop (~> 1.0)
|
|
92
|
+
rubocop-rspec (2.20.0)
|
|
93
|
+
rubocop (~> 1.33)
|
|
94
|
+
rubocop-capybara (~> 2.17)
|
|
95
|
+
ruby-progressbar (1.13.0)
|
|
96
|
+
slop (4.10.1)
|
|
97
|
+
tzinfo (2.0.6)
|
|
98
|
+
concurrent-ruby (~> 1.0)
|
|
99
|
+
unicode-display_width (2.4.2)
|
|
100
|
+
|
|
101
|
+
PLATFORMS
|
|
102
|
+
ruby
|
|
103
|
+
|
|
104
|
+
DEPENDENCIES
|
|
105
|
+
bundler
|
|
106
|
+
fcom!
|
|
107
|
+
pry
|
|
108
|
+
pry-byebug
|
|
109
|
+
rake
|
|
110
|
+
release_assistant!
|
|
111
|
+
rspec
|
|
112
|
+
rubocop
|
|
113
|
+
rubocop-performance
|
|
114
|
+
rubocop-rake
|
|
115
|
+
rubocop-rspec
|
|
116
|
+
runger_style!
|
|
117
|
+
|
|
118
|
+
RUBY VERSION
|
|
119
|
+
ruby 3.2.2p53
|
|
120
|
+
|
|
121
|
+
BUNDLED WITH
|
|
122
|
+
2.4.12
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2019 David Runger
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
[](https://travis-ci.org/davidrunger/fcom)
|
|
2
|
+
[](https://dependabot.com)
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
# `fcom` ("find commit(s)")
|
|
6
|
+
|
|
7
|
+
This is a CLI tool that I use to parse the git history of a repo.
|
|
8
|
+
|
|
9
|
+
For example, if I use `fcom` to search this repo with `fcom "line.(green|red)" --regex --repo
|
|
10
|
+
davidrunger/fcom`, I get this output:
|
|
11
|
+
|
|
12
|
+
.png)
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
gem install fcom
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Dependencies
|
|
21
|
+
|
|
22
|
+
This gem assumes that you have `git` and [`rg` (ripgrep)][ripgrep] installed.
|
|
23
|
+
|
|
24
|
+
[ripgrep]: https://github.com/BurntSushi/ripgrep
|
|
25
|
+
|
|
26
|
+
## Basic usage
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
$ fcom <search string> [options]
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
#### Available options and examples
|
|
33
|
+
|
|
34
|
+
After installing, execute `fcom --help` to see usage examples and available options.
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
$ fcom --help
|
|
38
|
+
|
|
39
|
+
Usage: fcom <search string> [options]
|
|
40
|
+
|
|
41
|
+
Examples:
|
|
42
|
+
fcom update
|
|
43
|
+
fcom 'def update'
|
|
44
|
+
fcom "def update" --days 60
|
|
45
|
+
fcom "[Uu]ser.*slug" -d 365 --regex
|
|
46
|
+
fcom options --path spec/
|
|
47
|
+
fcom "line.(green|red)" -d 365 --regex --repo davidrunger/fcom -a "David Runger"
|
|
48
|
+
|
|
49
|
+
--repo GitHub repo (in form `username/repo`)
|
|
50
|
+
-d, --days number of days to search back
|
|
51
|
+
-r, --regex interpret search string as a regular expression
|
|
52
|
+
-i, --ignore-case search case-insensitively
|
|
53
|
+
-p, --path path (directory or file) used to filter results
|
|
54
|
+
-a, --author author
|
|
55
|
+
--rg-options additional options passed directly to `rg` (e.g. `--rg-options "--max-columns 1000"`)
|
|
56
|
+
--debug print debugging info
|
|
57
|
+
--init create an `.fcom.yml` config file
|
|
58
|
+
-v, --version print the version
|
|
59
|
+
-h, --help print this help information
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## `.fcom.yml` config file
|
|
63
|
+
We highly recommend that you create an `.fcom.yml` file in any repository that you plan to search
|
|
64
|
+
with `fcom`.
|
|
65
|
+
|
|
66
|
+
**This file can be created automatically by executing `fcom --init`** in the relevant
|
|
67
|
+
repo/directory.
|
|
68
|
+
|
|
69
|
+
(You might (or might not) want to add `.fcom.yml` to your `~/.gitignore_global` file, so that this
|
|
70
|
+
file is not tracked by `git`.)
|
|
71
|
+
|
|
72
|
+
#### Example `.fcom.yml` config file
|
|
73
|
+
```yaml
|
|
74
|
+
repo: githubusername/reponame
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The advantage of creating an `.fcom.yml` config file is that it will make the `fcom` command execute
|
|
78
|
+
more quickly, because time will not be wasted parsing the output of `git remote [...]` in order to
|
|
79
|
+
determine the URL of the repo's remote repository (which is used to construct links to matching
|
|
80
|
+
commits).
|
|
81
|
+
|
|
82
|
+
## Development
|
|
83
|
+
|
|
84
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run
|
|
85
|
+
the tests. You can also run `bin/console` for an interactive prompt that will allow you to
|
|
86
|
+
experiment.
|
|
87
|
+
|
|
88
|
+
To install this gem onto your local machine, run (in this repository's root directory):
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
$ rm -f pkg/*.gem && rake build && gem install --local pkg/fcom-*.gem
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Contributing
|
|
95
|
+
|
|
96
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/davidrunger/fcom.
|
|
97
|
+
|
|
98
|
+
## License
|
|
99
|
+
|
|
100
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/RELEASING.md
ADDED
data/Rakefile
ADDED
data/bin/_guard-core
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
#
|
|
5
|
+
# This file was generated by Bundler.
|
|
6
|
+
#
|
|
7
|
+
# The application '_guard-core' is installed as part of a gem, and
|
|
8
|
+
# this file is here to facilitate running it.
|
|
9
|
+
#
|
|
10
|
+
|
|
11
|
+
require 'pathname'
|
|
12
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', Pathname.new(__FILE__).realpath)
|
|
13
|
+
|
|
14
|
+
bundle_binstub = File.expand_path('bundle', __dir__)
|
|
15
|
+
|
|
16
|
+
if File.file?(bundle_binstub)
|
|
17
|
+
if File.read(bundle_binstub, 300).include?('This file was generated by Bundler')
|
|
18
|
+
load(bundle_binstub)
|
|
19
|
+
else
|
|
20
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
|
21
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
require 'rubygems'
|
|
26
|
+
require 'bundler/setup'
|
|
27
|
+
|
|
28
|
+
load Gem.bin_path('guard', '_guard-core')
|
data/bin/console
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'bundler/setup'
|
|
5
|
+
require 'fcom'
|
|
6
|
+
|
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
|
9
|
+
|
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
|
11
|
+
# require "pry"
|
|
12
|
+
# Pry.start
|
|
13
|
+
|
|
14
|
+
require 'irb'
|
|
15
|
+
IRB.start(__FILE__)
|
data/bin/guard
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
#
|
|
5
|
+
# This file was generated by Bundler.
|
|
6
|
+
#
|
|
7
|
+
# The application 'guard' is installed as part of a gem, and
|
|
8
|
+
# this file is here to facilitate running it.
|
|
9
|
+
#
|
|
10
|
+
|
|
11
|
+
require 'pathname'
|
|
12
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', Pathname.new(__FILE__).realpath)
|
|
13
|
+
|
|
14
|
+
bundle_binstub = File.expand_path('bundle', __dir__)
|
|
15
|
+
|
|
16
|
+
if File.file?(bundle_binstub)
|
|
17
|
+
if File.read(bundle_binstub, 300).include?('This file was generated by Bundler')
|
|
18
|
+
load(bundle_binstub)
|
|
19
|
+
else
|
|
20
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
|
21
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
require 'rubygems'
|
|
26
|
+
require 'bundler/setup'
|
|
27
|
+
|
|
28
|
+
load Gem.bin_path('guard', 'guard')
|
data/bin/release
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
#
|
|
5
|
+
# This file was generated by Bundler.
|
|
6
|
+
#
|
|
7
|
+
# The application 'release' is installed as part of a gem, and
|
|
8
|
+
# this file is here to facilitate running it.
|
|
9
|
+
#
|
|
10
|
+
|
|
11
|
+
require 'pathname'
|
|
12
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', Pathname.new(__FILE__).realpath)
|
|
13
|
+
|
|
14
|
+
bundle_binstub = File.expand_path('bundle', __dir__)
|
|
15
|
+
|
|
16
|
+
if File.file?(bundle_binstub)
|
|
17
|
+
if File.read(bundle_binstub, 300).include?('This file was generated by Bundler')
|
|
18
|
+
load(bundle_binstub)
|
|
19
|
+
else
|
|
20
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
|
21
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
require 'rubygems'
|
|
26
|
+
require 'bundler/setup'
|
|
27
|
+
|
|
28
|
+
load Gem.bin_path('release_assistant', 'release')
|
data/bin/rspec
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
#
|
|
5
|
+
# This file was generated by Bundler.
|
|
6
|
+
#
|
|
7
|
+
# The application 'rspec' is installed as part of a gem, and
|
|
8
|
+
# this file is here to facilitate running it.
|
|
9
|
+
#
|
|
10
|
+
|
|
11
|
+
require 'pathname'
|
|
12
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', Pathname.new(__FILE__).realpath)
|
|
13
|
+
|
|
14
|
+
bundle_binstub = File.expand_path('bundle', __dir__)
|
|
15
|
+
|
|
16
|
+
if File.file?(bundle_binstub)
|
|
17
|
+
if File.read(bundle_binstub, 300).include?('This file was generated by Bundler')
|
|
18
|
+
load(bundle_binstub)
|
|
19
|
+
else
|
|
20
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
|
21
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
require 'rubygems'
|
|
26
|
+
require 'bundler/setup'
|
|
27
|
+
|
|
28
|
+
load Gem.bin_path('rspec-core', 'rspec')
|
data/bin/rubocop
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
#
|
|
5
|
+
# This file was generated by Bundler.
|
|
6
|
+
#
|
|
7
|
+
# The application 'rubocop' is installed as part of a gem, and
|
|
8
|
+
# this file is here to facilitate running it.
|
|
9
|
+
#
|
|
10
|
+
|
|
11
|
+
require 'pathname'
|
|
12
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', Pathname.new(__FILE__).realpath)
|
|
13
|
+
|
|
14
|
+
bundle_binstub = File.expand_path('bundle', __dir__)
|
|
15
|
+
|
|
16
|
+
if File.file?(bundle_binstub)
|
|
17
|
+
if File.read(bundle_binstub, 300).include?('This file was generated by Bundler')
|
|
18
|
+
load(bundle_binstub)
|
|
19
|
+
else
|
|
20
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
|
21
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
require 'rubygems'
|
|
26
|
+
require 'bundler/setup'
|
|
27
|
+
|
|
28
|
+
load Gem.bin_path('rubocop', 'rubocop')
|
data/bin/setup
ADDED
data/exe/fcom
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
|
|
5
|
+
require 'slop'
|
|
6
|
+
require_relative '../lib/fcom.rb'
|
|
7
|
+
|
|
8
|
+
opts =
|
|
9
|
+
Slop.parse do |o|
|
|
10
|
+
o.banner = <<~BANNER
|
|
11
|
+
|
|
12
|
+
Usage: fcom <search string> [options]
|
|
13
|
+
|
|
14
|
+
Examples:
|
|
15
|
+
fcom update
|
|
16
|
+
fcom 'def update'
|
|
17
|
+
fcom "def update" --days 60
|
|
18
|
+
fcom "[Uu]ser.*slug" -d 365 --regex
|
|
19
|
+
fcom options --path spec/
|
|
20
|
+
fcom "line.(green|red)" -d 365 --regex --repo davidrunger/fcom -a "David Runger"
|
|
21
|
+
BANNER
|
|
22
|
+
|
|
23
|
+
Fcom.define_slop_options(o)
|
|
24
|
+
|
|
25
|
+
o.on('--init', 'create an `.fcom.yml` config file') do
|
|
26
|
+
File.write('.fcom.yml', "repo: #{Fcom::GitHelpers.new.repo}\n")
|
|
27
|
+
puts('Created `.fcom.yml` file!'.green.bold)
|
|
28
|
+
exit
|
|
29
|
+
end
|
|
30
|
+
o.on('-v', '--version', 'print the version') do
|
|
31
|
+
puts(Fcom::VERSION)
|
|
32
|
+
exit
|
|
33
|
+
end
|
|
34
|
+
o.on('-h', '--help', 'print this help information') do
|
|
35
|
+
puts(o)
|
|
36
|
+
exit
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Note: mutating the globally accessible `Fcom.logger` constant like this is not thread-safe
|
|
41
|
+
Fcom.logger.level = Logger::DEBUG if opts.debug?
|
|
42
|
+
|
|
43
|
+
if opts.parse_mode?
|
|
44
|
+
Fcom::Parser.new(opts).parse
|
|
45
|
+
elsif !opts.arguments.empty?
|
|
46
|
+
Fcom.warn_if_config_file_repo_option_missing
|
|
47
|
+
Fcom::Querier.new(opts).query
|
|
48
|
+
else
|
|
49
|
+
puts(opts.options)
|
|
50
|
+
end
|
data/fcom.gemspec
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'lib/fcom/version'
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = 'fcom'
|
|
7
|
+
spec.version = Fcom::VERSION
|
|
8
|
+
spec.authors = ['David Runger']
|
|
9
|
+
spec.email = ['davidjrunger@gmail.com']
|
|
10
|
+
|
|
11
|
+
spec.summary = 'CLI tool for parsing git history'
|
|
12
|
+
spec.homepage = 'https://github.com/davidrunger/fcom'
|
|
13
|
+
spec.license = 'MIT'
|
|
14
|
+
|
|
15
|
+
if spec.respond_to?(:metadata)
|
|
16
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
|
17
|
+
|
|
18
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
|
19
|
+
spec.metadata['source_code_uri'] = 'https://github.com/davidrunger/fcom'
|
|
20
|
+
spec.metadata['changelog_uri'] = 'https://github.com/davidrunger/fcom/blob/master/CHANGELOG.md'
|
|
21
|
+
else
|
|
22
|
+
raise('RubyGems 2.0 or newer is required to protect against public gem pushes.')
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Specify which files should be added to the gem when it is released.
|
|
26
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
27
|
+
spec.files =
|
|
28
|
+
Dir.chdir(File.expand_path(__dir__)) do
|
|
29
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
30
|
+
end
|
|
31
|
+
spec.bindir = 'exe'
|
|
32
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
33
|
+
spec.require_paths = ['lib']
|
|
34
|
+
|
|
35
|
+
spec.add_dependency('activesupport', '>= 6', '< 8')
|
|
36
|
+
spec.add_dependency('colorize', '~> 0.8')
|
|
37
|
+
spec.add_dependency('memoist', '~> 0.16')
|
|
38
|
+
spec.add_dependency('slop', '~> 4.8')
|
|
39
|
+
|
|
40
|
+
spec.required_ruby_version = '>= 3.2'
|
|
41
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Fcom::ConfigFileOptions
|
|
4
|
+
extend Memoist
|
|
5
|
+
|
|
6
|
+
def initialize
|
|
7
|
+
@options =
|
|
8
|
+
if config_file_exists?
|
|
9
|
+
YAML.load_file(config_file_path)
|
|
10
|
+
else
|
|
11
|
+
{}
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def repo
|
|
16
|
+
@options['repo']
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
memoize \
|
|
22
|
+
def config_file_path
|
|
23
|
+
"#{ENV.fetch('PWD')}/.fcom.yml"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def config_file_exists?
|
|
27
|
+
File.exist?(config_file_path)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This class contains helpers that extract information from `git`.
|
|
4
|
+
class Fcom::GitHelpers
|
|
5
|
+
def repo
|
|
6
|
+
# Examples:
|
|
7
|
+
# git@github.com:davidrunger/fcom.git
|
|
8
|
+
# https://github.com/davidrunger/fcom.git
|
|
9
|
+
# https://github.com/davidrunger/fcom
|
|
10
|
+
origin_fetch_url.delete_suffix('/').match(%r{github\.com[:/](((?!\.git).)*)})[1]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def origin_fetch_url
|
|
16
|
+
origin_remote_info = `git remote -v`
|
|
17
|
+
origin_remote_info.match(/origin\s+(.*)\s+\(fetch\)$/)[1]
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This module contains convenience methods that expose more directly the command options provided.
|
|
4
|
+
module Fcom::OptionsHelpers
|
|
5
|
+
private
|
|
6
|
+
|
|
7
|
+
def author
|
|
8
|
+
@options[:author]
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def days
|
|
12
|
+
@options[:days]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def ignore_case?
|
|
16
|
+
@options.ignore_case?
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def path
|
|
20
|
+
@options[:path]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def regex_mode?
|
|
24
|
+
@options.regex?
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def debug?
|
|
28
|
+
@options.debug?
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def development?
|
|
32
|
+
@options.development?
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def repo
|
|
36
|
+
@options[:repo]
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def search_string
|
|
40
|
+
@options.arguments.first
|
|
41
|
+
end
|
|
42
|
+
end
|
data/lib/fcom/parser.rb
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This class parses (and then reprints some of) STDIN according to the options passed to `fcom`.
|
|
4
|
+
class Fcom::Parser
|
|
5
|
+
include ::Fcom::OptionsHelpers
|
|
6
|
+
|
|
7
|
+
def initialize(options)
|
|
8
|
+
@options = options
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
12
|
+
# rubocop:disable Metrics/MethodLength
|
|
13
|
+
def parse
|
|
14
|
+
expression_to_match = search_string
|
|
15
|
+
expression_to_match = Regexp.escape(expression_to_match).gsub('\\ ', ' ') unless regex_mode?
|
|
16
|
+
regex =
|
|
17
|
+
Regexp.new(
|
|
18
|
+
"((\\+|-)\\s?.*#{expression_to_match}.*|Omitted long (matching )?line)",
|
|
19
|
+
ignore_case? ? Regexp::IGNORECASE : nil,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
previous_commit = nil
|
|
23
|
+
a_commit_has_matched = false
|
|
24
|
+
filename = nil
|
|
25
|
+
$stdin.each do |line|
|
|
26
|
+
line.chomp!
|
|
27
|
+
if (match = line.match(/^commit (.*)/)&.[](1))
|
|
28
|
+
previous_commit = match
|
|
29
|
+
elsif line.match?(/^diff /)
|
|
30
|
+
old_filename = line.match(%r{ a/(\S+)})&.[](1) || '[weird filename]'
|
|
31
|
+
new_filename = line.match(%r{ b/(\S+)})&.[](1) || '[weird filename]'
|
|
32
|
+
filename =
|
|
33
|
+
case
|
|
34
|
+
when old_filename == new_filename then old_filename
|
|
35
|
+
else "#{old_filename} --> #{new_filename}"
|
|
36
|
+
end
|
|
37
|
+
elsif line.match?(regex) && (filename.blank? || path_match?(filename))
|
|
38
|
+
if previous_commit
|
|
39
|
+
title, sha, author, date = previous_commit.split('|')
|
|
40
|
+
sha_with_url = "#{sha[0, 7]} ( https://github.com/#{repo}/commit/#{sha[0, 7]} )"
|
|
41
|
+
|
|
42
|
+
puts("\n\n") if a_commit_has_matched # print commit separator, if needed
|
|
43
|
+
puts([title, sha_with_url, author, date])
|
|
44
|
+
puts('==============================================')
|
|
45
|
+
|
|
46
|
+
previous_commit = nil
|
|
47
|
+
a_commit_has_matched = true
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
if filename
|
|
51
|
+
puts(filename)
|
|
52
|
+
filename = nil
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
if line.start_with?('+')
|
|
56
|
+
puts(line.green)
|
|
57
|
+
elsif line.start_with?('-')
|
|
58
|
+
puts(line.red)
|
|
59
|
+
else
|
|
60
|
+
puts(line)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
# rubocop:enable Metrics/MethodLength
|
|
66
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
67
|
+
|
|
68
|
+
private
|
|
69
|
+
|
|
70
|
+
def path_match?(filename)
|
|
71
|
+
return true if path == Fcom::ROOT_PATH
|
|
72
|
+
|
|
73
|
+
filename.include?(path.delete_prefix('./'))
|
|
74
|
+
end
|
|
75
|
+
end
|
data/lib/fcom/querier.rb
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative './options_helpers.rb'
|
|
4
|
+
|
|
5
|
+
# This class executes a system command to retrieve the git history, which is passed through `rg`
|
|
6
|
+
# (ripgrep), and then ultimately is fed back to `fcom` for parsing.
|
|
7
|
+
class Fcom::Querier
|
|
8
|
+
include ::Fcom::OptionsHelpers
|
|
9
|
+
|
|
10
|
+
def initialize(options)
|
|
11
|
+
@options = options
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
|
15
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
|
16
|
+
def query
|
|
17
|
+
expression_to_match = search_string
|
|
18
|
+
expression_to_match = Regexp.escape(expression_to_match).gsub('\\ ', ' ') unless regex_mode?
|
|
19
|
+
|
|
20
|
+
if expression_to_match.nil? || expression_to_match.empty?
|
|
21
|
+
puts('provide expression to match as first argument')
|
|
22
|
+
exit
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
quote = expression_to_match.include?('"') ? "'" : '"'
|
|
26
|
+
|
|
27
|
+
command = <<~COMMAND.squish
|
|
28
|
+
git log
|
|
29
|
+
#{%(--author="#{author}") if author}
|
|
30
|
+
#{"--since=#{days}.day" unless days.nil?}
|
|
31
|
+
--full-diff
|
|
32
|
+
--no-textconv
|
|
33
|
+
--format="commit %s|%H|%an|%cr (%ci)"
|
|
34
|
+
--source
|
|
35
|
+
-p #{path}
|
|
36
|
+
|
|
|
37
|
+
|
|
38
|
+
rg #{quote}(#{expression_to_match})|(^commit )|(^diff )#{quote}
|
|
39
|
+
--color never
|
|
40
|
+
#{'--ignore-case' if ignore_case?}
|
|
41
|
+
#{@options[:rg_options]}
|
|
42
|
+
|
|
|
43
|
+
|
|
44
|
+
#{'exe/' if development?}fcom #{quote}#{search_string}#{quote}
|
|
45
|
+
#{"--days #{days}" if days}
|
|
46
|
+
#{'--regex' if regex_mode?}
|
|
47
|
+
#{'--debug' if debug?}
|
|
48
|
+
#{'--ignore-case' if ignore_case?}
|
|
49
|
+
--path #{path}
|
|
50
|
+
--parse-mode
|
|
51
|
+
--repo #{repo}
|
|
52
|
+
COMMAND
|
|
53
|
+
|
|
54
|
+
Fcom.logger.debug("Executing command: #{command}")
|
|
55
|
+
system(command)
|
|
56
|
+
end
|
|
57
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
|
58
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
|
59
|
+
end
|
data/lib/fcom/version.rb
ADDED
data/lib/fcom.rb
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support/all'
|
|
4
|
+
require 'colorize'
|
|
5
|
+
require 'memoist'
|
|
6
|
+
require 'slop'
|
|
7
|
+
require 'yaml'
|
|
8
|
+
|
|
9
|
+
# This `Fcom` class is the namespace within which most of the gem's code is written.
|
|
10
|
+
# We need to define the class before requiring the modules.
|
|
11
|
+
# rubocop:disable Lint/EmptyClass
|
|
12
|
+
class Fcom
|
|
13
|
+
end
|
|
14
|
+
# rubocop:enable Lint/EmptyClass
|
|
15
|
+
|
|
16
|
+
Dir["#{File.dirname(__FILE__)}/fcom/*.rb"].each { |file| require file }
|
|
17
|
+
|
|
18
|
+
class Fcom
|
|
19
|
+
ROOT_PATH = '.'
|
|
20
|
+
|
|
21
|
+
class << self
|
|
22
|
+
extend Memoist
|
|
23
|
+
|
|
24
|
+
memoize \
|
|
25
|
+
def logger
|
|
26
|
+
Logger.new($stdout).tap do |logger|
|
|
27
|
+
logger.formatter = ->(_severity, _datetime, _progname, msg) { "#{msg}\n" }
|
|
28
|
+
# default the log level to WARN, but this can be set to `DEBUG` via the `--debug` CLI option
|
|
29
|
+
logger.level = Logger::WARN
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
memoize \
|
|
34
|
+
def config_file_options
|
|
35
|
+
Fcom::ConfigFileOptions.new
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def warn_if_config_file_repo_option_missing
|
|
39
|
+
if config_file_options.repo.blank?
|
|
40
|
+
puts(<<~WARNING.rstrip.yellow)
|
|
41
|
+
Warning: you have not specified a `repo` option in an `.fcom.yml` file.
|
|
42
|
+
This will cause `fcom` to execute more slowly than necessary.
|
|
43
|
+
WARNING
|
|
44
|
+
puts('Execute `fcom --init` to create an `.fcom.yml` file.'.blue.bold)
|
|
45
|
+
puts("See https://github.com/davidrunger/fcom/#readme for more info.\n\n")
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def define_slop_options(options)
|
|
50
|
+
git_helpers = Fcom::GitHelpers.new
|
|
51
|
+
default_repo = config_file_options.repo || git_helpers.repo || 'username/repo'
|
|
52
|
+
|
|
53
|
+
options.string('--repo', 'GitHub repo (in form `username/repo`)', default: default_repo)
|
|
54
|
+
options.integer('-d', '--days', 'number of days to search back')
|
|
55
|
+
options.bool(
|
|
56
|
+
'-r',
|
|
57
|
+
'--regex',
|
|
58
|
+
'interpret search string as a regular expression',
|
|
59
|
+
default: false,
|
|
60
|
+
)
|
|
61
|
+
options.bool('-i', '--ignore-case', 'search case-insensitively', default: false)
|
|
62
|
+
options.string(
|
|
63
|
+
'-p',
|
|
64
|
+
'--path',
|
|
65
|
+
'path (directory or file) used to filter results',
|
|
66
|
+
default: Fcom::ROOT_PATH,
|
|
67
|
+
)
|
|
68
|
+
options.string(
|
|
69
|
+
'-a',
|
|
70
|
+
'--author',
|
|
71
|
+
'author',
|
|
72
|
+
)
|
|
73
|
+
options.string(
|
|
74
|
+
'--rg-options',
|
|
75
|
+
'additional options passed directly to `rg` (e.g. `--rg-options "--max-columns 1000"`)',
|
|
76
|
+
default: '',
|
|
77
|
+
)
|
|
78
|
+
options.bool('--debug', 'print debugging info', default: false)
|
|
79
|
+
options.bool('--parse-mode', 'whether we are in parse mode', default: false, help: false)
|
|
80
|
+
options.bool('--development', 'use local `fcom` executable', default: false, help: false)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: fcom
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.4.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- David Runger
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: exe
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2023-05-04 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: activesupport
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '6'
|
|
20
|
+
- - "<"
|
|
21
|
+
- !ruby/object:Gem::Version
|
|
22
|
+
version: '8'
|
|
23
|
+
type: :runtime
|
|
24
|
+
prerelease: false
|
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
26
|
+
requirements:
|
|
27
|
+
- - ">="
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
version: '6'
|
|
30
|
+
- - "<"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '8'
|
|
33
|
+
- !ruby/object:Gem::Dependency
|
|
34
|
+
name: colorize
|
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '0.8'
|
|
40
|
+
type: :runtime
|
|
41
|
+
prerelease: false
|
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '0.8'
|
|
47
|
+
- !ruby/object:Gem::Dependency
|
|
48
|
+
name: memoist
|
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '0.16'
|
|
54
|
+
type: :runtime
|
|
55
|
+
prerelease: false
|
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '0.16'
|
|
61
|
+
- !ruby/object:Gem::Dependency
|
|
62
|
+
name: slop
|
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '4.8'
|
|
68
|
+
type: :runtime
|
|
69
|
+
prerelease: false
|
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - "~>"
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '4.8'
|
|
75
|
+
description:
|
|
76
|
+
email:
|
|
77
|
+
- davidjrunger@gmail.com
|
|
78
|
+
executables:
|
|
79
|
+
- fcom
|
|
80
|
+
extensions: []
|
|
81
|
+
extra_rdoc_files: []
|
|
82
|
+
files:
|
|
83
|
+
- ".github/dependabot.yml"
|
|
84
|
+
- ".github/workflows/ruby.yml"
|
|
85
|
+
- ".gitignore"
|
|
86
|
+
- ".release_assistant.yml"
|
|
87
|
+
- ".rspec"
|
|
88
|
+
- ".rubocop.yml"
|
|
89
|
+
- ".ruby-version"
|
|
90
|
+
- CHANGELOG.md
|
|
91
|
+
- Gemfile
|
|
92
|
+
- Gemfile.lock
|
|
93
|
+
- LICENSE.txt
|
|
94
|
+
- README.md
|
|
95
|
+
- RELEASING.md
|
|
96
|
+
- Rakefile
|
|
97
|
+
- bin/_guard-core
|
|
98
|
+
- bin/console
|
|
99
|
+
- bin/guard
|
|
100
|
+
- bin/release
|
|
101
|
+
- bin/rspec
|
|
102
|
+
- bin/rubocop
|
|
103
|
+
- bin/setup
|
|
104
|
+
- exe/fcom
|
|
105
|
+
- fcom.gemspec
|
|
106
|
+
- lib/fcom.rb
|
|
107
|
+
- lib/fcom/config_file_options.rb
|
|
108
|
+
- lib/fcom/git_helpers.rb
|
|
109
|
+
- lib/fcom/options_helpers.rb
|
|
110
|
+
- lib/fcom/parser.rb
|
|
111
|
+
- lib/fcom/querier.rb
|
|
112
|
+
- lib/fcom/version.rb
|
|
113
|
+
homepage: https://github.com/davidrunger/fcom
|
|
114
|
+
licenses:
|
|
115
|
+
- MIT
|
|
116
|
+
metadata:
|
|
117
|
+
rubygems_mfa_required: 'true'
|
|
118
|
+
homepage_uri: https://github.com/davidrunger/fcom
|
|
119
|
+
source_code_uri: https://github.com/davidrunger/fcom
|
|
120
|
+
changelog_uri: https://github.com/davidrunger/fcom/blob/master/CHANGELOG.md
|
|
121
|
+
post_install_message:
|
|
122
|
+
rdoc_options: []
|
|
123
|
+
require_paths:
|
|
124
|
+
- lib
|
|
125
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
126
|
+
requirements:
|
|
127
|
+
- - ">="
|
|
128
|
+
- !ruby/object:Gem::Version
|
|
129
|
+
version: '3.2'
|
|
130
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
131
|
+
requirements:
|
|
132
|
+
- - ">="
|
|
133
|
+
- !ruby/object:Gem::Version
|
|
134
|
+
version: '0'
|
|
135
|
+
requirements: []
|
|
136
|
+
rubygems_version: 3.4.12
|
|
137
|
+
signing_key:
|
|
138
|
+
specification_version: 4
|
|
139
|
+
summary: CLI tool for parsing git history
|
|
140
|
+
test_files: []
|