ruby_yacht 0.5.0 → 0.6.0

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