ruby_yacht 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (127) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -1
  3. data/.rdoc_options +8 -2
  4. data/.rspec +1 -0
  5. data/.travis.yml +17 -1
  6. data/Gemfile.lock +18 -2
  7. data/README.md +28 -10
  8. data/bin/ruby_yacht +5 -0
  9. data/doc/TODO.md +1 -20
  10. data/doc/configuration.md +104 -21
  11. data/doc/configuration_sample.rb +19 -8
  12. data/doc/contributing.md +28 -5
  13. data/doc/plugins.md +105 -45
  14. data/lib/ruby_yacht/dsl/app.rb +14 -18
  15. data/lib/ruby_yacht/dsl/configuration.rb +51 -32
  16. data/lib/ruby_yacht/dsl/database.rb +24 -8
  17. data/lib/ruby_yacht/dsl/dsl.rb +32 -4
  18. data/lib/ruby_yacht/dsl/hook.rb +182 -48
  19. data/lib/ruby_yacht/dsl/project.rb +20 -14
  20. data/lib/ruby_yacht/dsl/server_type.rb +14 -31
  21. data/lib/ruby_yacht/dsl/web_server.rb +87 -0
  22. data/lib/ruby_yacht/dsl.rb +1 -0
  23. data/lib/ruby_yacht/images/app/Dockerfile.erb +17 -6
  24. data/lib/ruby_yacht/images/app/before_startup.bash.erb +5 -3
  25. data/lib/ruby_yacht/images/app/startup.bash.erb +5 -2
  26. data/lib/ruby_yacht/images/app-dependencies/Dockerfile.erb +7 -11
  27. data/lib/ruby_yacht/images/database/Dockerfile.erb +7 -18
  28. data/lib/ruby_yacht/images/database/startup.bash.erb +1 -1
  29. data/lib/ruby_yacht/images/web/Dockerfile.erb +25 -19
  30. data/lib/ruby_yacht/plugins/mysql.rb +18 -8
  31. data/lib/ruby_yacht/{images/web → plugins/nginx/scripts}/add_app.rb +5 -5
  32. data/lib/ruby_yacht/{images/web → plugins/nginx/scripts}/add_project.rb +3 -3
  33. data/lib/ruby_yacht/plugins/nginx.rb +28 -0
  34. data/lib/ruby_yacht/plugins/rails/scripts/build_new_app.rb +10 -0
  35. data/lib/ruby_yacht/plugins/rails/scripts/update_rails_config.rb +6 -1
  36. data/lib/ruby_yacht/plugins/rails.rb +34 -19
  37. data/lib/ruby_yacht/plugins.rb +2 -1
  38. data/lib/ruby_yacht/runner/build_images.rb +87 -73
  39. data/lib/ruby_yacht/runner/checkout.rb +1 -1
  40. data/lib/ruby_yacht/runner/command.rb +13 -1
  41. data/lib/ruby_yacht/runner/create_new_project.rb +91 -0
  42. data/lib/ruby_yacht/runner/help.rb +1 -1
  43. data/lib/ruby_yacht/runner/run_containers.rb +17 -21
  44. data/lib/ruby_yacht/runner/runner.rb +27 -2
  45. data/lib/ruby_yacht/runner/services.rb +15 -10
  46. data/lib/ruby_yacht/runner/shell.rb +1 -1
  47. data/lib/ruby_yacht/runner/update_hosts.rb +16 -11
  48. data/lib/ruby_yacht/runner.rb +1 -0
  49. data/log/.gitkeep +0 -0
  50. data/ruby_yacht.gemspec +4 -2
  51. data/spec/docker/Dockerfile +19 -3
  52. data/spec/docker/install_gems.bash +5 -0
  53. data/spec/docker/run.bash +44 -0
  54. data/spec/docker/startup.bash +10 -0
  55. data/spec/dsl/app_spec.rb +66 -38
  56. data/spec/dsl/configuration_spec.rb +236 -30
  57. data/spec/dsl/database_spec.rb +103 -4
  58. data/spec/dsl/dsl_spec.rb +46 -3
  59. data/spec/dsl/hook_spec.rb +278 -57
  60. data/spec/dsl/project_spec.rb +75 -45
  61. data/spec/dsl/server_type_spec.rb +52 -12
  62. data/spec/dsl/web_server_spec.rb +160 -0
  63. data/spec/fixtures/apollo-new-project-config +20 -0
  64. data/spec/fixtures/app-dependencies-dockerfile-generic +4 -7
  65. data/spec/fixtures/app-dependencies-dockerfile-generic-with-library-install +6 -10
  66. data/spec/fixtures/app-dependencies-dockerfile-rails +9 -11
  67. data/spec/fixtures/app-dependencies-dockerfile-with-no-repository +20 -0
  68. data/spec/fixtures/database-dockerfile +1 -1
  69. data/spec/fixtures/database-dockerfile-mysql +3 -3
  70. data/spec/fixtures/database-dockerfile-rails +5 -4
  71. data/spec/fixtures/database-dockerfile-rails-with-no-repository +27 -0
  72. data/spec/fixtures/database-dockerfile-with-seed-hooks +3 -3
  73. data/spec/fixtures/database-startup-mysql +2 -1
  74. data/spec/fixtures/mars-before-startup +2 -2
  75. data/spec/fixtures/mars-before-startup-rails +5 -4
  76. data/spec/fixtures/mars-before-startup-with-before-startup-hooks +5 -4
  77. data/spec/fixtures/mars-before-startup-with-custom-file-copy +3 -3
  78. data/spec/fixtures/mars-before-startup-with-no-repository +3 -0
  79. data/spec/fixtures/mars-dockerfile +3 -2
  80. data/spec/fixtures/mars-dockerfile-rails +6 -5
  81. data/spec/fixtures/mars-dockerfile-rails-with-no-repository +32 -0
  82. data/spec/fixtures/mars-dockerfile-with-after-checkout-hooks +5 -4
  83. data/spec/fixtures/mars-dockerfile-with-before-startup-hooks +5 -4
  84. data/spec/fixtures/mars-dockerfile-with-custom-file-copy +4 -3
  85. data/spec/fixtures/mars-dockerfile-with-local-database +4 -2
  86. data/spec/fixtures/mars-dockerfile-with-no-repository +22 -0
  87. data/spec/fixtures/mars-dockerfile-with-remote-database +4 -2
  88. data/spec/fixtures/mars-startup +2 -2
  89. data/spec/fixtures/mars-startup-rails +2 -2
  90. data/spec/fixtures/mars-startup-rails-with-no-repository +5 -0
  91. data/spec/fixtures/mars-startup-with-no-repository +4 -0
  92. data/spec/fixtures/web-dockerfile +18 -11
  93. data/spec/fixtures/web-dockerfile-jupiter +28 -0
  94. data/spec/fixtures/web-dockerfile-nginx +38 -0
  95. data/spec/fixtures/web-dockerfile-with-eponymous-app +16 -10
  96. data/spec/fixtures/web-dockerfile-with-primary-app +16 -10
  97. data/spec/integration/build_images_spec.rb +210 -0
  98. data/spec/integration/build_spec.rb +23 -0
  99. data/spec/integration/checkout_spec.rb +94 -0
  100. data/spec/integration/create_new_project_spec.rb +50 -0
  101. data/spec/integration/implode_spec.rb +20 -0
  102. data/spec/integration/run.rb +93 -0
  103. data/spec/integration/run_containers_spec.rb +279 -0
  104. data/spec/integration/services_spec.rb +99 -0
  105. data/spec/integration/shell_spec.rb +31 -0
  106. data/spec/integration/update_hosts_spec.rb +35 -0
  107. data/spec/plugins/mysql_spec.rb +18 -1
  108. data/spec/plugins/nginx_spec.rb +66 -0
  109. data/spec/plugins/rails_spec.rb +61 -89
  110. data/spec/runner/build_images_spec.rb +111 -58
  111. data/spec/runner/command_spec.rb +55 -3
  112. data/spec/runner/create_new_project_spec.rb +93 -0
  113. data/spec/runner/help_spec.rb +5 -1
  114. data/spec/runner/run_containers_spec.rb +22 -10
  115. data/spec/runner/runner_spec.rb +31 -4
  116. data/spec/runner/services_spec.rb +32 -4
  117. data/spec/runner/update_hosts_spec.rb +2 -1
  118. data/spec/spec_helper.rb +16 -1
  119. data/spec/support/integration_helpers.rb +76 -0
  120. data/spec/support/test_project.rb +15 -3
  121. metadata +97 -14
  122. data/spec/docker/build.bash +0 -10
  123. data/spec/fixtures/deploy-dockerfile +0 -2
  124. data/spec/fixtures/multi-project-web-dockerfile +0 -25
  125. /data/lib/ruby_yacht/{images/web → plugins/nginx/scripts}/app_config.erb +0 -0
  126. /data/lib/ruby_yacht/{images/web → plugins/nginx/scripts}/index.html.erb +0 -0
  127. /data/lib/ruby_yacht/{images/web → plugins/nginx/scripts}/index_config.erb +0 -0
