fcom 0.15.1 → 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0c8b0dd7d7b36e4bd151dfa83cd99252084903d32659371c5c69290ae38f206a
4
- data.tar.gz: 82cb2f4608be68669c1c2cd2d3738e2d1b43e36ed5bf7cf2d4385d89b4e0a748
3
+ metadata.gz: e65d9caf74b1e93ed107925a8e601991eea9e93852015fa9d70b6f4f22852689
4
+ data.tar.gz: 361e48b4cd8174078afd0c2e278efbe366119cb5dfd4fcfb3324440b8080f5f5
5
5
  SHA512:
6
- metadata.gz: fe72bb3397bd44703fa4ddb905beaa7dca2126327a8d1fb5c4d05864e24b4df004d536a609e6e6b4097a3d8414745999e9aec17baab57c0f781d249308c2316f
7
- data.tar.gz: feb8dfbe3440a91cd81d27656d99368b853b3e32d279dbcf2be8078a7038810b6c1295bca521e82d8f8b55364065e78b22d8eec66823700d764b9b8204e9e9f4
6
+ metadata.gz: d5c2b6e11a0c0eea3949ec3108233f589f8b3dc36b6e4db046aa1293e190476e86666195b672845cc975e89bf1b3686a5bb5e55b2373ea0d3f47c2b71f433a1f
7
+ data.tar.gz: '096901b32e4d02674839c3817eb67292b1182d2331a5fa71a7916e9b9fdf22a82404630cde1129bd9db23e1a53da0b82cd957e49662567bd280c9d2bb1c2dfc3'
@@ -9,3 +9,7 @@ updates:
9
9
  timezone: America/Chicago
10
10
  allow:
11
11
  - dependency-type: all
12
+ - package-ecosystem: github-actions
13
+ directory: "/"
14
+ schedule:
15
+ interval: weekly
@@ -15,8 +15,8 @@ jobs:
15
15
  build:
16
16
  runs-on: ubuntu-latest
17
17
  steps:
18
- - uses: actions/checkout@v4
19
- - uses: ruby/setup-ruby@v1
18
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
19
+ - uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
20
20
  with:
21
21
  bundler-cache: true
22
22
  - name: Run RuboCop
data/CHANGELOG.md CHANGED
@@ -1,6 +1,12 @@
1
1
  ## Unreleased
2
2
  [no unreleased changes yet]
3
3
 
4
+ ## v1.0.1 (2026-08-28)
5
+ - Don't include commits or files whose matches are only in diff context lines.
6
+
7
+ ## v1.0.0 (2026-08-28)
8
+ - **BREAKING CHANGE:** interpret search strings as regular expressions by default. Use `-F`/`--fixed-strings` to search for fixed strings.
9
+
4
10
  ## v0.15.1 (2026-08-15)
5
11
  - Exit cleanly with a clear message when interrupting a search with Ctrl-C.
6
12
 
data/Gemfile.lock CHANGED
@@ -1,6 +1,6 @@
1
1
  GIT
2
2
  remote: https://github.com/davidrunger/pry-byebug
3
- revision: 7c0c1cac48b00f51e652a25423aeccd5eed5c966
3
+ revision: a02f6ab4317cade079f3d9b3455e803acd6fccbe
4
4
  specs:
5
5
  pry-byebug (3.10.1)
6
6
  pry (>= 0.13)
@@ -10,7 +10,7 @@ GIT
10
10
  PATH
11
11
  remote: .
12
12
  specs:
13
- fcom (0.15.1)
13
+ fcom (1.0.1)
14
14
  activesupport (>= 6)
15
15
  memo_wise (>= 1.7)
16
16
  rainbow (>= 3.0)
@@ -73,7 +73,7 @@ GEM
73
73
  racc (1.8.1)
74
74
  rainbow (3.1.1)
75
75
  rake (13.4.2)
76
- rbs (4.1.3)
76
+ rbs (4.2.0)
77
77
  logger
78
78
  prism (>= 1.6.0)
79
79
  tsort
@@ -100,8 +100,8 @@ GEM
100
100
  diff-lcs (>= 1.2.0, < 2.0)
101
101
  rspec-support (~> 3.13.0)
102
102
  rspec-support (3.13.7)
103
- rubocop (1.89.0)
104
- json (~> 2.3)
103
+ rubocop (1.90.0)
104
+ json (>= 2.3)
105
105
  language_server-protocol (~> 3.17.0.2)
