thrust 0.2.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b6b885837e6c3dac116eca861cc6e772243c2d54
4
- data.tar.gz: 625f5556939cdb39a575c648c9b85de3b4825a92
3
+ metadata.gz: 978a630b927682d5514cf9ce5b71ce2bc2c9a9ff
4
+ data.tar.gz: ca9c565b330db40e39c02a7ca6ee600ae1a1a682
5
5
  SHA512:
6
- metadata.gz: 7f249ea7b0d1b30871c64de088427dccaf5a05fe66f1feb8707855c808374971b273b085ca1646b062e0358cac21866c9f9abc911425430c4c9ec2931a04f91d
7
- data.tar.gz: 254b3ca985e6b4cee3c4d866d60e30d48fd9fe8f9fa3fdde3b665ad5b17a70eee309ec229c991ea0b64043444de9e0fcf9e1716e3079db67c84d225ae3554443
6
+ metadata.gz: 483178b25da64bc6d343d3032fc60b4d0bf12fdf5380794564a4bec13f2dc0e97dd6424f4111ff06c83ce891d71d5ce5e30c48ae784b0ecb8824f91142edcbe8
7
+ data.tar.gz: 79ea4ddc3b9ad3879d0572a354922b7a1d2ac4450f1134ee2cdf53103a916e6c3414487d6801458165adc573924c530c0c6ceb467a38f57586a722ca35d9123d
data/bin/thrust CHANGED
@@ -20,7 +20,14 @@ File.open(rakefile, 'a') do |f|
20
20
  f.puts "require 'thrust/tasks'"
21
21
  end
22
22
 
23
- FileUtils.cp(File.join(thrust_root, 'lib', 'config', 'example.yml'), File.join(project_root, 'thrust.example.yml'))
23
+ if File.exists?('AndroidManifest.xml')
24
+ example_file_name = 'android_example.yml'
25
+ else
26
+ example_file_name = 'ios_example.yml'
27
+ end
28
+
29
+
30
+ FileUtils.cp(File.join(thrust_root, 'lib', 'config', example_file_name), File.join(project_root, 'thrust.example.yml'))
24
31
  puts ''
25
32
  puts " To finish installation of " + "Thrust".green + ", rename:\n\n"
26
33
  puts " #{project_root}/thrust.example.yml\n".blue
@@ -0,0 +1,17 @@
1
+ thrust_version: 0.3
2
+ project_name: My Great Project
3
+ app_name: My Great App
4
+
5
+ testflight:
6
+ api_token: 'testflight api token'
7
+ team_token: 'testflight team token'
8
+
9
+ deployment_targets:
10
+ staging:
11
+ distribution_list: Developers
12
+ notify: true
13
+ note_generation_method: autotag # If you set this value, it will auto-generate the deploy notes from the commit history. Optional.
14
+
15
+ demo:
16
+ distribution_list: Beta Testers
17
+ notify: true
@@ -0,0 +1,39 @@
1
+ thrust_version: 0.3
2
+ project_name: My Great Project # do not use if building with an xcode workspace
3
+ # workspace_name: My Workspace # use if building with an xcode workspace
4
+ app_name: My Great App
5
+ ios_distribution_certificate: 'Name of Distribution Signing Certificate'
6
+ ios_sim_binary: 'ios-sim' # or wax-sim. iOS only.
7
+
8
+ testflight:
9
+ api_token: 'testflight api token' # To find your App Token, follow the instructions at: http://help.testflightapp.com/customer/portal/articles/829956-what-does-the-api-token-do-
10
+ team_token: 'testflight team token' # To find your Team Token, follow the instructions at: http://help.testflightapp.com/customer/portal/articles/829942-how-do-i-find-my-team-token-
11
+
12
+ deployment_targets:
13
+ staging:
14
+ distribution_list: Developers # This is the name of a TestFlight distribution list
15
+ notify: true # Whether to notify people on the distribution list about this deployment
16
+ note_generation_method: autotag # If you set this value, it will auto-generate the deploy notes from the commit history. Optional.
17
+ ios_target: MyGreatAppTarget # Name of the build target. Optional, defaults to app name. iOS only.
18
+ ios_build_configuration: Release # iOS only
19
+ ios_provisioning_search_query: 'query to find Provisioning Profile' # iOS only. Optional.
20
+
21
+ demo:
22
+ distribution_list: Beta Testers
23
+ notify: true
24
+
25
+ ios_spec_targets:
26
+ specs: # This is the name of the rake task: `rake specs`
27
+ target: UISpecs # name of the build target
28
+ # scheme: Specs (My Great App) # use in addition to target when you want to use a scheme (necessary if you are building with an xcode workspace)
29
+ build_configuration: Debug # name of the build configuration
30
+ build_sdk: iphonesimulator7.0 # SDK used to build the target. Optional, defaults to latest iphonesimulator.
31
+ runtime_sdk: 7.0 # SDK used to run the target. Not optional.
32
+ device: ipad # Device to run the specs on. Optional, defaults to iPhone.
33
+
34
+ integration:
35
+ target: IntegrationSpecs
36
+ # scheme: IntegrationSpecs (My Great App) # use in addition to target when you want to use a scheme (necessary if you are building with an xcode workspace)
37
+ build_configuration: Release
38
+ build_sdk: macosx
39
+ runtime_sdk: macosx
data/lib/tasks/cedar.rake CHANGED
@@ -3,6 +3,8 @@ require 'tmpdir'
3
3
  require File.expand_path('../../thrust', __FILE__)
