xcode-archive-cache 0.0.6

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.
@@ -0,0 +1,289 @@
1
+ module XcodeArchiveCache
2
+ module BuildSettings
3
+ class Filter
4
+
5
+ # @param [Hash{String => String}] settings
6
+ #
7
+ # @return [Hash{String => String}]
8
+ #
9
+ # Meaningful settings affecting build result
10
+ # Machine-dependent settings i.e. paths, user names, group names are rejected
11
+ #
12
+ def filter(settings, settings_to_keep = SETTINGS_TO_KEEP)
13
+ filtered_settings = settings.select {|name, _| settings_to_keep.include?(name)}
14
+ SETTINGS_TO_STRIP.each do |name|
15
+ value = filtered_settings[name]
16
+ next if value == nil
17
+
18
+ filtered_settings[name] = strip(value)
19
+ end
20
+
21
+ filtered_settings
22
+ end
23
+
24
+ private
25
+
26
+ # @param [String] value
27
+ #
28
+ # @return [String]
29
+ #
30
+ def strip(value)
31
+ # one can quote flag (like Pods do with "-D" "COCOAPODS");
32
+ # we can safely ignore those quotes as long as
33
+ # we won't pass our return value to any (compiler / linker) calls
34
+ #
35
+ # leaving quotes may lead to weird situations:
36
+ # having value: -iquote "-D" "COCOAPODS"
37
+ # we're going to get output: -D" "COCOAPODS"
38
+ # because leading quote of -D becomes a part of -iquote string after split,
39
+ # and we delete all iquotes
40
+ #
41
+ value_without_quotes = value.gsub(/["']/, "")
42
+
43
+ # in case if we meet a path like "/some/dir/something -else",
44
+ # splitting will be broken, but probability of
45
+ # someone using such path is quite low (or it isn't ?)
46
+ #
47
+ value_components = value_without_quotes.split(/\s-/)
48
+
49
+ index = 0
50
+ indices_to_remove = []
51
+ while index < value_components.length do
52
+ component = value_components[index]
53
+
54
+ PATH_FLAGS.each do |flag|
55
+ if component.start_with?(flag)
56
+ indices_to_remove += [index]
57
+ break
58
+ end
59
+ end
60
+
61
+ index += 1
62
+ end
63
+
64
+ kept_components = []
65
+ value_components.each_with_index do |component, component_index|
66
+ kept_components.push(component) unless indices_to_remove.include?(component_index)
67
+ end
68
+
69
+ kept_components.join(" -")
70
+ end
71
+
72
+ # TODO: extend
73
+ SETTINGS_TO_KEEP = %w(
74
+ ACTION
75
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES
76
+ APPLICATION_EXTENSION_API_ONLY
77
+ APPLY_RULES_IN_COPY_FILES
78
+ APS_ENV
79
+ ARCHS
80
+ ASSETCATALOG_COMPILER_APPICON_NAME
81
+ ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME
82
+ BITCODE_GENERATION_MODE
83
+ BUILD_ACTIVE_RESOURCES_ONLY
84
+ CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES
85
+ CLANG_CXX_LANGUAGE_STANDARD
86
+ CLANG_CXX_LIBRARY
87
+ CLANG_ENABLE_MODULES
88
+ CLANG_ENABLE_OBJC_ARC
89
+ CLEAN_PRECOMPS
90
+ CLONE_HEADERS
91
+ COMBINE_HIDPI_IMAGES
92
+ COMPRESS_PNG_FILES
93
+ CONFIGURATION
94
+ COPYING_PRESERVES_HFS_DATA
95
+ COPY_HEADERS_RUN_UNIFDEF
96
+ COPY_PHASE_STRIP
97
+ COPY_RESOURCES_FROM_STATIC_FRAMEWORKS
98
+ CREATE_INFOPLIST_SECTION_IN_BINARY
99
+ DEAD_CODE_STRIPPING
100
+ DEBUGGING_SYMBOLS
101
+ DEBUG_INFORMATION_FORMAT
102
+ DEFAULT_COMPILER
103
+ DEFINES_MODULE
104
+ DEPLOYMENT_POSTPROCESSING
105
+ DEPLOYMENT_TARGET_CLANG_ENV_NAME
106
+ DEPLOYMENT_TARGET_CLANG_FLAG_NAME
107
+ DEPLOYMENT_TARGET_CLANG_FLAG_PREFIX
108
+ DEPLOYMENT_TARGET_LD_ENV_NAME
109
+ DEPLOYMENT_TARGET_LD_FLAG_NAME
110
+ DEPLOYMENT_TARGET_SETTING_NAME
111
+ EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE
112
+ ENABLE_BITCODE
113
+ GCC3_VERSION
114
+ GCC_C_LANGUAGE_STANDARD
115
+ GCC_INCREASE_PRECOMPILED_HEADER_SHARING
116
+ GCC_INLINES_ARE_PRIVATE_EXTERN
117
+ GCC_NO_COMMON_BLOCKS
118
+ GCC_PREPROCESSOR_DEFINITIONS
119
+ GCC_SYMBOLS_PRIVATE_EXTERN
120
+ GCC_TREAT_WARNINGS_AS_ERRORS
121
+ GCC_VERSION
122
+ GCC_VERSION_IDENTIFIER
123
+ GENERATE_MASTER_OBJECT_FILE
124
+ GENERATE_PKGINFO_FILE
125
+ GENERATE_PROFILING_CODE
126
+ GENERATE_TEXT_BASED_STUBS
127
+ HIDE_BITCODE_SYMBOLS
128
+ INFOPLIST_EXPAND_BUILD_SETTINGS
129
+ INFOPLIST_FILE
130
+ INFOPLIST_OUTPUT_FORMAT
131
+ INFOPLIST_PREPROCESS
132
+ INFOSTRINGS_PATH
133
+ INLINE_PRIVATE_FRAMEWORKS
134
+ IPHONEOS_DEPLOYMENT_TARGET
135
+ JAVAC_DEFAULT_FLAGS
136
+ JAVA_ARCHIVE_CLASSES
137
+ JAVA_ARCHIVE_TYPE
138
+ JAVA_FOLDER_PATH
139
+ JAVA_FRAMEWORK_RESOURCES_DIRS
140
+ JAVA_JAR_FLAGS
141
+ JAVA_USE_DEPENDENCIES
142
+ JAVA_ZIP_FLAGS
143
+ JIKES_DEFAULT_FLAGS
144
+ KASAN_DEFAULT_CFLAGS
145
+ KEEP_PRIVATE_EXTERNS
146
+ LD_GENERATE_MAP_FILE
147
+ LD_NO_PIE
148
+ LD_QUOTE_LINKER_ARGUMENTS_FOR_COMPILER_DRIVER
149
+ LD_RUNPATH_SEARCH_PATHS
150
+ LEX
151
+ LINK_WITH_STANDARD_LIBRARIES
152
+ LOCALIZED_RESOURCES_FOLDER_PATH
153
+ LOCALIZED_STRING_MACRO_NAMES
154
+ MACH_O_TYPE
155
+ OTHERLD_FLAGS
156
+ OTHER_CFLAGS
157
+ OTHER_CPLUSPLUSFLAGS
158
+ OTHER_LDFLAGS
159
+ OTHER_SWIFT_FLAGS
160
+ PACKAGE_TYPE
161
+ PASCAL_STRINGS
162
+ PBDEVELOPMENTPLIST_PATH
163
+ PFE_FILE_C_DIALECTS
164
+ PKGINFO_PATH
165
+ PLATFORM_NAME
166
+ PLIST_FILE_OUTPUT_FORMAT
167
+ PLUGINS_FOLDER_PATH
168
+ PRESERVE_DEAD_CODE_INITS_AND_TERMS
169
+ PRIVATE_HEADERS_FOLDER_PATH
170
+ PRODUCT_BUNDLE_IDENTIFIER
171
+ PRODUCT_MODULE_NAME
172
+ PRODUCT_NAME
173
+ PRODUCT_TYPE
174
+ PROFILING_CODE
175
+ PROJECT
176
+ PUBLIC_HEADERS_FOLDER_PATH
177
+ RECURSIVE_SEARCH_PATHS_FOLLOW_SYMLINKS
178
+ REMOVE_CVS_FROM_RESOURCES
179
+ REMOVE_GIT_FROM_RESOURCES
180
+ REMOVE_HEADERS_FROM_EMBEDDED_BUNDLES
181
+ REMOVE_HG_FROM_RESOURCES
182
+ REMOVE_SVN_FROM_RESOURCES
183
+ RESOURCE_RULES_REQUIRED
184
+ SCAN_ALL_SOURCE_FILES_FOR_INCLUDES
185
+ SCRIPTS_FOLDER_PATH
186
+ SDK_NAME
187
+ SDK_NAMES
188
+ SDK_PRODUCT_BUILD_VERSION
189
+ SDK_VERSION
190
+ SDK_VERSION_ACTUAL
191
+ SDK_VERSION_MAJOR
192
+ SDK_VERSION_MINOR
193
+ SEPARATE_STRIP
194
+ SEPARATE_SYMBOL_EDIT
195
+ SHALLOW_BUNDLE
196
+ SKIP_INSTALL
197
+ STRINGS_FILE_OUTPUT_ENCODING
198
+ STRIP_BITCODE_FROM_COPIED_FILES
199
+ STRIP_INSTALLED_PRODUCT
200
+ STRIP_STYLE
201
+ STRIP_SWIFT_SYMBOLS
202
+ SUPPORTED_DEVICE_FAMILIES
203
+ SUPPORTS_TEXT_BASED_API
204
+ SWIFT_COMPILATION_MODE
205
+ SWIFT_OBJC_BRIDGING_HEADER
206
+ SWIFT_PLATFORM_TARGET_PREFIX
207
+ SWIFT_VERSION
208
+ TAPI_VERIFY_MODE
209
+ TARGETED_DEVICE_FAMILY
210
+ TARGETNAME
211
+ TARGET_NAME
212
+ UNLOCALIZED_RESOURCES_FOLDER_PATH
213
+ UNSTRIPPED_PRODUCT
214
+ USE_DYNAMIC_NO_PIC
215
+ USE_HEADERMAP
216
+ USE_HEADER_SYMLINKS
217
+ VALIDATE_PRODUCT
218
+ VERBOSE_PBXCP
219
+ VERSIONING_SYSTEM
220
+ VERSIONPLIST_PATH
221
+ WRAPPER_EXTENSION
222
+ WRAPPER_NAME
223
+ WRAPPER_SUFFIX
224
+ WRAP_ASSET_PACKS_IN_SEPARATE_DIRECTORIES
225
+ XCODE_PRODUCT_BUILD_VERSION
226
+ XCODE_VERSION_ACTUAL
227
+ XCODE_VERSION_MAJOR
228
+ XCODE_VERSION_MINOR
229
+ XPCSERVICES_FOLDER_PATH
230
+ YACC
231
+ variant
232
+ )
233
+
234
+ SETTINGS_TO_STRIP = %w(
235
+ GCC_PREPROCESSOR_DEFINITIONS
236
+ OTHERLD_FLAGS
237
+ OTHER_CFLAGS
238
+ OTHER_CPLUSPLUSFLAGS
239
+ OTHER_LDFLAGS
240
+ OTHER_SWIFT_FLAGS
241
+ )
242
+
243
+ # most of these are unlikely to be used,
244
+ # most used are -I -L -F -iquote -isystem
245
+ #
246
+ # first part is from Clang, second is from swiftc
247
+ # some flags mean the same for both compilers
248
+ #
249
+ PATH_FLAGS = %w(
250
+ B
251
+ cxx-isystem
252
+ fapinotes-cache-path
253
+ fmodules-cache-path
254
+ fmodules-user-build-path
255
+ fprebuilt-module-path
256
+ fprofile-generate
257
+ F
258
+ iapinotes-modules
259
+ iframework
260
+ iframeworkwithsysroot
261
+ iprefix
262
+ iquote
263
+ isysroot
264
+ isystem-after
265
+ isystem
266
+ iwithprefixbefore
267
+ iwithprefix
268
+ iwithsysroot
269
+ I
270
+ L
271
+ api-diff-data-dir
272
+ api-diff-data-file
273
+ dump-migration-states-dir
274
+ emit-loaded-module-trace-path
275
+ emit-module-path
276
+ emit-objc-header-path
277
+ emit-parseable-module-interface-path
278
+ emit-tbd-path
279
+ Fsystem
280
+ index-file-path
281
+ index-store-path
282
+ module-cache-path
283
+ output-file-map
284
+ save-optimization-record-path
285
+ working-directory
286
+ )
287
+ end
288
+ end
289
+ end
@@ -0,0 +1,80 @@
1
+ module XcodeArchiveCache
2
+ module BuildSettings
3
+
4
+ FULL_PRODUCT_NAME_KEY = "FULL_PRODUCT_NAME".freeze
5
+ DWARF_DSYM_FILE_NAME_KEY = "DWARF_DSYM_FILE_NAME".freeze
6
+
7
+ class Container
8
+
9
+ # @return [Hash{String => String}]
10
+ #
11
+ attr_reader :all
12
+
13
+ # @return [Hash{String => String}]
14
+ #
15
+ attr_reader :filtered
16
+
17
+ # @param [Hash{String => String}] all
18
+ # @param [Hash{String => String}] filtered
19
+ #
20
+ def initialize(all, filtered)
21
+ @all = all
22
+ @filtered = filtered
23
+ end
24
+
25
+ def [](name)
26
+ all[name]
27
+ end
28
+
29
+ def ==(other)
30
+ other && other.all == all && other.filtered == filtered
31
+ end
32
+ end
33
+
34
+ class Loader
35
+
36
+ # @param [Xcodebuild::Executor.new] executor
37
+ #
38
+ def initialize(executor)
39
+ @executor = executor
40
+ @extractor = Extractor.new
41
+ @settings = Hash.new
42
+ end
43
+
44
+ # @param [String] project_path
45
+ #
46
+ # @return [Hash{String => String}]
47
+ # Target build settings keyed by target name
48
+ #
49
+ def load_settings(project_path)
50
+ return if settings[project_path]
51
+
52
+ all_targets_settings = executor.load_build_settings(project_path)
53
+ settings[project_path] = extractor.extract_per_target(all_targets_settings)
54
+ end
55
+
56
+ # @param [String] project_path
57
+ # @param [String] target_name
58
+ #
59
+ def get_settings(project_path, target_name)
60
+ return nil unless settings[project_path]
61
+
62
+ settings[project_path][target_name]
63
+ end
64
+
65
+ private
66
+
67
+ # @return [XcodeArchiveCache::Xcodebuild::Executor]
68
+ #
69
+ attr_reader :executor
70
+
71
+ # @return [XcodeArchiveCache::BuildSettings::Extractor]
72
+ #
73
+ attr_reader :extractor
74
+
75
+ # @return [Hash{String => Hash}]
76
+ #
77
+ attr_reader :settings
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,77 @@
1
+ module XcodeArchiveCache
2
+ module BuildSettings
3
+ class Parser
4
+
5
+ def initialize
6
+ @setting_name_regex = Regexp.new("^(?<#{SETTING_NAME_GROUP}>#{SETTING_NAME_CHARACTERS})\s=")
7
+ @setting_value_regex = Regexp.new("^#{SETTING_NAME_CHARACTERS}\s=\s(?<#{SETTING_VALUE_GROUP}>.+)$")
8
+ @setting_entry_regex = create_entry_regex
9
+ @setting_entry_name_regex = Regexp.new(SETTING_NAME_CHARACTERS)
10
+ end
11
+
12
+ # @param [String] string
13
+ #
14
+ # @return [Array<String>]
15
+ #
16
+ def find_all_names(string)
17
+ string.scan(setting_entry_regex)
18
+ .map {|entry| entry.scan(setting_entry_name_regex).first}
19
+ .flatten
20
+ .compact
21
+ .uniq
22
+ end
23
+
24
+ # @param [String] string
25
+ #
26
+ # @return [String]
27
+ #
28
+ def parse_name(string)
29
+ match = setting_name_regex.match(string)
30
+ return nil unless match
31
+
32
+ match[SETTING_NAME_GROUP]
33
+ end
34
+
35
+ # @param [String] string
36
+ #
37
+ # @return [String]
38
+ #
39
+ def parse_value(string)
40
+ match = setting_value_regex.match(string)
41
+ return nil unless match
42
+
43
+ match[SETTING_VALUE_GROUP]
44
+ end
45
+
46
+ # @param [String] characters
47
+ #
48
+ # @return [String]
49
+ #
50
+ def create_entry_regex(characters = SETTING_NAME_CHARACTERS)
51
+ Regexp.new("\\$[({]#{characters}[)}]")
52
+ end
53
+
54
+ private
55
+
56
+ # @return [Regexp]
57
+ #
58
+ attr_reader :setting_name_regex
59
+
60
+ # @return [Regexp]
61
+ #
62
+ attr_reader :setting_value_regex
63
+
64
+ # @return [Regexp]
65
+ #
66
+ attr_reader :setting_entry_regex
67
+
68
+ # @return [Regexp]
69
+ #
70
+ attr_reader :setting_entry_name_regex
71
+
72
+ SETTING_NAME_CHARACTERS = "[A-Z0-9_]+".freeze
73
+ SETTING_NAME_GROUP = "name".freeze
74
+ SETTING_VALUE_GROUP = "value".freeze
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,36 @@
1
+ module XcodeArchiveCache
2
+ module BuildSettings
3
+ class StringInterpolator
4
+
5
+ def initialize
6
+ @parser = Parser.new
7
+ end
8
+
9
+ # @param [String] string
10
+ # @param [Container] build_settings
11
+ #
12
+ # @return [String]
13
+ #
14
+ def interpolate(string, build_settings)
15
+ names = parser.find_all_names(string)
16
+ result = string
17
+
18
+ names.each do |name|
19
+ value = build_settings[name]
20
+ next unless value
21
+
22
+ replacement_regex = parser.create_entry_regex(name)
23
+ result = result.gsub(replacement_regex, value)
24
+ end
25
+
26
+ result
27
+ end
28
+
29
+ private
30
+
31
+ # @return [Parser]
32
+ #
33
+ attr_accessor :parser
34
+ end
35
+ end
36
+ end