fastlane-plugin-framer 0.2.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0e9290f3e19124b67452ff24982ca4f1eff09b19
4
- data.tar.gz: 4f5b1035d851c4c5b6dab6aca9c7f9f597faa639
3
+ metadata.gz: 4c4b531a62b518edcbfb5ef5d6696cd3a109511b
4
+ data.tar.gz: b85e2d2e122b8f4c32497f4b5274729793b44a64
5
5
  SHA512:
6
- metadata.gz: 803aa2a181b6d28ee43cfb7231308d678ae9aec6b4c82a0aa0234e572854d414da72326b396a7c019ed2bebcf900a256cbae73b20572d3ea409bc2b6ec6c8dfc
7
- data.tar.gz: a4604d3b991a74bcbab6ea41aa5b9b959d9369ebc1c83d4e5b52c837260faf42411f3ce5432b82449a88217627c0256594f23d2c54f57b622f50e68128ace342
6
+ metadata.gz: 75f7533dbabe59ff64b89e884440da4bbe438101dd851f600a79ad2434ccc2e5a63ead9709df95a7c45622a1b7941ba864470198df7054ecdece69d6eb9422dd
7
+ data.tar.gz: 8af5b26a8ffd8881c3b945173ce4b1bad502f5bf24b7007abaff2cfb96cbf6818877f33354eb520f7279312c1979d61336c5ba1e3f36ea5ba29e2165743ec7db
data/README.md CHANGED
@@ -24,11 +24,11 @@ You can specify the position and the size of the screen in the template and (opt
24
24
 
25
25
  ## Example
26
26
 
27
- Check out the [example `Fastfile`](fastlane/Fastfile) to see how to use this plugin.
27
+ Check out the [example `Fastfile`](fastlane/Fastfile) to see how to use this plugin.
28
28
 
29
29
  There are 2 lanes, one for a simple flow (`demo-1`) and another with more languages and screens (`demo-2`).
30
30
 
31
- Try them by cloning the repo, running `fastlane install_plugins` and `bundle exec fastlane demo_1` or `bundle exec fastlane demo_2`.
31
+ Try them by cloning the repo, running `fastlane install_plugins` and `bundle exec fastlane demo_1` or `bundle exec fastlane demo_2`.
32
32
 
33
33
  ## Configuration
34
34
 
@@ -42,7 +42,7 @@ The **framer** action support 4 optional parameters (default values are used).
42
42
 
43
43
  | Option | Description | Default |
44
44
  | ----------------- | -------- | ------------ |
45
- | `source_folder` | path to the folder that contains raw screenshots and `text.json` file | `./fastlane/framer/screens` |
45
+ | `source_folder` | path to the folder that contains raw screenshots and `text.json` file | `./fastlane/framer/screens` |
46
46
  | `template_folder` | path to the folder that contains the templates images and configuration | `./fastlane/framer/templates` |
47
47
  | `output_folder` | path to the folder that will contains the final images, framed. Used then by `deliver` | `./fastlane/screenshots` (default one for `deliver`) |
48
48
  | `output_suffix` | filenam suffix for the framed images | `-framed` |
@@ -101,6 +101,26 @@ If you want some text in the final framed images, you need to create a `text.jso
101
101
  `text.json` is a simple map where *key* is the part of the screenshot filename (I suggest the same string you use with the `snapshot()` command on your UI tests.
102
102
  The *value* can be any strings.
103
103
 
104
+ ### Colors
105
+
106
+ You can customize the color of the text and the background color applyed below the template (if you have transparencies on the template, you can fill them with the background color).
107
+
108
+ `colors.json` is a simple map where *key* is the part of the screenshot filename. The *value* is a map with 2 optional keys, *text* and *background*.
109
+
110
+ ```
111
+ {
112
+ "default": {
113
+ "background": "#00FFFF",
114
+ "text": "#FFFFFF"
115
+ },
116
+ "demo": {
117
+ "background": "#FF00FF",
118
+ }
119
+ }
120
+ ```
121
+
122
+ Default values can be defined inside the *default* map.
123
+
104
124
  ## Run tests for this plugin
105
125
 
106
126
  To run both the tests, and code style validation, run
@@ -108,7 +128,7 @@ To run both the tests, and code style validation, run
108
128
  rake
109
129
  ```
110
130
 
111
- To automatically fix many of the styling issues, use
131
+ To automatically fix many of the styling issues, use
112
132
  ```
113
133
  rubocop -a
114
134
  ```
@@ -3,13 +3,31 @@ require 'json'
3
3
 
4
4
  module Fastlane
5
5
  module Actions
6
+
6
7
  class Template
7
8
  attr_accessor :name
8
- attr_accessor :size
9
+ attr_accessor :width, :height
9
10
 
10
11
  attr_accessor :file
11
12
  attr_accessor :imageOffset, :imageWidth, :imageBelow
12
- attr_accessor :textOffsetX, :textOffsetY, :textWidth, :textHeight, :textPadding, :textSize, :textFont, :textColor
13
+ attr_accessor :textOffsetX, :textOffsetY, :textWidth, :textHeight, :textPadding, :textSize, :textFont
14
+ end
15
+
16
+ class Colors
17
+ attr_accessor :text, :background
18
+
19
+ def merge(other)
20
+ unless other.text.nil? || other.text.empty?
21
+ self.text = other.text
22
+ end
23
+ unless other.background.nil? || other.background.empty?
24
+ self.background = other.background
25
+ end
26
+ end
27
+
28
+ def to_s
29
+ "{ text: #{self.text}, background: #{self.background} }"
30
+ end
13
31
  end
14
32
 
15
33
  class FramerAction < Action
@@ -29,20 +47,23 @@ module Fastlane
29
47
  UI.message "Processing #{file}"
30
48
 
31
49
  template = self.find_template(templates, file)
32
- text = self.find_text(source_folder, file)
33
- output = self.find_output(source_folder, file, output_folder, params[:output_suffix])
34
-
35
50
  if template.nil?
36
51
  UI.error "Unable to find template for screenshot #{file}"
37
52
  next
38
53
  end
54
+ UI.message "Using template: #{template.name} (#{template.width}x#{template.height})"
39
55
 
40
- UI.verbose "Using template: #{template.name} (#{template.size})"
41
- UI.verbose "Using text: #{text}"
42
- UI.verbose "Saving to: #{output}"
56
+ text = self.find_text(source_folder, file)
57
+ UI.message "Using text: #{text}"
58
+
59
+ colors = self.find_colors(source_folder, file)
60
+ UI.message "Using colors: #{colors}"
61
+
62
+ output = self.find_output(source_folder, file, output_folder, params[:output_suffix])
63
+ UI.message "Saving to: #{output}"
43
64
 
44
65
  # Do the magic
45
- self.combine(file, template, text, output)
66
+ self.combine(file, template, colors, text, output)
46
67
 
47
68
  UI.verbose "Framed screenshot #{output}"
48
69
  end
@@ -76,7 +97,8 @@ module Fastlane
76
97
 
77
98
  # Read template image size
78
99
  img = MiniMagick::Image.open(file)
79
- template.size = "#{img.width}x#{img.height}"
100
+ template.width = img.width
101
+ template.height = img.height
80
102
  img.destroy!
81
103
 
82
104
  # Get template config
@@ -92,7 +114,6 @@ module Fastlane
92
114
  template.imageWidth = (config_custom['image'] && config_custom['image']['width']) || (config_default['image'] && config_default['image']['width'])
93
115
  template.imageBelow = (config_custom['image'] && config_custom['image']['add_below']) || (config_default['image'] && config_default['image']['add_below']) || false
94
116
 
95
- template.textColor = (config_custom['text'] && config_custom['text']['color']) || (config_default['text'] && config_default['text']['color'])
96
117
  template.textFont = (config_custom['text'] && config_custom['text']['font']) || (config_default['text'] && config_default['text']['font'])
97
118
  template.textSize = (config_custom['text'] && config_custom['text']['size']) || (config_default['text'] && config_default['text']['size'])
98
119
  template.textWidth = (config_custom['text'] && config_custom['text']['width']) || (config_default['text'] && config_default['text']['width'])
@@ -108,22 +129,20 @@ module Fastlane
108
129
  end
109
130
 
110
131
  def self.find_template(templates, screenshot_file)
111
- # Read screenshot image size
112
- img = MiniMagick::Image.open(screenshot_file)
113
- size = "#{img.width}x#{img.height}"
114
- img.destroy!
132
+ # Read device name from file
133
+ filename = File.basename(screenshot_file)
134
+ device = filename.slice(0, filename.rindex('-'))
115
135
 
116
136
  # Search template that matches that size
117
- return templates.find { |template| template.size == size }
137
+ return templates.find { |template| template.name == device }
118
138
  end
119
139
 
120
140
  def self.find_text(source_dir, screenshot_file)
121
141
  directory = File.dirname(screenshot_file)
122
142
  strings_path = File.join(directory, "text.json")
123
143
 
124
- while !File.exist?(strings_path) do
144
+ while directory.start_with?(source_dir) && !File.exist?(strings_path) do
125
145
  directory = File.dirname(directory)
126
- break if directory == source_dir
127
146
  strings_path = File.join(directory, "text.json")
128
147
  end
129
148
 
@@ -135,6 +154,46 @@ module Fastlane
135
154
  return result.last if result
136
155
  end
137
156
 
157
+ def self.find_colors(source_dir, screenshot_file)
158
+
159
+ # Default values
160
+ colors = Colors.new
161
+ colors.text = "#000000"
162
+ colors.background = nil
163
+
164
+ # Read values from file
165
+ directory = File.dirname(screenshot_file)
166
+ colors_path = File.join(directory, "colors.json")
167
+
168
+ while directory.start_with?(source_dir) && !File.exist?(colors_path) do
169
+ directory = File.dirname(directory)
170
+ colors_path = File.join(directory, "colors.json")
171
+ end
172
+
173
+ if File.exist?(colors_path)
174
+ config = JSON.parse(File.read(colors_path))
175
+
176
+ # Read default values
177
+ default = Colors.new
178
+ default.text = config['default']['text']
179
+ default.background = config['default']['background']
180
+ colors.merge(default)
181
+
182
+ # Read and apply override, if any
183
+ override = config.select { |k, v| File.basename(screenshot_file).upcase.include? k.upcase }.values.map { |value|
184
+ c = Colors.new
185
+ c.text = value['text']
186
+ c.background = value['background']
187
+ c
188
+ }
189
+ unless override.empty?
190
+ colors.merge(override.first)
191
+ end
192
+ end
193
+
194
+ return colors
195
+ end
196
+
138
197
  def self.find_output(source_folder, screenshot_file, output_folder, output_suffix)
139
198
  # Prepare file name
140
199
  if output_suffix.empty?
@@ -158,7 +217,19 @@ module Fastlane
158
217
  return file_path
159
218
  end
160
219
 
161
- def self.combine(screenshot_file, template, text, output_file)
220
+ def self.combine(screenshot_file, template, colors, text, output_file)
221
+
222
+ # Prepare base image
223
+ result_img = MiniMagick::Image.open("#{Framer::ROOT}/assets/background.png")
224
+ result_img.resize "#{template.width}x#{template.height}!" # `!` says it should ignore the ratio
225
+
226
+ # Apply background color, if any
227
+ unless colors.background.nil?
228
+ result_img.combine_options do |c|
229
+ c.fill "#{colors.background}"
230
+ c.draw "rectangle 0,0,#{template.width},#{template.height}"
231
+ end
232
+ end
162
233
 
163
234
  # Get template image
164
235
  template_img = MiniMagick::Image.open(template.file)
@@ -171,29 +242,27 @@ module Fastlane
171
242
 
172
243
  # Put screenshot over template
173
244
  if template.imageBelow
174
-
175
- # Create a blank image
176
- base_1_img = MiniMagick::Image.open("#{Framer::ROOT}/assets/background.png")
177
- base_1_img.resize "#{template.size}!" # `!` says it should ignore the ratio
178
245
 
179
246
  # Screenshot first
180
- base_2_img = base_1_img.composite(screenshot_img) do |c|
247
+ result_img = result_img.composite(screenshot_img) do |c|
181
248
  c.compose "Over"
182
249
  c.geometry template.imageOffset.to_s
183
250
  end
184
-
251
+
185
252
  # Template second
186
- result_img = base_2_img.composite(template_img) do |c|
253
+ result_img = result_img.composite(template_img) do |c|
187
254
  c.compose "Over"
188
255
  end
189
256
 
190
- base_1_img.destroy!
191
- base_2_img.destroy!
192
-
193
257
  else
194
258
 
195
- # Screenshot over template, in one shot
196
- result_img = template_img.composite(screenshot_img) do |c|
259
+ # Template first
260
+ result_img = result_img.composite(template_img) do |c|
261
+ c.compose "Over"
262
+ end
263
+
264
+ # Screenshot second
265
+ result_img = result_img.composite(screenshot_img) do |c|
197
266
  c.compose "Over"
198
267
  c.geometry template.imageOffset.to_s
199
268
  end
@@ -217,7 +286,7 @@ module Fastlane
217
286
  c.pointsize template.textSize.to_s
218
287
  c.gravity "Center"
219
288
  c.draw "text 0,0 '#{text}'"
220
- c.fill template.textColor.to_s
289
+ c.fill colors.text.to_s
221
290
  end
222
291
  text_img.trim # remove white space
223
292
 
@@ -255,7 +324,7 @@ module Fastlane
255
324
  result_img.destroy!
256
325
  screenshot_img.destroy!
257
326
  template_img.destroy!
258
-
327
+
259
328
  end
260
329
 
261
330
  def self.create_dir_if_not_exists(path)
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
2
  module Framer
3
- VERSION = "0.2.1"
3
+ VERSION = "1.0.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane-plugin-framer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - DrAL3X
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-11-06 00:00:00.000000000 Z
11
+ date: 2018-11-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mini_magick