summaryrefslogtreecommitdiff
path: root/app/services/projects/apple_target_platform_detector_service.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/services/projects/apple_target_platform_detector_service.rb')
-rw-r--r--app/services/projects/apple_target_platform_detector_service.rb58
1 files changed, 58 insertions, 0 deletions
diff --git a/app/services/projects/apple_target_platform_detector_service.rb b/app/services/projects/apple_target_platform_detector_service.rb
new file mode 100644
index 00000000000..ec4c16a1416
--- /dev/null
+++ b/app/services/projects/apple_target_platform_detector_service.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+module Projects
+ # Service class to detect target platforms of a project made for the Apple
+ # Ecosystem.
+ #
+ # This service searches project.pbxproj and *.xcconfig files (contains build
+ # settings) for the string "SDKROOT = <SDK_name>" where SDK_name can be
+ # 'iphoneos', 'macosx', 'appletvos' or 'watchos'. Currently, the service is
+ # intentionally limited (for performance reasons) to detect if a project
+ # targets iOS.
+ #
+ # Ref: https://developer.apple.com/documentation/xcode/build-settings-reference/
+ #
+ # Example usage:
+ # > AppleTargetPlatformDetectorService.new(a_project).execute
+ # => []
+ # > AppleTargetPlatformDetectorService.new(an_ios_project).execute
+ # => [:ios]
+ # > AppleTargetPlatformDetectorService.new(multiplatform_project).execute
+ # => [:ios, :osx, :tvos, :watchos]
+ class AppleTargetPlatformDetectorService < BaseService
+ BUILD_CONFIG_FILENAMES = %w(project.pbxproj *.xcconfig).freeze
+
+ # For the current iteration, we only want to detect when the project targets
+ # iOS. In the future, we can use the same logic to detect projects that
+ # target OSX, TvOS, and WatchOS platforms with SDK names 'macosx', 'appletvos',
+ # and 'watchos', respectively.
+ PLATFORM_SDK_NAMES = { ios: 'iphoneos' }.freeze
+
+ def execute
+ detect_platforms
+ end
+
+ private
+
+ def file_finder
+ @file_finder ||= ::Gitlab::FileFinder.new(project, project.default_branch)
+ end
+
+ def detect_platforms
+ # Return array of SDK names for which "SDKROOT = <sdk_name>" setting
+ # definition can be found in either project.pbxproj or *.xcconfig files.
+ PLATFORM_SDK_NAMES.select do |_, sdk|
+ config_files_containing_sdk_setting(sdk).present?
+ end.keys
+ end
+
+ # Return array of project.pbxproj and/or *.xcconfig files
+ # (Gitlab::Search::FoundBlob) that contain the setting definition string
+ # "SDKROOT = <sdk_name>"
+ def config_files_containing_sdk_setting(sdk)
+ BUILD_CONFIG_FILENAMES.map do |filename|
+ file_finder.find("SDKROOT = #{sdk} filename:#{filename}")
+ end.flatten
+ end
+ end
+end