106
106
  lint_roller (~> 1.1.0)
107
107
  parallel (>= 1.10)
@@ -114,9 +114,9 @@ GEM
114
114
  rubocop-ast (1.50.0)
115
115
  parser (>= 3.3.7.2)
116
116
  prism (~> 1.7)
117
- rubocop-performance (1.26.1)
117
+ rubocop-performance (1.27.0)
118
118
  lint_roller (~> 1.1)
119
- rubocop (>= 1.75.0, < 2.0)
119
+ rubocop (>= 1.89.0, < 2.0)
120
120
  rubocop-ast (>= 1.47.1, < 2.0)
121
121
  rubocop-rake (0.7.1)
122
122
  lint_roller (~> 1.1)
@@ -135,7 +135,7 @@ GEM
135
135
  rainbow (>= 3.0)
136
136
  rake (>= 13.2.1)
137
137
  slop (~> 4.8)
138
- runger_style (5.14.0)
138
+ runger_style (5.19.1)
139
139
  prism (>= 0.24.0)
140
140
  rubocop (>= 1.72.0)
141
141
  securerandom (0.4.1)
@@ -177,7 +177,7 @@ CHECKSUMS
177
177
  diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962
178
178
  drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373
179
179
  erb (6.0.7) sha256=c5ca6dc25b0ef974a44dc8f59fe847577122483b1968a38dec305c60bf91ee92
180
- fcom (0.15.1)
180
+ fcom (1.0.1)
181
181
  i18n (1.15.2) sha256=00f9eb62412fe593b2a65a97daa75300d37abb8f7202ec748e94b6d46a9dd1b5
182
182
  io-console (0.9.2) sha256=efa74f891dd03c0939a931dfc6e74c2813d904763d456ea9762b0525e748db08
183
183
  irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3
@@ -198,7 +198,7 @@ CHECKSUMS
198
198
  racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f
199
199
  rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a
200
200
  rake (13.4.2) sha256=cb825b2bd5f1f8e91ca37bddb4b9aaf345551b4731da62949be002fa89283701
201
- rbs (4.1.3) sha256=0c4474a9751cdc14364bfad0b3e53678323bbdc2c31683b0445932867dbab8c4
201
+ rbs (4.2.0) sha256=51f7b886dcc05bc09e10b901daa6a81829f6adc03101d6ca9ea4aac6103e0674
202
202
  rdoc (8.0.0) sha256=03bf8c08a9639658855a0cfd77c0abca8325c227693f7f33f82957811348c469
203
203
  readline (0.0.4) sha256=6138eef17be2b98298b672c3ea63bf9cb5158d401324f26e1e84f235879c1d6a
204
204
  regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb
@@ -208,15 +208,15 @@ CHECKSUMS
208
208
  rspec-expectations (3.13.5) sha256=33a4d3a1d95060aea4c94e9f237030a8f9eae5615e9bd85718fe3a09e4b58836
209
209
  rspec-mocks (3.13.8) sha256=086ad3d3d17533f4237643de0b5c42f04b66348c28bf6b9c2d3f4a3b01af1d47
210
210
  rspec-support (3.13.7) sha256=0640e5570872aafefd79867901deeeeb40b0c9875a36b983d85f54fb7381c47c
211
- rubocop (1.89.0) sha256=4dee8e3ee9c45e474834efd9e8d6fd031e8331c8dacdff0de4ad65ae0a6faae7
211
+ rubocop (1.90.0) sha256=9eb4c065b5c5154e4ef554c547972f3905a9eb6b53e657e580b6796b54bf8242
212
212
  rubocop-ast (1.50.0) sha256=b9ca88300da0803ee222ad20cdb30494c0a784eed06fdc35d254b06d662788db
213
- rubocop-performance (1.26.1) sha256=cd19b936ff196df85829d264b522fd4f98b6c89ad271fa52744a8c11b8f71834
213
+ rubocop-performance (1.27.0) sha256=eeeb1374d062a368ee1c787b70eb0b0cc4b184cb1f8565f424760946146d61ce
214
214
  rubocop-rake (0.7.1) sha256=3797f2b6810c3e9df7376c26d5f44f3475eda59eb1adc38e6f62ecf027cbae4d
215
215
  rubocop-rspec (3.10.2) sha256=0b3e2ecc592cd10ecbf0095bb58d1e357905276e069643523cc19eb7495f65e2