@@ -0,0 +1,91 @@
1
+ require 'fileutils'
2
+
3
+ module RubyYacht::Runner
4
+ # This command provides help information about other commands.
5
+ class CreateNewProject < Command
6
+ # The name of the command.
7
+ def self.command; 'new'; end
8
+
9
+ # The short description of the command.
10
+ def self.description
11
+ 'Create a new ruby-yacht project'
12
+ end
13
+
14
+ # The project that we are creating.
15
+ attr_accessor :project
16
+
17
+ # The directory where we should place the config.
18
+ attr_accessor :directory
19
+
20
+ # This method gets the command-line options for the command.
21
+ def option_parser
22
+ OptionParser.new do |options|
23
+ options.banner = "Usage: #{Command.short_script_name} new [PROJECT] [DIRECTORY]\n\n#{self.class.description}"
24
+ end
25
+ end
26
+
27
+ # This method extracts arguments from the command line.
28
+ #
29
+ # ### Parameters
30
+ #
31
+ # * **arguments: Array** The command line arguments.
32
+ def parse_positional_arguments(arguments)
33
+ self.project = arguments.shift
34
+ self.directory = arguments.shift
35
+ end
36
+
37
+ # This method runs the logic for the command.
38
+ def run
39
+ if project.nil?
40
+ log 'You must provide a project'
41
+ log "Run #{Command.short_script_name} help new for more information"
42
+ return false
43
+ end
44
+
45
+ if directory.nil?
46
+ log 'You must provide a directory'
47
+ log "Run #{Command.short_script_name} help new for more information"
48
+ return false
49
+ end
50
+
51
+ FileUtils.mkdir_p(directory)
52
+ File.open(File.join(directory, 'run.rb'), 'w') do |file|
53
+ write_config_file(file)
54
+ end
55
+ log "Your project has been created in #{directory}/run.rb."
56
+ log "You can go to #{directory} and run `ruby run.rb build` to create your docker containers."
57
+ log "Your initial app will be created in the #{project} directory."
58
+ true
59
+ end
60
+
61
+ private
62
+
63
+ # This method writes the config file for the new project to a file.
64
+ #
65
+ # ### Parameters
66
+ #
67
+ # * **file: IO** The file to write to.
68
+ def write_config_file(file)
69
+ file.puts "require 'ruby_yacht'"
70
+ file.puts ''
71
+ file.puts 'RubyYacht.configure do'
72
+ file.puts " project :#{project} do"
73
+ file.puts " system_prefix :#{project}"
74
+ file.puts " repository 'github.com'"
75
+ file.puts " rails_secret_key_base 'testkey'"
76
+ file.puts " check_out_locally"
77
+ file.puts ""
78
+ file.puts " rails_app :#{project}"
79
+ file.puts ""
80
+ file.puts " primary_app :#{project}"
81
+ file.puts ""
82
+ file.puts " nginx_web_server do"
83
+ file.puts " domain '#{project}.test.com'"
84
+ file.puts " end"
85
+ file.puts " end"
86
+ file.puts "end"
87
+ file.puts ""
88
+ file.puts "RubyYacht::Runner.run"
89
+ end
90
+ end
91
+ end
@@ -45,7 +45,7 @@ module RubyYacht::Runner
45
45
 
