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