docker_rails_proxy 0.0.0 → 0.0.1

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.
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