46
46
  log "Available commands: \n\n"
47
47
  RubyYacht::Runner.commands.each do |command|
48
- log "#{command.name}: #{command.description}"
48
+ log "#{command.command}: #{command.description}"
49
49
  end
50
50
 
51
51
  log "\nRun #{Command.short_script_name} help [command] for more information on a command"
@@ -17,18 +17,18 @@ module RubyYacht::Runner
17
17
  @project = project
18
18
 
19
19
  project.databases.select(&:local?).each do |database|
20
- run_container database.container_label
20
+ run_container database
21
21
  end
22
22
 
23
23
  project.apps.each do |app|
24
- run_container app.name
24
+ run_container app
25
+ end
26
+
27
+ project.web_servers.each do |web_server|
28
+ run_container web_server
25
29
  end
26
30
  end
27
31
 
28
- @project = projects.first
29
-
30
- run_container :web
31
-
32
32
  true
33
33
  end
34
34
 
@@ -48,11 +48,11 @@ module RubyYacht::Runner
48
48
  #
49
49
  # ### Parameters
50
50
  #
51
- # * **container_name: Symbol** The name of the container, not including
52
- # the system prefix.
53
- def volume_flags(container_name)
54
- if @project.check_out_locally && ![:database, :web].include?(container_name)
55
- return ["-v $PWD/../#{container_name}:/var/code"]
51
+ # * **server: App/Database/WebServer** The server we are running a
52
+ # container for.
53
+ def volume_flags(server)
54
+ if @project.check_out_locally && server.is_a?(RubyYacht::App)
55
+ return ["-v $PWD/../#{server.name}:/var/code"]
56
56
  else
