xcoder 0.1.13 → 0.1.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -48,7 +48,7 @@ module Xcode
48
48
  # identifier; false if it is not.
49
49
  #
50
50
  def self.is_identifier? value
51
- value =~ /^[0-9A-F]{24,}$/
51
+ value =~ /^[0-9a-fA-F]{24,}$/
52
52
  end
53
53
 
54
54
  #
data/lib/xcode/scheme.rb CHANGED
@@ -1,60 +1,107 @@
1
1
  require 'nokogiri'
2
2
 
3
3
  module Xcode
4
-
4
+
5
5
  # Schemes are an XML file that describe build, test, launch and profile actions
6
6
  # For the purposes of Xcoder, we want to be able to build and test
7
- # The scheme's build action only describes a target, so we need to look at launch for the config
8
7
  class Scheme
9
- attr_reader :path, :name, :launch, :test
10
- def initialize(path)
11
- @path = File.expand_path(path)
12
- @root = File.expand_path "#{@path}/../../../../"
13
- @name = File.basename(path).gsub(/\.xcscheme$/,'')
14
- doc = Nokogiri::XML(open(@path))
15
-
16
- @launch = parse_action(doc, 'launch')
17
- @test = parse_action(doc, 'test')
8
+ attr_reader :parent, :path, :name, :build_config, :build_targets
9
+
10
+ #
11
+ # Parse all the schemes given the current project.
12
+ #
13
+ def self.find_in_project(project)
14
+ find_in_path(project, project.path)
18
15
  end
19
-
20
- # def project
21
- # launch.target.project
22
- # end
23
-
24
- def builder
25
- Xcode::Builder.new(self)
16
+
17
+ #
18
+ # Parse all the schemes given the current workspace.
19
+ #
20
+ def self.find_in_workspace(workspace)
21
+ schemes = find_in_path(workspace, workspace.path)
22
+
23
+ # Project level schemes
24
+ workspace.projects.each do |project|
25
+ schemes+=project.schemes
26
+ end
27
+
28
+ schemes
26
29
  end
27
30
 
28
- #
29
- # Parse all the scheme files that can be found in the given project or workspace. Schemes
31
+ # Parse all the scheme files that can be found at the given path. Schemes
30
32
  # can be defined as `shared` schemes and then `user` specific schemes. Parsing
31
33
  # the schemes will load the shared ones and then the current acting user's
32
34
  # schemes.
35
+ #
33
36
  #
37
+ # @param project or workspace in which the scheme is contained
34
38
  # @return [Array<Scheme>] the shared schemes and user specific schemes found
35
- # within the projet/workspace at the path defined for schemes.
39
+ # within the project/workspace at the path defined for schemes.
36
40
  #
37
- def self.find_in_path(path)
38
- shared_schemes = Dir["#{path}/xcshareddata/xcschemes/*.xcscheme"]
39
- user_specific_schemes = Dir["#{path}/xcuserdata/#{ENV['USER']}.xcuserdatad/xcschemes/*.xcscheme"]
40
-
41
- (shared_schemes + user_specific_schemes).map do |scheme|
42
- Xcode::Scheme.new(scheme)
41
+ def self.find_in_path(parent, path)
42
+ all_schemes_paths(path).map do |scheme_path|
43
+ Xcode::Scheme.new(parent: parent, root: path, path: scheme_path)
43
44
  end
44
45
  end
45
46
 
46
- private
47
-
48
- def parse_action(doc, action_name)
49
- action = doc.xpath("//#{action_name.capitalize}Action").first
50
- buildableReference = action.xpath('BuildableProductRunnable/BuildableReference').first
51
- return nil if buildableReference.nil?
47
+ def initialize(params={})
48
+ @parent = params[:parent]
49
+ @path = File.expand_path params[:path]
50
+ @root = File.expand_path(File.join(params[:root],'..'))
51
+ @name = File.basename(path).gsub(/\.xcscheme$/,'')
52
+ doc = Nokogiri::XML(open(@path))
52
53
 
