redbreast 0.1.2 → 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.
Files changed (43) hide show
  1. checksums.yaml +5 -5
  2. data/.DS_Store +0 -0
  3. data/.rubocop.yml +5 -0
  4. data/README.md +102 -4
  5. data/Rakefile +3 -3
  6. data/bin/console +3 -3
  7. data/exe/redbreast +9 -7
  8. data/lib/.DS_Store +0 -0
  9. data/lib/redbreast.rb +25 -18
  10. data/lib/redbreast/.DS_Store +0 -0
  11. data/lib/redbreast/commands/color_generator.rb +54 -0
  12. data/lib/redbreast/commands/color_test_generator.rb +57 -0
  13. data/lib/redbreast/commands/configuration_installer.rb +29 -29
  14. data/lib/redbreast/commands/image_generator.rb +49 -47
  15. data/lib/redbreast/commands/image_test_generator.rb +57 -0
  16. data/lib/redbreast/commands/setup.rb +139 -92
  17. data/lib/redbreast/crawlers/color_crawler.rb +38 -0
  18. data/lib/redbreast/crawlers/image_crawler.rb +30 -10
  19. data/lib/redbreast/error_handler.rb +7 -6
  20. data/lib/redbreast/helpers/general.rb +73 -63
  21. data/lib/redbreast/helpers/hash.rb +8 -7
  22. data/lib/redbreast/helpers/terminal.rb +2 -3
  23. data/lib/redbreast/io/config.rb +14 -15
  24. data/lib/redbreast/serializers/objc_serializer.rb +66 -19
  25. data/lib/redbreast/serializers/serializer.rb +17 -16
  26. data/lib/redbreast/serializers/swift_serializer.rb +93 -2
  27. data/lib/redbreast/template_generators/.DS_Store +0 -0
  28. data/lib/redbreast/template_generators/colors/objc_colors_template_generator.rb +35 -0
  29. data/lib/redbreast/template_generators/colors/swift_colors_template_generator.rb +22 -0
  30. data/lib/redbreast/template_generators/images/objc_images_template_generator.rb +27 -41
  31. data/lib/redbreast/template_generators/images/swift_images_template_generator.rb +16 -21
  32. data/lib/redbreast/template_generators/objc_template_generator.rb +19 -19
  33. data/lib/redbreast/template_generators/swift_template_generator.rb +9 -10
  34. data/lib/redbreast/template_generators/tests/colors/objc_colors_tests_template_generator.rb +35 -0
  35. data/lib/redbreast/template_generators/tests/colors/swift_colors_tests_template_generator.rb +27 -0
  36. data/lib/redbreast/template_generators/tests/images/objc_images_tests_template_generator.rb +36 -0
  37. data/lib/redbreast/template_generators/tests/images/swift_images_tests_template_generator.rb +27 -0
  38. data/lib/redbreast/version.rb +1 -1
  39. data/redbreast.gemspec +21 -22
  40. metadata +35 -11
  41. data/lib/redbreast/commands/test_generator.rb +0 -56
  42. data/lib/redbreast/template_generators/tests/objc_tests_template_generator.rb +0 -39
  43. data/lib/redbreast/template_generators/tests/swift_tests_template_generator.rb +0 -31
@@ -1,18 +1,38 @@
1
1
  module Redbreast
2
2
  module Crawler
3
+ # Class for finding images
3
4
  class Image
4
-
5
5
  def self.image_names_uniq(assets_search_path)
6
- Dir.glob(assets_search_path).flat_map { |asset_folder|
7
- Dir.glob("#{asset_folder}/**/*.imageset").map { |image_name|
8
- image_name.split("/")[-1].chomp(".imageset")
9
- }
10
- }
11
- .uniq
12
- end
6
+ Dir.glob(assets_search_path).flat_map do |asset_folder|
7
+ Dir.glob("#{asset_folder}/**/*.imageset").map do |image_name|
8
+ name_to_split = image_name
9
+ split_name = name_to_split.split('.xcassets/')
10
+ current_image_name = split_name[0] + '.xcassets/'
11
+ current_iterating_name = split_name[0] + '.xcassets/'
12
+
13
+ split_name[1].split('/').each do |folder|
14
+ if folder.include? '.imageset'
15
+ current_image_name += folder
16
+ next
17
+ end
18
+
19
+ current_iterating_name += folder + '/'
13
20
 
