git-pkgs 0.2.0 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7ff2285e54475944f6c8a9cb98ae9f5efcb78ee0aa74dbea6d46553bbf71caa2
4
- data.tar.gz: 81aee90f3e0b9f573e1f9e442dc4c487f07957c320d70ca24a809929248279a3
3
+ metadata.gz: 6152060237bbc1d9902da8e721bb23cfeaed46bbe2f5241e848aa0853d906710
4
+ data.tar.gz: 5eebb36bd3eed487a100ddc8d3ef4c88cb0cdb28734f777d6fbfbd267f87f43e
5
5
  SHA512:
6
- metadata.gz: ffdcb5fe7cc217b105f10018ba24101131120fdfcc8305f3142fcc11f29e7f77114e95c0a2abbe661fcac3a74e4ea0662031dc6a997020225bdabcc9b6ab754b
7
- data.tar.gz: 204dc587c61ccb128957910784ccab0cb84c667627dff1fb81d18a6b6779abc34cfff3a838f06146c954d1a50b9ac095a036a67c898d12699c530476b9b3d31c
6
+ metadata.gz: b2192d675dd23a3a2c69fc4de998070db17ac05004842855b1fbd1d5b5b148d8063db93db3d84e4e0bbcf42f5d33a173180f641e3309241f7d83e04615c5ba9a
7
+ data.tar.gz: cd7cfbe811f2a809ef428452708b18d1842ef2898d4b78c55e6373773b50546b215ec2dc43591ed4252d20595973ad060581dba72cc1400145068f55294655c4
data/CHANGELOG.md CHANGED
@@ -1,4 +1,18 @@
1
- ## [Unreleased]
1
+ ## [0.3.0] - 2026-01-03
2
+
3
+ - Pager support for long output (respects `GIT_PAGER`, `core.pager`, `PAGER`)
4
+ - `--no-pager` option for commands with long output
5
+ - Colored output (respects `NO_COLOR`, `color.ui`, `color.pkgs`)
6
+ - `GIT_DIR` and `GIT_PKGS_DB` environment variable support
7
+ - `git pkgs stats` now supports `--since` and `--until` date filters
8
+ - Consistent error handling across all commands (JSON errors when `--format=json`)
9
+ - `git pkgs update` now uses a transaction for atomicity and better performance
10
+ - Renamed `git pkgs outdated` to `git pkgs stale` (outdated remains as alias)
11
+ - `git pkgs log` command to list commits with dependency changes
12
+ - `git pkgs schema` command to output database schema in text, SQL, JSON, or markdown
13
+ - `git pkgs praise` alias for `blame`
14
+ - `git pkgs upgrade` command to handle schema upgrades after updating git-pkgs
15
+ - Schema version tracking with automatic detection of outdated databases
2
16
 
3
17
  ## [0.2.0] - 2026-01-02
4
18
 
data/README.md CHANGED
@@ -146,6 +146,7 @@ Show who added each current dependency:
146
146
  ```bash
147
147
  git pkgs blame
148
148
  git pkgs blame --ecosystem=rubygems
149
+ git pkgs praise # alias for blame
149
150
  ```
150
151
 
151
152
  Example output:
@@ -167,8 +168,10 @@ Gemfile (rubygems):
167
168
 
168
169
  ```bash
169
170
  git pkgs stats
170
- git pkgs stats --by-author # who added the most dependencies
171
- git pkgs stats --ecosystem=npm # filter by ecosystem
171
+ git pkgs stats --by-author # who added the most dependencies
172
+ git pkgs stats --ecosystem=npm # filter by ecosystem
173
+ git pkgs stats --since=2024-01-01 # changes after date
174
+ git pkgs stats --until=2024-12-31 # changes before date
172
175
  ```
173
176
 
174
177
  Example output:
@@ -225,6 +228,17 @@ git pkgs tree --ecosystem=rubygems
225
228
 
226
229
  This shows dependencies grouped by type (runtime, development, etc).
227
230
 