54
+ parse_build_actions(doc)
55
+ end
56
+
57
+ # Returns a builder for building this scheme
58
+ def builder
59
+ Xcode::Builder::SchemeBuilder.new(self)
60
+ end
61
+
62
+ private
63
+
64
+ #
65
+ # @return an array of all the scheme filepaths found within the project
66
+ # or workspace path provided.
67
+ #
68
+ def self.all_schemes_paths(path)
69
+ shared_schemes_paths(path) + current_user_schemes_paths(path)
70
+ end
71
+
72
+ #
73
+ # @return an array of all the shared scheme filespaths found within the
74
+ # project or workspace path provided.
75
+ #
76
+ def self.shared_schemes_paths(root)
77
+ Dir["#{root}/xcshareddata/xcschemes/*.xcscheme"]
78
+ end
79
+
80
+ #
81
+ # @return an array of all the current user's scheme filespaths found within the
82
+ # project or workspace path provided.
83
+ #
84
+ def self.current_user_schemes_paths(root)
85
+ Dir["#{root}/xcuserdata/#{ENV['USER']}.xcuserdatad/xcschemes/*.xcscheme"]
86
+ end
87
+
88
+ def target_from_build_reference(buildableReference)
53
89
  project_name = buildableReference['ReferencedContainer'].gsub(/^container:/,'')
54
- project = Xcode.project "#{@root}/#{project_name}"
55
90
  target_name = buildableReference['BlueprintName']
91
+ project_path = File.join @root, project_name
92
+ project = Xcode.project project_path
93
+ project.target(target_name)
94
+ end
95
+
96
+ def parse_build_actions(doc)
97
+ # Build Config
98
+ @build_targets = []
56
99
 
57
- project.target(target_name).config(action['buildConfiguration'])
100
+ @build_config = doc.xpath("//LaunchAction").first['buildConfiguration']
101
+
102
+ build_action_entries = doc.xpath("//BuildAction//BuildableReference").each do |ref|
103
+ @build_targets << target_from_build_reference(ref)
104
+ end
58
105
  end
59
106
 
60
107
  end
data/lib/xcode/shell.rb CHANGED
@@ -1,3 +1,5 @@
1
+ require 'xcode/shell/command.rb'
2
+
1
3
  module Xcode
2
4
  module Shell
3
5
 
@@ -5,7 +7,7 @@ module Xcode
5
7
 
6
8
  def self.execute(bits, show_output=true)
7
9
  out = []
8
- cmd = bits.is_a?(Array) ? bits.join(' ') : bits
10
+ cmd = bits.is_a?(Xcode::Shell::Command) ? bits.to_s : bits
9
11
 
10
12
  puts "EXECUTE: #{cmd}"
11
13
  IO.popen (cmd) do |f|
@@ -0,0 +1,42 @@
1
+ require 'set'
2
+
3
+ module Xcode
4
+ module Shell
5
+ class Command
6
+ attr_accessor :env
7
+
8
+ def initialize(cmd, environment={})
9
+ @cmd = cmd
10
+ @args = []
11
+ @env = environment
12
+ end
13
+
14
+ def <<(arg)
15
+ @args << arg
16
+ end
17
+
18
+ def to_s
19
+ "#{to_a.join(' ')}"
20
+ end
21
+
22
+ def to_a
23
+ out = []
24
+ out << @cmd
25
+ out+=@args
26
+ out+=(@env.map {|k,v| "#{k}=#{v}"})
27
+ out
28
+ end
29
+
30
+ def ==(obj)
31
+ return false unless obj.is_a? Xcode::Shell::Command
32
+ # to_s==obj.to_s
33
+ Set.new(obj.to_a) == Set.new(self.to_a)
34
+ end
35
+
36
+ def execute(show_output=true, &block) #:yield: output
37
+ Xcode::Shell.execute(self, show_output, &block)
38
+ end
39
+
40
+ end
41
+ end
42
+ end
data/lib/xcode/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Xcode
2
- VERSION = "0.1.13"
2
+ VERSION = "0.1.14"
3
3
  end
@@ -27,7 +27,8 @@ module Xcode
27
27
  #
28
28
  def schemes
29
29
  return @schemes unless @schemes.nil?
