neptuno 1.0.10 → 1.2.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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +6 -5
  3. data/Rakefile +6 -6
  4. data/exe/neptuno +1 -1
  5. data/lib/neptuno/cli/activate.rb +19 -19
  6. data/lib/neptuno/cli/base.rb +4 -4
  7. data/lib/neptuno/cli/clone.rb +8 -2
  8. data/lib/neptuno/cli/configure.rb +3 -3
  9. data/lib/neptuno/cli/execute.rb +4 -4
  10. data/lib/neptuno/cli/init.rb +5 -5
  11. data/lib/neptuno/cli/install.rb +15 -17
  12. data/lib/neptuno/cli/list.rb +21 -31
  13. data/lib/neptuno/cli/version.rb +1 -1
  14. data/lib/neptuno/cli.rb +28 -28
  15. data/lib/neptuno/docker/attach.rb +2 -2
  16. data/lib/neptuno/docker/build.rb +5 -5
  17. data/lib/neptuno/docker/down.rb +18 -9
  18. data/lib/neptuno/docker/log.rb +1 -1
  19. data/lib/neptuno/docker/restart.rb +8 -8
  20. data/lib/neptuno/docker/services.rb +2 -2
  21. data/lib/neptuno/docker/up.rb +6 -11
  22. data/lib/neptuno/environment/config.rb +3 -3
  23. data/lib/neptuno/environment/update.rb +1 -1
  24. data/lib/neptuno/git/pull.rb +2 -2
  25. data/lib/neptuno/git/stash.rb +2 -2
  26. data/lib/neptuno/k8s/attach.rb +6 -6
  27. data/lib/neptuno/overmind/connect.rb +20 -71
  28. data/lib/neptuno/overmind/start.rb +22 -56
  29. data/lib/neptuno/overmind/stop.rb +12 -6
  30. data/lib/neptuno/services/add.rb +9 -15
  31. data/lib/neptuno/services/destroy.rb +1 -1
  32. data/lib/neptuno/services/list.rb +3 -2
  33. data/lib/neptuno/services/update.rb +8 -8
  34. data/lib/neptuno/templates/{tmuxinator.yml → .tmuxinator.yml} +2 -4
  35. data/lib/neptuno/templates/docker-compose.yml +18 -7
  36. data/lib/neptuno/templates/neptuno.yml +6 -0
  37. data/lib/neptuno/tty/config.rb +44 -10
  38. data/lib/neptuno/tty/file.rb +6 -6
  39. data/lib/neptuno/version.rb +1 -1
  40. data/lib/neptuno.rb +11 -11
  41. data/neptuno.gemspec +26 -26
  42. metadata +16 -15
@@ -4,7 +4,7 @@ module Neptuno
4
4
  module Docker
5
5
  module Services
6
6
  include Neptuno::TTY::Config
7
- require 'yaml'
7
+ require "yaml"
8
8
 
9
9
  def running_services
10
10
  running_services = `cd ~/.neptuno/projects/#{current_project} && docker compose ps | awk '{ print $3 }' | awk 'NR>1'`
@@ -13,7 +13,7 @@ module Neptuno
13
13
 
14
14
  def registered_services
15
15
  dc = YAML.load_file("#{neptuno_path}/docker-compose.yml")
16
- dc['services'].keys
16
+ dc["services"].keys
17
17
  end
18
18
 
19
19
  def stopped_services
@@ -4,21 +4,16 @@ module Neptuno
4
4
  module Docker
5
5
  # Build docker container for Neptuno project
6
6
  class Up < Neptuno::CLI::Base
7
- desc 'Docker: bring up docker containers for current project'
7
+ desc "Docker: bring up docker containers for current project"
8
8
 
9
- option :all, type: :boolean, default: false, desc: 'Run on all services'
10
- option :log, type: :boolean, default: false, desc: 'Show service log (only first service)'
11
- argument :services, type: :array, required: false, desc: 'Optional list of services'
9
+ option :all, type: :boolean, default: false, desc: "Run on all services"
10
+ option :wait, type: :boolean, default: true, desc: "Wait for services to be healthy"
11
+ argument :services, type: :array, required: false, desc: "Optional list of services"
12
12
 
