shatter-rb 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.husky/commit-msg +5 -0
- data/.rubocop.yml +4 -0
- data/.ruby-version +1 -1
- data/.tool-versions +1 -1
- data/Gemfile +0 -2
- data/Gemfile.lock +53 -17
- data/Guardfile +72 -0
- data/README.md +76 -14
- data/commitlint.config.js +1 -0
- data/example_app/Gemfile +3 -2
- data/example_app/Gemfile.lock +9 -16
- data/example_app/app/application.rb +4 -0
- data/example_app/app/functions/hello_world_function.rb +8 -16
- data/example_app/app/service_definition.rb +2 -6
- data/example_app/application.rb +4 -2
- data/example_app/bin/service +2 -2
- data/example_app/config/environment.rb +13 -7
- data/example_app/config.ru +8 -0
- data/exe/console +1 -1
- data/exe/shatter +33 -23
- data/lib/shatter/config.rb +14 -4
- data/lib/shatter/service/base.rb +28 -35
- data/lib/shatter/service/discovery.rb +32 -19
- data/lib/shatter/service/function.rb +45 -31
- data/lib/shatter/service/response_pool.rb +12 -7
- data/lib/shatter/service/service_definition.rb +10 -4
- data/lib/shatter/util.rb +21 -5
- data/lib/shatter/version.rb +1 -1
- data/lib/shatter/web/application.rb +34 -32
- data/lib/shatter/web/server.rb +25 -18
- data/lib/shatter.rb +59 -11
- data/package.json +7 -0
- data/templates/Gemfile.template +1 -3
- data/templates/application.erb +2 -6
- data/templates/config.ru +8 -0
- data/templates/environment.rb.erb +9 -8
- data/templates/function_definition.ts.erb +5 -0
- data/templates/hello_world_function.rb.erb +6 -14
- data/templates/service_client.ts.erb +25 -0
- data/templates/service_definition.rb.erb +3 -7
- data/yarn.lock +1338 -0
- metadata +103 -41
- data/example_app/bin/console +0 -11
- data/lib/shatter/service/function_params.rb +0 -21
- data/shatter.gemspec +0 -54
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f44b926ef9ef04ce878e7fd7a178560dc4f60038360627c8ed9cffa2dfba6eb3
|
4
|
+
data.tar.gz: cc4471e4f4d4da99db000efc779402673fe4fd843393cef0d9e5d62826952007
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f3422d6cd07a1977b6d2d8f293932716f3dea5ce8ce39bee5d925efae211c9163e4a3f0e06f566b7f983f6719a9b80db949fd76da08d8a4191a2ba047d011a53
|
7
|
+
data.tar.gz: e76434e400acaa9e0796d068b7ee792bdcdd866e2ea2c85d13bf5f2851a571fad696dbdd892d205d52ee789607cd655335eec4e8cae7dc6ff9e7dd23f7d394e8
|
data/.husky/commit-msg
ADDED
data/.rubocop.yml
CHANGED
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.
|
1
|
+
3.1.0
|
data/.tool-versions
CHANGED
@@ -1 +1 @@
|
|
1
|
-
ruby 3.
|
1
|
+
ruby 3.1.0
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,45 +1,71 @@
|
|
1
|
-
GIT
|
2
|
-
remote: https://github.com/EricRoos/zookeeper.git
|
3
|
-
revision: e024228fc1c3c22cd3b0854ff15ad0d53a98c4ae
|
4
|
-
specs:
|
5
|
-
zookeeper (1.5.4)
|
6
|
-
|
7
1
|
PATH
|
8
2
|
remote: .
|
9
3
|
specs:
|
10
|
-
shatter-rb (0.0
|
4
|
+
shatter-rb (0.1.0)
|
11
5
|
concurrent-ruby (~> 1.1)
|
12
6
|
erb (~> 2.2.0)
|
13
|
-
pg (~> 1.4)
|
14
7
|
puma (~> 6.0)
|
15
8
|
rack (~> 3.0)
|
16
|
-
|
9
|
+
rack-cors (~> 1.1)
|
17
10
|
thor (~> 1.2.1)
|
11
|
+
zeitwerk
|
18
12
|
zk (~> 1.10)
|
13
|
+
zookeeper (~> 1.5.4)
|
19
14
|
|
20
15
|
GEM
|
21
16
|
remote: https://rubygems.org/
|
22
17
|
specs:
|
23
18
|
ast (2.4.2)
|
24
19
|
cgi (0.3.6)
|
20
|
+
coderay (1.1.3)
|
25
21
|
concurrent-ruby (1.1.10)
|
26
22
|
diff-lcs (1.5.0)
|
23
|
+
docile (1.4.0)
|
27
24
|
erb (2.2.3)
|
28
25
|
cgi
|
26
|
+
ffi (1.15.5)
|
27
|
+
formatador (1.1.0)
|
28
|
+
guard (2.18.0)
|
29
|
+
formatador (>= 0.2.4)
|
30
|
+
listen (>= 2.7, < 4.0)
|
31
|
+
lumberjack (>= 1.0.12, < 2.0)
|
32
|
+
nenv (~> 0.1)
|
33
|
+
notiffany (~> 0.0)
|
34
|
+
pry (>= 0.13.0)
|
35
|
+
shellany (~> 0.0)
|
36
|
+
thor (>= 0.18.1)
|
37
|
+
guard-compat (1.2.1)
|
38
|
+
guard-rspec (4.7.3)
|
39
|
+
guard (~> 2.1)
|
40
|
+
guard-compat (~> 1.1)
|
41
|
+
rspec (>= 2.99.0, < 4.0)
|
29
42
|
json (2.6.3)
|
43
|
+
listen (3.7.1)
|
44
|
+
rb-fsevent (~> 0.10, >= 0.10.3)
|
45
|
+
rb-inotify (~> 0.9, >= 0.9.10)
|
46
|
+
lumberjack (1.2.8)
|
47
|
+
method_source (1.0.0)
|
48
|
+
nenv (0.3.0)
|
30
49
|
nio4r (2.5.8)
|
50
|
+
notiffany (0.1.3)
|
51
|
+
nenv (~> 0.1)
|
52
|
+
shellany (~> 0.0)
|
31
53
|
parallel (1.22.1)
|
32
54
|
parser (3.1.3.0)
|
33
55
|
ast (~> 2.4.1)
|
34
|
-
|
56
|
+
pry (0.14.1)
|
57
|
+
coderay (~> 1.1)
|
58
|
+
method_source (~> 1.0)
|
35
59
|
puma (6.0.2)
|
36
60
|
nio4r (~> 2.0)
|
37
61
|
rack (3.0.3)
|
38
|
-
|
39
|
-
rack (>=
|
40
|
-
webrick
|
62
|
+
rack-cors (1.1.1)
|
63
|
+
rack (>= 2.0.0)
|
41
64
|
rainbow (3.1.1)
|
42
65
|
rake (13.0.6)
|
66
|
+
rb-fsevent (0.11.2)
|
67
|
+
rb-inotify (0.10.1)
|
68
|
+
ffi (~> 1.0)
|
43
69
|
regexp_parser (2.6.1)
|
44
70
|
rexml (3.2.5)
|
45
71
|
rspec (3.12.0)
|
@@ -72,23 +98,33 @@ GEM
|
|
72
98
|
rubocop-rspec (2.16.0)
|
73
99
|
rubocop (~> 1.33)
|
74
100
|
ruby-progressbar (1.11.0)
|
101
|
+
shellany (0.0.1)
|
102
|
+
simplecov (0.22.0)
|
103
|
+
docile (~> 1.1)
|
104
|
+
simplecov-html (~> 0.11)
|
105
|
+
simplecov_json_formatter (~> 0.1)
|
106
|
+
simplecov-html (0.12.3)
|
107
|
+
simplecov_json_formatter (0.1.4)
|
75
108
|
thor (1.2.1)
|
76
109
|
unicode-display_width (2.3.0)
|
77
|
-
|
110
|
+
zeitwerk (2.6.6)
|
78
111
|
zk (1.10.0)
|
79
112
|
zookeeper (~> 1.5.0)
|
113
|
+
zookeeper (1.5.5)
|
80
114
|
|
81
115
|
PLATFORMS
|
82
116
|
x86_64-linux
|
83
117
|
|
84
118
|
DEPENDENCIES
|
119
|
+
guard
|
120
|
+
guard-rspec
|
85
121
|
rake (~> 13.0)
|
86
122
|
rspec (~> 3.0)
|
87
123
|
rubocop (~> 1.21)
|
88
|
-
rubocop-rake
|
89
|
-
rubocop-rspec
|
124
|
+
rubocop-rake (~> 0.6.0)
|
125
|
+
rubocop-rspec (~> 2.16.0)
|
90
126
|
shatter-rb!
|
91
|
-
|
127
|
+
simplecov
|
92
128
|
|
93
129
|
BUNDLED WITH
|
94
130
|
2.4.1
|
data/Guardfile
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# A sample Guardfile
|
4
|
+
# More info at https://github.com/guard/guard#readme
|
5
|
+
|
6
|
+
## Uncomment and set this to only include directories you want to watch
|
7
|
+
# directories %w(app lib config test spec features) \
|
8
|
+
# .select{|d| Dir.exist?(d) ? d : UI.warning("Directory #{d} does not exist")}
|
9
|
+
|
10
|
+
## Note: if you are using the `directories` clause above and you are not
|
11
|
+
## watching the project directory ('.'), then you will want to move
|
12
|
+
## the Guardfile to a watched dir and symlink it back, e.g.
|
13
|
+
#
|
14
|
+
# $ mkdir config
|
15
|
+
# $ mv Guardfile config/
|
16
|
+
# $ ln -s config/Guardfile .
|
17
|
+
#
|
18
|
+
# and, you'll have to watch "config/Guardfile" instead of "Guardfile"
|
19
|
+
|
20
|
+
# NOTE: The cmd option is now required due to the increasing number of ways
|
21
|
+
# rspec may be run, below are examples of the most common uses.
|
22
|
+
# * bundler: 'bundle exec rspec'
|
23
|
+
# * bundler binstubs: 'bin/rspec'
|
24
|
+
# * spring: 'bin/rspec' (This will use spring if running and you have
|
25
|
+
# installed the spring binstubs per the docs)
|
26
|
+
# * zeus: 'zeus rspec' (requires the server to be started separately)
|
27
|
+
# * 'just' rspec: 'rspec'
|
28
|
+
|
29
|
+
guard :rspec, cmd: "bundle exec rspec" do
|
30
|
+
require "guard/rspec/dsl"
|
31
|
+
dsl = Guard::RSpec::Dsl.new(self)
|
32
|
+
|
33
|
+
# Feel free to open issues for suggestions and improvements
|
34
|
+
|
35
|
+
# RSpec files
|
36
|
+
rspec = dsl.rspec
|
37
|
+
watch(rspec.spec_helper) { rspec.spec_dir }
|
38
|
+
watch(rspec.spec_support) { rspec.spec_dir }
|
39
|
+
watch(rspec.spec_files)
|
40
|
+
|
41
|
+
# Ruby files
|
42
|
+
ruby = dsl.ruby
|
43
|
+
dsl.watch_spec_files_for(ruby.lib_files)
|
44
|
+
|
45
|
+
# Rails files
|
46
|
+
rails = dsl.rails(view_extensions: %w[erb haml slim])
|
47
|
+
dsl.watch_spec_files_for(rails.app_files)
|
48
|
+
dsl.watch_spec_files_for(rails.views)
|
49
|
+
|
50
|
+
watch(rails.controllers) do |m|
|
51
|
+
[
|
52
|
+
rspec.spec.call("routing/#{m[1]}_routing"),
|
53
|
+
rspec.spec.call("controllers/#{m[1]}_controller"),
|
54
|
+
rspec.spec.call("acceptance/#{m[1]}")
|
55
|
+
]
|
56
|
+
end
|
57
|
+
|
58
|
+
# Rails config changes
|
59
|
+
watch(rails.spec_helper) { rspec.spec_dir }
|
60
|
+
watch(rails.routes) { "#{rspec.spec_dir}/routing" }
|
61
|
+
watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" }
|
62
|
+
|
63
|
+
# Capybara features specs
|
64
|
+
watch(rails.view_dirs) { |m| rspec.spec.call("features/#{m[1]}") }
|
65
|
+
watch(rails.layouts) { |m| rspec.spec.call("features/#{m[1]}") }
|
66
|
+
|
67
|
+
# Turnip features and steps
|
68
|
+
watch(%r{^spec/acceptance/(.+)\.feature$})
|
69
|
+
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
|
70
|
+
Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance"
|
71
|
+
end
|
72
|
+
end
|
data/README.md
CHANGED
@@ -1,30 +1,88 @@
|
|
1
|
-
# Shatter
|
2
1
|
|
3
|
-
|
2
|
+
![shatter-banner](https://user-images.githubusercontent.com/1334489/211411749-49d3377f-e413-4838-bae7-60705688b514.png#gh-light-mode-only)
|
3
|
+
![shatter-banner-darkmode](https://user-images.githubusercontent.com/1334489/211412250-0660c441-31f1-4d74-87f8-5118ccebffa0.png#gh-dark-mode-only)
|
4
4
|
|
5
|
-
|
5
|
+
<p align='center'>
|
6
|
+
An async first RPC app server built in Ruby. Supported by DRb, Puma, and Zookeeper.
|
7
|
+
</p>
|
6
8
|
|
7
|
-
## Installation
|
8
9
|
|
9
|
-
|
10
|
+
## Why
|
10
11
|
|
11
|
-
|
12
|
+
Small apps are very common and RPC is a great simple alternative to REST, GraphQL, SOAP, and others. Shatter allows you to very simply, without too much opinion, define your business functions and invoke them with a premade HTTP endpoint.
|
12
13
|
|
13
|
-
|
14
|
+
## Whats needed
|
14
15
|
|
15
|
-
|
16
|
+
* Ruby3.1 and later
|
17
|
+
* A box to run it on
|
18
|
+
* Zookeeper instance
|
19
|
+
* Optional: Extra server to run the service layer across different boxes.
|
16
20
|
|
17
|
-
$ gem install UPDATE_WITH_YOUR_GEM_NAME_PRIOR_TO_RELEASE_TO_RUBYGEMS_ORG
|
18
21
|
|
19
|
-
##
|
22
|
+
## Developing
|
20
23
|
|
21
|
-
|
24
|
+
### Installation
|
25
|
+
Start with creating your project directory.
|
26
|
+
```
|
27
|
+
mkdir MyApp
|
28
|
+
```
|
22
29
|
|
23
|
-
|
30
|
+
Create a new Gemfile and `bundle install`.
|
31
|
+
```ruby
|
32
|
+
source "https://rubygems.org"
|
24
33
|
|
25
|
-
|
34
|
+
gem 'shatter-rb'
|
35
|
+
```
|
26
36
|
|
27
|
-
|
37
|
+
Create the project with:
|
38
|
+
```
|
39
|
+
bundle exec shatter new <AppName>
|
40
|
+
```
|
41
|
+
For now, app name should be in provided in UpperCamelCase.
|
42
|
+
|
43
|
+
|
44
|
+
Init zookeeper with the required keys needed
|
45
|
+
```ruby
|
46
|
+
bundle exec shatter init_service_discovery
|
47
|
+
```
|
48
|
+
|
49
|
+
|
50
|
+
Finally, you start shatter by running both the web server and service applications.
|
51
|
+
|
52
|
+
```bash
|
53
|
+
bin/service
|
54
|
+
bin/server
|
55
|
+
```
|
56
|
+
|
57
|
+
Congrats! Shatter is up and running!
|
58
|
+
|
59
|
+
### Testing things out
|
60
|
+
|
61
|
+
Included in the setup is one example `HelloWorldFunction` to show you how things work. You can invoke it with curl like:
|
62
|
+
|
63
|
+
```
|
64
|
+
curl -i -X POST -d '{}' localhost:9292/hello_world
|
65
|
+
```
|
66
|
+
|
67
|
+
Check the `location` header in the response and follow that url till your response is ready. The Javascript client does all this for you, however.
|
68
|
+
|
69
|
+
|
70
|
+
You can check out a demo js script here:
|
71
|
+
https://github.com/EricRoos/shatter/blob/main/javascript/dist/demo.js
|
72
|
+
|
73
|
+
|
74
|
+
|
75
|
+
### Front end things
|
76
|
+
|
77
|
+
We suggest you use Vite to setup your front end. Shatter comes with the ability to export your functions to a typescript definition that will give you a configured out of the box client ready for use. No need for wiring yourself except for importing whats generated.
|
78
|
+
|
79
|
+
You can generate your typescript with:
|
80
|
+
|
81
|
+
```
|
82
|
+
bundle exec shatter generate_typescript --path web/src/
|
83
|
+
```
|
84
|
+
|
85
|
+
Assuming you have setup your javascript based front end at ./web
|
28
86
|
|
29
87
|
## Contributing
|
30
88
|
|
@@ -37,3 +95,7 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
37
95
|
## Code of Conduct
|
38
96
|
|
39
97
|
Everyone interacting in the Shatter project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/shatter/blob/master/CODE_OF_CONDUCT.md).
|
98
|
+
|
99
|
+
## Attribution
|
100
|
+
|
101
|
+
Shatter logo provided by: <a href='https://pngtree.com/so/Beautiful'>Beautiful png from pngtree.com/</a>
|
@@ -0,0 +1 @@
|
|
1
|
+
module.exports = {extends: ['@commitlint/config-conventional']}
|
data/example_app/Gemfile
CHANGED
data/example_app/Gemfile.lock
CHANGED
@@ -1,21 +1,16 @@
|
|
1
|
-
GIT
|
2
|
-
remote: https://github.com/EricRoos/zookeeper.git
|
3
|
-
revision: e024228fc1c3c22cd3b0854ff15ad0d53a98c4ae
|
4
|
-
specs:
|
5
|
-
zookeeper (1.5.4)
|
6
|
-
|
7
1
|
PATH
|
8
2
|
remote: ..
|
9
3
|
specs:
|
10
|
-
shatter (0.
|
4
|
+
shatter-rb (0.0.2)
|
11
5
|
concurrent-ruby (~> 1.1)
|
12
6
|
erb (~> 2.2.0)
|
13
|
-
pg (~> 1.4)
|
14
7
|
puma (~> 6.0)
|
15
8
|
rack (~> 3.0)
|
16
|
-
|
9
|
+
rack-cors (~> 1.1)
|
17
10
|
thor (~> 1.2.1)
|
11
|
+
zeitwerk
|
18
12
|
zk (~> 1.10)
|
13
|
+
zookeeper (~> 1.5.4)
|
19
14
|
|
20
15
|
GEM
|
21
16
|
remote: https://rubygems.org/
|
@@ -26,25 +21,23 @@ GEM
|
|
26
21
|
cgi
|
27
22
|
foreman (0.87.2)
|
28
23
|
nio4r (2.5.8)
|
29
|
-
pg (1.4.5)
|
30
24
|
puma (6.0.2)
|
31
25
|
nio4r (~> 2.0)
|
32
26
|
rack (3.0.3)
|
33
|
-
|
34
|
-
rack (>=
|
35
|
-
webrick
|
27
|
+
rack-cors (1.1.1)
|
28
|
+
rack (>= 2.0.0)
|
36
29
|
thor (1.2.1)
|
37
|
-
|
30
|
+
zeitwerk (2.6.6)
|
38
31
|
zk (1.10.0)
|
39
32
|
zookeeper (~> 1.5.0)
|
33
|
+
zookeeper (1.5.5)
|
40
34
|
|
41
35
|
PLATFORMS
|
42
36
|
x86_64-linux
|
43
37
|
|
44
38
|
DEPENDENCIES
|
45
39
|
foreman (~> 0.87.2)
|
46
|
-
shatter!
|
47
|
-
zookeeper (~> 1.5.4)!
|
40
|
+
shatter-rb!
|
48
41
|
|
49
42
|
BUNDLED WITH
|
50
43
|
2.4.1
|
@@ -1,19 +1,11 @@
|
|
1
|
-
|
2
|
-
require "shatter/service/function"
|
3
|
-
require "shatter/service/function_params"
|
1
|
+
# frozen_string_literal: true
|
4
2
|
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
class HelloWorldFunction < Shatter::Service::Function
|
4
|
+
define_param :name, nullable: false, type: "string"
|
5
|
+
define_param :number, nullable: false, type: "integer"
|
8
6
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
def invoke
|
14
|
-
params.to_h => name:, number:
|
15
|
-
{ result: "Hello #{name}, your number is #{number || 'unknown'}.", error: nil, }
|
16
|
-
end
|
17
|
-
end
|
7
|
+
def invoke
|
8
|
+
params.to_h => name:, uuid:
|
9
|
+
{ result: "Hello #{name}", error: nil, uuid: }
|
18
10
|
end
|
19
|
-
end
|
11
|
+
end
|
@@ -1,9 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
module MyApp
|
6
|
-
class ServiceDefinition < Shatter::Service::ServiceDefinition
|
7
|
-
register_function :hello_world, MyApp::Functions::HelloWorldFunction
|
8
|
-
end
|
3
|
+
class ServiceDefinition < Shatter::Service::ServiceDefinition
|
4
|
+
register_function :hello_world, HelloWorldFunction
|
9
5
|
end
|
data/example_app/application.rb
CHANGED
data/example_app/bin/service
CHANGED
@@ -1,9 +1,15 @@
|
|
1
|
-
|
2
|
-
Shatter::Config.initial_delay = 100
|
3
|
-
Shatter::Config.missing_result_delay = 100
|
4
|
-
Shatter::Config.service_port = ENV.fetch('SHATTER_SERVICE_PORT') { 8787 }
|
1
|
+
# frozen_string_literal: true
|
5
2
|
|
6
|
-
|
3
|
+
Shatter.config do |config|
|
4
|
+
config.root = File.expand_path("..", __dir__)
|
5
|
+
config.zookeeper_host = "localhost:2181"
|
6
|
+
config.initial_delay = 100
|
7
|
+
config.missing_result_delay = 100
|
8
|
+
config.service_port = ENV.fetch("SHATTER_SERVICE_PORT", 8787)
|
9
|
+
config.autoload_paths = %w[app app/functions]
|
10
|
+
end
|
7
11
|
|
8
|
-
Shatter
|
9
|
-
|
12
|
+
Shatter.load
|
13
|
+
|
14
|
+
Shatter::Service::Base.service_definition = ServiceDefinition
|
15
|
+
Shatter::Web::Server.application = Application
|
data/example_app/config.ru
CHANGED
@@ -2,8 +2,16 @@
|
|
2
2
|
|
3
3
|
require "bundler/setup"
|
4
4
|
require "shatter"
|
5
|
+
require "rack/cors"
|
5
6
|
|
6
7
|
require_relative "./config/environment"
|
7
8
|
|
8
9
|
use Rack::CommonLogger
|
10
|
+
|
11
|
+
use Rack::Cors do
|
12
|
+
allow do
|
13
|
+
origins "*"
|
14
|
+
resource "*", headers: :any, methods: %i[get post patch put], expose: %w[delay location]
|
15
|
+
end
|
16
|
+
end
|
9
17
|
run Shatter::Web::Server
|
data/exe/console
CHANGED
data/exe/shatter
CHANGED
@@ -1,7 +1,11 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
|
4
|
-
require
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "shatter"
|
5
|
+
require "thor"
|
6
|
+
require "erb"
|
7
|
+
require "fileutils"
|
8
|
+
require 'zk'
|
5
9
|
$stdout.sync = true
|
6
10
|
|
7
11
|
def safe_makedir(path)
|
@@ -11,54 +15,60 @@ end
|
|
11
15
|
class ShatterCLI < Thor
|
12
16
|
desc "init_service_discovery", "Sets up required keys for service discovery to work properly"
|
13
17
|
|
18
|
+
desc "init_service_discovery", "creates necessary keys in zookeeper"
|
14
19
|
def init_service_discovery
|
20
|
+
Shatter.load_environment
|
15
21
|
zk = ZK.new(Shatter::Config.zookeeper_host)
|
16
|
-
|
17
|
-
|
22
|
+
[
|
23
|
+
Shatter::Util.instances_key,
|
24
|
+
Shatter::Util.zookeeper_response_key_root,
|
25
|
+
].each do |key|
|
26
|
+
next if zk.exists?(key)
|
27
|
+
zk.create(key)
|
28
|
+
end
|
18
29
|
zk.close
|
19
30
|
end
|
20
31
|
|
32
|
+
desc "generate_typescript", "generates typescript defs of your service definition"
|
33
|
+
option :path
|
34
|
+
def generate_typescript
|
35
|
+
Shatter.load_environment
|
36
|
+
File.open("#{Shatter.root}/#{options[:path]}/Client.ts", "w") { |f| f.write(ServiceDefinition.to_typescript) }
|
37
|
+
end
|
38
|
+
|
21
39
|
desc "new APP_NAME", "scaffold a new shatter app"
|
22
40
|
def new(app_name)
|
23
41
|
puts "Generating new Shatter APP - #{app_name}"
|
24
42
|
|
25
43
|
puts "Updating Gemfile"
|
26
|
-
FileUtils.cp("#{__dir__}/../templates/Gemfile.template","./Gemfile")
|
44
|
+
::FileUtils.cp("#{__dir__}/../templates/Gemfile.template", "./Gemfile")
|
27
45
|
system("bundle install")
|
28
46
|
|
29
47
|
puts "Generating scripts"
|
30
|
-
FileUtils.mkdir("./bin", noop: Dir.exist?(
|
48
|
+
FileUtils.mkdir("./bin", noop: Dir.exist?("./bin"))
|
31
49
|
FileUtils.cp("#{__dir__}/../bin/service", "./bin/service", verbose: true)
|
32
50
|
FileUtils.cp("#{__dir__}/../bin/server", "./bin/server", verbose: true)
|
33
51
|
|
34
52
|
puts "Generating boilerplate"
|
35
53
|
|
36
54
|
application_code = ERB.new(File.read("#{__dir__}/../templates/application.erb")).result(binding)
|
37
|
-
|
38
|
-
|
39
|
-
end
|
55
|
+
safe_makedir("./app")
|
56
|
+
File.write("./app/application.rb", application_code)
|
40
57
|
|
41
58
|
FileUtils.cp("#{__dir__}/../templates/config.ru", "./config.ru", verbose: true)
|
42
59
|
FileUtils.cp("#{__dir__}/../templates/docker-compose.yml.example", "./docker-compose.yml", verbose: true)
|
43
60
|
|
44
|
-
safe_makedir('./app')
|
45
61
|
|
46
62
|
service_definition = ERB.new(File.read("#{__dir__}/../templates/service_definition.rb.erb")).result(binding)
|
47
|
-
File.
|
48
|
-
f.write service_definition
|
49
|
-
end
|
63
|
+
File.write("./app/service_definition.rb", service_definition)
|
50
64
|
|
51
|
-
safe_makedir(
|
65
|
+
safe_makedir("./app/functions")
|
52
66
|
sample_function = ERB.new(File.read("#{__dir__}/../templates/hello_world_function.rb.erb")).result(binding)
|
53
|
-
File.
|
54
|
-
|
55
|
-
end
|
56
|
-
safe_makedir('./config')
|
67
|
+
File.write("./app/functions/hello_world_function.rb", sample_function)
|
68
|
+
safe_makedir("./config")
|
57
69
|
|
58
70
|
environment_config = ERB.new(File.read("#{__dir__}/../templates/environment.rb.erb")).result(binding)
|
59
|
-
File.
|
60
|
-
f.write environment_config
|
61
|
-
end
|
71
|
+
File.write("./config/environment.rb", environment_config)
|
62
72
|
end
|
63
73
|
end
|
64
|
-
ShatterCLI.start(ARGV)
|
74
|
+
ShatterCLI.start(ARGV)
|
data/lib/shatter/config.rb
CHANGED
@@ -3,10 +3,20 @@
|
|
3
3
|
module Shatter
|
4
4
|
class Config
|
5
5
|
class << self
|
6
|
-
attr_accessor :zookeeper_host
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
attr_accessor :zookeeper_host, :service_port, :root, :reload_classes
|
7
|
+
attr_writer :autoload_paths, :initial_delay, :missing_result_delay
|
8
|
+
|
9
|
+
def autoload_paths
|
10
|
+
@autoload_paths ||= []
|
11
|
+
end
|
12
|
+
|
13
|
+
def initial_delay
|
14
|
+
@initial_delay || 100
|
15
|
+
end
|
16
|
+
|
17
|
+
def missing_result_delay
|
18
|
+
@missing_result_delay || 100
|
19
|
+
end
|
10
20
|
end
|
11
21
|
end
|
12
22
|
end
|