xcoder 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/spec/TestProject/TestProject.xcodeproj/project.pbxproj +801 -433
  2. data/spec/build_phase_spec.rb +1 -1
  3. data/spec/builder_spec.rb +54 -32
  4. data/spec/configuration_list_spec.rb +38 -0
  5. data/spec/configuration_spec.rb +5 -6
  6. data/spec/group_spec.rb +43 -32
  7. data/spec/integration/builder_spec.rb +60 -0
  8. data/spec/integration/cedar_install_spec.rb +107 -0
  9. data/spec/integration/pull_to_refresh_install_spec.rb +36 -0
  10. data/spec/integration/reachability_install_spec.rb +43 -0
  11. data/spec/keychain_spec.rb +2 -2
  12. data/spec/project_spec.rb +55 -6
  13. data/spec/scheme_spec.rb +1 -2
  14. data/spec/spec_helper.rb +2 -1
  15. data/spec/target_spec.rb +93 -3
  16. data/spec/test_report_spec.rb +2 -2
  17. data/spec/workspace_spec.rb +1 -2
  18. metadata +25 -48
  19. data/.gitignore +0 -7
  20. data/.rvmrc +0 -4
  21. data/Gemfile +0 -11
  22. data/Guardfile +0 -13
  23. data/README.md +0 -125
  24. data/Rakefile +0 -16
  25. data/lib/xcode/build_file.rb +0 -22
  26. data/lib/xcode/build_phase.rb +0 -46
  27. data/lib/xcode/builder.rb +0 -182
  28. data/lib/xcode/buildfile.rb +0 -101
  29. data/lib/xcode/configuration.rb +0 -129
  30. data/lib/xcode/core_ext/array.rb +0 -23
  31. data/lib/xcode/core_ext/boolean.rb +0 -21
  32. data/lib/xcode/core_ext/fixnum.rb +0 -5
  33. data/lib/xcode/core_ext/hash.rb +0 -27
  34. data/lib/xcode/core_ext/string.rb +0 -11
  35. data/lib/xcode/file_reference.rb +0 -29
  36. data/lib/xcode/group.rb +0 -118
  37. data/lib/xcode/info_plist.rb +0 -41
  38. data/lib/xcode/keychain.rb +0 -77
  39. data/lib/xcode/parsers/plutil_project_parser.rb +0 -20
  40. data/lib/xcode/project.rb +0 -190
  41. data/lib/xcode/provisioning_profile.rb +0 -53
  42. data/lib/xcode/registry.rb +0 -120
  43. data/lib/xcode/resource.rb +0 -187
  44. data/lib/xcode/scheme.rb +0 -36
  45. data/lib/xcode/shell.rb +0 -21
  46. data/lib/xcode/target.rb +0 -94
  47. data/lib/xcode/test/report_parser.rb +0 -172
  48. data/lib/xcode/testflight.rb +0 -56
  49. data/lib/xcode/variant_group.rb +0 -8
  50. data/lib/xcode/version.rb +0 -3
  51. data/lib/xcode/workspace.rb +0 -40
  52. data/lib/xcoder.rb +0 -105
  53. data/xcoder.gemspec +0 -26
