containers 0.1.1 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/exe/ctrs +5 -0
  3. data/lib/containers/cli.rb +33 -2
  4. data/lib/containers/commands/attach.rb +4 -2
  5. data/lib/containers/commands/bash.rb +4 -2
  6. data/lib/containers/commands/bin.rb +11 -0
  7. data/lib/containers/commands/config/print.rb +11 -0
  8. data/lib/containers/commands/down.rb +1 -1
  9. data/lib/containers/commands/exec.rb +7 -3
  10. data/lib/containers/commands/inspect.rb +4 -2
  11. data/lib/containers/commands/list.rb +7 -4
  12. data/lib/containers/commands/rails/rails.rb +11 -0
  13. data/lib/containers/commands/restart.rb +5 -3
  14. data/lib/containers/commands/ruby/bundle.rb +11 -0
  15. data/lib/containers/commands/ruby/rake.rb +11 -0
  16. data/lib/containers/commands/start.rb +5 -3
  17. data/lib/containers/commands/stop.rb +5 -3
  18. data/lib/containers/commands/tail.rb +7 -2
  19. data/lib/containers/commands/up.rb +1 -1
  20. data/lib/containers/commands/yarn/yarn.rb +11 -0
  21. data/lib/containers/concerns/configurable.rb +34 -9
  22. data/lib/containers/generator/cli.rb +6 -6
  23. data/lib/containers/generator/commands/compose.rb +17 -5
  24. data/lib/containers/generator/commands/config.rb +20 -6
  25. data/lib/containers/generator/commands/dockerfile.rb +12 -2
  26. data/lib/containers/generator/templates/containers.yml.erb +14 -4
  27. data/lib/containers/generator/templates/docker-compose.yml.erb +18 -18
  28. data/lib/containers/version.rb +1 -1
  29. metadata +85 -11
  30. data/lib/containers/commands/bundle.rb +0 -9
  31. data/lib/containers/commands/rails.rb +0 -9
  32. data/lib/containers/commands/yarn.rb +0 -9
  33. data/lib/containers/generator.rb +0 -40
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 693d21d25089049c59a5c47070a22ae26416d248bff32641c98f6dcce47cb9d8
4
- data.tar.gz: 3815ca80c36f79de060019e99006674718377cba79048893af0da7eea03088e1
3
+ metadata.gz: 5f3784b3013279542f697c744a5eea116d5272f09c1641d86d5b643d973b88d3
4
+ data.tar.gz: 70d25bfc0859a02f22032b8b5ef6bb8ac79458d4ee6eb0a57a32f7369676932d
5
5
  SHA512:
6
- metadata.gz: cbbd93da6bda8bcf772dcf5679048bf4282bc0a3d2b9a3c6d0251e4f9a154d9e415a78b7ef6abfa689502eacd3fe5571c8ce5997404c2220e60721aa3f6da391
7
- data.tar.gz: 66a9a386d8e52f19814a43a014fdcdbf8ea8c33c1a305f7048bfbc5a84a5b57696173690fd67ce1c6333575b8c56bd26a236b1e810f96297b26cbee5d78b20fb
6
+ metadata.gz: 6df7ceec75fd5654ec0cc6ea146781b116c61b6a415b723f2c799b863bcb91090dcd3c43df42323d3b1e76fcfd2cbe1eb940b0352feca65c2188fd345feab71f
7
+ data.tar.gz: 8ce7cb11bd0c47fdcb4e094c002c38e4a4ca9faef00256786765de4afdc330fbbead793af55eb01bb3f844f7888a97ee76a421dfaa8fd8cc0c0449ecf6fa46f0
data/exe/ctrs ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "containers"
4
+
5
+ Containers::CLI.start(ARGV)
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "pry-byebug"
4
3
  require "thor"
4
+ require "awesome_print"
5
5
  require "rainbow"
6
6
  require "active_support/all"
7
7
  require_relative "concerns/commandable"
@@ -20,8 +20,39 @@ module Containers
20
20
 
21
21
  protected
22
22
 