30
- @schemes = Xcode::Scheme.find_in_path @path
30
+ @schemes = Xcode::Scheme.find_in_workspace(self)
31
+ @schemes
31
32
  end
32
33
 
33
34
  #
data/spec/builder_spec.rb CHANGED
@@ -10,25 +10,35 @@ describe Xcode::Builder do
10
10
 
11
11
  describe "#build" do
12
12
 
13
- let(:default_build_parameters) do
14
- [ "xcodebuild",
15
- "-sdk #{configuration.target.project.sdk}",
16
- "-project \"#{configuration.target.project.path}\"",
17
- "-target \"#{configuration.target.name}\"",
18
- "-configuration \"#{configuration.name}\"",
19
- "OBJROOT=\"#{File.dirname(configuration.target.project.path)}/build/\"",
20
- "SYMROOT=\"#{File.dirname(configuration.target.project.path)}/build/\"" ]
13
+ let(:default_build_parameters) do
14
+ cmd = Xcode::Shell::Command.new "xcodebuild"
15
+ cmd << "-project \"#{configuration.target.project.path}\""
16
+ cmd << "-target \"#{configuration.target.name}\""
17
+ cmd << "-config \"#{configuration.name}\""
18
+ cmd << "-sdk #{configuration.target.project.sdk}"
19
+ cmd.env["OBJROOT"]="\"#{File.dirname(configuration.target.project.path)}/build/\""
20
+ cmd.env["SYMROOT"]="\"#{File.dirname(configuration.target.project.path)}/build/\""
21
+ cmd
22
+ end
23
+
24
+ let(:macosx_build_parameters) do
25
+ cmd = Xcode::Shell::Command.new "xcodebuild"
26
+ cmd << "-project \"#{configuration.target.project.path}\""
27
+ cmd << "-target \"#{configuration.target.name}\""
28
+ cmd << "-config \"#{configuration.name}\""
29
+ cmd << "-sdk macosx10.7"
30
+ cmd.env["OBJROOT"]="\"#{File.dirname(configuration.target.project.path)}/build/\""
31
+ cmd.env["SYMROOT"]="\"#{File.dirname(configuration.target.project.path)}/build/\""
32
+ cmd
21
33
  end
22
34
 
23
35
  it "should build the project with the default parameters" do
24
- Xcode::Shell.should_receive(:execute).with(default_build_parameters)
36
+ Xcode::Shell.should_receive(:execute).with(default_build_parameters,true)
25
37
  subject.build
26
38
  end
27
39
 
28
40
  it "should allow the override of the sdk" do
29
- expected = default_build_parameters
30
- expected[1] = '-sdk macosx10.7'
31
- Xcode::Shell.should_receive(:execute).with(expected)
41
+ Xcode::Shell.should_receive(:execute).with(macosx_build_parameters, true)
32
42
  subject.build :sdk => 'macosx10.7'
33
43
  end
34
44
 
@@ -70,27 +80,27 @@ describe Xcode::Builder do
70
80
  end
71
81
 
72
82
  let(:iphonesimulator_test_parameters) do
73
- [ "xcodebuild",
74
- "-sdk iphonesimulator",
75
- "-project \"#{configuration.target.project.path}\"",
76
- "-target \"#{configuration.target.name}\"",
77
- "-configuration \"#{configuration.name}\"",
78
- "OBJROOT=\"#{File.dirname(configuration.target.project.path)}/build/\"",
79
- "SYMROOT=\"#{File.dirname(configuration.target.project.path)}/build/\"",
80
- "TEST_AFTER_BUILD=YES"
81
- ]
83
+ cmd = Xcode::Shell::Command.new "xcodebuild"
84
+ cmd << "-project \"#{configuration.target.project.path}\""
85
+ cmd << "-target \"#{configuration.target.name}\""
86
+ cmd << "-config \"#{configuration.name}\""
87
+ cmd << "-sdk iphonesimulator"
88
+ cmd.env["OBJROOT"]="\"#{File.dirname(configuration.target.project.path)}/build/\""
89
+ cmd.env["SYMROOT"]="\"#{File.dirname(configuration.target.project.path)}/build/\""
90
+ cmd.env["TEST_AFTER_BUILD"]="YES"
91
+ cmd
82
92
  end
