gem_dating 0.1.1 → 0.1.2
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/Gemfile.lock +3 -2
- data/README.md +39 -14
- data/Rakefile +1 -1
- data/gem_dating.gemspec +10 -11
- data/lib/gem_dating/cli.rb +32 -3
- data/lib/gem_dating/input.rb +1 -1
- data/lib/gem_dating/result.rb +53 -0
- data/lib/gem_dating/version.rb +1 -1
- data/lib/gem_dating.rb +13 -5
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 50f8a606d682704f10a2ac5378c25a792d4c336ad08e05319e28333dc8ddfcb1
|
4
|
+
data.tar.gz: e8bc47b72796b1db95d67de3602d4bc6f27907807f80ad441b9f31faa7409596
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: abe1fdb44e970f1b0f0ae005104109da3f4cceb8124e081f81b4fc8a4727df70d0f51186879f96e7451c575aad4449fdeec2b9ef37790e695a1a0f5fe3f14839
|
7
|
+
data.tar.gz: f07e00ddc9906d3a5e378971bc09bbc709b2ba131b9740cbe0cb329c055a1283fb4536be6dbf110255d56860d72d0ac79f1768cab62763116472c511a806821b
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
gem_dating (0.1.
|
4
|
+
gem_dating (0.1.2)
|
5
5
|
bundler
|
6
6
|
table_print
|
7
7
|
|
@@ -56,8 +56,9 @@ GEM
|
|
56
56
|
unicode-display_width (2.4.2)
|
57
57
|
|
58
58
|
PLATFORMS
|
59
|
-
arm64-darwin-21
|
60
59
|
arm64-darwin-22
|
60
|
+
arm64-darwin-23
|
61
|
+
arm64-darwin-24
|
61
62
|
x86_64-linux
|
62
63
|
|
63
64
|
DEPENDENCIES
|
data/README.md
CHANGED
@@ -4,11 +4,6 @@
|
|
4
4
|
|
5
5
|
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
|
6
6
|
|
7
|
-
`gem_dating` avoids utilizing Bundler, and intends to be useful where you want to evaluate a set of gems without
|
8
|
-
the overhead of a full bundle install. If you've got a valid bundle you should consider the built in
|
9
|
-
[bundle-outdated](https://bundler.io/v2.4/man/bundle-outdated.1.html), or other available tools for interacting
|
10
|
-
with your Gemfile, like [libyear-bundler](https://github.com/jaredbeck/libyear-bundler).
|
11
|
-
|
12
7
|
## Usage
|
13
8
|
|
14
9
|
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
|
|
22
17
|
gem 'gem_dating', group: [:development], require: false
|
23
18
|
```
|
24
19
|
|
25
|
-
###
|
20
|
+
### Command Line Options
|
26
21
|
|
27
|
-
|
22
|
+
GemDating supports several command line options to customize its behavior:
|
28
23
|
|
29
|
-
```
|
30
|
-
|
24
|
+
```
|
25
|
+
gem_dating [OPTIONS] [<GEMFILE_FILEPATH>]
|
31
26
|
```
|
32
27
|
|
33
|
-
|
34
|
-
If it finds one, it will output a list of gems and their relative ages to the stdout stream.
|
28
|
+
#### Available Options:
|
35
29
|
|
36
|
-
|
30
|
+
- `--help`, `-h`, `-?`: Show the help message
|
31
|
+
- `--older-than=<AGE>`, `--ot=<AGE>`: Filter gems updated within the last X time period
|
32
|
+
- Examples: `--older-than=2y` (2 years), `--ot=1m` (1 month), `--ot=4w` (4 weeks), `--ot=10d` (10 days)
|
33
|
+
- `--sort-by=<FIELD>`: Sort by field
|
34
|
+
- Available fields: `name` or `date`
|
35
|
+
- Default: `name`
|
36
|
+
- `--order=<DIRECTION>`: Sort direction
|
37
|
+
- Available directions: `asc` (ascending) or `desc` (descending)
|
38
|
+
- Default: `asc`
|
39
|
+
- `--json`: Output results as JSON instead of table format
|
40
|
+
|
41
|
+
#### Examples:
|
37
42
|
|
38
43
|
```bash
|
39
|
-
|
40
|
-
|
44
|
+
# Show gems older than 1 year
|
45
|
+
$ gem_dating --older-than=1y
|
46
|
+
|
47
|
+
# Sort gems by date in descending order (newest first)
|
48
|
+
$ gem_dating --sort-by=date --order=desc
|
49
|
+
|
50
|
+
# Output results as JSON
|
51
|
+
$ gem_dating --json
|
52
|
+
|
53
|
+
# Combine multiple options
|
54
|
+
$ gem_dating ~/code/my_app/Gemfile --older-than=6m --sort-by=date --order=desc
|
55
|
+
```
|
41
56
|
|
42
57
|
GemDating leans on `$stdout`, so you can pipe the output to a file if you'd like:
|
43
58
|
```bash
|
@@ -86,6 +101,16 @@ more_dating.table_print
|
|
86
101
|
# ...etc
|
87
102
|
```
|
88
103
|
|
104
|
+
### Caveats
|
105
|
+
|
106
|
+
`gem_dating` avoids utilizing Bundler, and intends to be useful where you want to evaluate a set of gems without
|
107
|
+
the overhead of a full bundle install. If you've got a valid bundle you should consider the built in
|
108
|
+
[bundle-outdated](https://bundler.io/v2.4/man/bundle-outdated.1.html), or other available tools for interacting
|
109
|
+
with your Gemfile, like [libyear-bundler](https://github.com/jaredbeck/libyear-bundler).
|
110
|
+
|
111
|
+
Sometimes we [get incorrect dates](https://github.com/testdouble/gem_dating/issues/10).
|
112
|
+
TLDR; sometimes GemSpecs are built in an environment where the date gets overwritten. That'll be up to the gem
|
113
|
+
owner(s) to determine if they'd like to adjust it to provide accurate dates.
|
89
114
|
|
90
115
|
|
91
116
|
## Code of Conduct
|
data/Rakefile
CHANGED
data/gem_dating.gemspec
CHANGED
@@ -1,27 +1,26 @@
|
|
1
|
-
|
2
1
|
lib = File.expand_path("../lib", __FILE__)
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
3
|
require "gem_dating/version"
|
5
4
|
|
6
5
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name
|
8
|
-
spec.version
|
9
|
-
spec.authors
|
10
|
-
spec.email
|
6
|
+
spec.name = "gem_dating"
|
7
|
+
spec.version = GemDating::VERSION
|
8
|
+
spec.authors = ["Steve Jackson", "Daniel Huss"]
|
9
|
+
spec.email = ["steve@testdouble.com"]
|
11
10
|
|
12
|
-
spec.summary
|
13
|
-
spec.homepage
|
14
|
-
spec.license
|
11
|
+
spec.summary = "How old is that anyway?"
|
12
|
+
spec.homepage = "https://github.com/testdouble/gem_dating"
|
13
|
+
spec.license = "MIT"
|
15
14
|
|
16
15
|
spec.metadata["homepage_uri"] = spec.homepage
|
17
16
|
spec.metadata["source_code_uri"] = spec.homepage
|
18
17
|
spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/CHANGELOG.md"
|
19
18
|
|
20
|
-
spec.files
|
19
|
+
spec.files = Dir.chdir(File.expand_path("..", __FILE__)) do
|
21
20
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
22
21
|
end
|
23
|
-
spec.bindir
|
24
|
-
spec.executables
|
22
|
+
spec.bindir = "exe"
|
23
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
25
24
|
spec.require_paths = ["lib"]
|
26
25
|
|
27
26
|
spec.add_dependency "bundler"
|
data/lib/gem_dating/cli.rb
CHANGED
@@ -10,7 +10,11 @@ module GemDating
|
|
10
10
|
GEMFILE_FILEPATH defaults to ./Gemfile if not provided.
|
11
11
|
|
12
12
|
Options:
|
13
|
-
--help, -h Show this help message
|
13
|
+
--help, -h, -? Show this help message
|
14
|
+
--older-than=<AGE>, --ot=<AGE> Filter gems updated within the last X (e.g. 2y, 1m, 4w, 10d)
|
15
|
+
--sort-by=<FIELD> Sort by field (name or date), defaults to name
|
16
|
+
--order=<DIRECTION> Sort direction (asc or desc), defaults to asc
|
17
|
+
--json Output results as JSON
|
14
18
|
HELP
|
15
19
|
|
16
20
|
def initialize(argv = [])
|
@@ -18,10 +22,11 @@ module GemDating
|
|
18
22
|
|
19
23
|
@args = args
|
20
24
|
@file_path = file_path.first
|
25
|
+
@options = parse_args
|
21
26
|
end
|
22
27
|
|
23
28
|
def run
|
24
|
-
if
|
29
|
+
if @options[:help]
|
25
30
|
$stdout << HELP_TEXT
|
26
31
|
return SUCCESS
|
27
32
|
end
|
@@ -38,9 +43,33 @@ module GemDating
|
|
38
43
|
end
|
39
44
|
end
|
40
45
|
|
41
|
-
|
46
|
+
result = GemDating.from_file(@file_path, @options)
|
47
|
+
output = @options[:json] ? result.to_json : result.table_print
|
48
|
+
$stdout << output << "\n"
|
42
49
|
|
43
50
|
SUCCESS
|
44
51
|
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def parse_args(args = @args)
|
56
|
+
options = {}
|
57
|
+
options[:help] = true if (args & %w[-h --help -?]).any?
|
58
|
+
options[:json] = true if args.include?("--json")
|
59
|
+
|
60
|
+
if (older_than = args.find { |arg| arg.start_with?("--older-than=", "--ot=") })
|
61
|
+
options[:older_than] = older_than.split("=").last
|
62
|
+
end
|
63
|
+
|
64
|
+
if (sort_by = args.find { |arg| arg.start_with?("--sort-by=") })
|
65
|
+
options[:sort_by] = sort_by.split("=").last
|
66
|
+
end
|
67
|
+
|
68
|
+
if (order = args.find { |arg| arg.start_with?("--order=") })
|
69
|
+
options[:order] = order.split("=").last
|
70
|
+
end
|
71
|
+
|
72
|
+
options
|
73
|
+
end
|
45
74
|
end
|
46
75
|
end
|
data/lib/gem_dating/input.rb
CHANGED
data/lib/gem_dating/result.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require "table_print"
|
2
|
+
require "json"
|
2
3
|
|
3
4
|
module GemDating
|
4
5
|
class Result
|
@@ -24,5 +25,57 @@ module GemDating
|
|
24
25
|
def table_print
|
25
26
|
TablePrint::Printer.table_print(specs, [:name, :version, {date: {time_format: "%Y-%m-%d", width: 10}}]).encode("utf-8")
|
26
27
|
end
|
28
|
+
|
29
|
+
def to_json
|
30
|
+
JSON.generate(to_h)
|
31
|
+
end
|
32
|
+
|
33
|
+
def older_than(date)
|
34
|
+
specs.select! { |spec| spec.date.to_date < cut_off(date) }
|
35
|
+
self
|
36
|
+
end
|
37
|
+
|
38
|
+
def sort(options = {})
|
39
|
+
field = options[:sort_by] || "name"
|
40
|
+
direction = options[:order] || "asc"
|
41
|
+
|
42
|
+
@specs = @specs.sort_by do |spec|
|
43
|
+
case field
|
44
|
+
when "name"
|
45
|
+
spec.name.downcase
|
46
|
+
when "date"
|
47
|
+
spec.date
|
48
|
+
else
|
49
|
+
spec.name.downcase
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
@specs = @specs.reverse if direction.downcase == "desc"
|
54
|
+
|
55
|
+
self
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def cut_off(date)
|
61
|
+
return unless date
|
62
|
+
curr_date = Date.today
|
63
|
+
|
64
|
+
number = date[0..-2].to_i
|
65
|
+
unit = date[-1]
|
66
|
+
|
67
|
+
case unit
|
68
|
+
when "y"
|
69
|
+
curr_date << (12 * number)
|
70
|
+
when "m"
|
71
|
+
curr_date << number
|
72
|
+
when "w"
|
73
|
+
curr_date - (number * 7)
|
74
|
+
when "d"
|
75
|
+
curr_date - number
|
76
|
+
else
|
77
|
+
raise ArgumentError, "Invalid date format: #{date}"
|
78
|
+
end
|
79
|
+
end
|
27
80
|
end
|
28
81
|
end
|
data/lib/gem_dating/version.rb
CHANGED
data/lib/gem_dating.rb
CHANGED
@@ -5,15 +5,23 @@ require_relative "gem_dating/result"
|
|
5
5
|
require_relative "gem_dating/cli"
|
6
6
|
|
7
7
|
module GemDating
|
8
|
-
def self.from_string(s)
|
8
|
+
def self.from_string(s, options = {})
|
9
9
|
gems = Input.string(s).gems
|
10
|
-
|
11
|
-
Result.new(specs)
|
10
|
+
fetch_specs(gems, options)
|
12
11
|
end
|
13
12
|
|
14
|
-
def self.from_file(path)
|
13
|
+
def self.from_file(path, options = {})
|
15
14
|
gems = Input.file(path).gems
|
15
|
+
fetch_specs(gems, options)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.fetch_specs(gems, options)
|
16
19
|
specs = Rubygems.fetch(gems)
|
17
|
-
Result.new(specs)
|
20
|
+
results = Result.new(specs)
|
21
|
+
results.older_than(options[:older_than]) if options[:older_than]
|
22
|
+
results.sort(options)
|
23
|
+
results
|
18
24
|
end
|
25
|
+
|
26
|
+
private_class_method :fetch_specs
|
19
27
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gem_dating
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Steve Jackson
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2025-06-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -88,7 +88,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '0'
|
90
90
|
requirements: []
|
91
|
-
rubygems_version: 3.4.
|
91
|
+
rubygems_version: 3.4.10
|
92
92
|
signing_key:
|
93
93
|
specification_version: 4
|
94
94
|
summary: How old is that anyway?
|