ios_ci 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/bin/ios_ci ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/ruby
2
+ require "ios_ci"
3
+
4
+ IOSCI.new
@@ -0,0 +1,44 @@
1
+ require "model/params.rb"
2
+
3
+ class BaseCommand
4
+
5
+ # public methods
6
+ public
7
+
8
+ def initialize(params)
9
+ @params = params
10
+ end
11
+
12
+ def all_commands
13
+ [before_command, main_command, after_command].compact
14
+ end
15
+
16
+ def empty?
17
+ all_commands.empty?
18
+ end
19
+
20
+ def log_file
21
+ @params.log_file
22
+ end
23
+
24
+ # override in subclasses
25
+ def before_command
26
+ raise "Invoking of abstract method 'before_command' of 'BaseCommand class'"
27
+ end
28
+
29
+ def main_command
30
+ raise "Invoking of abstract method 'main_command' of 'BaseCommand class'"
31
+ end
32
+
33
+ def after_command
34
+ raise "Invoking of abstract method 'after_command' of 'BaseCommand class'"
35
+ end
36
+
37
+ # private methods
38
+ private
39
+
40
+ def app_path
41
+ "#{@params.source_root}/#{@params.build_path}/#{@params.configuration}-#{@params.architecture}/#{@params.app_name}.app"
42
+ end
43
+
44
+ end
@@ -0,0 +1,36 @@
1
+ require "commands/base_command.rb"
2
+
3
+ class BuildApp < BaseCommand
4
+
5
+ # overriding base class methods
6
+ def before_command
7
+ "cd #{@params.source_root} && pod install" if cocoapods?
8
+ end
9
+
10
+ def main_command
11
+ "cd #{@params.source_root} && xcodebuild #{build_args} -sdk #{@params.architecture} -configuration #{@params.configuration} clean build CONFIGURATION_BUILD_DIR=#{clean_dir}"
12
+ end
13
+
14
+ def after_command
15
+ end
16
+
17
+ def log_file
18
+ end
19
+
20
+ # private methods
21
+ private
22
+
23
+ def build_args
24
+ @params.target? ? "-target '#{@params.target}'" :
25
+ "-scheme '#{@params.scheme}' -workspace '#{@params.workspace}'"
26
+ end
27
+
28
+ def clean_dir
29
+ "#{@params.source_root}/#{@params.build_path}/#{@params.configuration}-#{@params.architecture}"
30
+ end
31
+
32
+ def cocoapods?
33
+ File.exist?("#{@params.source_root}/Podfile")
34
+ end
35
+
36
+ end
@@ -0,0 +1,24 @@
1
+ require "commands/base_command.rb"
2
+
3
+ class DownloadCalabash < BaseCommand
4
+
5
+ # overrides from base class
6
+ def before_command
7
+ "cd #{@params.source_root} && rm -rf calabash.framework" if framework?
8
+ end
9
+
10
+ def main_command
11
+ "cd #{@params.source_root} && calabash-ios download"
12
+ end
13
+
14
+ def after_command
15
+ end
16
+
17
+ # private
18
+ private
19
+
20
+ def framework?
21
+ File.directory?("#{@params.source_root}/calabash.framework")
22
+ end
23
+
24
+ end
@@ -0,0 +1,24 @@
1
+ require "commands/base_command.rb"
2
+
3
+ class TestCalabash < BaseCommand
4
+
5
+ # overrides from base class
6
+ def before_command
7
+ end
8
+
9
+ def main_command
10
+ "cd #{@params.source_root} && APP_BUNDLE_PATH='#{app_path}' #{test_command} -o #{log_file} --require features"
11
+ end
12
+
13
+ def after_command
14
+ "! grep -q \"failed\" #{log_file} && grep -q \"passed\" #{log_file}"
15
+ end
16
+
17
+ # private methods
18
+ private
19
+
20
+ def test_command
21
+ "cucumber"
22
+ end
23
+
24
+ end
@@ -0,0 +1,31 @@
1
+ require "commands/base_command.rb"
2
+
3
+ SIM_PATH = "/usr/local/bin/ios-sim"
4
+
5
+ class TestCedar < BaseCommand
6
+
7
+ # overrides from base class
8
+ def before_command
9
+ end
10
+
11
+ def main_command
12
+ "#{test_command} > #{self.log_file} 2>&1"
13
+ end
14
+
15
+ def after_command
16
+ "grep -q \"0 failures\" #{self.log_file}"
17
+ end
18
+
19
+ # private methods
20
+ private
21
+
22
+ def test_command
23
+ command = "#{SIM_PATH} launch #{app_path} --setenv CEDAR_HEADLESS_SPECS=1\
24
+ --setenv CEDAR_REPORTER_CLASS=CDRColorizedReporter,CDRJUnitXMLReporter\
25
+ --setenv CEDAR_JUNIT_XML_FILE=#{@params.source_root}/test-reports/cedar.xml"
26
+ command += " --family #{@params.family} " unless @params.family.nil?
27
+ command += " --sdk #{@params.sdk} " unless @params.sdk.nil?
28
+ command
29
+ end
30
+
31
+ end
@@ -0,0 +1,13 @@
1
+ def print_file(file)
2
+ if !file.nil?
3
+ if File.exist?(file)
4
+ File.open(file, 'r') do | f |
5
+ while line = f.gets
6
+ puts line
7
+ end
8
+ end
9
+ else
10
+ puts "File not exists:\n#{file}"
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,43 @@
1
+ require "model/params.rb"
2
+ require "commands/build_app.rb"
3
+ require "commands/test_cedar.rb"
4
+ require "commands/test_calabash.rb"
5
+ require "commands/download_calabash.rb"
6
+
7
+ class CommandFactory
8
+ # instance variables
9
+ @params = nil
10
+
11
+ # public methods
12
+ public
13
+
14
+ def initialize(params)
15
+ @params = params
16
+ end
17
+
18
+ def get_commands
19
+ if @params.action == ACTION_BUILD
20
+ [get_build]
21
+ elsif @params.action == ACTION_CEDAR
22
+ get_cedar
23
+ elsif @params.action == ACTION_CALABASH
24
+ get_calabash
25
+ end
26
+ end
27
+
28
+ #private methods
29
+ private
30
+
31
+ def get_build
32
+ BuildApp.new(@params)
33
+ end
34
+
35
+ def get_cedar
36
+ [get_build, TestCedar.new(@params)]
37
+ end
38
+
39
+ def get_calabash
40
+ [DownloadCalabash.new(@params), get_build, TestCalabash.new(@params)]
41
+ end
42
+
43
+ end
data/lib/ios_ci.rb ADDED
@@ -0,0 +1,34 @@
1
+ require "model/params.rb"
2
+ require "launcher/launcher.rb"
3
+ require "factories/command_factory.rb"
4
+
5
+ class IOSCI
6
+ # instance variables
7
+ @launcher = nil
8
+ @params = nil
9
+
10
+ # public methods
11
+ public
12
+
13
+ def initialize
14
+ @launcher = Launcher.new
15
+ @params = Params.new
16
+ factory = CommandFactory.new(@params)
17
+ run(factory.get_commands)
18
+ end
19
+
20
+ # private methods
21
+ private
22
+
23
+ def run(commands)
24
+ @launcher.run(commands)
25
+ if @launcher.success?
26
+ puts "#{@params.action} succeeded"
27
+ exit 0
28
+ else
29
+ puts "#{@params.action} failed"
30
+ exit 1
31
+ end
32
+ end
33
+
34
+ end
@@ -0,0 +1,47 @@
1
+ require "commands/base_command.rb"
2
+ require "extra/print_file.rb"
3
+
4
+ class Launcher
5
+
6
+ # instance variables
7
+ @result = nil
8
+
9
+ # public methods
10
+ public
11
+
12
+ def run(commands)
13
+ commands.map { | command |
14
+ next if command.empty?
15
+ @result = run_command(command)
16
+ break unless @result
17
+ }
18
+ end
19
+
20
+ def success?
21
+ @result
22
+ end
23
+
24
+ # private
25
+ private
26
+
27
+ def run_command(command)
28
+ close_simulator
29
+ invoke_result = invoke(command.all_commands)
30
+ print_file(command.log_file) unless command.log_file.nil?
31
+ return invoke_result
32
+ end
33
+
34
+ def invoke(commands)
35
+ commands.map { | cmd |
36
+ puts ">>>>> Running commands <<<<<\n#{cmd}\n"
37
+ system(cmd)
38
+ }.last
39
+ end
40
+
41
+ def close_simulator
42
+ puts "Closing iPhone Simulator"
43
+ %x[ killall "iPhone Simulator" ]
44
+ puts ""
45
+ end
46
+
47
+ end
@@ -0,0 +1,128 @@
1
+ require "getoptlong"
2
+ require "extra/print_file.rb"
3
+
4
+ ACTION_BUILD = "build"
5
+ ACTION_CEDAR = "cedar"
6
+ ACTION_CALABASH = "calabash"
7
+
8
+ class Params
9
+ # attributes
10
+ attr_reader :action, :source_root, :target, :scheme, :workspace, :configuration,
11
+ :architecture, :sdk, :family, :build_path, :log_file
12
+
13
+ # public methods
14
+ public
15
+
16
+ def initialize
17
+ set_defaults
18
+ begin
19
+ parse_action
20
+ getoptlong = get_options
21
+ parse_options(getoptlong)
22
+ check_options
23
+ set_log_file
24
+
25
+ rescue StandardError=>error
26
+ puts "\n#{error}\n#{usage}"
27
+ exit 1
28
+ end
29
+ end
30
+
31
+ def app_name
32
+ target? ? @target : @scheme
33
+ end
34
+
35
+ def workspace?
36
+ !@scheme.nil? && !@workspace.nil?
37
+ end
38
+
39
+ def target?
40
+ !@target.nil?
41
+ end
42
+
43
+ # private methods
44
+ private
45
+
46
+ def set_defaults
47
+ @architecture = "iphonesimulator"
48
+ @configuration = "Release"
49
+ @build_path = "build"
50
+ end
51
+
52
+ def parse_action
53
+ @action = ARGV.shift
54
+ raise unless check_action
55
+ end
56
+
57
+ def get_options
58
+ GetoptLong.new(
59
+ [ '--target', '-t', GetoptLong::OPTIONAL_ARGUMENT ],
60
+ [ '--scheme', '-h', GetoptLong::OPTIONAL_ARGUMENT ],
61
+ [ '--workspace', '-w', GetoptLong::OPTIONAL_ARGUMENT ],
62
+ [ '--source-root', '-r', GetoptLong::OPTIONAL_ARGUMENT ],
63
+ [ '--arch', '-a' ,GetoptLong::OPTIONAL_ARGUMENT ],
64
+ [ '--configuration', '-c', GetoptLong::OPTIONAL_ARGUMENT ],
65
+ [ '--sdk', '-s', GetoptLong::OPTIONAL_ARGUMENT ],
66
+ [ '--log-file', '-l', GetoptLong::OPTIONAL_ARGUMENT ],
67
+ [ '--family', '-f' ,GetoptLong::OPTIONAL_ARGUMENT ],
68
+ [ '--build-path', '-b' ,GetoptLong::OPTIONAL_ARGUMENT ]
69
+ )
70
+ end
71
+
72
+ def parse_options(getoptlong)
73
+ getoptlong.each do |opt, arg|
74
+ case opt
75
+ when ACTION_BUILD
76
+ @action = ACTION_BUILD
77
+ when ACTION_CEDAR
78
+ @action = ACTION_CEDAR
79
+ when ACTION_CALABASH
80
+ @action = ACTION_CALABASH
81
+ when "--source-root"
82
+ @source_root = arg
83
+ when "--target"
84
+ @target = arg
85
+ when "--scheme"
86
+ @scheme = arg
87
+ when "--workspace"
88
+ @workspace = arg
89
+ when "--configuration"
90
+ @configuration = arg
91
+ when "--arch"
92
+ @architecture = arg
93
+ when "--sdk"
94
+ @sdk = arg
95
+ when "--family"
96
+ @family = arg
97
+ when "--build-path"
98
+ @build_path = arg
99
+ when "--log-file"
100
+ @log_file = arg
101
+ end
102
+ end
103
+ end
104
+
105
+ def check_action
106
+ @action == ACTION_BUILD || @action == ACTION_CEDAR || @action == ACTION_CALABASH
107
+ end
108
+ def check_options
109
+ if self.action.nil?
110
+ puts "You must specify action type"
111
+ raise
112
+ elsif self.source_root.nil?
113
+ puts "You must specify source root"
114
+ raise
115
+ elsif !self.target? && !self.workspace?
116
+ puts "You must specify target root or scheme and workspace"
117
+ raise
118
+ end
119
+ end
120
+
121
+ def set_log_file
122
+ @log_file = "/tmp/#{@action}-#{app_name}-#{Time.now.to_i}.log" if @log_file.nil?
123
+ end
124
+
125
+ def usage
126
+ print_file("lib/usage.txt")
127
+ end
128
+ end
data/lib/usage.txt ADDED
@@ -0,0 +1,32 @@
1
+ Usage:
2
+ ios_ci Action ProjectOptions
3
+
4
+ === Action
5
+
6
+ build :: build project
7
+ cedar :: build and run cedar-tests
8
+ calabash :: build and run calabash-tests
9
+
10
+
11
+ === Project Options
12
+
13
+ --source-root :: path to project source code directory
14
+ (required)
15
+ --target :: project target name
16
+ (required if no scheme and workspace specified)
17
+ --scheme :: project build scheme
18
+ (required if no target specified)
19
+ --workspace :: project worspace
20
+ (required id no target specified)
21
+ --configuration :: Release, Debug
22
+ (optional, default: Release)
23
+ --architecture :: iphoneos, iphonesimulator
24
+ (optional, default: iphonesimulator)
25
+ --sdk :: version
26
+ (optional, default: latest)
27
+ --family :: iphone, ipad
28
+ (optional, default: iphone)
29
+ --build-path :: relative path from source root to app build
30
+ (optional, default: $source-root/build/)
31
+ --log-file :: path to log file
32
+ (optional, default: /tmp/$action-$target-$timestamp.log)
metadata ADDED
@@ -0,0 +1,58 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ios_ci
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Alexey Belkevich
9
+ - Alexey Denisov
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2012-11-28 00:00:00.000000000 Z
14
+ dependencies: []
15
+ description: Script for iOS continuous integration
16
+ email: belkevich@okolodev.org
17
+ executables:
18
+ - ios_ci
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - lib/ios_ci.rb
23
+ - lib/usage.txt
24
+ - lib/commands/base_command.rb
25
+ - lib/commands/build_app.rb
26
+ - lib/commands/test_calabash.rb
27
+ - lib/commands/download_calabash.rb
28
+ - lib/commands/test_cedar.rb
29
+ - lib/factories/command_factory.rb
30
+ - lib/launcher/launcher.rb
31
+ - lib/model/params.rb
32
+ - lib/extra/print_file.rb
33
+ - bin/ios_ci
34
+ homepage: https://github.com/okolodev/ios_ci
35
+ licenses: []
36
+ post_install_message:
37
+ rdoc_options: []
38
+ require_paths:
39
+ - lib
40
+ required_ruby_version: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ required_rubygems_version: !ruby/object:Gem::Requirement
47
+ none: false
48
+ requirements:
49
+ - - ! '>='
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ requirements: []
53
+ rubyforge_project:
54
+ rubygems_version: 1.8.24
55
+ signing_key:
56
+ specification_version: 3
57
+ summary: iOS continuous integration
58
+ test_files: []