diff --git a/Gemfile.lock b/Gemfile.lock index 93d986b..d2883b2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - gem_dating (0.1.1) + gem_dating (0.1.2) bundler table_print diff --git a/README.md b/README.md index 483d4b6..b6c9fae 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,6 @@ The primary use case is when evaluating a codebase for upgrades - a gem from 2017 may effectively be abandoned and could cause trouble if you're targeting an upgrade to Ruby 4.1 -`gem_dating` avoids utilizing Bundler, and intends to be useful where you want to evaluate a set of gems without -the overhead of a full bundle install. If you've got a valid bundle you should consider the built in -[bundle-outdated](https://bundler.io/v2.4/man/bundle-outdated.1.html), or other available tools for interacting -with your Gemfile, like [libyear-bundler](https://github.com/jaredbeck/libyear-bundler). - ## Usage If you have rubygems 3.4.8 or later installed, you can skip installation and just run via `gem exec gem_dating [[path/to/Gemfile]` @@ -22,22 +17,42 @@ If you have rubygems 3.4.8 or later installed, you can skip installation and jus gem 'gem_dating', group: [:development], require: false ``` -### Running GemDating +### Command Line Options -This gem provides a small command line interface. It may be invoked with: +GemDating supports several command line options to customize its behavior: -```bash -$ gem_dating +``` +gem_dating [OPTIONS] [] ``` -By default, GemDating will look for a Gemfile in the current directory. -If it finds one, it will output a list of gems and their relative ages to the stdout stream. +#### Available Options: -You may also pass a path to a Gemfile as an argument: +- `--help`, `-h`, `-?`: Show the help message +- `--older-than=`, `--ot=`: Filter gems updated within the last X time period + - Examples: `--older-than=2y` (2 years), `--ot=1m` (1 month), `--ot=4w` (4 weeks), `--ot=10d` (10 days) +- `--sort-by=`: Sort by field + - Available fields: `name` or `date` + - Default: `name` +- `--order=`: Sort direction + - Available directions: `asc` (ascending) or `desc` (descending) + - Default: `asc` +- `--json`: Output results as JSON instead of table format + +#### Examples: ```bash -$ gem_dating ~/code/my_app/Gemfile -``` +# Show gems older than 1 year +$ gem_dating --older-than=1y + +# Sort gems by date in descending order (newest first) +$ gem_dating --sort-by=date --order=desc + +# Output results as JSON +$ gem_dating --json + +# Combine multiple options +$ gem_dating ~/code/my_app/Gemfile --older-than=6m --sort-by=date --order=desc +``` GemDating leans on `$stdout`, so you can pipe the output to a file if you'd like: ```bash @@ -86,6 +101,16 @@ more_dating.table_print # ...etc ``` +### Caveats + +`gem_dating` avoids utilizing Bundler, and intends to be useful where you want to evaluate a set of gems without +the overhead of a full bundle install. If you've got a valid bundle you should consider the built in +[bundle-outdated](https://bundler.io/v2.4/man/bundle-outdated.1.html), or other available tools for interacting +with your Gemfile, like [libyear-bundler](https://github.com/jaredbeck/libyear-bundler). + +Sometimes we [get incorrect dates](https://github.com/testdouble/gem_dating/issues/10). +TLDR; sometimes GemSpecs are built in an environment where the date gets overwritten. That'll be up to the gem +owner(s) to determine if they'd like to adjust it to provide accurate dates. ## Code of Conduct diff --git a/Rakefile b/Rakefile index d433a1e..3d52175 100644 --- a/Rakefile +++ b/Rakefile @@ -7,4 +7,4 @@ Rake::TestTask.new(:test) do |t| t.test_files = FileList["test/**/*_test.rb"] end -task :default => :test +task default: :test diff --git a/gem_dating.gemspec b/gem_dating.gemspec index f422f07..a8766e6 100644 --- a/gem_dating.gemspec +++ b/gem_dating.gemspec @@ -1,27 +1,26 @@ - lib = File.expand_path("../lib", __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require "gem_dating/version" Gem::Specification.new do |spec| - spec.name = "gem_dating" - spec.version = GemDating::VERSION - spec.authors = ["Steve Jackson", "Daniel Huss"] - spec.email = ["steve@testdouble.com"] + spec.name = "gem_dating" + spec.version = GemDating::VERSION + spec.authors = ["Steve Jackson", "Daniel Huss"] + spec.email = ["steve@testdouble.com"] - spec.summary = "How old is that anyway?" - spec.homepage = "https://github.com/testdouble/gem_dating" - spec.license = "MIT" + spec.summary = "How old is that anyway?" + spec.homepage = "https://github.com/testdouble/gem_dating" + spec.license = "MIT" spec.metadata["homepage_uri"] = spec.homepage spec.metadata["source_code_uri"] = spec.homepage spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/CHANGELOG.md" - spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do + spec.files = Dir.chdir(File.expand_path("..", __FILE__)) do `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } end - spec.bindir = "exe" - spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } + spec.bindir = "exe" + spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } spec.require_paths = ["lib"] spec.add_dependency "bundler" diff --git a/lib/gem_dating.rb b/lib/gem_dating.rb index 0a5d78c..fdb2104 100644 --- a/lib/gem_dating.rb +++ b/lib/gem_dating.rb @@ -15,7 +15,6 @@ def self.from_file(path, options = {}) fetch_specs(gems, options) end - def self.fetch_specs(gems, options) specs = Rubygems.fetch(gems) results = Result.new(specs) diff --git a/lib/gem_dating/input.rb b/lib/gem_dating/input.rb index d19e5ea..04ae250 100644 --- a/lib/gem_dating/input.rb +++ b/lib/gem_dating/input.rb @@ -23,7 +23,7 @@ def gems end def gem_line(line) - single_word_ruby_statements = %w{end else # gemspec} + single_word_ruby_statements = %w[end else # gemspec] return if single_word_ruby_statements.include? line.strip if line.start_with? "gem(" diff --git a/lib/gem_dating/result.rb b/lib/gem_dating/result.rb index 4ee131b..fb3eb60 100644 --- a/lib/gem_dating/result.rb +++ b/lib/gem_dating/result.rb @@ -31,7 +31,7 @@ def to_json end def older_than(date) - specs.select! { |spec| spec.date.to_date < self.cut_off(date) } + specs.select! { |spec| spec.date.to_date < cut_off(date) } self end diff --git a/lib/gem_dating/version.rb b/lib/gem_dating/version.rb index 96a23d0..6650cef 100644 --- a/lib/gem_dating/version.rb +++ b/lib/gem_dating/version.rb @@ -1,3 +1,3 @@ module GemDating - VERSION = "0.1.1" + VERSION = "0.1.2" end diff --git a/test/cli_test.rb b/test/cli_test.rb index 83261f9..22b4875 100644 --- a/test/cli_test.rb +++ b/test/cli_test.rb @@ -112,10 +112,10 @@ def test_help_option def test_parse_args cli = GemDating::Cli.new(["--help", "--older-than=2y"]) - assert_equal({ help: true, older_than: "2y" }, cli.send(:parse_args)) + assert_equal({help: true, older_than: "2y"}, cli.send(:parse_args)) cli = GemDating::Cli.new(["--json"]) - assert_equal({ json: true }, cli.send(:parse_args)) + assert_equal({json: true}, cli.send(:parse_args)) cli = GemDating::Cli.new([]) assert_equal({}, cli.send(:parse_args)) diff --git a/test/result_test.rb b/test/result_test.rb index 5c9f928..f3abdbd 100644 --- a/test/result_test.rb +++ b/test/result_test.rb @@ -2,7 +2,6 @@ require "date" class TestResult < Minitest::Test - def build_mock_spec(name:, version:, date:) spec = Gem::Specification.new spec.name = name