d13n 0.5.2

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.
Files changed (95) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +35 -0
  3. data/.rspec +6 -0
  4. data/.rubocop.yml +5 -0
  5. data/.ruby-version +1 -0
  6. data/Gemfile +22 -0
  7. data/Gemfile.lock +151 -0
  8. data/Guardfile +63 -0
  9. data/README.md +200 -0
  10. data/bin/d13n +11 -0
  11. data/d13n.gemspec +34 -0
  12. data/lib/d13n/application/class_methods.rb +56 -0
  13. data/lib/d13n/application.rb +3 -0
  14. data/lib/d13n/cli/command.rb +76 -0
  15. data/lib/d13n/cli/commands/scaffold.rb +345 -0
  16. data/lib/d13n/configuration/default_source.rb +200 -0
  17. data/lib/d13n/configuration/dotted_hash.rb +39 -0
  18. data/lib/d13n/configuration/environment_source.rb +89 -0
  19. data/lib/d13n/configuration/manager.rb +239 -0
  20. data/lib/d13n/configuration/manual_source.rb +4 -0
  21. data/lib/d13n/configuration/mask_defaults.rb +6 -0
  22. data/lib/d13n/configuration/server_source.rb +83 -0
  23. data/lib/d13n/configuration/yaml_source.rb +66 -0
  24. data/lib/d13n/configuration.rb +6 -0
  25. data/lib/d13n/ext/string.rb +17 -0
  26. data/lib/d13n/logger/log_once.rb +24 -0
  27. data/lib/d13n/logger/memory_logger.rb +48 -0
  28. data/lib/d13n/logger/null_logger.rb +16 -0
  29. data/lib/d13n/logger.rb +213 -0
  30. data/lib/d13n/metric/conductor.rb +123 -0
  31. data/lib/d13n/metric/helper.rb +62 -0
  32. data/lib/d13n/metric/http_clients/http_helper.rb +15 -0
  33. data/lib/d13n/metric/http_clients/net_http_wrappers.rb +54 -0
  34. data/lib/d13n/metric/http_clients.rb +4 -0
  35. data/lib/d13n/metric/instrumentation/app_exception.rb +70 -0
  36. data/lib/d13n/metric/instrumentation/controller_instrumentation.rb +91 -0
  37. data/lib/d13n/metric/instrumentation/em-websocket.rb +71 -0
  38. data/lib/d13n/metric/instrumentation/exception.rb +65 -0
  39. data/lib/d13n/metric/instrumentation/middleware_tracing.rb +82 -0
  40. data/lib/d13n/metric/instrumentation/net.rb +36 -0
  41. data/lib/d13n/metric/instrumentation/sinatra/stream_namer.rb +35 -0
  42. data/lib/d13n/metric/instrumentation/sinatra.rb +165 -0
  43. data/lib/d13n/metric/instrumentation/websocket_instrumentation.rb +42 -0
  44. data/lib/d13n/metric/instrumentation.rb +41 -0
  45. data/lib/d13n/metric/manager.rb +106 -0
  46. data/lib/d13n/metric/metrics/app_database_metric.rb +4 -0
  47. data/lib/d13n/metric/metrics/app_http_metric.rb +229 -0
  48. data/lib/d13n/metric/metrics/app_state_metric.rb +103 -0
  49. data/lib/d13n/metric/metrics/base.rb +14 -0
  50. data/lib/d13n/metric/metrics/biz_state_metric.rb +4 -0
  51. data/lib/d13n/metric/metrics.rb +6 -0
  52. data/lib/d13n/metric/stream/span_tracer_helpers.rb +72 -0
  53. data/lib/d13n/metric/stream/stream_tracer_helpers.rb +141 -0
  54. data/lib/d13n/metric/stream/traced_span_stack.rb +73 -0
  55. data/lib/d13n/metric/stream.rb +322 -0
  56. data/lib/d13n/metric/stream_state.rb +68 -0
  57. data/lib/d13n/metric.rb +11 -0
  58. data/lib/d13n/rack/d13n_middleware.rb +21 -0
  59. data/lib/d13n/rack/metric_middleware.rb +18 -0
  60. data/lib/d13n/service/background_job/sinatra.rb +24 -0
  61. data/lib/d13n/service/background_job.rb +1 -0
  62. data/lib/d13n/service/start.rb +75 -0
  63. data/lib/d13n/service.rb +91 -0
  64. data/lib/d13n/support/request_id.rb +29 -0
  65. data/lib/d13n/version.rb +14 -0
  66. data/lib/d13n.rb +92 -0
  67. data/templates/.rspec.template +6 -0
  68. data/templates/.ruby-version.template +1 -0
  69. data/templates/Gemfile.template +16 -0
  70. data/templates/Guardfile.template +64 -0
  71. data/templates/Jenkinsfile.template +85 -0
  72. data/templates/Makefile.template +178 -0
  73. data/templates/README.md.template +1 -0
  74. data/templates/Rakefile.template +6 -0
  75. data/templates/application.yml.template +14 -0
  76. data/templates/config.ru.template +4 -0
  77. data/templates/docker/.dockerignore.template +5 -0
  78. data/templates/docker/Dockerfile.application.development +15 -0
  79. data/templates/docker/Dockerfile.cache.development +18 -0
  80. data/templates/docker/Dockerfile.development +27 -0
  81. data/templates/docker/Dockerfile.release +16 -0
  82. data/templates/docker/docker-compose.yml.development +53 -0
  83. data/templates/docker/docker-compose.yml.release +37 -0
  84. data/templates/lib/api/service.rb.template +10 -0
  85. data/templates/lib/api/support.rb.template +38 -0
  86. data/templates/lib/api/version.rb.template +3 -0
  87. data/templates/lib/api.rb.template +4 -0
  88. data/templates/lib/application.rb.template +49 -0
  89. data/templates/lib/service.rb.template +4 -0
  90. data/templates/lib/version.rb.template +3 -0
  91. data/templates/scripts/test.sh.template +7 -0
  92. data/templates/spec/spec_helper.rb.template +56 -0
  93. data/templates/tasks/migration.rake.template +11 -0
  94. data/templates/tasks/spec.rake.template +21 -0
  95. metadata +199 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 579f082bbf5421f1d1601f2126536657c7993105021a5ebba7f8f1db62d5165f