data/lib/xcode/scheme.rb DELETED
@@ -1,36 +0,0 @@
1
- require 'nokogiri'
2
-
3
- module Xcode
4
-
5
- # Schemes are an XML file that describe build, test, launch and profile actions
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
- class Scheme
9
- attr_reader :project, :path, :name, :launch, :test
10
- def initialize(project, path)
11
- @project = project
12
- @path = 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')
18
- end
19
-
20
- def builder
21
- Xcode::Builder.new(self)
22
- end
23
-
24
- private
25
-
26
- def parse_action(doc, action_name)
27
- action = doc.xpath("//#{action_name.capitalize}Action").first
28
- buildableReference = action.xpath('BuildableProductRunnable/BuildableReference').first
29
- return nil if buildableReference.nil?
30
-
31
- target_name = buildableReference['BlueprintName']
32
- @project.target(target_name).config(action['buildConfiguration'])
33
- end
34
-
35
- end
36
- end
data/lib/xcode/shell.rb DELETED
@@ -1,21 +0,0 @@
1
- module Xcode
2
- module Shell
3
- def self.execute(bits, show_output=true)
4
- out = []
5
- cmd = bits.is_a?(Array) ? bits.join(' ') : bits
6
-
7
- puts "EXECUTE: #{cmd}"
8
- IO.popen (cmd) do |f|
9
- f.each do |line|
10
- puts line if show_output
11
- yield(line) if block_given?
12
- out << line
13
- end
14
- end
15
- #Process.wait
16
- raise "Error (#{$?.exitstatus}) executing '#{cmd}'\n\n #{out.join(" ")}" if $?.exitstatus>0
17
- #puts "RETURN: #{out.inspect}"
18
- out
19
- end
20
- end
21
- end
data/lib/xcode/target.rb DELETED
@@ -1,94 +0,0 @@
1
- require_relative 'build_file'
2
-
3
- module Xcode
4
-
5
- #
6
- # Within a project a user may define a number of targets. These targets may
7
- # be to generate the application, generate a universal framework, or execute
8
- # tests.
9
- #
10
- #
11
- # @example Target as Hash
12
- #
13
- # E21D8AA914E0F817002E56AA /* newtarget */ = {
14
- # isa = PBXNativeTarget;
15
- # buildConfigurationList = E21D8ABD14E0F817002E56AA /* Build configuration list for PBXNativeTarget "newtarget" */;
16
- # buildPhases = (
17
- # E21D8AA614E0F817002E56AA /* Sources */,
18
- # E21D8AA714E0F817002E56AA /* Frameworks */,
19
- # E21D8AA814E0F817002E56AA /* Resources */,
20
- # );
21
- # buildRules = (
22
- # );
23
- # dependencies = (
24
- # );
25
- # name = newtarget;
26
- # productName = newtarget;
27
- # productReference = E21D8AAA14E0F817002E56AA /* newtarget.app */;
28
- # productType = "com.apple.product-type.application";
29
- # };
30
- #
31
- #
32
- module Target
33
-
34
- # A reference to the project for which these targets reside.
35
- attr_accessor :project
36
-
37
- #
38
- # @return [PBXBuildConfiguration] the configurations that this target supports.
39
- # these are generally 'Debug' or 'Release' but may be custom designed
40
- # configurations.
41
- #
42
- def configs
43
- buildConfigurationList.buildConfigurations.map do |config|
44
- config.target = self
45
- config
46
- end
47
- end
48
-
49
- #
50
- # Return a specific build configuration. When one is not found to match,
51
- # an exception is raised.
52
- #
53
- # @param [String] name of a configuration to return
54
- # @return [PBXBuildConfiguration] a specific build configuration that
55
- # matches the specified name.
56
- #
57
- def config(name)
58
- config = configs.select {|config| config.name == name.to_s }.first
59
- raise "No such config #{name}, available configs are #{configs.map {|c| c.name}.join(', ')}" if config.nil?
60
- yield config if block_given?
61
- config
62
- end
63
-
64
- #
65
- # A ruby-friendly alias for the property defined at buildPhases.
66
- #
67
- def build_phases
68
- buildPhases
69
- end
70
-
71
- #
72
- # @return [BuildPhase] the framework specific build phase of the target.
73
- #
74
- def framework_build_phase
75
- build_phases.find {|phase| phase.isa == 'PBXFrameworksBuildPhase' }
76
- end
77
-
78
- #
79
- # @return [BuildPhase] the sources specific build phase of the target.
80
- #
81
- def sources_build_phase
82
- build_phases.find {|phase| phase.isa == 'PBXSourcesBuildPhase' }
83
- end
84
-
85
- #
86
- # @return [BuildPhase] the resources specific build phase of the target.
87
- #
88
- def resources_build_phase
89
- build_phases.find {|phase| phase.isa == 'PBXResourcesBuildPhase' }
90
- end
91
-
92
- end
93
-
94
- end
@@ -1,172 +0,0 @@
1
- require 'time'
2
- require 'FileUtils'
3
- require 'socket'
4
- require 'builder'
5
-
6
- module Xcode
7
- module Test
8
- module Formatters
9
- class JunitFormatter
10
- def initialize(dir)
11
- @dir = dir
12
- end
13
-
14
- def string_to_xml(s)
15
- s.gsub(/&/, '&amp;').gsub(/'/, '&quot;').gsub(/</, '&lt;')
16
- end
17
-
18
- def write(report)
19
- if report.end_time.nil?
20
- raise "Report #{report} #{report.name} has a nil end time!?"
21
- end
22
- xml = ::Builder::XmlMarkup.new( :indent => 2 )
23
- xml.instruct! :xml, :encoding => "UTF-8"
24
- xml.testsuite(:errors => report.total_error_tests,
25
- :failures => report.total_failed_tests,
26
- :hostname => Socket.gethostname,
27
- :name => report.name,
28
- :tests => report.tests.count,
29
- :time => (report.end_time - report.start_time),
30
- :timestamp => report.end_time
31
- ) do |p|
32
-
33
- report.tests.each do |t|
34
- p.testcase(:classname => report.name,
35
- :name => t.name,
36
- :time => t.time
37
- ) do |e|
38
-
39
- if t.error?
40
- e.failure t.error_location, :message => t.error_message, :type => 'Failure'
41
- end
42
- end
43
- end
44
- end
45
-
46
- File.open("#{@dir}/TEST-#{report.name}.xml", 'w') do |current_file|
47
- current_file.write xml.target!
48
- end
49
-
50
- end
51
- end
52
- end
53
-
54
- class SuiteReport
55
- attr_accessor :tests, :name, :start_time, :end_time
56
-
57
- def initialize(name, start_time)
58
- @name = name
59
- @start_time = start_time
60
- @tests = []
61
- end
62
-
63
- def finish(time)
64
- raise "Time is nil" if time.nil?
65
- @end_time = time
66
- end
67
-
68
- def total_error_tests
69
- @tests.select {|t| t.error? }.count
70
- end
71
-
72
- def total_passed_tests
73
- @tests.select {|t| t.passed? }.count
74
- end
75
-
76
- def total_failed_tests
77
- @tests.select {|t| t.failed? }.count
78
- end
79
-
80
- end
81
-
82
- class CaseReport
83
- attr_reader :name, :time, :error_message, :error_location
84
-
85
- def initialize(name)
86
- @name = name
87
- end
88
-
89
- def passed?
90
- @passed
91
- end
92
-
93
- def failed?
94
- error? or !@passed
95
- end
96
-
97
- def error?
98
- !@error_message.nil?
99
- end
100
-
101
- def passed(time)
102
- @passed = true
103
- @time = time
104
- end
105
-
106
- def failed(time)
107
- @passed = false
108
- @time = time
109
- end
110
-
111
- def error(error_message,error_location)
112
- @error_message = error_message
113
- @error_location = error_location
114
- end
115
- end
116
-
117
- class ReportParser
118
-
119
- attr_reader :exit_code, :reports
120
-
121
- def initialize
122
- @exit_code = 0
123
- @reports = []
124
- end
125
-
126
- def write(dir, format=:junit)
127
- dir = File.expand_path(dir)
128
- FileUtils.mkdir_p(dir)
129
-
130
- formatter = Formatters.const_get("#{format.to_s.capitalize}Formatter").new(dir)
131
- @reports.each do |r|
132
- formatter.write(r)
133
- end
134
- end
135
-
136
- def <<(piped_row)
137
- case piped_row
138
-
139
- when /Test Suite '(\S+)'.*started at\s+(.*)/
140
- name = $1
141
- time = Time.parse($2)
142
- @reports << SuiteReport.new(name, time) unless name=~/\// # ignore if its a file path
143
-
144
- when /Test Suite '(\S+)'.*finished at\s+(.*)./
145
- @reports.last.finish(Time.parse($2))
146
-
147
- when /Test Case '-\[\S+\s+(\S+)\]' started./
148
- test = CaseReport.new($1)
149
- @reports.last.tests << test
150
-
151
- when /Test Case '-\[\S+\s+(\S+)\]' passed \((.*) seconds\)/
152
- @reports.last.tests.last.passed($2.to_f)
153
-
154
- when /(.*): error: -\[(\S+) (\S+)\] : (.*)/
155
- @reports.last.tests.last.error(error_message,error_location)
156
- @exit_code = 1 # should terminate
157
-
158
- when /Test Case '-\[\S+ (\S+)\]' failed \((\S+) seconds\)/
159
- @reports.last.tests.last.failed($2.to_f)
160
- @exit_code = 1 # should terminate
161
-
162
- when /failed with exit code (\d+)/
163
- @exit_code = $1.to_i
164
-
165
- when
166
- /BUILD FAILED/
167
- @exit_code = -1;
168
- end
169
- end
170
- end
171
- end
172
- end
@@ -1,56 +0,0 @@
1
- require 'rest-client'
2
- require 'json'
3
-
4
- module Xcode
5
- class Testflight
6
- attr_accessor :api_token, :team_token, :notify, :proxy, :notes, :lists
7
-
8
- def initialize(api_token, team_token)
9
- @api_token = api_token
10
- @team_token = team_token
11
- @notify = true
12
- @notes = nil
13
- @lists = []
14
- @proxy = ENV['http_proxy'] || ENV['HTTP_PROXY']
15
- end
16
-
17
- def upload(ipa_path, dsymzip_path=nil)
18
- puts "Uploading to Testflight..."
19
-
20
- # RestClient.proxy = @proxy || ENV['http_proxy'] || ENV['HTTP_PROXY']
21
- # RestClient.log = '/tmp/restclient.log'
22
- #
23
- # response = RestClient.post('http://testflightapp.com/api/builds.json',
24
- # :file => File.new(ipa_path),
25
- # :dsym => File.new(dsymzip_path),
26
- # :api_token => @api_token,
27
- # :team_token => @team_token,
28
- # :notes => @notes,
29
- # :notify => @notify ? 'True' : 'False',
30
- # :distribution_lists => @lists.join(',')
31
- # )
32
- #
33
- # json = JSON.parse(response)
34
- # puts " + Done, got: #{json.inspect}"
35
- # json
36
-
37
- cmd = []
38
- cmd << 'curl'
39
- cmd << "--proxy #{@proxy}" unless @proxy.nil?
40
- cmd << "-X POST http://testflightapp.com/api/builds.json"
41
- cmd << "-F file=@\"#{ipa_path}\""
42
- cmd << "-F dsym=@\"#{dsymzip_path}\"" unless dsymzip_path.nil?
43
- cmd << "-F api_token='#{@api_token}'"
44
- cmd << "-F team_token='#{@team_token}'"
45
- cmd << "-F notes=\"#{@notes}\"" unless @notes.nil?
46
- cmd << "-F notify=#{@notify ? 'True' : 'False'}"
47
- cmd << "-F distribution_lists='#{@lists.join(',')}'" unless @lists.count==0
48
-
49
- response = Xcode::Shell.execute(cmd)
50
-
51
- json = JSON.parse(response.join(''))
52
- puts " + Done, got: #{json.inspect}"
53
- json
54
- end
55
- end
56
- end
@@ -1,8 +0,0 @@
1
- require_relative 'group'
2
-
3
- module Xcode
4
-
5
- module VariantGroup
6
- include Group ; extend Group
7
- end
8
- end
data/lib/xcode/version.rb DELETED
@@ -1,3 +0,0 @@
1
- module Xcode
2
- VERSION = "0.1.0"
3
- end
@@ -1,40 +0,0 @@
1
- require 'xcode/project'
2
-
3
- module Xcode
4
- class Workspace
5
- attr_reader :projects, :name, :path
6
- def initialize(path)
7
- path = "#{path}.xcworkspace" unless path=~/\.xcworkspace/
8
- path = "#{path}/contents.xcworkspacedata" unless path=~/xcworkspacedata$/
9
-
10
- @name = File.basename(path.gsub(/\.xcworkspace\/contents\.xcworkspacedata/,''))
11
- @projects = []
12
- @path = File.expand_path path
13
-
14
- File.open(@path).read.split(/<FileRef/).each do |line|
15
- if line=~/location\s*=\s*\"group\:(.+?)\"/
16
- project_path = "#{workspace_root}/#{$1}"
17
- @projects << Xcode::Project.new(project_path)
18
- end
19
- end
20
- end
21
-
22
- def project(name)
23
- project = @projects.select {|c| c.name == name.to_s}.first
24
- raise "No such project #{name}, available projects are #{@projects.map {|c| c.name}.join(', ')}" if project.nil?
25
- yield project if block_given?
26
- project
27
- end
28
-
29
- def describe
30
- puts "Workspace #{name} contains:"
31
- projects.each do |p|
32
- p.describe
33
- end
34
- end
35
-
36
- def workspace_root
37
- File.dirname(File.dirname(@path))
38
- end
39
- end
40
- end
data/lib/xcoder.rb DELETED
@@ -1,105 +0,0 @@
1
- require 'find'
2
- require 'fileutils'
3
- require "xcode/version"
4
- require "xcode/project"
5
- require "xcode/info_plist"
6
- require "xcode/shell"
7
- require 'plist'
8
- require 'xcode/keychain'
9
- require 'xcode/workspace'
10
- require 'xcode/buildfile'
11
-
12
- module Xcode
13
- @@projects = nil
14
- @@workspaces = nil
15
- @@sdks = nil
16
-
17
- def self.projects
18
- @@projects = parse_projects if @@projects.nil?
19
- @@projects
20
- end
21
-
22
- def self.workspaces
23
- @@workspaces = parse_workspaces if @@workspaces.nil?
24
- @@workspaces
25
- end
26
-
27
- def self.project(name)
28
- name = name.to_s
29
-
30
- return Xcode::Project.new(name) if name=~/\.xcodeproj/
31
-
32
- self.projects.each do |p|
33
- return p if p.name == name
34
- end
35
- raise "Unable to find a project named #{name}. However, I did find these projects: #{self.projects.map {|p| p.name}.join(', ') }"
36
- end
37
-
38
- def self.workspace(name)
39
- name = name.to_s
40
-
41
- return Xcode::Workspace.new(name) if name=~/\.xcworkspace/
42
-
43
- self.workspaces.each do |p|
44
- return p if p.name == name
45
- end
46
- raise "Unable to find a workspace named #{name}. However, I did find these workspaces: #{self.workspaces.map {|p| p.name}.join(', ') }"
47
- end
48
-
49
- def self.find_projects(dir='.')
50
- parse_projects(dir)
51
- end
52
-
53
- def self.is_sdk_available?(sdk)
54
- parse_sdks if @@sdks.nil?
55
- @@sdks.values.include? sdk
56
- end
57
-
58
- def self.available_sdks
59
- parse_sdks if @@sdks.nil?
60
- @@sdks
61
- end
62
-
63
- private
64
- def self.parse_sdks
65
- @@sdks = {}
66
- parsing = false
67
- `xcodebuild -showsdks`.split("\n").each do |l|
68
- l.strip!
69
- if l=~/(.*)\s+SDKs:/
70
- parsing = true
71
- elsif l=~/^\s*$/
72
- parsing = false
73
- elsif parsing
74
- l=~/([^\t]+)\t+\-sdk (.*)/
75
- @@sdks[$1.strip] = $2.strip unless $1.nil? and $2.nil?
76
- end
77
- end
78
- end
79
-
80
- def self.parse_workspaces(dir='.')
81
- projects = []
82
- Find.find(dir) do |path|
83
- if path=~/\.xcworkspace$/ and !(path=~/\.xcodeproj\//)
84
- projects << Xcode::Workspace.new(path)
85
- end
86
- end
87
- projects
88
- end
89
-
90
- def self.parse_projects(dir='.')
91
- projects = []
92
- Find.find(dir) do |path|
93
- if path=~/(.*)\.xcodeproj$/
94
- projects << Xcode::Project.new(path)
95
- end
96
- end
97
- projects
98
- end
99
- end
100
-
101
- require 'xcode/core_ext/hash'
102
- require 'xcode/core_ext/array'
103
- require 'xcode/core_ext/string'
104
- require 'xcode/core_ext/boolean'
105
- require 'xcode/core_ext/fixnum'