83
93
 
84
94
  let(:macosx_test_parameters) do
85
- [ "xcodebuild",
86
- "-sdk macosx10.7",
87
- "-project \"#{configuration.target.project.path}\"",
88
- "-target \"#{configuration.target.name}\"",
89
- "-configuration \"#{configuration.name}\"",
90
- "OBJROOT=\"#{File.dirname(configuration.target.project.path)}/build/\"",
91
- "SYMROOT=\"#{File.dirname(configuration.target.project.path)}/build/\"",
92
- "TEST_AFTER_BUILD=YES",
93
- ]
95
+ cmd = Xcode::Shell::Command.new "xcodebuild"
96
+ cmd << "-project \"#{configuration.target.project.path}\""
97
+ cmd << "-target \"#{configuration.target.name}\""
98
+ cmd << "-config \"#{configuration.name}\""
99
+ cmd << "-sdk macosx10.7"
100
+ cmd.env["OBJROOT"]="\"#{File.dirname(configuration.target.project.path)}/build/\""
101
+ cmd.env["SYMROOT"]="\"#{File.dirname(configuration.target.project.path)}/build/\""
102
+ cmd.env["TEST_AFTER_BUILD"]="YES"
103
+ cmd
94
104
  end
95
105
 
96
106
 
@@ -99,15 +109,8 @@ describe Xcode::Builder do
99
109
  subject.test :sdk => 'iphonesimulator'
100
110
  end
101
111
 
102
- it "should be able to run the test target on macosx10.7" do
103
- Xcode::Shell.should_receive(:execute).with(macosx_test_parameters, false)
104
- subject.test :sdk => 'macosx10.7'
105
- end
106
-
107
112
  it "should allow the override of the sdk" do
108
- expected = macosx_test_parameters
109
- expected[1] = '-sdk macosx10.7'
110
- Xcode::Shell.should_receive(:execute).with(expected, false)
113
+ Xcode::Shell.should_receive(:execute).with(macosx_test_parameters, false)
111
114
  subject.test :sdk => 'macosx10.7'
112
115
  end
113
116
 
@@ -125,19 +128,20 @@ describe Xcode::Builder do
125
128
  describe "#clean" do
126
129
 
127
130
  let(:default_clean_parameters) do
128
- [ "xcodebuild",
129
- "-project \"#{configuration.target.project.path}\"",
130
- "-sdk iphoneos",
131
- "-target \"#{configuration.target.name}\"",
132
- "-configuration \"#{configuration.name}\"",
133
- "OBJROOT=\"#{File.dirname(configuration.target.project.path)}/build/\"",
134
- "SYMROOT=\"#{File.dirname(configuration.target.project.path)}/build/\"",
135
- "clean" ]
131
+ cmd = Xcode::Shell::Command.new "xcodebuild"
132
+ cmd << "-project \"#{configuration.target.project.path}\""
133
+ cmd << "-target \"#{configuration.target.name}\""
134
+ cmd << "-config \"#{configuration.name}\""
135
+ cmd << "-sdk iphoneos"
136
+ cmd << "clean"
137
+ cmd.env["OBJROOT"]="\"#{File.dirname(configuration.target.project.path)}/build/\""
138
+ cmd.env["SYMROOT"]="\"#{File.dirname(configuration.target.project.path)}/build/\""
139
+ cmd
136
140
  end
137
141
 
138
142
 
139
143
  it "should clean the project with the default parameter" do
140
- Xcode::Shell.should_receive(:execute).with(default_clean_parameters)
144
+ Xcode::Shell.should_receive(:execute).with(default_clean_parameters, true)
141
145
  subject.clean
142
146
  end
143
147
 
@@ -154,16 +158,17 @@ describe Xcode::Builder do
154
158
  describe "#build" do
155
159
 
156
160
  let(:default_build_parameters) do