21
+ Dir.glob("#{current_iterating_name}*.json").map do |path_name|
22
+ File.open path_name do |file|
23
+ unless file.find { |line| line =~ /provides/ }.nil?
24
+ current_image_name += folder + '/'
25
+ next
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ current_image_name.split('.xcassets/')[-1].chomp('.imageset')
32
+ end
33
+ end
34
+ .uniq
35
+ end
14
36
  end
15
37
  end
16
38
  end
17
-
18
-
@@ -1,24 +1,25 @@
1
1
  module Redbreast
2
+ # Class for handling errors that occurr
2
3
  class ErrorHandler
3
4
  extend Helper::Terminal
4
5
 
5
6
  class << self
6
7
  def rescuable
7
8
  yield
8
- rescue => e
9
+ rescue StandardError => e
9
10
  handle(e)
10
11
  end
11
12
 
12
- def handle(e)
13
+ def handle(error)
13
14
  prompt.error(
14
- case e
15
+ case error
15
16
  when Errno::ENOENT
16
- "We could not find a file that we need:\n\n#{e.message}"
17
+ "We could not find a file that we need:\n\n#{error.message}"
17
18
  else
18
- "An error happened. This might help:\n\n#{e.message}"
19
+ "An error happened. This might help:\n\n#{error.message}"
19
20
  end
20
21
  )
21
22
  end
22
23
  end
23
24
  end
24
- end
25
+ end
@@ -1,67 +1,77 @@
1
1
  module Redbreast
2
- module Helper
3
- module General
4
- ESCAPE_KEYWORDS = ["associatedtype", "class", "deinit", "enum", "extension", "fileprivate", "func",
5
- "import", "init", "inout", "internal", "let", "operator", "private", "protocol",
6
- "public", "static", "struct", "subscript", "typealias", "var", "break", "case",
7
- "continue", "default", "defer", "do", "else", "fallthrough", "for", "guard", "if",
8
- "in", "repeat", "return", "switch", "where", "while", "as", "Any", "catch", "false",
9
- "is", "nil", "rethrows", "super", "self", "Self", "throw", "throws", "true", "try", "_"]
10
-
11
- def config
12
- @config ||= Redbreast::IO::Config.read
13
- end
14
-
15
- def programming_language
16
- @programming_language ||= config[:language]
17
- end
2
+ module Helper
3
+ # Module with general metods used in creating files
4
+ module General
5
+ ESCAPE_KEYWORDS = ['associatedtype', 'class', 'deinit', 'enum', 'extension',
6
+ 'fileprivate', 'func', 'import', 'init', 'inout',
7
+ 'internal', 'let', 'operator', 'private', 'protocol',
8
+ 'public', 'static', 'struct', 'subscript', 'typealias',
9
+ 'var', 'break', 'case', 'continue', 'default',
10
+ 'defer', 'do', 'else', 'fallthrough', 'for',
11
+ 'guard', 'if', 'in', 'repeat', 'return',
12
+ 'switch', 'where', 'while', 'as', 'Any',
13
+ 'catch', 'false', 'is', 'nil', 'rethrows',
14
+ 'super', 'self', 'Self', 'throw', 'throws',
15
+ 'true', 'try', '_'].freeze
16
+ def config
17
+ @config ||= Redbreast::IO::Config.read
18
+ end
19
+
20
+ def programming_language
21
+ @programming_language ||= config[:language]
22
+ end
23
+
24
+ def bundles
25
+ @bundles ||= config[:bundles]
26
+ end
27
+
28
+ def app_name
29
+ @app_name ||= config[:app_name]
30
+ end
31
+
32
+ def indent(level = 0, initial = '')
33
+ (1..level)
34
+ .to_a.reduce('') { |result, _| result + ' ' }
35
+ .concat(initial)
36
+ end
37
+
38
+ def clean_enum_name(name)
39
+ clean_name = name
40
+ .split(/[^0-9a-zA-Z]/)
41
+ .reject(&:empty?)
42
+ .map(&:capitalize)
43
+ .join
44
+
45
+ escape_with_underscore_if_needed(clean_name)
46
+ end
47
+
48
+ def clean_case_name(name)
49
+ clean_variable_name(name)
50
+ end
51
+
52
+ def clean_variable_name(name)
53
+ clean_name = name
54
+ .split(/[^0-9a-zA-Z]/)
55
+ .reject(&:empty?)
56
+ .each_with_index
57
+ .map { |v, i| i.zero? ? v.tap { |char| char[0] = char[0].downcase } : v.capitalize }
58
+ .join
59
+
60
+ escaped_underscore = escape_with_underscore_if_needed(clean_name)
61
+ escape_keyword_if_needed(escaped_underscore)
62
+ end
63
+
64
+ def escape_with_underscore_if_needed(name)
65
+ return name if name.match(/^[A-Za-z_]/)
66
+
67
+ '_' + name
68
+ end
69
+
70
+ def escape_keyword_if_needed(name)
71
+ return name unless ESCAPE_KEYWORDS.include? name
18
72
 
