gem_lookup 1.0.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 +7 -0
- data/.github/workflows/tests.yml +16 -0
- data/.gitignore +14 -0
- data/.rspec +2 -0
- data/.rubocop.yml +46 -0
- data/CHANGELOG.md +98 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +24 -0
- data/LICENSE +21 -0
- data/LICENSE.txt +21 -0
- data/README.md +378 -0
- data/Rakefile +12 -0
- data/bin/console +10 -0
- data/bin/setup +8 -0
- data/booster_pack.rb +5 -0
- data/exe/gems +8 -0
- data/gem_lookup.gemspec +42 -0
- data/init/bundler.rb +6 -0
- data/init/environment.rb +3 -0
- data/init/zeitwerk.rb +13 -0
- data/lib/gem_lookup.rb +3 -0
- data/lib/gem_lookup/errors.rb +13 -0
- data/lib/gem_lookup/flags.rb +49 -0
- data/lib/gem_lookup/gems.rb +75 -0
- data/lib/gem_lookup/help.rb +78 -0
- data/lib/gem_lookup/rate_limit.rb +34 -0
- data/lib/gem_lookup/requests.rb +69 -0
- data/lib/gem_lookup/ruby_gems.rb +132 -0
- data/lib/gem_lookup/serializers/emoji.rb +120 -0
- data/lib/gem_lookup/serializers/interface.rb +51 -0
- data/lib/gem_lookup/serializers/json.rb +23 -0
- data/lib/gem_lookup/serializers/wordy.rb +118 -0
- data/lib/gem_lookup/version.rb +9 -0
- metadata +125 -0
@@ -0,0 +1,132 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'colorize'
|
4
|
+
|
5
|
+
module GemLookup
|
6
|
+
class RubyGems
|
7
|
+
# Creates a new instance of RubyGems.
|
8
|
+
# @param gems [Array] an array of gems and/or flags.
|
9
|
+
def initialize(gems)
|
10
|
+
@gem_list = gems
|
11
|
+
@flags = []
|
12
|
+
@display_mode = :emoji
|
13
|
+
@serializer = nil
|
14
|
+
@continue = true
|
15
|
+
end
|
16
|
+
|
17
|
+
# Handles the preparation and processing of the gems and/or flags.
|
18
|
+
def find_all
|
19
|
+
format_list
|
20
|
+
process_flags if valid?
|
21
|
+
|
22
|
+
return unless continue?
|
23
|
+
|
24
|
+
process_gems if valid?
|
25
|
+
display_help! unless valid?
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
# Processes the detection and handling of flags.
|
31
|
+
def process_flags
|
32
|
+
detect_flags
|
33
|
+
handle_flags
|
34
|
+
detect_serializer
|
35
|
+
end
|
36
|
+
|
37
|
+
# Looks for strings that start with a dash and marks them as flags, and removes them from the
|
38
|
+
# gem list.
|
39
|
+
def detect_flags
|
40
|
+
@flags = @gem_list.select {|g| g[0] == '-' }
|
41
|
+
@gem_list -= @flags
|
42
|
+
end
|
43
|
+
|
44
|
+
# Lower-cases the entire gem list, and then removes duplicate entries.
|
45
|
+
def format_list
|
46
|
+
@gem_list.map!(&:downcase).uniq!
|
47
|
+
end
|
48
|
+
|
49
|
+
# Creates a new GemLookup::Gems instance and calls #process.
|
50
|
+
def process_gems
|
51
|
+
Gems.new(@gem_list, serializer: @serializer).process
|
52
|
+
end
|
53
|
+
|
54
|
+
# Calls the #check_flags method if there are any flag entries.
|
55
|
+
def handle_flags
|
56
|
+
return unless @flags.any?
|
57
|
+
|
58
|
+
check_flags
|
59
|
+
rescue GemLookup::Errors::UnsupportedFlag => e
|
60
|
+
error message: "Unsupported flag [#{e.message}]"
|
61
|
+
rescue GemLookup::Errors::UnsupportedFlags => e
|
62
|
+
error message: "Unsupported flags [#{e.message}]"
|
63
|
+
end
|
64
|
+
|
65
|
+
# Looks through the flags and calls GemLookup::Flags to assist, and either calls GemLookup::Help
|
66
|
+
# or sets the display mode, where appropriate.
|
67
|
+
# rubocop:disable Metrics/MethodLength
|
68
|
+
def check_flags
|
69
|
+
if Flags.supported?(:help, flags: @flags)
|
70
|
+
Help.display exit_code: 0
|
71
|
+
@continue = false
|
72
|
+
elsif Flags.supported?(:version, flags: @flags)
|
73
|
+
Help.version exit_code: 0
|
74
|
+
@continue = false
|
75
|
+
elsif Flags.supported?(:wordy, flags: @flags)
|
76
|
+
@display_mode = :wordy
|
77
|
+
elsif Flags.supported?(:json, flags: @flags)
|
78
|
+
@display_mode = :json
|
79
|
+
else
|
80
|
+
Flags.unsupported(flags: @flags)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
# rubocop:enable Metrics/MethodLength
|
84
|
+
|
85
|
+
# Utilizes the display mode to identify which serializer to utilize.
|
86
|
+
def detect_serializer
|
87
|
+
@serializer = case @display_mode
|
88
|
+
when :wordy
|
89
|
+
Serializers::Wordy
|
90
|
+
when :json
|
91
|
+
Serializers::Json
|
92
|
+
when :emoji
|
93
|
+
Serializers::Emoji
|
94
|
+
end
|
95
|
+
|
96
|
+
invalid_display_mode! if @serializer.nil?
|
97
|
+
end
|
98
|
+
|
99
|
+
# Raises the Invalid display mode error.
|
100
|
+
def invalid_display_mode!
|
101
|
+
@continue = false
|
102
|
+
raise GemLookup::Errors::InvalidDisplayMode, @display_mode
|
103
|
+
rescue GemLookup::Errors::InvalidDisplayMode => e
|
104
|
+
error message: "Invalid display mode [#{e.message}]"
|
105
|
+
end
|
106
|
+
|
107
|
+
# If the lookup process should continue.
|
108
|
+
# @return [Boolean] whether to continue the lookup process or not.
|
109
|
+
def continue?
|
110
|
+
@continue
|
111
|
+
end
|
112
|
+
|
113
|
+
# If the gem list is valid.
|
114
|
+
# @return [Boolean] whether there are any entries in the gem list.
|
115
|
+
def valid?
|
116
|
+
@gem_list.any?
|
117
|
+
end
|
118
|
+
|
119
|
+
# Calls the GemLookup::Help.display method and exits with an exit code of 1.
|
120
|
+
def display_help!
|
121
|
+
Help.display exit_code: 1
|
122
|
+
end
|
123
|
+
|
124
|
+
# Outputs the passed in message in a standard error format, in red, and exits with an exit code
|
125
|
+
# of 1.
|
126
|
+
# @param message [String] the error message to present.
|
127
|
+
def error(message:)
|
128
|
+
puts "=> Error: #{message}".red
|
129
|
+
exit 1
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'colorize'
|
4
|
+
require 'date'
|
5
|
+
|
6
|
+
module GemLookup
|
7
|
+
module Serializers
|
8
|
+
class Emoji < Interface
|
9
|
+
class << self
|
10
|
+
# Outputs the emoji-based format for the gem
|
11
|
+
# @param json [Hash] the json hash, with symbolized keys.
|
12
|
+
def display(json:)
|
13
|
+
if json[:timeout]
|
14
|
+
puts timed_out(gem_name: json[:name])
|
15
|
+
elsif json[:exists]
|
16
|
+
puts gem_details(json: json)
|
17
|
+
else
|
18
|
+
puts not_found(gem_name: json[:name])
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Outputs the number of gems being queried.
|
23
|
+
# @param num [Numeric] the number of gems.
|
24
|
+
def gem_count(num:)
|
25
|
+
puts "=> 🤔 #{num} gems".light_cyan
|
26
|
+
end
|
27
|
+
|
28
|
+
# Outputs the current batch and total number of batches
|
29
|
+
# @param num [Numeric] the current batch number.
|
30
|
+
# @param total [Numeric] the total number of batches.
|
31
|
+
def batch_iterator(num:, total:)
|
32
|
+
puts "=> 🧺 #{num} of #{total}".yellow
|
33
|
+
end
|
34
|
+
|
35
|
+
# Outputs the list of gems being looked up from the batch.
|
36
|
+
# @param batch [Array] the array of gems.
|
37
|
+
def querying(batch:)
|
38
|
+
puts "=> 🔎 #{batch.join(", ")}".light_yellow
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns if the serializer is meant to be used to stream content.
|
42
|
+
# @return [Boolean] whether the serializer is meant for streaming content.
|
43
|
+
def streaming?
|
44
|
+
true
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
# rubocop:disable Metrics/AbcSize
|
50
|
+
# Returns the emoji-based format for the gem
|
51
|
+
# @param json [Hash] the json hash, with symbolized keys.
|
52
|
+
def gem_details(json:)
|
53
|
+
[].tap do |output|
|
54
|
+
output.push "=> 💎 #{json[:name]} is at #{json[:version]}".green
|
55
|
+
output.push "==> 📅 #{convert_date(date: json[:version_created_at])}"
|
56
|
+
output.push "==> 🏠 #{json[:homepage_uri]}"
|
57
|
+
output.push source_code(source_code_uri: json[:source_code_uri])
|
58
|
+
output.push changelog(changelog_uri: json[:changelog_uri])
|
59
|
+
output.push mailing_list(mailing_list_uri: json[:mailing_list_uri])
|
60
|
+
end.join "\n"
|
61
|
+
end
|
62
|
+
# rubocop:enable Metrics/AbcSize
|
63
|
+
|
64
|
+
# Generates the "Source Code" string
|
65
|
+
# @param source_code_uri [String] the source code uri.
|
66
|
+
# @return [String] the repository string.
|
67
|
+
def source_code(source_code_uri:)
|
68
|
+
if source_code_uri && !source_code_uri.empty?
|
69
|
+
"==> 🔗 #{source_code_uri}"
|
70
|
+
else
|
71
|
+
'==> 🔗 Unavailable'.light_red
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Generates the "changelog" string
|
76
|
+
# @param changelog_uri [String] the changelog uri.
|
77
|
+
# @return [String] the changelog string.
|
78
|
+
def changelog(changelog_uri:)
|
79
|
+
if changelog_uri && !changelog_uri.empty?
|
80
|
+
"==> 📑 #{changelog_uri}".light_cyan
|
81
|
+
else
|
82
|
+
'==> 📑 Unavailable'.light_red
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# Generates the "mailing list" string
|
87
|
+
# @param mailing_list_uri [String] the mailing list uri.
|
88
|
+
# @return [String] the mailing list string.
|
89
|
+
def mailing_list(mailing_list_uri:)
|
90
|
+
if mailing_list_uri && !mailing_list_uri.empty?
|
91
|
+
"==> 💌 #{mailing_list_uri}".light_cyan
|
92
|
+
else
|
93
|
+
'==> 💌 Unavailable'.light_red
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# Generates the "gem lookup timed out" string
|
98
|
+
# @param gem_name [String] the name of the gem that the lookup timed out on.
|
99
|
+
# @return [String] the gem lookup timed out string.
|
100
|
+
def timed_out(gem_name:)
|
101
|
+
"=> 💎 #{gem_name} lookup timed out".red
|
102
|
+
end
|
103
|
+
|
104
|
+
# Generates the "gem not found" string
|
105
|
+
# @param gem_name [String] the name of the gem that was not found.
|
106
|
+
# @return [String] the gem not found string.
|
107
|
+
def not_found(gem_name:)
|
108
|
+
"=> 💎 #{gem_name} not found".red
|
109
|
+
end
|
110
|
+
|
111
|
+
# Parses the passed date/datetime string into the desired format, aka "November 13, 2014".
|
112
|
+
# @param date [String] the date to be parsed.
|
113
|
+
# @return [String] the formatted date.
|
114
|
+
def convert_date(date:)
|
115
|
+
Date.parse(date).strftime '%B %-d, %Y'
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GemLookup
|
4
|
+
module Serializers
|
5
|
+
class Interface
|
6
|
+
class << self
|
7
|
+
# rubocop:disable Lint/UnusedMethodArgument
|
8
|
+
|
9
|
+
# Should be overriden to output the desired output format for the gem
|
10
|
+
# @param json [Hash] the json hash, with symbolized keys.
|
11
|
+
def display(json:)
|
12
|
+
not_implemented __method__, params: %w[:json]
|
13
|
+
end
|
14
|
+
|
15
|
+
# Should be overriden to output the number of gems being queried.
|
16
|
+
# @param num [Numeric] the number of gems.
|
17
|
+
def gem_count(num:)
|
18
|
+
not_implemented __method__, params: %w[:num]
|
19
|
+
end
|
20
|
+
|
21
|
+
# Should be overriden to output the current batch and total number of batches
|
22
|
+
# @param num [Numeric] the current batch number.
|
23
|
+
# @param total [Numeric] the total number of batches.
|
24
|
+
def batch_iterator(num:, total:)
|
25
|
+
not_implemented __method__, params: %w[:num :total]
|
26
|
+
end
|
27
|
+
|
28
|
+
# Should be overridden to output the list of gems being looked up from the batch.
|
29
|
+
# @param batch [Array] the array of gems.
|
30
|
+
def querying(batch:)
|
31
|
+
not_implemented __method__, params: %w[:batch]
|
32
|
+
end
|
33
|
+
|
34
|
+
# Should be overriden to return if the serializer is meant to be used to stream content.
|
35
|
+
# @return [Boolean] whether the serializer is meant for streaming content.
|
36
|
+
def streaming?
|
37
|
+
not_implemented __method__
|
38
|
+
end
|
39
|
+
# rubocop:enable Lint/UnusedMethodArgument
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def not_implemented(method, params: [])
|
44
|
+
required = params.any? ? " with params (#{params.join(", ")})" : ''
|
45
|
+
raise GemLookup::Errors::UndefinedInterfaceMethod,
|
46
|
+
"Class method .#{method}#{required} must be implemented by sub-class"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module GemLookup
|
6
|
+
module Serializers
|
7
|
+
class Json < Interface
|
8
|
+
class << self
|
9
|
+
# Outputs the json (in a pretty format) for the gem
|
10
|
+
# @param json [Hash] the json hash.
|
11
|
+
def display(json:)
|
12
|
+
puts JSON.pretty_generate json
|
13
|
+
end
|
14
|
+
|
15
|
+
# Returns if the serializer is meant to be used to stream content.
|
16
|
+
# @return [Boolean] whether the serializer is meant for streaming content.
|
17
|
+
def streaming?
|
18
|
+
false
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'colorize'
|
4
|
+
require 'date'
|
5
|
+
|
6
|
+
module GemLookup
|
7
|
+
module Serializers::Wordy
|
8
|
+
class << self
|
9
|
+
# Outputs the emoji-based format for the gem
|
10
|
+
# @param json [Hash] the json hash, with symbolized keys.
|
11
|
+
def display(json:)
|
12
|
+
if json[:timeout]
|
13
|
+
puts timed_out(gem_name: json[:name])
|
14
|
+
elsif json[:exists]
|
15
|
+
puts gem_details(json: json)
|
16
|
+
else
|
17
|
+
puts not_found(gem_name: json[:name])
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Outputs the number of gems being queried.
|
22
|
+
# @param num [Numeric] the number of gems.
|
23
|
+
def gem_count(num:)
|
24
|
+
puts "=> Query: #{num} gems".light_cyan
|
25
|
+
end
|
26
|
+
|
27
|
+
# Outputs the current batch and total number of batches
|
28
|
+
# @param num [Numeric] the current batch number.
|
29
|
+
# @param total [Numeric] the total number of batches.
|
30
|
+
def batch_iterator(num:, total:)
|
31
|
+
puts "=> Batch: #{num} of #{total}".yellow
|
32
|
+
end
|
33
|
+
|
34
|
+
# Outputs the list of gems being looked up from the batch.
|
35
|
+
# @param batch [Array] the array of gems.
|
36
|
+
def querying(batch:)
|
37
|
+
puts "=> Looking up: #{batch.join(", ")}".light_yellow
|
38
|
+
end
|
39
|
+
|
40
|
+
# Returns if the serializer is meant to be used to stream content.
|
41
|
+
# @return [Boolean] whether the serializer is meant for streaming content.
|
42
|
+
def streaming?
|
43
|
+
true
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
# rubocop:disable Metrics/AbcSize
|
49
|
+
# Returns the emoji-based format for the gem.
|
50
|
+
# @param json [Hash] the json hash, with symbolized keys.
|
51
|
+
def gem_details(json:)
|
52
|
+
[].tap do |output|
|
53
|
+
output.push "=> Gem: #{json[:name]} is at #{json[:version]}".green
|
54
|
+
output.push "==> Updated: #{convert_date(date: json[:version_created_at])}"
|
55
|
+
output.push "==> Homepage: #{json[:homepage_uri]}"
|
56
|
+
output.push source_code(source_code_uri: json[:source_code_uri])
|
57
|
+
output.push changelog(changelog_uri: json[:changelog_uri])
|
58
|
+
output.push mailing_list(mailing_list_uri: json[:mailing_list_uri])
|
59
|
+
end.join "\n"
|
60
|
+
end
|
61
|
+
# rubocop:enable Metrics/AbcSize
|
62
|
+
|
63
|
+
# Generates the "Source Code" string
|
64
|
+
# @param source_code_uri [String] the source code uri.
|
65
|
+
# @return [String] the repository string.
|
66
|
+
def source_code(source_code_uri:)
|
67
|
+
if source_code_uri && !source_code_uri.empty?
|
68
|
+
"==> Source Code: #{source_code_uri}"
|
69
|
+
else
|
70
|
+
'==> Source Code: Unavailable'.light_red
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Generates the "changelog" string
|
75
|
+
# @param changelog_uri [String] the changelog uri.
|
76
|
+
# @return [String] the changelog string.
|
77
|
+
def changelog(changelog_uri:)
|
78
|
+
if changelog_uri && !changelog_uri.empty?
|
79
|
+
"==> Changelog: #{changelog_uri}".light_cyan
|
80
|
+
else
|
81
|
+
'==> Changelog: Unavailable'.light_red
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# Generates the "mailing list" string
|
86
|
+
# @param mailing_list_uri [String] the mailing list uri.
|
87
|
+
# @return [String] the mailing list string.
|
88
|
+
def mailing_list(mailing_list_uri:)
|
89
|
+
if mailing_list_uri && !mailing_list_uri.empty?
|
90
|
+
"==> Mailing List: #{mailing_list_uri}".light_cyan
|
91
|
+
else
|
92
|
+
'==> Mailing List: Unavailable'.light_red
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# Generates the "gem lookup timed out" string
|
97
|
+
# @param gem_name [String] the name of the gem that the lookup timed out on.
|
98
|
+
# @return [String] the gem lookup timed out string.
|
99
|
+
def timed_out(gem_name:)
|
100
|
+
"=> Gem: #{gem_name} lookup timed out".red
|
101
|
+
end
|
102
|
+
|
103
|
+
# Generates the "gem not found" string.
|
104
|
+
# @param gem_name [String] the name of the gem that was not found.
|
105
|
+
# @return [String] the gem not found string.
|
106
|
+
def not_found(gem_name:)
|
107
|
+
"=> Gem: #{gem_name} not found".red
|
108
|
+
end
|
109
|
+
|
110
|
+
# Parses the passed date/datetime string into the desired format, aka "November 13, 2014".
|
111
|
+
# @param date [String] the date to be parsed.
|
112
|
+
# @return [String] the formatted date.
|
113
|
+
def convert_date(date:)
|
114
|
+
Date.parse(date).strftime '%B %-d, %Y'
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|