157
- [ "xcodebuild",
158
- "-sdk iphoneos",
159
- "-project \"#{scheme.launch.target.project.path}\"",
160
- "-scheme \"#{scheme.name}\"",
161
- "OBJROOT=\"#{File.dirname(scheme.launch.target.project.path)}/build/\"",
162
- "SYMROOT=\"#{File.dirname(scheme.launch.target.project.path)}/build/\"" ]
161
+ cmd = Xcode::Shell::Command.new "xcodebuild"
162
+ cmd << "-project \"#{scheme.build_targets.last.project.path}\""
163
+ cmd << "-scheme \"#{scheme.name}\""
164
+ cmd << "-sdk iphoneos"
165
+ cmd.env["OBJROOT"]="\"#{File.dirname(scheme.build_targets.last.project.path)}/build/\""
166
+ cmd.env["SYMROOT"]="\"#{File.dirname(scheme.build_targets.last.project.path)}/build/\""
167
+ cmd
163
168
  end
164
169
 
165
170
  it "should build the project with the default parameters" do
166
- Xcode::Shell.should_receive(:execute).with(default_build_parameters)
171
+ Xcode::Shell.should_receive(:execute).with(default_build_parameters, true)
167
172
  subject.build
168
173
  end
169
174
 
@@ -172,18 +177,19 @@ describe Xcode::Builder do
172
177
  describe "#clean" do
173
178
 
174
179
  let(:default_clean_parameters) do
175
- [ "xcodebuild",
176
- "-project \"#{scheme.launch.target.project.path}\"",
177
- "-sdk iphoneos",
178
- "-scheme \"#{scheme.name}\"",
179
- "OBJROOT=\"#{File.dirname(scheme.launch.target.project.path)}/build/\"",
180
- "SYMROOT=\"#{File.dirname(scheme.launch.target.project.path)}/build/\"",
181
- "clean" ]
180
+ cmd = Xcode::Shell::Command.new "xcodebuild"
181
+ cmd << "-project \"#{scheme.build_targets.last.project.path}\""
182
+ cmd << "-scheme \"#{scheme.name}\""
183
+ cmd << "-sdk iphoneos"
184
+ cmd << "clean"
185
+ cmd.env["OBJROOT"]="\"#{File.dirname(scheme.build_targets.last.project.path)}/build/\""
186
+ cmd.env["SYMROOT"]="\"#{File.dirname(scheme.build_targets.last.project.path)}/build/\""
187
+ cmd
182
188
  end
183
189
 
184
190
 
185
191
  it "should clean the project with the default parameter" do
186
- Xcode::Shell.should_receive(:execute).with(default_clean_parameters)
192
+ Xcode::Shell.should_receive(:execute).with(default_clean_parameters, true)
187
193
  subject.clean
188
194
  end
189
195
 
@@ -0,0 +1,51 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe Xcode::Registry do
4
+
5
+ def self.is_identifier? value
6
+ value =~ /^[0-9A-F]{24,}$/
7
+ end
8
+
9
+ describe "ClassMethods" do
10
+ subject { described_class }
11
+
12
+ describe "#is_identifier?" do
13
+ context "when the value is valid hexadecimal 24 character length string" do
14
+ context "when it is all uppercase" do
15
+ let(:input) { "0123456789ABCDEF01234567" }
16
+
17
+ it "should be an identifier" do
18
+ subject.is_identifier?(input).should be_true
19
+ end
20
+ end
21
+
22
+ context "when it uses lowercase characters" do
23
+ let(:input) { "0123456789abcdef01234567" }
24
+
25
+ it "should be an identifier" do
26
+ subject.is_identifier?(input).should be_true
27
+ end
28
+ end
29
+ end
30
+
31
+ context "when the value is less than 24 characters" do
32
+ let(:input) { "0123456789ABCDEF" }
33
+
34
+ it "should not be an identifier" do
35
+ subject.is_identifier?(input).should be_false
36
+ end
37
+ end
38
+
39
+ context "when it contains other than hexadecimal characters" do
40
+ let(:input) { "0123456789ABCDEFGHIJKLMNO" }
41
+
42
+ it "should not be an identifier" do
43
+ subject.is_identifier?(input).should be_false
44
+ end
45
+ end
46
+
47
+ end
48
+ end
49
+
50
+
51
+ end