Skip to content
This repository has been archived by the owner on Oct 28, 2024. It is now read-only.

Up and attach #27

Merged
merged 9 commits into from
Oct 11, 2019
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
kaiser (0.4.0)
kaiser (0.4.1)
optimist

GEM
Expand Down
43 changes: 40 additions & 3 deletions lib/kaiser/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,21 @@
module Kaiser
# The commandline
class Cli
@options = []

class << self
def option(*option)
@options ||= []
@options << option
end

def options
@options || []
end
end

attr_reader :opts
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This bunch of things is a great thing to abstract into a module. If you define this in a module, say a CliOptions module, you can extend CliOptions in the class Cli and it will be easier to see whats going on.

At the moment its really easy to confuse :opts and options.

Also with a CliOptions module renaming @options to @cli_options would make making the link easier.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potentially you can also add it to only commands that require options if you do it this way. So it looks a lot less like magic.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I was also worried about opts and options being confusing. Especially since one is a class instance variable and the other is an instance variable. I'll put them in the module. I also like the idea of less magic. :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do think it's better to keep it in the superclass because this line over here relies on the cmd.class.options method existing and returning an array.

opts = cmd.define_options(global_opts + cmd.class.options)

I feel like this is more elegant than writing a check to see if the module was extended or not.


def set_config
# This is here for backwards compatibility since it can be used in Kaiserfiles.
# It would be a good idea to deprecate this and make it more abstract.
Expand All @@ -29,7 +44,7 @@ def define_options(global_opts = [])
# the scope to Optimist::Parser. We can still reference variables but we can't
# call instance methods of a Kaiser::Cli class.
u = usage
Optimist.options do
@opts = Optimist.options do
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of making this global, can we just pass it in as a parameter to execute?

Copy link
Member Author

@Metallion Metallion Oct 10, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about too at first but the thing is execute calls a lot of private methods that are often shared between commands. We would have to pass the options to every single one.

Or I guess you could only pass them to the ones that actually make use of them which could make it more transparent. You could see at a glance which method uses options and which one does not.

I started writing this comment as a counter-argument but finished it thinking maybe you're right. lol

It would be less magic that way too.

banner u

global_opts.each { |o| opt *o }
Expand All @@ -43,7 +58,7 @@ def self.register(name, klass)

def self.run_command(name, global_opts)
cmd = @subcommands[name]
opts = cmd.define_options(global_opts)
opts = cmd.define_options(global_opts + cmd.class.options)

# The define_options method has stripped all arguments from the cli so now
# all that we're left with in ARGV are the subcommand to be run and possibly
Expand All @@ -57,7 +72,6 @@ def self.run_command(name, global_opts)
# unless they create a Kaiserfile firest.
out = Kaiser::Dotter.new
info_out = Kaiser::AfterDotter.new(dotter: out)

if opts[:quiet]
out = File.open(File::NULL, 'w')
info_out = File.open(File::NULL, 'w')
Expand Down Expand Up @@ -216,6 +230,29 @@ def default_db_image
db_image_path('.default')
end

def attach_app
cmd = (ARGV || []).join(' ')
killrm app_container_name

attach_mounts = Config.kaiserfile.attach_mounts
volumes = attach_mounts.map { |from, to| "-v #{`pwd`.chomp}/#{from}:#{to}" }.join(' ')

system "docker run -ti
--name #{app_container_name}
--network #{network_name}
--dns #{ip_of_container(Config.config[:shared_names][:dns])}
--dns-search #{http_suffix}
-p #{app_port}:#{app_expose}
-e DEV_APPLICATION_HOST=#{envname}.#{http_suffix}
-e VIRTUAL_HOST=#{envname}.#{http_suffix}
-e VIRTUAL_PORT=#{app_expose}
#{volumes}
#{app_params}
kaiser:#{envname}-#{current_branch} #{cmd}".tr("\n", ' ')

Config.out.puts 'Cleaning up...'
end

def start_app
Config.info_out.puts 'Starting up application'
killrm app_container_name
Expand Down
26 changes: 3 additions & 23 deletions lib/kaiser/cmds/attach.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,17 @@ def usage
<<~EOS
Shuts down the application container and starts it up again with the current directory bind mounted inside. This way the application will run from the source code in the current directory and any edits you make will immediately show up inside the container. This is ideal for development.

Once the attached container exits (through the use of control+c for example) it will be replaced by a regular non-attached version of the app container.

USAGE: kaiser attach
EOS
end

def execute
ensure_setup
cmd = (ARGV || []).join(' ')
killrm app_container_name

volumes = attach_mounts.map { |from, to| "-v #{`pwd`.chomp}/#{from}:#{to}" }.join(' ')

system "docker run -ti
--name #{app_container_name}
--network #{network_name}
--dns #{ip_of_container(Config.config[:shared_names][:dns])}
--dns-search #{http_suffix}
-p #{app_port}:#{app_expose}
-e DEV_APPLICATION_HOST=#{envname}.#{http_suffix}
-e VIRTUAL_HOST=#{envname}.#{http_suffix}
-e VIRTUAL_PORT=#{app_expose}
#{volumes}
#{app_params}
kaiser:#{envname}-#{current_branch} #{cmd}".tr("\n", ' ')

Config.out.puts 'Cleaning up...'
attach_app
start_app
end

def attach_mounts
Config.kaiserfile.attach_mounts
end
end
end
end
9 changes: 8 additions & 1 deletion lib/kaiser/cmds/up.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
module Kaiser
module Cmds
class Up < Cli
option :attach, "Bind mount the current source code directory in the app container (as the \`kaiser attach\` command would)", short: '-a'

def usage
<<~EOS
Boots up the application in docker as defined in the \`Kaiserfile\` in its source code. Usually this will create two docker containers \`<ENV_NAME>-db\` and \`<ENV_NAME>-app\` running your database and application respectively.
Expand All @@ -17,7 +19,12 @@ def execute
ensure_setup
setup_app
setup_db
start_app

if opts[:attach]
attach_app
else
start_app
end
end

def setup_app
Expand Down
2 changes: 1 addition & 1 deletion lib/kaiser/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module Kaiser
VERSION = '0.4.0'
VERSION = '0.4.1'
end
6 changes: 5 additions & 1 deletion spec/kaiser_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,11 @@
shared_examples 'single help' do
it "prints the help message for just #{name} and nothing else" do
# Remove the help arguments generated by Optimist as they won't be in the usage method
unwrapped_output = cmd_stdout.lines.delete_if { |l| l =~ /^ -.+/ }.join
# We remove each line after the first argument. We can't just check for lines that start
# with ' -' because optimist might wrap them over multiple lines.
lines = cmd_stdout.lines
args_line = lines.index { |l| l =~ /^ -.+/ }
unwrapped_output = lines[0, args_line].join

# Remove all newlines because Optimist will wordwrap according to terminal size
unwrapped_output.gsub!("\n", ' ')
Expand Down