thrust 0.2.0 → 0.3.1

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.
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