4
4
 
5
5
  @thrust = Thrust::Config.make(Dir.getwd, File.join(Dir.getwd, 'thrust.yml'))
6
+ @xcode_tools_provider = Thrust::IOS::XCodeToolsProvider.new
7
+ @executor = Thrust::Executor.new
6
8
 
7
9
  desc 'Trim whitespace'
8
10
  task :trim do
@@ -16,51 +18,57 @@ task :trim do
16
18
  AWK
17
19
  awk_statement.gsub!(%r{\s+}, " ")
18
20
 
19
- Thrust::Executor.system_or_exit %Q[git status --porcelain | awk '#{awk_statement}' | grep -e '.*\.[cmh]$' | xargs sed -i '' -e 's/ / /g;s/ *$//g;']
21
+ @executor.system_or_exit %Q[git status --porcelain | awk '#{awk_statement}' | grep -e '.*\.[cmh]$' | xargs sed -i '' -e 's/ / /g;s/ *$//g;']
20
22
  end
21
23
 
22
- desc "Remove any focus from specs"
24
+ desc 'Remove any focus from specs'
23
25
  task :nof do
24
26
  substitutions = focused_methods.map do |method|
25
27
  unfocused_method = method.sub(/^f/, '')
26
28
  "-e 's/#{method}/#{unfocused_method}/g;'"
27
29
  end
28
30
 