23
+ def container_name(service_name)
24
+ service_name ||= docker_default_service
25
+ return nil unless service_name
26
+ "#{app_name}-#{service_name}"
27
+ end
28
+
29
+ def service_name(container_name)
30
+ return nil unless container_name
31
+ container_name.sub(/\A#{app_name}-/, "")
32
+ end
33
+
34
+ def service_names
35
+ `containers list -s`.split("\n").reject do |line|
36
+ line.nil? || line.empty? || line.include?(Containers::Commandable::PREFIX)
37
+ end
38
+ end
39
+
23
40
  def container_names
24
- `containers list -f`.split("\n")
41
+ `containers list`.split("\n").reject do |line|
42
+ line.nil? || line.empty? || line.include?(Containers::Commandable::PREFIX)
43
+ end
44
+ end
45
+
46
+ def requested_container_names
47
+ return options[:container].compact if options[:container]
48
+ return requested_service_names.map { |name| container_name name }.compact if options[:service]
49
+ container_names
50
+ end
51
+
52
+ def requested_service_names
53
+ return options[:service].compact if options[:service]
54
+ return requested_container_names(options).map { |name| service_name name }.compact if options[:container]
55
+ service_names
25
56
  end
26
57
  end
27
58
  end
@@ -2,8 +2,10 @@
2
2
 
3
3
  class Containers::CLI < Thor
4
4
  desc "attach", "Attaches to a running container"
5
- method_option :container, type: :string, aliases: "-c", required: true, desc: "The short name for the container"
5
+ method_option :container, type: :string, aliases: "-c", desc: "The container name"
6
+ method_option :service, type: :string, aliases: "-s", desc: "The service name"
6
7
  def attach(*args)
7
- execute_command "docker attach #{project_name}-#{options[:container]} #{args.join " "}"
8
+ container = options[:container] || container_name(options[:service])
9
+ execute_command "docker attach #{container} #{args.join " "}"
8
10
  end
9
11
  end
@@ -2,8 +2,10 @@
2
2
 
3
3
  class Containers::CLI < Thor
4
4
  desc "bash", "Starts a bash shell"
5
- method_option :container, type: :string, aliases: "-c", default: "shell", desc: "The short name for the container"
5
+ method_option :container, type: :string, aliases: "-c", desc: "The container name"
6
+ method_option :service, type: :string, aliases: "-s", desc: "The service name"
6
7
  def bash(*args)
7
- execute_command "containers exec -c #{options[:container]} bash #{args.join " "}"
8
+ container = options[:container] || container_name(options[:service])
9
+ execute_command "containers exec -c #{container} bash #{args.join " "}"
8
10
  end
9
11
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Containers::CLI < Thor
4
+ desc "bin", "Runs executables in the ./bin directory"
5
+ method_option :container, type: :string, aliases: "-c", desc: "The container name"
6
+ method_option :service, type: :string, aliases: "-s", desc: "The service name"
7
+ def bin(*args)
8
+ container = options[:container] || container_name(options[:service])
9
+ execute_command "containers exec -c #{container} bin/#{args.join " "}"
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Containers::CLI < Thor
4
+ desc "config:print", "Prints the configuration for the current directory"
5
+ def config_print(*args)
6
+ awesome_print configuration
7
+ end
8
+
9
+ map "config:print" => :config_print
10
+ map "config" => :config_print
11
+ end
@@ -3,6 +3,6 @@
3
3
  class Containers::CLI < Thor
4
4
  desc "down", "Tears down the environment defined in docker-compose.yml"
5
5
  def down(*args)
6
- execute_command "docker compose down #{args.join " "}"
6
+ execute_command "docker compose #{docker_compose_files.map { |f| "-f #{f}" }.join " "} down #{args.join " "}"
7
7
  end
8
8
  end
@@ -2,9 +2,13 @@
2
2
 
3
3
  class Containers::CLI < Thor
4
4
  desc "exec", "Executes a command in a container"
5
- method_option :container, type: :string, aliases: "-c", default: "shell", desc: "The short name for the container"
5
+ long_desc "Also aliased as `x` for convenience"
6
+ method_option :container, type: :string, aliases: "-c", desc: "The container name"
7
+ method_option :service, type: :string, aliases: "-s", desc: "The service name"
6
8
  def exec(*args)
7
- options[:container] = "shell" if options[:container].to_s.strip == ""
8
- execute_command "docker exec -it #{project_name}-#{options[:container]} #{args.join " "}"
9
+ container = options[:container] || container_name(options[:service])
10
+ execute_command "docker exec -it #{container} #{args.join " "}"
9
11
  end
12
+
13
+ map "x" => :exec
10
14
  end
@@ -2,8 +2,10 @@
2
2
 
3
3
  class Containers::CLI < Thor
4
4
  desc "inspect", "Inspects a container"
5
- method_option :container, type: :string, aliases: "-c", required: true, desc: "The short name for the container"
5
+ method_option :container, type: :string, aliases: "-c", desc: "The container name"
6
+ method_option :service, type: :string, aliases: "-s", desc: "The service name"
6
7
  def inspect(*args)
7
- execute_command "docker inspect #{args.join " "} #{project_name}-#{options[:container]}"
8
+ container = options[:container] || container_name(options[:service])
9
+ execute_command "docker inspect #{args.join " "} #{container}"
8
10
  end
9
11
  end
@@ -2,16 +2,17 @@
2
2
 
3
3
  class Containers::CLI < Thor
4
4
  desc "list", "Lists all containers for this project"
5
+ long_desc "Also aliased as `ls` for convenience"
5
6
  method_option :detailed, type: :boolean, aliases: "-d", desc: "List detailed container information"
6
7
  method_option :service, type: :boolean, aliases: "-s", desc: "List container service names"
7
8
  def list(*args)
8
- return execute_command "docker ps -a | grep #{project_name}" if options[:detailed]
9
+ return execute_command "docker ps -a | grep #{app_name}" if options[:detailed]
9
10
 
10
11
  if options[:service]
11
- command = "containers list -f"
12
- puts_command "#{command} | #{Rainbow("(strip project name)").green.faint}"
12
+ command = "containers list"
13
+ puts_command "#{command} | #{Rainbow("(strip app_name)").green.faint}"
13
14
  list = `#{command}`.split("\n").reject { |item| item.strip == "" || item.include?(PREFIX) }
14
- puts list.map { |item| item.gsub(/\A#{project_name}-|\s/, "") }.sort.join("\n")
15
+ puts list.map { |item| item.gsub(/\A#{app_name}-|\s/, "") }.sort.join("\n")
15
16
  return
16
17
  end
17
18
 
@@ -20,4 +21,6 @@ class Containers::CLI < Thor
20
21
  list = `#{command}`.split("\n").reject { |item| item.strip == "" || item.include?(PREFIX) }
21
22
  puts list.map { |item| item.split(" ").last.strip }.sort.join("\n")
22
23
  end
24
+
25
+ map "ls" => :list
23
26
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Containers::CLI < Thor
4
+ desc "rails", "Runs the Rails command"
5
+ method_option :container, type: :string, aliases: "-c", desc: "The container name"
6
+ method_option :service, type: :string, aliases: "-s", desc: "The service name"
7
+ def rails(*args)
8
+ container = options[:container] || container_name(options[:service])
9
+ execute_command "containers bundle -c #{container} exec rails #{args.join " "}"
10
+ end
11
+ end
@@ -2,9 +2,11 @@
2
2
 
3
3
  class Containers::CLI < Thor
4
4
  desc "restart", "Restarts container(s)"
5
- method_option :container, type: :array, aliases: "-c", desc: "A list of container short names"
5
+ method_option :container, type: :array, aliases: "-c", desc: "A list of container names (space delimited)"
6
+ method_option :service, type: :array, aliases: "-s", desc: "A list of service names (space delimited)"
6
7
  def restart(*args)
7
- containers = options[:container] || container_names
8
- containers.each { |c| execute_command "docker restart #{args.join " "} #{c}", replace_current_process: false }
8
+ requested_container_names.each do |container_name|
9
+ execute_command "docker restart #{args.join " "} #{container_name}", replace_current_process: false
10
+ end
9
11
  end
10
12
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Containers::CLI < Thor
4
+ desc "bundle", "Runs the bundle command"
5
+ method_option :container, type: :string, aliases: "-c", desc: "The container name"
6
+ method_option :service, type: :string, aliases: "-s", desc: "The service name"
7
+ def bundle(*args)
8
+ container = options[:container] || container_name(options[:service])
9
+ execute_command "containers exec -c #{container} bundle #{args.join " "}"
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Containers::CLI < Thor
4
+ desc "rake", "Runs ruby's rake command"
5
+ method_option :container, type: :string, aliases: "-c", desc: "The container name"
6
+ method_option :service, type: :string, aliases: "-s", desc: "The service name"
7
+ def rake(*args)
8
+ container = options[:container] || container_name(options[:service])
9
+ execute_command "containers exec -c #{container} rake #{args.join " "}"
10
+ end
11
+ end
@@ -2,9 +2,11 @@
2
2
 
3
3
  class Containers::CLI < Thor
4
4
  desc "start", "Starts container(s)"
5
- method_option :container, type: :string, aliases: "-c", desc: "The short name for the container"
5
+ method_option :container, type: :array, aliases: "-c", desc: "A list of container names (space delimited)"
6
+ method_option :service, type: :array, aliases: "-s", desc: "A list of service names (space delimited)"
6
7
  def start(*args)
7
- return execute_command "docker start #{args.join " "} #{project_name}-#{options[:container]}" if options[:container]
8
- container_names.each { |c| execute_command "docker start #{args.join " "} #{c}", replace_current_process: false }
8
+ requested_container_names.each do |container_name|
9
+ execute_command "docker start #{args.join " "} #{container_name}", replace_current_process: false
10
+ end
9
11
  end
10
12
  end
@@ -2,9 +2,11 @@
2
2
 
3
3
  class Containers::CLI < Thor
4
4
  desc "stop", "Stops container(s)"
5
- method_option :container, type: :string, aliases: "-c", desc: "The short name for the container"
5
+ method_option :container, type: :array, aliases: "-c", desc: "A list of container names (space delimited)"
6
+ method_option :service, type: :array, aliases: "-s", desc: "A list of service names (space delimited)"
6
7
  def stop(*args)
7
- return execute_command "docker stop #{args.join " "} #{project_name}-#{options[:container]}" if options[:container]
8
- container_names.each { |c| execute_command "docker stop #{args.join " "} #{c}", replace_current_process: false }
8
+ requested_container_names.each do |container_name|
9
+ execute_command "docker stop #{args.join " "} #{container_name}", replace_current_process: false
10
+ end
9
11
  end
10
12
  end
@@ -2,9 +2,14 @@
2
2
 
3
3
  class Containers::CLI < Thor
4
4
  desc "tail", "Tails container logs"
5
- method_option :container, type: :array, aliases: "-c", required: true, desc: "The short name for the container (also supports a list of names)"
5
+ long_desc "Also aliased as `logs` and `log` for convenience"
6
+ method_option :container, type: :array, aliases: "-c", desc: "A list of container names (space delimited)"
7
+ method_option :service, type: :array, aliases: "-s", desc: "A list of service names (space delimited)"
6
8
  def tail(*args)
7
9
  args << "--since 5m" unless args.include?("--since")
8
- execute_command "docker compose logs #{args.join " "} -f #{options[:container].join " "}"
10
+ execute_command "docker compose #{docker_compose_files.map { |f| "-f #{f}" }.join " "} logs #{args.join " "} -f #{requested_service_names.join " "}"
9
11
  end
12
+
13
+ map "logs" => :tail
14
+ map "log" => :tail
10
15
  end
@@ -3,6 +3,6 @@
3
3
  class Containers::CLI < Thor
4
4
  desc "up", "Brings up the environment defined in docker-compose.yml"
5
5
  def up(*args)
6
- execute_command "docker compose up -d #{args.join " "}"
6
+ execute_command "docker compose #{docker_compose_files.map { |f| "-f #{f}" }.join " "} up -d #{args.join " "}"
7
7
  end
8
8
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Containers::CLI < Thor
4
+ desc "yarn", "Runs the yarn command"
5
+ method_option :container, type: :string, aliases: "-c", desc: "The container name"
6
+ method_option :service, type: :string, aliases: "-s", desc: "The service name"
7
+ def yarn(*args)
8
+ container = options[:container] || container_name(options[:service])
9
+ execute_command "containers exec -c #{container} yarn #{args.join " "}"
10
+ end
11
+ end
@@ -3,27 +3,52 @@
3
3
  module Containers::Configurable
4
4
  extend ActiveSupport::Concern
5
5
 
6
+ def self.gitname
7
+ email = begin
8
+ `git config --get user.email`.strip
9
+ rescue
10
+ nil
11
+ end
12
+ email&.split("@")&.first || "example"
13
+ end
14
+
6
15
  DEFAULT_CONFIGURATION = {
7
- "organization_name" => "example-organization",
8
- "project_name" => File.basename(Dir.pwd).parameterize,
9
- "app_directory" => ".",
10
- "docker_directory" => "."
16
+ "organization" => {
17
+ "name" => gitname
18
+ },
19
+ "app" => {
20
+ "name" => File.basename(Dir.pwd).parameterize,
21
+ "directory" => "."
22
+ },
23
+ "docker" => {
24
+ "directory" => ".",
25
+ "default_service" => nil,
26
+ "compose_files" => ["docker-compose.yml"]
27
+ }
11
28
  }.freeze
12
29
 
13
30
  def organization_name
14
- configuration["organization_name"]
31
+ configuration["organization"]["name"]
15
32
  end
16
33
 
17
- def project_name
18
- configuration["project_name"]
34
+ def app_name
35
+ configuration["app"]["name"]
19
36
  end
20
37
 
21
38
  def app_directory
22
- configuration["app_directory"]
39
+ configuration["app"]["directory"]
23
40
  end
24
41
 
25
42
  def docker_directory
26
- configuration["docker_directory"]
43
+ configuration["docker"]["directory"]
44
+ end
45
+
46
+ def docker_default_service
47
+ configuration["docker"]["default_service"]
48
+ end
49
+
50
+ def docker_compose_files
51
+ configuration["docker"]["compose_files"]
27
52
  end
28
53
 
29
54
  def configuration
@@ -15,29 +15,29 @@ module Containers::Generator
15
15
  Pathname.new(__dir__).join "templates/#{template_name}.erb"
16
16
  end
17
17
 
18
- def raw_template(template_name)
18
+ def template_string(template_name)
19
19
  File.read template_path(template_name)
20
20
  end
21
21
 
22
- def erb_template(template_name)
23
- ERB.new raw_template(template_name)
22
+ def template(template_name)
23
+ ERB.new template_string(template_name), trim_mode: "-"
24
24
  end
25
25
 
26
26
  def render_template(template_name, vars = {})
27
27
  view = Struct.new(*vars.keys).new(*vars.values).instance_eval { binding }
28
- erb_template(template_name).result view
28
+ template(template_name).result view
29
29
  end
30
30
 
31
31
  def render_external_template(template, vars = {})
32
32
  view = Struct.new(*vars.keys).new(*vars.values).instance_eval { binding }
33
33
 
34
- raw_template = if template.start_with?("http")
34
+ template_string = if template.start_with?("http")
35
35
  Net::HTTP.get URI.parse(template)
36
36
  else
37
37
  File.read template
38
38
  end
39
39
 
40
- ERB.new(raw_template).result view
40
+ ERB.new(template_string).result view
41
41
  end
42
42
  end
43
43
  end
@@ -11,19 +11,25 @@ class Containers::Generator::CLI < Thor
11
11
  def compose
12
12
  FileUtils.mkdir_p docker_directory
13
13
  path = File.expand_path("#{docker_directory}/docker-compose.yml")
14
+ exists = File.exist?(path)
15
+ original = File.read(path) if exists
14
16
 
15
- continue = if File.exist?(path)
16
- ask("#{Rainbow("docker-compose.yml already exists").red} Overwrite?", default: "Y").to_s.upcase == "Y"
17
+ continue = if exists
18
+ ask("#{Rainbow("docker-compose.yml already exists").red} Overwrite?", default: "n").to_s.upcase == "Y"
17
19
  else
18
20
  true
19
21
  end
20
22
 
21
23
  return unless continue
22
24
 
25
+ FileUtils.rm_f path
26
+
23
27
  vars = {
24
- organization_name: ask("What is the organization name? (lowercase, dasherized)", default: organization_name).to_s,
25
- project_name: ask("What is the project name? (lowercase, dasherized)", default: project_name).to_s,
26
- app_directory: File.expand_path(ask("What is the application directory? ", default: app_directory).to_s)
28
+ organization: {name: ask("What is the organization name?", default: organization_name).to_s},
29
+ app: {
30
+ name: ask("What is the app name?", default: app_name).to_s.parameterize,
31
+ directory: File.expand_path(ask("What is the path to the app directory? ", default: app_directory).to_s)
32
+ }
27
33
  }
28
34
 
29
35
  contents = if options[:template]
@@ -35,5 +41,11 @@ class Containers::Generator::CLI < Thor
35
41
  puts_command Rainbow("(Create #{path})").green.faint
36
42
  File.write path, contents
37
43
  puts Rainbow("docker-compose.yml created successfully").green.bright
44
+ rescue => error
45
+ puts Rainbow("Unexpected error! #{error.message}").red.bright
46
+ if exists && original
47
+ puts Rainbow("Restoring the original file.").green.faint
48
+ File.write path, original
49
+ end
38
50
  end
39
51
  end
@@ -8,22 +8,36 @@ class Containers::Generator::CLI < Thor
8
8
  desc "config", "Creates a .containers.yml config file for the project"
9
9
  def config
10
10
  path = File.expand_path(".containers.yml")
11
+ exists = File.exist?(path)
12
+ original = File.read(path) if exists
11
13
 
12
- continue = if File.exist?(path)
13
- ask("#{Rainbow(".containers.yml already exists").red} Overwrite?", default: "Y").to_s.upcase == "Y"
14
+ continue = if exists
15
+ ask("#{Rainbow(".containers.yml already exists").red} Overwrite?", default: "n").to_s.upcase == "Y"
14
16
  else
15
17
  true
16
18
  end
17
19
 
18
20
  return unless continue
19
21
 
22
+ FileUtils.rm_f path
23
+
20
24
  vars = {
21
- organization_name: ask("What is the organization name? (lowercase, dasherized)", default: organization_name).to_s,
22
- project_name: ask("What is the project name? (lowercase, dasherized)", default: project_name).to_s,
23
- app_directory: File.expand_path(ask("What is the application directory? ", default: app_directory).to_s),
24
- docker_directory: File.expand_path(ask("What is the docker directory? ", default: docker_directory).to_s)
25
+ organization_name: ask("What is the organization name?", default: organization_name).to_s.parameterize,
26
+ app_name: ask("What is the app name?", default: app_name).to_s.parameterize,
27
+ app_directory: File.expand_path(ask("What is the path to the app directory? ", default: app_directory).to_s),
28
+ docker: {
29
+ directory: File.expand_path(ask("What is the path to the Docker directory? ", default: docker_directory).to_s),
30
+ default_service: ask("What is the default Docker service?", default: docker_default_service).to_s,
31
+ compose_files: docker_compose_files
32
+ }
25
33
  }
26
34
 
27
35
  File.write path, render_template("containers.yml", vars)
36
+ rescue => error
37
+ puts Rainbow("Unexpected error! #{error.message}").red.bright
38
+ if exists && original
39
+ puts Rainbow("Restoring the original file.").green.faint
40
+ File.write path, original
41
+ end
28
42
  end
29
43
  end
@@ -11,15 +11,19 @@ class Containers::Generator::CLI < Thor
11
11
  def dockerfile
12
12
  FileUtils.mkdir_p docker_directory
13
13
  path = File.expand_path("#{docker_directory}/Dockerfile")
14
+ exists = File.exist?(path)
15
+ original = File.read(path) if exists
14
16
 
15
- continue = if File.exist?(path)
16
- ask("#{Rainbow("Dockerfile already exists").red} Overwrite?", default: "Y").to_s.upcase == "Y"
17
+ continue = if exists
18
+ ask("#{Rainbow("Dockerfile already exists").red} Overwrite?", default: "n").to_s.upcase == "Y"
17
19
  else
18
20
  true
19
21
  end
20
22
 
21
23
  return unless continue
22
24
 
25
+ FileUtils.rm_f path
26
+
23
27
  ruby_version = ask("What Ruby version does this project use?", default: "3.1.2").to_s
24
28
  vars = {ruby_version: ruby_version}
25
29
 
@@ -32,5 +36,11 @@ class Containers::Generator::CLI < Thor
32
36
  puts_command Rainbow("(Create #{path})").green.faint
33
37
  File.write path, contents
34
38
  puts Rainbow("Dockerfile created successfully").green.bright
39
+ rescue => error
40
+ puts Rainbow("Unexpected error! #{error.message}").red.bright
41
+ if exists && original
42
+ puts Rainbow("Restoring the original file.").green.faint
43
+ File.write path, original
44
+ end
35
45
  end
36
46
  end
@@ -1,5 +1,15 @@
1
1
  ---
2
- organization_name: <%= organization_name %>
3
- project_name: <%= project_name %>
4
- app_directory: <%= app_directory %>
5
- docker_directory: <%= docker_directory %>
2
+ organization:
3
+ name: <%= organization_name %>
4
+
5
+ app:
6
+ name: <%= app_name %>
7
+ directory: <%= app_directory %>
8
+
9
+ docker:
10
+ directory: <%= docker[:directory] %>
11
+ default_service: <%= docker[:default_service] %>
12
+ compose_files:
13
+ <% docker[:compose_files].each do |file| -%>
14
+ - <%= file %>
15
+ <% end -%>
@@ -14,17 +14,17 @@ x-default-env: &default_env
14
14
 
15
15
  x-default-app: &default_app
16
16
  build: .
17
- image: <%= organization_name %>/<%= project_name %>
18
- working_dir: /<%= project_name %>
17
+ image: <%= organization[:name] %>/<%= app[:name] %>
18
+ working_dir: /<%= app[:name] %>
19
19
  tty: true
20
20
  stdin_open: true
21
- env_file: <%= File.join app_directory, ".env" %>
21
+ env_file: <%= File.join app[:directory], ".env" %>
22
22
  environment:
23
23
  <<: *default_env
24
24
  volumes:
25
- - <%= app_directory %>:/<%= project_name %>:cached
25
+ - <%= app[:directory] %>:/<%= app[:name] %>:cached
26
26
  - bundle:/bundle:delegated
27
- - node_modules:/<%= project_name %>/node_modules:delegated
27
+ - node_modules:/<%= app[:name] %>/node_modules:delegated
28
28
 
29
29
  # TODO: dump pg database then rename db -> postgres
30
30
  volumes:
@@ -41,7 +41,7 @@ services:
41
41
  # ----------------------------------------------------------------------------
42
42
  postgres:
43
43
  image: postgres:13.4-alpine3.14
44
- container_name: <%= project_name %>-postgres
44
+ container_name: <%= app[:name] %>-postgres
45
45
  restart: unless-stopped
46
46
  environment:
47
47
  POSTGRES_PASSWORD: password
@@ -55,7 +55,7 @@ services:
55
55
  # ----------------------------------------------------------------------------
56
56
  redis_cable:
57
57
  image: redis:6.2.6-alpine3.14
58
- container_name: <%= project_name %>-redis-cable
58
+ container_name: <%= app[:name] %>-redis-cable
59
59
  restart: unless-stopped
60
60
  expose:
61
61
  - 6379
@@ -68,7 +68,7 @@ services:
68
68
  # ----------------------------------------------------------------------------
69
69
  redis_cache:
70
70
  image: redis:6.2.6-alpine3.14
71
- container_name: <%= project_name %>-redis-cache
71
+ container_name: <%= app[:name] %>-redis-cache
72
72
  restart: unless-stopped
73
73
  expose:
74
74
  - 6379
@@ -81,7 +81,7 @@ services:
81
81
  # ----------------------------------------------------------------------------
82
82
  redis_queue:
83
83
  image: redis:6.2.6-alpine3.14
84
- container_name: <%= project_name %>-redis-queue
84
+ container_name: <%= app[:name] %>-redis-queue
85
85
  restart: unless-stopped
86
86
  expose:
87
87
  - 6379
@@ -94,7 +94,7 @@ services:
94
94
  # ----------------------------------------------------------------------------
95
95
  shell:
96
96
  <<: *default_app
97
- container_name: <%= project_name %>-shell
97
+ container_name: <%= app[:name] %>-shell
98
98
  command: /bin/bash -c "tail -f /dev/null"
99
99
 
100
100
  # ----------------------------------------------------------------------------
@@ -102,7 +102,7 @@ services:
102
102
  # ----------------------------------------------------------------------------
103
103
  js:
104
104
  <<: *default_app
105
- container_name: <%= project_name %>-js
105
+ container_name: <%= app[:name] %>-js
106
106
  command: /bin/bash -c "yarn && yarn build --watch"
107
107
 
108
108
  # ----------------------------------------------------------------------------
@@ -110,7 +110,7 @@ services:
110
110
  # ----------------------------------------------------------------------------
111
111
  css:
112
112
  <<: *default_app
113
- container_name: <%= project_name %>-css
113
+ container_name: <%= app[:name] %>-css
114
114
  command: /bin/bash -c "yarn build:css --watch"
115
115
  depends_on:
116
116
  - js
@@ -120,7 +120,7 @@ services:
120
120
  # ----------------------------------------------------------------------------
121
121
  web:
122
122
  <<: *default_app
123
- container_name: <%= project_name %>-web
123
+ container_name: <%= app[:name] %>-web
124
124
  command: >
125
125
  /bin/bash -c "bundle &&
126
126
  rm -f tmp/pids/server.pid &&
@@ -145,7 +145,7 @@ services:
145
145
  # ----------------------------------------------------------------------------
146
146
  worker:
147
147
  <<: *default_app
148
- container_name: <%= project_name %>-worker
148
+ container_name: <%= app[:name] %>-worker
149
149
  command: /bin/bash -c "bin/rails log:clear &&
150
150
  bundle exec sidekiq -C config/sidekiq.yml"
151
151
  depends_on:
@@ -156,7 +156,7 @@ services:
156
156
  # ----------------------------------------------------------------------------
157
157
  anycable_ws:
158
158
  image: anycable/anycable-go:1.2
159
- container_name: <%= project_name %>-anycable-ws
159
+ container_name: <%= app[:name] %>-anycable-ws
160
160
  restart: unless-stopped
161
161
  environment:
162
162
  ANYCABLE_HOST: "0.0.0.0"
@@ -173,7 +173,7 @@ services:
173
173
  # ----------------------------------------------------------------------------
174
174
  anycable_rpc:
175
175
  <<: *default_app
176
- container_name: <%= project_name %>-anycable-rpc
176
+ container_name: <%= app[:name] %>-anycable-rpc
177
177
  restart: unless-stopped
178
178
  environment:
179
179
  <<: *default_env
@@ -191,10 +191,10 @@ services:
191
191
  # ----------------------------------------------------------------------------
192
192
  logs:
193
193
  image: amir20/dozzle
194
- container_name: <%= project_name %>-logs
194
+ container_name: <%= app[:name] %>-logs
195
195
  volumes:
196
196
  - /var/run/docker.sock:/var/run/docker.sock
197
197
  ports:
198
198
  - ${PORT_LOGS:-3004}:8080
199
199
  restart: unless-stopped
200
- command: "--filter name=<%= project_name %>*"
200
+ command: "--filter name=<%= app[:name] %>*"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Containers
4
- VERSION = "0.1.1"
4
+ VERSION = "0.1.3"
5
5
  end
metadata CHANGED
@@ -1,15 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: containers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hopsoft
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-08-20 00:00:00.000000000 Z
11
+ date: 2023-05-21 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '6.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '6.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: awesome_print
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '1.9'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '1.9'
13
41
  - !ruby/object:Gem::Dependency
14
42
  name: rainbow
15
43
  requirement: !ruby/object:Gem::Requirement
@@ -24,6 +52,20 @@ dependencies:
24
52
  - - ">="
25
53
  - !ruby/object:Gem::Version
26
54
  version: '3.1'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
27
69
  - !ruby/object:Gem::Dependency
28
70
  name: thor
29
71
  requirement: !ruby/object:Gem::Requirement
@@ -39,19 +81,33 @@ dependencies:
39
81
  - !ruby/object:Gem::Version
40
82
  version: '1.2'
41
83
  - !ruby/object:Gem::Dependency
42
- name: activesupport
84
+ name: magic_frozen_string_literal
43
85
  requirement: !ruby/object:Gem::Requirement
44
86
  requirements:
45
87
  - - ">="
46
88
  - !ruby/object:Gem::Version
47
- version: '6.0'
48
- type: :runtime
89
+ version: '0'
90
+ type: :development
49
91
  prerelease: false
50
92
  version_requirements: !ruby/object:Gem::Requirement
51
93
  requirements:
52
94
  - - ">="
53
95
  - !ruby/object:Gem::Version
54
- version: '6.0'
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: minitest
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
55
111
  - !ruby/object:Gem::Dependency
56
112
  name: pry-byebug
57
113
  requirement: !ruby/object:Gem::Requirement
@@ -66,34 +122,52 @@ dependencies:
66
122
  - - ">="
67
123
  - !ruby/object:Gem::Version
68
124
  version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: standardrb
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
69
139
  description: Manage local development environments with Docker
70
140
  email:
71
141
  - natehop@gmail.com
72
142
  executables:
73
143
  - containers
144
+ - ctrs
74
145
  extensions: []
75
146
  extra_rdoc_files: []
76
147
  files:
77
148
  - exe/containers
149
+ - exe/ctrs
78
150
  - lib/containers.rb
79
151
  - lib/containers/cli.rb
80
152
  - lib/containers/commands/attach.rb
81
153
  - lib/containers/commands/bash.rb
82
- - lib/containers/commands/bundle.rb
154
+ - lib/containers/commands/bin.rb
155
+ - lib/containers/commands/config/print.rb
83
156
  - lib/containers/commands/down.rb
84
157
  - lib/containers/commands/exec.rb
85
158
  - lib/containers/commands/inspect.rb
86
159
  - lib/containers/commands/list.rb
87
- - lib/containers/commands/rails.rb
160
+ - lib/containers/commands/rails/rails.rb
88
161
  - lib/containers/commands/restart.rb
162
+ - lib/containers/commands/ruby/bundle.rb
163
+ - lib/containers/commands/ruby/rake.rb
89
164
  - lib/containers/commands/start.rb
90
165
  - lib/containers/commands/stop.rb
91
166
  - lib/containers/commands/tail.rb
92
167
  - lib/containers/commands/up.rb
93
- - lib/containers/commands/yarn.rb
168
+ - lib/containers/commands/yarn/yarn.rb
94
169
  - lib/containers/concerns/commandable.rb
95
170
  - lib/containers/concerns/configurable.rb
96
- - lib/containers/generator.rb
97
171
  - lib/containers/generator/cli.rb
98
172
  - lib/containers/generator/commands/compose.rb
99
173
  - lib/containers/generator/commands/config.rb
@@ -127,7 +201,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
127
201
  - !ruby/object:Gem::Version
128
202
  version: '0'
129
203
  requirements: []
130
- rubygems_version: 3.3.7
204
+ rubygems_version: 3.4.10
131
205
  signing_key:
132
206
  specification_version: 4
133
207
  summary: Manage local development environments with Docker
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Containers::CLI < Thor
4
- desc "bundle", "Runs the bundle command"
5
- method_option :container, type: :string, aliases: "-c", default: "shell", desc: "The short name for the container"
6
- def bundle(*args)
7
- execute_command "containers exec -c #{options[:container]} bundle #{args.join " "}"
8
- end
9
- end
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Containers::CLI < Thor
4
- desc "rails", "Runs the Rails command"
5
- method_option :container, type: :string, aliases: "-c", default: "shell", desc: "The short name for the container"
6
- def rails(*args)
7
- execute_command "containers bundle -c #{options[:container]} exec rails #{args.join " "}"
8
- end
9
- end
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Containers::CLI < Thor
4
- desc "yarn", "Runs the yarn command"
5
- method_option :container, type: :string, aliases: "-c", default: "shell", desc: "The short name for the container"
6
- def yarn(*args)
7
- execute_command "containers exec -c #{options[:container]} yarn #{args.join " "}"
8
- end
9
- end
@@ -1,40 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "erb"
4
-
5
- class Generator < Thor
6
- desc "dockerfile", "Creates a Dockerfile for the project"
7
- def dockerfile
8
- path = File.expand_path("Dockerfile")
9
-
10
- continue = if File.exist?(path)
11
- ask("#{Rainbow("Dockerfile already exists").red} Overwrite?", default: "Y").to_s.upcase == "Y"
12
- else
13
- true
14
- end
15
-
16
- return unless continue
17
-
18
- ruby_version = ask("What Ruby version does this project use?", default: "3.1.2").to_s
19
- File.write path, render("Dockerfile", ruby_version: ruby_version)
20
- end
21
-
22
- desc "compose", "Creates a docker-compose.yml file for the project"
23
- def compose
24
- end
25
-
26
- private
27
-
28
- def root_path
29
- File.expand_path(File.join(__dir__, "..", ".."))
30
- end
31
-
32
- def template(name)
33
- ERB.new(File.read(File.join(root_path, "lib/containers/templates/#{name}.erb")))
34
- end
35
-
36
- def render(template_name, vars = {})
37
- view = Struct.new(*vars.keys).new(*vars.values).instance_eval { binding }
38
- template(template_name).result view
39
- end
40
- end