fastlane/lib/fastlane/actions/get_version_number.rb in fastlane-2.86.0.beta.20180316050051 vs fastlane/lib/fastlane/actions/get_version_number.rb in fastlane-2.86.0.beta.20180317050040

- old
+ new

@@ -2,93 +2,83 @@ module Actions class GetVersionNumberAction < Action require 'shellwords' def self.run(params) - # More information about how to set up your project and how it works: - # https://developer.apple.com/library/ios/qa/qa1827/_index.html - folder = params[:xcodeproj] ? File.join(params[:xcodeproj], '..') : '.' + target_name = params[:target] + configuration = params[:configuration] - command_prefix = [ - 'cd', - File.expand_path(folder).shellescape, - '&&' - ].join(' ') + # Get version_number + project = get_project!(folder) + target = get_target!(project, target_name) + plist_file = get_plist!(folder, target, configuration) + version_number = get_version_number!(plist_file) - command = [ - command_prefix, - 'agvtool', - 'what-marketing-version', - '-terse' - ].join(' ') + # Store the number in the shared hash + Actions.lane_context[SharedValues::VERSION_NUMBER] = version_number - line = "" - scheme = params[:scheme] || "" - target = params[:target] || "" - results = [] + # Return the version number because Swift might need this return value + return version_number + end - if Helper.test? - results = [ - '$(date +%s)n /usr/libexec/Plistbuddy -c "Set CFBundleVersion $buildnum" "${plist}"n', - '"SampleProject.xcodeproj/../TargetA/TargetA-Info.plist"=4.3.2', - '"SampleProject.xcodeproj/../TargetATests/Info.plist"=4.3.2', - '"SampleProject.xcodeproj/../TargetB/TargetB-Info.plist"=5.4.3', - '"SampleProject.xcodeproj/../TargetBTests/Info.plist"=5.4.3', - '"SampleProject.xcodeproj/../SampleProject/supporting_files/TargetC_internal-Info.plist"=7.5.2', - '"SampleProject.xcodeproj/../SampleProject/supporting_files/TargetC_production-Info.plist"=6.4.9', - '"SampleProject.xcodeproj/../SampleProject_tests/Info.plist"=1.0' - ] + def self.get_project!(folder) + require 'xcodeproj' + project_path = Dir.glob("#{folder}/*.xcodeproj").first + if project_path + return Xcodeproj::Project.open(project_path) else - results = Actions.sh(command).split("\n") + UI.user_error!("Unable to find Xcode project in folder: #{folder}") end + end - if target.empty? && scheme.empty? - # Sometimes the results array contains nonsense as the first element - # This iteration finds the first 'real' result and returns that - # emulating the actual behavior or the -terse1 flag correctly - project_string = ".xcodeproj" - results.any? do |result| - if result.include?(project_string) - line = result - break - end - end + def self.get_target!(project, target_name) + targets = project.targets + + # Prompt targets if no name + unless target_name + options = targets.map(&:name) + target_name = UI.select("What target would you like to use?", options) + end + + # Find target + target = targets.find do |t| + t.name == target_name + end + UI.user_error!("Cannot find target named '#{target_name}'") unless target + + target + end + + def self.get_plist!(folder, target, configuration = nil) + plist_files = target.resolved_build_setting("INFOPLIST_FILE") + plist_files_count = plist_files.values.compact.uniq.count + + # Get plist file for specified configuration + # Or: Prompt for configuration if plist has different files in each configurations + # Else: Get first(only) plist value + if configuration + plist_file = plist_files[configuration] + elsif plist_files_count > 1 + options = plist_files.keys + selected = UI.select("What build configuration would you like to use?", options) + plist_file = plist_files[selected] else - # This iteration finds the first folder structure or info plist - # matching the specified target - scheme_string = "/#{scheme}" - target_string = "/#{target}/" - plist_target_string = "/#{target}-" - results.any? do |result| - if !target.empty? - if result.include?(target_string) - line = result - break - elsif result.include?(plist_target_string) - line = result - break - end - else - if result.include?(scheme_string) - line = result - break - end - end - end + plist_file = plist_files.values.first end - version_number = line.partition('=').last + plist_file = File.absolute_path(File.join(folder, plist_file)) + UI.user_error!("Cannot find plist file: #{plist_file}") unless File.exist?(plist_file) - # Store the number in the shared hash - Actions.lane_context[SharedValues::VERSION_NUMBER] = version_number + plist_file + end - # Return the version number because Swift might need this return value - return version_number - rescue => ex - UI.error('Before being able to increment and read the version number from your Xcode project, you first need to setup your project properly. Please follow the guide at https://developer.apple.com/library/content/qa/qa1827/_index.html') - raise ex + def self.get_version_number!(plist_file) + plist = Xcodeproj::Plist.read_from_path(plist_file) + UI.user_error!("Unable to read plist: #{plist_file}") unless plist + + plist["CFBundleShortVersionString"] end ##################################################### # @!group Documentation ##################################################### @@ -97,13 +87,11 @@ "Get the version number of your project" end def self.details [ - "This action will return the current version number set on your project.", - "You first have to set up your Xcode project, if you haven't done it already:", - "https://developer.apple.com/library/ios/qa/qa1827/_index.html" + "This action will return the current version number set on your project." ].join(' ') end def self.available_options [ @@ -111,23 +99,19 @@ env_name: "FL_VERSION_NUMBER_PROJECT", description: "optional, you must specify the path to your main Xcode project if it is not in the project root directory", optional: true, verify_block: proc do |value| UI.user_error!("Please pass the path to the project, not the workspace") if value.end_with?(".xcworkspace") - UI.user_error!("Could not find Xcode project at path '#{File.expand_path(value)}'") if !File.exist?(value) and !Helper.test? + UI.user_error!("Could not find Xcode project at path '#{File.expand_path(value)}'") if !File.exist?(value) && !Helper.test? end), - FastlaneCore::ConfigItem.new(key: :scheme, - env_name: "FL_VERSION_NUMBER_SCHEME", - description: "Specify a specific scheme if you have multiple per project, optional. " \ - "This parameter is deprecated and will be removed in a future release. " \ - "Please use the 'target' parameter instead. The behavior of this parameter " \ - "is currently undefined if your scheme name doesn't match your target name", - optional: true, - deprecated: true), FastlaneCore::ConfigItem.new(key: :target, env_name: "FL_VERSION_NUMBER_TARGET", description: "Specify a specific target if you have multiple per project, optional", + optional: true), + FastlaneCore::ConfigItem.new(key: :configuration, + env_name: "FL_VERSION_NUMBER_CONFIGURATION", + description: "Specify a specific configuration if you have multiple per target, optional", optional: true) ] end def self.output @@ -135,10 +119,10 @@ ['VERSION_NUMBER', 'The version number'] ] end def self.authors - ["Liquidsoul"] + ["Liquidsoul", "joshdholtz"] end def self.is_supported?(platform) [:ios, :mac].include?(platform) end