ios_dev_tools 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,115 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'ios_dev_tools'
5
+
6
+ $be_verbose=false
7
+
8
+ def verbose_msg message
9
+
10
+ puts message if $be_verbose
11
+
12
+ end
13
+
14
+ def error_msg message
15
+
16
+ puts "\nERROR:\t#{message}\n"
17
+
18
+ end
19
+
20
+ def parse_options(args)
21
+
22
+ options = Hash.new
23
+ OptionParser.new do |opts|
24
+
25
+ opts.banner = "Usage: ios_sign.rb -i \"iPhone Distribution: Name\" -p path/to/profile -o output/ipa/file [options] inputIpa"
26
+
27
+ opts.separator ""
28
+ opts.separator "Options:"
29
+
30
+ opts.on("-p", "--profile PATH_TO_PROFILE", "Path to profile") do |profile_location|
31
+ options[:profile_location] = profile_location
32
+ end
33
+
34
+ opts.on("-b", "--bundle-id [BUNDLE_IDENTIFIER]", "Bundle identifier") do |bundle_id|
35
+ options[:bundle_id] = bundle_id
36
+ end
37
+
38
+ opts.on("-o", "--output OUTPUT_IPA_FILE", "Output ipa archive") do |output_ipa|
39
+ options[:output_ipa] = output_ipa
40
+ end
41
+
42
+ opts.on("-i", "--identity IDENTITY", "Identity") do |identity|
43
+ options[:identity] = identity
44
+ end
45
+
46
+ opts.on("-t", "--temp [TEMP_FOLDER]", "Temporary folder location") do |temp_folder|
47
+ options[:temp_folder] = temp_folder
48
+ end
49
+
50
+ opts.separator ""
51
+ opts.separator "Common options:"
52
+
53
+ opts.on("-v", "--verbose", "Run verbosely") do |v|
54
+ options[:verbose] = v
55
+ end
56
+
57
+ # No argument, shows at tail. This will print an options summary.
58
+ # Try it and see!
59
+ opts.on_tail("-h", "--help", "Show this message") do
60
+ puts opts
61
+ exit
62
+ end
63
+
64
+ end.parse!(args)
65
+
66
+ options[:input_file]=ARGV[0]
67
+ mandatory=[options[:profile_location],options[:identity],options[:output_ipa],options[:input_file]]
68
+ expected_number=mandatory.count
69
+ real_number=mandatory.compact.count
70
+ if expected_number != real_number
71
+ # one of mandatory switches is missing
72
+ # display help and exit
73
+ parse_options ["-h"]
74
+ end
75
+
76
+ $be_verbose=(options[:verbose]!=nil)
77
+
78
+ return options
79
+ end
80
+
81
+ def main
82
+
83
+ options=parse_options ARGV
84
+
85
+ verbose_msg "Passed options:\n#{options.inspect}"
86
+
87
+ begin
88
+ provisioning_profile=IOSDevTools::ProvisioningProfile.new options[:profile_location]
89
+ application_bundle=IOSDevTools::ApplicationBundle.new options[:input_file] do |ab|
90
+ ab.temp_folder=options[:temp_folder]
91
+ end
92
+ rescue => error
93
+ error_msg error
94
+ exit 1
95
+ end
96
+
97
+ new_bundle_id = options[:bundle_id]
98
+ new_bundle_id ||= application_bundle.bundle_id
99
+
100
+ if not provisioning_profile.is_compatible_with_bundle_id new_bundle_id
101
+ error_msg "Provisioning profile identifier [#{provisioning_profile.application_identifier}] is not compatible with bundle identifier [#{new_bundle_id}]\n \
102
+ \tMaybe you should use -b switch to overwrite the bundle identifier?"
103
+ exit 1
104
+ end
105
+
106
+ application_bundle.bundle_id = new_bundle_id
107
+ application_bundle.set_provisioning_profile provisioning_profile.profile_location
108
+ application_bundle.sign_with_identity options[:identity]
109
+ application_bundle.package_to_ipa options[:output_ipa]
110
+
111
+ puts "\nApplication archive created and signed: #{options[:output_ipa]}"
112
+
113
+ end
114
+
115
+ main
@@ -0,0 +1,7 @@
1
+
2
+ module IOSDevTools
3
+
4
+ autoload :ApplicationBundle, 'ios_dev_tools/application_bundle'
5
+ autoload :ProvisioningProfile, 'ios_dev_tools/provisioning_profile'
6
+
7
+ end
@@ -0,0 +1,98 @@
1
+
2
+ require 'pathname'
3
+
4
+ module IOSDevTools
5
+
6
+ #
7
+ #
8
+ #
9
+ class ApplicationBundle
10
+
11
+ attr_accessor :is_application_folder
12
+ attr_accessor :is_valid_zip_archive
13
+ attr_accessor :src_location
14
+ attr_accessor :location
15
+ attr_accessor :temp_folder
16
+ attr_accessor :plist_buddy_cmd
17
+ attr_accessor :application_name
18
+
19
+ def initialize file_or_folder_location
20
+
21
+ raise "Application bundle \"#{file_or_folder_location}\" doesn't exist" if not File.exists? file_or_folder_location
22
+
23
+ @is_application_folder=File.directory?(file_or_folder_location) && file_or_folder_location.end_with?(".app")
24
+ if not @is_application_folder
25
+ @is_valid_zip_archive=`file #{file_or_folder_location}`.include? "Zip archive data"
26
+ raise "[#{file_or_folder_location}] is not a valid application archive" if not @is_valid_zip_archive
27
+ end
28
+
29
+ yield self if block_given?
30
+
31
+ @src_location=file_or_folder_location
32
+ @temp_folder||="temp"
33
+ @plist_buddy_cmd||="/usr/libexec/PlistBuddy"
34
+
35
+ if not @is_application_folder
36
+ # wipe out temp folder
37
+ `rm -Rf #{temp_folder}/Payload 2>&1 > /dev/null`
38
+ # unzip application bundle
39
+ `unzip -q "#{@src_location}" -d #{@temp_folder}`
40
+ # point to unzipped location
41
+ @location=Dir.glob("#{@temp_folder}/Payload/*")[0]
42
+ else
43
+ @location=@src_location
44
+ end
45
+
46
+ @application_name=Pathname.new(@location).basename
47
+
48
+ end
49
+
50
+ def display_name
51
+ `#{@plist_buddy_cmd} -c "Print :CFBundleDisplayName" "#{@location}/Info.plist"`.strip
52
+ end
53
+
54
+ def display_name= new_name
55
+ return if not new_name
56
+ `#{@plist_buddy_cmd} -c "Set :CFBundleDisplayName #{new_name}" "#{@location}/Info.plist"`
57
+ end
58
+
59
+ def bundle_id
60
+ `#{@plist_buddy_cmd} -c "Print :CFBundleIdentifier" "#{@location}/Info.plist"`.strip
61
+ end
62
+
63
+ def bundle_id= new_bundle_id
64
+ return if not new_bundle_id
65
+ `#{@plist_buddy_cmd} -c "Set :CFBundleIdentifier #{new_bundle_id}" "#{@location}/Info.plist"`
66
+ end
67
+
68
+ def set_provisioning_profile new_provisioning_profile_location
69
+ return if not new_provisioning_profile_location
70
+ `cp "#{new_provisioning_profile_location}" "#{@location}/embedded.mobileprovision"`
71
+ end
72
+
73
+ def sign_with_identity new_identity
74
+ return if not new_identity
75
+ `/usr/bin/codesign -f -s "#{new_identity}" --resource-rules="#{@location}/ResourceRules.plist" "#{@location}" 2>&1`
76
+ end
77
+
78
+ def current_identity
79
+
80
+ invalid_signature=`codesign -d -vv "#{@location}" 2>&1`.include? "invalid signature"
81
+ return "Invalid signature" if invalid_signature
82
+
83
+ codesign_output=`codesign -d -vv "#{@location}" 2>&1 | grep "Authority"`
84
+ info=codesign_output.lines.first
85
+ return info.strip.split("=")[1] if info
86
+
87
+ return nil
88
+
89
+ end
90
+
91
+ def package_to_ipa ipa_file_location
92
+ return if not ipa_file_location
93
+ `(cd #{@temp_folder} && zip -qr ../temp.ipa *) && mv temp.ipa "#{ipa_file_location}"`
94
+ end
95
+
96
+ end
97
+
98
+ end
@@ -0,0 +1,30 @@
1
+
2
+
3
+ module IOSDevTools
4
+
5
+ class ProvisioningProfile
6
+
7
+ attr_accessor :profile_location
8
+
9
+ def initialize profile_location
10
+
11
+ raise "Profisioning profile file \"#{profile_location}\" doesn't exist" if not File.exists? profile_location
12
+
13
+ @profile_location=profile_location
14
+
15
+ yield self if block_given?
16
+
17
+ end
18
+
19
+ def application_identifier
20
+ `egrep -a -A 2 application-identifier "#{@profile_location}" | grep string | sed -e 's/<string>//' -e 's/<\\/string>//' -e 's/ //' | awk '{split($0,a,"."); i = length(a); for(ix=2; ix <= i;ix++){ s=s a[ix]; if(i!=ix){s=s "."};} print s;}'`.strip
21
+ end
22
+
23
+ def is_compatible_with_bundle_id bundle_id
24
+ bundle_id_prefix=application_identifier.sub(/\*$/,"")
25
+ bundle_id.start_with? bundle_id_prefix
26
+ end
27
+
28
+ end
29
+
30
+ end
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ios_dev_tools
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Marcin Maciukiewicz
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2013-12-28 00:00:00 +00:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: Set of ruby wrappers around iOS dev tasks
22
+ email: mm@csquirrel.com
23
+ executables:
24
+ - ios_sign
25
+ extensions: []
26
+
27
+ extra_rdoc_files: []
28
+
29
+ files:
30
+ - lib/ios_dev_tools.rb
31
+ - lib/ios_dev_tools/application_bundle.rb
32
+ - lib/ios_dev_tools/provisioning_profile.rb
33
+ has_rdoc: true
34
+ homepage: https://github.com/cSquirrel/ios_dev_tools
35
+ licenses:
36
+ - MIT
37
+ post_install_message:
38
+ rdoc_options: []
39
+
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ segments:
47
+ - 0
48
+ version: "0"
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ segments:
54
+ - 0
55
+ version: "0"
56
+ requirements: []
57
+
58
+ rubyforge_project: nowarning
59
+ rubygems_version: 1.3.6
60
+ signing_key:
61
+ specification_version: 3
62
+ summary: iOS Dev Tools
63
+ test_files: []
64
+