xcodebuild-rb 0.1.0

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.
@@ -0,0 +1,61 @@
1
+ require 'ostruct'
2
+
3
+ module XcodeBuild
4
+ module Reporting
5
+ module BuildReporting
6
+ def self.included(klass)
7
+ klass.instance_eval do
8
+ attr_reader :build
9
+ end
10
+ end
11
+
12
+ def build_started(params)
13
+ @build = Build.new(params)
14
+ notify :build_started, @build
15
+ end
16
+
17
+ def build_step(params)
18
+ if @build.last_step
19
+ notify :build_step_finished, @build.last_step
20
+ end
21
+
22
+ @build.add_step(params)
23
+
24
+ notify :build_step_started, @build.last_step
25
+ end
26
+
27
+ def build_error_detected(params)
28
+ @build.last_step.add_error(params)
29
+ end
30
+
31
+ def build_succeeded
32
+ @build.success!
33
+ build_finished
34
+ end
35
+
36
+ def build_failed
37
+ @build.failure!
38
+ build_finished
39
+ end
40
+
41
+ def build_step_failed(params)
42
+ if step = @build.step_with_params(params)
43
+ step.failed = true
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ def build_finished
50
+ if @build.last_step
51
+ notify :build_step_finished, @build.last_step
52
+ end
53
+
54
+ notify :build_finished, @build
55
+ end
56
+
57
+ class Build < BuildAction
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,59 @@
1
+ module XcodeBuild
2
+ module Reporting
3
+ module CleanReporting
4
+ def self.included(klass)
5
+ klass.instance_eval do
6
+ attr_reader :clean
7
+ end
8
+ end
9
+
10
+ def clean_started(params)
11
+ @clean = Clean.new(params)
12
+ notify :clean_started, @clean
13
+ end
14
+
15
+ def clean_step(params)
16
+ if clean.last_step
17
+ notify :clean_step_finished, clean.last_step
18
+ end
19
+
20
+ clean.add_step(params)
21
+
22
+ notify :clean_step_started, clean.last_step
23
+ end
24
+
25
+ def clean_error_detected(params)
26
+ clean.last_step.add_error(params)
27
+ end
28
+
29
+ def clean_succeeded
30
+ clean.success!
31
+ clean_finished
32
+ end
33
+
34
+ def clean_failed
35
+ clean.failure!
36
+ clean_finished
37
+ end
38
+
39
+ def clean_step_failed(params)
40
+ if step = clean.step_with_params(params)
41
+ step.failed = true
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ def clean_finished
48
+ if clean.last_step
49
+ notify :clean_step_finished, clean.last_step
50
+ end
51
+
52
+ notify :clean_finished, clean
53
+ end
54
+
55
+ class Clean < BuildAction
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,84 @@
1
+ require 'rake/tasklib'
2
+
3
+ module XcodeBuild
4
+ module Tasks
5
+ class BuildTask < ::Rake::TaskLib
6
+ attr_accessor :project_name
7
+ attr_accessor :target
8
+ attr_accessor :workspace
9
+ attr_accessor :scheme
10
+ attr_accessor :configuration
11
+ attr_accessor :arch
12
+ attr_accessor :sdk
13
+ attr_accessor :xcconfig
14
+ attr_accessor :output_to
15
+ attr_accessor :formatter
16
+ attr_accessor :invoke_from_within
17
+ attr_accessor :reporter
18
+
19
+ def initialize(namespace = :xcode, &block)
20
+ @namespace = namespace
21
+ @output_to = STDOUT
22
+ @invoke_from_within = "."
23
+
24
+ yield self if block_given?
25
+ define
26
+ end
27
+
28
+ def run(task)
29
+ Rake::Task["#{@namespace}:#{task}"].invoke
30
+ end
31
+
32
+ def build_opts
33
+ [].tap do |opts|
34
+ opts << "-project #{project_name}" if project_name
35
+ opts << "-target #{target}" if target
36
+ opts << "-workspace #{workspace}" if workspace
37
+ opts << "-scheme #{scheme}" if scheme
38
+ opts << "-configuration #{configuration}" if configuration
39
+ opts << "-arch #{arch}" if arch
40
+ opts << "-sdk #{sdk}" if sdk
41
+ opts << "-xcconfig #{xcconfig}" if xcconfig
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ def output_buffer
48
+ if reporter
49
+ XcodeBuild::OutputTranslator.new(reporter)
50
+ elsif formatter
51
+ default_reporter = XcodeBuild::Reporter.new(formatter)
52
+ XcodeBuild::OutputTranslator.new(default_reporter)
53
+ else
54
+ output_to
55
+ end
56
+ end
57
+
58
+ def build_opts_string(*additional_opts)
59
+ (build_opts + additional_opts).join(" ")
60
+ end
61
+
62
+ def define
63
+ namespace(@namespace) do
64
+ desc "Builds the specified target(s)."
65
+ task :build do
66
+ Dir.chdir(invoke_from_within) do
67
+ XcodeBuild.run(build_opts_string, output_buffer)
68
+ end
69
+ end
70
+
71
+ desc "Cleans the build using the same build settings."
72
+ task :clean do
73
+ Dir.chdir(invoke_from_within) do
74
+ XcodeBuild.run(build_opts_string("clean"), output_buffer)
75
+ end
76
+ end
77
+
78
+ desc "Builds the specified target(s) from a clean slate."
79
+ task :cleanbuild => [:clean, :build]
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,20 @@
1
+ module XcodeBuild
2
+ module Translations
3
+ extend self
4
+
5
+ def registered_translations
6
+ @registered_translators ||= {}
7
+ end
8
+
9
+ def register_translation(key, the_module)
10
+ registered_translations[key] = the_module
11
+ end
12
+
13
+ def registered_translation(key)
14
+ registered_translations[key]
15
+ end
16
+ end
17
+ end
18
+
19
+ require_relative "translations/building"
20
+ require_relative "translations/cleaning"
@@ -0,0 +1,101 @@
1
+ module XcodeBuild
2
+ module Translations
3
+ module Building
4
+ def attempt_to_translate(line)
5
+ if line =~ /^\=\=\= BUILD/
6
+ notify_build_started(line)
7
+ end
8
+
9
+ return unless building?
10
+
11
+ if line =~ /^\*\* BUILD (\w+) \*\*/
12
+ notify_build_ended($1)
13
+ return
14
+ end
15
+
16
+ if @beginning_build_step
17
+ @beginning_build_step = false
18
+ notify_build_step(line) unless line.strip.empty?
19
+ return
20
+ end
21
+
22
+ if @beginning_error_report
23
+ if line =~ /^\(\d+ failure(s?)\)/
24
+ @beginning_error_report = false
25
+ else
26
+ notify_build_step_failed(line)
27
+ end
28
+ end
29
+
30
+ case line
31
+ when /^(.*):(\d+):(\d+): error: (.*)$/
32
+ notify_build_error($1, $2, $3, $4)
33
+ when /^The following build commands failed:/
34
+ @beginning_error_report = true
35
+ when /^\n/
36
+ @beginning_build_step = true
37
+ end
38
+ end
39
+
40
+ def building?
41
+ @building
42
+ end
43
+
44
+ private
45
+
46
+ def notify_build_started(line)
47
+ @building = true
48
+
49
+ target = line.match(/TARGET (\w+)/)[1]
50
+ project = line.match(/PROJECT (\w+)/)[1]
51
+
52
+ if line =~ /DEFAULT CONFIGURATION \((\w+)\)/
53
+ configuration = $1
54
+ default = true
55
+ else
56
+ configuration = line.match(/CONFIGURATION (\w+)/)[1]
57
+ default = false
58
+ end
59
+
60
+ notify_delegate(:build_started, required: true, args: [{
61
+ target: target,
62
+ project: project,
63
+ configuration: configuration,
64
+ default: default
65
+ }])
66
+ end
67
+
68
+ def notify_build_step(line)
69
+ notify_delegate(:build_step, args: [build_step_from_line(line)])
70
+ end
71
+
72
+ def notify_build_error(file, line, char, message)
73
+ notify_delegate(:build_error_detected, args: [{
74
+ file: file,
75
+ line: line.to_i,
76
+ char: char.to_i,
77
+ message: message
78
+ }])
79
+ end
80
+
81
+ def notify_build_ended(result)
82
+ if result =~ /SUCCEEDED/
83
+ notify_delegate(:build_succeeded, required: true)
84
+ else
85
+ notify_delegate(:build_failed, required: true)
86
+ end
87
+ end
88
+
89
+ def notify_build_step_failed(line)
90
+ notify_delegate(:build_step_failed, args: [build_step_from_line(line)])
91
+ end
92
+
93
+ def build_step_from_line(line)
94
+ parts = line.strip.split(" ")
95
+ {type: parts.shift, arguments: parts}
96
+ end
97
+ end
98
+
99
+ register_translation :building, Building
100
+ end
101
+ end
@@ -0,0 +1,96 @@
1
+ module XcodeBuild
2
+ module Translations
3
+ module Cleaning
4
+ def attempt_to_translate(line)
5
+ if line =~ /^\=\=\= CLEAN/
6
+ notify_clean_started(line)
7
+ end
8
+
9
+ return unless cleaning?
10
+
11
+ if line =~ /^\*\* CLEAN (\w+) \*\*/
12
+ notify_clean_ended($1)
13
+ return
14
+ end
15
+
16
+ if @beginning_clean_step
17
+ @beginning_clean_step = false
18
+ notify_clean_step(line) unless line.strip.empty?
19
+ return
20
+ end
21
+
22
+ if @beginning_error_report
23
+ if line =~ /^\(\d+ failure(s?)\)/
24
+ @beginning_error_report = false
25
+ else
26
+ notify_clean_step_failed(line)
27
+ end
28
+ end
29
+
30
+ case line
31
+ when /^error: (.*)$/
32
+ notify_clean_error($1)
33
+ when /^The following build commands failed:/
34
+ @beginning_error_report = true
35
+ when /^\n/
36
+ @beginning_clean_step = true
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ def cleaning?
43
+ @cleaning
44
+ end
45
+
46
+ def notify_clean_started(line)
47
+ @cleaning = true
48
+
49
+ target = line.match(/TARGET (\w+)/)[1]
50
+ project = line.match(/PROJECT (\w+)/)[1]
51
+
52
+ if line =~ /DEFAULT CONFIGURATION \((\w+)\)/
53
+ configuration = $1
54
+ default = true
55
+ else
56
+ configuration = line.match(/CONFIGURATION (\w+)/)[1]
57
+ default = false
58
+ end
59
+
60
+ notify_delegate(:clean_started, required: true, args: [{
61
+ target: target,
62
+ project: project,
63
+ configuration: configuration,
64
+ default: default
65
+ }])
66
+ end
67
+
68
+ def notify_clean_step(line)
69
+ notify_delegate(:clean_step, args: [clean_step_from_line(line)])
70
+ end
71
+
72
+ def notify_clean_step_failed(line)
73
+ notify_delegate(:clean_step_failed, args: [clean_step_from_line(line)])
74
+ end
75
+
76
+ def notify_clean_error(message)
77
+ notify_delegate(:clean_error_detected, args: [{message: message}])
78
+ end
79
+
80
+ def notify_clean_ended(result)
81
+ if result =~ /SUCCEEDED/
82
+ notify_delegate(:clean_succeeded, required: true)
83
+ else
84
+ notify_delegate(:clean_failed, required: true)
85
+ end
86
+ end
87
+
88
+ def clean_step_from_line(line)
89
+ parts = line.strip.split(" ")
90
+ {type: parts.shift, arguments: parts}
91
+ end
92
+ end
93
+
94
+ register_translation :cleaning, Cleaning
95
+ end
96
+ end
@@ -0,0 +1,45 @@
1
+ module XcodeBuild
2
+ module Utilities
3
+ module Colorize # borrowed from rspec-core
4
+ def color(text, color_code)
5
+ color_enabled? ? "#{color_code}#{text}\e[0m" : text
6
+ end
7
+
8
+ def bold(text)
9
+ color(text, "\e[1m")
10
+ end
11
+
12
+ def red(text)
13
+ color(text, "\e[31m")
14
+ end
15
+
16
+ def green(text)
17
+ color(text, "\e[32m")
18
+ end
19
+
20
+ def yellow(text)
21
+ color(text, "\e[33m")
22
+ end
23
+
24
+ def blue(text)
25
+ color(text, "\e[34m")
26
+ end
27
+
28
+ def magenta(text)
29
+ color(text, "\e[35m")
30
+ end
31
+
32
+ def cyan(text)
33
+ color(text, "\e[36m")
34
+ end
35
+
36
+ def white(text)
37
+ color(text, "\e[37m")
38
+ end
39
+
40
+ def short_padding
41
+ ' '
42
+ end
43
+ end
44
+ end
45
+ end