gem_lookup 1.0.0

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