231
+ ### Find stale dependencies
232
+
233
+ ```bash
234
+ git pkgs stale # list deps by how long since last touched
235
+ git pkgs stale --days=365 # only show deps untouched for a year
236
+ git pkgs stale --ecosystem=npm # filter by ecosystem
237
+ git pkgs outdated # alias for stale
238
+ ```
239
+
240
+ Shows dependencies sorted by how long since they were last changed in your repo. Useful for finding packages that may have been forgotten or need review.
241
+
228
242
  ### Diff between commits
229
243
 
230
244
  ```bash
@@ -244,6 +258,16 @@ git pkgs show HEAD~5 # relative ref
244
258
 
245
259
  Like `git show` but for dependencies. Shows what was added, modified, or removed in a single commit.
246
260
 
261
+ ### List commits with dependency changes
262
+
263
+ ```bash
264
+ git pkgs log # recent commits with dependency changes
265
+ git pkgs log --author=alice # filter by author
266
+ git pkgs log -n 50 # show more commits
267
+ ```
268
+
269
+ Like `git log` but only shows commits that changed dependencies, with the changes listed under each commit.
270
+
247
271
  ### Keep database updated
248
272
 
249
273
  After the initial analysis, you can incrementally update the database with new commits:
@@ -258,6 +282,27 @@ You can also install git hooks to update automatically after commits and merges:
258
282
  git pkgs hooks --install
259
283
  ```
260
284
 
285
+ ### Upgrading
286
+
287
+ After updating git-pkgs, you may need to rebuild the database if the schema has changed:
288
+
289
+ ```bash
290
+ git pkgs upgrade
291
+ ```
292
+
293
+ This is detected automatically and you'll see a message if an upgrade is needed.
294
+
295
+ ### Show database schema
296
+
297
+ ```bash
298
+ git pkgs schema # human-readable table format
299
+ git pkgs schema --format=sql # CREATE TABLE statements
300
+ git pkgs schema --format=json # JSON structure
301
+ git pkgs schema --format=markdown # markdown tables
302
+ ```
303
+
304
+ Useful for understanding the [database structure](docs/schema.md) or generating documentation.
305
+
261
306
  ### CI usage
262
307
 
263
308
  You can run git-pkgs in CI to show dependency changes in pull requests:
@@ -283,6 +328,19 @@ jobs:
283
328
  - run: git pkgs diff --from=origin/${{ github.base_ref }} --to=HEAD
