9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
# File 'lib/fastlane/plugin/rearchive/actions/iconset_action.rb', line 9
def self.run(params)
archive_path = File.expand_path(params[:archive_path])
raise "Archive path #{archive_path} does not exist" unless File.exist?(archive_path)
iconset_path = File.expand_path(params[:iconset_path])
iconset_manifest_path = File.expand_path("#{iconset_path}/Contents.json")
raise ".iconset manifest #{iconset_manifest_path} does not exist" unless File.exist?(iconset_manifest_path)
if File.directory?(archive_path)
archive = RearchiveHelper::XCArchive.new(archive_path)
else
archive = RearchiveHelper::IPAArchive.new(archive_path)
end
FastlaneCore::UI.message("Patching icons from: #{iconset_path}")
plist_path = archive.(archive.app_path("Info.plist"))
plist_buddy = RearchiveHelper::PlistBuddy.new(archive.local_path(plist_path))
plist_buddy.parse_dict_keys(plist_buddy.exec("Print")).filter_map do |key|
key.match(/^CFBundleIcons(~.+)?$/)
end.map do |(key, idiom_suffix)|
[":#{key}:CFBundlePrimaryIcon:CFBundleIconFiles", idiom_suffix]
end.each do |(icon_files_key, idiom_suffix)|
plist_buddy.parse_scalar_array(plist_buddy.exec("Print #{icon_files_key}")).map do |name|
%W[#{name}#{idiom_suffix}* #{name}@*x#{idiom_suffix}*].each do |path|
archive.delete(archive.app_path(path))
end
end
rescue RuntimeError => e
FastlaneCore::UI.message(e)
next
end.each do |(icon_files_key, _)|
plist_buddy.exec("Delete #{icon_files_key}")
end
JSON.parse(File.read(iconset_manifest_path))["images"].select do |image|
image["filename"]
end.map do |entry|
scale_suffix = entry["scale"] == "1x" ? "" : "@#{entry["scale"]}"
idiom_suffix = entry["idiom"] == "iphone" ? "" : "~#{entry["idiom"]}"
file_extension = File.extname(entry["filename"])
{
source: "#{iconset_path}/#{entry["filename"]}",
name: "#{File.basename(iconset_path, ".appiconset")}#{entry["size"]}",
idiom: entry["idiom"],
target: "#{File.basename(iconset_path, ".appiconset")}#{entry["size"]}#{scale_suffix}#{idiom_suffix}#{file_extension}"
}
end.group_by do |icon|
icon[:idiom]
end.each do |idiom, icons|
idiom_suffix = idiom == "iphone" ? "" : "~#{idiom}"
icons_plist_key = ":CFBundleIcons#{idiom_suffix}:CFBundlePrimaryIcon:CFBundleIconFiles"
plist_buddy.exec("Add #{icons_plist_key} array")
icons.each do |icon|
relative_path = archive.app_path((icon[:target]).to_s)
local_path = archive.local_path(relative_path)
FastlaneCore::UI.message("Copy icon from #{icon[:source].shellescape} to #{local_path.shellescape}")
system("cp #{icon[:source].shellescape} #{local_path.shellescape}", exception: true)
archive.replace(relative_path)
end.map do |icon|
icon[:name]
end.uniq.each do |key|
plist_buddy.exec("Add #{icons_plist_key}: string #{key}")
end
end
Dir.mktmpdir do |dir|
Dir.chdir(dir) do
FastlaneCore::UI.message("Current Directory: #{dir}")
FastlaneCore::UI.message("Iconset: #{iconset_path}")
IO.popen(%W[
/usr/bin/actool
--output-format human-readable-text
--notices
--warnings
--output-partial-info-plist assetcatalog_generated_info.plist
--app-icon #{File.basename(iconset_path, ".appiconset")}
--compress-pngs
--enable-on-demand-resources YES
--sticker-pack-identifier-prefix #{plist_buddy.exec("Print CFBundleIdentifier")}.sticker-pack.
--target-device iphone
--target-device ipad
--minimum-deployment-target #{plist_buddy.exec("Print MinimumOSVersion")}
--platform iphoneos
--product-type com.apple.product-type.application
--compile
.
#{File.dirname(iconset_path)}
].map(&:shellescape).join(" "), "r") do |io|
FastlaneCore::UI.verbose(io.read) if params[:verbose]
end
generated_plist_buddy = RearchiveHelper::PlistBuddy.new("assetcatalog_generated_info.plist")
plist_buddy.parse_dict_keys(generated_plist_buddy.exec("Print")).filter_map do |key|
key.match(/^CFBundleIcons(~.+)?$/)
end.each do |key|
plist_buddy.exec("Delete #{key}")
end
plist_buddy.exec("Merge assetcatalog_generated_info.plist")
archive.replace(plist_path)
relative_path = archive.app_path("Assets.car")
local_path = archive.local_path(relative_path)
system("mkdir -p #{File.dirname(local_path).shellescape}", exception: true)
system("mv Assets.car #{local_path.shellescape}", exception: true)
archive.replace(relative_path)
end
end
end
|