fastlane 2.142.0 → 2.143.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +84 -84
- data/fastlane/lib/fastlane/actions/.hockey.rb.swp +0 -0
- data/fastlane/lib/fastlane/actions/.slack.rb.swp +0 -0
- data/fastlane/lib/fastlane/actions/.update_project_provisioning.rb.swp +0 -0
- data/fastlane/lib/fastlane/actions/docs/frame_screenshots.md +22 -6
- data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +20 -4
- data/fastlane/lib/fastlane/actions/frame_screenshots.rb +2 -1
- data/fastlane/lib/fastlane/actions/s3.rb +3 -289
- data/fastlane/lib/fastlane/helper/s3_client_helper.rb +56 -0
- data/fastlane/lib/fastlane/version.rb +1 -1
- data/fastlane/swift/Deliverfile.swift +1 -1
- data/fastlane/swift/Fastlane.swift +59 -5
- data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.xcworkspace/xcuserdata/josh.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- data/fastlane/swift/Gymfile.swift +1 -1
- data/fastlane/swift/Matchfile.swift +1 -1
- data/fastlane/swift/MatchfileProtocol.swift +17 -1
- data/fastlane/swift/Precheckfile.swift +1 -1
- data/fastlane/swift/Scanfile.swift +1 -1
- data/fastlane/swift/Screengrabfile.swift +1 -1
- data/fastlane/swift/Snapshotfile.swift +1 -1
- data/fastlane_core/lib/fastlane_core/ipa_file_analyser.rb +1 -0
- data/frameit/lib/frameit/commands_generator.rb +25 -0
- data/frameit/lib/frameit/config_parser.rb +31 -9
- data/frameit/lib/frameit/device.rb +90 -0
- data/frameit/lib/frameit/device_types.rb +121 -5
- data/frameit/lib/frameit/editor.rb +28 -40
- data/frameit/lib/frameit/offsets.rb +8 -1
- data/frameit/lib/frameit/options.rb +81 -54
- data/frameit/lib/frameit/runner.rb +17 -7
- data/frameit/lib/frameit/screenshot.rb +35 -47
- data/frameit/lib/frameit/template_finder.rb +15 -12
- data/match/lib/match/change_password.rb +1 -1
- data/match/lib/match/encryption.rb +4 -0
- data/match/lib/match/importer.rb +2 -2
- data/match/lib/match/module.rb +1 -1
- data/match/lib/match/nuke.rb +5 -1
- data/match/lib/match/options.rb +18 -0
- data/match/lib/match/runner.rb +4 -0
- data/match/lib/match/setup.rb +1 -1
- data/match/lib/match/storage.rb +4 -0
- data/match/lib/match/storage/s3_storage.rb +162 -0
- data/pilot/lib/pilot/.manager.rb.swp +0 -0
- data/scan/lib/scan/test_command_generator.rb +2 -1
- data/screengrab/lib/screengrab/runner.rb +11 -3
- data/spaceship/lib/spaceship/connect_api/.DS_Store +0 -0
- data/spaceship/lib/spaceship/connect_api/models/build.rb +1 -2
- data/spaceship/lib/spaceship/connect_api/models/certificate.rb +2 -0
- data/spaceship/lib/spaceship/portal/.certificate.rb.swp +0 -0
- metadata +42 -19
- data/gym/lib/gym/.code_signing_mapping.rb.swp +0 -0
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'fastimage'
|
2
|
+
require_relative 'module'
|
3
|
+
|
4
|
+
module Frameit
|
5
|
+
class Device
|
6
|
+
REQUIRED_PRIORITY = 999
|
7
|
+
|
8
|
+
attr_reader :id
|
9
|
+
attr_reader :deliver_screen_id
|
10
|
+
attr_reader :formatted_name
|
11
|
+
attr_reader :resolutions
|
12
|
+
attr_reader :density_ppi
|
13
|
+
attr_reader :default_color
|
14
|
+
attr_reader :platform
|
15
|
+
attr_reader :priority_config_key
|
16
|
+
|
17
|
+
def initialize(id, formatted_name, priority, resolutions, density_ppi, default_color, platform = Platform::IOS, deliver_screen_id = nil, priority_config_key = nil)
|
18
|
+
Raise("Priority mustn't be higher than #{REQUIRED_PRIORITY}") if priority > REQUIRED_PRIORITY
|
19
|
+
@id = id
|
20
|
+
@deliver_screen_id = deliver_screen_id
|
21
|
+
@formatted_name = formatted_name
|
22
|
+
@priority = priority
|
23
|
+
@resolutions = resolutions
|
24
|
+
@density_ppi = density_ppi
|
25
|
+
@default_color = default_color
|
26
|
+
@platform = platform
|
27
|
+
@priority_config_key = priority_config_key
|
28
|
+
end
|
29
|
+
|
30
|
+
def priority
|
31
|
+
if !priority_config_key.nil? && Frameit.config[priority_config_key]
|
32
|
+
REQUIRED_PRIORITY
|
33
|
+
else
|
34
|
+
@priority
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def is_chosen_platform?(platform)
|
39
|
+
@platform == platform || platform == Platform::ANY
|
40
|
+
end
|
41
|
+
|
42
|
+
def formatted_name_without_apple
|
43
|
+
formatted_name.gsub("Apple", "").strip.to_s
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.detect_device(path, platform)
|
47
|
+
size = FastImage.size(path)
|
48
|
+
|
49
|
+
UI.user_error!("Could not find or parse file at path '#{path}'") if size.nil? || size.count == 0
|
50
|
+
|
51
|
+
found_device = nil
|
52
|
+
filename_device = nil
|
53
|
+
filename = Pathname.new(path).basename.to_s
|
54
|
+
Devices.constants.each do |c|
|
55
|
+
device = Devices.const_get(c)
|
56
|
+
next unless device.resolutions.include?(size)
|
57
|
+
# assign to filename_device if the filename contains the formatted name / id and its priority is higher than the current filename_device
|
58
|
+
filename_device = device if (filename.include?(device.formatted_name_without_apple) || filename.include?(device.id)) && (filename_device.nil? || filename_device.priority < device.priority)
|
59
|
+
next unless device.is_chosen_platform?(platform) && (found_device.nil? || device.priority > found_device.priority)
|
60
|
+
found_device = device
|
61
|
+
end
|
62
|
+
|
63
|
+
# prefer filename
|
64
|
+
return filename_device if filename_device
|
65
|
+
|
66
|
+
# return found_device which was detected according to platform & priority & settings if found
|
67
|
+
return found_device if found_device
|
68
|
+
|
69
|
+
# no device detected - show error and return nil
|
70
|
+
UI.user_error!("Unsupported screen size #{size} for path '#{path}'")
|
71
|
+
return nil
|
72
|
+
end
|
73
|
+
|
74
|
+
# Previously ENV[FRAMEIT_FORCE_DEVICE_TYPE] was matched to Deliver::AppScreenshot::ScreenSize constants. However,
|
75
|
+
# options.rb defined a few Apple devices with unspecified IDs, this option was never read from Frameit.config.
|
76
|
+
# Therefore this function matches both ScreenSize constants and formatted names to maintain backward compatibility.
|
77
|
+
def self.find_device_by_id_or_name(id)
|
78
|
+
return nil if id.nil?
|
79
|
+
found_device = nil
|
80
|
+
# multiple devices can be matched to the same deliver_screen_id constant -> we return the one with the highest priority
|
81
|
+
Devices.constants.each do |c|
|
82
|
+
device = Devices.const_get(c)
|
83
|
+
if (device.id == id || device.deliver_screen_id == id || device.formatted_name_without_apple == id) && (found_device.nil? || device.priority > found_device.priority)
|
84
|
+
found_device = device
|
85
|
+
end
|
86
|
+
end
|
87
|
+
return found_device
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -1,18 +1,134 @@
|
|
1
|
+
require_relative 'device'
|
2
|
+
require_relative 'module'
|
3
|
+
require 'deliver/app_screenshot'
|
4
|
+
|
1
5
|
module Frameit
|
2
6
|
module Color
|
3
|
-
|
4
|
-
|
7
|
+
MATTE_BLACK = "Matte Black"
|
8
|
+
SPACE_GRAY = "Space Gray"
|
5
9
|
ROSE_GOLD = "Rose Gold"
|
10
|
+
CLEARLY_WHITE = "Clearly White"
|
11
|
+
JUST_BLACK = "Just Black"
|
12
|
+
NOT_PINK = "Not Pink"
|
13
|
+
SILVER_TITANIUM = "Silver Titanium"
|
14
|
+
ARCTIC_SILVER = "Arctic Silver"
|
15
|
+
CORAL_BLUE = "Coral Blue"
|
16
|
+
MAPLE_GOLD = "Maple Gold"
|
17
|
+
MIDNIGHT_BLACK = "Midnight Black"
|
18
|
+
MIDNIGHT_GREEN = "Midnight Green"
|
19
|
+
ORCHID_GRAY = "Orchid Gray"
|
20
|
+
BURGUNDY_RED = "Burgundy Red"
|
21
|
+
LILAC_PURPLE = "Lilac Purple"
|
22
|
+
SUNRISE_GOLD = "Sunrise Gold"
|
23
|
+
TITANIUM_GRAY = "Titanium Gray"
|
24
|
+
FLAMINGO_PINK = "Flamingo Pink"
|
25
|
+
PRISM_BLACK = "Prism Black"
|
26
|
+
PRISM_BLUE = "Prism Blue"
|
27
|
+
PRISM_GREEN = "Prism Green"
|
28
|
+
PRISM_WHITE = "Prism White"
|
29
|
+
CERAMIC_WHITE = "Ceramic White"
|
30
|
+
OH_SO_ORANGE = "Oh So Orange"
|
31
|
+
AURA_BLACK = "Aura Black"
|
32
|
+
AURA_GLOW = "Aura Glow"
|
33
|
+
AURA_PINK = "Aura Pink"
|
34
|
+
AURA_RED = "Aura Red"
|
35
|
+
AURA_WHITE = "Aura White"
|
36
|
+
AURA_BLUE = "Aura Blue"
|
37
|
+
CORAL = "Coral"
|
38
|
+
BLACK = "Black"
|
39
|
+
WHITE = "White"
|
6
40
|
GOLD = "Gold"
|
41
|
+
SILVER = "Silver"
|
42
|
+
BLUE = "Blue"
|
7
43
|
RED = "Red"
|
8
44
|
YELLOW = "Yellow"
|
9
|
-
|
10
|
-
|
11
|
-
|
45
|
+
GREEN = "Green"
|
46
|
+
PINK = "Pink"
|
47
|
+
PURPLE = "Purple"
|
48
|
+
|
49
|
+
def self.all_colors
|
50
|
+
Color.constants.map { |c| Color.const_get(c).upcase.gsub(' ', '_') }
|
51
|
+
end
|
12
52
|
end
|
13
53
|
|
14
54
|
module Orientation
|
15
55
|
PORTRAIT = "PORTRAIT"
|
16
56
|
LANDSCAPE = "LANDSCAPE"
|
17
57
|
end
|
58
|
+
|
59
|
+
module Platform
|
60
|
+
ANDROID = "ANDROID"
|
61
|
+
IOS = "IOS"
|
62
|
+
ANY = "ANY"
|
63
|
+
|
64
|
+
def self.all_platforms
|
65
|
+
Platform.constants.map { |c| Platform.const_get(c) }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
module Devices
|
70
|
+
GOOGLE_PIXEL_3 = Frameit::Device.new("google-pixel-3", "Google Pixel 3", 7, [[1080, 2160], [2160, 1080]], 443, Color::JUST_BLACK, Platform::ANDROID)
|
71
|
+
GOOGLE_PIXEL_3_XL = Frameit::Device.new("google-pixel-3-xl", "Google Pixel 3 XL", 7, [[1440, 2960], [2960, 1440]], 523, Color::JUST_BLACK, Platform::ANDROID)
|
72
|
+
# Google Pixel 4's priority should be higher than Samsung Galaxy S10+ (priority 8):
|
73
|
+
GOOGLE_PIXEL_4 = Frameit::Device.new("google-pixel-4", "Google Pixel 4", 9, [[1080, 2280], [2280, 1080]], 444, Color::JUST_BLACK, Platform::ANDROID)
|
74
|
+
GOOGLE_PIXEL_4_XL = Frameit::Device.new("google-pixel-4-xl", "Google Pixel 4 XL", 9, [[1440, 3040], [3040, 1440]], 537, Color::JUST_BLACK, Platform::ANDROID)
|
75
|
+
HTC_ONE_A9 = Frameit::Device.new("htc-one-a9", "HTC One A9", 6, [[1080, 1920], [1920, 1080]], 441, Color::BLACK, Platform::ANDROID)
|
76
|
+
HTC_ONE_M8 = Frameit::Device.new("htc-one-m8", "HTC One M8", 3, [[1080, 1920], [1920, 1080]], 441, Color::BLACK, Platform::ANDROID)
|
77
|
+
HUAWEI_P8 = Frameit::Device.new("huawei-p8", "Huawei P8", 5, [[1080, 1920], [1920, 1080]], 424, Color::BLACK, Platform::ANDROID)
|
78
|
+
MOTOROLA_MOTO_E = Frameit::Device.new("motorola-moto-e", "Motorola Moto E", 3, [[540, 960], [960, 540]], 245, Color::BLACK, Platform::ANDROID)
|
79
|
+
MOTOROLA_MOTO_G = Frameit::Device.new("motorola-moto-g", "Motorola Moto G", 4, [[1080, 1920], [1920, 1080]], 401, nil, Platform::ANDROID, nil)
|
80
|
+
NEXUS_4 = Frameit::Device.new("nexus-4", "Nexus 4", 7, [[768, 1280], [1820, 768]], 318, nil, Platform::ANDROID)
|
81
|
+
NEXUS_5X = Frameit::Device.new("nexus-5x", "Nexus 5X", 7, [[1080, 1920], [1920, 1080]], 423, nil, Platform::ANDROID)
|
82
|
+
NEXUS_6P = Frameit::Device.new("nexus-6p", "Nexus 6P", 7, [[1440, 2560], [2560, 1440]], 518, nil, Platform::ANDROID)
|
83
|
+
NEXUS_9 = Frameit::Device.new("nexus-9", "Nexus 9", 7, [[1536, 2048], [2048, 1536]], 281, nil, Platform::ANDROID)
|
84
|
+
SAMSUNG_GALAXY_GRAND_PRIME = Frameit::Device.new("samsung-galaxy-grand-prime", "Samsung Galaxy Grand Prime", 5, [[540, 960], [960, 540]], 220, Color::BLACK, Platform::ANDROID)
|
85
|
+
SAMSUNG_GALAXY_NOTE_5 = Frameit::Device.new("samsung-galaxy-note-5", "Samsung Galaxy Note 5", 5, [[1440, 2560], [2560, 1440]], 518, Color::BLACK, Platform::ANDROID)
|
86
|
+
SAMSUNG_GALAXY_NOTE_10 = Frameit::Device.new("samsung-galaxy-note-10", "Samsung Galaxy Note 10", 6, [[1080, 2280], [2280, 1080]], 401, Color::AURA_BLACK, Platform::ANDROID)
|
87
|
+
SAMSUNG_GALAXY_NOTE_10_PLUS = Frameit::Device.new("samsung-galaxy-note-10-plus", "Samsung Galaxy Note 10+", 7, [[1440, 3040], [3040, 1440]], 498, Color::AURA_BLACK, Platform::ANDROID)
|
88
|
+
SAMSUNG_GALAXY_S_DUOS = Frameit::Device.new("samsung-galaxy-s-duos", "Samsung Galaxy S Duos", 3, [[480, 800], [800, 480]], 233, nil, Platform::ANDROID)
|
89
|
+
SAMSUNG_GALAXY_S3 = Frameit::Device.new("samsung-galaxy-s3", "Samsung Galaxy S3", 3, [[720, 1280], [1280, 720]], 306, nil, Platform::ANDROID)
|
90
|
+
SAMSUNG_GALAXY_S5 = Frameit::Device.new("samsung-galaxy-s5", "Samsung Galaxy S5", 3, [[1080, 1920], [1920, 1080]], 432, Color::BLACK, Platform::ANDROID)
|
91
|
+
SAMSUNG_GALAXY_S7 = Frameit::Device.new("samsung-galaxy-s7", "Samsung Galaxy S7", 4, [[1440, 2560], [2560, 1440]], 577, Color::BLACK, Platform::ANDROID)
|
92
|
+
SAMSUNG_GALAXY_S8 = Frameit::Device.new("samsung-galaxy-s8", "Samsung Galaxy S8", 5, [[1440, 2960], [2960, 1440]], 570, Color::MIDNIGHT_BLACK, Platform::ANDROID)
|
93
|
+
SAMSUNG_GALAXY_S9 = Frameit::Device.new("samsung-galaxy-s9", "Samsung Galaxy S9", 6, [[1440, 2960], [2960, 1440]], 570, Color::MIDNIGHT_BLACK, Platform::ANDROID)
|
94
|
+
SAMSUNG_GALAXY_S10 = Frameit::Device.new("samsung-galaxy-s10", "Samsung Galaxy S10", 7, [[1440, 3040], [3040, 1440]], 550, Color::PRISM_BLACK, Platform::ANDROID)
|
95
|
+
SAMSUNG_GALAXY_S10_PLUS = Frameit::Device.new("samsung-galaxy-s10-plus", "Samsung Galaxy S10+", 8, [[1440, 3040], [3040, 1440]], 522, Color::PRISM_BLACK, Platform::ANDROID)
|
96
|
+
XIAOMI_MI_MIX_ALPHA = Frameit::Device.new("xiaomi-mi-mix-alpha", "Xiaomi Mi Mix Alpha", 1, [[2088, 2250], [2250, 2088]], 388, nil, Platform::ANDROID)
|
97
|
+
IPHONE_5S = Frameit::Device.new("iphone-5s", "Apple iPhone 5s", 2, [[640, 1096], [640, 1136], [1136, 600], [1136, 640]], 326, Color::SPACE_GRAY, Platform::IOS, Deliver::AppScreenshot::ScreenSize::IOS_40, :use_legacy_iphone5s)
|
98
|
+
IPHONE_5C = Frameit::Device.new("iphone-5c", "Apple iPhone 5c", 2, [[640, 1136], [1136, 640]], 326, Color::WHITE)
|
99
|
+
IPHONE_SE = Frameit::Device.new("iphone-se", "Apple iPhone SE", 3, [[640, 1096], [640, 1136], [1136, 600], [1136, 640]], 326, Color::SPACE_GRAY, Platform::IOS, Deliver::AppScreenshot::ScreenSize::IOS_40)
|
100
|
+
IPHONE_6S = Frameit::Device.new("iphone-6s", "Apple iPhone 6s", 4, [[750, 1334], [1334, 750]], 326, Color::SPACE_GRAY, Platform::IOS, Deliver::AppScreenshot::ScreenSize::IOS_47, :use_legacy_iphone6s)
|
101
|
+
IPHONE_6S_PLUS = Frameit::Device.new("iphone-6s-plus", "Apple iPhone 6s Plus", 4, [[1242, 2208], [2208, 1242]], 401, Color::SPACE_GRAY, Platform::IOS, Deliver::AppScreenshot::ScreenSize::IOS_55, :use_legacy_iphone6s)
|
102
|
+
IPHONE_7 = Frameit::Device.new("iphone-7", "Apple iPhone 7", 5, [[750, 1334], [1334, 750]], 326, Color::MATTE_BLACK, Platform::IOS, Deliver::AppScreenshot::ScreenSize::IOS_47, :use_legacy_iphone7)
|
103
|
+
IPHONE_7_PLUS = Frameit::Device.new("iphone-7-plus", "Apple iPhone 7 Plus", 5, [[1242, 2208], [2208, 1242]], 401, Color::MATTE_BLACK, Platform::IOS, Deliver::AppScreenshot::ScreenSize::IOS_55, :use_legacy_iphone7)
|
104
|
+
IPHONE_8 = Frameit::Device.new("iphone-8", "Apple iPhone 8", 6, [[750, 1334], [1334, 750]], 326, Color::SPACE_GRAY)
|
105
|
+
IPHONE_8_PLUS = Frameit::Device.new("iphone-8-plus", "Apple iPhone 8 Plus", 6, [[1080, 1920], [1920, 1080]], 401, Color::SPACE_GRAY)
|
106
|
+
IPHONE_X = Frameit::Device.new("iphone-X", "Apple iPhone X", 7, [[1125, 2436], [2436, 1125]], 458, Color::SPACE_GRAY, Platform::IOS, Deliver::AppScreenshot::ScreenSize::IOS_58, :use_legacy_iphonex)
|
107
|
+
IPHONE_XS = Frameit::Device.new("iphone-XS", "Apple iPhone XS", 8, [[1125, 2436], [2436, 1125]], 458, Color::SPACE_GRAY, Platform::IOS, Deliver::AppScreenshot::ScreenSize::IOS_58, :use_legacy_iphonexs)
|
108
|
+
IPHONE_XR = Frameit::Device.new("iphone-XR", "Apple iPhone XR", 8, [[828, 1792], [1792, 828]], 326, Color::SPACE_GRAY, Platform::IOS, Deliver::AppScreenshot::ScreenSize::IOS_61, :use_legacy_iphonexr)
|
109
|
+
IPHONE_XS_MAX = Frameit::Device.new("iphone-XS-Max", "Apple iPhone XS Max", 8, [[1242, 2688], [2688, 1242]], 458, Color::SPACE_GRAY, Platform::IOS, Deliver::AppScreenshot::ScreenSize::IOS_65, :use_legacy_iphonexsmax)
|
110
|
+
IPHONE_11 = Frameit::Device.new("iphone-11", "Apple iPhone 11", 9, [[828, 1792], [1792, 828]], 326, Color::BLACK, Platform::IOS)
|
111
|
+
IPHONE_11_PRO = Frameit::Device.new("iphone-11-pro", "Apple iPhone 11 Pro", 9, [[1125, 2436], [2436, 1125]], 458, Color::SPACE_GRAY, Platform::IOS)
|
112
|
+
IPHONE_11_PRO_MAX = Frameit::Device.new("iphone11-pro-max", "Apple iPhone 11 Pro Max", 9, [[1242, 2688], [2688, 1242]], 458, Color::SPACE_GRAY, Platform::IOS)
|
113
|
+
IPAD_10_2 = Frameit::Device.new("ipad-10-2", "Apple iPad 10.2", 1, [[1620, 2160], [2160, 1620]], 264, Color::SPACE_GRAY, Platform::IOS)
|
114
|
+
IPAD_AIR_2 = Frameit::Device.new("ipad-air-2", "Apple iPad Air 2", 1, [[1536, 2048], [2048, 1536]], 264, Color::SPACE_GRAY, Platform::IOS, Deliver::AppScreenshot::ScreenSize::IOS_IPAD)
|
115
|
+
IPAD_AIR_2019 = Frameit::Device.new("ipad-air-2019", "Apple iPad Air (2019)", 2, [[1668, 2224], [2224, 1668]], 265, Color::SPACE_GRAY, Platform::IOS)
|
116
|
+
IPAD_MINI_4 = Frameit::Device.new("ipad-mini-4", "Apple iPad Mini 4", 2, [[1536, 2048], [2048, 1536]], 324, Color::SPACE_GRAY)
|
117
|
+
IPAD_MINI_2019 = Frameit::Device.new("ipad-mini-2019", "Apple iPad Mini (2019)", 3, [[1536, 2048], [2048, 1536]], 324, Color::SPACE_GRAY)
|
118
|
+
# this is 1st or 2nd gen of iPad Pro 12.9:
|
119
|
+
IPAD_PRO = Frameit::Device.new("ipad-pro", "Apple iPad Pro", 3, [[2048, 2732], [2732, 2048]], 264, Color::SPACE_GRAY, Platform::IOS, Deliver::AppScreenshot::ScreenSize::IOS_IPAD_PRO)
|
120
|
+
# 3rd generation:
|
121
|
+
IPAD_PRO_12_9 = Frameit::Device.new("ipadPro129", "Apple iPad Pro (12.9-inch) (3rd generation)", 4, [[2048, 2732], [2732, 2048]], 264, Color::SPACE_GRAY, Platform::IOS, Deliver::AppScreenshot::ScreenSize::IOS_IPAD_PRO_12_9)
|
122
|
+
# iPad Pro (10.5-inch) is not in frameit-frames repo, but must be included so that we are backward compatible with PR #15373
|
123
|
+
# priority must be lower so that users who didn't copy the frame to their frameit frames folder will not get an error
|
124
|
+
# ID and formatted name must be exactly as specified so that device.detect_device() will select this device if the filename includes them
|
125
|
+
IPAD_PRO_10_5 = Frameit::Device.new("ipad105", "Apple iPad Pro (10.5-inch)", 1, [[1668, 2224], [2224, 1668]], 265, Color::SPACE_GRAY, Platform::IOS, Deliver::AppScreenshot::ScreenSize::IOS_IPAD_10_5)
|
126
|
+
IPAD_PRO_11 = Frameit::Device.new("ipadPro11", "Apple iPad Pro (11-inch)", 1, [[1668, 2388], [2388, 1668]], 265, Color::SPACE_GRAY, Platform::IOS, Deliver::AppScreenshot::ScreenSize::IOS_IPAD_11)
|
127
|
+
|
128
|
+
MAC = Frameit::Device.new("mac", "Apple MacBook", 0, [[1280, 800], [1440, 900], [2560, 1600], [2880, 1800]], nil, Color::SPACE_GRAY, Platform::IOS, Deliver::AppScreenshot::ScreenSize::MAC)
|
129
|
+
|
130
|
+
def self.all_device_names_without_apple
|
131
|
+
Devices.constants.map { |c| Devices.const_get(c).formatted_name_without_apple }
|
132
|
+
end
|
133
|
+
end
|
18
134
|
end
|
@@ -18,8 +18,9 @@ module Frameit
|
|
18
18
|
attr_accessor :image # the current image used for editing
|
19
19
|
attr_accessor :space_to_device
|
20
20
|
|
21
|
-
def initialize(screenshot, debug_mode = false)
|
21
|
+
def initialize(screenshot, config, debug_mode = false)
|
22
22
|
@screenshot = screenshot
|
23
|
+
@config = config
|
23
24
|
self.debug_mode = debug_mode
|
24
25
|
end
|
25
26
|
|
@@ -121,7 +122,7 @@ module Frameit
|
|
121
122
|
def offset
|
122
123
|
return @offset_information if @offset_information
|
123
124
|
|
124
|
-
@offset_information =
|
125
|
+
@offset_information = @config['offset'] || Offsets.image_offset(screenshot).dup
|
125
126
|
|
126
127
|
if @offset_information && (@offset_information['offset'] || @offset_information['offset'])
|
127
128
|
return @offset_information
|
@@ -148,7 +149,7 @@ module Frameit
|
|
148
149
|
|
149
150
|
# Do we add a background and title as well?
|
150
151
|
def is_complex_framing_mode?
|
151
|
-
return (
|
152
|
+
return (@config['background'] and (@config['title'] or @config['keyword']))
|
152
153
|
end
|
153
154
|
|
154
155
|
# more complex mode: background, frame and title
|
@@ -157,8 +158,8 @@ module Frameit
|
|
157
158
|
|
158
159
|
self.space_to_device = vertical_frame_padding
|
159
160
|
|
160
|
-
if
|
161
|
-
background = put_title_into_background(background,
|
161
|
+
if @config['title']
|
162
|
+
background = put_title_into_background(background, @config['stack_title'])
|
162
163
|
end
|
163
164
|
|
164
165
|
if self.frame # we have no frame on le mac
|
@@ -169,7 +170,7 @@ module Frameit
|
|
169
170
|
frame_width = background.width - horizontal_frame_padding * 2
|
170
171
|
frame_height = background.height - effective_text_height - vertical_frame_padding
|
171
172
|
|
172
|
-
if
|
173
|
+
if @config['show_complete_frame']
|
173
174
|
# calculate the final size of the screenshot to resize in one go
|
174
175
|
# it may be limited either by the width or height of the frame
|
175
176
|
image_aspect_ratio = @image.width.to_f / @image.height.to_f
|
@@ -191,7 +192,7 @@ module Frameit
|
|
191
192
|
|
192
193
|
# Horizontal adding around the frames
|
193
194
|
def horizontal_frame_padding
|
194
|
-
padding =
|
195
|
+
padding = @config['padding']
|
195
196
|
if padding.kind_of?(String) && padding.split('x').length == 2
|
196
197
|
padding = padding.split('x')[0]
|
197
198
|
padding = padding.to_i unless padding.end_with?('%')
|
@@ -201,7 +202,7 @@ module Frameit
|
|
201
202
|
|
202
203
|
# Vertical adding around the frames
|
203
204
|
def vertical_frame_padding
|
204
|
-
padding =
|
205
|
+
padding = @config['padding']
|
205
206
|
if padding.kind_of?(String) && padding.split('x').length == 2
|
206
207
|
padding = padding.split('x')[1]
|
207
208
|
padding = padding.to_i unless padding.end_with?('%')
|
@@ -212,7 +213,7 @@ module Frameit
|
|
212
213
|
# Minimum height for the title
|
213
214
|
def title_min_height
|
214
215
|
@title_min_height ||= begin
|
215
|
-
height =
|
216
|
+
height = @config['title_min_height'] || 0
|
216
217
|
if height.kind_of?(String) && height.end_with?('%')
|
217
218
|
height = ([image.width, image.height].min * height.to_f * 0.01).ceil
|
218
219
|
end
|
@@ -244,12 +245,12 @@ module Frameit
|
|
244
245
|
end
|
245
246
|
|
246
247
|
def title_below_image
|
247
|
-
@title_below_image ||=
|
248
|
+
@title_below_image ||= @config['title_below_image']
|
248
249
|
end
|
249
250
|
|
250
251
|
# Returns a correctly sized background image
|
251
252
|
def generate_background
|
252
|
-
background = MiniMagick::Image.open(
|
253
|
+
background = MiniMagick::Image.open(@config['background'])
|
253
254
|
|
254
255
|
if background.height != screenshot.size[1]
|
255
256
|
background.resize("#{screenshot.size[0]}x#{screenshot.size[1]}^") # `^` says it should fill area
|
@@ -338,12 +339,12 @@ module Frameit
|
|
338
339
|
sum_width = title.width
|
339
340
|
sum_width += keyword.width + keyword_padding if keyword
|
340
341
|
|
341
|
-
title_below_image =
|
342
|
+
title_below_image = @config['title_below_image']
|
342
343
|
|
343
344
|
# Resize the 2 labels if they exceed the available space either horizontally or vertically:
|
344
345
|
image_scale_factor = 1.0 # default
|
345
346
|
ratio_horizontal = sum_width / (image.width.to_f - horizontal_frame_padding * 2) # The fraction of the text images compared to the left and right padding
|
346
|
-
ratio_vertical = title.height.to_f /
|
347
|
+
ratio_vertical = title.height.to_f / effective_text_height # The fraction of the actual height of the images compared to the available space
|
347
348
|
if ratio_horizontal > 1.0 || ratio_vertical > 1.0
|
348
349
|
# If either is too large, resize with the maximum ratio:
|
349
350
|
image_scale_factor = (1.0 / [ratio_horizontal, ratio_vertical].max)
|
@@ -385,7 +386,7 @@ module Frameit
|
|
385
386
|
end
|
386
387
|
|
387
388
|
def actual_font_size
|
388
|
-
font_scale_factor =
|
389
|
+
font_scale_factor = @config['font_scale_factor'] || 0.1
|
389
390
|
UI.user_error!("Parameter 'font_scale_factor' can not be 0. Please provide a value larger than 0.0 (default = 0.1).") if font_scale_factor == 0.0
|
390
391
|
[@image.width * font_scale_factor].max.round
|
391
392
|
end
|
@@ -420,7 +421,7 @@ module Frameit
|
|
420
421
|
text.gsub!('\n', "\n")
|
421
422
|
text.gsub!(/(?<!\\)(')/) { |s| "\\#{s}" } # escape unescaped apostrophes with a backslash
|
422
423
|
|
423
|
-
interline_spacing =
|
424
|
+
interline_spacing = @config['interline_spacing']
|
424
425
|
|
425
426
|
# Add the actual title
|
426
427
|
text_image.combine_options do |i|
|
@@ -429,7 +430,7 @@ module Frameit
|
|
429
430
|
i.pointsize(actual_font_size)
|
430
431
|
i.draw("text 0,0 '#{text}'")
|
431
432
|
i.interline_spacing(interline_spacing) if interline_spacing
|
432
|
-
i.fill(
|
433
|
+
i.fill(@config[key.to_s]['color'])
|
433
434
|
end
|
434
435
|
|
435
436
|
results[key] = text_image
|
@@ -491,18 +492,6 @@ module Frameit
|
|
491
492
|
results
|
492
493
|
end
|
493
494
|
|
494
|
-
# Loads the config (colors, background, texts, etc.)
|
495
|
-
# Don't use this method to access the actual text and use `fetch_texts` instead
|
496
|
-
def fetch_config
|
497
|
-
return @config if @config
|
498
|
-
|
499
|
-
config_path = File.join(File.expand_path("..", screenshot.path), "Framefile.json")
|
500
|
-
config_path = File.join(File.expand_path("../..", screenshot.path), "Framefile.json") unless File.exist?(config_path)
|
501
|
-
file = ConfigParser.new.load(config_path)
|
502
|
-
return {} unless file # no config file at all
|
503
|
-
@config = file.fetch_value(screenshot.path)
|
504
|
-
end
|
505
|
-
|
506
495
|
# Fetches the title + keyword for this particular screenshot
|
507
496
|
def fetch_text(type)
|
508
497
|
UI.user_error!("Valid parameters :keyword, :title") unless [:keyword, :title].include?(type)
|
@@ -518,20 +507,19 @@ module Frameit
|
|
518
507
|
UI.verbose("Falling back to text in Framefile.json as there was nothing specified in the #{type}.strings file")
|
519
508
|
|
520
509
|
# No string files, fallback to Framefile config
|
521
|
-
text =
|
510
|
+
text = @config[type.to_s]['text'] if @config[type.to_s] && @config[type.to_s]['text'] && @config[type.to_s]['text'].length > 0 # Ignore empty string
|
522
511
|
return text
|
523
512
|
end
|
524
513
|
|
525
514
|
def fetch_frame_color
|
526
|
-
color =
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
return Frameit::Color::ROSE_GOLD
|
515
|
+
color = @config['frame']
|
516
|
+
unless color.nil?
|
517
|
+
Frameit::Color.constants.each do |c|
|
518
|
+
constant = Frameit::Color.const_get(c)
|
519
|
+
if color == constant.upcase.gsub(' ', '_')
|
520
|
+
return constant
|
521
|
+
end
|
522
|
+
end
|
535
523
|
end
|
536
524
|
|
537
525
|
return nil
|
@@ -539,10 +527,10 @@ module Frameit
|
|
539
527
|
|
540
528
|
# The font we want to use
|
541
529
|
def font(key)
|
542
|
-
single_font =
|
530
|
+
single_font = @config[key.to_s]['font']
|
543
531
|
return single_font if single_font
|
544
532
|
|
545
|
-
fonts =
|
533
|
+
fonts = @config[key.to_s]['fonts']
|
546
534
|
if fonts
|
547
535
|
fonts.each do |font|
|
548
536
|
if font['supported']
|
@@ -13,9 +13,16 @@ module Frameit
|
|
13
13
|
@offsets_cache = JSON.parse(File.read(offsets_json_path))
|
14
14
|
end
|
15
15
|
|
16
|
-
offset_value = @offsets_cache["portrait"][screenshot.device_name]
|
16
|
+
offset_value = @offsets_cache["portrait"][sanitize_device_name(screenshot.device_name)]
|
17
17
|
UI.error("Tried looking for offset information for 'portrait', #{screenshot.device_name} in '#{offsets_json_path}'") unless offset_value
|
18
18
|
return offset_value
|
19
19
|
end
|
20
|
+
|
21
|
+
def self.sanitize_device_name(basename)
|
22
|
+
# this should be the same as frames_generator's sanitize_device_name (except stripping colors):
|
23
|
+
basename = basename.gsub("Apple", "")
|
24
|
+
basename = basename.gsub("-", " ")
|
25
|
+
basename.strip.to_s
|
26
|
+
end
|
20
27
|
end
|
21
28
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'fastlane_core/configuration/config_item'
|
2
2
|
|
3
3
|
require_relative 'module'
|
4
|
+
require_relative 'config_parser'
|
5
|
+
require_relative 'device_types'
|
4
6
|
|
5
7
|
module Frameit
|
6
8
|
class Options
|
@@ -8,74 +10,99 @@ module Frameit
|
|
8
10
|
@options ||= [
|
9
11
|
|
10
12
|
FastlaneCore::ConfigItem.new(key: :white,
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
13
|
+
env_name: "FRAMEIT_WHITE_FRAME",
|
14
|
+
description: "Use white device frames",
|
15
|
+
type: Boolean,
|
16
|
+
optional: true),
|
15
17
|
FastlaneCore::ConfigItem.new(key: :silver,
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
18
|
+
env_name: "FRAMEIT_SILVER_FRAME",
|
19
|
+
description: "Use white device frames. Alias for :white",
|
20
|
+
type: Boolean,
|
21
|
+
optional: true),
|
20
22
|
FastlaneCore::ConfigItem.new(key: :rose_gold,
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
23
|
+
env_name: "FRAMEIT_ROSE_GOLD_FRAME",
|
24
|
+
description: "Use rose gold device frames. Alias for :rose_gold",
|
25
|
+
type: Boolean,
|
26
|
+
optional: true),
|
25
27
|
FastlaneCore::ConfigItem.new(key: :gold,
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
28
|
+
env_name: "FRAMEIT_GOLD_FRAME",
|
29
|
+
description: "Use gold device frames. Alias for :gold",
|
30
|
+
type: Boolean,
|
31
|
+
optional: true),
|
30
32
|
FastlaneCore::ConfigItem.new(key: :force_device_type,
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
UI.user_error!("Invalid device type '#{value}'. Available values: #{available}")
|
38
|
-
end
|
39
|
-
end),
|
33
|
+
env_name: "FRAMEIT_FORCE_DEVICE_TYPE",
|
34
|
+
description: "Forces a given device type, useful for Mac screenshots, as their sizes vary",
|
35
|
+
optional: true,
|
36
|
+
verify_block: proc do |value|
|
37
|
+
UI.user_error!("Invalid device type '#{value}'. Available values: " + Devices.all_device_names_without_apple.join(', ')) unless ConfigParser.supported_device?(value)
|
38
|
+
end),
|
40
39
|
FastlaneCore::ConfigItem.new(key: :use_legacy_iphone5s,
|
41
|
-
|
42
|
-
|
40
|
+
env_name: "FRAMEIT_USE_LEGACY_IPHONE_5_S",
|
41
|
+
description: "Use iPhone 5s instead of iPhone SE frames",
|
42
|
+
default_value: false,
|
43
|
+
type: Boolean),
|
44
|
+
FastlaneCore::ConfigItem.new(key: :use_legacy_iphone6s,
|
45
|
+
env_name: "FRAMEIT_USE_LEGACY_IPHONE_6_S",
|
46
|
+
description: "Use iPhone 6s frames instead of iPhone 7 frames",
|
47
|
+
default_value: false,
|
48
|
+
type: Boolean),
|
49
|
+
FastlaneCore::ConfigItem.new(key: :use_legacy_iphone7,
|
50
|
+
env_name: "FRAMEIT_USE_LEGACY_IPHONE_7",
|
51
|
+
description: "Use iPhone 7 frames instead of iPhone 8 frames",
|
52
|
+
default_value: false,
|
53
|
+
type: Boolean),
|
54
|
+
FastlaneCore::ConfigItem.new(key: :use_legacy_iphonex,
|
55
|
+
env_name: "FRAMEIT_USE_LEGACY_IPHONE_X",
|
56
|
+
description: "Use iPhone X instead of iPhone XS frames",
|
57
|
+
default_value: false,
|
58
|
+
type: Boolean),
|
59
|
+
FastlaneCore::ConfigItem.new(key: :use_legacy_iphonexr,
|
60
|
+
env_name: "FRAMEIT_USE_LEGACY_IPHONE_XR",
|
61
|
+
description: "Use iPhone XR instead of iPhone 11 frames",
|
43
62
|
default_value: false,
|
44
63
|
type: Boolean),
|
45
|
-
FastlaneCore::ConfigItem.new(key: :
|
46
|
-
env_name: "
|
47
|
-
description: "Use iPhone
|
64
|
+
FastlaneCore::ConfigItem.new(key: :use_legacy_iphonexs,
|
65
|
+
env_name: "FRAMEIT_USE_LEGACY_IPHONE_XS",
|
66
|
+
description: "Use iPhone XS instead of iPhone 11 Pro frames",
|
48
67
|
default_value: false,
|
49
68
|
type: Boolean),
|
50
|
-
FastlaneCore::ConfigItem.new(key: :
|
51
|
-
env_name: "
|
52
|
-
description: "Use iPhone
|
69
|
+
FastlaneCore::ConfigItem.new(key: :use_legacy_iphonexsmax,
|
70
|
+
env_name: "FRAMEIT_USE_LEGACY_IPHONE_XS_MAX",
|
71
|
+
description: "Use iPhone XS Max instead of iPhone 11 Pro Max frames",
|
53
72
|
default_value: false,
|
54
73
|
type: Boolean),
|
55
74
|
FastlaneCore::ConfigItem.new(key: :force_orientation_block,
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
75
|
+
type: :string_callback,
|
76
|
+
description: "[Advanced] A block to customize your screenshots' device orientation",
|
77
|
+
display_in_shell: false,
|
78
|
+
optional: true,
|
79
|
+
default_value: proc do |filename|
|
80
|
+
f = filename.downcase
|
81
|
+
if f.end_with?("force_landscapeleft")
|
82
|
+
:landscape_left
|
83
|
+
elsif f.end_with?("force_landscaperight")
|
84
|
+
:landscape_right
|
85
|
+
end
|
86
|
+
end,
|
87
|
+
default_value_dynamic: true),
|
69
88
|
FastlaneCore::ConfigItem.new(key: :debug_mode,
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
89
|
+
env_name: "FRAMEIT_DEBUG_MODE",
|
90
|
+
description: "Output debug information in framed screenshots",
|
91
|
+
default_value: false,
|
92
|
+
type: Boolean),
|
74
93
|
FastlaneCore::ConfigItem.new(key: :resume,
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
94
|
+
env_name: "FRAMEIT_RESUME",
|
95
|
+
description: "Resume frameit instead of reprocessing all screenshots",
|
96
|
+
default_value: false,
|
97
|
+
type: Boolean),
|
98
|
+
FastlaneCore::ConfigItem.new(key: :use_platform,
|
99
|
+
env_name: "FRAMEIT_USE_PLATFORM",
|
100
|
+
description: "Choose a platform, the valid options are IOS, ANDROID and ANY (IOS is default to ensure backward compatibility)",
|
101
|
+
optional: true,
|
102
|
+
default_value: Platform::IOS,
|
103
|
+
verify_block: proc do |value|
|
104
|
+
UI.user_error!("Invalid platform type '#{value}'. Available values are " + Platform.all_platforms.join(', ') + ".") unless ConfigParser.supported_platform?(value)
|
105
|
+
end)
|
79
106
|
]
|
80
107
|
end
|
81
108
|
end
|