4
+ data.tar.gz: f45437b4cb7dbacaccca7df1ad21853b8c7c65d6e57caa9d8bd8b4227a359b22
5
+ SHA512:
6
+ metadata.gz: 10e622d409f03a863cc1e8ba4d7f34e8eb9a8aa43d69f3656569ce943032395f64c3d55d7c7ac499dc011224e6ab3411d731b4babaa1f989c73ae634862b3efe
7
+ data.tar.gz: 9cfa4a24d039dca47895dec39be701d88e811511ff6adc71bb1e0768e9273d95effb66b680ce4e2d2cbd62f5dc04c6a5371e0f9cfb4bc02a69bec5041650f94f
data/.gitignore ADDED
@@ -0,0 +1,35 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ coverage
6
+ InstalledFiles
7
+ lib/bundler/man
8
+ pkg
9
+ rdoc
10
+ spec/reports
11
+ test/tmp
12
+ test/version_tmp
13
+ tmp
14
+
15
+ # YARD artifacts
16
+ .yardoc
17
+ _yardoc
18
+ doc/
19
+
20
+ # Vim
21
+ *.swp
22
+ *.swo
23
+
24
+ # ctags
25
+ tags
26
+
27
+ #Mac
28
+ .DS_Store
29
+ tmp/
30
+
31
+ .idea
32
+ reports/
33
+ target/
34
+ log
35
+ migrations/*.db
data/.rspec ADDED
@@ -0,0 +1,6 @@
1
+ --format Fuubar
2
+ --color
3
+ --format html
4
+ --out reports/rspec/result.html
5
+ --format json
6
+ --out reports/rspec/result.json
data/.rubocop.yml ADDED
@@ -0,0 +1,5 @@
1
+ AllCops:
2
+ Exclude:
3
+ - 'vendor/**/*'
4
+ - 'spec/fixtures/**/*'
5
+ - 'tmp/**/*'
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-2.5.0@d13n
data/Gemfile ADDED
@@ -0,0 +1,22 @@
1
+ source 'http://gems.sd.laxino.com'
2
+
3
+ #gem 'config_kit'
4
+ gemspec
5
+ group :development do
6
+ gem 'guard'
7
+ gem 'guard-rspec', require: false
8
+ gem 'guard-bundler', require: false
9
+ gem 'linguistics'
10
+ end
11
+
12
+ group :test do
13
+ gem 'rubocop', require: false
14
+ gem 'simplecov', '0.16.0'
15
+ gem 'rspec'
16
+ gem 'rspec-nc'
17
+ gem 'fuubar'
18
+ gem 'factory_bot'
19
+ gem 'rack-test'
20
+ gem 'faker'
21
+ gem 'as-duration'
22
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,151 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ d13n (0.4.6)
5
+ bundler (~> 1.14)
6
+ config_kit (= 0.0.16)
7
+ statsd-instrument (~> 2.2, >= 2.2.0)
8
+
9
+ GEM
10
+ remote: http://gems.sd.laxino.com/
11
+ specs:
12
+ activesupport (5.1.4)
13
+ concurrent-ruby (~> 1.0, >= 1.0.2)
14
+ i18n (~> 0.7)
15
+ minitest (~> 5.1)
16
+ tzinfo (~> 1.1)
17
+ as-duration (0.1.1)
18
+ ast (2.4.0)
19
+ coderay (1.1.2)
20
+ concurrent-ruby (1.0.5)
21
+ config_kit (0.0.16)
22
+ bundler (~> 1.12)
23
+ diplomat (= 2.0.2)
24
+ git (= 1.3.0)
25
+ diff-lcs (1.3)
26
+ diplomat (2.0.2)
27
+ faraday (~> 0.9)
28
+ json
29
+ docile (1.3.0)
30
+ factory_bot (4.8.2)
31
+ activesupport (>= 3.0.0)
32
+ faker (1.8.4)
33
+ i18n (~> 0.5)
34
+ faraday (0.15.2)
35
+ multipart-post (>= 1.2, < 3)
36
+ ffi (1.9.18)
37
+ formatador (0.2.5)
38
+ fuubar (2.2.0)
39
+ rspec-core (~> 3.0)
40
+ ruby-progressbar (~> 1.4)
41
+ git (1.3.0)
42
+ guard (2.14.1)
43
+ formatador (>= 0.2.4)
44
+ listen (>= 2.7, < 4.0)
45
+ lumberjack (~> 1.0)
46
+ nenv (~> 0.1)
47
+ notiffany (~> 0.0)
48
+ pry (>= 0.9.12)
49
+ shellany (~> 0.0)
50
+ thor (>= 0.18.1)
51
+ guard-bundler (2.1.0)
52
+ bundler (~> 1.0)
53
+ guard (~> 2.2)
54
+ guard-compat (~> 1.1)
55
+ guard-compat (1.2.1)
56
+ guard-rspec (4.7.3)
57
+ guard (~> 2.1)
58
+ guard-compat (~> 1.1)
59
+ rspec (>= 2.99.0, < 4.0)
60
+ i18n (0.9.1)
61
+ concurrent-ruby (~> 1.0)
62
+ json (2.1.0)
63
+ linguistics (2.1.0)
64
+ loggability (~> 0.11)
65
+ listen (3.1.5)
66
+ rb-fsevent (~> 0.9, >= 0.9.4)
67
+ rb-inotify (~> 0.9, >= 0.9.7)
68
+ ruby_dep (~> 1.2)
69
+ loggability (0.14.0)
70
+ lumberjack (1.0.12)
71
+ method_source (0.9.0)
72
+ minitest (5.10.3)
73
+ multipart-post (2.0.0)
74
+ nenv (0.3.0)
75
+ notiffany (0.1.1)
76
+ nenv (~> 0.1)
77
+ shellany (~> 0.0)
78
+ parallel (1.12.1)
79
+ parser (2.5.1.0)
80
+ ast (~> 2.4.0)
81
+ powerpack (0.1.1)
82
+ pry (0.11.2)
83
+ coderay (~> 1.1.0)
84
+ method_source (~> 0.9.0)
85
+ rack (2.0.3)
86
+ rack-test (0.7.0)
87
+ rack (>= 1.0, < 3)
88
+ rainbow (3.0.0)
89
+ rb-fsevent (0.10.2)
90
+ rb-inotify (0.9.10)
91
+ ffi (>= 0.5.0, < 2)
92
+ rspec (3.7.0)
93
+ rspec-core (~> 3.7.0)
94
+ rspec-expectations (~> 3.7.0)
95
+ rspec-mocks (~> 3.7.0)
96
+ rspec-core (3.7.0)
97
+ rspec-support (~> 3.7.0)
98
+ rspec-expectations (3.7.0)
99
+ diff-lcs (>= 1.2.0, < 2.0)
100
+ rspec-support (~> 3.7.0)
101
+ rspec-mocks (3.7.0)
102
+ diff-lcs (>= 1.2.0, < 2.0)
103
+ rspec-support (~> 3.7.0)
104
+ rspec-nc (0.3.0)
105
+ rspec (>= 3)
106
+ terminal-notifier (>= 1.4)
107
+ rspec-support (3.7.0)
108
+ rubocop (0.54.0)
109
+ parallel (~> 1.10)
110
+ parser (>= 2.5)
111
+ powerpack (~> 0.1)
112
+ rainbow (>= 2.2.2, < 4.0)
113
+ ruby-progressbar (~> 1.7)
114
+ unicode-display_width (~> 1.0, >= 1.0.1)
115
+ ruby-progressbar (1.9.0)
116
+ ruby_dep (1.5.0)
117
+ shellany (0.0.1)
118
+ simplecov (0.16.0)
119
+ docile (~> 1.1)
120
+ json (>= 1.8, < 3)
121
+ simplecov-html (~> 0.10.0)
122
+ simplecov-html (0.10.2)
123
+ statsd-instrument (2.2.1)
124
+ terminal-notifier (2.0.0)
125
+ thor (0.20.0)
126
+ thread_safe (0.3.6)
127
+ tzinfo (1.2.4)
128
+ thread_safe (~> 0.1)
129
+ unicode-display_width (1.3.0)
130
+
131
+ PLATFORMS
132
+ ruby
133
+
134
+ DEPENDENCIES
135
+ as-duration
136
+ d13n!
137
+ factory_bot
138
+ faker
139
+ fuubar
140
+ guard
141
+ guard-bundler
142
+ guard-rspec
143
+ linguistics
144
+ rack-test
145
+ rspec
146
+ rspec-nc
147
+ rubocop
148
+ simplecov (= 0.16.0)
149
+
150
+ BUNDLED WITH
151
+ 1.14.6
data/Guardfile ADDED
@@ -0,0 +1,63 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ ## Uncomment and set this to only include directories you want to watch
5
+ # directories %w(app lib config test spec features) \
6
+ # .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}
7
+
8
+ ## Note: if you are using the `directories` clause above and you are not
9
+ ## watching the project directory ('.'), then you will want to move
10
+ ## the Guardfile to a watched dir and symlink it back, e.g.
11
+ #
12
+ # $ mkdir config
13
+ # $ mv Guardfile config/
14
+ # $ ln -s config/Guardfile .
15
+ #
16
+ # and, you'll have to watch "config/Guardfile" instead of "Guardfile"
17
+
18
+ guard :bundler do
19
+ require 'guard/bundler'
20
+ require 'guard/bundler/verify'
21
+ helper = Guard::Bundler::Verify.new
22
+
23
+ files = ['Gemfile']
24
+ files += Dir['*.gemspec'] if files.any? { |f| helper.uses_gemspec?(f) }
25
+
26
+ # Assume files are symlinked from somewhere
27
+ files.each { |file| watch(helper.real_path(file)) }
28
+ end
29
+
30
+ # Note: The cmd option is now required due to the increasing number of ways
31
+ # rspec may be run, below are examples of the most common uses.
32
+ # * bundler: 'bundle exec rspec'
33
+ # * bundler binstubs: 'bin/rspec'
34
+ # * spring: 'bin/rspec' (This will use spring if running and you have
35
+ # installed the spring binstubs per the docs)
36
+ # * zeus: 'zeus rspec' (requires the server to be started separately)
37
+ # * 'just' rspec: 'rspec'
38
+
39
+ guard :rspec, cmd: "bundle exec rspec" do
40
+ require "guard/rspec/dsl"
41
+ dsl = Guard::RSpec::Dsl.new(self)
42
+
43
+ # Feel free to open issues for suggestions and improvements
44
+
45
+ # RSpec files
46
+ rspec = dsl.rspec
47
+ watch(rspec.spec_helper) { rspec.spec_dir }
48
+ watch(rspec.spec_support) { rspec.spec_dir }
49
+ watch(rspec.spec_files)
50
+
51
+ # Ruby files
52
+ ruby = dsl.ruby
53
+ dsl.watch_spec_files_for(ruby.lib_files)
54
+ watch(%r{^spec/(.+)\.rb$}) {|m| puts m}
55
+ watch(%r{^lib/d13n/(.+)\.rb$}) { |m| ["spec/unit/#{m[1]}_spec.rb","spec/funcational/#{m[1]}_spec.rb"]}
56
+ watch(%r{^spec/factories/(.+)\.rb$}) { |m| ["spec/d13n/functional/service_objects/#{m[1]}_spec.rb","spec/d13n/unit/service_objects/#{m[1]}_spec.rb"] }
57
+ watch('spec/spec_helper.rb') { "spec" }
58
+ # Turnip features and steps
59
+ watch(%r{^spec/acceptance/(.+)\.feature$})
60
+ watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
61
+ Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance"
62
+ end
63
+ end
data/README.md ADDED
@@ -0,0 +1,200 @@
1
+ # Dockerization Gem for Microservice
2
+
3
+ To reduce developer afford to apply docker techinology for Microserice, d13n gem privodes following features:
4
+
5
+ * Microservice Scaffold
6
+ * Configuration Management
7
+ * Log Management
8
+ * Metric Collection
9
+ * Alert and Monitor
10
+
11
+ d13n provides a executable command 'd13n' and some sub-commands to cater all freatures
12
+
13
+ ## Microservice Scaffold
14
+
15
+ To lower the barrier for developer bootstrap a docker compactable Microserivce application, d13n provides scaffold feature to boostrap Microservice application folder in:
16
+
17
+ * CI Build and Release Docker files and scripts
18
+ * CI Workflow Makefile
19
+ * DB Migration folder
20
+ * Jenkinsfile
21
+ * Application Configuration YAML file
22
+
23
+ ### How to Use
24
+
25
+ d13n sub-command 'scaffold' will provide scaffold feature with minimun required options
26
+
27
+ Here is the help of scaffold:
28
+
29
+ ```bash
30
+ Usage: d13n scaffold [OPTIONS] ["description"]
31
+
32
+ Specific options:
33
+ -a, --app APP Specify an application to scaffold
34
+ -p, --project PROJECT Specify project of application to scaffold
35
+ -b, --bare Scaffold a bare folder
36
+ ```
37
+
38
+ The required options of scaffold are application name and project name belonged to application
39
+
40
+ Example:
41
+
42
+ ```bash
43
+ d13n scaffold -p g2 -a piston
44
+ Setting up appication [Piston] directories...
45
+ Generating Rake file ...
46
+ Generating Rake Task folder ...
47
+ Generating database migration folders ...
48
+ Generating Rake migration file ...
49
+ Generating Gemfile ...
50
+ Generating Makefile ...
51
+ Generating test.yml ...
52
+ Generating docker folder ...
53
+ Generating docker development folder ...
54
+ Generating development docker files ...
55
+ Generating docker release folder ...
56
+ Generating release docker files ...
57
+ Generating docker scripts ...
58
+ Generating Jekinsfile ...
59
+ Generating Ruby Version file ...
60
+ Generating RSpec configuraion file ...
61
+ Generating Spec folders ...
62
+ Generating Rspec Helper file ...
63
+ Generating Rspec rake task file ...
64
+ ```
65
+
66
+ Above is to generate a project named g2 and application piston.
67
+
68
+ Run Docker Test Step
69
+
70
+ ```bash
71
+ cd piston
72
+ make test
73
+ ```
74
+
75
+ ## Library Scaffold
76
+
77
+ For library, d13n privods a bare option to scaffold some files and folders, which can help to speed up the library development with docker ready on CI testing.
78
+
79
+ ### How to use
80
+
81
+ Assume an library named pivot-api with empty folder
82
+
83
+ ```
84
+ mkdir pivot-api
85
+ cd pivot-api
86
+
87
+ git init .
88
+ git remote add origin http://ben.wu@stash.mo.laxino.com/scm/g2/pivot-api.git
89
+ ```
90
+
91
+ After git repository create and add origin path, next to use d13n to scaffold a library folders and files
92
+
93
+ ```
94
+ d13n scaffold -a pivot-api -p g2 --bare
95
+ Generating Rake file ...
96
+ Generating Rake Task folder ...
97
+ Generating database migration folders ...
98
+ Generating Rake migration file ...
99
+ Generating Gemfile ...
100
+ Generating Makefile ...
101
+ Generating pivot-api.yml ...
102
+ Generating docker folder ...
103
+ Generating docker development folder ...
104
+ Generating development docker files ...
105
+ Generating docker release folder ...
106
+ Generating release docker files ...
107
+ Generating docker scripts ...
108
+ Generating Jekinsfile ...
109
+ Generating Ruby Version file ...
110
+ Generating RSpec configuraion file ...
111
+ Generating Spec folders ...
112
+ Generating Rspec Helper file ...
113
+ Generating Rspec rake task file ...
114
+ ```
115
+
116
+ Above folder and files will be generated
117
+
118
+ ```
119
+ git add .
120
+ git commit -m 'first init'
121
+ git push origin master
122
+ ```
123
+
124
+ ## Backgroud Job Example
125
+ ```
126
+ require 'd13n/service/background_job'
127
+ module Websocket::Api
128
+ class Service < ::Sinatra::Base
129
+ #
130
+ # define service routes here
131
+ #
132
+ background_job "a" do |opts|
133
+ EventMachine.run {
134
+ timer = EventMachine::PeriodicTimer.new(1) do
135
+ Websocket.logger.info(Websocket.config.to_hash)
136
+ end
137
+ }
138
+ end
139
+
140
+ get '/ws' do
141
+ headers 'Access-Control-Allow-Origin' => '*'
142
+ headers 'Access-Control-Allow-Headers' => '*'
143
+
144
+ if request.websocket?
145
+ @srv_manager ||= RollingRestartWS::ServiceManager.new
146
+ @ws_manager = @srv_manager.ws_manager
147
+ request.websocket do |ws|
148
+ ws.onopen do
149
+ Websocket.logger.info 'Socket Client connected'
150
+ end
151
+
152
+ ws.onmessage do |msg|
153
+
154
+ mem = `ps -o rss= -p #{Process.pid}`.to_i
155
+ Websocket.logger.info "Socket Client message received(#{msg.size}) #{msg}"
156
+ @msg = msg
157
+ response = process :json
158
+ response = "#{response}, mem:#{mem}"
159
+ Websocket.logger.info "Socket Response(#{response.size}) #{response}"
160
+ ws.send(response)
161
+ end
162
+
163
+ ws.onclose do
164
+ Websocket.logger.debug 'Socket Client disconnected'
165
+ ws = nil
166
+ end
167
+ end
168
+
169
+ else
170
+ 'Hello from WebSocket'
171
+ end
172
+ end
173
+
174
+ get '/service' do
175
+ process :json
176
+
177
+ end
178
+
179
+ def process(format)
180
+ uri = URI('http://localhost:3004')
181
+ Net::HTTP.get(uri)
182
+ mem = `ps -o rss= -p #{Process.pid}`.to_i
183
+ "Hello again #{format}, mem: #{mem}"
184
+ end
185
+ end
186
+ end
187
+ ```
188
+
189
+ ## Developement Stage to build gem
190
+
191
+ * checkout the master
192
+ * build gem with gemspec file
193
+ * install gem locally
194
+
195
+ ```bash
196
+ git clone http://{your name}@stash.mo.laxino.com/scm/~ben.wu/d13n.git
197
+ cd d13n
198
+ gem build d13n.gemspec
199
+ gem install -l d13n-{version}.gem
200
+ ```
data/bin/d13n ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH << File.expand_path(File.join File.dirname(__FILE__), '..', 'lib')
4
+ require 'd13n/cli/command'
5
+ begin
6
+ D13n::Cli::Command.run
7
+ rescue D13n::Cli::Command::CommandFailure => failure
8
+ STDERR.puts failure.message
9
+ STDERR.puts failure.options if failure.options
10
+ exit 1
11
+ end
data/d13n.gemspec ADDED
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'd13n/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "d13n"
8
+ spec.version = D13n::VERSION::STRING
9
+ spec.authors = ["Ben Wu"]
10
+ spec.email = ["ben.wu@laxino.com"]
11
+
12
+ spec.summary = %q{Write a short summary, because Rubygems requires one.}
13
+ spec.description = %q{Write a longer description or delete this line.}
14
+ spec.homepage = "http://github.com/cheokman"
15
+
16
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
17
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
18
+ if spec.respond_to?(:metadata)
19
+ spec.metadata['allowed_push_host'] = "https://rubygems.org"
20
+ else
21
+ raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
22
+ end
23
+
24
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
25
+ spec.bindir = "bin"
26
+ spec.executables = ['d13n']
27
+ spec.require_paths = ["lib"]
28
+
29
+ spec.add_development_dependency "rspec", "~> 3.0"
30
+
31
+ spec.add_dependency "bundler", "~> 1.14"
32
+ spec.add_runtime_dependency 'statsd-instrument', '~> 2.2', '>= 2.2.0'
33
+ spec.add_runtime_dependency 'config_kit', '0.0.16'
34
+ end
@@ -0,0 +1,56 @@
1
+ module D13n::Application
2
+ module ClassMethods
3
+ def self.extended(descendant)
4
+ D13n.application = descendant
5
+ end
6
+
7
+ def config
8
+ @config ||= D13n.config
9
+ end
10
+
11
+ def config=(cfg)
12
+ @config = cfg
13
+ end
14
+
15
+ def logger
16
+ @logger ||= D13n.logger
17
+ end
18
+
19
+ def logger=(log)
20
+ @logger = log
21
+ end
22
+
23
+ def default_source
24
+ D13n::Configuration::DefaultSource.defaults
25
+ end
26
+
27
+ def default_source=(default_config)
28
+ D13n::Configuration::DefaultSource.defaults = default_config
29
+ end
30
+
31
+ # def opt_state
32
+ # D13n::Api::OperationState.opt_get
33
+ # end
34
+
35
+ def service
36
+ D13n.service
37
+ end
38
+
39
+ def application
40
+ D13n.application
41
+ end
42
+
43
+ def app_name
44
+ D13n.app_name
45
+ end
46
+
47
+ def app_prefix
48
+ D13n.app_prefix
49
+ end
50
+
51
+ def reset
52
+ @config = nil
53
+ @logger = nil
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,3 @@
1
+ require 'd13n/application/class_methods'
2
+ module D13n::Application
3
+ end
@@ -0,0 +1,76 @@
1
+ require 'optparse'
2
+ require 'pp'
3
+
4
+ $LOAD_PATH << "#{File.dirname(__FILE__)}/.."
5
+
6
+ module D13n
7
+ module Cli
8
+ class Command
9
+ class CommandFailure < StandardError
10
+ attr_reader :options
11
+ def initialize message, opt_parser=nil
12
+ super message
13
+ @options = opt_parser
14
+ end
15
+ end
16
+
17
+ def initialize(args)
18
+ if Hash === args
19
+ args.each do |k, v|
20
+ instance_variable_set "@#{k}", v.to_s if v
21
+ end
22
+ else
23
+
24
+ @options = options do |opts|
25
+ opts.on("-h", "Show this help") { raise CommandFailure, opts.to_s }
26
+ end
27
+ raise CommandFailure, @options.to_s if args.empty?
28
+ @leftover = @options.parse(args)
29
+ end
30
+ rescue OptionParser::ParseError => e
31
+ raise CommandFailure.new(e.message, @options)
32
+ end
33
+
34
+ @commands = []
35
+ def self.inherited(subclass)
36
+ @commands << subclass
37
+ end
38
+
39
+ cmds = cmds = File.expand_path(File.join(File.dirname(__FILE__), 'commands', '*.rb'))
40
+ Dir[cmds].each { |command| require command }
41
+
42
+ def self.run
43
+ @command_names = @commands.map{ |c| c.command}
44
+
45
+ extra = []
46
+
47
+ options = ARGV.options do |opts|
48
+ script_name = File.basename($0)
49
+ opts.banner = "Usage: #{script_name} [ #{ @command_names.join(" | ")} ] [options]"
50
+ opts.separator "use '#{script_name} <command> -h' to see detailed command options"
51
+ opts
52
+ end
53
+ extra = options.order!
54
+ command = extra.shift
55
+
56
+ if command.nil?
57
+ STDOUT.puts "No command provided"
58
+ STDOUT.puts options.to_s
59
+ elsif !@command_names.include?(command)
60
+ STDOUT.puts "Unrecognized command: #{command}"
61
+ STDOUT.puts options
62
+ else
63
+ command_class = @commands.find{ |c| c.command == command}
64
+ command_class.new(extra).run
65
+ end
66
+ rescue OptionParser::InvalidOption => e
67
+ raise CommandFailure.new(e.message)
68
+ end
69
+
70
+ def run
71
+ raise NotImplementedError, 'Command class must be able to #run!'
72
+ end
73
+
74
+ end
75
+ end
76
+ end