xcoder 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -18,18 +18,21 @@ and then require the gem in your project/rakefile/etc
18
18
 
19
19
  ### Find a configuration for a target on a project
20
20
 
21
- project = Xcode.find_projects.first
22
- config = project.target(:Target).config(:Debug)
23
-
21
+ project = Xcode.project(:MyProject).target(:Target).config(:Debug)
24
22
 
25
23
  ### Building a configuration
26
24
 
27
- config.build
25
+ builder = config.builder
26
+ builder.profile = 'Profiles/MyAdHoc.mobileprovision' # This will remove old profiles and install the profile
27
+ builder.identity = 'iPhone Developer: Ray Hilton' # The name of the identity to use to sign the IPA (optional)
28
+ builder.build
28
29
 
29
30
  ### Packaging a built .app
30
31
 
31
- config.package :sign => 'Developer Identity Name', :profile => 'Profile.mobileprovision'
32
+ builder.package
32
33
 
34
+ This will produce a .ipa and a .dSYM.zip
35
+
33
36
  ### Incrementing the build number
34
37
 
35
38
  config.info_plist do |info|
@@ -0,0 +1,129 @@
1
+ require 'xcode/shell'
2
+ require 'xcode/provisioning_profile'
3
+
4
+ module Xcode
5
+ class Builder
6
+ attr_accessor :profile, :identity
7
+
8
+ def initialize(config)
9
+ @target = config.target
10
+ @config = config
11
+ end
12
+
13
+ def install_profile
14
+ return if @profile.nil?
15
+ # TODO: remove other profiles for the same app?
16
+ p = ProvisioningProfile.new(@profile)
17
+
18
+ ProvisioningProfile.installed_profiles.each do |installed|
19
+ if installed.identifiers==p.identifiers and installed.uuid==p.uuid
20
+ installed.uninstall
21
+ end
22
+ end
23
+
24
+ p.install
25
+ end
26
+
27
+ def build
28
+ install_profile
29
+
30
+ cmd = []
31
+ cmd << "xcodebuild"
32
+ cmd << "-sdk #{@target.project.sdk}" unless @target.project.sdk.nil?
33
+ cmd << "-project \"#{@target.project.path}\""
34
+ cmd << "-target \"#{@target.name}\""
35
+ cmd << "-configuration \"#{@config.name}\""
36
+ Xcode::Shell.execute(cmd)
37
+ end
38
+
39
+ def clean
40
+ cmd = []
41
+ cmd << "xcodebuild"
42
+ cmd << "-project \"#{@target.project.path}\""
43
+ cmd << "-target \"#{@target.name}\""
44
+ cmd << "-configuration \"#{@config.name}\""
45
+ cmd << "clean"
46
+ Xcode::Shell.execute(cmd)
47
+
48
+ # FIXME: Totally not safe
49
+ # cmd = []
50
+ # cmd << "rm -Rf #{build_path}"
51
+ # Xcode::Shell.execute(cmd)
52
+ end
53
+
54
+ def sign
55
+ cmd = []
56
+ cmd << "codesign"
57
+ cmd << "--force"
58
+ cmd << "--sign \"#{@identity}\""
59
+ cmd << "--resource-rules=\"#{app_path}/ResourceRules.plist\""
60
+ cmd << "--entitlements \"#{entitlements_path}\""
61
+ cmd << "\"#{ipa_path}\""
62
+ Xcode::Shell.execute(cmd)
63
+ end
64
+
65
+ def package
66
+ #package IPA
67
+ cmd = []
68
+ cmd << "xcrun"
69
+ cmd << "-sdk #{@target.project.sdk.nil? ? "iphoneos" : @target.project.sdk}"
70
+ cmd << "PackageApplication"
71
+ cmd << "-v \"#{app_path}\""
72
+ cmd << "-o \"#{ipa_path}\""
73
+
74
+ unless @identity.nil?
75
+ cmd << "--sign \"#{@identity}\""
76
+ end
77
+
78
+ unless @profile.nil?
79
+ cmd << "--embed \"#{@profile}\""
80
+ end
81
+
82
+ Xcode::Shell.execute(cmd)
83
+
84
+ # package dSYM
85
+ cmd = []
86
+ cmd << "zip"
87
+ cmd << "-r"
88
+ cmd << "-T"
89
+ cmd << "-y #{dsym_zip_path}"
90
+ cmd << "#{dsym_path}"
91
+ Xcode::Shell.execute(cmd)
92
+ end
93
+
94
+ def build_path
95
+ "#{File.dirname(@target.project.path)}/build/"
96
+ end
97
+
98
+ def configuration_build_path
99
+ "#{build_path}/#{@config.name}-#{@target.project.sdk}"
100
+ end
101
+
102
+ def entitlements_path
103
+ "#{build_path}/#{@target.name}.build/#{name}-#{@target.project.sdk}/#{@target.name}.build/#{@config.product_name}.xcent"
104
+ end
105
+
106
+ def app_path
107
+ "#{configuration_build_path}/#{@config.product_name}.app"
108
+ end
109
+
110
+ def product_version_basename
111
+ version = @config.info_plist.version
112
+ version = "SNAPSHOT" if version.nil? or version==""
113
+ "#{configuration_build_path}/#{@config.product_name}-#{@config.name}-#{version}"
114
+ end
115
+
116
+ def ipa_path
117
+ "#{product_version_basename}.ipa"
118
+ end
119
+
120
+ def dsym_path
121
+ "#{app_path}.dSYM"
122
+ end
123
+
124
+ def dsym_zip_path
125
+ "#{product_version_basename}.dSYM.zip"
126
+ end
127
+
128
+ end
129
+ end
@@ -1,4 +1,4 @@
1
- require 'xcode/shell'
1
+ require 'xcode/builder'
2
2
 