284
329
  ```
285
330
 
331
+ ## Configuration
332
+
333
+ git-pkgs respects [standard git configuration](https://git-scm.com/docs/git-config).
334
+
335
+ **Colors** are enabled when writing to a terminal. Disable with `NO_COLOR=1`, `git config color.ui never`, or `git config color.pkgs never` for git-pkgs only.
336
+
337
+ **Pager** follows git's precedence: `GIT_PAGER` env, `core.pager` config, `PAGER` env, then `less -FRSX`. Use `--no-pager` flag or `git config core.pager cat` to disable.
338
+
339
+ **Environment variables:**
340
+
341
+ - `GIT_DIR` - git directory location (standard git variable)
342
+ - `GIT_PKGS_DB` - database path (default: `.git/pkgs.sqlite3`)
343
+
286
344
  ## Performance
287
345
 
288
346
  Benchmarked on a MacBook Pro analyzing [octobox](https://github.com/octobox/octobox) (5191 commits, 8 years of history): init takes about 18 seconds at roughly 300 commits/sec, producing an 8.3 MB database. About half the commits (2531) had dependency changes.
data/lib/git/pkgs/cli.rb CHANGED
@@ -5,7 +5,8 @@ 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 outdated stats diff branch show].freeze
8
+ COMMANDS = %w[init update hooks info list tree history search why blame stale stats diff branch show log upgrade schema].freeze
9
+ ALIASES = { "praise" => "blame", "outdated" => "stale" }.freeze
9
10
 
10
11
  def self.run(args)
11
12
  new(args).run
@@ -24,7 +25,7 @@ module Git
24
25
  print_help
25
26
  when "-v", "--version", "version"
26
27
  puts "git-pkgs #{Git::Pkgs::VERSION}"
27
- when *COMMANDS
28
+ when *COMMANDS, *ALIASES.keys
28
29
  run_command(command)
29
30
  else
30
31
  $stderr.puts "Unknown command: #{command}"
@@ -34,6 +35,7 @@ module Git
34
35
  end
35
36
 
36
37
  def run_command(command)
38
+ command = ALIASES.fetch(command, command)
37
39
  command_class = Commands.const_get(command.capitalize.gsub(/_([a-z])/) { $1.upcase })
38
40
  command_class.new(@args).run
39
41
  rescue NameError
@@ -57,10 +59,13 @@ module Git
57
59
  search Find a dependency across all history
58
60
  why Explain why a dependency exists
59
61
  blame Show who added each dependency
60
- outdated Show dependencies that haven't been updated
62
+ stale Show dependencies that haven't been updated
61
63
  stats Show dependency statistics
62
64
  diff Show dependency changes between commits
63
65
  show Show dependency changes in a commit
66
+ log List commits with dependency changes
67
+ upgrade Upgrade database after git-pkgs update
68
+ schema Show database schema
64
69
 
65
70
  Options:
66
71
  -h, --help Show this help message
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Git
4
+ module Pkgs
5
+ module Color
6
+ CODES = {
7
+ red: 31,
8
+ green: 32,
9
+ yellow: 33,
10
+ blue: 34,
11
+ magenta: 35,
12
+ cyan: 36,
13
+ bold: 1,
14
+ dim: 2
15
+ }.freeze
16
+
17
+ def self.enabled?
18
+ return @enabled if defined?(@enabled)
19
+
20
+ @enabled = determine_color_support
21
+ end
22
+
23
+ def self.enabled=(value)
24
+ @enabled = value
25
+ end
26
+
27
+ def self.reset!
28
+ remove_instance_variable(:@enabled) if defined?(@enabled)
29
+ end
30
+
31
+ def self.determine_color_support
32
+ # NO_COLOR takes precedence (https://no-color.org/)
33
+ return false if ENV["NO_COLOR"] && !ENV["NO_COLOR"].empty?
34
+ return false if ENV["TERM"] == "dumb"
35
+
36
+ # Check git config: color.pkgs takes precedence over color.ui
37
+ git_color = git_color_config
38
+ case git_color
39
+ when "always" then return true
40
+ when "never" then return false
41
+ # "auto" falls through to TTY check
42
+ end
43
+
44
+ $stdout.respond_to?(:tty?) && $stdout.tty?
45
+ end
46
+
47
+ def self.git_color_config
48
+ # color.pkgs overrides color.ui for git-pkgs specific control
49
+ pkgs_color = `git config --get color.pkgs 2>/dev/null`.chomp
50
+ return normalize_color_value(pkgs_color) unless pkgs_color.empty?
51
+
52
+ ui_color = `git config --get color.ui 2>/dev/null`.chomp
53
+ return normalize_color_value(ui_color) unless ui_color.empty?
54
+
55
+ "auto"
56
+ end
57
+
58
+ def self.normalize_color_value(value)
59
+ case value.downcase
60
+ when "true", "always" then "always"
61
+ when "false", "never" then "never"
62
+ else "auto"
63
+ end
64
+ end
65
+
66
+ def self.colorize(text, *codes)
67
+ return text unless enabled?
68
+
69
+ code_str = codes.map { |c| CODES[c] || c }.join(";")
70
+ "\e[#{code_str}m#{text}\e[0m"
71
+ end
72
+
73
+ def self.red(text) = colorize(text, :red)
74
+ def self.green(text) = colorize(text, :green)
75
+ def self.yellow(text) = colorize(text, :yellow)
76
+ def self.blue(text) = colorize(text, :blue)
77
+ def self.cyan(text) = colorize(text, :cyan)
78
+ def self.bold(text) = colorize(text, :bold)
79
+ def self.dim(text) = colorize(text, :dim)
80
+ end
81
+ end
82
+ end
@@ -4,6 +4,8 @@ module Git
4
4
  module Pkgs
5
5
  module Commands
6
6
  class Blame
7
+ include Output
8
+
7
9
  def initialize(args)
8
10
  @args = args
9
11
  @options = parse_options
@@ -11,11 +13,7 @@ module Git
11
13
 
12
14
  def run
13
15
  repo = Repository.new
14
-
15
- unless Database.exists?(repo.git_dir)
16
- $stderr.puts "Database not initialized. Run 'git pkgs init' first."
17
- exit 1
18
- end
16
+ require_database(repo)
19
17
 
20
18
  Database.connect(repo.git_dir)
21
19
 
@@ -23,10 +21,7 @@ module Git
23
21
  branch_name = @options[:branch] || repo.default_branch
24
22
  branch = Models::Branch.find_by(name: branch_name)
25
23
 
26
- unless branch&.last_analyzed_sha
27
- $stderr.puts "No analysis found for branch '#{branch_name}'"
28
- exit 1
29
- end
24
+ error "No analysis found for branch '#{branch_name}'" unless branch&.last_analyzed_sha
30
25
 
31
26
  current_commit = Models::Commit.find_by(sha: branch.last_analyzed_sha)
32
27
  snapshots = current_commit&.dependency_snapshots&.includes(:manifest) || []
@@ -36,7 +31,7 @@ module Git
36
31
  end
37
32
 
38
33
  if snapshots.empty?
39
- puts "No dependencies found"
34
+ empty_result "No dependencies found"
40
35
  return
41
36
  end
42
37
 
@@ -74,20 +69,24 @@ module Git
74
69
  end
75
70
  puts JSON.pretty_generate(json_data)
76
71
  else
77
- grouped = blame_data.group_by { |d| [d[:manifest], d[:ecosystem]] }
72
+ paginate { output_text(blame_data) }
73
+ end
74
+ end
75
+
76
+ def output_text(blame_data)
77
+ grouped = blame_data.group_by { |d| [d[:manifest], d[:ecosystem]] }
78
78
 
79
- grouped.each do |(manifest, ecosystem), deps|
80
- puts "#{manifest} (#{ecosystem}):"
79
+ grouped.each do |(manifest, ecosystem), deps|
80
+ puts "#{manifest} (#{ecosystem}):"
81
81
 
82
- max_name_len = deps.map { |d| d[:name].length }.max
83
- max_author_len = deps.map { |d| d[:author].length }.max
82
+ max_name_len = deps.map { |d| d[:name].length }.max
83
+ max_author_len = deps.map { |d| d[:author].length }.max
84
84
 
85
- deps.sort_by { |d| d[:name] }.each do |dep|
86
- date = dep[:date].strftime("%Y-%m-%d")
87
- puts " #{dep[:name].ljust(max_name_len)} #{dep[:author].ljust(max_author_len)} #{date} #{dep[:sha]}"
88
- end
89
- puts
85
+ deps.sort_by { |d| d[:name] }.each do |dep|
86
+ date = dep[:date].strftime("%Y-%m-%d")
87
+ puts " #{dep[:name].ljust(max_name_len)} #{dep[:author].ljust(max_author_len)} #{date} #{dep[:sha]}"
90
88
  end
89
+ puts
91
90
  end
92
91
  end
93
92
 
@@ -127,6 +126,10 @@ module Git
127
126
  options[:format] = v
128
127
  end
129
128
 
129
+ opts.on("--no-pager", "Do not pipe output into a pager") do
130
+ options[:no_pager] = true
131
+ end
132
+
130
133
  opts.on("-h", "--help", "Show this help") do
131
134
  puts opts
132
135
  exit
@@ -4,6 +4,8 @@ module Git
4
4
  module Pkgs
5
5
  module Commands
6
6
  class Branch
7
+ include Output
8
+
7
9
  BATCH_SIZE = 100
8
10
  SNAPSHOT_INTERVAL = 20
9
11
 
@@ -25,32 +27,20 @@ module Git
25
27
  when nil, "-h", "--help"
26
28
  print_help
27
29
  else
28
- $stderr.puts "Unknown subcommand: #{subcommand}"
29
- $stderr.puts "Run 'git pkgs branch --help' for usage"
30
- exit 1
30
+ error "Unknown subcommand: #{subcommand}. Run 'git pkgs branch --help' for usage"
31
31
  end
32
32
  end
33
33
 
34
34
  def add_branch
35
35
  branch_name = @args.shift
36
- unless branch_name
37
- $stderr.puts "Usage: git pkgs branch add <name>"
38
- exit 1
39
- end
36
+ error "Usage: git pkgs branch add <name>" unless branch_name
40
37
 
41
38
  repo = Repository.new
42
-
43
- unless Database.exists?(repo.git_dir)
44
- $stderr.puts "Database not initialized. Run 'git pkgs init' first."
45
- exit 1
46
- end
39
+ require_database(repo)
47
40
 
48
41
  Database.connect(repo.git_dir)
49
42
 
50
- unless repo.branch_exists?(branch_name)
51
- $stderr.puts "Branch '#{branch_name}' not found"
52
- exit 1
53
- end
43
+ error "Branch '#{branch_name}' not found" unless repo.branch_exists?(branch_name)
54
44
 
55
45
  existing = Models::Branch.find_by(name: branch_name)
56
46
  if existing
@@ -84,18 +74,14 @@ module Git
84
74
 
85
75
  def list_branches
86
76
  repo = Repository.new
87
-
88
- unless Database.exists?(repo.git_dir)
89
- $stderr.puts "Database not initialized. Run 'git pkgs init' first."
90
- exit 1
91
- end
77
+ require_database(repo)
92
78
 
93
79
  Database.connect(repo.git_dir)
94
80
 
95
81
  branches = Models::Branch.all
96
82
 
97
83
  if branches.empty?
98
- puts "No branches tracked"
84
+ empty_result "No branches tracked"
99
85
  return
100
86
  end
101
87
 
@@ -110,25 +96,15 @@ module Git
110
96
 
111
97
  def remove_branch
112
98
  branch_name = @args.shift
113
- unless branch_name
114
- $stderr.puts "Usage: git pkgs branch remove <name>"
115
- exit 1
116
- end
99
+ error "Usage: git pkgs branch remove <name>" unless branch_name
117
100
 
118
101
  repo = Repository.new
119
-
120
- unless Database.exists?(repo.git_dir)
121
- $stderr.puts "Database not initialized. Run 'git pkgs init' first."
122
- exit 1
123
- end
102
+ require_database(repo)
124
103
 
125
104
  Database.connect(repo.git_dir)
126
105
 
127
106
  branch = Models::Branch.find_by(name: branch_name)
128
- unless branch
129
- $stderr.puts "Branch '#{branch_name}' not tracked"
130
- exit 1
131
- end
107
+ error "Branch '#{branch_name}' not tracked" unless branch
132
108
 
133
109
  # Only delete branch_commits, keep shared commits
134
110
  count = branch.branch_commits.count
@@ -4,6 +4,8 @@ module Git
4
4
  module Pkgs
5
5
  module Commands
6
6
  class Diff
7
+ include Output
8
+
7
9
  def initialize(args)
8
10
  @args = args
9
11
  @options = parse_options
@@ -11,48 +13,27 @@ module Git
11
13
 
12
14
  def run
13
15
  repo = Repository.new
14
-
15
- unless Database.exists?(repo.git_dir)
16
- $stderr.puts "Database not initialized. Run 'git pkgs init' first."
17
- exit 1
18
- end
16
+ require_database(repo)
19
17
 
20
18
  Database.connect(repo.git_dir)
21
19
 
22
20
  from_ref = @options[:from]
23
21
  to_ref = @options[:to] || "HEAD"
24
22
 
25
- unless from_ref
26
- $stderr.puts "Usage: git pkgs diff --from=REF [--to=REF]"
27
- exit 1
28
- end
23
+ error "Usage: git pkgs diff --from=REF [--to=REF]" unless from_ref
29
24
 
30
25
  # Resolve git refs (like HEAD~10) to SHAs
31
26
  from_sha = repo.rev_parse(from_ref)
32
27
  to_sha = repo.rev_parse(to_ref)
33
28
 
34
- unless from_sha
35
- $stderr.puts "Could not resolve '#{from_ref}'"
36
- exit 1
37
- end
38
-
39
- unless to_sha
40
- $stderr.puts "Could not resolve '#{to_ref}'"
41
- exit 1
42
- end
29
+ error "Could not resolve '#{from_ref}'" unless from_sha
30
+ error "Could not resolve '#{to_ref}'" unless to_sha
43
31
 
44
32
  from_commit = find_or_create_commit(repo, from_sha)
45
33
  to_commit = find_or_create_commit(repo, to_sha)
46
34
 
47
- unless from_commit
48
- $stderr.puts "Commit '#{from_sha[0..7]}' not found"
49
- exit 1
50
- end
51
-
52
- unless to_commit
53
- $stderr.puts "Commit '#{to_sha[0..7]}' not found"
54
- exit 1
55
- end
35
+ error "Commit '#{from_sha[0..7]}' not found" unless from_commit
36
+ error "Commit '#{to_sha[0..7]}' not found" unless to_commit
56
37
 
57
38
  # Get all changes between the two commits
58
39
  changes = Models::DependencyChange
@@ -67,10 +48,14 @@ module Git
67
48
  end
68
49
 
69
50
  if changes.empty?
70
- puts "No dependency changes between #{from_commit.short_sha} and #{to_commit.short_sha}"
51
+ empty_result "No dependency changes between #{from_commit.short_sha} and #{to_commit.short_sha}"
71
52
  return
72
53
  end
73
54
 
55
+ paginate { output_text(from_commit, to_commit, changes) }
56
+ end
57
+
58
+ def output_text(from_commit, to_commit, changes)
74
59
  puts "Dependency changes from #{from_commit.short_sha} to #{to_commit.short_sha}:"
75
60
  puts
76
61
 
@@ -79,35 +64,38 @@ module Git
79
64
  removed = changes.select { |c| c.change_type == "removed" }
80
65
 
81
66
  if added.any?
82
- puts "Added:"
67
+ puts Color.green("Added:")
83
68
  added.group_by(&:name).each do |name, pkg_changes|
84
69
  latest = pkg_changes.last
85
- puts " + #{name} #{latest.requirement} (#{latest.manifest.path})"
70
+ puts Color.green(" + #{name} #{latest.requirement} (#{latest.manifest.path})")
86
71
  end
87
72
  puts
88
73
  end
89
74
 
90
75
  if modified.any?
91
- puts "Modified:"
76
+ puts Color.yellow("Modified:")
92
77
  modified.group_by(&:name).each do |name, pkg_changes|
93
78
  first = pkg_changes.first
94
79
  latest = pkg_changes.last
95
- puts " ~ #{name} #{first.previous_requirement} -> #{latest.requirement}"
80
+ puts Color.yellow(" ~ #{name} #{first.previous_requirement} -> #{latest.requirement}")
96
81
  end
97
82
  puts
98
83
  end
99
84
 
100
85
  if removed.any?
101
- puts "Removed:"
86
+ puts Color.red("Removed:")
102
87
  removed.group_by(&:name).each do |name, pkg_changes|
103
88
  latest = pkg_changes.last
104
- puts " - #{name} (was #{latest.requirement})"
89
+ puts Color.red(" - #{name} (was #{latest.requirement})")
105
90
  end
106
91
  puts
107
92
  end
108
93
 
109
94
  # Summary
110
- puts "Summary: +#{added.map(&:name).uniq.count} -#{removed.map(&:name).uniq.count} ~#{modified.map(&:name).uniq.count}"
95
+ added_count = Color.green("+#{added.map(&:name).uniq.count}")
96
+ removed_count = Color.red("-#{removed.map(&:name).uniq.count}")
97
+ modified_count = Color.yellow("~#{modified.map(&:name).uniq.count}")
98
+ puts "Summary: #{added_count} #{removed_count} #{modified_count}"
111
99
  end
112
100
 
113
101
  def find_or_create_commit(repo, sha)
@@ -149,6 +137,10 @@ module Git
149
137
  options[:ecosystem] = v
150
138
  end
151
139
 
140
+ opts.on("--no-pager", "Do not pipe output into a pager") do
141
+ options[:no_pager] = true
142
+ end
143
+
152
144
  opts.on("-h", "--help", "Show this help") do
153
145
  puts opts
154
146
  exit
@@ -6,6 +6,8 @@ module Git
6
6
  module Pkgs
7
7
  module Commands
8
8
  class History
9
+ include Output
10
+
9
11
  def initialize(args)
10
12
  @args = args
11
13
  @options = parse_options
@@ -15,11 +17,7 @@ module Git
15
17
  package_name = @args.shift
16
18
 
17
19
  repo = Repository.new
18
-
19
- unless Database.exists?(repo.git_dir)
20
- $stderr.puts "Database not initialized. Run 'git pkgs init' first."
21
- exit 1
22
- end
20
+ require_database(repo)
23
21
 
24
22
  Database.connect(repo.git_dir)
25
23
 
@@ -52,18 +50,15 @@ module Git
52
50
  end
53
51
 
54
52
  if changes.empty?
55
- if package_name
56
- puts "No history found for '#{package_name}'"
57
- else
58
- puts "No dependency changes found"
59
- end
53
+ msg = package_name ? "No history found for '#{package_name}'" : "No dependency changes found"
54
+ empty_result msg
60
55
  return
61
56
  end
62
57
 
63
58
  if @options[:format] == "json"
64
59
  output_json(changes)
65
60
  else
66
- output_text(changes, package_name)
61
+ paginate { output_text(changes, package_name) }
67
62
  end
68
63
  end
69
64
 
@@ -81,13 +76,13 @@ module Git
81
76
 
82
77
  case change.change_type
83
78
  when "added"
84
- action = "Added"
79
+ action = Color.green("Added")
85
80
  version_info = change.requirement
86
81
  when "modified"
87
- action = "Updated"
82
+ action = Color.yellow("Updated")
88
83
  version_info = "#{change.previous_requirement} -> #{change.requirement}"
89
84
  when "removed"
90
- action = "Removed"
85
+ action = Color.red("Removed")
91
86
  version_info = change.requirement
92
87
  end
93
88
 
@@ -150,6 +145,10 @@ module Git
150
145
  options[:until] = v
151
146
  end
152
147
 
148
+ opts.on("--no-pager", "Do not pipe output into a pager") do
149
+ options[:no_pager] = true
150
+ end
151
+
153
152
  opts.on("-h", "--help", "Show this help") do
154
153
  puts opts
155
154
  exit
@@ -163,8 +162,7 @@ module Git
163
162
  def parse_time(str)
164
163
  Time.parse(str)
165
164
  rescue ArgumentError
166
- $stderr.puts "Invalid date format: #{str}"
167
- exit 1
165
+ error "Invalid date format: #{str}"
168
166
  end
169
167
  end
170
168
  end
@@ -4,6 +4,8 @@ module Git
4
4
  module Pkgs
5
5
  module Commands
6
6
  class Hooks
7
+ include Output
8
+
7
9
  HOOK_SCRIPT = <<~SCRIPT
8
10
  #!/bin/sh
9
11
  # git-pkgs auto-update hook