57
57
  return []
58
58
  end
@@ -64,20 +64,16 @@ module RubyYacht::Runner
64
64
  #
65
65
  # ### Parameters
66
66
  #
67
- # * **name: Symbol** The name of the container, not including the system
68
- # prefix.
69
- def run_container(name)
70
- if name == @project.system_prefix
71
- container_name = name
72
- else
73
- container_name = "#{@project.system_prefix}-#{name}"
74
- end
67
+ # * **server: App/Database/WebServer** The server we are running a
68
+ # container for.
69
+ def run_container(server)
70
+ container_name = server.container_name
75
71
  remove_container container_name
76
72
 
77
73
  flags = ["-d"]
78
74
  flags += dns_server_flags
79
- flags += volume_flags(name)
80
- flags << "-p 80:80" if name == :web
75
+ flags += volume_flags(server)
76
+ flags << "-p #{server.port}:80" if server.is_a?(RubyYacht::WebServer)
81
77
  flags << "--net=#{@network}"
82
78
  flags << "--net-alias=#{container_name}"
83
79
 
@@ -1,7 +1,28 @@
1
1
  module RubyYacht::Runner
2
2
  # This method provides the commands that we can run.
3
3
  def self.commands
4
- [Help, Build, BuildImages, RunContainers, Services, Checkout, Shell, UpdateHosts, Implode]
4
+ @commands ||= []
5
+ end
6
+
7
+ # This method clears our list of commands that we can run.
8
+ def self.clear_commands
9
+ @commands = []
10
+ end
11
+
12
+ # This method loads the default commands into our command list.
13
+ #
14
+ # ### Parameters
15
+ #
16
+ # * **in_project* Boolean** Whether we are running a script in the context
17
+ # of a project, or in the top-level ruby_yacht
18
+ # command.
19
+ def self.load_default_commands(in_project=true)
20
+ @commands ||= []
21
+ if in_project
22
+ @commands += [Help, Build, BuildImages, RunContainers, Services, Checkout, Shell, UpdateHosts, Implode]
23
+ else
24
+ @commands += [Help, CreateNewProject]
25
+ end
5
26
  end
6
27
 
7
28
  # This method gets the arguments for the current command.
@@ -11,13 +32,14 @@ module RubyYacht::Runner
11
32
 
12
33
  # This method runs a command based on the command line arguments.
13
34
  def self.run
35
+ load_default_commands if self.commands == []
14
36
  arg = arguments[0]
