boxci 0.0.30

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.ruby-version +1 -0
  4. data/CHANGELOG.md +146 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +118 -0
  8. data/Rakefile +13 -0
  9. data/bin/boxci +6 -0
  10. data/boxci.gemspec +28 -0
  11. data/lib/boxci/builder.rb +29 -0
  12. data/lib/boxci/cli.rb +70 -0
  13. data/lib/boxci/config_permutation.rb +15 -0
  14. data/lib/boxci/config_permutation_component.rb +11 -0
  15. data/lib/boxci/config_permutation_component_factory.rb +7 -0
  16. data/lib/boxci/config_permutation_components/rbenv.rb +13 -0
  17. data/lib/boxci/dependency_checker.rb +55 -0
  18. data/lib/boxci/global_config.rb +26 -0
  19. data/lib/boxci/initializer.rb +41 -0
  20. data/lib/boxci/language.rb +35 -0
  21. data/lib/boxci/language_factory.rb +7 -0
  22. data/lib/boxci/languages/ruby.rb +31 -0
  23. data/lib/boxci/project_config.rb +96 -0
  24. data/lib/boxci/provider.rb +35 -0
  25. data/lib/boxci/provider_config.rb +23 -0
  26. data/lib/boxci/provider_factory.rb +7 -0
  27. data/lib/boxci/providers/aws.rb +27 -0
  28. data/lib/boxci/providers/openstack.rb +27 -0
  29. data/lib/boxci/providers/virtualbox.rb +24 -0
  30. data/lib/boxci/templates/Vagrantfile +41 -0
  31. data/lib/boxci/templates/boxci/global_config.yml.tt +1 -0
  32. data/lib/boxci/templates/dot_boxci.yml.tt +11 -0
  33. data/lib/boxci/templates/languages/ruby/main.pp +27 -0
  34. data/lib/boxci/templates/providers/aws/Vagrantfile.erb +45 -0
  35. data/lib/boxci/templates/providers/aws.yml.tt +5 -0
  36. data/lib/boxci/templates/providers/openstack/Vagrantfile.erb +37 -0
  37. data/lib/boxci/templates/providers/openstack.yml.tt +16 -0
  38. data/lib/boxci/templates/providers/virtualbox/Vagrantfile.erb +47 -0
  39. data/lib/boxci/templates/providers/virtualbox.yml.tt +2 -0
  40. data/lib/boxci/templates/puppet/manifests/.empty_directory +0 -0
  41. data/lib/boxci/templates/puppet/modules/.empty_directory +0 -0
  42. data/lib/boxci/test_runner.rb +134 -0
  43. data/lib/boxci/tester.rb +287 -0
  44. data/lib/boxci/version.rb +3 -0
  45. data/lib/boxci.rb +71 -0
  46. data/spec/lib/boxci/builder_spec.rb +86 -0
  47. data/spec/lib/boxci/config_permutation_component_factory_spec.rb +17 -0
  48. data/spec/lib/boxci/config_permutation_component_spec.rb +19 -0
  49. data/spec/lib/boxci/config_permutation_components/rbenv_spec.rb +12 -0
  50. data/spec/lib/boxci/config_permutation_spec.rb +27 -0
  51. data/spec/lib/boxci/dependency_checker_spec.rb +215 -0
  52. data/spec/lib/boxci/global_config_spec.rb +34 -0
  53. data/spec/lib/boxci/initializer_spec.rb +117 -0
  54. data/spec/lib/boxci/language_factory_spec.rb +17 -0
  55. data/spec/lib/boxci/language_spec.rb +31 -0
  56. data/spec/lib/boxci/project_config_spec.rb +218 -0
  57. data/spec/lib/boxci/provider_config_spec.rb +39 -0
  58. data/spec/lib/boxci/provider_factory_spec.rb +17 -0
  59. data/spec/lib/boxci/provider_spec.rb +30 -0
  60. data/spec/lib/boxci/tester_spec.rb +15 -0
  61. data/spec/lib/boxci_spec.rb +176 -0
  62. data/spec/spec_helper.rb +11 -0
  63. metadata +213 -0