13
13
  def call(services: [], **options)
14
- command_services_to('come up', all: options.fetch(:all), services_as_args: services) do |services, project|
14
+ command_services_to("come up", all: options.fetch(:all), services_as_args: services) do |services, _project|
15
15
  make_service_files(services)
16
- system("cd #{neptuno_path} && docker compose up -d #{services.join(' ')}")
17
- success = system("cd #{neptuno_path} && docker logs -f #{project}_#{services.first}_1") if options.fetch(:log)
18
- unless success
19
- puts "Trying #{project}-#{services.first}-1"
20
- system("cd #{neptuno_path} && docker logs -f #{project}-#{services.first}-1") if options.fetch(:log)
21
- end
16
+ system("cd #{neptuno_path} && docker-compose up -d --wait #{services.join(" ")}")
22
17
  end
23
18
  end
24
19
  end
@@ -4,12 +4,12 @@ module Neptuno
4
4
  module Environment
5
5
  # Build docker container for Neptuno project
6
6
  class Config < Neptuno::CLI::Base
7
- desc 'Environment: Configure local or remote'
7
+ desc "Environment: Configure local or remote"
8
8
 
9
- argument :services, type: :array, required: false, desc: 'Optional list of services'
9
+ argument :services, type: :array, required: false, desc: "Optional list of services"
10
10
 
11
11
  def call(services: [], **_options)
12
- command_services_to('print', services_as_args: services) do |services|
12
+ command_services_to("print", services_as_args: services) do |services|
13
13
  services.each do |service|
14
14
  puts service
15
15
  end
@@ -4,7 +4,7 @@ module Neptuno
4
4
  module Environment
5
5
  # Build docker container for Neptuno project
6
6
  class Update < Neptuno::CLI::Base
7
- desc 'Environment: Update all environment files'
7
+ desc "Environment: Update all environment files"
8
8
 
9
9
  def call
10
10
  env_path = "#{neptuno_path}/environments/"
@@ -4,10 +4,10 @@ module Neptuno
4
4
  module Git
5
5
  # Pull all submodule changes
6
6
  class Pull < Neptuno::CLI::Base
7
- desc 'Git: pull all submodule changes'
7
+ desc "Git: pull all submodule changes"
8
8
 
9
9
  def call(services: [], **_options)
10
- system('git submodule foreach git pull')
10
+ system("git submodule foreach git pull")
11
11
  end
12
12
  end
13
13
  end
@@ -4,10 +4,10 @@ module Neptuno
4
4
  module Git
5
5
  # Stash all submodule changes
6
6
  class Stash < Neptuno::CLI::Base
7
- desc 'Git: stash all submodule changes'
7
+ desc "Git: stash all submodule changes"
8
8
 
9
9
  def call(services: [], **_options)
10
- system('git submodule foreach git stash')
10
+ system("git submodule foreach git stash")
11
11
  end
12
12
  end
13
13
  end
@@ -4,20 +4,20 @@ module Neptuno
4
4
  module K8s
5
5
  class Attach < Neptuno::CLI::Base
6
6
  include ::Neptuno::TTY::Config
7
- desc 'K8s: Attach to a container with k8s'
7
+ desc "K8s: Attach to a container with k8s"
8
8
 
9
- option :context, type: :string, default: 'int', desc: 'K8s context to run in'
10
- option :namespace, type: :string, default: 'thrillshare', desc: 'K8s namespace to run in'
11
- option :dependent, type: :string, desc: 'Dependent service'
9
+ option :context, type: :string, default: "int", desc: "K8s context to run in"
10
+ option :namespace, type: :string, default: "thrillshare", desc: "K8s namespace to run in"
11
+ option :dependent, type: :string, desc: "Dependent service"
12
12
  option :pr, type: :integer, desc: "PR's Github ID"