216
216
  ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33
217
217
  runger_byebug (11.4.0) sha256=569e22ba2215f57e7f69e145fcb63be401e29fcd312f7936d813e12d0c7bbee6
218
218
  runger_release_assistant (4.3.1) sha256=3246c925240739eb12b9e6b9526a77ea00fcf0a0941441ff5ffacefb7e3e4d83
219
- runger_style (5.14.0) sha256=4fbed1be49c06a3f3358e47cedfce7d1d0e20d8aeaef22e751d0742f1b8c5755
219
+ runger_style (5.19.1) sha256=d085f17bbfd0f9356692b0bc65199f4e9fb08a87d15b4bffe4bbd61368f9874e
220
220
  securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1
221
221
  slop (4.10.1) sha256=844322b5ffcf17ed4815fdb173b04a20dd82b4fd93e3744c88c8fafea696d9c7
222
222
  tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f
data/README.md CHANGED
@@ -4,8 +4,7 @@
4
4
 
5
5
  This is a CLI tool that I use to parse the git history of a repo.
6
6
 
7
- For example, if I use `fcom` to search this repo with `fcom "line.(green|red)" --regex --repo
8
- davidrunger/fcom`, I get this output:
7
+ For example, if I use `fcom` to search this repo with `fcom "line.(green|red)" --repo davidrunger/fcom`, I get this output:
9
8
 
