devkitkat 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,46 @@
1
+ module Devkitkat
2
+ class Main
3
+ attr_reader :config, :command
4
+
5
+ def initialize
6
+ @command = Command.new
7
+ @config = Config.new(command.kit_root)
8
+ end
9
+
10
+ def execute
11
+ if command.tty? && target_services.count > 1
12
+ raise ArgumentError, 'TTY mode accepts only one service'
13
+ end
14
+
15
+ log_paths = target_services.map(&:log_path)
16
+ puts %Q{See the log at \n#{log_paths.join("\n")}}
17
+
18
+ if target_services.count == 1
19
+ # If the target is only one, it could be console access (TTY)
20
+ # so we can't run in parallel.
21
+ service = target_services.first
22
+ execute_for(service)
23
+ else
24
+ Parallel.map(target_services, progress: 'Executing', in_processes: 8) do |service|
25
+ execute_for(service)
26
+ end
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def execute_for(service)
33
+ begin
34
+ service.execute!
35
+ rescue Devkitkat::Service::ScriptError => e
36
+ puts "Failure: #{e}".colorize(:red)
37
+ raise Parallel::Kill
38
+ end
39
+ end
40
+
41
+ def target_services
42
+ @target_services ||= config.resolve!(command.target, exclude: command.options[:exclude])
43
+ .map { |name| Service.new(name, config, command) }
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,243 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'fileutils'
4
+
5
+ module Devkitkat
6
+ class Service
7
+ attr_reader :name, :config, :command, :executor
8
+
9
+ ScriptError = Class.new(StandardError)
10
+
11
+ DIVISIONS = %w[src script data cache log example dockerfile].freeze
12
+ SERVICE_PROPERTIES = %w[repo host port]
13
+
14
+ SCRIPT_TEMPLATE = <<-EOS
15
+ #!/bin/bash
16
+ set -e
17
+
18
+ # TODO: Define scripts
19
+ EOS
20
+
21
+ delegate :options, :script, :args, :kit_root, to: :command
22
+
23
+ def initialize(name, config, command)
24
+ @name, @config, @command = name, config, command
25
+ end
26
+
27
+ def execute!
28
+ executor.prepare
29
+
30
+ inject_global_variables
31
+ inject_public_variables
32
+ inject_private_variables
33
+ setup_logger
34
+
35
+ FileUtils.rm_f(log_path)
36
+ FileUtils.mkdir_p(log_dir)
37
+
38
+ method = script.tr('-', '_')
39
+
40
+ if File.exist?(script_path)
41
+ executor.write(%Q{echo "This script is a custom script provided by you."})
42
+ executor.write(script_path)
43
+ elsif respond_to?(method, true)
44
+ executor.write(%Q{echo "This script is a predefined script provided by devkitkat."})
45
+ send(method)
46
+ end
47
+
48
+ executor.commit.tap do |result|
49
+ raise ScriptError, process_error_message($?) unless result
50
+ end
51
+ ensure
52
+ executor.cleanup
53
+ end
54
+
55
+ def log_path
56
+ File.join(log_dir, "#{script}.log")
57
+ end
58
+
59
+ def container_name
60
+ "#{config.application}-#{name}"
61
+ end
62
+
63
+ DIVISIONS.each do |division|
64
+ define_method :"#{division}_dir" do
65
+ File.join(service_dir, division)
66
+ end
67
+ end
68
+
69
+ SERVICE_PROPERTIES.each do |property|
70
+ define_method :"#{property}_defined?" do
71
+ config.service_hash(name).key?(property)
72
+ end
73
+
74
+ define_method :"#{property}" do
75
+ config.service_hash(name)[property]
76
+ end
77
+ end
78
+
79
+ def service_dir
80
+ File.join(kit_root, 'services', name)
81
+ end
82
+
83
+ def shared_script_dir
84
+ File.join(script_dir, 'shared')
85
+ end
86
+
87
+ private
88
+
89
+ def inject_global_variables
90
+ config.variables.each do |key, value|
91
+ executor.write("export #{key}=#{value}")
92
+ end
93
+
94
+ command.variables&.each do |key, value|
95
+ executor.write("export #{key}=#{value}")
96
+ end
97
+
98
+ executor.write("export MI_ROOT_DIR=#{kit_root}")
99
+ executor.write("export MI_ENVIRONMENT_TYPE=#{config.environment_type.to_s}")
100
+ executor.write("export MI_APPLICATION=#{config.application.to_s}")
101
+ end
102
+
103
+ def inject_public_variables
104
+ all_services.each do |service|
105
+ executor.write("export MI_#{service.name.upcase}_DIR=#{service.service_dir}")
106
+
107
+ DIVISIONS.each do |division|
108
+ executor.write("export MI_#{service.name.upcase}_#{division.upcase}_DIR=#{service.send("#{division}_dir")}")
109
+ end
110
+
111
+ executor.write("export MI_#{service.name.upcase}_SHARED_SCRIPT_DIR=#{service.shared_script_dir}")
112
+
113
+ config.service_hash(service.name).each do |key, value|
114
+ executor.write("export MI_#{service.name.upcase}_#{key.upcase}=#{value}")
115
+ end
116
+ end
117
+ end
118
+
119
+ def inject_private_variables
120
+ executor.write("export MI_SELF_DIR=#{service_dir}")
121
+
122
+ DIVISIONS.each do |division|
123
+ executor.write("export MI_SELF_#{division.upcase}_DIR=#{send("#{division}_dir")}")
124
+ end
125
+
126
+ config.service_hash(name).each do |key, value|
127
+ executor.write("export #{key}=#{value}")
128
+ end
129
+ end
130
+
131
+ def setup_logger
132
+ return if command.tty?
133
+
134
+ executor.write("exec > #{log_path} 2>&1")
135
+ end
136
+
137
+ def all_services
138
+ @all_services ||= config.all_services.map { |service| Service.new(service, config, command) }
139
+ end
140
+
141
+ def script_path
142
+ File.join(script_dir, script)
143
+ end
144
+
145
+ def system?
146
+ name == 'system'
147
+ end
148
+
149
+ def process_error_message(exit_code)
150
+ %Q[The command "#{script}" for "#{name}" exited with non-zero code: #{exit_code}.
151
+ See the log file: #{log_path}]
152
+ end
153
+
154
+ def add_script
155
+ names = command.args.any? ? command.args : %w[configure unconfigure start stop]
156
+
157
+ FileUtils.mkdir_p(script_dir)
158
+
159
+ names.each do |name|
160
+ file_path = File.join(script_dir, name)
161
+
162
+ next if File.exist?(file_path)
163
+
164
+ File.write(file_path, SCRIPT_TEMPLATE)
165
+ File.chmod(0777, file_path)
166
+ end
167
+ end
168
+
169
+ def add_example
170
+ names = command.args
171
+
172
+ raise ArgumentError, 'Please specify at least one example name' if names.empty?
173
+
174
+ FileUtils.mkdir_p(example_dir)
175
+
176
+ names.each do |name|
177
+ file_path = File.join(example_dir, name)
178
+
179
+ next if File.exist?(file_path)
180
+
181
+ FileUtils.touch(file_path)
182
+ File.chmod(0777, file_path)
183
+ end
184
+ end
185
+
186
+ def add_shared_script
187
+ raise ArgumentError, %Q{Shared script has to be added to "system"} unless name == 'system'
188
+
189
+ FileUtils.mkdir_p(script_dir)
190
+
191
+ file_path = File.join(script_dir, 'shared')
192
+
193
+ return if File.exist?(file_path)
194
+
195
+ FileUtils.touch(file_path)
196
+ File.chmod(0777, file_path)
197
+ end
198
+
199
+ def clone
200
+ return unless repo_defined?
201
+
202
+ options = []
203
+
204
+ if command.options[:git_depth]
205
+ options << "--depth #{command.options[:git_depth]}"
206
+ end
207
+
208
+ executor.write("git clone #{repo} #{src_dir} #{options.join(' ')}")
209
+ end
210
+
211
+ def pull
212
+ return unless repo_defined?
213
+
214
+ remote = command.options[:git_remote] || 'origin'
215
+ branch = command.options[:git_branch] || 'master'
216
+
217
+ executor.write("git pull #{remote} #{branch}")
218
+ end
219
+
220
+ def clean
221
+ executor.write("rm -rf #{src_dir}")
222
+ executor.write("rm -rf #{data_dir}")
223
+ executor.write("rm -rf #{cache_dir}")
224
+ executor.write("rm -rf #{log_dir}")
225
+ end
226
+
227
+ def reconfigure
228
+ unconfigure_path = File.join(script_dir, 'unconfigure')
229
+ configure_path = File.join(script_dir, 'configure')
230
+
231
+ executor.write(unconfigure_path) if File.exist?(unconfigure_path)
232
+ executor.write(configure_path) if File.exist?(configure_path)
233
+ end
234
+
235
+ def poop
236
+ executor.write(%Q{echo "💩"})
237
+ end
238
+
239
+ def executor
240
+ @executor ||= Executor.new(self)
241
+ end
242
+ end
243
+ end
@@ -0,0 +1,3 @@
1
+ module Devkitkat
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,225 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: devkitkat
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Shinya Maeda
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-10-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.17'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.17'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec-temp_dir
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 1.1.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.1.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.12.2
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.12.2
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry-nav
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: activesupport
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 6.0.0
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 6.0.0
111
+ - !ruby/object:Gem::Dependency
112
+ name: parallel
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 1.17.0
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 1.17.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: ruby-progressbar
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: 1.10.1
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: 1.10.1
139
+ - !ruby/object:Gem::Dependency
140
+ name: colorize
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: 0.8.1
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: 0.8.1
153
+ - !ruby/object:Gem::Dependency
154
+ name: docker-api
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: 1.34.2
160
+ type: :runtime
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: 1.34.2
167
+ description: Make micro services easy
168
+ email:
169
+ - shinya@gitlab.com
170
+ executables:
171
+ - devkitkat
172
+ extensions: []
173
+ extra_rdoc_files: []
174
+ files:
175
+ - ".gitignore"
176
+ - ".gitlab-ci.yml"
177
+ - ".rspec"
178
+ - CODE_OF_CONDUCT.md
179
+ - Gemfile
180
+ - Gemfile.lock
181
+ - LICENSE.txt
182
+ - README.md
183
+ - Rakefile
184
+ - bin/console
185
+ - bin/devkitkat
186
+ - bin/fast_rspec
187
+ - bin/setup
188
+ - devkitkat.gemspec
189
+ - docs/READ.md
190
+ - docs/config/READ.md
191
+ - docs/machine/READ.md
192
+ - docs/service/READ.md
193
+ - lib/devkitkat.rb
194
+ - lib/devkitkat/command.rb
195
+ - lib/devkitkat/config.rb
196
+ - lib/devkitkat/executor.rb
197
+ - lib/devkitkat/executor/docker.rb
198
+ - lib/devkitkat/executor/local.rb
199
+ - lib/devkitkat/main.rb
200
+ - lib/devkitkat/service.rb
201
+ - lib/devkitkat/version.rb
202
+ homepage: https://gitlab.com/dosuken123/devkitkat
203
+ licenses:
204
+ - MIT
205
+ metadata: {}
206
+ post_install_message:
207
+ rdoc_options: []
208
+ require_paths:
209
+ - lib
210
+ required_ruby_version: !ruby/object:Gem::Requirement
211
+ requirements:
212
+ - - ">="
213
+ - !ruby/object:Gem::Version
214
+ version: '0'
215
+ required_rubygems_version: !ruby/object:Gem::Requirement
216
+ requirements:
217
+ - - ">="
218
+ - !ruby/object:Gem::Version
219
+ version: '0'
220
+ requirements: []
221
+ rubygems_version: 3.0.3
222
+ signing_key:
223
+ specification_version: 4
224
+ summary: Make micro services easy
225
+ test_files: []