15
37
 
16
38
  if arg == '' || arg == nil
17
39
  puts "You must provide a command to run"
18
40
  puts "Run `#{$0} help` for more information"
19
41
  exit(1)
20
- return
42
+ return false
21
43
  end
22
44
 
23
45
  command = self.commands.find { |c| c.command == arg }
@@ -32,11 +54,14 @@ module RubyYacht::Runner
32
54
  success = instance.run
33
55
  unless success
34
56
  exit(1)
57
+ return false
35
58
  end
36
59
  else
37
60
  puts "Command not recognized: #{arg}"
38
61
  puts "Run `#{$0} help` for more information"
39
62
  exit(1)
63
+ return false
40
64
  end
65
+ true
41
66
  end
42
67
  end
@@ -46,32 +46,37 @@ module RubyYacht::Runner
46
46
  return false
47
47
  end
48
48
 
49
- if command == 'start' && backtick('which docker-machine') != ''
49
+ if command == 'start'
50
50
  start_docker_machine
51
51
  end
52
52
 
53
53
  projects.each do |project|
54
54
  project.databases.select(&:local?).each do |database|
55
- docker "#{command} #{database.container_name(project)}"
55
+ docker "#{command} #{database.container_name}"
56
56
  end
57
57
 
58
58
  project.apps.each do |app|
59
- docker "#{command} #{app.container_name(project)}"
59
+ docker "#{command} #{app.container_name}"
60
+ end
61
+
62
+ project.web_servers.each do |server|
63
+ docker "#{command} #{server.container_name}"
60
64
  end
61
65
  end
62
- docker "#{command} #{projects.first.system_prefix}-web"
63
66
 
64
67
  true
65
68
  end
66
69
 
67
70
  # This method starts the default docker machine.
68
71
  def start_docker_machine
69
- system "docker-machine start default"
70
-
71
- environment_args = backtick('docker-machine env default').split("\n")
72
- environment_args.each do |arg|
73
- if arg =~ /export (\w*)=\"(.*)\"/
74
- ENV[$1] = $2
72
+ if docker_machine != ''
73
+ system "#{docker_machine} start default"
74
+
75
+ environment_args = backtick("#{docker_machine} env default").split("\n")
76
+ environment_args.each do |arg|
77
+ if arg =~ /export (\w*)=\"(.*)\"/
78
+ ENV[$1] = $2
79
+ end
75
80
  end
76
81
  end
77
82
  end
@@ -58,7 +58,7 @@ module RubyYacht::Runner
58
58
  return false unless project
59
59
 
60
60
  app = project.apps.find { |a| a.name == app_name.to_sym }
61
- container = app.container_name(project)
61
+ container = app.container_name
62
62
  exec("docker exec -it #{container} bash -c 'cd /var/code; TERM=xterm #{command}'")
63
63
  true
64
64
  end
@@ -24,7 +24,9 @@ module RubyYacht::Runner
24
24
  current_hosts = current_host_contents.split("\n")
25
25
  new_hosts = current_hosts.select do |entry|
26
26
  projects.none? do |project|
27
- entry.include?(project.domain) || entry.include?("#{project.system_prefix} docker containers")
27
+ project.web_servers.any? do |server|
28
+ entry.include?(server.domain) || entry.include?("#{project.system_prefix} docker containers")
29
+ end
28
30
  end
29
31
  end
30
32
 
@@ -39,9 +41,9 @@ module RubyYacht::Runner
39
41
 
40
42
  timestamp = Time.now.utc.strftime('%Y%m%d%H%M%S')
41
43
  log "Please enter your password so that we can update the hosts file"
42
- system "sudo cp /etc/hosts /etc/hosts.#{timestamp}.backup"
43
- system "sudo mv tmp/hosts /etc/hosts"
44
-
44
+ sudo_command = backtick('which sudo').strip
45
+ system "#{sudo_command} cp /etc/hosts /etc/hosts.#{timestamp}.backup"
46
+ system "#{sudo_command} cat tmp/hosts > /etc/hosts"
45
47
  true
46
48
  end
47
49
 