10
9
  ![](https://s3.amazonaws.com/screens.davidrunger.com/2019-12-28-20-50-09-oect2(1).png)
11
10
 
@@ -58,24 +57,24 @@ Usage: fcom <search string> [options]
58
57
 
59
58
  Examples:
60
59
  fcom update
61
- fcom 'def update'
60
+ fcom 'user.update!' --fixed-strings
62
61
  fcom "def update" --days 60
63
- fcom "[Uu]ser.*slug" -d 365 --regex
62
+ fcom "[Uu]ser.*slug" -d 365
64
63
  fcom options --path spec/
65
- fcom "line.(green|red)" -d 365 --regex --repo davidrunger/fcom -a "David Runger"
66
-
67
- --repo GitHub repo (in form `username/repo`)
68
- -d, --days number of days to search back
69
- -c, --commits maximum number of commits to show
70
- -r, --regex interpret search string as a regular expression
71
- -i, --ignore-case search case-insensitively
72
- -p, --path path (directory or file) used to filter results
73
- -a, --author author
74
- --rg-options additional options passed directly to `rg` (e.g. `--rg-options "--max-columns 1000"`)
75
- --debug print debugging info
76
- --init create an `.fcom.yml` config file
77
- -v, --version print the version
78
- -h, --help print this help information
64
+ fcom "line.(green|red)" -d 365 --repo davidrunger/fcom -a "David Runger"
65
+
66
+ --repo GitHub repo (in form `username/repo`)
67
+ -d, --days number of days to search back
68
+ -c, --commits maximum number of commits to show
69
+ -F, --fixed-strings interpret search string as a fixed string
70
+ -i, --ignore-case search case-insensitively
71
+ -p, --path path (directory or file) used to filter results
72
+ -a, --author author
73
+ --rg-options additional options passed directly to `rg` (e.g. `--rg-options "--max-columns 1000"`)
74
+ --debug print debugging info
75
+ --init create an `.fcom.yml` config file
76
+ -v, --version print the version
77
+ -h, --help print this help information
79
78
  ```
80
79
 
81
80
  ## The `.fcom.yml` config file
data/exe/fcom CHANGED
@@ -16,11 +16,11 @@ opts =
16
16
 
17
17
  Examples:
18
18
  fcom update
19
- fcom 'def update'
19
+ fcom 'user.update!' --fixed-strings
20
20
  fcom "def update" --days 60
21
- fcom "[Uu]ser.*slug" -d 365 --regex
21
+ fcom "[Uu]ser.*slug" -d 365
22
22
  fcom options --path spec/
23
- fcom "line.(green|red)" -d 365 --regex --repo davidrunger/fcom -a "David Runger"
23
+ fcom "line.(green|red)" -d 365 --repo davidrunger/fcom -a "David Runger"
24
24
  BANNER
25
25
 
26
26
  Fcom.define_slop_options(o)
@@ -41,7 +41,9 @@ opts =
41
41
  end
42
42
 
43
43
  # Note: mutating the globally accessible `Fcom.logger` constant like this is not thread-safe
44
- Fcom.logger.level = Logger::DEBUG if opts.debug?
44
+ if opts.debug?
45
+ Fcom.logger.level = Logger::DEBUG
46
+ end
45
47
 
46
48
  if !system('which rg > /dev/null')
47
49
  puts("fcom requires that `rg` (ripgrep) be available on your PATH, but it's not.".red)
@@ -24,8 +24,8 @@ module Fcom::OptionsHelpers
24
24
  @options[:path]
25
25
  end
26
26
 
27
- def regex_mode?
28
- @options.regex?
27
+ def fixed_strings?
28
+ @options.fixed_strings?
29
29
  end
30
30
 
31
31
  def debug?
data/lib/fcom/parser.rb CHANGED
@@ -14,8 +14,12 @@ class Fcom::Parser
14
14
  end
15
15
 
16
16
  def parse
17
- expression_to_match = search_string
18
- expression_to_match = Regexp.escape(expression_to_match).gsub('\\ ', ' ') unless regex_mode?
17
+ expression_to_match =
18
+ if fixed_strings?
19
+ Regexp.escape(search_string).gsub('\\ ', ' ')
20
+ else
21
+ search_string
22
+ end
19
23
  regex =
20
24
  Regexp.new(
21
25
  "((\\+|-)\\s?.*#{expression_to_match}.*|Omitted long (matching )?line)",
@@ -28,7 +32,9 @@ class Fcom::Parser
28
32
  $stdin.each do |line|
29
33
  line.chomp!
30
34
  if (match = line.match(/^commit (.*)/)&.[](1))
31
- break if commit_limit_reached?
35
+ if commit_limit_reached?
36
+ break
37
+ end
32
38
 
33
39
  previous_commit = match
34
40
  elsif line.match?(/^diff /)
@@ -45,7 +51,9 @@ class Fcom::Parser
45
51
  short_sha = sha[0, 8]
46
52
  sha_with_url = "#{short_sha} ( https://github.com/#{repo}/commit/#{short_sha} )"
47
53
 
48
- puts("\n\n") if a_commit_has_matched # print commit separator, if needed
54
+ if a_commit_has_matched # print commit separator, if needed
55
+ puts("\n\n")
56
+ end
49
57
  puts([title, sha_with_url, author, date])
50
58
  puts(COMMIT_HEADER_SEPARATOR)
51
59
 
@@ -77,8 +85,10 @@ class Fcom::Parser
77
85
  end
78
86
 
79
87
  def path_match?(filename)
80
- return true if path == Fcom::ROOT_PATH
81
-
82
- filename.include?(path.delete_prefix('./'))
88
+ if path == Fcom::ROOT_PATH
89
+ true
90
+ else
91
+ filename.include?(path.delete_prefix('./'))
92
+ end
83
93
  end
84
94
  end
data/lib/fcom/querier.rb CHANGED
@@ -16,8 +16,12 @@ class Fcom::Querier
16
16
  end
17
17
 
18
18
  def query
19
- expression_to_match = search_string
20
- expression_to_match = Regexp.escape(expression_to_match).gsub('\\ ', ' ') unless regex_mode?
19
+ expression_to_match =
20
+ if fixed_strings?
21
+ Regexp.escape(search_string).gsub('\\ ', ' ')
22
+ else
23
+ search_string
24
+ end
21
25
 
22
26
  if expression_to_match.nil? || expression_to_match.empty?
23
27
  puts('provide expression to match as first argument')
@@ -30,7 +34,9 @@ class Fcom::Querier
30
34
  remaining_commits = commits
31
35
 
32
36
  filename_by_most_recent_containing_commit.each do |commit, path_at_commit|
33
- break if remaining_commits && remaining_commits <= 0
37
+ if remaining_commits && remaining_commits <= 0
38
+ break
39
+ end
34
40
 
35
41
  command = query_command(commit, path_at_commit, expression_to_match, quote, remaining_commits)
36
42
  Fcom.logger.debug("Executing command: #{command}")
@@ -43,7 +49,7 @@ class Fcom::Querier
43
49
  if first_byte
44
50
  # Add spacing if needed
45
51
  if a_previous_command_generated_output_not_yet_spaced
46
- print "\n\n"
52
+ print("\n\n")
47
53
  end
48
54
 
49
55
  a_previous_command_generated_output_not_yet_spaced = true
@@ -53,14 +59,18 @@ class Fcom::Querier
53
59
  # Now read the rest line by line
54
60
  stdout.each_line do |line|
55
61
  puts(line)
56
- commits_printed += 1 if line.chomp == Fcom::Parser::COMMIT_HEADER_SEPARATOR
62
+ if line.chomp == Fcom::Parser::COMMIT_HEADER_SEPARATOR
63
+ commits_printed += 1
64
+ end
57
65
  end
58
66
  end
59
67
  rescue Errno::EIO
60
68
  # The command produced no output.
61
69
  end
62
70
 
63
- remaining_commits -= commits_printed if remaining_commits
71
+ if remaining_commits
72
+ remaining_commits -= commits_printed
73
+ end
64
74
  end
65
75
  rescue Interrupt
66
76
  puts("\nSearch interrupted.")
@@ -84,12 +94,15 @@ class Fcom::Querier
84
94
  git log
85
95
  --format="commit %s|%H|%an|%cr (%ci)"
86
96
  --patch
97
+ --unified=0
87
98
  --full-diff
88
99
  --diff-algorithm=default
89
100
  --topo-order
90
101
  --no-textconv
91
102
  --stdin
92
- #{%(--author="#{author}") if author}
103
+ #{if author
104
+ %(--author="#{author}")
105
+ end}
93
106
  #{days_limiter}
94
107
  --
95
108
  #{path_at_commit}
@@ -97,16 +110,30 @@ class Fcom::Querier
97
110
 
98
111
  rg #{quote}(#{expression_to_match})|(^commit )|(^diff )#{quote}
99
112
  --color never
100
- #{'--ignore-case' if ignore_case?}
113
+ #{if ignore_case?
114
+ '--ignore-case'
115
+ end}
101
116
  #{@options[:rg_options]}
102
117
  |
103
118
 
104
- #{File.join(__dir__, '../../exe/') if development?}fcom #{quote}#{search_string}#{quote}
105
- #{"--days #{days}" if days}
106
- #{"--commits #{commits_limit}" if commits_limit}
107
- #{'--regex' if regex_mode?}
108
- #{'--debug' if debug?}
109
- #{'--ignore-case' if ignore_case?}
119
+ #{if development?
120
+ File.join(__dir__, '../../exe/')
121
+ end}fcom #{quote}#{search_string}#{quote}
122
+ #{if days
123
+ "--days #{days}"
124
+ end}
125
+ #{if commits_limit
126
+ "--commits #{commits_limit}"
127
+ end}
128
+ #{if fixed_strings?
129
+ '--fixed-strings'
130
+ end}
131
+ #{if debug?
132
+ '--debug'
133
+ end}
134
+ #{if ignore_case?
135
+ '--ignore-case'
136
+ end}
110
137
  --path #{path_at_commit}
111
138
  --parse-mode
112
139
  --repo #{repo}
data/lib/fcom/version.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # rubocop:disable Style/StaticClass
3
+ # rubocop:disable-next Style/StaticClass
4
4
  class Fcom
5
- VERSION = '0.15.1'
5
+ VERSION = '1.0.1'
6
6
  end
7
- # rubocop:enable Style/StaticClass
data/lib/fcom.rb CHANGED
@@ -10,10 +10,9 @@ using Rainbow
10
10
 
11
11
  # This `Fcom` class is the namespace within which most of the gem's code is written.
12
12
  # We need to define the class before requiring the modules.
13
- # rubocop:disable Lint/EmptyClass
13
+ # rubocop:disable-next Lint/EmptyClass
14
14
  class Fcom
15
15
  end
16
- # rubocop:enable Lint/EmptyClass
17
16
 
18
17
  Dir["#{File.dirname(__FILE__)}/fcom/*.rb"].each { |file| require file }
19
18
 
@@ -56,9 +55,9 @@ class Fcom
56
55
  options.integer('-d', '--days', 'number of days to search back')
57
56
  options.integer('-c', '--commits', 'maximum number of commits to show')
58
57
  options.bool(
59
- '-r',
60
- '--regex',
61
- 'interpret search string as a regular expression',
58
+ '-F',
59
+ '--fixed-strings',
60
+ 'interpret search string as a fixed string',
62
61
  default: false,
63
62
  )
64
63
  options.bool('-i', '--ignore-case', 'search case-insensitively', default: false)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fcom
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.1
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Runger