19
- def bundles
20
- @bundles ||= config[:bundles]
21
- end
22
-
23
- def indent(level = 0, initial = "")
24
- (1..level)
25
- .to_a.reduce("") { |result, value| result + " " }
26
- .concat(initial)
27
- end
28
-
29
- def clean_enum_name(name)
30
- clean_name = name
31
- .split(/[^0-9a-zA-Z]/)
32
- .reject { |c| c.empty? }
33
- .map { |value| value.capitalize }
34
- .join
35
-
36
- escape_with_underscore_if_needed(clean_name)
37
- end
38
-
39
- def clean_case_name(name)
40
- clean_variable_name(name)
41
- end
42
-
43
- def clean_variable_name(name)
44
- clean_name = name
45
- .split(/[^0-9a-zA-Z]/)
46
- .reject { |c| c.empty? }
47
- .each_with_index
48
- .map { |value, index| index == 0 ? value.tap { |char| char[0] = char[0].downcase } : value.capitalize }
49
- .join
50
-
51
- escaped_underscore = escape_with_underscore_if_needed(clean_name)
52
- escape_keyword_if_needed(escaped_underscore)
53
- end
54
-
55
- def escape_with_underscore_if_needed(name)
56
- return name if name.match(/^[A-Za-z_]/)
57
- "_" + name
58
- end
59
-
60
- def escape_keyword_if_needed(name)
61
- return name if !ESCAPE_KEYWORDS.include? name
62
- "`#{name}`"
63
- end
64
-
73
+ "`#{name}`"
65
74
  end
66
75
  end
67
- end
76
+ end
77
+ end
@@ -1,9 +1,10 @@
1
1
  module Redbreast
2
- module Helper
3
- module HashHelper
4
- def compact(dictionary)
5
- dictionary.delete_if { |k, v| v.nil? }
6
- end
7
- end
2
+ module Helper
3
+ # Module used for creating compact dictionaries
4
+ module HashHelper
5
+ def compact(dictionary)
6
+ dictionary.delete_if { |_k, v| v.nil? }
7
+ end
8
8
  end
9
- end
9
+ end
10
+ end
@@ -2,8 +2,8 @@ require 'tty-prompt'
2
2
 
3
3
  module Redbreast
4
4
  module Helper
5
+ # Module used for communicatin with user via terminal
5
6
  module Terminal
6
-
7
7
  def success(message = 'Success!')
8
8
  prompt.ok(message)
9
9
  end
@@ -11,7 +11,6 @@ module Redbreast
11
11
  def prompt
12
12
  @prompt ||= TTY::Prompt.new(interrupt: :exit)
13
13
  end
14
-
15
14
  end
16
15
  end
17
- end
16
+ end
@@ -1,19 +1,18 @@
1
1
  module Redbreast
2
- module IO
3
- class Config
4
-
5
- CONFIG_FILE_PATH = "#{Dir.pwd}/.redbrest.yml".freeze
6
-
7
- class << self
8
- def write(data)
9
- File.open(CONFIG_FILE_PATH, 'w') { |file| YAML.dump(data, file) }
10
- end
11
-
12
- def read
13
- YAML.load_file(CONFIG_FILE_PATH)
14
- end
2
+ module IO
3
+ # Used for reading and writing to config file
4
+ class Config
5
+ CONFIG_FILE_PATH = "#{Dir.pwd}/.redbrest.yml"
6
+
7
+ class << self
8
+ def write(data)
9
+ File.open(CONFIG_FILE_PATH, 'w') { |file| YAML.dump(data, file) }
10
+ end
11
+
12
+ def read
13
+ YAML.load_file(CONFIG_FILE_PATH)
15
14
  end
16
-
17
15
  end
18
16
  end
19
- end
17
+ end
18
+ end
@@ -1,27 +1,74 @@
1
- require_relative 'serializer'
1
+ require_relative 'serializer'
2
2
 
3
3
  module Redbreast
4
4
  module Serializer