13
13
 
14
14
  def call(**options)
15
- command_service_to('attach with k8s', service_as_args: options[:args]&.first) do |service, _project|
15
+ command_service_to("attach with k8s", service_as_args: options[:args]&.first) do |service, _project|
16
16
  deployment = "deploy/#{options[:dependent] || service}"
17
17
  deployment += "-#{service}-#{options[:pr]}" unless options[:pr].nil?
18
18
 
19
19
  context = options[:context]
20
- context = 'qa' unless options[:pr].nil?
20
+ context = "qa" unless options[:pr].nil?
21
21
 
22
22
  system("kubectl config use-context #{context} > /dev/null 2>&1")
23
23
  puts "Attaching to #{deployment} in the #{options[:namespace]} namespace using the #{context} context"
@@ -7,91 +7,40 @@ module Neptuno
7
7
  include ::Neptuno::TTY::Config
8
8
  desc 'Overmind: Connect to processes inside docker containers'
9
9
 
10
- option :force, type: :boolean, default: false, desc: 'Try to connect disrigarding container status'
10
+ option :up, type: :boolean, default: true, desc: 'Try to start containers before connecting'
11
+ option :start, type: :boolean, default: true, desc: 'Try to start processes on containers before connecting'
11
12
  option :all, type: :boolean, default: false, desc: 'Run on all services'
12
- option :up, type: :boolean, default: false, desc: 'Try to start containers before connecting'
13
- option :tmux, type: :boolean, default: false, desc: 'Connect to services using Tmux'
14
- option :tmux_sessions, type: :boolean, default: false, desc: 'Connect to services using Tmux'
13
+ option :wait, type: :boolean, default: true, desc: 'Wait for all services to be healthy'
14
+ option :dependencies, type: :boolean, default: true, desc: 'Connect to service and its dependencies'
15
15
  argument :services, type: :array, required: false, desc: 'Optional list of services'
16
16
 
17
17
  def call(services: [], **options)
18
- multi_spinner = ::TTY::Spinner::Multi.new('[:spinner] Services')
19
- spinners = {}
20
- count = 0
21
18
  command_services_to('connect to procs', all: options.fetch(:all), services_as_args: services) do |services|