29
- Thrust::Executor.system_or_exit %Q[ rake focused_specs | xargs -I filename sed -i '' #{substitutions.join(' ')} "filename" ]
31
+ @executor.system_or_exit %Q[ rake focused_specs | xargs -I filename sed -i '' #{substitutions.join(' ')} "filename" ]
30
32
  end
31
33
 
32
- desc "Print out names of files containing focused specs"
34
+ desc 'Print out names of files containing focused specs'
33
35
  task :focused_specs do
34
36
  pattern = focused_methods.join("\\|")
35
37
  directories = @thrust.app_config['ios_spec_targets'].values.map {|h| h['target']}.join(' ')
36
- Thrust::Executor.system_or_exit %Q[ grep -l -r -e "\\(#{pattern}\\)" #{directories} | grep -v 'Frameworks' ; exit 0 ]
38
+ @executor.system_or_exit %Q[ grep -l -r -e "\\(#{pattern}\\)" #{directories} | grep -v 'Frameworks' ; exit 0 ]
37
39
  end
38
40
 
39
41
  desc 'Clean all targets'
40
- task :clean_build do
41
- Thrust::IOS::XCodeTools.build_configurations(@thrust.app_config['project_name']).each do |config|
42
- xcode_tools = Thrust::IOS::XCodeTools.new($stdout, config, @thrust.build_dir, @thrust.app_config['project_name'])
43
- xcode_tools.clean_build
44
- end
42
+ task :clean do
43
+ xcode_tools_instance(nil).clean_build
45
44
  end
46
45
 
46
+ desc 'Clean all targets (deprecated, use "clean")'
47
+ task :clean_build => :clean
48
+
47
49
  (@thrust.app_config['ios_spec_targets'] || []).each do |task_name, target_info|
48
- desc "Run the #{target_info['target']} target"
49
- task task_name do
50
+ desc target_info['scheme'] ? "Run the #{target_info['scheme'].inspect} scheme" : "Run the #{target_info['target'].inspect} target"
51
+ task task_name, :runtime_sdk do |_, args|
50
52
  build_configuration = target_info['build_configuration']
51
53
  target = target_info['target']
54
+ scheme = target_info['scheme']
52
55
  build_sdk = target_info['build_sdk'] || 'iphonesimulator' #build sdk - version you compile the code with
53
- runtime_sdk = target_info['runtime_sdk'] #runtime sdk
56
+ runtime_sdk = args[:runtime_sdk] || target_info['runtime_sdk'] #runtime sdk
54
57
 
55
- xcode_tools = Thrust::IOS::XCodeTools.new($stdout, build_configuration, @thrust.build_dir, @thrust.app_config['project_name'])
56
- xcode_tools.clean_and_build_target(target, build_sdk)
58
+ xcode_tools = xcode_tools_instance(build_configuration)
59
+ xcode_tools.build_scheme_or_target(scheme || target, build_sdk, 'i386')
57
60
 
58
- cedar_success = Thrust::IOS::Cedar.run($stdout, build_configuration, target, runtime_sdk, build_sdk, target_info['device'], @thrust.build_dir, @thrust.app_config['ios_sim_binary'])
61
+ cedar_success = Thrust::IOS::Cedar.new.run($stdout, build_configuration, target, runtime_sdk, build_sdk, target_info['device'], @thrust.build_dir, @thrust.app_config['ios_sim_binary'])
59
62
 
60
- exit(cedar_success ? 0 : 1)
63
+ exit(1) unless cedar_success
61
64
  end
62
65
  end
63
66
 
64
67
  def focused_methods
65
- ["fit", "fcontext", "fdescribe"].map { |method| "#{method}(@" }
68
+ %w(fit fcontext fdescribe).map { |method| "#{method}(@" }
69
+ end
70
+
71
+ def xcode_tools_instance(build_configuration)
72
+ tools_options = { project_name: @thrust.app_config['project_name'], workspace_name: @thrust.app_config['workspace_name'] }
73
+ @xcode_tools_provider.instance($stdout, build_configuration, @thrust.build_dir, tools_options)
66
74
  end
@@ -11,14 +11,14 @@ namespace :testflight do
11
11
  if android_project
12
12
  desc "Deploy Android build to #{task_name} (use NOTIFY=false to prevent team notification)"
13
13
  task task_name do |_, _|
14
- Thrust::Android::Deploy.make(@thrust, deployment_config, task_name).run
14
+ Thrust::Android::DeployProvider.new.instance(@thrust, deployment_config, task_name).run
15
15
 
16
16
  Rake::Task['autotag:create'].invoke(task_name)
17
17
  end
18
18
  else
19
19
  desc "Deploy iOS build to #{task_name} (use NOTIFY=false to prevent team notification)"
20
20
  task task_name do |_, _|
21
- Thrust::IOS::Deploy.make(@thrust, deployment_config, task_name).run
21
+ Thrust::IOS::DeployProvider.new.instance(@thrust, deployment_config, task_name).run
22
22
 
23
23
  Rake::Task['autotag:create'].invoke(task_name)
24
24
  end
@@ -34,7 +34,7 @@ namespace :autotag do
34
34
  desc 'Show the commit that is currently deployed to each environment'
35
35
  task :list do
36
36
  @thrust.app_config['deployment_targets'].each do |deployment_target, _|
37
- puts Thrust::Git.new($stdout).commit_summary_for_last_deploy(deployment_target)
37
+ puts Thrust::Git.new(Thrust::Executor.new, $stdout).commit_summary_for_last_deploy(deployment_target)
38
38
  end
39
39
  end
40
40
  end
@@ -0,0 +1,12 @@
1
+ require File.expand_path('../../thrust', __FILE__)
2
+
3
+ desc 'Set build number'
4
+ task :set_build_number, :build_number do |_, args|
5
+ executor = Thrust::Executor.new
6
+
7
+ if File.exists?('AndroidManifest.xml')
8
+ Thrust::Android::Tools.new(executor, $stdout).change_build_number(Time.now.utc.strftime('%y%m%d%H%M'), args[:build_number])
9
+ else
10
+ Thrust::IOS::AgvTool.new(executor, $stdout).change_build_number(args[:build_number])
11
+ end
12
+ end
@@ -1,15 +1,4 @@
1
1
  class Thrust::Android::Deploy
2
- def self.make(thrust_config, deployment_config, deployment_target)
3
- tools = Thrust::Android::Tools.new($stdout)
4
- git = Thrust::Git.new($stdout)
5
-
6
- testflight_config = thrust_config.app_config['testflight']
7
- testflight = Thrust::Testflight.new($stdout, $stdin, testflight_config['api_token'], testflight_config['team_token'])
8
-
9
- autogenerate_notes = deployment_config['note_generation_method'] == 'autotag'
10
- new($stdout, tools, git, testflight, deployment_config['notify'], deployment_config['distribution_list'], autogenerate_notes, deployment_target)
11
- end
12
-
13
2
  def initialize(out, tools, git, testflight, notify, distribution_list, autogenerate_notes, deployment_target)
14
3
  @out = out
15
4
  @tools = tools
@@ -0,0 +1,13 @@
1
+ class Thrust::Android::DeployProvider
2
+ def instance(thrust_config, deployment_config, deployment_target)
3
+ thrust_executor = Thrust::Executor.new
4
+ tools = Thrust::Android::Tools.new(thrust_executor, $stdout)
5
+ git = Thrust::Git.new(thrust_executor, $stdout)
6
+
7
+ testflight_config = thrust_config.app_config['testflight']
8
+ testflight = Thrust::Testflight.new(thrust_executor, $stdout, $stdin, testflight_config['api_token'], testflight_config['team_token'])
9
+
10
+ autogenerate_notes = deployment_config['note_generation_method'] == 'autotag'
11
+ Thrust::Android::Deploy.new($stdout, tools, git, testflight, deployment_config['notify'], deployment_config['distribution_list'], autogenerate_notes, deployment_target)
12
+ end
13
+ end
@@ -1,33 +1,39 @@
1
1
  require 'colorize'
2
2
 
3
3
  class Thrust::Android::Tools
4
- def initialize(out)
4
+ def initialize(thrust_executor, out)
5
+ @thrust_executor = thrust_executor
5
6
  @out = out
6
-
7
- if ENV['ANDROID_HOME'].nil?
8
- if File.directory?('/usr/local/opt/android-sdk')
9
- @out.puts 'Setting /usr/local/opt/android-sdk as ANDROID_HOME...'.magenta
10
- ENV['ANDROID_HOME'] = '/usr/local/opt/android-sdk'
11
- else
12
- raise('**********Android is not installed. Run `brew install android`.**********')
13
- end
14
- end
15
7
  end
16
8
 
17
9
  def change_build_number(version_code, version_name)
18
- Thrust::Executor.system_or_exit(
10
+ @thrust_executor.system_or_exit(
19
11
  "sed -i ''" +
20
12
  " -e 's/android:versionCode=\"[0-9]*\"/android:versionCode=\"#{version_code}\"/'" +
21
13
  " -e 's/android:versionName=\"\\([^ \"]*\\)[^\"]*\"/android:versionName=\"\\1 (#{version_name})\"/'" +
22
14
  " AndroidManifest.xml")
23
- Thrust::Executor.system_or_exit(
15
+ @thrust_executor.system_or_exit(
24
16
  "sed -i ''" +
25
17
  " '1,/<version>/s/<version>\\([^- <]*\\)[^<]*<\\/version>/<version>\\1 (#{version_name})<\\/version>/'" +
26
18
  " pom.xml")
27
19
  end
28
20
 
29
21
  def build_signed_release
30
- Thrust::Executor.system_or_exit('mvn clean package -Prelease')
22
+ verify_android_installed!
23
+ @thrust_executor.system_or_exit('mvn clean package -Prelease')
31
24
  Dir.glob('target/*-signed-aligned.apk').first or raise 'Signed APK was not generated'
32
25
  end
26
+
27
+ private
28
+
29
+ def verify_android_installed!
30
+ if ENV['ANDROID_HOME'].nil?
31
+ if File.directory?('/usr/local/opt/android-sdk')
32
+ @out.puts 'Setting /usr/local/opt/android-sdk as ANDROID_HOME...'.magenta
33
+ ENV['ANDROID_HOME'] = '/usr/local/opt/android-sdk'
34
+ else
35
+ raise('**********Android is not installed. Run `brew install android`.**********')
36
+ end
37
+ end
38
+ end
33
39
  end
data/lib/thrust/config.rb CHANGED
@@ -2,7 +2,7 @@ require 'colorize'
2
2
 
3
3
  class Thrust::Config
4
4
  attr_reader :project_root, :app_config, :build_dir
5
- THRUST_VERSION = 0.2
5
+ THRUST_VERSION = 0.3
6
6
  THRUST_ROOT = File.expand_path('../..', __FILE__)
7
7
 
8
8
  def self.make(relative_project_root, config_file)
@@ -1,22 +1,24 @@
1
- module Thrust::Executor
2
- def self.system_or_exit(cmd, output_file = nil)
3
- self.system(cmd, output_file) or raise '******** Build failed ********'
1
+ class Thrust::Executor
2
+ CommandFailed = Class.new(StandardError)
3
+
4
+ def system_or_exit(cmd, output_file = nil)
5
+ system(cmd, output_file) or raise(CommandFailed, '******** Build failed ********')
4
6
  end
5
7
 
6
- def self.system(cmd, output_file = nil)
8
+ def system(cmd, output_file = nil)
7
9
  STDERR.puts "Executing #{cmd}"
8
10
  cmd += " > #{output_file}" if output_file
9
11
  Kernel::system(cmd)
10
12
  end
11
13
 
12
- def self.capture_output_from_system(cmd)
14
+ def capture_output_from_system(cmd)
13
15
  captured_output = `#{cmd}`
14
- raise '******** Build failed ********' if $?.exitstatus > 0
16
+ raise(CommandFailed, '******** Build failed ********') if $?.exitstatus > 0
15
17
 
16
18
  captured_output
17
19
  end
18
20
 
19
- def self.check_command_for_failure(cmd)
21
+ def check_command_for_failure(cmd)
20
22
  STDERR.puts "Executing #{cmd} and checking for FAILURE"
21
23
  result = %x[#{cmd} 2>&1]
22
24
  STDERR.puts "Results:"
data/lib/thrust/git.rb CHANGED
@@ -1,7 +1,8 @@
1
1
  require 'colorize'
2
2
 
3
3
  class Thrust::Git
4
- def initialize(out)
4
+ def initialize(thrust_executor, out)
5
+ @thrust_executor = thrust_executor
5
6
  @out = out
6
7
  end
7
8
 
@@ -10,20 +11,20 @@ class Thrust::Git
10
11
  @out.puts 'WARNING NOT CHECKING FOR CLEAN WORKING DIRECTORY'.red
11
12
  else
12
13
  @out.puts 'Checking for clean working tree...'
13
- Thrust::Executor.system_or_exit 'git diff-index --quiet HEAD'
14
+ @thrust_executor.system_or_exit 'git diff-index --quiet HEAD'
14
15
  end
15
16
  end
16
17
 
17
18
  def current_commit
18
- Thrust::Executor.capture_output_from_system('git log --format=format:%h -1').strip
19
+ @thrust_executor.capture_output_from_system('git log --format=format:%h -1').strip
19
20
  end
20
21
 
21
22
  def reset
22
- Thrust::Executor.system_or_exit('git reset --hard')
23
+ @thrust_executor.system_or_exit('git reset --hard')
23
24
  end
24
25
 
25
26
  def checkout_file(filename)
26
- Thrust::Executor.system_or_exit("git checkout #{filename}")
27
+ @thrust_executor.system_or_exit("git checkout #{filename}")
27
28
  end
28
29
 
29
30
  def commit_summary_for_last_deploy(deployment_target)
@@ -36,13 +37,13 @@ class Thrust::Git
36
37
  end
37
38
 
38
39
  def generate_notes_for_deployment(deployment_target)
39
- sha_of_latest_commit = Thrust::Executor.capture_output_from_system('git rev-parse HEAD').strip
40
+ sha_of_latest_commit = @thrust_executor.capture_output_from_system('git rev-parse HEAD').strip
40
41
  sha_of_latest_deployed_commit = latest_deployed_commit(deployment_target)
41
42
 
42
43
  notes = Tempfile.new('deployment_notes')
43
44
 
44
45
  if sha_of_latest_deployed_commit
45
- Thrust::Executor.system_or_exit("git log --oneline #{sha_of_latest_deployed_commit}...#{sha_of_latest_commit}", notes.path)
46
+ @thrust_executor.system_or_exit("git log --oneline #{sha_of_latest_deployed_commit}...#{sha_of_latest_commit}", notes.path)
46
47
  else
47
48
  notes.puts(summary_for_commit(sha_of_latest_commit))
48
49
  notes.close
@@ -54,11 +55,11 @@ class Thrust::Git
54
55
  private
55
56
 
56
57
  def summary_for_commit(sha)
57
- Thrust::Executor.capture_output_from_system("git log --oneline -n 1 #{sha}")
58
+ @thrust_executor.capture_output_from_system("git log --oneline -n 1 #{sha}")
58
59
  end
59
60
 
60
61
  def latest_deployed_commit(deployment_target)
61
- list = Thrust::Executor.capture_output_from_system("autotag list #{deployment_target}")
62
+ list = @thrust_executor.capture_output_from_system("autotag list #{deployment_target}")
62
63
  unless list.strip.empty?
63
64
  list.split("\n").last.split(" ").first
64
65
  end
@@ -0,0 +1,13 @@
1
+ class Thrust::IOS::AgvTool
2
+
3
+ def initialize(thrust_executor, out)
4
+ @thrust_executor = thrust_executor
5
+ @out = out
6
+ @git = Thrust::Git.new(@thrust_executor, @out)
7
+ end
8
+
9
+ def change_build_number(build_number)
10
+ @thrust_executor.system_or_exit "agvtool new-version -all '#{build_number}'"
11
+ @git.checkout_file('*.xcodeproj')
12
+ end
13
+ end
@@ -1,17 +1,21 @@
1
1
  class Thrust::IOS::Cedar
2
2
 
3
- def self.run(out, build_configuration, target, runtime_sdk, build_sdk, device, build_dir, simulator_binary)
3
+ def initialize(thrust_executor = Thrust::Executor.new)
4
+ @thrust_executor = thrust_executor
5
+ end
6
+
7
+ def run(out, build_configuration, target, runtime_sdk, build_sdk, device, build_dir, simulator_binary)
4
8
  if build_sdk == 'macosx'
5
9
  build_path = File.join(build_dir, build_configuration)
6
10
  app_dir = File.join(build_path, target)
7
- Thrust::Executor.check_command_for_failure("DYLD_FRAMEWORK_PATH=#{build_path.inspect} #{app_dir}")
11
+ @thrust_executor.check_command_for_failure("DYLD_FRAMEWORK_PATH=#{build_path.inspect} #{app_dir}")
8
12
  else
9
13
  app_executable = File.join(build_dir, "#{build_configuration}-#{build_sdk}", "#{target}.app")
10
14
 
11
15
  if simulator_binary =~ /waxim%/
12
- Thrust::Executor.check_command_for_failure(%Q[#{simulator_binary} -s #{runtime_sdk} -f #{device} -e CFFIXED_USER_HOME=#{Dir.tmpdir} -e CEDAR_HEADLESS_SPECS=1 -e CEDAR_REPORTER_CLASS=CDRDefaultReporter #{app_executable}])
16
+ @thrust_executor.check_command_for_failure(%Q[#{simulator_binary} -s #{runtime_sdk} -f #{device} -e CFFIXED_USER_HOME=#{Dir.tmpdir} -e CEDAR_HEADLESS_SPECS=1 -e CEDAR_REPORTER_CLASS=CDRDefaultReporter #{app_executable}])
13
17
  elsif simulator_binary =~ /ios-sim$/
14
- Thrust::Executor.check_command_for_failure(%Q[#{simulator_binary} launch #{app_executable} --sdk #{runtime_sdk} --family #{device} --retina --tall --setenv CFFIXED_USER_HOME=#{Dir.tmpdir} --setenv CEDAR_HEADLESS_SPECS=1 --setenv CEDAR_REPORTER_CLASS=CDRDefaultReporter])
18
+ @thrust_executor.check_command_for_failure(%Q[#{simulator_binary} launch #{app_executable} --sdk #{runtime_sdk} --family #{device} --retina --tall --setenv CFFIXED_USER_HOME=#{Dir.tmpdir} --setenv CEDAR_HEADLESS_SPECS=1 --setenv CEDAR_REPORTER_CLASS=CDRDefaultReporter])
15
19
  else
16
20
  out.puts "Unknown binary for running specs: '#{simulator_binary}'"
17
21
  false
@@ -1,17 +1,8 @@
1
1
  class Thrust::IOS::Deploy
2
- def self.make(thrust_config, deployment_config, deployment_target)
3
- build_configuration = deployment_config['ios_build_configuration']
4
- x_code_tools = Thrust::IOS::XCodeTools.new($stdout, build_configuration, thrust_config.build_dir, thrust_config.app_config['project_name'])
5
- git = Thrust::Git.new($stdout)
6
- testflight_config = thrust_config.app_config['testflight']
7
- testflight = Thrust::Testflight.new($stdout, $stdin, testflight_config['api_token'], testflight_config['team_token'])
8
-
9
- new($stdout, x_code_tools, git, testflight, thrust_config, deployment_config, deployment_target)
10
- end
11
-
12
- def initialize(out, x_code_tools, git, testflight, thrust_config, deployment_config, deployment_target)
2
+ def initialize(out, x_code_tools, agv_tool, git, testflight, thrust_config, deployment_config, deployment_target)
13
3
  @out = out
14
4
  @x_code_tools = x_code_tools
5
+ @agv_tool = agv_tool
15
6
  @git = git
16
7
  @testflight = testflight
17
8
  @thrust_config = thrust_config
@@ -21,7 +12,7 @@ class Thrust::IOS::Deploy
21
12
 
22
13
  def run
23
14
  @git.ensure_clean
24
- @x_code_tools.change_build_number(@git.current_commit)
15
+ @agv_tool.change_build_number(@git.current_commit)
25
16
 
26
17
  app_name = @thrust_config.app_config['app_name']
27
18
  target = @deployment_config['ios_target'] || app_name
@@ -0,0 +1,15 @@
1
+ class Thrust::IOS::DeployProvider
2
+ def instance(thrust_config, deployment_config, deployment_target)
3
+ stdout = $stdout
4
+ thrust_executor = Thrust::Executor.new
5
+ build_configuration = deployment_config['ios_build_configuration']
6
+ tools_options = { project_name: thrust_config.app_config['project_name'], workspace_name: thrust_config.app_config['workspace_name'] }
7
+ x_code_tools = Thrust::IOS::XCodeToolsProvider.new.instance(stdout, build_configuration, thrust_config.build_dir, tools_options)
8
+ agv_tool = Thrust::IOS::AgvTool.new(thrust_executor, stdout)
9
+ git = Thrust::Git.new(thrust_executor, stdout)
10
+ testflight_config = thrust_config.app_config['testflight']
11
+ testflight = Thrust::Testflight.new(thrust_executor, stdout, $stdin, testflight_config['api_token'], testflight_config['team_token'])
12
+
13
+ Thrust::IOS::Deploy.new(stdout, x_code_tools, agv_tool, git, testflight, thrust_config, deployment_config, deployment_target)
14
+ end
15
+ end
@@ -1,33 +1,21 @@
1
1
  class Thrust::IOS::XCodeTools
2
2
  ProvisioningProfileNotFound = Class.new(StandardError)
3
3
 
4
- def self.build_configurations(project_name) #TODO: Backfill a test
5
- output = Thrust::Executor.capture_output_from_system("xcodebuild -project #{project_name}.xcodeproj -list")
6
- match = /Build Configurations:(.+?)\n\n/m.match(output)
7
- if match
8
- match[1].strip.split("\n").map { |line| line.strip }
9
- else
10
- []
11
- end
12
- end
13
-
14
- def initialize(out, build_configuration, build_directory, project_name)
4
+ def initialize(thrust_executor, out, build_configuration, build_directory, options = {})
5
+ @thrust_executor = thrust_executor
15
6
  @out = out
16
- @git = Thrust::Git.new(out)
7
+ @git = Thrust::Git.new(@thrust_executor, @out)
17
8
  @build_configuration = build_configuration
18
9
  @build_directory = build_directory
19
- @project_name = project_name
20
- end
21
-
22
- def change_build_number(build_number)
23
- Thrust::Executor.system_or_exit "agvtool new-version -all '#{build_number}'"
24
- @git.checkout_file('*.xcodeproj')
10
+ @project_name = options[:project_name]
11
+ @workspace_name = options[:workspace_name]
12
+ raise "project_name OR workspace_name required" unless @project_name.nil? ^ @workspace_name.nil?
25
13
  end
26
14
 
27
15
  def cleanly_create_ipa(target, app_name, signing_identity, provision_search_query = nil)
28
16
  clean_build
29
17
  kill_simulator
30
- build_target(target, 'iphoneos')
18
+ build_scheme_or_target(target, 'iphoneos')
31
19
  create_ipa(app_name, signing_identity, provision_search_query)
32
20
  end
33
21
 
@@ -37,27 +25,21 @@ class Thrust::IOS::XCodeTools
37
25
 
38
26
  def clean_build
39
27
  @out.puts 'Cleaning...'
40
- run_xcode('clean')
41
- FileUtils.rm_rf(build_configuration_directory)
28
+ FileUtils.rm_rf(@build_directory)
42
29
  end
43
30
 
44
- def clean_and_build_target(target, build_sdk)
45
- clean_build
46
- build_target(target, build_sdk)
31
+ def build_scheme_or_target(scheme_or_target, build_sdk, architecture=nil)
32
+ @out.puts "Building..."
33
+ run_xcode('build', build_sdk, scheme_or_target, architecture)
47
34
  end
48
35
 
49
36
  private
50
37
 
51
- def build_target(target, build_sdk)
52
- @out.puts "Building..."
53
- run_xcode('build', build_sdk, target)
54
- end
55
-
56
38
  def kill_simulator
57
39
  @out.puts('Killing simulator...')
58
- Thrust::Executor.system %q[killall -m -KILL "gdb"]
59
- Thrust::Executor.system %q[killall -m -KILL "otest"]
60
- Thrust::Executor.system %q[killall -m -KILL "iPhone Simulator"]
40
+ @thrust_executor.system %q[killall -m -KILL "gdb"]
41
+ @thrust_executor.system %q[killall -m -KILL "otest"]
42
+ @thrust_executor.system %q[killall -m -KILL "iPhone Simulator"]
61
43
  end
62
44
 
63
45
  def provision_path(provision_search_query)
@@ -79,30 +61,37 @@ class Thrust::IOS::XCodeTools
79
61
  "--sign '#{signing_identity}'",
80
62
  "--embed '#{provision_path(provision_search_query)}'"
81
63
  ].join(' ')
82
- Thrust::Executor.system_or_exit(cmd)
64
+ @thrust_executor.system_or_exit(cmd)
83
65
  ipa_filename
84
66
  end
85
67
 
86
-
87
- def run_xcode(build_command, sdk = nil, target = nil)
88
- target_flag = target ? "-target #{target}" : "-alltargets"
89
- sdk_flag = sdk ? "-sdk #{sdk}" : ''
90
-
91
- Thrust::Executor.system_or_exit(
92
- [
93
- 'set -o pipefail &&',
94
- 'xcodebuild',
95
- "-project #{@project_name}.xcodeproj",
96
- target_flag,
97
- "-configuration #{@build_configuration}",
98
- sdk_flag,
99
- "#{build_command}",
100
- "SYMROOT=#{@build_directory.inspect}",
101
- '2>&1',
102
- "| grep -v 'backing file'"
103
- ].join(' '),
104
- output_file("#{@build_configuration}-#{build_command}")
105
- )
68
+ def run_xcode(build_command, sdk = nil, scheme_or_target = nil, architecture=nil)
69
+ architecture_flag = architecture ? "-arch #{architecture}" : nil
70
+ target_flag = @workspace_name ? "-scheme \"#{scheme_or_target}\"" : "-target \"#{scheme_or_target}\""
71
+ sdk_flag = sdk ? "-sdk #{sdk}" : nil
72
+ configuration_build_dir = File.join(@build_directory, "#{@build_configuration}-#{sdk}")
73
+
74
+ command = [
75
+ 'set -o pipefail &&',
76
+ 'xcodebuild',
77
+ project_or_workspace_flag,
78
+ architecture_flag,
79
+ target_flag,
80
+ "-configuration #{@build_configuration}",
81
+ sdk_flag,
82
+ "#{build_command}",
83
+ "SYMROOT=#{@build_directory.inspect}",
84
+ "CONFIGURATION_BUILD_DIR=#{configuration_build_dir.inspect}",
85
+ '2>&1',
86
+ "| grep -v 'backing file'"
87
+ ].compact.join(' ')
88
+ output_file = output_file("#{@build_configuration}-#{build_command}")
89
+ begin
90
+ @thrust_executor.system_or_exit(command, output_file)
91
+ rescue Thrust::Executor::CommandFailed => e
92
+ @out.write File.read(output_file)
93
+ raise e
94
+ end
106
95
  end
107
96
 
108
97
  def output_file(target)
@@ -114,4 +103,8 @@ class Thrust::IOS::XCodeTools
114
103
 
115
104
  File.join(output_dir, "#{target}.output").tap { |file| @out.puts "Output: #{file}" }
116
105
  end
106
+
107
+ def project_or_workspace_flag
108
+ @workspace_name ? "-workspace #{@workspace_name}.xcworkspace" : "-project #{@project_name}.xcodeproj"
109
+ end
117
110
  end
@@ -0,0 +1,10 @@
1
+ class Thrust::IOS::XCodeToolsProvider
2
+
3
+ def initialize(thrust_executor = Thrust::Executor.new)
4
+ @thrust_executor = thrust_executor
5
+ end
6
+
7
+ def instance(out, build_configuration, build_directory, options)
8
+ Thrust::IOS::XCodeTools.new(@thrust_executor, out, build_configuration, build_directory, options)
9
+ end
10
+ end
data/lib/thrust/tasks.rb CHANGED
@@ -1,3 +1,3 @@
1
- Dir[File.expand_path("../../tasks/*.rake", __FILE__)].each do |file|
2
- load file
3
- end
1
+ load File.expand_path("../../tasks/cedar.rake", __FILE__) unless File.exists?('AndroidManifest.xml')
2
+ load File.expand_path("../../tasks/testflight.rake", __FILE__)
3
+ load File.expand_path("../../tasks/version.rake", __FILE__)
@@ -1,8 +1,9 @@
1
1
  class Thrust::Testflight
2
- def initialize(out, input, api_token, team_token)
2
+ def initialize(thrust_executor, out, input, api_token, team_token)
3
+ @thrust_executor = thrust_executor
3
4
  @out = out
4
5
  @in = input
5
- @git = Thrust::Git.new(@out)
6
+ @git = Thrust::Git.new(@thrust_executor, @out)
6
7
  @api_token = api_token
7
8
  @team_token = team_token
8
9
  end
@@ -11,7 +12,7 @@ class Thrust::Testflight
11
12
  if dsym_path
12
13
  @out.puts 'Zipping dSYM...'
13
14
  zipped_dsym_path = "#{dsym_path}.zip"
14
- Thrust::Executor.system_or_exit "zip -r -T -y '#{zipped_dsym_path}' '#{dsym_path}'"
15
+ @thrust_executor.system_or_exit "zip -r -T -y '#{zipped_dsym_path}' '#{dsym_path}'"
15
16
  @out.puts 'Done!'
16
17
  end
17
18
 
@@ -22,7 +23,7 @@ class Thrust::Testflight
22
23
  end
23
24
 
24
25
 
25
- Thrust::Executor.system_or_exit [
26
+ @thrust_executor.system_or_exit [
26
27
  'curl http://testflightapp.com/api/builds.json',
27
28
  "-F file=@#{package_file}",
28
29
  ("-F dsym=@#{zipped_dsym_path}" if dsym_path),
data/lib/thrust.rb CHANGED
@@ -9,8 +9,12 @@ require 'thrust/testflight'
9
9
  require 'thrust/user_prompt'
10
10
 
11
11
  require 'thrust/android/deploy'
12
+ require 'thrust/android/deploy_provider'
12
13
  require 'thrust/android/tools'
13
14
 
15
+ require 'thrust/ios/agv_tool'
14
16
  require 'thrust/ios/cedar'
15
17
  require 'thrust/ios/deploy'
18
+ require 'thrust/ios/deploy_provider'
16
19
  require 'thrust/ios/x_code_tools'
20
+ require 'thrust/ios/x_code_tools_provider'
metadata CHANGED
@@ -1,25 +1,26 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: thrust
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
- - Michael McCormick
8
- - Johnathon Britz
9
- - Jonathan Barnes
7
+ - Aaron Levine
8
+ - Aaron VonderHaar
9
+ - Andrew Bruce
10
10
  - Andrew Kitchen
11
- - Tyler Schultz
12
- - Wiley Kestner
13
11
  - Brandon Liu
12
+ - Can Berk Güder
13
+ - Eugenia Dellapenna
14
14
  - Jeff Hui
15
+ - Johnathon Britz
16
+ - Jonathan Barnes
17
+ - Michael McCormick
18
+ - Molly Trombley-McCann
15
19
  - Philip Kuryloski
16
- - Andrew Bruce
17
- - Aaron Levine
18
- - Eugenia Dellapenna
19
- - Aaron VonderHaar
20
- - Sheel Choksi
21
20
  - Rachel Bobbins
22
- - Molly Trombley-McCann
21
+ - Sheel Choksi
22
+ - Tyler Schultz
23
+ - Wiley Kestner
23
24
  autorequire:
24
25
  bindir: bin
25
26
  cert_chain: []
@@ -119,18 +120,24 @@ extensions: []
119
120
  extra_rdoc_files: []
120
121
  files:
121
122
  - bin/thrust
122
- - lib/config/example.yml
123
+ - lib/config/android_example.yml
124
+ - lib/config/ios_example.yml
123
125
  - lib/tasks/cedar.rake
124
126
  - lib/tasks/testflight.rake
127
+ - lib/tasks/version.rake
125
128
  - lib/thrust.rb
126
129
  - lib/thrust/android/deploy.rb
130
+ - lib/thrust/android/deploy_provider.rb
127
131
  - lib/thrust/android/tools.rb
128
132
  - lib/thrust/config.rb
129
133
  - lib/thrust/executor.rb
130
134
  - lib/thrust/git.rb
135
+ - lib/thrust/ios/agv_tool.rb
131
136
  - lib/thrust/ios/cedar.rb
132
137
  - lib/thrust/ios/deploy.rb
138
+ - lib/thrust/ios/deploy_provider.rb
133
139
  - lib/thrust/ios/x_code_tools.rb
140
+ - lib/thrust/ios/x_code_tools_provider.rb
134
141
  - lib/thrust/tasks.rb
135
142
  - lib/thrust/testflight.rb
136
143
  - lib/thrust/user_prompt.rb
@@ -154,7 +161,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
154
161
  version: '0'
155
162
  requirements: []
156
163
  rubyforge_project:
157
- rubygems_version: 2.2.1
164
+ rubygems_version: 2.2.2
158
165
  signing_key:
159
166
  specification_version: 4
160
167
  summary: Thrust is a collection of rake tasks for iOS/Android development and deployment
@@ -1,36 +0,0 @@
1
- thrust_version: 0.2
2
- project_name: My Great Project
3
- app_name: My Great App
4
- ios_distribution_certificate: 'Name of Distribution Signing Certificate'
5
- ios_sim_binary: 'ios-sim' # or wax-sim. iOS only.
6
-
7
- testflight:
8
- api_token: 'testflight api token'
9
- team_token: 'testflight team token'
10
-
11
- deployment_targets:
12
- staging:
13
- distribution_list: Developers
14
- notify: true
15
- note_generation_method: autotag # If you set this value, it will auto-generate the deploy notes from the commit history. Optional.
16
- ios_target: MyGreatAppTarget # Name of the build target. Optional, defaults to app name. iOS only.
17
- ios_build_configuration: Release # iOS only
18
- ios_provisioning_search_query: 'query to find Provisioning Profile' # iOS only. Optional.
19
-
20
- demo:
21
- distribution_list: Beta Testers
22
- notify: true
23
-
24
- ios_spec_targets:
25
- specs:
26
- target: UISpecs # name of the build target
27
- build_configuration: Debug # name of the build configuration
28
- build_sdk: 6.1 # SDK used to build the target. Optional, defaults to iphonesimulator.
29
- runtime_sdk: 7.0 # SDK used to run the target. Not optional.
30
- device: ipad # Device to run the specs on. Optional, defaults to iPhone.
31
-
32
- integration:
33
- target: IntegrationSpecs
34
- build_configuration: Release
35
- build_sdk: macosx
36
- runtime_sdk: macosx