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.
@@ -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