docker_rails_proxy 0.0.0 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3347b8edebbf4f84fcacd12e36816f0727902b68
4
- data.tar.gz: 385331e600909f99227598f7b37428020e6ed878
3
+ metadata.gz: c565af80fd33cee75c95b7ada9c8c7bdb42f0bf0
4
+ data.tar.gz: 288e91970419af210886a50ab0d78cbd95a3f203
5
5
  SHA512:
6
- metadata.gz: d6387a4ae7ddd92c832863bdb959286b837032364b21a57ae9b01a7365af3090a0b267685a0427a6b7297ca234c77ee7e4c6125dfd275f8b5d24ee35bc3b3f03
7
- data.tar.gz: 9b0f92fc9ec121ccec5fd1f51cd65cca384c904b163cff3e4e32f10755f361aaf3977bf688ac6733a4e26f2e67c8d1f6c9d51c16cc390bc2676b805ccec23224
6
+ metadata.gz: 4bb58cfef7d4fbf1e344b61c32117323e5730dd879938bf1d10033abb408e8a3e029a833235474d55a0166b61ac1750ff073102246568080ee9437e17b24c45c
7
+ data.tar.gz: 216df1896cb8ac1fbdef8994c87f50a863e710ef49ef660144ac30eb0f980d2822279332c8855593706b3fdf134abe56e1da681cc542303e7a068bc559c3194d
@@ -0,0 +1,37 @@
1
+ module DockerRailsProxy
2
+ class Cli
3
+ class << self
4
+ def invoke(arguments)
5
+ command, *args = arguments
6
+
7
+ if command.nil?
8
+ $stderr.puts <<-EOF
9
+ #{"bin/#{APP_NAME} requires 1 argument.".bold}
10
+
11
+ #{"Usage: bin/#{APP_NAME} <command> [<args>]".bold}
12
+ EOF
13
+ exit 1
14
+ end
15
+
16
+ if COMMANDS.include? command
17
+ args << '-h' if args.empty?
18
+ "DockerRailsProxy::#{command}".constantize.(arguments: args)
19
+ else
20
+ $stderr.puts <<-EOS
21
+ #{'No such command'.yellow}
22
+
23
+ #{'COMMANDS'.bold}
24
+ EOS
25
+
26
+ COMMANDS.each do |script|
27
+ $stderr.puts <<-EOS
28
+ #{script.parameterize.bold} [<args>]
29
+ EOS
30
+ end
31
+
32
+ exit 1
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,77 @@
1
+ require 'optparse'
2
+
3
+ module DockerRailsProxy
4
+ class Build < Docker
5
+ attr_accessor :options
6
+
7
+ after_initialize { self.options = {} }
8
+ after_initialize :parse_options!
9
+
10
+ validates do
11
+ if options[:dockerfile].nil?
12
+ '--dockerfile is required'
13
+ elsif !File.exist?(options[:dockerfile])
14
+ "#{options[:dockerfile]} dockerfile does not exist."
15
+ end
16
+ end
17
+
18
+ validates { '--tag is required' if options[:tag].nil? }
19
+
20
+ validates do
21
+ options[:build_args] ||= {}
22
+
23
+ args = File.readlines(options[:dockerfile]).map do |line|
24
+ /^ARG/ =~ line ? line.split(' ').last : nil
25
+ end.compact
26
+
27
+ missings = args.select { |arg| options[:build_args][arg].nil? }.compact
28
+
29
+ (options[:build_args].keys - args).each { |k| options[:build_args].delete k }
30
+
31
+ missings.map { |a| "#{a} is required" }.join(', ') unless missings.empty?
32
+ end
33
+
34
+ def process
35
+ system <<-EOS
36
+ docker build \
37
+ -f '#{options[:dockerfile]}' \
38
+ -t '#{options[:tag]}' \
39
+ #{build_args} \
40
+ '#{APP_PATH}'
41
+ EOS
42
+ end
43
+
44
+ private
45
+
46
+ def build_args
47
+ options[:build_args].map do |k, v|
48
+ "--build-arg #{k.upcase}='#{v.strip}'"
49
+ end.join(' ')
50
+ end
51
+
52
+ def parse_options!
53
+ opt_parser.parse!(arguments)
54
+ end
55
+
56
+ def opt_parser
57
+ @opt_parser ||= OptionParser.new do |opts|
58
+ opts.banner = "Usage: bin/#{APP_NAME} build [options]"
59
+
60
+ opts.on('--dockerfile DOCKERFILE', 'Dockerfile') do |dockerfile|
61
+ options[:dockerfile] = dockerfile
62
+ end
63
+
64
+ opts.on('--tag TAG', 'Docker Image Tag') { |tag| options[:tag] = tag }
65
+
66
+ opts.on('--build-args A=val,B=val...', Array, 'Docker build-args') do |o|
67
+ options[:build_args] = Hash[o.map { |s| s.split('=', 2) }]
68
+ end
69
+
70
+ opts.on('-h', '--help', 'Display this screen') do
71
+ puts opts
72
+ exit
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,8 @@
1
+ module DockerRailsProxy
2
+ class Bundle < SyncBack
3
+ def process
4
+ command, *args = arguments
5
+ system "docker exec -it #{APP_NAME} bundle #{command} #{args.join(' ')}"
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,15 @@
1
+ module DockerRailsProxy
2
+ class Compose < Docker
3
+ class Down < self
4
+ def process
5
+ containers = %x(
6
+ docker-compose ps | grep '#{APP_NAME}' | awk '{print $1}' | xargs
7
+ ).strip.split(' ')
8
+
9
+ system "docker stop #{containers.join(' ')}"
10
+ system "docker rm -v #{containers.join(' ')}"
11
+ system 'docker-compose down'
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,20 @@
1
+ module DockerRailsProxy
2
+ class Compose < Docker
3
+ class Override < self
4
+ OVERRIDE_PATH = build_path('docker-compose.override.yml')
5
+ OVERRIDE_FILE = <<EOS.freeze
6
+ version: "2"
7
+ services:
8
+ app:
9
+ volumes:
10
+ - #{build_path(".data-bags/certs/localhost.#{APP_NAME}/cert.crt:/certs/cert.crt")}
11
+ - #{build_path(".data-bags/certs/localhost.#{APP_NAME}/cert.key:/certs/cert.key")}
12
+ EOS
13
+
14
+ def process
15
+ File.write(OVERRIDE_PATH, OVERRIDE_FILE)
16
+ puts "#{OVERRIDE_PATH} was created"
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,10 @@
1
+ module DockerRailsProxy
2
+ class Compose < Docker
3
+ class Proxy < self
4
+ def process
5
+ command, *args = arguments
6
+ system "docker-compose #{command} #{args.join(' ')}"
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,131 @@
1
+ require 'pty'
2
+ require 'optparse'
3
+
4
+ module DockerRailsProxy
5
+ class Compose < Docker
6
+ class Up < self
7
+ FSWATCH_CMD = <<-EOS.strip.freeze
8
+ fswatch -r -0 \
9
+ --latency=0.1 \
10
+ --exclude '.git' \
11
+ --exclude '4913' \
12
+ "#{APP_PATH}" "#{GEMS_PATH}" | xargs -0 -n1 -I{} echo {}
13
+ EOS
14
+
15
+ EIO_ERROR = %(
16
+ Errno:EIO error, but this probably just means that the process
17
+ has finished giving output
18
+ ).freeze
19
+
20
+ attr_accessor :branch_name, :stopping, :options, :from_scratch
21
+
22
+ alias_method :stopping?, :stopping
23
+ alias_method :from_scratch?, :from_scratch
24
+
25
+ before_initialize do
26
+ unless system 'type fswatch &> /dev/null'
27
+ 'fswatch is required, `brew install fswatch`'
28
+ end
29
+ end
30
+
31
+ after_initialize { self.options = {} }
32
+ after_initialize { self.branch_name = current_branch }
33
+
34
+ after_initialize :parse_options!, :set_defaults
35
+
36
+ before_process do
37
+ self.from_scratch = %x(docker-compose ps | grep -c #{APP_NAME}).to_i.zero?
38
+ end
39
+
40
+ after_process { fswatch_start }
41
+
42
+ def process
43
+ system 'docker-compose up -d'
44
+ sync_app_and_gems_folders
45
+ run_bundle_install if options[:bundle]
46
+ seed if from_scratch?
47
+ end
48
+
49
+ private
50
+
51
+ def seed
52
+ system <<-EOS.strip.freeze
53
+ docker exec #{APP_NAME} bin/rake db:drop db:create db:migrate db:seed
54
+ EOS
55
+ end
56
+
57
+ def sync_app_and_gems_folders
58
+ rsync_app
59
+ sync source: GEMS_PATH
60
+ end
61
+
62
+ def rsync_app
63
+ loop do
64
+ break if sync(source: APP_PATH)
65
+ puts "waiting for rsync-volume service on #{rsync_host}"
66
+ sleep 2
67
+ end
68
+ end
69
+
70
+ def fswatch_start
71
+ PTY.spawn(FSWATCH_CMD) do |stdout, stdin, pid|
72
+ begin
73
+ stdout.each { |path| sync_or_kill(path: path, pid: pid) }
74
+ rescue Errno::EIO
75
+ $stderr.puts EIO_ERROR
76
+ end
77
+ end
78
+ rescue PTY::ChildExited
79
+ $stderr.puts '"The fswatch process exited!'
80
+ end
81
+
82
+ def sync_or_kill(path:, pid:)
83
+ return if stopping?
84
+
85
+ if branch_name == (branch = current_branch)
86
+ sync source: path
87
+ else
88
+ $stderr.puts %(
89
+ `git checkout #{branch}` was detected, stopping fswatch
90
+ Previous branch was '#{branch_name}'
91
+ )
92
+ Process.kill(9, pid)
93
+ self.stopping = true
94
+ end
95
+ end
96
+
97
+ def current_branch
98
+ %x(git rev-parse --abbrev-ref HEAD).strip
99
+ end
100
+
101
+ # since new gems may have been added, we need bundle install
102
+ def run_bundle_install
103
+ system "docker exec #{APP_NAME} bundle install"
104
+ end
105
+
106
+ def parse_options!
107
+ opt_parser.parse!(arguments)
108
+ end
109
+
110
+ def set_defaults
111
+ options[:bundle] = true if options[:bundle].nil?
112
+ end
113
+
114
+ def opt_parser
115
+ @opt_parser ||= OptionParser.new do |opts|
116
+ opts.banner = "Usage: bin/#{APP_NAME} compose up [options]"
117
+
118
+ opts.on(
119
+ '--[no-]bundle',
120
+ 'Run bundle install in all related containers'
121
+ ) { |bundle| options[:bundle] = bundle }
122
+
123
+ opts.on('-h', '--help', 'Display this screen') do
124
+ puts opts
125
+ exit
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,18 @@
1
+ module DockerRailsProxy
2
+ class Compose < Docker
3
+ autoload :Down, 'docker_rails_proxy/commands/compose/down'
4
+ autoload :Override, 'docker_rails_proxy/commands/compose/override'
5
+ autoload :Proxy, 'docker_rails_proxy/commands/compose/proxy'
6
+ autoload :Up, 'docker_rails_proxy/commands/compose/up'
7
+
8
+ builds -> (params:) do
9
+ case params[:arguments].first
10
+ when 'down' then Down
11
+ when 'override' then Override
12
+ when 'up' then Up
13
+ else
14
+ Proxy
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,91 @@
1
+ require 'optparse'
2
+
3
+ module DockerRailsProxy
4
+ class DataBags < AwsCli
5
+ attr_accessor :options
6
+
7
+ after_initialize { self.options = {} }
8
+ after_initialize :parse_options!, :set_defaults
9
+
10
+ before_process :set_folder_and_bucket
11
+
12
+ validates { '--profile is required.' if options[:profile].nil? }
13
+ validates { '--bucket is required.' if options[:bucket].nil? }
14
+
15
+ def process
16
+ case arguments.first
17
+ when 'pull' then pull
18
+ when 'push' then push
19
+ else
20
+ opt_parser.parse %w(-h)
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def pull
27
+ if system <<-EOS.strip
28
+ aws s3 sync '#{options[:bucket]}' '#{options[:folder]}' \
29
+ --delete \
30
+ --exact-timestamps \
31
+ --profile '#{options[:profile]}'
32
+ EOS
33
+
34
+ puts "Data bags pulled from #{options[:bucket]} to #{options[:folder]}"
35
+ end
36
+ end
37
+
38
+ def push
39
+ puts "#{options[:bucket]} will be synced with #{options[:folder]}, are you sure?: [yes]"
40
+ confirm = $stdin.gets.chomp
41
+
42
+ exit unless confirm == 'yes'
43
+
44
+ if system <<-EOS
45
+ aws s3 sync '#{options[:folder]}' '#{options[:bucket]}' \
46
+ --delete \
47
+ --exact-timestamps \
48
+ --profile '#{options[:profile]}' \
49
+ --sse aws:kms
50
+ EOS
51
+
52
+ puts "Data bags pushed from #{options[:folder]} to #{options[:bucket]}"
53
+ end
54
+ end
55
+
56
+ def set_defaults
57
+ options[:profile] ||= APP_NAME
58
+ options[:bucket] ||= "#{APP_NAME}-data-bags"
59
+ end
60
+
61
+ def set_folder_and_bucket
62
+ options[:folder] = build_path('.data-bags')
63
+ options[:bucket] = "s3://#{options[:bucket]}"
64
+ end
65
+
66
+ def parse_options!
67
+ opt_parser.parse!(arguments)
68
+ end
69
+
70
+ def opt_parser
71
+ @opt_parser ||= OptionParser.new do |opts|
72
+ opts.banner = "Usage: bin/#{APP_NAME} data-bags <pull|push> [options]"
73
+
74
+ opts.on(
75
+ '--profile [PROFILE]',
76
+ "Aws profile (Default: #{APP_NAME})"
77
+ ) { |profile| options[:profile] = profile }
78
+
79
+ opts.on(
80
+ '--bucket [BUCKET]',
81
+ "AWS S3 Data bags bucket (Default: #{APP_NAME}-data-bags)"
82
+ ) { |bucket| options[:bucket] = bucket }
83
+
84
+ opts.on('-h', '--help', 'Display this screen') do
85
+ puts opts
86
+ exit
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,39 @@
1
+ module DockerRailsProxy
2
+ class Rails < SyncBack
3
+ def process
4
+ command, *args = arguments
5
+
6
+ case command
7
+ when 'c', 'console' then console args
8
+ when 'db', 'dbconsole' then db args
9
+ when 'logs' then logs args
10
+ when 'restart', 'touch' then restart
11
+ else
12
+ system "docker exec -it #{APP_NAME} bin/rails #{command} #{args.join(' ')}"
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def console(args)
19
+ exec "docker exec -it #{APP_NAME} bin/rails c #{args.join(' ')}"
20
+ end
21
+
22
+ def db(args)
23
+ exec <<-EOS
24
+ docker exec -it #{APP_NAME}_db \
25
+ mysql #{args.first || "#{APP_NAME}_development"}
26
+ EOS
27
+ end
28
+
29
+ def logs(args)
30
+ exec <<-EOS
31
+ docker exec #{APP_NAME} tail -f log/#{args.first || 'development'}.log
32
+ EOS
33
+ end
34
+
35
+ def restart
36
+ exec "docker exec #{APP_NAME} touch tmp/restart.txt"
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,8 @@
1
+ module DockerRailsProxy
2
+ class Rake < SyncBack
3
+ def process
4
+ command, *args = arguments
5
+ system "docker exec -it #{APP_NAME} bin/rake #{command} #{args.join(' ')}"
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ module DockerRailsProxy
2
+ class Rspec < SyncBack
3
+ def process
4
+ command, *args = arguments
5
+ system "docker exec #{APP_NAME} bin/rspec #{command} #{args.join(' ')}"
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ module DockerRailsProxy
2
+ class Spring < DockerMainApp
3
+ def process
4
+ command, *args = arguments
5
+ system "docker exec #{APP_NAME} bin/spring #{command} #{args.join(' ')}"
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,29 @@
1
+ require 'optparse'
2
+
3
+ module DockerRailsProxy
4
+ class Ssh < DockerMainApp
5
+ def process
6
+ command, *args = arguments
7
+
8
+ case command
9
+ when '-h', '--help'
10
+ opt_parser.parse %w(-h)
11
+ else
12
+ system "docker exec -it #{APP_NAME} #{command} #{args.join(' ')}"
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def opt_parser
19
+ @opt_parser ||= OptionParser.new do |opts|
20
+ opts.banner = "Usage: bin/#{APP_NAME} ssh COMMAND [options]"
21
+
22
+ opts.on('-h', '--help', 'Display this screen') do
23
+ puts opts
24
+ exit
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,115 @@
1
+ module DockerRailsProxy
2
+ module Callbacks
3
+ INHERITABLE_CALLBACKS = %w(
4
+ _before_initialize
5
+ _after_initialize
6
+ _validates
7
+ _before_process
8
+ _after_process
9
+ ).freeze
10
+
11
+ UNINHERITABLE_CALLBACKS = %w(
12
+ _builds
13
+ ).freeze
14
+
15
+ def self.included(base)
16
+ base.extend(ClassMethods)
17
+
18
+ INHERITABLE_CALLBACKS.each do |callback|
19
+ base.inheritable_attributes callback.to_sym
20
+ base.send "#{callback}=", []
21
+ end
22
+
23
+ UNINHERITABLE_CALLBACKS.each do |callback|
24
+ base.uninheritable_attributes callback.to_sym
25
+ end
26
+ end
27
+
28
+ module ClassMethods
29
+ private
30
+
31
+ INHERITABLE_CALLBACKS.each do |type|
32
+ define_method(type.sub('_', '').to_sym) do |*callbacks, &block|
33
+ _add_callbacks type: type, callbacks: callbacks, &block
34
+ end
35
+ end
36
+
37
+ UNINHERITABLE_CALLBACKS.each do |type|
38
+ define_method(type.sub('_', '').to_sym) do |*callbacks, &block|
39
+ send("#{type}=", []) if send(type).nil?
40
+ _add_callbacks type: type, callbacks: callbacks, &block
41
+ end
42
+ end
43
+
44
+ def _add_callbacks(type:, callbacks:, &block)
45
+ callbacks.each { |c| send(type) << _make_lambda(callback: c) }
46
+ send(type) << _make_lambda(callback: block) if block_given?
47
+ send type
48
+ end
49
+
50
+ def _make_lambda(callback:)
51
+ case callback
52
+ when Symbol
53
+ -> (resource, *rest) { resource.send(callback, *rest) }
54
+ when ::Proc
55
+ if callback.arity <= 0
56
+ -> (resource) { resource.instance_exec(&callback) }
57
+ else
58
+ -> (resource, *rest) do
59
+ if rest.empty?
60
+ resource.instance_exec(resource, &callback)
61
+ else
62
+ resource.instance_exec(*rest, &callback)
63
+ end
64
+ end
65
+ end
66
+ else
67
+ -> (*) {}
68
+ end
69
+ end
70
+
71
+ def _run_before_initialize_callbacks
72
+ Array(_before_initialize).each do |callback|
73
+ if (result = callback.call(self)).is_a? String
74
+ $stderr.puts %(
75
+ #{result}
76
+ )
77
+ exit 1
78
+ end
79
+ end
80
+ end
81
+
82
+ def _run_after_initialize_callbacks(resource:)
83
+ Array(_after_initialize).each { |c| c.call(resource) }
84
+ end
85
+
86
+ def _run_validation_callbacks(resource:)
87
+ Array(_validates).each do |callback|
88
+ if (result = callback.call(resource)).is_a? String
89
+ $stderr.puts %(
90
+ #{result}
91
+ )
92
+ exit 1
93
+ end
94
+ end
95
+ end
96
+
97
+ def _run_before_process_callbacks(resource:)
98
+ Array(_before_process).each { |c| c.call(resource) }
99
+ end
100
+
101
+ def _run_after_process_callbacks(resource:)
102
+ Array(_after_process).each { |c| c.call(resource) }
103
+ end
104
+
105
+ def _run_build_callbacks(params:)
106
+ Array(_builds).each do |callback|
107
+ result = callback.call(self, params: params)
108
+ return result if result.is_a?(Class)
109
+ end
110
+
111
+ self
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,46 @@
1
+ module DockerRailsProxy
2
+ module InheritableAttributes
3
+ def self.included(base)
4
+ base.extend(ClassMethods)
5
+ end
6
+
7
+ module ClassMethods
8
+ def inheritable_attributes(*args)
9
+ @inheritable_attributes ||= [:inheritable_attributes]
10
+ @inheritable_attributes += args
11
+ args.each do |arg|
12
+ class_eval %(class << self; attr_accessor :#{arg} end)
13
+ end
14
+ @inheritable_attributes
15
+ end
16
+
17
+ def uninheritable_attributes(*args)
18
+ @uninheritable_attributes ||= [:uninheritable_attributes]
19
+ @uninheritable_attributes += args
20
+ args.each do |arg|
21
+ class_eval %(class << self; attr_accessor :#{arg} end)
22
+ end
23
+ @uninheritable_attributes
24
+ end
25
+
26
+ def inherited(subclass)
27
+ @inheritable_attributes.each do |inheritable_attribute|
28
+ instance_name = "@#{inheritable_attribute}"
29
+ instance_value = instance_variable_get(instance_name).dup
30
+ subclass.instance_variable_set(instance_name, instance_value)
31
+ end
32
+
33
+ @uninheritable_attributes.each do |uninheritable_attribute|
34
+ instance_name = "@#{uninheritable_attribute}"
35
+
36
+ if instance_name == '@uninheritable_attributes'
37
+ instance_value = instance_variable_get(instance_name).dup
38
+ subclass.instance_variable_set(instance_name, instance_value)
39
+ else
40
+ subclass.instance_variable_set(instance_name, nil)
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,91 @@
1
+ module DockerRailsProxy
2
+ module Rsync
3
+ def self.included(base)
4
+ base.extend(ClassMethods)
5
+ end
6
+
7
+ module ClassMethods
8
+ end
9
+
10
+ def sync(source:, reverse: false, silent: false)
11
+ _rsync.sync source: source, reverse: reverse, silent: silent
12
+ end
13
+
14
+ private
15
+
16
+ def _rsync_host
17
+ @_rsync_host ||= begin
18
+ "rsync://#{ENV['DOCKER_HOST'].to_s.sub('tcp://', '').sub(/:\d+$/, '')}:10873"
19
+ end
20
+ end
21
+
22
+ def _rsync
23
+ @_rsync ||= Sync.new(rsync_host: _rsync_host)
24
+ end
25
+
26
+ class Sync
27
+ attr_reader :rsync_host
28
+
29
+ def initialize(rsync_host:)
30
+ @rsync_host = rsync_host
31
+ end
32
+
33
+ def self.call(rsync_host:, **options)
34
+ new(rsync_host: rsync_host).sync(options)
35
+ end
36
+
37
+ def sync(options)
38
+ source, target, volume = normalize_options(options)
39
+
40
+ result = send "sync_#{volume}", source: source, target: target
41
+
42
+ if result && options[:silent].eql?(false)
43
+ puts "#{source} =======> #{target}"
44
+ end
45
+
46
+ result
47
+ end
48
+
49
+ private
50
+
51
+ def normalize_options(source:, reverse: false, **)
52
+ values = if source.include? APP_PATH
53
+ ["#{APP_PATH}/", 'app']
54
+ elsif source.include? GEMS_PATH
55
+ ["#{GEMS_PATH}/", 'gems']
56
+ else
57
+ $stderr.puts "There is no rsync volume related with this path: #{source}"
58
+ exit 1
59
+ end
60
+
61
+ paths = [values.first, "#{rsync_host}/#{values.last}"]
62
+
63
+ [paths.send(reverse ? :reverse : :to_a), values.last].flatten
64
+ end
65
+
66
+ def sync_app(source:, target:)
67
+ system <<-EOS
68
+ rsync -avqP --no-owner --no-group \
69
+ --exclude 'tmp/cache' \
70
+ --exclude 'tmp/letter_opener' \
71
+ --exclude 'tmp/pids' \
72
+ --exclude 'log' \
73
+ --exclude '.git*' \
74
+ --force \
75
+ --delete \
76
+ #{source} #{target}
77
+ EOS
78
+ end
79
+
80
+ def sync_gems(source:, target:)
81
+ system <<-EOS
82
+ rsync -avqP --no-owner --no-group \
83
+ --exclude '.git*' \
84
+ --force \
85
+ --delete \
86
+ #{source} #{target}
87
+ EOS
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,36 @@
1
+ class String
2
+ def red
3
+ colorize(31)
4
+ end
5
+
6
+ def green
7
+ colorize(32)
8
+ end
9
+
10
+ def yellow
11
+ colorize(33)
12
+ end
13
+
14
+ def blue
15
+ colorize(34)
16
+ end
17
+
18
+ def pink
19
+ colorize(35)
20
+ end
21
+
22
+ def light_blue
23
+ colorize(36)
24
+ end
25
+
26
+ def bold
27
+ "\033[1m#{self}\033[0m"
28
+ end
29
+
30
+ private
31
+
32
+ # colorization
33
+ def colorize(color_code)
34
+ "\e[#{color_code}m#{self}\e[0m"
35
+ end
36
+ end
@@ -0,0 +1,21 @@
1
+ class String
2
+ def parameterize(separator = '-'.freeze)
3
+ downcase.gsub(/\W/, separator).gsub('_'.freeze, separator)
4
+ end
5
+
6
+ def classify
7
+ gsub(/\W/, ''.freeze)
8
+ .gsub('_'.freeze, ''.freeze)
9
+ .sub(/^[a-z\d]*/, &:capitalize)
10
+ end
11
+
12
+ def constantize
13
+ split('::'.freeze).inject(Object) do |constant, name|
14
+ constant.const_get(name.classify)
15
+ end
16
+ end
17
+
18
+ def underscore
19
+ downcase.gsub('::'.freeze, '/'.freeze).gsub('-'.freeze, '_'.freeze)
20
+ end
21
+ end
@@ -0,0 +1,3 @@
1
+ module DockerRailsProxy
2
+ VERSION = '0.0.1'
3
+ end
@@ -1,2 +1,105 @@
1
+ require 'docker_rails_proxy/extends/colorization'
2
+ require 'docker_rails_proxy/extends/string_support'
3
+
1
4
  module DockerRailsProxy
5
+ COMMANDS = Dir[File.expand_path('../docker_rails_proxy/commands/*.rb', __FILE__)].map do |f|
6
+ File.basename(f, '.rb').parameterize
7
+ end.freeze
8
+
9
+ COMMANDS.each do |c|
10
+ autoload c.classify.to_sym, "docker_rails_proxy/commands/#{c.underscore}"
11
+ end
12
+
13
+ autoload :InheritableAttributes, 'docker_rails_proxy/concerns/inheritable_attributes'
14
+ autoload :Callbacks, 'docker_rails_proxy/concerns/callbacks'
15
+ autoload :Rsync, 'docker_rails_proxy/concerns/rsync'
16
+
17
+ autoload :Cli, 'docker_rails_proxy/cli'
18
+ autoload :VERSION, 'docker_rails_proxy/version'
19
+
20
+ class Base
21
+ include InheritableAttributes
22
+ include Callbacks
23
+ include Rsync
24
+
25
+ attr_reader :arguments
26
+
27
+ def initialize(arguments:)
28
+ @arguments = arguments
29
+ end
30
+
31
+ class << self
32
+ def build_path(path = nil)
33
+ File.join(APP_PATH, block_given? ? yield : path)
34
+ end
35
+
36
+ def call(options)
37
+ klass = _run_build_callbacks params: options
38
+
39
+ klass.send :_run_before_initialize_callbacks
40
+
41
+ resource = klass.new(options)
42
+
43
+ klass.send :_run_after_initialize_callbacks, resource: resource
44
+
45
+ klass.send :_run_validation_callbacks, resource: resource
46
+
47
+ klass.send :_run_before_process_callbacks, resource: resource
48
+
49
+ result = resource.process
50
+
51
+ klass.send :_run_after_process_callbacks, resource: resource
52
+ result
53
+ end
54
+ end
55
+
56
+ def process
57
+ raise NotImplementedError, 'Subclasses must implement a process method'
58
+ end
59
+
60
+ private
61
+
62
+ def build_path(*args, &block)
63
+ self.class.build_path(*args, &block)
64
+ end
65
+ end
66
+
67
+ class AwsCli < Base
68
+ before_initialize do
69
+ unless system 'type aws &> /dev/null'
70
+ 'aws is required, `brew install awscli`'
71
+ end
72
+ end
73
+ end
74
+
75
+ class Docker < Base
76
+ before_initialize do
77
+ if ENV['DOCKER_HOST'].nil?
78
+ %(
79
+ Couldn't connect to Docker daemon you might need to run:
80
+ docker-machine start default
81
+ eval $(docker-machine env default)
82
+ )
83
+ end
84
+ end
85
+ end
86
+
87
+ class DockerMainApp < Docker
88
+ before_initialize do
89
+ unless system "docker ps | grep '#{APP_NAME}$' &> /dev/null"
90
+ %(
91
+ Couldn't connect to #{APP_NAME} container you might need to run:
92
+ bin/#{APP_NAME} compose up
93
+ )
94
+ end
95
+ end
96
+
97
+ # Makes sure the container is in sync with the APP_PATH
98
+ before_process { sync source: APP_PATH, silent: true }
99
+ end
100
+
101
+ class SyncBack < DockerMainApp
102
+ after_process { system "docker exec #{APP_NAME} chown -R nobody:nogroup ." }
103
+ after_process { sync source: APP_PATH, reverse: true }
104
+ end
2
105
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: docker_rails_proxy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jairo
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-09-27 00:00:00.000000000 Z
12
+ date: 2016-09-30 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Configures docker-compose and provides rails command helpers
15
15
  email:
@@ -22,6 +22,26 @@ files:
22
22
  - MIT-LICENSE
23
23
  - README.md
24
24
  - lib/docker_rails_proxy.rb
25
+ - lib/docker_rails_proxy/cli.rb
26
+ - lib/docker_rails_proxy/commands/build.rb
27
+ - lib/docker_rails_proxy/commands/bundle.rb
28
+ - lib/docker_rails_proxy/commands/compose.rb
29
+ - lib/docker_rails_proxy/commands/compose/down.rb
30
+ - lib/docker_rails_proxy/commands/compose/override.rb
31
+ - lib/docker_rails_proxy/commands/compose/proxy.rb
32
+ - lib/docker_rails_proxy/commands/compose/up.rb
33
+ - lib/docker_rails_proxy/commands/data_bags.rb
34
+ - lib/docker_rails_proxy/commands/rails.rb
35
+ - lib/docker_rails_proxy/commands/rake.rb
36
+ - lib/docker_rails_proxy/commands/rspec.rb
37
+ - lib/docker_rails_proxy/commands/spring.rb
38
+ - lib/docker_rails_proxy/commands/ssh.rb
39
+ - lib/docker_rails_proxy/concerns/callbacks.rb
40
+ - lib/docker_rails_proxy/concerns/inheritable_attributes.rb
41
+ - lib/docker_rails_proxy/concerns/rsync.rb
42
+ - lib/docker_rails_proxy/extends/colorization.rb
43
+ - lib/docker_rails_proxy/extends/string_support.rb
44
+ - lib/docker_rails_proxy/version.rb
25
45
  homepage: https://github.com/jairovm/docker_rails_proxy
26
46
  licenses:
27
47
  - MIT