Class: Fastlane::Actions::ExtractAppIconAction

Inherits:
Action
  • Object
show all
Defined in:
lib/fastlane/plugin/polidea/actions/extract_app_icon.rb

Class Method Summary collapse

Class Method Details

.authorObject



155
156
157
# File 'lib/fastlane/plugin/polidea/actions/extract_app_icon.rb', line 155

def self.author
  "Piotrek Dubiel"
end

.available_optionsObject



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/fastlane/plugin/polidea/actions/extract_app_icon.rb', line 129

def self.available_options
  [
    FastlaneCore::ConfigItem.new(key: :ipa,
                                 env_name: "",
                                 description: ".ipa file to extract icon",
                                 optional: true,
                                 default_value: Actions.lane_context[SharedValues::IPA_OUTPUT_PATH]),
    FastlaneCore::ConfigItem.new(key: :apk,
                                 env_name: "",
                                 description: ".apk file to extract icon",
                                 optional: true,
                                 default_value: Actions.lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH]),
    FastlaneCore::ConfigItem.new(key: :icon_output_path,
                                 env_name: "",
                                 description: "icon output path",
                                 optional: true,
                                 default_value: "./app_icon.png")
  ]
end

.categoryObject



163
164
165
# File 'lib/fastlane/plugin/polidea/actions/extract_app_icon.rb', line 163

def self.category
  :deprecated
end

.descriptionObject



125
126
127
# File 'lib/fastlane/plugin/polidea/actions/extract_app_icon.rb', line 125

def self.description
  "Extracts largest icon from .ipa/.apk, use `extract_app_info` instead"
end

.extract_icon(platform, config) ⇒ Object



29
30
31
32
33
34
35
36
37
# File 'lib/fastlane/plugin/polidea/actions/extract_app_icon.rb', line 29

def self.extract_icon(platform, config)
  validate_common(config)
  case platform
  when :ios
    extract_icon_from_ipa(config[:ipa], config[:icon_output_path]) if validate_ios(config)
  when :android
    extract_icon_from_apk(config[:apk], config[:icon_output_path]) if validate_android(config)
  end
end

.extract_icon_from_apk(apk_file, icon_output_path) ⇒ Object



90
91
92
93
94
95
96
97
# File 'lib/fastlane/plugin/polidea/actions/extract_app_icon.rb', line 90

def self.extract_icon_from_apk(apk_file, icon_output_path)
  apk = Android::Apk.new(apk_file)
  icon = largest_android_icon(apk)
  return unless icon
  icon_file = File.open(icon_output_path, 'wb')
  icon_file.write icon[:data]
  icon_file
end

.extract_icon_from_ipa(ipa_file, icon_output_path) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/fastlane/plugin/polidea/actions/extract_app_icon.rb', line 46

def self.extract_icon_from_ipa(ipa_file, icon_output_path)
  info = FastlaneCore::IpaFileAnalyser.fetch_info_plist_file(ipa_file)
  icon_files = ipa_icon_files(info)
  return if icon_files.empty?
  icon_file_name = icon_files.first
  Zip::File.open(ipa_file) do |zipfile|
    icon_file = self.largest_ios_icon(zipfile.glob("**/Payload/**/#{icon_file_name}*.png"))
    return nil unless icon_file
    tmp_path = "/tmp/app_icon.png"
    File.write(tmp_path, zipfile.read(icon_file))
    Actions.sh("xcrun -sdk iphoneos pngcrush -revert-iphone-optimizations #{tmp_path} #{icon_output_path}")
    File.delete(tmp_path)
  end
end

.ipa_icon_files(info) ⇒ Object



61
62
63
64
65
66
67
68
69
70
# File 'lib/fastlane/plugin/polidea/actions/extract_app_icon.rb', line 61

def self.ipa_icon_files(info)
  icons = info['CFBundleIcons']
  unless icons.nil?
    primary_icon = icons['CFBundlePrimaryIcon']
    unless primary_icon.nil?
      return primary_icon['CFBundleIconFiles']
    end
  end
  []
end

.is_supported?(platform) ⇒ Boolean

Returns:

  • (Boolean)


159
160
161
# File 'lib/fastlane/plugin/polidea/actions/extract_app_icon.rb', line 159

def self.is_supported?(platform)
  [:ios, :android].include? platform
end

.largest_android_icon(apk) ⇒ Object



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/fastlane/plugin/polidea/actions/extract_app_icon.rb', line 99

def self.largest_android_icon(apk)
  icons = apk.icon
  selected_icon = icons.max_by do |name, _|
    case name
    when /x*hdpi/
      name.count "x"
    when /mdpi/
      -1
    when %r{\/drawable\/}
      -2
    else
      -3
    end
  end
  { name: selected_icon[0], data: selected_icon[1] } if selected_icon
rescue
  nil
end

.largest_ios_icon(icons) ⇒ Object



72
73
74
75
76
77
78
79
80
81
# File 'lib/fastlane/plugin/polidea/actions/extract_app_icon.rb', line 72

def self.largest_ios_icon(icons)
  icons.max_by do |file, _|
    case file.name
    when /@(\d+)x/
      $1.to_i
    else
      1
    end
  end
end

.outputObject



149
150
151
152
153
# File 'lib/fastlane/plugin/polidea/actions/extract_app_icon.rb', line 149

def self.output
  [
    ['ICON_OUTPUT_PATH', 'Path to app icon extracted from .ipa/.apk']
  ]
end

.run(config) ⇒ Object



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/fastlane/plugin/polidea/actions/extract_app_icon.rb', line 12

def self.run(config)
  platform = Actions.lane_context[Actions::SharedValues::PLATFORM_NAME].to_sym
  icon_output_path = config[:icon_output_path]

  # Gets icon from ipa/apk
  icon_file = extract_icon(platform, config)

  if icon_file
    Actions.lane_context[SharedValues::ICON_OUTPUT_PATH] = icon_output_path
    ENV[SharedValues::ICON_OUTPUT_PATH.to_s] = icon_output_path
    UI.success("Successfully extracted app icon file to '#{Actions.lane_context[SharedValues::ICON_OUTPUT_PATH]}'")
    icon_file
  else
    UI.important("No icon found.")
  end
end

.validate_android(config) ⇒ Object

android specific



85
86
87
88
# File 'lib/fastlane/plugin/polidea/actions/extract_app_icon.rb', line 85

def self.validate_android(config)
  UI.user_error!("No APK file path given, pass using `apk: 'apk path'`") unless config[:apk].to_s.length > 0
  true
end

.validate_common(config) ⇒ Object

common



120
121
122
123
# File 'lib/fastlane/plugin/polidea/actions/extract_app_icon.rb', line 120

def self.validate_common(config)
  UI.user_error!("No icon path given, pass using `icon_output_path: 'icon path'`") unless config[:icon_output_path].to_s.length > 0
  true
end

.validate_ios(config) ⇒ Object

ios specific



41
42
43
44
# File 'lib/fastlane/plugin/polidea/actions/extract_app_icon.rb', line 41

def self.validate_ios(config)
  UI.user_error!("No IPA file path given, pass using `ipa: 'ipa path'`") unless config[:ipa].to_s.length > 0
  true
end