3
3
  module Xcode
4
4
  class Configuration
@@ -43,86 +43,8 @@ module Xcode
43
43
  info
44
44
  end
45
45
 
46
- def build
47
- cmd = []
48
- cmd << "xcodebuild"
49
- cmd << "-sdk #{@target.project.sdk}" unless @target.project.sdk.nil?
50
- cmd << "-project \"#{@target.project.path}\""
51
- cmd << "-target \"#{@target.name}\""
52
- cmd << "-configuration \"#{name}\""
53
- Xcode::Shell.execute(cmd)
46
+ def builder
47
+ Xcode::Builder.new(self)
54
48
  end
55
-
56
- def clean
57
- cmd = []
58
- cmd << "xcodebuild"
59
- # cmd << "-sdk #{@target.project.sdk}" unless @target.project.sdk.nil?
60
- cmd << "-project \"#{@target.project.path}\""
61
- cmd << "-target \"#{@target.name}\""
62
- cmd << "-configuration \"#{name}\""
63
- cmd << "clean"
64
- Xcode::Shell.execute(cmd)
65
- end
66
-
67
- def sign(identity)
68
- cmd = []
69
- cmd << "codesign"
70
- cmd << "--force"
71
- cmd << "--sign \"#{identity}\""
72
- cmd << "--resource-rules=\"#{app_path}/ResourceRules.plist\""
73
- cmd << "--entitlements \"#{entitlements_path}\""
74
- cmd << "\"#{ipa_path}\""
75
- Xcode::Shell.execute(cmd)
76
- end
77
-
78
- def entitlements_path
79
- "#{File.dirname(@target.project.path)}/build/#{@target.name}.build/#{name}-#{@target.project.sdk}/#{@target.name}.build/#{product_name}.xcent"
80
- end
81
-
82
- def app_path
83
- "#{File.dirname(@target.project.path)}/build/#{name}-#{@target.project.sdk}/#{product_name}.app"
84
- end
85
-
86
- def ipa_path
87
- "#{File.dirname(@target.project.path)}/build/#{name}-#{@target.project.sdk}/#{product_name}-#{name}-#{info_plist.version}.ipa"
88
- end
89
-
90
- def package(options={})
91
- cmd = []
92
- cmd << "xcrun"
93
- cmd << "-sdk #{@target.project.sdk.nil? ? "iphoneos" : @target.project.sdk}"
94
- cmd << "PackageApplication"
95
- cmd << "-v \"#{app_path}\""
96
- cmd << "-o \"#{ipa_path}\""
97
-
98
- if options.has_key? :sign
99
- cmd << "--sign \"#{options[:sign]}\""
100
- end
101
-
102
- if options.has_key? :profile
103
- cmd << "--embed \"#{options[:profile]}\""
104
- end
105
-
106
- Xcode::Shell.execute(cmd)
107
- end
108
-
109
- private
110
-
111
- def execute(bits, show_output=true)
112
- out = []
113
- cmd = bits.join(' ')
114
- puts "EXECUTE: #{cmd}"
115
- IO.popen (cmd) do |f|
116
- f.each do |line|
117
- puts line if show_output
118
- out << line
119
- end
120
- end
121
- #Process.wait
122
- raise "Error (#{$?.exitstatus}) executing '#{cmd}'\n\n #{out.join(" ")}" if $?.exitstatus>0
123
- #puts "RETURN: #{out.inspect}"
124
- out
125
- end
126
-
127
49
  end
128
50
  end
data/lib/xcode/project.rb CHANGED
@@ -4,11 +4,12 @@ require 'xcode/configuration'
4
4
 
5
5
  module Xcode
6
6
  class Project
7
- attr_reader :targets, :sdk, :path
7
+ attr_reader :name, :targets, :sdk, :path
8
8
  def initialize(path, sdk=nil)
9
9
  @sdk = sdk || "iphoneos" # FIXME: should support OSX/simulator too
10
10
  @path = File.expand_path path
11
11
  @targets = {}
12
+ @name = File.basename(@path).gsub(/\.xcodeproj/,'')
12
13
 
13
14
  parse_pbxproj
14
15
  # parse_configurations
@@ -27,6 +28,7 @@ module Xcode
27
28
  json = JSON.parse(`plutil -convert json -o - "#{@path}/project.pbxproj"`)
28
29
 
29
30
  root = json['objects'][json['rootObject']]