@@ -57,15 +59,18 @@ module RubyYacht::Runner
57
59
  # An Array with the new lines for the hosts file.
58
60
  def hosts_file_entries(project, ip_address)
59
61
  system_prefix = project.system_prefix
60
- main_domain = project.domain
61
-
62
- domains = [main_domain]
63
- apps = project.apps.select { |app| app.name != system_prefix }
64
- domains += apps.map { |app| "#{app.name}.#{main_domain}" }
65
-
66
62
  header = "# #{system_prefix} docker containers"
67
63
  new_hosts = ["", header]
68
- new_hosts += domains.map { |domain| "#{ip_address} #{domain}" }
64
+
65
+ project.web_servers.each do |web_server|
66
+ main_domain = web_server.domain
67
+
68
+ domains = [main_domain]
69
+ apps = project.apps.select { |app| app.name != system_prefix }
70
+ domains += apps.map { |app| "#{app.name}.#{main_domain}" }
71
+
72
+ new_hosts += domains.map { |domain| "#{ip_address} #{domain}" }
73
+ end
69
74
  new_hosts
70
75
  end
71
76
  end
@@ -15,4 +15,5 @@ require 'ruby_yacht/runner/checkout'
15
15
  require 'ruby_yacht/runner/implode'
16
16
  require 'ruby_yacht/runner/shell'
17
17
  require 'ruby_yacht/runner/update_hosts'
18
+ require 'ruby_yacht/runner/create_new_project'
18
19
  require 'ruby_yacht/runner/runner'
data/log/.gitkeep ADDED
File without changes
data/ruby_yacht.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = 'ruby_yacht'
3
- spec.version = '0.5.0'
4
- spec.date = '2016-05-05'
3
+ spec.version = '0.6.0'
4
+ spec.date = '2016-05-15'
5
5
  spec.description = "A DSL for building docker containers for a family of Rails apps"
6
6
  spec.summary = "A DSL for building docker containers for a family of Rails apps"
7
7
  spec.authors = ["John Brownlee"]
@@ -16,4 +16,6 @@ Gem::Specification.new do |spec|
16
16
  spec.add_development_dependency "rspec"
17
17
  spec.add_development_dependency "codeclimate-test-reporter"
18
18
  spec.add_development_dependency "timecop"
19
+ spec.add_development_dependency "byebug"
20
+ spec.add_development_dependency 'rubocop'
19
21
  end
@@ -1,5 +1,21 @@
1
1
  FROM ruby:2.3
2
2
 