@@ -0,0 +1,7 @@
1
+ module Boxci
2
+ module LanguageFactory
3
+ def self.build(language)
4
+ Boxci::Languages.const_get(language.capitalize).new
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,31 @@
1
+ module Boxci
2
+ module Languages
3
+ class Ruby < ::Boxci::Language
4
+
5
+ no_commands do
6
+ def default_script
7
+ %q{bundle exec rake}
8
+ end
9
+
10
+ def before_permutation_switch
11
+ %q{export RAILS_ENV=test}
12
+ end
13
+
14
+ def after_permutation_switch
15
+ %q{gem install bundler && bundle install --without production}
16
+ end
17
+
18
+ def generate_starter_puppet_manifest
19
+ @project_config = Boxci.project_config
20
+ if @project_config.rbenv
21
+ inside Boxci.project_path do
22
+ run "git submodule add -f git@github.com:alup/puppet-rbenv.git puppet/modules/rbenv"
23
+ run "git submodule update --init"
24
+ end
25
+ end
26
+ template "templates/languages/#{Boxci.project_config.language}/main.pp", File.join(Boxci.project_path, "puppet/manifests/main.pp")
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,96 @@
1
+ module Boxci
2
+ class ProjectConfig
3
+ def initialize
4
+ @project_config = { 'language' => 'ruby', 'box_size' => 'small', 'artifact_path' => '/tmp/boxci/artifacts' }
5
+ end
6
+
7
+ def load
8
+ @project_config.merge! read_project_config_hash
9
+ end
10
+
11
+ def rbenv
12
+ @project_config['rbenv']
13
+ end
14
+
15
+ def language
16
+ @project_config['language']
17
+ end
18
+
19
+ def puppet_facts
20
+ return [] unless @project_config['puppet_facts']
21
+ @project_config['puppet_facts']
22
+ end
23
+
24
+ def box_size
25
+ @project_config['box_size']
26
+ end
27
+
28
+ def artifact_path
29
+ @project_config['artifact_path']
30
+ end
31
+
32
+ # Test Runner Hooks
33
+ def before_install
34
+ return [] unless @project_config['before_install']
35
+ option_as_array("before_install")
36
+ end
37
+
38
+ def install
39
+ return [] unless @project_config['install']
40
+ option_as_array("install")
41
+ end
42
+
43
+ def before_script
44
+ return [] unless @project_config['before_script']
45
+ option_as_array("before_script")
46
+ end
47
+
48
+ def script
49
+ return [] unless @project_config['script']
50
+ option_as_array("script")
51
+ end
52
+
53
+ def after_failure
54
+ return [] unless @project_config['after_failure']
55
+ option_as_array("after_failure")
56
+ end
57
+
58
+ def after_success
59
+ return [] unless @project_config['after_success']
60
+ option_as_array("after_success")
61
+ end
62
+
63
+ def after_script
64
+ return [] unless @project_config['after_script']
65
+ option_as_array("after_script")
66
+ end
67
+
68
+ def permutations
69
+ # permutations_of_components = [rbenv_components].inject(&:product).map(&:flatten)
70
+ if rbenv.nil? || rbenv.empty?
71
+ return nil
72
+ else
73
+ perms = []
74
+ rbenv.each do |ver|
75
+ perms << Boxci::ConfigPermutation.new([Boxci::ConfigPermutationComponentFactory.build('rbenv', ver)])
76
+ end
77
+ return perms
78
+ end
79
+ end
80
+
81
+ private
82
+
83
+ def option_as_array(key)
84
+ if @project_config[key].is_a?(Array)
85
+ @project_config[key]
86
+ else
87
+ [@project_config[key]]
88
+ end
89
+ end
90
+
91
+ def read_project_config_hash
92
+ project_config_path = File.join(Boxci.project_path, ".boxci.yml")
93
+ return YAML::load_file(project_config_path)
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,35 @@
1
+ module Boxci
2
+ class Provider < Thor
3
+ include Thor::Actions
4
+
5
+ no_commands do
6
+ def self.source_root
7
+ File.dirname(__FILE__)
8
+ end
9
+
10
+ def self.supported_providers
11
+ @@supported_providers ||= []
12
+ end
13
+
14
+ def self.inherited(subclass)
15
+ self.supported_providers << subclass.to_s.split('::').last.downcase
16
+ end
17
+
18
+ def generate_provider_vagrantfile
19
+ raise ::Boxci::PureVirtualMethod, "'generate_provider_vagrantfile' must be implemented on Boxci::Provider classes"
20
+ end
21
+
22
+ def requires_plugin?
23
+ raise ::Boxci::PureVirtualMethod, "'requires_plugin?' must be implemented on Boxci::Provider classes"
24
+ end
25
+
26
+ def plugin
27
+ raise ::Boxci::PureVirtualMethod, "'plugin' must be implemented on Boxci::Provider classes"
28
+ end
29
+
30
+ def dummy_box_url
31
+ raise ::Boxci::PureVirtualMethod, "'plugin' must be implemented on Boxci::Provider classes"
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,23 @@
1
+ module Boxci
2
+ class ProviderConfig
3
+ def initialize(provider)
4
+ @provider = provider
5
+ @provider_config = {}
6
+ end
7
+
8
+ def load
9
+ @provider_config.merge!(read_provider_config_hash)
10
+ end
11
+
12
+ def fetch(key)
13
+ @provider_config.fetch(key.to_s)
14
+ end
15
+
16
+ private
17
+
18
+ def read_provider_config_hash
19
+ provider_config_path = File.join(ENV['HOME'], "/.boxci/providers/#{@provider}.yml")
20
+ provider_config = YAML::load_file(provider_config_path)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,7 @@
1
+ module Boxci
2
+ module ProviderFactory
3
+ def self.build(provider)
4
+ Boxci::Providers.const_get(provider.capitalize).new
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,27 @@
1
+ module Boxci
2
+ module Providers
3
+ class Aws < ::Boxci::Provider
4
+ PLUGIN = {
5
+ name: "vagrant-aws",
6
+ dummy_box_url: "https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box"
7
+ }
8
+
9
+ no_commands do
10
+ def generate_provider_vagrantfile
11
+ end
12
+
13
+ def requires_plugin?
14
+ true
15
+ end
16
+
17
+ def plugin
18
+ PLUGIN[:name]
19
+ end
20
+
21
+ def dummy_box_url
22
+ PLUGIN[:dummy_box_url]
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ module Boxci
2
+ module Providers
3
+ class Openstack < ::Boxci::Provider
4
+ PLUGIN = {
5
+ name: "vagrant-openstack-plugin",
6
+ dummy_box_url: "https://github.com/cloudbau/vagrant-openstack-plugin/raw/master/dummy.box"
7
+ }
8
+
9
+ no_commands do
10
+ def generate_provider_vagrantfile
11
+ end
12
+
13
+ def requires_plugin?
14
+ true
15
+ end
16
+
17
+ def plugin
18
+ PLUGIN[:name]
19
+ end
20
+
21
+ def dummy_box_url
22
+ PLUGIN[:dummy_box_url]
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,24 @@
1
+ module Boxci
2
+ module Providers
3
+ class Virtualbox < ::Boxci::Provider
4
+ PLUGIN = {}
5
+
6
+ no_commands do
7
+ def generate_provider_vagrantfile
8
+ end
9
+
10
+ def requires_plugin?
11
+ false
12
+ end
13
+
14
+ def plugin
15
+ PLUGIN[:name]
16
+ end
17
+
18
+ def dummy_box_url
19
+ PLUGIN[:dummy_box_url]
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,41 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ # Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
5
+ VAGRANTFILE_API_VERSION = "2"
6
+
7
+ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
8
+ config.vm.box = "precise64"
9
+ config.vm.box_url = "http://files.vagrantup.com/precise64.box"
10
+
11
+ config.vm.provider :virtualbox do |vb|
12
+ <% if @project_config.box_size == 'tiny' %>
13
+ vb.customize ["modifyvm", :id, "--memory", "512"]
14
+ <% elsif @project_config.box_size == 'small' %>
15
+ vb.customize ["modifyvm", :id, "--memory", "2048"]
16
+ <% elsif @project_config.box_size == 'medium' %>
17
+ vb.customize ["modifyvm", :id, "--memory", "4096"]
18
+ vb.customize ["modifyvm", :id, "--cpus", "2"]
19
+ vb.customize ["modifyvm", :id, "--ioapic", "on"]
20
+ <% elsif @project_config.box_size == 'large' %>
21
+ vb.customize ["modifyvm", :id, "--memory", "8192"]
22
+ vb.customize ["modifyvm", :id, "--cpus", "4"]
23
+ vb.customize ["modifyvm", :id, "--ioapic", "on"]
24
+ <% elsif @project_config.box_size == 'xlarge' %>
25
+ vb.customize ["modifyvm", :id, "--memory", "16384"]
26
+ vb.customize ["modifyvm", :id, "--cpus", "8"]
27
+ vb.customize ["modifyvm", :id, "--ioapic", "on"]
28
+ <% end %>
29
+ end
30
+
31
+ config.vm.provision "puppet" do |puppet|
32
+ puppet.facter = {
33
+ "vagrant_user" => "vagrant",
34
+ "vagrant_home" => "/home/vagrant"
35
+ }
36
+ # puppet.options = "--verbose --debug"
37
+ puppet.module_path = "puppet/modules"
38
+ puppet.manifests_path = "puppet/manifests"
39
+ puppet.manifest_file = "main.pp"
40
+ end
41
+ end
@@ -0,0 +1 @@
1
+ default_provider: <%= @provider -%>
@@ -0,0 +1,11 @@
1
+ language: <%= @language -%>
2
+ <% if @language == 'ruby' %>
3
+ rbenv:
4
+ <% if @current_ruby_version -%>
5
+ - "<%= @current_ruby_version -%>"
6
+ <% else %>
7
+ - "2.1.0"
8
+ <% end -%>
9
+ # uncomment this line if your project needs to run something other than `rake`:
10
+ # script: bundle exec rspec spec
11
+ <% end -%>
@@ -0,0 +1,27 @@
1
+ exec { "apt-update":
2
+ command => "/usr/bin/apt-get update"
3
+ }
4
+
5
+ Exec["apt-update"] -> Package <| |>
6
+
7
+ package {
8
+ "rbenv":
9
+ ensure => present,
10
+ require => Exec['apt-update'],
11
+ }
12
+
13
+ rbenv::install { $vagrant_user:
14
+ home => $vagrant_home,
15
+ require => [Package['rbenv']],
16
+ }
17
+ <% if @project_config.rbenv %>
18
+ <% @project_config.rbenv.each do |ruby_version| -%>
19
+
20
+ rbenv::compile { "$vagrant_user/<%= ruby_version -%>":
21
+ user => $vagrant_user,
22
+ home => $vagrant_home,
23
+ ruby => '<%= ruby_version -%>',
24
+ require => Rbenv::Install["$vagrant_user"],
25
+ }
26
+ <% end -%>
27
+ <% end %>
@@ -0,0 +1,45 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+ Vagrant.configure("2") do |config|
4
+ config.vm.box = "dummy"
5
+
6
+ config.vm.provider :aws do |aws, override|
7
+ aws.access_key_id = "<%= @provider_config.fetch("access_key") %>"
8
+ aws.secret_access_key = "<%= @provider_config.fetch("secret_access_key") %>"
9
+ aws.keypair_name = "<%= @provider_config.fetch("keypair_name") %>"
10
+ <% if @project_config.box_size == 'tiny' %>
11
+ aws.instance_type = 'm1.small'
12
+ <% elsif @project_config.box_size == 'small' %>
13
+ aws.instance_type = 'm1.small'
14
+ <% elsif @project_config.box_size == 'medium' %>
15
+ aws.instance_type = 'm1.medium'
16
+ <% elsif @project_config.box_size == 'large' %>
17
+ aws.instance_type = 'm1.large'
18
+ <% elsif @project_config.box_size == 'xlarge' %>
19
+ aws.instance_type = 'm1.xlarge'
20
+ <% end %>
21
+
22
+ # aws.ami = "ami-a81470c1"
23
+ aws.ami = "<%= @provider_config.fetch("ami") %>"
24
+ override.ssh.private_key_path = "<%= @provider_config.fetch("ssh_private_key_path") %>"
25
+ override.ssh.username = "<%= @provider_config.fetch("vagrant_user") %>"
26
+ end
27
+
28
+ config.vm.provision :puppet do |puppet|
29
+ puppet.facter = {
30
+ <% @project_config.puppet_facts.each do |k, v| %>
31
+ "<%= k %>" => "<%= v %>",
32
+ <% end %>
33
+ "role" => "ci",
34
+ "operationsystem" => "debian",
35
+ "vagrant_user" => "<%= @provider_config.fetch("vagrant_user") %>",
36
+ "vagrant_home" => "<%= @provider_config.fetch("vagrant_home") %>"
37
+ }
38
+ puppet.module_path = "<%= @puppet_path %>/modules"
39
+ puppet.manifests_path = "<%= @puppet_path %>/manifests"
40
+ puppet.manifest_file = "main.pp"
41
+ <% if @options["verbose"] == true %>
42
+ puppet.options = "--verbose --debug"
43
+ <% end %>
44
+ end
45
+ end
@@ -0,0 +1,5 @@
1
+ access_key: abcd1234
2
+ secret_access_key: abcd1234
3
+ keypair_name: rl_user
4
+ ssh_private_key_path: /Users/rl.user/.ec2/key
5
+ ami: ami-7747d01e
@@ -0,0 +1,37 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+ Vagrant.configure("2") do |config|
4
+ config.vm.box = "dummy"
5
+
6
+ config.ssh.private_key_path = "<%= @provider_config.fetch("private_key_path") %>"
7
+ config.ssh.username = "<%= @provider_config.fetch("vagrant_user") %>"
8
+
9
+ config.vm.provider :openstack do |os|
10
+ os.server_name = "shanty<%= rand(10000) -%>.<%= @provider_config.fetch("domain_name") -%>"
11
+ os.username = "<%= @provider_config.fetch("username") %>"
12
+ os.api_key = "<%= @provider_config.fetch("password") %>"
13
+ os.flavor = Regexp.new('<%= @provider_config.fetch("box_size_flavor_map")[@project_config.box_size] -%>')
14
+ os.image = Regexp.new('<%= @provider_config.fetch("image") -%>')
15
+ os.endpoint = "<%= @provider_config.fetch('endpoint') -%>"
16
+ os.keypair_name = "<%= @provider_config.fetch("key_pair") %>"
17
+ os.metadata = {}
18
+ os.network = "<%= @provider_config.fetch('network') -%>"
19
+ end
20
+
21
+ config.vm.provision :puppet do |puppet|
22
+ puppet.facter = {
23
+ <% @project_config.puppet_facts.each do |k, v| %>
24
+ "<%= k %>" => "<%= v %>",
25
+ <% end %>
26
+ "role" => "shanty",
27
+ "vagrant_user" => "<%= @provider_config.fetch("vagrant_user") %>",
28
+ "vagrant_home" => "<%= @provider_config.fetch("vagrant_home") %>"
29
+ }
30
+ puppet.module_path = "<%= @puppet_path %>/modules"
31
+ puppet.manifests_path = "<%= @puppet_path %>/manifests"
32
+ puppet.manifest_file = "main.pp"
33
+ <% if @options["verbose"] == true %>
34
+ puppet.options = "--verbose --debug"
35
+ <% end %>
36
+ end
37
+ end
@@ -0,0 +1,16 @@
1
+ username: the_openstack_username
2
+ password: the_openstack_password
3
+ private_key_path: "~/.ssh/id_rsa"
4
+ key_pair: the_openstack_keypair
5
+ box_size_flavor_map:
6
+ tiny: m1.tiny
7
+ small: m1.small
8
+ medium: m1.medium
9
+ large: m1.large
10
+ xlarge: m1.xlarge
11
+ image: the_image_identifier
12
+ endpoint: the_openstack_tokens_endpoint
13
+ network: the_openstack_network_identifier
14
+ domain_name: the_base_domain_for_server_names
15
+ vagrant_user: the_user_name
16
+ vagrant_home: the_users_home_directory
@@ -0,0 +1,47 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ # Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
5
+ VAGRANTFILE_API_VERSION = "2"
6
+
7
+ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
8
+ config.vm.box = "precise64"
9
+ config.vm.box_url = "http://files.vagrantup.com/precise64.box"
10
+
11
+ config.vm.provider :virtualbox do |vb|
12
+ <% if @project_config.box_size == 'tiny' %>
13
+ vb.customize ["modifyvm", :id, "--memory", "512"]
14
+ <% elsif @project_config.box_size == 'small' %>
15
+ vb.customize ["modifyvm", :id, "--memory", "2048"]
16
+ <% elsif @project_config.box_size == 'medium' %>
17
+ vb.customize ["modifyvm", :id, "--memory", "4096"]
18
+ vb.customize ["modifyvm", :id, "--cpus", "2"]
19
+ vb.customize ["modifyvm", :id, "--ioapic", "on"]
20
+ <% elsif @project_config.box_size == 'large' %>
21
+ vb.customize ["modifyvm", :id, "--memory", "8192"]
22
+ vb.customize ["modifyvm", :id, "--cpus", "4"]
23
+ vb.customize ["modifyvm", :id, "--ioapic", "on"]
24
+ <% elsif @project_config.box_size == 'xlarge' %>
25
+ vb.customize ["modifyvm", :id, "--memory", "16384"]
26
+ vb.customize ["modifyvm", :id, "--cpus", "8"]
27
+ vb.customize ["modifyvm", :id, "--ioapic", "on"]
28
+ <% end %>
29
+ end
30
+
31
+ config.vm.provision :puppet do |puppet|
32
+ puppet.facter = {
33
+ <% @project_config.puppet_facts.each do |k, v| %>
34
+ "<%= k %>" => "<%= v %>",
35
+ <% end %>
36
+ "role" => "shanty",
37
+ "vagrant_user" => "<%= @provider_config.fetch("vagrant_user") %>",
38
+ "vagrant_home" => "<%= @provider_config.fetch("vagrant_home") %>"
39
+ }
40
+ puppet.module_path = "<%= @puppet_path %>/modules"
41
+ puppet.manifests_path = "<%= @puppet_path %>/manifests"
42
+ puppet.manifest_file = "main.pp"
43
+ <% if @options["verbose"] == true %>
44
+ puppet.options = "--verbose --debug"
45
+ <% end %>
46
+ end
47
+ end
@@ -0,0 +1,2 @@
1
+ vagrant_user: vagrant
2
+ vagrant_home: /home/vagrant
@@ -0,0 +1,134 @@
1
+ module Boxci
2
+ class TestRunner
3
+ def initialize(language)
4
+ @language = language
5
+ end
6
+
7
+ def generate_script
8
+ snippets = []
9
+ snippets << %q{#!/bin/bash --login}
10
+ snippets << %q{test_runner_exit_status=0}
11
+ snippets << <<SNIPPET
12
+ PROJECT_DIR="/vagrant/project"
13
+ mkdir $PROJECT_DIR
14
+ tar -xf /vagrant/project.tar -C $PROJECT_DIR
15
+ cd $PROJECT_DIR
16
+ SNIPPET
17
+
18
+ snippets << generate_short_circuiting_hook_script('before_install')
19
+ snippets << generate_short_circuiting_hook_script('install')
20
+
21
+ snippets << short_circuit_on_step_failure('before_permutation_switch', @language.before_permutation_switch)
22
+
23
+ if Boxci.project_config.permutations
24
+ Boxci.project_config.permutations.each do |current_permutation|
25
+ snippets << current_permutation.switch_to_script
26
+
27
+ snippets << short_circuit_on_step_failure('after_permutation_switch', @language.after_permutation_switch)
28
+
29
+ snippets << generate_short_circuiting_hook_script('before_script')
30
+ snippets << generate_script_hook_script
31
+ snippets << generate_after_success_and_failure_hook_script
32
+ snippets << generate_continuing_hook_script('after_script')
33
+ end
34
+ else
35
+ snippets << short_circuit_on_step_failure('after_permutation_switch', @language.after_permutation_switch)
36
+
37
+ snippets << generate_short_circuiting_hook_script('before_script')
38
+ snippets << generate_script_hook_script
39
+ snippets << generate_after_success_and_failure_hook_script
40
+ snippets << generate_continuing_hook_script('after_script')
41
+ end
42
+ snippets << %{exit $test_runner_exit_status}
43
+ return snippets.join("\n")
44
+ end
45
+
46
+ private
47
+
48
+ def generate_after_success_and_failure_hook_script
49
+ <<SNIPPET
50
+ if [ $test_runner_exit_status -eq 0 ]; then
51
+ :
52
+ #{generate_continuing_hook_script('after_success')}
53
+ else
54
+ :
55
+ #{generate_continuing_hook_script('after_failure')}
56
+ fi
57
+ SNIPPET
58
+ end
59
+
60
+ def generate_short_circuiting_hook_script(hook_name)
61
+ if !Boxci.project_config.send(hook_name.to_sym).empty?
62
+ snippets = []
63
+ Boxci.project_config.send(hook_name.to_sym).each do |step|
64
+ snippets << short_circuit_on_step_failure(hook_name, step)
65
+ end
66
+ return snippets.join("\n")
67
+ else
68
+ return %Q(# Placeholder where '#{hook_name}' would go if it was set.)
69
+ end
70
+ end
71
+
72
+ def generate_continuing_hook_script(hook_name)
73
+ if !Boxci.project_config.send(hook_name.to_sym).empty?
74
+ snippets = []
75
+ Boxci.project_config.send(hook_name.to_sym).each do |step|
76
+ snippets << continue_on_step_failure(hook_name, step)
77
+ end
78
+ return snippets.join("\n")
79
+ else
80
+ return %Q(# Placeholder where '#{hook_name}' would go if it was set.)
81
+ end
82
+ end
83
+
84
+ def generate_script_hook_script
85
+ if !Boxci.project_config.script.empty?
86
+ snippets = []
87
+ Boxci.project_config.script.each do |step|
88
+ snippets << continue_on_step_failure('script', step)
89
+ end
90
+ return snippets.join("\n")
91
+ else
92
+ return continue_on_step_failure('script', @language.default_script)
93
+ end
94
+ end
95
+
96
+ def short_circuit_on_step_failure(hook_name, step)
97
+ if step && !step.empty?
98
+ <<SNIPPET
99
+ # Beginning of '#{hook_name}' step '#{step}'
100
+ echo "Running '#{hook_name}' step '#{step}'"
101
+ step_exit_code=0
102
+ #{step}
103
+ step_exit_code=$?
104
+ if [ $step_exit_code -ne 0 ]; then
105
+ echo "Err: #{hook_name} step '#{step}' exited with non-zero exit code ($step_exit_code)"
106
+ exit 1
107
+ fi
108
+ # End of '#{hook_name}' step '#{step}'
109
+ SNIPPET
110
+ else
111
+ %Q(# Placeholder where '#{hook_name}' would go if it was set.)
112
+ end
113
+ end
114
+
115
+ def continue_on_step_failure(hook_name, step)
116
+ if step && !step.empty?
117
+ <<SNIPPET
118
+ # Beginning of '#{hook_name}' step '#{step}'
119
+ echo "Running '#{hook_name}' step '#{step}'"
120
+ step_exit_code=0
121
+ #{step}
122
+ step_exit_code=$?
123
+ if [ $step_exit_code -ne 0 ]; then
124
+ echo "Warning: script step '#{step}' exited with non-zero exit code ($step_exit_code)."
125
+ test_runner_exit_status=1
126
+ fi
127
+ # End of '#{hook_name}' step '#{step}'
128
+ SNIPPET
129
+ else
130
+ %Q(# Placeholder where '#{hook_name}' would go if it was set.)
131
+ end
132
+ end
133
+ end
134
+ end