31
+
30
32
  root['targets'].each do |target_id|
31
33
  target = Xcode::Target.new(self, json['objects'][target_id])
32
34
 
@@ -0,0 +1,50 @@
1
+ module Xcode
2
+ class ProvisioningProfile
3
+ attr_reader :path, :name, :uuid, :identifiers
4
+ def initialize(path)
5
+ @path = path
6
+ @identifiers = []
7
+
8
+ # TODO: im sure this could be done in a nicer way. maybe read out the XML-like stuff and use the plist -> json converter
9
+ uuid = nil
10
+ File.open(path, "rb") do |f|
11
+ input = f.read
12
+ input=~/<key>UUID<\/key>.*?<string>(.*?)<\/string>/im
13
+ @uuid = $1.strip
14
+
15
+ input=~/<key>Name<\/key>.*?<string>(.*?)<\/string>/im
16
+ @name = $1.strip
17
+
18
+ input=~/<key>ApplicationIdentifierPrefix<\/key>.*?<array>(.*?)<\/array>/im
19
+ $1.split(/<string>/).each do |id|
20
+ next if id.nil? or id.strip==""
21
+ @identifiers << id.gsub(/<\/string>/,'').strip
22
+ end
23
+ end
24
+
25
+ end
26
+
27
+ def self.profiles_path
28
+ File.expand_path "~/Library/MobileDevice/Provisioning\\ Profiles/"
29
+ end
30
+
31
+ def install_path
32
+ "#{ProvisioningProfile.profiles_path}/#{self.uuid}.mobileprovision"
33
+ end
34
+
35
+ def install
36
+ Xcode::Shell.execute("cp #{self.path} #{self.install_path}")
37
+ end
38
+
39
+ def uninstall
40
+ Xcode::Shell.execute("rm -f #{self.install_path}")
41
+ end
42
+
43
+ def self.installed_profiles
44
+ Dir["#{self.profiles_path}/*.mobileprovision"].map do |file|
45
+ ProvisioningProfile.new(file)
46
+ end
47
+ end
48
+
49
+ end
50
+ end
data/lib/xcode/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Xcode
2
- VERSION = "0.0.7"
2
+ VERSION = "0.0.8"
3
3
  end
data/lib/xcoder.rb CHANGED
@@ -10,13 +10,16 @@ module Xcode
10
10
  @@projects = nil
11
11
  @@sdks = nil
12
12
 
13
- # def self.project(name)
14
- # parse_projects if @@projects.nil?
15
- # @@projects.each do |p|
16
- # return p if p.name == name
17
- # end
18
- # raise "Unable to find project named #{name}"
19
- # end
13
+ def self.project(name)
14
+ name = name.to_s
15
+ if @@projects.nil?
16
+ @@projects = parse_projects
17
+ end
18
+ @@projects.each do |p|
19
+ return p if p.name == name
20
+ end
21
+ raise "Unable to find project named #{name}. However, I did find these projects: #{@@projects.map {|p| p.name}.join(', ') }"
22
+ end
20
23
 
21
24
  def self.import_certificate(cert, password, keychain="~/Library/Keychains/login.keychain")
22
25
  cmd = []
@@ -28,19 +31,6 @@ module Xcode
28
31
  Xcode::Shell.execute(cmd)
29
32
  end
30
33
 
31
- def self.import_provisioning_profile(profile)
32
- uuid = nil
33
- File.open(profile, "rb") do |f|
34
- input = f.read
35
- input=~/<key>UUID<\/key>.*<string>(.*)<\/string>/im
36
- uuid = $1.strip
37
- end
38
-
39
- puts "Importing profile #{profile} with UUID #{uuid}"
40
-
41
- Xcode::Shell.execute("cp #{profile} ~/Library/MobileDevice/Provisioning\\ Profiles/#{uuid}.mobileprovision")
42
- end
43
-
44
34
  def self.find_projects(dir='.')
45
35
  parse_projects(dir)
46
36
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xcoder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-10-27 00:00:00.000000000Z
12
+ date: 2011-11-08 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: json
16
- requirement: &70290395384320 !ruby/object:Gem::Requirement
16
+ requirement: &70359983645620 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70290395384320
24
+ version_requirements: *70359983645620
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: plist
27
- requirement: &70290395383900 !ruby/object:Gem::Requirement
27
+ requirement: &70359983645200 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,7 +32,7 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70290395383900
35
+ version_requirements: *70359983645200
36
36
  description: Provides a ruby based object-model for parsing project structures and
37
37
  invoking builds
38
38
  email:
@@ -46,9 +46,11 @@ files:
46
46
  - Gemfile
47
47
  - README.md
48
48
  - Rakefile
49
+ - lib/xcode/builder.rb
49
50
  - lib/xcode/configuration.rb
50
51
  - lib/xcode/info_plist.rb
51
52
  - lib/xcode/project.rb
53
+ - lib/xcode/provisioning_profile.rb
52
54
  - lib/xcode/shell.rb
53
55
  - lib/xcode/target.rb
54
56
  - lib/xcode/version.rb