neptuno 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/workflows/gem-push.yml +33 -0
- data/.github/workflows/main.yml +16 -0
- data/.gitignore +9 -0
- data/AUTHORS +8 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +108 -0
- data/LICENSE +201 -0
- data/README.md +70 -0
- data/Rakefile +13 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/docs/bg.png +0 -0
- data/docs/docs.css +22 -0
- data/docs/gh.png +0 -0
- data/docs/index.html +84 -0
- data/docs/logo.svg +1 -0
- data/docs/logo_shadow.svg +1 -0
- data/docs/rg.svg +7 -0
- data/docs/splash.png +0 -0
- data/exe/neptuno +8 -0
- data/lib/neptuno/cli/activate.rb +73 -0
- data/lib/neptuno/cli/base.rb +37 -0
- data/lib/neptuno/cli/configure.rb +19 -0
- data/lib/neptuno/cli/execute.rb +26 -0
- data/lib/neptuno/cli/init.rb +27 -0
- data/lib/neptuno/cli/install.rb +35 -0
- data/lib/neptuno/cli/list.rb +76 -0
- data/lib/neptuno/cli/version.rb +14 -0
- data/lib/neptuno/cli.rb +38 -0
- data/lib/neptuno/docker/attach.rb +20 -0
- data/lib/neptuno/docker/build.rb +19 -0
- data/lib/neptuno/docker/down.rb +23 -0
- data/lib/neptuno/docker/log.rb +17 -0
- data/lib/neptuno/docker/restart.rb +22 -0
- data/lib/neptuno/docker/services.rb +24 -0
- data/lib/neptuno/docker/up.rb +22 -0
- data/lib/neptuno/environment/config.rb +20 -0
- data/lib/neptuno/environment/update.rb +24 -0
- data/lib/neptuno/git/pull.rb +14 -0
- data/lib/neptuno/git/stash.rb +14 -0
- data/lib/neptuno/k8s/attach.rb +29 -0
- data/lib/neptuno/overmind/connect.rb +103 -0
- data/lib/neptuno/overmind/start.rb +74 -0
- data/lib/neptuno/overmind/stop.rb +22 -0
- data/lib/neptuno/services/add.rb +88 -0
- data/lib/neptuno/services/destroy.rb +14 -0
- data/lib/neptuno/services/list.rb +12 -0
- data/lib/neptuno/services/update.rb +38 -0
- data/lib/neptuno/templates/Dockerfile +0 -0
- data/lib/neptuno/templates/Procfile +0 -0
- data/lib/neptuno/templates/docker-compose.yml +7 -0
- data/lib/neptuno/templates/tmuxinator.yml +0 -0
- data/lib/neptuno/templates/ude.yml +0 -0
- data/lib/neptuno/tty/command.rb +24 -0
- data/lib/neptuno/tty/config.rb +27 -0
- data/lib/neptuno/tty/file.rb +40 -0
- data/lib/neptuno/tty/prompt.rb +14 -0
- data/lib/neptuno/tty/which.rb +14 -0
- data/lib/neptuno/version.rb +5 -0
- data/lib/neptuno.rb +19 -0
- data/neptuno.gemspec +46 -0
- metadata +278 -0
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Neptuno
|
4
|
+
module Docker
|
5
|
+
# Build docker container for Neptuno project
|
6
|
+
class Up < Neptuno::CLI::Base
|
7
|
+
desc 'Docker: bring up docker containers for current project'
|
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'
|
12
|
+
|
13
|
+
def call(services: [], **options)
|
14
|
+
dd = config.fetch('docker_delimiter') || '-'
|
15
|
+
command_services_to('come up', all: options.fetch(:all), services_as_args: services) do |services, project|
|
16
|
+
system("cd #{neptuno_path} && docker compose up -d #{services.join(' ')}")
|
17
|
+
system("cd #{neptuno_path} && docker logs -f #{project}#{dd}#{services.first}#{dd}1") if options.fetch(:log)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Neptuno
|
4
|
+
module Environment
|
5
|
+
# Build docker container for Neptuno project
|
6
|
+
class Config < Neptuno::CLI::Base
|
7
|
+
desc 'Environment: Configure local or remote'
|
8
|
+
|
9
|
+
argument :services, type: :array, required: false, desc: 'Optional list of services'
|
10
|
+
|
11
|
+
def call(services: [], **_options)
|
12
|
+
command_services_to('print', services_as_args: services) do |services|
|
13
|
+
services.each do |service|
|
14
|
+
puts service
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Neptuno
|
4
|
+
module Environment
|
5
|
+
# Build docker container for Neptuno project
|
6
|
+
class Update < Neptuno::CLI::Base
|
7
|
+
desc 'Environment: Update all environment files'
|
8
|
+
|
9
|
+
def call
|
10
|
+
env_path = "#{neptuno_path}/environments/"
|
11
|
+
services.each do |service|
|
12
|
+
service_env_path = env_path + service
|
13
|
+
if File.exist?("#{service_env_path}/key") && File.exist?("#{service_env_path}/secrets.gpg")
|
14
|
+
system("cd #{service_env_path} && gpg --pinentry-mode loopback --passphrase-file key secrets.gpg")
|
15
|
+
system("cd #{service_env_path} && cat default secrets > local_env")
|
16
|
+
system("cd #{service_env_path} && rm secrets")
|
17
|
+
else
|
18
|
+
system("cd #{service_env_path} && ln -sf default local_env")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Neptuno
|
4
|
+
module Git
|
5
|
+
# Pull all submodule changes
|
6
|
+
class Pull < Neptuno::CLI::Base
|
7
|
+
desc 'Git: pull all submodule changes'
|
8
|
+
|
9
|
+
def call(services: [], **_options)
|
10
|
+
system('git submodule foreach git pull')
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Neptuno
|
4
|
+
module Git
|
5
|
+
# Stash all submodule changes
|
6
|
+
class Stash < Neptuno::CLI::Base
|
7
|
+
desc 'Git: stash all submodule changes'
|
8
|
+
|
9
|
+
def call(services: [], **_options)
|
10
|
+
system('git submodule foreach git stash')
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Neptuno
|
4
|
+
module K8s
|
5
|
+
class Attach < Neptuno::CLI::Base
|
6
|
+
include ::Neptuno::TTY::Config
|
7
|
+
desc 'K8s: Attach to a container with k8s'
|
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'
|
12
|
+
option :pr, type: :integer, desc: "PR's Github ID"
|
13
|
+
|
14
|
+
def call(**options)
|
15
|
+
command_service_to('attach with k8s', service_as_args: options[:args]&.first) do |service, _project|
|
16
|
+
deployment = "deploy/#{options[:dependent] || service}"
|
17
|
+
deployment += "-#{service}-#{options[:pr]}" unless options[:pr].nil?
|
18
|
+
|
19
|
+
context = options[:context]
|
20
|
+
context = 'qa' unless options[:pr].nil?
|
21
|
+
|
22
|
+
system("kubectl config use-context #{context} > /dev/null 2>&1")
|
23
|
+
puts "Attaching to #{deployment} in the #{options[:namespace]} namespace using the #{context} context"
|
24
|
+
system("kubectl exec #{deployment} -n #{options[:namespace]} --stdin --tty -- /bin/sh")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Neptuno
|
4
|
+
module Overmind
|
5
|
+
# Build docker container for Neptuno project
|
6
|
+
class Connect < Neptuno::CLI::Base
|
7
|
+
include ::Neptuno::TTY::Config
|
8
|
+
desc 'Overmind: Connect to processes inside docker containers'
|
9
|
+
|
10
|
+
option :force, type: :boolean, default: false, desc: 'Try to connect 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
|
+
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'
|
15
|
+
argument :services, type: :array, required: false, desc: 'Optional list of services'
|
16
|
+
|
17
|
+
def call(services: [], **options)
|
18
|
+
dd = config.fetch('docker_delimiter') || '-'
|
19
|
+
multi_spinner = ::TTY::Spinner::Multi.new('[:spinner] Services')
|
20
|
+
spinners = {}
|
21
|
+
count = 0
|
22
|
+
command_services_to('connect to procs', all: options.fetch(:all), services_as_args: services) do |services|
|
23
|
+
system("cd #{neptuno_path} && docker-compose up -d #{services.join(' ')}") if options.fetch(:up)
|
24
|
+
running_services = ::Neptuno::CLI::List.new.running_services.first.keys
|
25
|
+
running_services.sort.each do |service|
|
26
|
+
spinners[service] ||= multi_spinner.register("[:spinner] :state #{service}")
|
27
|
+
spinners[service].update(state: '- ')
|
28
|
+
spinners[service].auto_spin
|
29
|
+
end
|
30
|
+
loop do
|
31
|
+
ps = `cd #{neptuno_path} && docker-compose ps`.split("\n").compact.select { |x| x.match(/^\s*#{project}/) }
|
32
|
+
|
33
|
+
running_services.sort.each do |service|
|
34
|
+
service_ps = ps.find { |s| s.include?(project.to_s) && s.include?("#{dd}#{service}#{dd}") }
|
35
|
+
|
36
|
+
status = :dead if service_ps.to_s.include?('exited')
|
37
|
+
status = :starting if service_ps.to_s.include?('starting')
|
38
|
+
status = :unhealthy if service_ps.to_s.include?('(unhealthy')
|
39
|
+
status = :healthy if service_ps.to_s.include?('(healthy')
|
40
|
+
status = :force if options.fetch(:force)
|
41
|
+
|
42
|
+
case status
|
43
|
+
when :force
|
44
|
+
spinners[service].success
|
45
|
+
`cd #{neptuno_path}/procfiles/#{service} && overmind start -D -N > /dev/null 2>&`
|
46
|
+
when :dead
|
47
|
+
spinners[service].update(state: 'dead ')
|
48
|
+
spinners[service].error
|
49
|
+
when :starting
|
50
|
+
spinners[service].update(state: 'starting ')
|
51
|
+
when :unhealthy
|
52
|
+
spinners[service].update(state: 'unhealthy ')
|
53
|
+
spinners[service].error if spinners[service].instance_variable_get(:@state) == :spinning && count > 50
|
54
|
+
when :healthy
|
55
|
+
spinners[service].update(state: 'ready ')
|
56
|
+
spinners[service].success
|
57
|
+
else
|
58
|
+
spinners[service].update(state: 'down ')
|
59
|
+
spinners[service].error
|
60
|
+
end
|
61
|
+
end
|
62
|
+
break if spinners.values.map { |s| s.instance_variable_get(:@state) }.uniq.all?(:stopped)
|
63
|
+
|
64
|
+
count += 1
|
65
|
+
sleep(5)
|
66
|
+
end
|
67
|
+
spinner = ::TTY::Spinner.new('Neptuno: Connecting[:spinner]', format: :dots)
|
68
|
+
spinner.auto_spin
|
69
|
+
|
70
|
+
healthy_services = spinners.select { |_k, v| v.instance_variable_get(:@succeeded) == :success }.keys
|
71
|
+
spinner.stop
|
72
|
+
if config.fetch('procfile_manager') == 'tmux'
|
73
|
+
healthy_services.each do |service|
|
74
|
+
pid = spawn("cd #{neptuno_path} && tmuxinator start neptuno_#{service} #{service} -n #{service}",
|
75
|
+
3 => '/dev/null')
|
76
|
+
Process.detach(pid)
|
77
|
+
puts "Neptuno started tmux session for: #{service}"
|
78
|
+
end
|
79
|
+
else
|
80
|
+
spinners.select { |_k, v| v.instance_variable_get(:@succeeded) == :success }.each_key do |service|
|
81
|
+
system("cd #{neptuno_path}/procfiles/#{service} && overmind start -D -N > /dev/null 2>&1")
|
82
|
+
end
|
83
|
+
sleep(5)
|
84
|
+
spinner.stop
|
85
|
+
if options.fetch(:tmux)
|
86
|
+
system("cd #{neptuno_path} && tmuxinator start neptuno #{healthy_services.join(' ')}")
|
87
|
+
else
|
88
|
+
begin
|
89
|
+
system("cd #{neptuno_path}/procfiles/#{services.first} && overmind connect shell", exception: true)
|
90
|
+
rescue RuntimeError
|
91
|
+
puts 'sry'
|
92
|
+
system("cd #{neptuno_path} && docker compose exec #{service} kill -9 -1")
|
93
|
+
system("cd #{neptuno_path}/procfiles/#{service} && rm .overmind.sock > /dev/null 2>&1")
|
94
|
+
system("cd #{neptuno_path}/procfiles/#{service} && overmind start -D -N > /dev/null 2>&1")
|
95
|
+
retry
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Neptuno
|
4
|
+
module Overmind
|
5
|
+
# Build docker container for Neptuno project
|
6
|
+
class Start < Neptuno::CLI::Base
|
7
|
+
include ::Neptuno::TTY::Config
|
8
|
+
desc 'Overmind: Start processes inside docker containers'
|
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'
|
14
|
+
|
15
|
+
def call(services: [], **options)
|
16
|
+
dd = config.fetch('docker_delimiter') || '-'
|
17
|
+
multi_spinner = ::TTY::Spinner::Multi.new('[:spinner] Services')
|
18
|
+
spinners = {}
|
19
|
+
count = 0
|
20
|
+
command_services_to('connect to procs', all: options.fetch(:all), services_as_args: services) do |services|
|
21
|
+
system("cd #{neptuno_path} && docker compose up -d #{services.join(' ')}") if options.fetch(:up)
|
22
|
+
running_services = ::Neptuno::CLI::List.new.running_services.first.keys
|
23
|
+
running_services.sort.each do |service|
|
24
|
+
spinners[service] ||= multi_spinner.register("[:spinner] :state #{service}")
|
25
|
+
spinners[service].update(state: '- ')
|
26
|
+
spinners[service].auto_spin
|
27
|
+
end
|
28
|
+
loop do
|
29
|
+
ps = `cd #{neptuno_path} && docker compose ps`.split("\n").compact.select { |x| x.match(/^\s*#{project}/) }
|
30
|
+
|
31
|
+
running_services.sort.each do |service|
|
32
|
+
service_ps = ps.find { |s| s.include?(project.to_s) && s.include?("#{dd}#{service}#{dd}") }
|
33
|
+
|
34
|
+
status = :dead if service_ps.to_s.include?('exited')
|
35
|
+
status = :starting if service_ps.to_s.include?('starting')
|
36
|
+
status = :unhealthy if service_ps.to_s.include?('(unhealthy')
|
37
|
+
status = :healthy if service_ps.to_s.include?('(healthy')
|
38
|
+
status = :force if options.fetch(:force)
|
39
|
+
|
40
|
+
case status
|
41
|
+
when :force
|
42
|
+
spinners[service].success
|
43
|
+
`cd #{neptuno_path}/procfiles/#{service} && overmind start -D -N > /dev/null 2>&1`
|
44
|
+
when :dead
|
45
|
+
spinners[service].update(state: 'dead ')
|
46
|
+
spinners[service].error
|
47
|
+
when :starting
|
48
|
+
spinners[service].update(state: 'starting ')
|
49
|
+
when :unhealthy
|
50
|
+
spinners[service].update(state: 'unhealthy ')
|
51
|
+
spinners[service].error if spinners[service].instance_variable_get(:@state) == :spinning && count > 50
|
52
|
+
when :healthy
|
53
|
+
spinners[service].update(state: 'ready ')
|
54
|
+
spinners[service].success
|
55
|
+
`cd #{neptuno_path}/procfiles/#{service} && overmind start -D -N > /dev/null 2>&1`
|
56
|
+
else
|
57
|
+
spinners[service].update(state: 'down ')
|
58
|
+
spinners[service].error
|
59
|
+
end
|
60
|
+
end
|
61
|
+
break if spinners.values.map { |s| s.instance_variable_get(:@state) }.uniq.all?(:stopped)
|
62
|
+
|
63
|
+
count += 1
|
64
|
+
sleep(5)
|
65
|
+
end
|
66
|
+
spinner = ::TTY::Spinner.new('Neptuno: Starting[:spinner]', format: :dots)
|
67
|
+
spinner.auto_spin
|
68
|
+
|
69
|
+
spinner.stop
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Neptuno
|
4
|
+
module Overmind
|
5
|
+
# Build docker container for Neptuno project
|
6
|
+
class Stop < Neptuno::CLI::Base
|
7
|
+
desc 'Overmind: Stop processes inside docker containers'
|
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'
|
11
|
+
|
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|
|
15
|
+
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
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Neptuno
|
4
|
+
module Services
|
5
|
+
# Add project to neptuno
|
6
|
+
class Add < Neptuno::CLI::Base
|
7
|
+
include TTY::Prompt
|
8
|
+
include TTY::Config
|
9
|
+
include TTY::File
|
10
|
+
|
11
|
+
desc 'Add a Neptuno service with Git'
|
12
|
+
|
13
|
+
def call(**)
|
14
|
+
name = prompt.ask('? Service name:')
|
15
|
+
add_name_to_config(name)
|
16
|
+
repo = prompt.ask('? Git repo:')
|
17
|
+
clone_into_folder(repo, name)
|
18
|
+
add_dockerfile(name)
|
19
|
+
add_procfile(name)
|
20
|
+
add_environment(name)
|
21
|
+
add_service_to_dc(name)
|
22
|
+
end
|
23
|
+
|
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
|
+
def clone_into_folder(repo, name)
|
30
|
+
if repo.nil?
|
31
|
+
command.run("mkdir #{neptuno_path}/services/#{name}")
|
32
|
+
else
|
33
|
+
command.run("cd #{neptuno_path} && git submodule add #{repo} ./services/#{name}")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def add_dockerfile(name)
|
38
|
+
file.create_file("#{neptuno_path}/dockerfiles/#{name}/Dockerfile")
|
39
|
+
file.create_file("#{neptuno_path}/dockerfiles/#{name}/entrypoint.sh")
|
40
|
+
end
|
41
|
+
|
42
|
+
def add_procfile(name)
|
43
|
+
file.create_file("#{neptuno_path}/procfiles/#{name}/Procfile")
|
44
|
+
end
|
45
|
+
|
46
|
+
def add_environment(name)
|
47
|
+
file.create_file("#{neptuno_path}/environments/#{name}/default")
|
48
|
+
end
|
49
|
+
|
50
|
+
def add_service_to_dc(name)
|
51
|
+
puts(<<~EOT)
|
52
|
+
#---------------------------------------------------------------
|
53
|
+
# Registered #{name} as a service. You can now add it to the docker-compose.yml:
|
54
|
+
#---------------------------------------------------------------
|
55
|
+
|
56
|
+
version: '3'
|
57
|
+
services:
|
58
|
+
##########################
|
59
|
+
# #{name}
|
60
|
+
##########################
|
61
|
+
#{name}:
|
62
|
+
stdin_open: true
|
63
|
+
tty: true
|
64
|
+
command: ash
|
65
|
+
build:#{' '}
|
66
|
+
context: .
|
67
|
+
dockerfile: ./dockerfiles/#{name}/Dockerfile
|
68
|
+
env_file:#{' '}
|
69
|
+
- ./environments/#{name}/default
|
70
|
+
# volumes:#{' '}
|
71
|
+
# -
|
72
|
+
# ports:#{' '}
|
73
|
+
# -
|
74
|
+
# depends_on:#{' '}
|
75
|
+
# -
|
76
|
+
|
77
|
+
#---------------------------------------------------------------
|
78
|
+
# Next steps
|
79
|
+
#---------------------------------------------------------------
|
80
|
+
|
81
|
+
Add the service's Dockerfile at ./dockerfiles/#{name}/Dockerfile
|
82
|
+
Add the service's Environments at ./environments/#{name}/default
|
83
|
+
Add the service's Procfile at ./procfiles/#{name}/Procfile
|
84
|
+
EOT
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Neptuno
|
4
|
+
module Services
|
5
|
+
# Update project to to latest GH master/main
|
6
|
+
class Update < Neptuno::CLI::Base
|
7
|
+
desc 'Stashes changes and pulls latest from main/master'
|
8
|
+
|
9
|
+
option :all, type: :boolean, default: false, desc: 'Run on all services'
|
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'
|
13
|
+
|
14
|
+
def call(services: [], **options)
|
15
|
+
command_services_to('update', all: options.fetch(:all), services_as_args: services) do |services|
|
16
|
+
services.each do |service|
|
17
|
+
puts "---Updating #{service}---"
|
18
|
+
current_branch = `git branch --show-current`
|
19
|
+
puts current_branch
|
20
|
+
system("cd #{neptuno_path}/services/#{service} 2>/dev/null && git stash save -u -q neptuno_stash")
|
21
|
+
`cd #{neptuno_path}/services/#{service} 2>/dev/null && git checkout main 2>/dev/null`
|
22
|
+
`cd #{neptuno_path}/services/#{service} 2>/dev/null && git checkout master 2>/dev/null`
|
23
|
+
system("cd #{neptuno_path}/services/#{service} 2>/dev/null && git pull")
|
24
|
+
unless options.fetch(:main)
|
25
|
+
stash_id = `git stash list`.lines.find { |str| str =~ /neptuno_stash/ }&.split(':')&.first
|
26
|
+
`cd #{neptuno_path}/services/#{service} 2>/dev/null && git checkout #{current_branch} 2>/dev/null`
|
27
|
+
if stash_id
|
28
|
+
puts 'Applying stashed changes'
|
29
|
+
system("cd #{neptuno_path}/services/#{service} 2>/dev/null && git stash pop -q #{stash_id}")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
puts ''
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Neptuno
|
4
|
+
module TTY
|
5
|
+
# Wrapper class for TTY gem
|
6
|
+
module Command
|
7
|
+
include TTY::Config
|
8
|
+
TTY = ::TTY::Command.new(printer: :null)
|
9
|
+
TTYP = ::TTY::Command.new(printer: :pretty)
|
10
|
+
|
11
|
+
def command
|
12
|
+
TTY
|
13
|
+
end
|
14
|
+
|
15
|
+
def command_p
|
16
|
+
TTYP
|
17
|
+
end
|
18
|
+
|
19
|
+
def neptuno_command(command)
|
20
|
+
`cd #{neptuno_path} && #{command}`
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Neptuno
|
4
|
+
module TTY
|
5
|
+
# Wrapper class for TTY gem
|
6
|
+
module Config
|
7
|
+
TTY = ::TTY::Config.new
|
8
|
+
TTY.filename = 'neptuno'
|
9
|
+
|
10
|
+
ABORT_MESSAGE = 'fatal: there are no registered services. Add one with: neptuno services add'
|
11
|
+
|
12
|
+
def config
|
13
|
+
TTY
|
14
|
+
end
|
15
|
+
|
16
|
+
def services
|
17
|
+
s = config.fetch('services')
|
18
|
+
abort ABORT_MESSAGE if s.count.zero?
|
19
|
+
s.sort
|
20
|
+
end
|
21
|
+
|
22
|
+
def configured_services
|
23
|
+
config.fetch('configured_services')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Neptuno
|
4
|
+
module TTY
|
5
|
+
# Wrapper class for TTY gem
|
6
|
+
module File
|
7
|
+
TTY = ::TTY::File
|
8
|
+
ABORT_MESSAGE = 'fatal: not a Neptuno repository (or any of the parent directories)'
|
9
|
+
|
10
|
+
def file
|
11
|
+
TTY
|
12
|
+
end
|
13
|
+
|
14
|
+
# define path helpers
|
15
|
+
def project
|
16
|
+
neptuno_path.split('/').last
|
17
|
+
end
|
18
|
+
|
19
|
+
def in_service?
|
20
|
+
Dir.pwd.include?("#{neptuno_path}/services/")
|
21
|
+
end
|
22
|
+
|
23
|
+
def service
|
24
|
+
ENV['PWD'].match(%r{services/([^/]*)})&.captures&.first
|
25
|
+
end
|
26
|
+
|
27
|
+
def neptuno_path
|
28
|
+
return @base_path if @base_path
|
29
|
+
|
30
|
+
pwd = Dir.pwd
|
31
|
+
loop do
|
32
|
+
return pwd if pwd == ''
|
33
|
+
return @base_path = pwd if Dir.children(pwd).include?('neptuno.yml')
|
34
|
+
|
35
|
+
pwd = pwd.split('/')[0..-2].join('/')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/neptuno.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'zeitwerk'
|
4
|
+
require 'tty-config'
|
5
|
+
require 'tty-command'
|
6
|
+
require 'tty-which'
|
7
|
+
require 'tty-file'
|
8
|
+
require 'tty-spinner'
|
9
|
+
require 'hirb'
|
10
|
+
require 'dotiw'
|
11
|
+
|
12
|
+
loader = Zeitwerk::Loader.for_gem
|
13
|
+
loader.inflector.inflect('neptuno' => 'Neptuno')
|
14
|
+
loader.inflector.inflect('cli' => 'CLI')
|
15
|
+
loader.inflector.inflect('tty' => 'TTY')
|
16
|
+
loader.setup
|
17
|
+
|
18
|
+
module Neptuno
|
19
|
+
end
|