git-pkgs 0.3.0 → 0.4.0
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 +12 -0
- data/CONTRIBUTING.md +27 -0
- data/LICENSE +189 -189
- data/README.md +41 -0
- data/SECURITY.md +7 -0
- data/lib/git/pkgs/analyzer.rb +1 -1
- data/lib/git/pkgs/cli.rb +5 -2
- data/lib/git/pkgs/color.rb +1 -0
- data/lib/git/pkgs/commands/blame.rb +1 -1
- data/lib/git/pkgs/commands/diff_driver.rb +169 -0
- data/lib/git/pkgs/commands/info.rb +5 -1
- data/lib/git/pkgs/commands/init.rb +10 -8
- data/lib/git/pkgs/commands/where.rb +166 -0
- data/lib/git/pkgs/version.rb +1 -1
- data/lib/git/pkgs.rb +2 -0
- metadata +6 -1
data/README.md
CHANGED
|
@@ -258,6 +258,23 @@ git pkgs show HEAD~5 # relative ref
|
|
|
258
258
|
|
|
259
259
|
Like `git show` but for dependencies. Shows what was added, modified, or removed in a single commit.
|
|
260
260
|
|
|
261
|
+
### Find where a package is declared
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
git pkgs where rails # find in manifest files
|
|
265
|
+
git pkgs where lodash -C 2 # show 2 lines of context
|
|
266
|
+
git pkgs where express --ecosystem=npm
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
Shows which manifest files declare a package and the exact line:
|
|
270
|
+
|
|
271
|
+
```
|
|
272
|
+
Gemfile:5:gem "rails", "~> 7.0"
|
|
273
|
+
Gemfile.lock:142: rails (7.0.8)
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
Like `grep` but scoped to manifest files that git-pkgs knows about.
|
|
277
|
+
|
|
261
278
|
### List commits with dependency changes
|
|
262
279
|
|
|
263
280
|
```bash
|
|
@@ -328,6 +345,30 @@ jobs:
|
|
|
328
345
|
- run: git pkgs diff --from=origin/${{ github.base_ref }} --to=HEAD
|
|
329
346
|
```
|
|
330
347
|
|
|
348
|
+
### Diff driver
|
|
349
|
+
|
|
350
|
+
Install a git textconv driver that shows semantic dependency changes instead of raw lockfile diffs:
|
|
351
|
+
|
|
352
|
+
```bash
|
|
353
|
+
git pkgs diff-driver --install
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
Now `git diff` on lockfiles shows a sorted dependency list instead of raw lockfile changes:
|
|
357
|
+
|
|
358
|
+
```diff
|
|
359
|
+
diff --git a/Gemfile.lock b/Gemfile.lock
|
|
360
|
+
--- a/Gemfile.lock
|
|
361
|
+
+++ b/Gemfile.lock
|
|
362
|
+
@@ -1,3 +1,3 @@
|
|
363
|
+
+kamal 1.0.0
|
|
364
|
+
-puma 5.0.0
|
|
365
|
+
+puma 6.0.0
|
|
366
|
+
rails 7.0.0
|
|
367
|
+
-sidekiq 6.0.0
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
Use `git diff --no-textconv` to see the raw lockfile diff. To remove: `git pkgs diff-driver --uninstall`
|
|
371
|
+
|
|
331
372
|
## Configuration
|
|
332
373
|
|
|
333
374
|
git-pkgs respects [standard git configuration](https://git-scm.com/docs/git-config).
|
data/SECURITY.md
ADDED
data/lib/git/pkgs/analyzer.rb
CHANGED
|
@@ -46,7 +46,7 @@ module Git
|
|
|
46
46
|
QUICK_MANIFEST_REGEX = Regexp.union(
|
|
47
47
|
QUICK_MANIFEST_PATTERNS.map do |pattern|
|
|
48
48
|
if pattern.include?('*')
|
|
49
|
-
Regexp.new(
|
|
49
|
+
Regexp.new(Regexp.escape(pattern).gsub('\\*', '.*'))
|
|
50
50
|
else
|
|
51
51
|
/(?:^|\/)#{Regexp.escape(pattern)}$/
|
|
52
52
|
end
|
data/lib/git/pkgs/cli.rb
CHANGED
|
@@ -5,7 +5,7 @@ require "optparse"
|
|
|
5
5
|
module Git
|
|
6
6
|
module Pkgs
|
|
7
7
|
class CLI
|
|
8
|
-
COMMANDS = %w[init update hooks info list tree history search why blame stale stats diff branch show log upgrade schema].freeze
|
|
8
|
+
COMMANDS = %w[init update hooks info list tree history search where why blame stale stats diff branch show log upgrade schema diff-driver].freeze
|
|
9
9
|
ALIASES = { "praise" => "blame", "outdated" => "stale" }.freeze
|
|
10
10
|
|
|
11
11
|
def self.run(args)
|
|
@@ -36,7 +36,9 @@ module Git
|
|
|
36
36
|
|
|
37
37
|
def run_command(command)
|
|
38
38
|
command = ALIASES.fetch(command, command)
|
|
39
|
-
|
|
39
|
+
# Convert kebab-case or snake_case to PascalCase
|
|
40
|
+
class_name = command.split(/[-_]/).map(&:capitalize).join
|
|
41
|
+
command_class = Commands.const_get(class_name)
|
|
40
42
|
command_class.new(@args).run
|
|
41
43
|
rescue NameError
|
|
42
44
|
$stderr.puts "Command '#{command}' not yet implemented"
|
|
@@ -57,6 +59,7 @@ module Git
|
|
|
57
59
|
tree Show dependency tree grouped by type
|
|
58
60
|
history Show the history of a package
|
|
59
61
|
search Find a dependency across all history
|
|
62
|
+
where Show where a package appears in manifest files
|
|
60
63
|
why Explain why a dependency exists
|
|
61
64
|
blame Show who added each dependency
|
|
62
65
|
stale Show dependencies that haven't been updated
|
data/lib/git/pkgs/color.rb
CHANGED
|
@@ -74,6 +74,7 @@ module Git
|
|
|
74
74
|
def self.green(text) = colorize(text, :green)
|
|
75
75
|
def self.yellow(text) = colorize(text, :yellow)
|
|
76
76
|
def self.blue(text) = colorize(text, :blue)
|
|
77
|
+
def self.magenta(text) = colorize(text, :magenta)
|
|
77
78
|
def self.cyan(text) = colorize(text, :cyan)
|
|
78
79
|
def self.bold(text) = colorize(text, :bold)
|
|
79
80
|
def self.dim(text) = colorize(text, :dim)
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bibliothecary"
|
|
4
|
+
|
|
5
|
+
module Git
|
|
6
|
+
module Pkgs
|
|
7
|
+
module Commands
|
|
8
|
+
class DiffDriver
|
|
9
|
+
include Output
|
|
10
|
+
|
|
11
|
+
# Only lockfiles - manifests are human-readable and diff fine normally
|
|
12
|
+
LOCKFILE_PATTERNS = %w[
|
|
13
|
+
Brewfile.lock.json
|
|
14
|
+
Cargo.lock
|
|
15
|
+
Cartfile.resolved
|
|
16
|
+
Gemfile.lock
|
|
17
|
+
Gopkg.lock
|
|
18
|
+
Package.resolved
|
|
19
|
+
Pipfile.lock
|
|
20
|
+
Podfile.lock
|
|
21
|
+
Project.lock.json
|
|
22
|
+
bun.lock
|
|
23
|
+
composer.lock
|
|
24
|
+
gems.locked
|
|
25
|
+
glide.lock
|
|
26
|
+
go.sum
|
|
27
|
+
mix.lock
|
|
28
|
+
npm-shrinkwrap.json
|
|
29
|
+
package-lock.json
|
|
30
|
+
packages.lock.json
|
|
31
|
+
paket.lock
|
|
32
|
+
pnpm-lock.yaml
|
|
33
|
+
poetry.lock
|
|
34
|
+
project.assets.json
|
|
35
|
+
pubspec.lock
|
|
36
|
+
pylock.toml
|
|
37
|
+
shard.lock
|
|
38
|
+
uv.lock
|
|
39
|
+
yarn.lock
|
|
40
|
+
].freeze
|
|
41
|
+
|
|
42
|
+
def initialize(args)
|
|
43
|
+
@args = args
|
|
44
|
+
@options = parse_options
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def run
|
|
48
|
+
if @options[:install]
|
|
49
|
+
install_driver
|
|
50
|
+
return
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
if @options[:uninstall]
|
|
54
|
+
uninstall_driver
|
|
55
|
+
return
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# textconv mode: single file argument, output dependency list
|
|
59
|
+
if @args.length == 1
|
|
60
|
+
output_textconv(@args[0])
|
|
61
|
+
return
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
error "Usage: git pkgs diff-driver <file>"
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def output_textconv(file_path)
|
|
68
|
+
content = read_file(file_path)
|
|
69
|
+
deps = parse_deps(file_path, content)
|
|
70
|
+
|
|
71
|
+
# Output sorted dependency list for git to diff
|
|
72
|
+
deps.keys.sort.each do |name|
|
|
73
|
+
dep = deps[name]
|
|
74
|
+
# Only show type if it's not runtime (the default)
|
|
75
|
+
type_suffix = dep[:type] && dep[:type] != "runtime" ? " [#{dep[:type]}]" : ""
|
|
76
|
+
puts "#{name} #{dep[:requirement]}#{type_suffix}"
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def install_driver
|
|
81
|
+
# Set up git config for textconv
|
|
82
|
+
system("git", "config", "diff.pkgs.textconv", "git-pkgs diff-driver")
|
|
83
|
+
|
|
84
|
+
# Add to .gitattributes
|
|
85
|
+
gitattributes_path = File.join(Dir.pwd, ".gitattributes")
|
|
86
|
+
existing = File.exist?(gitattributes_path) ? File.read(gitattributes_path) : ""
|
|
87
|
+
|
|
88
|
+
new_entries = []
|
|
89
|
+
LOCKFILE_PATTERNS.each do |pattern|
|
|
90
|
+
entry = "#{pattern} diff=pkgs"
|
|
91
|
+
new_entries << entry unless existing.include?(entry)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
if new_entries.any?
|
|
95
|
+
File.open(gitattributes_path, "a") do |f|
|
|
96
|
+
f.puts unless existing.end_with?("\n") || existing.empty?
|
|
97
|
+
f.puts "# git-pkgs textconv for lockfiles"
|
|
98
|
+
new_entries.each { |entry| f.puts entry }
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
puts "Installed textconv driver for lockfiles."
|
|
103
|
+
puts " git config: diff.pkgs.textconv = git-pkgs diff-driver"
|
|
104
|
+
puts " .gitattributes: #{new_entries.count} lockfile patterns added"
|
|
105
|
+
puts
|
|
106
|
+
puts "Now 'git diff' on lockfiles shows dependency changes."
|
|
107
|
+
puts "Use 'git diff --no-textconv' to see raw diff."
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def uninstall_driver
|
|
111
|
+
system("git", "config", "--unset", "diff.pkgs.textconv")
|
|
112
|
+
|
|
113
|
+
gitattributes_path = File.join(Dir.pwd, ".gitattributes")
|
|
114
|
+
if File.exist?(gitattributes_path)
|
|
115
|
+
lines = File.readlines(gitattributes_path)
|
|
116
|
+
lines.reject! { |line| line.include?("diff=pkgs") || line.include?("# git-pkgs") }
|
|
117
|
+
File.write(gitattributes_path, lines.join)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
puts "Uninstalled diff driver."
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def read_file(path)
|
|
124
|
+
return "" if path == "/dev/null"
|
|
125
|
+
return "" unless File.exist?(path)
|
|
126
|
+
|
|
127
|
+
File.read(path)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def parse_deps(path, content)
|
|
131
|
+
return {} if content.empty?
|
|
132
|
+
|
|
133
|
+
result = Bibliothecary.analyse_file(path, content).first
|
|
134
|
+
return {} unless result
|
|
135
|
+
|
|
136
|
+
result[:dependencies].map { |d| [d[:name], d] }.to_h
|
|
137
|
+
rescue StandardError
|
|
138
|
+
{}
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def parse_options
|
|
142
|
+
options = {}
|
|
143
|
+
|
|
144
|
+
parser = OptionParser.new do |opts|
|
|
145
|
+
opts.banner = "Usage: git pkgs diff-driver <file>"
|
|
146
|
+
opts.separator ""
|
|
147
|
+
opts.separator "Outputs dependency list for git textconv diffing."
|
|
148
|
+
|
|
149
|
+
opts.on("--install", "Install textconv driver for lockfiles") do
|
|
150
|
+
options[:install] = true
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
opts.on("--uninstall", "Uninstall textconv driver") do
|
|
154
|
+
options[:uninstall] = true
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
opts.on("-h", "--help", "Show this help") do
|
|
158
|
+
puts opts
|
|
159
|
+
exit
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
parser.parse!(@args)
|
|
164
|
+
options
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
end
|
|
@@ -69,7 +69,11 @@ module Git
|
|
|
69
69
|
puts " Commits with snapshots: #{snapshot_commits}"
|
|
70
70
|
if total_dep_commits > 0
|
|
71
71
|
ratio = (snapshot_commits.to_f / total_dep_commits * 100).round(1)
|
|
72
|
-
|
|
72
|
+
if snapshot_commits > 0
|
|
73
|
+
puts " Coverage: #{ratio}% (1 snapshot per ~#{(total_dep_commits / snapshot_commits)} changes)"
|
|
74
|
+
else
|
|
75
|
+
puts " Coverage: #{ratio}%"
|
|
76
|
+
end
|
|
73
77
|
end
|
|
74
78
|
end
|
|
75
79
|
|
|
@@ -17,6 +17,9 @@ module Git
|
|
|
17
17
|
def run
|
|
18
18
|
repo = Repository.new
|
|
19
19
|
|
|
20
|
+
branch_name = @options[:branch] || repo.default_branch
|
|
21
|
+
error "Branch '#{branch_name}' not found" unless repo.branch_exists?(branch_name)
|
|
22
|
+
|
|
20
23
|
if Database.exists?(repo.git_dir) && !@options[:force]
|
|
21
24
|
puts "Database already exists. Use --force to rebuild."
|
|
22
25
|
return
|
|
@@ -27,9 +30,6 @@ module Git
|
|
|
27
30
|
Database.create_schema(with_indexes: false)
|
|
28
31
|
Database.optimize_for_bulk_writes
|
|
29
32
|
|
|
30
|
-
branch_name = @options[:branch] || repo.default_branch
|
|
31
|
-
error "Branch '#{branch_name}' not found" unless repo.branch_exists?(branch_name)
|
|
32
|
-
|
|
33
33
|
branch = Models::Branch.find_or_create(branch_name)
|
|
34
34
|
analyzer = Analyzer.new(repo)
|
|
35
35
|
|
|
@@ -73,6 +73,7 @@ module Git
|
|
|
73
73
|
dependency_commit_count = 0
|
|
74
74
|
snapshots_stored = 0
|
|
75
75
|
processed = 0
|
|
76
|
+
last_processed_sha = nil
|
|
76
77
|
|
|
77
78
|
flush = lambda do
|
|
78
79
|
return if pending_commits.empty?
|
|
@@ -160,6 +161,8 @@ module Git
|
|
|
160
161
|
position: processed
|
|
161
162
|
}
|
|
162
163
|
|
|
164
|
+
last_processed_sha = rugged_commit.oid
|
|
165
|
+
|
|
163
166
|
if has_changes
|
|
164
167
|
dependency_commit_count += 1
|
|
165
168
|
|
|
@@ -206,13 +209,12 @@ module Git
|
|
|
206
209
|
flush.call if pending_commits.size >= BATCH_SIZE
|
|
207
210
|
end
|
|
208
211
|
|
|
209
|
-
# Always store final snapshot for
|
|
210
|
-
if snapshot.any?
|
|
211
|
-
|
|
212
|
-
if last_sha && !pending_snapshots.any? { |s| s[:sha] == last_sha }
|
|
212
|
+
# Always store final snapshot for the last processed commit
|
|
213
|
+
if snapshot.any? && last_processed_sha
|
|
214
|
+
unless pending_snapshots.any? { |s| s[:sha] == last_processed_sha }
|
|
213
215
|
snapshot.each do |(manifest_path, name), dep_info|
|
|
214
216
|
pending_snapshots << {
|
|
215
|
-
sha:
|
|
217
|
+
sha: last_processed_sha,
|
|
216
218
|
manifest_path: manifest_path,
|
|
217
219
|
name: name,
|
|
218
220
|
ecosystem: dep_info[:ecosystem],
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Git
|
|
4
|
+
module Pkgs
|
|
5
|
+
module Commands
|
|
6
|
+
class Where
|
|
7
|
+
include Output
|
|
8
|
+
|
|
9
|
+
def initialize(args)
|
|
10
|
+
@args = args
|
|
11
|
+
@options = parse_options
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def run
|
|
15
|
+
name = @args.first
|
|
16
|
+
|
|
17
|
+
error "Usage: git pkgs where <package-name>" unless name
|
|
18
|
+
|
|
19
|
+
repo = Repository.new
|
|
20
|
+
require_database(repo)
|
|
21
|
+
|
|
22
|
+
Database.connect(repo.git_dir)
|
|
23
|
+
|
|
24
|
+
workdir = File.dirname(repo.git_dir)
|
|
25
|
+
branch = Models::Branch.find_by(name: @options[:branch] || repo.default_branch)
|
|
26
|
+
|
|
27
|
+
unless branch
|
|
28
|
+
error "Branch not found. Run 'git pkgs init' first."
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
snapshots = Models::DependencySnapshot.current_for_branch(branch)
|
|
32
|
+
snapshots = snapshots.where(ecosystem: @options[:ecosystem]) if @options[:ecosystem]
|
|
33
|
+
|
|
34
|
+
manifest_paths = snapshots.for_package(name).joins(:manifest).pluck("manifests.path").uniq
|
|
35
|
+
|
|
36
|
+
if manifest_paths.empty?
|
|
37
|
+
empty_result "Package '#{name}' not found in current dependencies"
|
|
38
|
+
return
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
results = manifest_paths.flat_map do |path|
|
|
42
|
+
find_in_manifest(name, File.join(workdir, path), path)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
if results.empty?
|
|
46
|
+
empty_result "Package '#{name}' tracked but not found in current files"
|
|
47
|
+
return
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
if @options[:format] == "json"
|
|
51
|
+
output_json(results)
|
|
52
|
+
else
|
|
53
|
+
paginate { output_text(results, name) }
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def find_in_manifest(name, full_path, display_path)
|
|
58
|
+
return [] unless File.exist?(full_path)
|
|
59
|
+
|
|
60
|
+
lines = File.readlines(full_path)
|
|
61
|
+
matches = []
|
|
62
|
+
|
|
63
|
+
lines.each_with_index do |line, idx|
|
|
64
|
+
next unless line.include?(name)
|
|
65
|
+
|
|
66
|
+
match = { path: display_path, line: idx + 1, content: line.rstrip }
|
|
67
|
+
|
|
68
|
+
if context_lines > 0
|
|
69
|
+
match[:before] = context_before(lines, idx)
|
|
70
|
+
match[:after] = context_after(lines, idx)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
matches << match
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
matches
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def context_lines
|
|
80
|
+
@options[:context] || 0
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def context_before(lines, idx)
|
|
84
|
+
start_idx = [0, idx - context_lines].max
|
|
85
|
+
(start_idx...idx).map { |i| { line: i + 1, content: lines[i].rstrip } }
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def context_after(lines, idx)
|
|
89
|
+
end_idx = [lines.length - 1, idx + context_lines].min
|
|
90
|
+
((idx + 1)..end_idx).map { |i| { line: i + 1, content: lines[i].rstrip } }
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def output_text(results, name)
|
|
94
|
+
results.each_with_index do |result, i|
|
|
95
|
+
puts "--" if i > 0 && context_lines > 0
|
|
96
|
+
|
|
97
|
+
result[:before]&.each do |ctx|
|
|
98
|
+
puts format_context_line(result[:path], ctx[:line], ctx[:content])
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
puts format_match_line(result[:path], result[:line], result[:content], name)
|
|
102
|
+
|
|
103
|
+
result[:after]&.each do |ctx|
|
|
104
|
+
puts format_context_line(result[:path], ctx[:line], ctx[:content])
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def format_match_line(path, line_num, content, name)
|
|
110
|
+
path_str = Color.magenta(path)
|
|
111
|
+
line_str = Color.green(line_num.to_s)
|
|
112
|
+
highlighted = content.gsub(name, Color.red(name))
|
|
113
|
+
"#{path_str}:#{line_str}:#{highlighted}"
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def format_context_line(path, line_num, content)
|
|
117
|
+
path_str = Color.magenta(path)
|
|
118
|
+
line_str = Color.green(line_num.to_s)
|
|
119
|
+
content_str = Color.dim(content)
|
|
120
|
+
"#{path_str}-#{line_str}-#{content_str}"
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def output_json(results)
|
|
124
|
+
require "json"
|
|
125
|
+
puts JSON.pretty_generate(results)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def parse_options
|
|
129
|
+
options = {}
|
|
130
|
+
|
|
131
|
+
parser = OptionParser.new do |opts|
|
|
132
|
+
opts.banner = "Usage: git pkgs where <package-name> [options]"
|
|
133
|
+
|
|
134
|
+
opts.on("-b", "--branch=NAME", "Branch to search (default: current)") do |v|
|
|
135
|
+
options[:branch] = v
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
opts.on("-e", "--ecosystem=NAME", "Filter by ecosystem") do |v|
|
|
139
|
+
options[:ecosystem] = v
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
opts.on("-C", "--context=NUM", Integer, "Show NUM lines of context") do |v|
|
|
143
|
+
options[:context] = v
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
opts.on("-f", "--format=FORMAT", "Output format (text, json)") do |v|
|
|
147
|
+
options[:format] = v
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
opts.on("--no-pager", "Do not pipe output into a pager") do
|
|
151
|
+
options[:no_pager] = true
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
opts.on("-h", "--help", "Show this help") do
|
|
155
|
+
puts opts
|
|
156
|
+
exit
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
parser.parse!(@args)
|
|
161
|
+
options
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|
data/lib/git/pkgs/version.rb
CHANGED
data/lib/git/pkgs.rb
CHANGED
|
@@ -30,9 +30,11 @@ require_relative "pkgs/commands/tree"
|
|
|
30
30
|
require_relative "pkgs/commands/branch"
|
|
31
31
|
require_relative "pkgs/commands/search"
|
|
32
32
|
require_relative "pkgs/commands/show"
|
|
33
|
+
require_relative "pkgs/commands/where"
|
|
33
34
|
require_relative "pkgs/commands/log"
|
|
34
35
|
require_relative "pkgs/commands/upgrade"
|
|
35
36
|
require_relative "pkgs/commands/schema"
|
|
37
|
+
require_relative "pkgs/commands/diff_driver"
|
|
36
38
|
|
|
37
39
|
module Git
|
|
38
40
|
module Pkgs
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: git-pkgs
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrew Nesbitt
|
|
@@ -76,9 +76,11 @@ extra_rdoc_files: []
|
|
|
76
76
|
files:
|
|
77
77
|
- CHANGELOG.md
|
|
78
78
|
- CODE_OF_CONDUCT.md
|
|
79
|
+
- CONTRIBUTING.md
|
|
79
80
|
- LICENSE
|
|
80
81
|
- README.md
|
|
81
82
|
- Rakefile
|
|
83
|
+
- SECURITY.md
|
|
82
84
|
- benchmark_bulk.rb
|
|
83
85
|
- benchmark_db.rb
|
|
84
86
|
- benchmark_detailed.rb
|
|
@@ -92,6 +94,7 @@ files:
|
|
|
92
94
|
- lib/git/pkgs/commands/blame.rb
|
|
93
95
|
- lib/git/pkgs/commands/branch.rb
|
|
94
96
|
- lib/git/pkgs/commands/diff.rb
|
|
97
|
+
- lib/git/pkgs/commands/diff_driver.rb
|
|
95
98
|
- lib/git/pkgs/commands/history.rb
|
|
96
99
|
- lib/git/pkgs/commands/hooks.rb
|
|
97
100
|
- lib/git/pkgs/commands/info.rb
|
|
@@ -106,6 +109,7 @@ files:
|
|
|
106
109
|
- lib/git/pkgs/commands/tree.rb
|
|
107
110
|
- lib/git/pkgs/commands/update.rb
|
|
108
111
|
- lib/git/pkgs/commands/upgrade.rb
|
|
112
|
+
- lib/git/pkgs/commands/where.rb
|
|
109
113
|
- lib/git/pkgs/commands/why.rb
|
|
110
114
|
- lib/git/pkgs/database.rb
|
|
111
115
|
- lib/git/pkgs/models/branch.rb
|
|
@@ -125,6 +129,7 @@ metadata:
|
|
|
125
129
|
homepage_uri: https://github.com/andrew/git-pkgs
|
|
126
130
|
source_code_uri: https://github.com/andrew/git-pkgs
|
|
127
131
|
changelog_uri: https://github.com/andrew/git-pkgs/blob/main/CHANGELOG.md
|
|
132
|
+
funding_uri: https://github.com/sponsors/andrew
|
|
128
133
|
rdoc_options: []
|
|
129
134
|
require_paths:
|
|
130
135
|
- lib
|