22
- system("cd #{neptuno_path} && docker-compose up -d #{services.join(' ')}") if options.fetch(:up)
23
- running_services = ::Neptuno::CLI::List.new.running_services.first.keys
24
- running_services.sort.each do |service|
25
- spinners[service] ||= multi_spinner.register("[:spinner] :state #{service}")
26
- spinners[service].update(state: '- ')
27
- spinners[service].auto_spin
28
- end
29
- loop do
30
- ps = `cd #{neptuno_path} && docker-compose ps`.split("\n").compact.select { |x| x.match(/^\s*#{project}/) }
31
-
32
- running_services.sort.each do |service|
33
- service_ps = ps.find {|s| s =~ /#{project}[-_]#{service}[-_]\d\s/ }
19
+ `neptuno up #{services.join(' ')}` if options.fetch(:up)
20
+ original_services = services
21
+ services = services_with_procs.intersection(get_dependants(services).concat(services).uniq).sort
34
22
 
35
- status = :dead if service_ps.to_s.include?('exited')
36
- status = :starting if service_ps.to_s.include?('starting')
37
- status = :unhealthy if service_ps.to_s.include?('(unhealthy')
38
- status = :healthy if service_ps.to_s.include?('(healthy')
39
- status = :force if options.fetch(:force)
23
+ outside_tmux = `echo $TMUX`.strip.empty?
40
24
 
41
- case status
42
- when :force
43
- spinners[service].success
44
- `cd #{neptuno_path}/procfiles/#{service} && overmind start -D -N #{auto_restart_procs.unshift("-r").join(" ") if auto_restart_procs.to_a.count > 0} > /dev/null 2>&`
45
- when :dead
46
- spinners[service].update(state: 'dead ')
47
- spinners[service].error
48
- when :starting
49
- spinners[service].update(state: 'starting ')
50
- when :unhealthy
51
- spinners[service].update(state: 'unhealthy ')
52
- spinners[service].error if spinners[service].instance_variable_get(:@state) == :spinning && count > 50
53
- when :healthy
54
- spinners[service].update(state: 'ready ')
55
- spinners[service].success
56
- else
57
- spinners[service].update(state: 'down ')
58
- spinners[service].error
25
+ if config.fetch('procfile_manager') == 'tmux'
26
+ services.each do |service|
27
+ if /#{service}/.match?(`tmux ls`)
28
+ puts "Neptuno wil use existing Tmux session for: #{service}"
29
+ next
59
30
  end
60
- end
61
- break if spinners.values.map { |s| s.instance_variable_get(:@state) }.uniq.all?(:stopped)
62
31
 
63
- count += 1
64
- sleep(5)
65
- end
66
- spinner = ::TTY::Spinner.new('Neptuno: Connecting[:spinner]', format: :dots)
67
- spinner.auto_spin
68
-
69
- healthy_services = spinners.select { |_k, v| v.instance_variable_get(:@succeeded) == :success }.keys
70
- spinner.stop
71
- if config.fetch('procfile_manager') == 'tmux'
72
- healthy_services.each do |service|
73
- pid = spawn("cd #{neptuno_path} && tmuxinator start neptuno_#{service} #{service} -n #{service}",
32
+ pid = spawn("cd #{neptuno_path} && tmuxinator start neptuno_#{service} #{service}",
74
33
  3 => '/dev/null')
75
34
  Process.detach(pid)
76
- puts "Neptuno started tmux session for: #{service}"
35
+ puts "Neptuno started Tmux session for: #{service}" if `echo $TMUX`.strip.empty?
77
36
  end
78
37
  else
79
- spinners.select { |_k, v| v.instance_variable_get(:@succeeded) == :success }.each_key do |service|
80
- system("cd #{neptuno_path}/procfiles/#{service} && overmind start -D -N #{auto_restart_procs.unshift("-r").join(" ") if auto_restart_procs.to_a.count > 0} > /dev/null 2>&1")
81
- end
82
- sleep(5)
83
- spinner.stop
84
- if options.fetch(:tmux)
85
- system("cd #{neptuno_path} && tmuxinator start neptuno #{healthy_services.join(' ')}")
38
+ puts `neptuno start --no-up #{services.join(' ')}` if options.fetch(:start)
39
+ if outside_tmux
40
+ system("cd #{neptuno_path} && tmuxinator start neptuno #{services.join(' ')}")
86
41
  else
87
- begin
88
- system("cd #{neptuno_path}/procfiles/#{services.first} && overmind connect shell", exception: true)
89
- rescue RuntimeError
90
- system("cd #{neptuno_path} && docker compose exec #{service} kill -9 -1")
91
- system("cd #{neptuno_path}/procfiles/#{service} && rm .overmind.sock > /dev/null 2>&1")
92
- system("cd #{neptuno_path}/procfiles/#{service} && overmind start -D -N #{auto_restart_procs.unshift("-r").join(" ") if auto_restart_procs.to_a.count > 0} > /dev/null 2>&1")
93
- retry
94
- end
42
+ puts "Connecting to #{original_services.first}"
43
+ system("cd #{neptuno_path}/procfiles/#{original_services.first} && overmind connect shell")
95
44
  end
96
45
  end
97
46
  end
@@ -5,67 +5,33 @@ module Neptuno
5
5
  # Build docker container for Neptuno project
6
6
  class Start < Neptuno::CLI::Base
7
7
  include ::Neptuno::TTY::Config
8
- desc 'Overmind: Start processes inside docker containers'
8
+ desc "Overmind: Start processes inside docker containers"
9
9
 
10
- option :force, type: :boolean, default: false, desc: 'Try to start disrigarding container status'
11
- option :all, type: :boolean, default: false, desc: 'Run on all services'
12
- option :up, type: :boolean, default: false, desc: 'Try to start containers before connecting'
13
- argument :services, type: :array, required: false, desc: 'Optional list of services'
10
+ option :all, type: :boolean, default: false, desc: "Run on all services"
11
+ option :up, type: :boolean, default: true, desc: "Try to start containers before connecting"
12
+ argument :services, type: :array, required: false, desc: "Optional list of services"
14
13
 
15
14
  def call(services: [], **options)
16
- multi_spinner = ::TTY::Spinner::Multi.new('[:spinner] Services')
17
- spinners = {}
18
- count = 0
19
- command_services_to('connect to procs', all: options.fetch(:all), services_as_args: services) do |services|
20
- system("cd #{neptuno_path} && docker compose up -d #{services.join(' ')}") if options.fetch(:up)
21
- running_services = ::Neptuno::CLI::List.new.running_services.first.keys
22
- running_services.sort.each do |service|
23
- spinners[service] ||= multi_spinner.register("[:spinner] :state #{service}")
24
- spinners[service].update(state: '- ')
25
- spinners[service].auto_spin
26
- end
27
- loop do
28
- ps = `cd #{neptuno_path} && docker compose ps`.split("\n").compact.select { |x| x.match(/^\s*#{project}/) }
29
-
30
- running_services.sort.each do |service|
31
- service_ps = ps.find {|s| s =~ /#{project}[-_]#{service}[-_]\d\s/ }
32
-
33
- status = :dead if service_ps.to_s.include?('exited')
34
- status = :starting if service_ps.to_s.include?('starting')
35
- status = :unhealthy if service_ps.to_s.include?('(unhealthy')
36
- status = :healthy if service_ps.to_s.include?('(healthy')
37
- status = :force if options.fetch(:force)
38
-
39
- case status
40
- when :force
41
- spinners[service].success
42
- `cd #{neptuno_path}/procfiles/#{service} && overmind start -D -N > /dev/null 2>&1`
43
- when :dead
44
- spinners[service].update(state: 'dead ')
45
- spinners[service].error
46
- when :starting
47
- spinners[service].update(state: 'starting ')
48
- when :unhealthy
49
- spinners[service].update(state: 'unhealthy ')
50
- spinners[service].error if spinners[service].instance_variable_get(:@state) == :spinning && count > 50
51
- when :healthy
52
- spinners[service].update(state: 'ready ')
53
- spinners[service].success
54
- `cd #{neptuno_path}/procfiles/#{service} && overmind start -D -N > /dev/null 2>&1`
55
- else
56
- spinners[service].update(state: 'down ')
57
- spinners[service].error
58
- end
15
+ command_services_to("start procs", all: options.fetch(:all), services_as_args: services) do |services|
16
+ `neptuno up #{services.join(" ")}` if options.fetch(:up)
17
+
18
+ services = services_with_procs.intersection(get_dependants(services).concat(services).uniq).sort
19
+ puts "Starting processes on services: #{services.join(", ")}"
20
+
21
+ if config.fetch("procfile_manager") == "tmux"
22
+ services.each do |service|
23
+ pid = spawn("cd #{neptuno_path} && tmuxinator start neptuno_#{service} #{service} -n #{service}",
24
+ 3 => "/dev/null")
25
+ Process.detach(pid)
26
+ puts "Neptuno started Tmux session for: #{service}" if `echo $TMUX`.strip.empty?
27
+ end
28
+ else
29
+ services.each do |service|
30
+ system("cd #{neptuno_path}/procfiles/#{service} && overmind start -D -N #{if auto_restart_procs.to_a.size > 0
31
+ ("-r " + auto_restart_procs.join(",") + " ")
32
+ end} > /dev/null 2>&1")
59
33
  end
60
- break if spinners.values.map { |s| s.instance_variable_get(:@state) }.uniq.all?(:stopped)
61
-
62
- count += 1
63
- sleep(5)
64
34
  end
65
- spinner = ::TTY::Spinner.new('Neptuno: Starting[:spinner]', format: :dots)
66
- spinner.auto_spin
67
-
68
- spinner.stop
69
35
  end
70
36
  end
71
37
  end
@@ -4,16 +4,22 @@ module Neptuno
4
4
  module Overmind
5
5
  # Build docker container for Neptuno project
6
6
  class Stop < Neptuno::CLI::Base
7
- desc 'Overmind: Stop processes inside docker containers'
7
+ desc "Stop processes inside docker containers"
8
8
 
9
- option :all, type: :boolean, default: false, desc: 'Run on all services'
10
- argument :services, type: :array, required: false, desc: 'Optional list of services'
9
+ option :all, type: :boolean, default: false, desc: "Run on all services"
10
+ argument :services, type: :array, required: false, desc: "Optional list of services"
11
11
 
12
12
  def call(services: [], **options)
13
- command_services_to('stop procs', all: options.fetch(:all), services_as_args: services) do |services|
14
- services.each do |service|
13
+ command_services_to("stop procs", all: options.fetch(:all), services_as_args: services) do |services|
14
+ services_to_stop = services.intersection(services_with_procs).intersection(running_services)
15
+ services_to_stop.each do |service|
15
16
  system("cd #{neptuno_path} && docker compose exec #{service} kill -9 -1")
16
- system("cd #{neptuno_path}/procfiles/#{service} && rm .overmind.sock > /dev/null 2>&1")
17
+ if config.fetch("procfile_manager") == "tmux"
18
+ system("tmux kill-session -t #{service} 2>/dev/null ")
19
+ puts "Neptuno killed Tmux session for: #{service}" if `echo $TMUX`.strip.empty?
20
+ else
21
+ system("cd #{neptuno_path}/procfiles/#{service} && rm .overmind.sock > /dev/null 2>&1")
22
+ end
17
23
  end
18
24
  end
19
25
  end
@@ -8,24 +8,18 @@ module Neptuno
8
8
  include TTY::Config
9
9
  include TTY::File
10
10
 
11
- desc 'Add a Neptuno service with Git'
11
+ desc "Add a Neptuno service with Git"
12
12
 
13
13
  def call(**)
14
- name = prompt.ask('? Service name:')
15
- add_name_to_config(name)
16
- repo = prompt.ask('? Git repo:')
14
+ name = prompt.ask("? Service name:")
15
+ repo = prompt.ask("? Git repo:")
17
16
  clone_into_folder(repo, name)
18
- add_dockerfile(name)
17
+ # add_dockerfile(name)
19
18
  add_procfile(name)
20
19
  add_environment(name)
21
20
  add_service_to_dc(name)
22
21
  end
23
22
 
24
- def add_name_to_config(name)
25
- config.append(name, to: :services) unless config.fetch(:services).include? name
26
- config.write(force: true)
27
- end
28
-
29
23
  def clone_into_folder(repo, name)
30
24
  if repo.nil?
31
25
  command.run("mkdir #{neptuno_path}/services/#{name}")
@@ -62,16 +56,16 @@ module Neptuno
62
56
  stdin_open: true
63
57
  tty: true
64
58
  command: ash
65
- build:#{' '}
59
+ build:#{" "}
66
60
  context: .
67
61
  dockerfile: ./dockerfiles/#{name}/Dockerfile
68
- env_file:#{' '}
62
+ env_file:#{" "}
69
63
  - ./environments/#{name}/default
70
- # volumes:#{' '}
64
+ # volumes:#{" "}
71
65
  # -
72
- # ports:#{' '}
66
+ # ports:#{" "}
73
67
  # -
74
- # depends_on:#{' '}
68
+ # depends_on:#{" "}
75
69
  # -
76
70
 
77
71
  #---------------------------------------------------------------
@@ -4,7 +4,7 @@ module Neptuno
4
4
  module Services
5
5
  # Add project to neptuno
6
6
  class Destroy < Neptuno::CLI::Base
7
- desc 'Remove a Neptuno service'
7
+ desc "Remove a Neptuno service"
8
8
 
9
9
  def call(**)
10
10
  puts destroy
@@ -4,9 +4,10 @@ module Neptuno
4
4
  module Services
5
5
  # Add project to neptuno
6
6
  class List < Neptuno::CLI::Base
7
- desc 'List Neptuno projects'
7
+ desc "List Neptuno projects"
8
8
 
9
- def call(**); end
9
+ def call(**)
10
+ end
10
11
  end
11
12
  end
12
13
  end
@@ -4,15 +4,15 @@ module Neptuno
4
4
  module Services
5
5
  # Update project to to latest GH master/main
6
6
  class Update < Neptuno::CLI::Base
7
- desc 'Stashes changes and pulls latest from main/master'
7
+ desc "Stashes changes and pulls latest from main/master"
8
8
 
9
- option :all, type: :boolean, default: false, desc: 'Run on all services'
9
+ option :all, type: :boolean, default: false, desc: "Run on all services"
10
10
  option :main, type: :boolean, default: false,
11
- desc: "Keep service on main/master after pull. Uncommited changes are stashed as 'neptuno_stash'"
12
- argument :services, type: :array, required: false, desc: 'Optional list of services'
11
+ desc: "Keep service on main/master after pull. Uncommited changes are stashed as 'neptuno_stash'"
12
+ argument :services, type: :array, required: false, desc: "Optional list of services"
13
13
 
14
14
  def call(services: [], **options)
15
- command_services_to('update', all: options.fetch(:all), services_as_args: services) do |services|
15
+ command_services_to("update", all: options.fetch(:all), services_as_args: services) do |services|
16
16
  services.each do |service|
17
17
  puts "---Updating #{service}---"
18
18
  current_branch = `git branch --show-current`
@@ -22,14 +22,14 @@ module Neptuno
22
22
  `cd #{neptuno_path}/services/#{service} 2>/dev/null && git checkout master 2>/dev/null`
23
23
  system("cd #{neptuno_path}/services/#{service} 2>/dev/null && git pull")
24
24
  unless options.fetch(:main)
25
- stash_id = `git stash list`.lines.find { |str| str =~ /neptuno_stash/ }&.split(':')&.first
25
+ stash_id = `git stash list`.lines.find { |str| str =~ /neptuno_stash/ }&.split(":")&.first
26
26
  `cd #{neptuno_path}/services/#{service} 2>/dev/null && git checkout #{current_branch} 2>/dev/null`
27
27
  if stash_id
28
- puts 'Applying stashed changes'
28
+ puts "Applying stashed changes"
29
29
  system("cd #{neptuno_path}/services/#{service} 2>/dev/null && git stash pop -q #{stash_id}")
30
30
  end
31
31
  end
32
- puts ''
32
+ puts ""
33
33
  end
34
34
  end
35
35
  end
@@ -1,4 +1,5 @@
1
- # ./.tmuxinator.yml
1
+ # This file defines what Tmux will do when Neptuno connects to your services.
2
+ # You can add or remove Tmux windows and panes for each service here.
2
3
 
3
4
  <% if YAML.load_file('neptuno.yml')["procfile_manager"] == "tmux" %>
4
5
  name: <%= @args[0] %>
@@ -19,9 +20,7 @@ on_project_exit: tmux kill-session -t neptuno
19
20
  windows:
20
21
  - neptuno:
21
22
  panes:
22
- - sleep 2 && vim
23
23
  - neptuno ps
24
- - # host shell
25
24
 
26
25
  <% @args.each do |service| %>
27
26
  - <%= service %>:
@@ -40,5 +39,4 @@ windows:
40
39
  neptuno c <%= service %>
41
40
  <% end %>
42
41
  <% end %>
43
-
44
42
  <% end %>
@@ -1,7 +1,18 @@
1
- version: '3'
2
- services:
3
- alpine:
4
- image: alpine
5
- tty: true
6
- stdin_open: true
7
- command: ash
1
+ # This file should contain all your project's services with references to their dockerfiles, env_files, volumes, etc.
2
+ # You can then connect to your services using `neptuno connect <service1 service2 ...>`
3
+ #
4
+ # Example:
5
+ #
6
+ # version: '3'
7
+ #
8
+ # services:
9
+ # alpine:
10
+ # tty: true
11
+ # stdin_open: true
12
+ # build:
13
+ # context: .
14
+ # dockerfile: ./dockerfiles/alpine/Dockerfile
15
+ # env_file:
16
+ # - ./environments/alpine/local_env
17
+ # volumes:
18
+ # - ./services/alpine:/usr/src/app:cached
@@ -0,0 +1,6 @@
1
+ ---
2
+ # mode: ide
3
+ # procfile_manager = ["overmind" | "tmux"] # overmind is the default
4
+ configured_services: ''
5
+ services: []
6
+ auto_restart_procs: []
@@ -6,37 +6,71 @@ module Neptuno
6
6
  module Config
7
7
  include TTY::File
8
8
  TTY = ::TTY::Config.new
9
- TTY.filename = 'neptuno'
9
+ TTY.filename = "neptuno"
10
10
 
11
- ABORT_MESSAGE = 'fatal: there are no registered services. Add one with: neptuno services add'
11
+ ABORT_MESSAGE = "fatal: there are no registered services. Add one with: neptuno services add"
12
12
 
13
13
  def config
14
14
  TTY
15
15
  end
16
16
 
17
- def docker_compose_services
17
+ def docker_compose_hash
18
18
  source = ::File.read("#{neptuno_path}/docker-compose.yml")
19
- docker_compose = begin
19
+ @@docker_compose ||= begin
20
20
  YAML.load(source, aliases: true)
21
21
  rescue ArgumentError
22
22
  YAML.load(source)
23
23
  end
24
- docker_compose.fetch('services').keys
24
+ @@docker_compose
25
+ end
26
+
27
+ def docker_compose_services
28
+ docker_compose_hash.fetch("services").keys.sort
25
29
  end
26
30
 
27
31
  def auto_restart_procs
28
- config.fetch('auto_restart_procs')
32
+ config.fetch("auto_restart_procs")
29
33
  end
30
34
 
31
35
  def services
32
- s = config.fetch('services')
33
- s = s.to_a.union(docker_compose_services)
36
+ s = docker_compose_services
34
37
  abort ABORT_MESSAGE if s.count.zero?
35
- s.sort
38
+ s
36
39
  end
37
40
 
38
41
  def configured_services
39
- config.fetch('configured_services')
42
+ config.fetch("configured_services")
43
+ end
44
+
45
+ def running_services
46
+ `cd #{neptuno_path} && docker-compose ps --status running --services`.split
47
+ end
48
+
49
+ def json_services_status
50
+ JSON.parse(`cd #{neptuno_path} && docker compose ps --all --format json`).map do |service|
51
+ [service.dig("Service"), service.dig("Status")]
52
+ end
53
+ end
54
+
55
+ def starting_services(status: nil)
56
+ data = status || json_services_status
57
+ data.select { |service| service.last.match(/starting\)|\(unhealthy\)/) }
58
+ end
59
+
60
+ def healthy_services(status: nil)
61
+ data = status || json_services_status
62
+ data.select { |service| service.last.match(/\(healthy\)/) }
63
+ end
64
+
65
+ def services_with_procs
66
+ `cd #{neptuno_path} && find procfiles -type f -size +0`.split.map { |x| x.split("/")[1] }
67
+ end
68
+
69
+ def get_dependants(services = [])
70
+ return [] if services.empty?
71
+
72
+ deps = services.map { |service| docker_compose_hash.dig("services", service, "depends_on") }.flatten.uniq
73
+ [deps, get_dependants(deps - services)].flatten.compact.uniq
40
74
  end
41
75
  end
42
76
  end