5
- class ObjC < Base
6
- include Helper::General
7
-
8
- def save(output_source_path, template_generator)
9
- FileUtils.mkdir_p output_source_path unless File.exist? output_source_path
10
-
11
- name = File.basename(output_source_path)
12
-
13
- if template_generator.h_template
14
- h_file = ERB.new(template_generator.h_template, nil, '-').result(binding)
15
- File.write(File.join(output_source_path, "UIImage+#{name}.h"), h_file)
16
- end
17
-
18
- if template_generator.m_template
19
- m_file = ERB.new(template_generator.m_template, nil, '-').result(binding)
20
- File.write(File.join(output_source_path, "UIImage+#{name}.m"), m_file)
21
- end
22
-
5
+ # Used for saving and creating ObjC files
6
+ class ObjC < Base
7
+ include Helper::General
8
+
9
+ def save(output_source_path:, template_generator:, generate_colors:)
10
+ FileUtils.mkdir_p output_source_path unless File.exist? output_source_path
11
+
12
+ file_base_name = generate_colors ? 'UIColor' : 'UIImage'
13
+ name = app_name.nil? ? 'Common' : app_name
14
+
15
+ if template_generator.h_template
16
+ write(output_source_path, template_generator.h_template, "#{file_base_name}+#{name}.h")
17
+ end
18
+
19
+ return unless template_generator.m_template
20
+
21
+ write(output_source_path, template_generator.m_template, "#{file_base_name}+#{name}.m")
22
+ end
23
+
24
+ def write(output_source_path, template, file_name)
25
+ file = ERB.new(template, nil, '-').result(binding)
26
+ File.write(File.join(output_source_path, file_name), file)
27
+ end
28
+
29
+ def create_objc_test_cases(names:, variable:)
30
+ text = ''
31
+ names.each do |name|
32
+ temp_array = name.split('/')
33
+ variable_name = temp_array.length == 1 ? clean_variable_name(name) : temp_array.unshift(temp_array.shift.downcase).join('')
34
+ text += variable % variable_name
23
35
  end
36
+ text
37
+ end
38
+
39
+ def generate_m_file_objc(names:, variable_declaration:, variable_implementation:, bundle_name:)
40
+ text = ''
41
+
42
+ names.each do |name|
43
+ temp_arr = name.split('/')
44
+
45
+ variable_name = temp_arr.length == 1 ? clean_variable_name(name) : temp_arr.unshift(temp_arr.shift.downcase).join('')
46
+ text += variable_declaration % variable_name + variable_implementation % [name, bundle_name[:reference]]
47
+ text += name == names.last ? '' : "\n"
48
+ end
49
+
50
+ text
51
+ end
52
+
53
+ def generate_h_file_objc(names:, variable:)
54
+ text = ''
55
+
56
+ names.each do |name|
57
+ temp_arr = name.split('/')
58
+ variable_name = temp_arr.length == 1 ? clean_variable_name(name) : temp_arr.unshift(temp_arr.shift.downcase).join('')
59
+ text += variable % variable_name
60
+ end
61
+
62
+ text
63
+ end
64
+
65
+ def generate_category(type, class_name, app_name)
66
+ text = "@#{type} #{class_name} ("
67
+
68
+ return text += 'Common)\n' if app_name.nil? || app_name.empty?
24
69
 
70
+ text + app_name + ")\n"
71
+ end
25
72
  end
26
73
  end
27
74
  end
@@ -1,18 +1,19 @@
1
1
  module Redbreast
2
- module Serializer
3
- class Base
4
- include ERB::Util
5
- attr_accessor :image_names, :bundle
6
-
7
- def initialize(image_names, bundle)
8
- @image_names = image_names
9
- @bundle = bundle
10
- end
11
-
12
- def save(path)
13
- fail NotImplementedError, 'Abstract Method'
14
- end
15
-
16
- end
2
+ module Serializer
3
+ # Used for initializing a serializer which will save files for respective languages
4
+ class Base
5
+ include ERB::Util
6
+ attr_accessor :asset_names, :bundle
7
+
8
+ def initialize(asset_names, bundle, app_name)
9
+ @asset_names = asset_names
10
+ @bundle = bundle
11
+ @app_name = app_name
12
+ end
13
+
14
+ def save(*)
15
+ raise NotImplementedError, 'Abstract Method'
16
+ end
17
17
  end
18
- end
18
+ end
19
+ end
@@ -1,11 +1,12 @@
1
- require_relative 'serializer'
1
+ require_relative 'serializer'
2
2
 
3
3
  module Redbreast
4
4
  module Serializer
5
+ # Used to save swift files
5
6
  class Swift < Base
6
7
  include Helper::General
