gem_lookup 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|