3
- VOLUME /var/code
4
- WORKDIR /var/code
5
- CMD bundle install; bash
3
+ RUN apt-get update
4
+ RUN curl -fsSL https://get.docker.com/ | sh
5
+
6
+ RUN mkdir -p /var/docker
7
+
8
+ COPY startup.bash /var/docker/
9
+ COPY install_gems.bash /var/docker/
10
+ RUN chmod u+x /var/docker/*.bash
11
+
12
+ RUN /var/docker/install_gems.bash
13
+
14
+ RUN mkdir -p /root/.ssh
15
+ COPY id_rsa /root/.ssh
16
+
17
+ VOLUME /var/lib/docker
18
+ VOLUME /var/code/ruby-yacht
19
+ WORKDIR /var/code/ruby-yacht
20
+
21
+ CMD /var/docker/startup.bash
@@ -0,0 +1,5 @@
1
+ gem install rspec
2
+ gem install codeclimate-test-reporter
3
+ gem install timecop
4
+ gem install byebug
5
+ gem install rubocop
@@ -0,0 +1,44 @@
1
+ #! /bin/bash
2
+
3
+ # This script runs our tests in a docker container.
4
+ #
5
+ # This keeps the development dependencies isolated from other parts of the
6
+ # system.
7
+
8
+ EXISTING_IMAGE=`docker images | grep ruby-yacht-tests`
9
+ if [ -z "$EXISTING_IMAGE" ]; then
10
+ if [ -f ~/.ssh/id_rsa ]; then
11
+ cp ~/.ssh/id_rsa spec/docker
12
+ else
13
+ touch spec/docker/id_rsa
14
+ fi
15
+ docker build -t ruby-yacht-tests spec/docker
16
+ rm spec/docker/id_rsa
17
+ fi
18
+
19
+ if [ -z $PRESERVE_IMAGES ]; then
20
+ PRESERVE_IMAGES='0'
21
+ fi
22
+
23
+ EXTRA_FLAGS="$EXTRA_FLAGS -e PRESERVE_IMAGES=$PRESERVE_IMAGES"
24
+
25
+ if [ $PRESERVE_IMAGES -eq 1 ]; then
26
+ EXTRA_FLAGS="$EXTRA_FLAGS -d"
27
+ EXISTING_CONTAINER=`docker ps | grep ruby-yacht-tests`
28
+ else
29
+ docker rm -f ruby-yacht-tests 1> /dev/null 2> /dev/null
30
+ EXTRA_FLAGS="$EXTRA_FLAGS --rm"
31
+ EXISTING_CONTAINER=""
32
+ fi
33
+
34
+ if [ -z "$EXISTING_CONTAINER" ]; then
35
+ docker run -it $EXTRA_FLAGS --privileged --name=ruby-yacht-tests -v $PWD:/var/code/ruby-yacht ruby-yacht-tests /var/docker/startup.bash $*
36
+ RESULT=$?
37
+ fi
38
+
39
+ if [ $PRESERVE_IMAGES -eq 1 ]; then
40
+ docker exec -it ruby-yacht-tests bash -c "bundle install --quiet; rspec $*"
41
+ RESULT=$?
42
+ fi
43
+
44
+ exit $RESULT
@@ -0,0 +1,10 @@
1
+ #! /bin/bash
2
+
3
+ /etc/init.d/docker start
4
+ bundle install --quiet
5
+ if [ $PRESERVE_IMAGES -eq 1 ]
6
+ then
7
+ bash
8
+ else
9
+ rspec $*
10
+ fi
data/spec/dsl/app_spec.rb CHANGED
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  RSpec.describe RubyYacht::App do
4
4
  describe "DSL" do
5
5
  let(:name) { :test_app }
6
- let(:app) { RubyYacht::App::DSL.new(name).run(@builder).create_object }
6
+ let(:app) { RubyYacht::App::DSL.new(:test, name).run(@builder).create_object }
7
7
 
8
8
  before do
9
9
  RubyYacht.configuration.clear
@@ -19,7 +19,6 @@ RSpec.describe RubyYacht::App do
19
19
  @builder = Proc.new do
20
20
  repository_name 'brownleej/test-app'
21
21
  database_name :database
22
- server_type :test
23
22
  port 3000
24
23
  end
25
24
  expect(app.name).to eq :test_app
@@ -29,32 +28,17 @@ RSpec.describe RubyYacht::App do
29
28
  expect(app.port).to eq 3000
30
29
  end
31
30
 
32
- it "requires the repository name" do
31
+ it "defaults the repository name to nil" do
33
32
  @builder = Proc.new do
34
33
  port 3000
35
- server_type :test
36
34
  database_name :database
37
35
  end
38
- expect do
39
- self.app
40
- end.to raise_exception("Missing required attribute repository_name for RubyYacht::App::DSL")
41
- end
42
-
43
- it "requires the server type" do
44
- @builder = Proc.new do
45
- repository_name 'brownleej/test-app'
46
- port 3000
47
- database_name :database
48
- end
49
- expect do
50
- self.app
51
- end.to raise_exception("Missing required attribute server_type for RubyYacht::App::DSL")
36
+ expect(self.app.repository_name).to be_nil
52
37
  end
53
38
 
54
39
  it "does not require the database name" do
55
40
  @builder = Proc.new do
56
41
  repository_name 'brownleej/test-app'
57
- server_type :test
58
42
  port 3000
59
43
  end
60
44
  expect(app.database_name).to be_nil
@@ -69,7 +53,7 @@ RSpec.describe RubyYacht::App do
69
53
  end
70
54
  expect do
71
55
  self.app
72
- end.to raise_exception("App has invalid server type `invalid`")
56
+ end.to raise_exception("RubyYacht::App::DSL has invalid app server type `invalid`")
73
57
  end
74
58
 
75
59
  it "requires a defined server type for apps" do
@@ -88,41 +72,82 @@ RSpec.describe RubyYacht::App do
88
72
  end
89
73
  expect do
90
74
  self.app
91
- end.to raise_exception("App has invalid server type `sqlite`")
75
+ end.to raise_exception("RubyYacht::App::DSL has invalid app server type `sqlite`")
92
76
  end
93
77
 
94
78
  it "defaults the port to 8080" do
95
79
  @builder = Proc.new do
96
80
  repository_name 'brownleej/test-app'
97
- server_type :test
98
81
  database_name :database
99
82
  end
100
83
  expect(app.port).to eq 8080
101
84
  end
102
85
  end
103
86
 
87
+ describe 'project' do
88
+ before do
89
+ RubyYacht.configuration.clear
90
+ RubyYacht.configure do
91
+ server_type :test do
92
+ container_type :app
93
+ baseline_image 'ubuntu'
94
+ end
95
+ end
96
+ RubyYacht.configure do
97
+ project :project1 do
98
+ repository 'github.com'
99
+ system_prefix :project1
100
+
101
+ test_app :app1 do
102
+ repository_name 'app1'
103
+ end
104
+
105
+ test_app :app2 do
106
+ repository_name 'app2'
107
+ end
108
+ end
109
+
110
+ project :project2 do
111
+ repository 'github.com'
112
+ system_prefix :project2
113
+
114
+ test_app :app3 do
115
+ repository_name 'app3'
116
+ end
117
+ end
118
+ end
119
+ end
120
+
121
+ it 'finds the project that contains the app' do
122
+ app2 = RubyYacht.configuration.projects[0].apps[1]
123
+ expect(app2.project.name).to eq :project1
124
+
125
+ app3 = RubyYacht.configuration.projects[1].apps[0]
126
+ expect(app3.project.name).to eq :project2
127
+ end
128
+ end
129
+
104
130
  describe "container_name" do
105
- it "combines the project's prefix with the app's name" do
106
- project = RubyYacht::Project.new
107
- project.name = :test_project
108
- project.system_prefix = :tests
131
+ before do
132
+ @project = RubyYacht::Project.new
133
+ @project.name = :test_project
134
+ @project.system_prefix = :tests
109
135
 
110
- app = RubyYacht::App.new
111
- app.name = 'app1'
136
+ @app = RubyYacht::App.new
137
+ @app.name = 'app1'
138
+ @project.apps = [@app]
139
+ RubyYacht.configuration.projects << @project
140
+ end
112
141
 
113
- expect(app.container_name(project)).to eq 'tests-app1'
142
+ it "combines the project's prefix with the app's name" do
143
+ expect(@app.container_name).to eq 'tests-app1'
114
144
  end
115
145
 
116
146
  context "with the same name as the project's system_prefix" do
117
147
  it "is just the project's system prefix" do
118
- project = RubyYacht::Project.new
119
- project.name = :test_project
120
- project.system_prefix = :tests
148
+ @app.name = :tests
121
149
 
122
- app = RubyYacht::App.new
123
- app.name = :tests
124
-
125
- expect(app.container_name(project)).to eq 'tests'
150
+ expect(@app.container_name).to eq 'tests'
126
151
  end
127
152
  end
128
153
  end
@@ -146,10 +171,13 @@ RSpec.describe RubyYacht::App do
146
171
  @app = RubyYacht::App.new
147
172
  @app.name = 'app1'
148
173
  @app.database_name = 'second_db'
174
+
175
+ @project.apps = [@app]
176
+ RubyYacht.configuration.projects << @project
149
177
  end
150
178
 
151
179
  it "is the database with the app's database_name" do
152
- database = @app.database(@project)
180
+ database = @app.database
153
181
  expect(database).not_to be_nil
154
182
  expect(database.host).to eq 'db2.test.com'
155
183
  end
@@ -160,7 +188,7 @@ RSpec.describe RubyYacht::App do
160
188
  end
161
189
 
162
190
  it "is nil" do
163
- expect(@app.database(@project)).to be_nil
191
+ expect(@app.database).to be_nil
164
192
  end
165
193
  end
166
194
  end