7
8
 
8
- def save(output_source_path, template_generator)
9
+ def save(output_source_path:, template_generator:, generate_colors:)
9
10
  directory = File.dirname(output_source_path)
10
11
  FileUtils.mkdir_p directory unless File.exist? directory
11
12
 
@@ -13,6 +14,96 @@ module Redbreast
13
14
  File.write(output_source_path, file)
14
15
  end
15
16
 
17
+ def generate_file_swift(names:, spacing: "\t", indentation: '', variable:, bundle:)
18
+ return if names.empty?
19
+
20
+ text = ''
21
+ arr = []
22
+
23
+ text, arr = generate_variables(names: names, spacing: spacing, indentation: indentation, variable: variable, bundle: bundle, text: text, array: arr)
24
+
25
+ arr = arr.uniq
26
+ text += indentation.empty? && text.empty? ? "\n" : ''
27
+ arr.each do |enum_name|
28
+ names_new = []
29
+ names_new_enum = []
30
+ new_enum_name = enum_name
31
+
32
+ text += "\n" + spacing + 'enum ' + enum_name + ' {'
33
+ names_new, names_new_enum = separate_variables_from_folders(names: names, enum_name: enum_name, new_enum_name: new_enum_name, names_new_enum: names_new_enum, names_new: names_new)
34
+
35
+ if !names_new_enum.empty? && new_enum_name == enum_name
36
+ indentation += indentation.empty? || indentation[-1] == '/' ? '' : '/'
37
+ text += "\n" + generate_file_swift(names: names_new_enum, spacing: spacing + "\t", indentation: indentation + enum_name, variable: variable, bundle: bundle)
38
+ end
39
+
40
+ unless names_new.empty?
41
+
42
+ indentation += indentation.empty? || indentation[-1] == '/' ? '' : '/'
43
+ text += "\n" + generate_file_swift(names: names_new, spacing: spacing + "\t", indentation: indentation + enum_name, variable: variable, bundle: bundle)
44
+ end
45
+
46
+ text += "\n" + spacing + '}' + "\n"
47
+ end
48
+ text
49
+ end
50
+
51
+ def generate_extension(extended_class, app_name)
52
+ text = 'extension ' + extended_class + " {\n"
53
+
54
+ return text if app_name.nil? || app_name.empty?
55
+
56
+ text + "\tenum " + app_name + " {}\n}\n\nextension " + extended_class + '.' + app_name + " {\n"
57
+ end
58
+
59
+ def create_swift_test_cases(names:, declaration:, app_name:)
60
+ text = ''
61
+ app_name_text = app_name.nil? || app_name.empty? ? '' : app_name + '.'
62
+
63
+ names.each do |name|
64
+ temp_array = name.split('/')
65
+ variable = temp_array.pop
66
+ additional_text = temp_array.count.zero? ? '' : '.'
67
+ text += "\t\t" + declaration + app_name_text + temp_array.join('.') + additional_text + clean_variable_name(variable)
68
+ text += name == names.last ? '' : "\n"
69
+ end
70
+
71
+ text
72
+ end
73
+
74
+ def generate_variables(names:, spacing:, indentation:, bundle:, variable:, text:, array:)
75
+ names.each do |name|
76
+ temp_arr = name.split('/')
77
+
78
+ if temp_arr.length != 1
79
+ array.push(temp_arr.first)
80
+ else
81
+ name_prefix = indentation.empty? ? '' : '/'
82
+ text += spacing + variable % [clean_variable_name(name), indentation + name_prefix + name, bundle[:reference]]
83
+ #text += spacing + declaration + clean_variable_name(name) + type + indentation + name_prefix + name + var_end + bundle[:reference] + line_end
84
+ text += name == names.last ? '' : "\n"
85
+ end
86
+ end
87
+
88
+ [text, array]
89
+ end
90
+
91
+ def separate_variables_from_folders(names:, enum_name:, new_enum_name:, names_new_enum:, names_new:)
92
+ names.each do |name|
93
+ temp_arr = name.split('/')
94
+
95
+ next if temp_arr.length == 1
96
+
97
+ if temp_arr.length > 2
98
+ names_new_enum.push(temp_arr.drop(1).join('/')) if temp_arr.first == new_enum_name
99
+ next
100
+ end
101
+
102
+ names_new.push(temp_arr.drop(1).join('/')) if temp_arr[0] == enum_name
103
+ end
104
+
105
+ [names_new, names_new_enum]
106
+ end
16
107
  end
17
108
  end
18
109
  end