gutsy 0.1.0
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 +7 -0
- data/.gitignore +4 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +62 -0
- data/LICENSE.txt +21 -0
- data/README.md +56 -0
- data/Rakefile +2 -0
- data/bin/console +14 -0
- data/bin/gutsy +6 -0
- data/bin/setup +8 -0
- data/gutsy.gemspec +28 -0
- data/lib/gutsy/cli.rb +7 -0
- data/lib/gutsy/generator.rb +202 -0
- data/lib/gutsy/version.rb +3 -0
- data/lib/gutsy.rb +72 -0
- data/templates/app_client/.gitignore.erb +0 -0
- data/templates/app_client/Gemfile.erb +4 -0
- data/templates/app_client/LICENSE.txt.erb +21 -0
- data/templates/app_client/README.md.erb +91 -0
- data/templates/app_client/Rakefile.erb +2 -0
- data/templates/app_client/app_client.gemspec.erb +23 -0
- data/templates/app_client/lib/app_client/v1/adapter.rb.erb +66 -0
- data/templates/app_client/lib/app_client/v1/adapters/.gitkeep +0 -0
- data/templates/app_client/lib/app_client/v1/resource.rb.erb +11 -0
- data/templates/app_client/lib/app_client/version.rb.erb +3 -0
- data/templates/app_client/lib/app_client.rb.erb +58 -0
- metadata +157 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: da3a90cbf88bebcc6de078248e83b515338e5be3
|
4
|
+
data.tar.gz: d9fdb9b74896ff504fe4e45f529fda7ee97f3a8c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3386699eea4d6be07d403c3fedee8efdc5024bf369e3a926af9d7a111aa02bb5ba87e72d686580258656067e8081513aa7167508d1aa8680eaa74536a7bb00fd
|
7
|
+
data.tar.gz: 036a6f184c812021f132f8519fb03b362c7ede9a747022e5e808e5938efca651d4cc3c2d394b2a1c874c535336342cfe0adb68c9090ed3ac7727f71456935184
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# Contributor Code of Conduct
|
2
|
+
|
3
|
+
As contributors and maintainers of this project, and in the interest of
|
4
|
+
fostering an open and welcoming community, we pledge to respect all people who
|
5
|
+
contribute through reporting issues, posting feature requests, updating
|
6
|
+
documentation, submitting pull requests or patches, and other activities.
|
7
|
+
|
8
|
+
We are committed to making participation in this project a harassment-free
|
9
|
+
experience for everyone, regardless of level of experience, gender, gender
|
10
|
+
identity and expression, sexual orientation, disability, personal appearance,
|
11
|
+
body size, race, ethnicity, age, religion, or nationality.
|
12
|
+
|
13
|
+
Examples of unacceptable behavior by participants include:
|
14
|
+
|
15
|
+
* The use of sexualized language or imagery
|
16
|
+
* Personal attacks
|
17
|
+
* Trolling or insulting/derogatory comments
|
18
|
+
* Public or private harassment
|
19
|
+
* Publishing other's private information, such as physical or electronic
|
20
|
+
addresses, without explicit permission
|
21
|
+
* Other unethical or unprofessional conduct
|
22
|
+
|
23
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
24
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
25
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
26
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
27
|
+
threatening, offensive, or harmful.
|
28
|
+
|
29
|
+
By adopting this Code of Conduct, project maintainers commit themselves to
|
30
|
+
fairly and consistently applying these principles to every aspect of managing
|
31
|
+
this project. Project maintainers who do not follow or enforce the Code of
|
32
|
+
Conduct may be permanently removed from the project team.
|
33
|
+
|
34
|
+
This code of conduct applies both within project spaces and in public spaces
|
35
|
+
when an individual is representing the project or its community.
|
36
|
+
|
37
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
38
|
+
reported by contacting a project maintainer at max.fierke@iorahealth.com. All
|
39
|
+
complaints will be reviewed and investigated and will result in a response that
|
40
|
+
is deemed necessary and appropriate to the circumstances. Maintainers are
|
41
|
+
obligated to maintain confidentiality with regard to the reporter of an
|
42
|
+
incident.
|
43
|
+
|
44
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
45
|
+
version 1.3.0, available at
|
46
|
+
[http://contributor-covenant.org/version/1/3/0/][version]
|
47
|
+
|
48
|
+
[homepage]: http://contributor-covenant.org
|
49
|
+
[version]: http://contributor-covenant.org/version/1/3/0/
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
gutsy (0.1.0)
|
5
|
+
activesupport (>= 3.2)
|
6
|
+
heroics (~> 0.0.17)
|
7
|
+
json_schema (~> 0.13)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
activesupport (4.1.11)
|
13
|
+
i18n (~> 0.6, >= 0.6.9)
|
14
|
+
json (~> 1.7, >= 1.7.7)
|
15
|
+
minitest (~> 5.1)
|
16
|
+
thread_safe (~> 0.1)
|
17
|
+
tzinfo (~> 1.1)
|
18
|
+
diff-lcs (1.2.5)
|
19
|
+
erubis (2.7.0)
|
20
|
+
excon (0.51.0)
|
21
|
+
heroics (0.0.17)
|
22
|
+
erubis (~> 2.0)
|
23
|
+
excon
|
24
|
+
moneta
|
25
|
+
multi_json (>= 1.9.2)
|
26
|
+
netrc
|
27
|
+
i18n (0.7.0)
|
28
|
+
json (1.8.3)
|
29
|
+
json_schema (0.13.0)
|
30
|
+
minitest (5.8.3)
|
31
|
+
moneta (0.8.0)
|
32
|
+
multi_json (1.12.1)
|
33
|
+
netrc (0.11.0)
|
34
|
+
rake (10.5.0)
|
35
|
+
rspec (3.5.0)
|
36
|
+
rspec-core (~> 3.5.0)
|
37
|
+
rspec-expectations (~> 3.5.0)
|
38
|
+
rspec-mocks (~> 3.5.0)
|
39
|
+
rspec-core (3.5.2)
|
40
|
+
rspec-support (~> 3.5.0)
|
41
|
+
rspec-expectations (3.5.0)
|
42
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
43
|
+
rspec-support (~> 3.5.0)
|
44
|
+
rspec-mocks (3.5.0)
|
45
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
46
|
+
rspec-support (~> 3.5.0)
|
47
|
+
rspec-support (3.5.0)
|
48
|
+
thread_safe (0.3.5)
|
49
|
+
tzinfo (1.2.2)
|
50
|
+
thread_safe (~> 0.1)
|
51
|
+
|
52
|
+
PLATFORMS
|
53
|
+
ruby
|
54
|
+
|
55
|
+
DEPENDENCIES
|
56
|
+
bundler (~> 1.12)
|
57
|
+
gutsy!
|
58
|
+
rake (~> 10.0)
|
59
|
+
rspec (~> 3.0)
|
60
|
+
|
61
|
+
BUNDLED WITH
|
62
|
+
1.12.5
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 Iora Health
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
# Gutsy
|
2
|
+
|
3
|
+
<center>
|
4
|
+
<pre>
|
5
|
+
|
6
|
+
╓▄╖,
|
7
|
+
,▄▓▓▒░░ ╓▄▓▓█▓▄µ ╓▄▄▄▒▄╗╦, ╓▓▓▓▓▒░║▓
|
8
|
+
╟▓▓▓▓▄▄▄▌ ▓█▓▓▓▓▄╙▓╦ ╚▓▓▓▓▓█▒▒▒░~ ▐▓▓▓▓▓▓▓▓▓
|
9
|
+
╟▓▓▓▓██▓Å▒ ▐▓▓▓▓╣▓▓▌▐█▒▒▓█░╬░░░-⌐ `. ▓▓▓▓▓▓▓▓▓
|
10
|
+
▀Φ▓▓▓▓▓Θ ▓▓▓▓▓▓▓▓▓▒╬▓▓▓▌δ░░░░"░ W,▓▓▓Θ `█▓▒▓▓▓▀▀
|
11
|
+
└▓▀▓ ╣▓▓▓▓▓▓▓▓▓▓▓▓▀▓▄╬░ └Γ▀▓▓█▄ ▓Γ
|
12
|
+
▓ ▓▓▓▓▓▓▓▓▓▓▓▄▓▓▓▀▓▓▌▌ └▌╙▓▓▓▄ ▓▀
|
13
|
+
╙▓▄▓▓▓▓▓▓▓▓▓▀▓▓▓▓▓▌╬▒ ^▓▓▓▄▓█
|
14
|
+
▓▓ █ ╠▓▓▓▌▓▓▓▓▓▓▓▌Ü ▀▓▓▓
|
15
|
+
█▓▓▒▓▓▓▓▓▓▓╣Ö`^``` , Γ
|
16
|
+
█▓▓▓▓▓▓▓▓▌▓δ^^^^` ░░. ,,
|
17
|
+
╙▓▓▓▓▓▓▓▓▓▓▌▒▒▒▄░╣▄▄▒▒▒`
|
18
|
+
,▓▓▓▓▓▓▓██▓▓▓▓▓▓▓▓▓▓▓▓▌░╤
|
19
|
+
▄ ,▄ ▄▓▓▓▓▓▓▓▓╣╬δ▒▓▓▓▄▓▓▓▓▓▓▓▓╦
|
20
|
+
╚╣▓▓▓▓▄ ╒▓▓▓▓▓▓▓▓▓▓Ñ░-▓▓▓▓▓▒ ▀█▓▓▓▓▌▄
|
21
|
+
▀▀▓▓▓▓▌ ╙▓▓▓▓▓▀╒▓▓╡ ╫▓▒╫▓▓Θ ▀▓▓▓▓▓╛ ▄▄▄▄▄▓▓▓▓
|
22
|
+
▀▓▓▓▌ ╙▀╫▓▄▄╦▓▓▓▒╦╥▓▓╣▓▓▓▒ ,▄▓▓▓y ▄▓▓▄▓▓█▀ΓΓ▀ΓΓ.
|
23
|
+
▓▓▓▌ ▄▓▓▓▓▓▓▓▓▓▓▒▓▓╠╫▓▌░ ╔▓▓▓▓▌▄ ▓▓▓▓▓▓█
|
24
|
+
▓▌▌ █▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▀` ╓▓▓▓▓▓▌δ ╙▓▓▓▓▀
|
25
|
+
▓─ ▀▓▓▓▓▓▓▓▓▓▓▓▓▓▌ ,▓▓▓▓▓▓▒ ▐▓▓█
|
26
|
+
▓ ╙▓▓▓▓▓▓█╢▓▓▓▓▓▌ ▓▓▓▓▓▓▀` ▓▌
|
27
|
+
▌δ █▓▓▓▌░ ╙▓▓▀▀╘▓▓▓▓▓▓` ╒▓▌
|
28
|
+
▐▓ ▌╓p╦▄▄▄▄,▓▓▓▓▓▌╦░▓█ ▓▓▓▓Σ ▌▓µ
|
29
|
+
▓▌▄▓▓▓▄╠▓╣▌▄▓▓▓▓▓▓▓Θ╫▌ ^▓▓▓▌╕ ╬ ▓
|
30
|
+
▀▀▓▓▓▓▓▄▌δ▓▓▓▓█▓▓Θ⌐╟▌ ▓▓▓▌░ ╒Γ▐▓∩
|
31
|
+
.▀█▓▓▓▄▓▓▓█ ▓▓░ ▒⌐ ▓▓▓▌╗▄╗╗QQQQ▒▒▓▌▓▓▌
|
32
|
+
Γ▓▓▒` ▓▓░⌐▓ █▓▓▓▓▓▓▓▓███▀▀▀▀▀
|
33
|
+
▓▌ ▓▓▌╦█ ╙▀
|
34
|
+
╫Σ ƒ▓ΘΓ▓▄
|
35
|
+
╫▒ ▄█░░4
|
36
|
+
▐▌╫▓░▄╝
|
37
|
+
▐▓▓▓▓▀
|
38
|
+
▐▓▌▌
|
39
|
+
^▀Γ
|
40
|
+
</pre>
|
41
|
+
</center>
|
42
|
+
|
43
|
+
Gutsy generates RubyGem wrappers and documentation for [heroics](https://github.com/interagent/heroics)-generated API clients from JSON schema. It's the Ruby side of the coin to [`braise`](https://github.com/IoraHealth/braise).
|
44
|
+
|
45
|
+
## Usage
|
46
|
+
|
47
|
+
```bash
|
48
|
+
$ gem install gutsy
|
49
|
+
$ gutsy generate AppName /path/to/schema.json /path/for/output/
|
50
|
+
```
|
51
|
+
|
52
|
+
Check out your generated API gem! You'll probably want to edit the `gemspec`, `README.md`, and `LICENSE.txt` to better fit your needs.
|
53
|
+
|
54
|
+
## License
|
55
|
+
|
56
|
+
See [LICENSE.txt](LICENSE.txt)
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "gutsy"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/gutsy
ADDED
data/bin/setup
ADDED
data/gutsy.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'gutsy/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "gutsy"
|
8
|
+
spec.version = Gutsy::VERSION
|
9
|
+
spec.authors = ["Iora Health"]
|
10
|
+
spec.email = ["rubygems@iorahealth.com"]
|
11
|
+
|
12
|
+
spec.summary = "Generates heroics-powered API client gem wrappers from JSON Schema"
|
13
|
+
spec.description = spec.summary
|
14
|
+
spec.homepage = "https://github.com/IoraHealth/gutsy"
|
15
|
+
spec.license = "MIT"
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
+
spec.require_paths = ["lib"]
|
18
|
+
|
19
|
+
spec.executables << 'gutsy'
|
20
|
+
|
21
|
+
spec.add_runtime_dependency "heroics", "~> 0.0.17"
|
22
|
+
spec.add_runtime_dependency "json_schema", "~> 0.13"
|
23
|
+
spec.add_runtime_dependency "activesupport", ">= 3.2"
|
24
|
+
|
25
|
+
spec.add_development_dependency "bundler", "~> 1.12"
|
26
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
27
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
28
|
+
end
|
data/lib/gutsy/cli.rb
ADDED
@@ -0,0 +1,202 @@
|
|
1
|
+
module Gutsy
|
2
|
+
module Cli
|
3
|
+
class Generator
|
4
|
+
extend Forwardable
|
5
|
+
|
6
|
+
class State
|
7
|
+
attr_reader :app_name
|
8
|
+
attr_accessor :resources
|
9
|
+
|
10
|
+
def initialize(app_name, resources=[])
|
11
|
+
@app_name = app_name
|
12
|
+
@resources = resources
|
13
|
+
end
|
14
|
+
|
15
|
+
def gem_name
|
16
|
+
@gem_name_snake ||= "#{app_name.underscore}_client"
|
17
|
+
end
|
18
|
+
|
19
|
+
def gem_name_snake
|
20
|
+
gem_name
|
21
|
+
end
|
22
|
+
|
23
|
+
def gem_name_pascal
|
24
|
+
@gem_name_pascal ||= gem_name.camelize(:upper)
|
25
|
+
end
|
26
|
+
|
27
|
+
def copyright_year
|
28
|
+
@copyright_year ||= Time.now.year
|
29
|
+
end
|
30
|
+
|
31
|
+
def copyright_owner
|
32
|
+
@copyright_owner ||= "YOUR_NAME_HERE"
|
33
|
+
end
|
34
|
+
|
35
|
+
def twine
|
36
|
+
binding
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class ResourceState
|
41
|
+
attr_reader :resource_name, :gem_name_pascal
|
42
|
+
|
43
|
+
def initialize(resource_name, gem_name_pascal)
|
44
|
+
@resource_name = resource_name
|
45
|
+
@gem_name_pascal = gem_name_pascal
|
46
|
+
end
|
47
|
+
|
48
|
+
def twine
|
49
|
+
binding
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
attr_reader :app_name
|
54
|
+
|
55
|
+
def initialize(app_name, schema_path, output_path)
|
56
|
+
@state = State.new(app_name)
|
57
|
+
@schema_path = schema_path
|
58
|
+
@output_path = output_path
|
59
|
+
end
|
60
|
+
|
61
|
+
def generate!
|
62
|
+
create_output_dir
|
63
|
+
|
64
|
+
schema = load_and_validate_schema!
|
65
|
+
|
66
|
+
state.resources = map_schema_to_resources(schema)
|
67
|
+
|
68
|
+
scaffold_gem
|
69
|
+
|
70
|
+
generate_heroics_client
|
71
|
+
|
72
|
+
puts "Generated client gem can be found in... #{output_path}"
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
attr_reader :state, :schema_path, :output_path
|
78
|
+
attr_accessor :schema
|
79
|
+
def_delegators :state, :app_name, :gem_name_snake, :gem_name_pascal
|
80
|
+
|
81
|
+
def create_output_dir
|
82
|
+
print "Creating #{output_path}..."
|
83
|
+
Dir.mkdir(output_path, 0755) unless Dir.exist?(output_path)
|
84
|
+
puts "OK"
|
85
|
+
end
|
86
|
+
|
87
|
+
def load_and_validate_schema!
|
88
|
+
print "Validating schema against draft-04 JSON Schema..."
|
89
|
+
draft04_uri = URI.parse("http://json-schema.org/draft-04/hyper-schema")
|
90
|
+
draft04 = JsonSchema.parse!(JSON.parse(draft04_uri.read))
|
91
|
+
|
92
|
+
schema_json = JSON.parse(File.read(schema_path))
|
93
|
+
|
94
|
+
schema = JsonSchema.parse!(schema_json)
|
95
|
+
schema.expand_references!
|
96
|
+
|
97
|
+
draft04.validate!(schema)
|
98
|
+
puts "OK"
|
99
|
+
|
100
|
+
schema
|
101
|
+
end
|
102
|
+
|
103
|
+
def map_schema_to_resources(schema)
|
104
|
+
resources = Hash[schema.definitions.map do |key, resource|
|
105
|
+
links = Hash[resource.links.map do |link|
|
106
|
+
link.schema.expand_references! if link.schema
|
107
|
+
properties = link.schema.try(:properties) || {}
|
108
|
+
[link.title.downcase.to_sym, OpenStruct.new(properties: properties)]
|
109
|
+
end]
|
110
|
+
[key.to_sym, OpenStruct.new(title: key.camelize, links: links)]
|
111
|
+
end]
|
112
|
+
resources
|
113
|
+
end
|
114
|
+
|
115
|
+
def scaffold_gem
|
116
|
+
print "Creating gem directory structure..."
|
117
|
+
template_dirs.each do |dir|
|
118
|
+
dir = dir.gsub('app_client', gem_name_snake)
|
119
|
+
dir_path = File.join(output_path, dir)
|
120
|
+
Dir.mkdir(dir_path, 0755) unless Dir.exist?(dir_path)
|
121
|
+
end
|
122
|
+
puts "OK"
|
123
|
+
|
124
|
+
[
|
125
|
+
".gitignore",
|
126
|
+
"Gemfile",
|
127
|
+
"LICENSE.txt",
|
128
|
+
"Rakefile",
|
129
|
+
"README.md",
|
130
|
+
].each do |file|
|
131
|
+
copy_file file
|
132
|
+
end
|
133
|
+
|
134
|
+
copy_file "app_client.gemspec",
|
135
|
+
as: "#{gem_name_snake}.gemspec"
|
136
|
+
|
137
|
+
copy_file "lib/app_client.rb",
|
138
|
+
as: "lib/#{gem_name_snake}.rb"
|
139
|
+
|
140
|
+
[
|
141
|
+
"version.rb",
|
142
|
+
"v1/adapter.rb"
|
143
|
+
].each do |file|
|
144
|
+
copy_file "lib/app_client/#{file}",
|
145
|
+
as: "lib/#{gem_name_snake}/#{file}"
|
146
|
+
end
|
147
|
+
|
148
|
+
state.resources.each do |key, resource|
|
149
|
+
copy_file "lib/app_client/v1/resource.rb",
|
150
|
+
as: "lib/#{gem_name_snake}/v1/#{key.to_s.underscore}.rb",
|
151
|
+
binding: ResourceState.new(key.to_s, gem_name_pascal).twine
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def generate_heroics_client
|
156
|
+
print "Generating Heroics client for JSON Schema..."
|
157
|
+
unless system "heroics-generate \
|
158
|
+
#{gem_name_pascal}::V1::Adapters::Http \
|
159
|
+
#{schema_path} \
|
160
|
+
http://#{app_name.downcase}/api/v1 > \
|
161
|
+
#{output_path}/lib/#{gem_name_snake}/v1/adapters/http.rb"
|
162
|
+
puts "FAIL"
|
163
|
+
puts "Please see stacktrace or heroics errors"
|
164
|
+
end
|
165
|
+
puts "OK"
|
166
|
+
end
|
167
|
+
|
168
|
+
# Derived from Methadone::Cli (https://github.com/davetron5000/methadone/blob/935444f9deb81100a33ec3234effbeb65acbc080/lib/methadone/cli.rb)
|
169
|
+
def copy_file(relative_path,options = {})
|
170
|
+
relative_path = File.join(relative_path.split(/\//))
|
171
|
+
|
172
|
+
template_path = File.join(template_dir, "#{relative_path}.erb")
|
173
|
+
template = ERB.new(File.read(template_path), nil, '-')
|
174
|
+
|
175
|
+
output_relative_path ||= options[:as] || relative_path
|
176
|
+
|
177
|
+
file_output_path = File.join(output_path, output_relative_path)
|
178
|
+
|
179
|
+
print "Copying #{file_output_path}..."
|
180
|
+
|
181
|
+
erb_binding = options[:binding] || state.twine
|
182
|
+
|
183
|
+
File.open(file_output_path, 'w') do |file|
|
184
|
+
file.puts template.result(erb_binding)
|
185
|
+
file.chmod(0755) if options[:executable]
|
186
|
+
end
|
187
|
+
|
188
|
+
print "OK\n"
|
189
|
+
end
|
190
|
+
|
191
|
+
def template_dir
|
192
|
+
@template_dir ||= File.join(File.dirname(__FILE__), '..', '..', 'templates', 'app_client')
|
193
|
+
end
|
194
|
+
|
195
|
+
def template_dirs
|
196
|
+
Dir["#{template_dir}/**/*"].
|
197
|
+
select { |x| File.directory? x }.
|
198
|
+
map { |dir| dir.gsub(/^#{template_dir}\//,'') }
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
data/lib/gutsy.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
require 'active_support/core_ext/object/try'
|
3
|
+
require 'active_support/core_ext/string/inflections'
|
4
|
+
require 'erb'
|
5
|
+
require 'json_schema'
|
6
|
+
require 'open-uri'
|
7
|
+
require 'gutsy/version'
|
8
|
+
require 'gutsy/cli'
|
9
|
+
|
10
|
+
module Gutsy
|
11
|
+
def self.initialize!
|
12
|
+
args = ARGV
|
13
|
+
|
14
|
+
command = args[0]
|
15
|
+
|
16
|
+
case command
|
17
|
+
when "generate"
|
18
|
+
unless args.length == 4
|
19
|
+
puts <<-TEXT
|
20
|
+
Error: Not enough arguments for command 'generate'
|
21
|
+
|
22
|
+
Usage: gutsy generate [app_name] [schema_path] [output_path]
|
23
|
+
|
24
|
+
DESCRIPTION
|
25
|
+
Generates a gem scaffold and resource API clients on top of a heroics-generated client.
|
26
|
+
|
27
|
+
ARGUMENTS
|
28
|
+
[app_name] - CamelCased name of your application
|
29
|
+
[schema_path] - Path to your JSON Schema file
|
30
|
+
[output_path] - Path to output generated API client gem.
|
31
|
+
(Will be created if it doesn't exist)
|
32
|
+
TEXT
|
33
|
+
exit 1
|
34
|
+
end
|
35
|
+
app_name = args[1]
|
36
|
+
schema_path = File.expand_path(args[2])
|
37
|
+
output_path = File.expand_path(args[3])
|
38
|
+
|
39
|
+
generator = Gutsy::Cli::Generator.new(app_name, schema_path, output_path)
|
40
|
+
|
41
|
+
begin
|
42
|
+
generator.generate!
|
43
|
+
rescue => e
|
44
|
+
puts "FAIL"
|
45
|
+
puts e.message
|
46
|
+
puts e.backtrace.join("\n")
|
47
|
+
exit 1
|
48
|
+
end
|
49
|
+
|
50
|
+
exit 0
|
51
|
+
when "version"
|
52
|
+
puts "Gutsy version #{Gutsy::VERSION}"
|
53
|
+
exit 0
|
54
|
+
else
|
55
|
+
puts <<-TEXT
|
56
|
+
Usage: gutsy [command] [options]
|
57
|
+
|
58
|
+
DESCRIPTION
|
59
|
+
Generates gem wrappers around heroics-generated API clients
|
60
|
+
built with JSON Schema. (Enough layers of generation for ya?)
|
61
|
+
|
62
|
+
COMMANDS
|
63
|
+
generate scaffolds out an API client
|
64
|
+
version returns the gutsy version
|
65
|
+
help displays this message
|
66
|
+
|
67
|
+
Shouts out Mr. Gutsy. Keep on plugging in the Wasteland.
|
68
|
+
TEXT
|
69
|
+
exit 0
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
File without changes
|
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) <%= copyright_year %> <%= copyright_owner %>
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# <%= app_name %> Ruby Client
|
2
|
+
|
3
|
+
<%= app_name %> is an application that does things. This gem provides a wrapper around an HTTP Client generated from <%= app_name %>'s JSON Schema using [heroics](https://github.com/interagent/heroics).
|
4
|
+
|
5
|
+
|
6
|
+
## Usage
|
7
|
+
|
8
|
+
Add this to your Gemfile
|
9
|
+
|
10
|
+
```
|
11
|
+
gem '<%= gem_name_snake %>' #, git: 'git@github.com:USER/REPO.git', tag: 'v0.1.0'
|
12
|
+
```
|
13
|
+
|
14
|
+
### Rails Setup
|
15
|
+
|
16
|
+
* Add to an initializer (e.g. `config/initializers/<%= gem_name_snake %>.rb`)
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
<%= gem_name_pascal %>.configure do |config|
|
20
|
+
config.base_url = "http://<%= app_name.downcase %>.dev"
|
21
|
+
config.api_key = "i-am-api-user"
|
22
|
+
config.api_secret = "very-secret-sssshhh"
|
23
|
+
# or OAuth access token
|
24
|
+
# config.access_token = "SHA-goodness"
|
25
|
+
end
|
26
|
+
```
|
27
|
+
|
28
|
+
### Example
|
29
|
+
|
30
|
+
```
|
31
|
+
class SomeResourceLister
|
32
|
+
attr_accessor :client
|
33
|
+
|
34
|
+
def initialize(access_token)
|
35
|
+
@client = <%= gem_name_pascal %>::V1::SomeResource.new(access_token: access_token)
|
36
|
+
end
|
37
|
+
|
38
|
+
def call
|
39
|
+
response = client.list({ "start_time" => Time.now.iso8601, "end_time" => (Time.now + 7.days).iso8601 })
|
40
|
+
|
41
|
+
if response.ok?
|
42
|
+
response.some_resources
|
43
|
+
else
|
44
|
+
response.errors
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
```
|
49
|
+
|
50
|
+
## API
|
51
|
+
|
52
|
+
All Client and Resource API methods return an Object mirroring the JSON response of the <%= app_name.capitalize %> API call, with the added method `ok?`, indicating whether the call was a success (`2xx`), or whether the call was invalid (`422`). Other failures will raise an `Excon::Errors::Error` such as an `Excon::Errors::HTTPStatusError`.
|
53
|
+
|
54
|
+
The methods supported by each Resource API are generated by heroics and are determined by the JSON schema. In most cases, the Resource APIs found in `lib/<%= gem_name_snake %>` just proxy method calls to the API adapter (by default the heroics-generated API adapter).
|
55
|
+
|
56
|
+
<% resources.each do |key, resource| %>
|
57
|
+
|
58
|
+
### <%= resource.title.camelize %>
|
59
|
+
|
60
|
+
#### `::new(client=nil, access_token: nil, api_key: nil, api_secret: nil, options: {})`
|
61
|
+
|
62
|
+
Called with no arguments, `client` defaults to a newly created heroics client instance using the authentication details specified in an initializer/with `<%= gem_name_pascal %>.configure`. Passing an optional argument will override the authentication specified in `<%= gem_name_pascal %>.configuration` for the instance.
|
63
|
+
|
64
|
+
#### Methods
|
65
|
+
|
66
|
+
<% resource.links.each do |key, link| -%>
|
67
|
+
<% if key == :list || key == :create -%>
|
68
|
+
##### `#<%= key %>(body)`
|
69
|
+
|
70
|
+
* `body` - Hash containing the following properties:
|
71
|
+
<% link.properties.each do |key, prop| -%>
|
72
|
+
* `<%= key %>` - <%= prop.description %>
|
73
|
+
<% end -%>
|
74
|
+
<% end -%>
|
75
|
+
<% if key == :info || key == :destroy -%>
|
76
|
+
##### `#<%= key %>(id)`
|
77
|
+
|
78
|
+
* `id` - <%= resource.title.titleize %> identifier
|
79
|
+
|
80
|
+
<% end -%>
|
81
|
+
<% if key == :update -%>
|
82
|
+
##### `#<%= key %>(id, body)`
|
83
|
+
|
84
|
+
* `id` - <%= resource.title.titleize %> identifier
|
85
|
+
* `body` - Hash containing the following properties:
|
86
|
+
<% link.properties.each do |key, prop| -%>
|
87
|
+
* `<%= key %>` - <%= prop.description %>
|
88
|
+
<% end -%>
|
89
|
+
<% end -%>
|
90
|
+
<% end -%>
|
91
|
+
<% end -%>
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$LOAD_PATH.push File.expand_path("lib/<%= gem_name_snake %>", __FILE__)
|
3
|
+
require "./lib/<%= gem_name_snake %>/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = '<%= gem_name_snake %>'
|
7
|
+
s.version = <%= gem_name_pascal %>::VERSION
|
8
|
+
s.authors = ["AUTHOR"]
|
9
|
+
s.email = "author@localhost"
|
10
|
+
s.summary = "Gutsy-generated gem for <%= app_name %> client"
|
11
|
+
s.description = "<%= app_name %> API client generated by gutsy from JSON Schema"
|
12
|
+
|
13
|
+
s.files = `git ls-files`.split "\n"
|
14
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split "\n"
|
15
|
+
s.require_paths = ['lib']
|
16
|
+
|
17
|
+
s.add_dependency 'multi_json'
|
18
|
+
s.add_dependency 'heroics', '~> 0.0.17'
|
19
|
+
s.add_dependency 'recursive-open-struct', '~> 1.0'
|
20
|
+
s.add_dependency 'excon', '>= 0.49.0', '< 1.0'
|
21
|
+
|
22
|
+
s.add_development_dependency 'rake'
|
23
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module <%= gem_name_pascal %>
|
2
|
+
module V1
|
3
|
+
# Empty namespace, needed for heroics-generated HTTP client
|
4
|
+
module Adapters; end
|
5
|
+
|
6
|
+
module Adapter
|
7
|
+
def initialize(client=nil, access_token: nil, api_key: nil, api_secret: nil, options: {})
|
8
|
+
@client = if client
|
9
|
+
client
|
10
|
+
else
|
11
|
+
config = <%= gem_name_pascal %>.configuration
|
12
|
+
access_token ||= config.access_token
|
13
|
+
api_key ||= config.api_key
|
14
|
+
api_secret ||= config.api_secret
|
15
|
+
options = config.options.merge!(options)
|
16
|
+
|
17
|
+
# Workaround issue with some TLS setups (haproxy)
|
18
|
+
# Prevents :443 being added to hostname for TLS
|
19
|
+
Excon.defaults[:omit_default_port] = true
|
20
|
+
|
21
|
+
if access_token
|
22
|
+
config.adapter_factory.connect_oauth(access_token, options)
|
23
|
+
elsif api_key && api_secret
|
24
|
+
config.adapter_factory.connect(api_secret, options.merge!({
|
25
|
+
user: config.api_key
|
26
|
+
}))
|
27
|
+
else
|
28
|
+
raise 'access_token or API key & secret are required to connect to <%= app_name.downcase %> API'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def method_missing(name, *args)
|
34
|
+
if resource_caller.respond_to?(name)
|
35
|
+
begin
|
36
|
+
response = resource_caller.send(name, *args)
|
37
|
+
response[:ok?] = true
|
38
|
+
rescue Excon::Errors::UnprocessableEntity => e
|
39
|
+
response = MultiJson.load(e.response.body)
|
40
|
+
response[:ok?] = false
|
41
|
+
end
|
42
|
+
|
43
|
+
RecursiveOpenStruct.new(response, recurse_over_arrays: true)
|
44
|
+
else
|
45
|
+
raise NoMethodError.new("'#{resource_name}' API adapter '#{to_s}' does not respond to ##{name}")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def resource_name
|
50
|
+
raise "Please define a name for this resource"
|
51
|
+
end
|
52
|
+
|
53
|
+
def adapter_class
|
54
|
+
client.class
|
55
|
+
end
|
56
|
+
|
57
|
+
protected
|
58
|
+
|
59
|
+
attr_accessor :client
|
60
|
+
|
61
|
+
def resource_caller
|
62
|
+
client.send(resource_name)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
File without changes
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'multi_json'
|
2
|
+
require 'recursive-open-struct'
|
3
|
+
require '<%= gem_name_snake %>/v1/adapter'
|
4
|
+
|
5
|
+
Dir.glob(File.join(File.dirname(__FILE__), "<%= gem_name_snake %>", '**', '*.rb')).each do |file|
|
6
|
+
require file
|
7
|
+
end
|
8
|
+
|
9
|
+
module <%= gem_name_pascal %>
|
10
|
+
class << self
|
11
|
+
attr_accessor :configuration
|
12
|
+
end
|
13
|
+
|
14
|
+
# Configure <%= gem_name_pascal %> someplace sensible,
|
15
|
+
# like config/initializers/<%= gem_name_snake %>.rb
|
16
|
+
#
|
17
|
+
# @example
|
18
|
+
# <%= gem_name_pascal %>.configure do |config|
|
19
|
+
# config.base_url = 'http://<%= app_name.downcase %>.dev'
|
20
|
+
# # Specify credentials for OAuth browser-flow
|
21
|
+
# config.access_token = 'randomness'
|
22
|
+
# # or server-side flow
|
23
|
+
# config.api_key = 'i-am-app'
|
24
|
+
# config.api_secret = 'am-secret-dont-tell'
|
25
|
+
# end
|
26
|
+
def self.configure
|
27
|
+
self.configuration ||= Configuration.new
|
28
|
+
yield(configuration) if block_given?
|
29
|
+
end
|
30
|
+
|
31
|
+
class Configuration
|
32
|
+
attr_accessor :access_token, :api_key, :api_secret,
|
33
|
+
:base_url, :options,
|
34
|
+
:adapter_factory, :api_version
|
35
|
+
|
36
|
+
def options
|
37
|
+
@options ||= {}
|
38
|
+
end
|
39
|
+
|
40
|
+
def api_version
|
41
|
+
@api_version ||= 'v1'
|
42
|
+
end
|
43
|
+
|
44
|
+
def api_version=(version)
|
45
|
+
options[:url] = "#{base_url}/api/#{version}"
|
46
|
+
@api_version = version
|
47
|
+
end
|
48
|
+
|
49
|
+
def adapter_factory
|
50
|
+
@adapter_factory ||= <%= gem_name_pascal %>.const_get("#{api_version.upcase}")::Adapters::Http
|
51
|
+
end
|
52
|
+
|
53
|
+
def base_url=(url)
|
54
|
+
options[:url] = "#{url}/api/#{api_version}"
|
55
|
+
@base_url = url
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
metadata
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gutsy
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Iora Health
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-08-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: heroics
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.0.17
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.0.17
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: json_schema
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.13'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.13'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: activesupport
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.2'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.2'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.12'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.12'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '10.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '10.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3.0'
|
97
|
+
description: Generates heroics-powered API client gem wrappers from JSON Schema
|
98
|
+
email:
|
99
|
+
- rubygems@iorahealth.com
|
100
|
+
executables:
|
101
|
+
- gutsy
|
102
|
+
extensions: []
|
103
|
+
extra_rdoc_files: []
|
104
|
+
files:
|
105
|
+
- ".gitignore"
|
106
|
+
- ".rspec"
|
107
|
+
- ".travis.yml"
|
108
|
+
- CODE_OF_CONDUCT.md
|
109
|
+
- Gemfile
|
110
|
+
- Gemfile.lock
|
111
|
+
- LICENSE.txt
|
112
|
+
- README.md
|
113
|
+
- Rakefile
|
114
|
+
- bin/console
|
115
|
+
- bin/gutsy
|
116
|
+
- bin/setup
|
117
|
+
- gutsy.gemspec
|
118
|
+
- lib/gutsy.rb
|
119
|
+
- lib/gutsy/cli.rb
|
120
|
+
- lib/gutsy/generator.rb
|
121
|
+
- lib/gutsy/version.rb
|
122
|
+
- templates/app_client/.gitignore.erb
|
123
|
+
- templates/app_client/Gemfile.erb
|
124
|
+
- templates/app_client/LICENSE.txt.erb
|
125
|
+
- templates/app_client/README.md.erb
|
126
|
+
- templates/app_client/Rakefile.erb
|
127
|
+
- templates/app_client/app_client.gemspec.erb
|
128
|
+
- templates/app_client/lib/app_client.rb.erb
|
129
|
+
- templates/app_client/lib/app_client/v1/adapter.rb.erb
|
130
|
+
- templates/app_client/lib/app_client/v1/adapters/.gitkeep
|
131
|
+
- templates/app_client/lib/app_client/v1/resource.rb.erb
|
132
|
+
- templates/app_client/lib/app_client/version.rb.erb
|
133
|
+
homepage: https://github.com/IoraHealth/gutsy
|
134
|
+
licenses:
|
135
|
+
- MIT
|
136
|
+
metadata: {}
|
137
|
+
post_install_message:
|
138
|
+
rdoc_options: []
|
139
|
+
require_paths:
|
140
|
+
- lib
|
141
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
147
|
+
requirements:
|
148
|
+
- - ">="
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: '0'
|
151
|
+
requirements: []
|
152
|
+
rubyforge_project:
|
153
|
+
rubygems_version: 2.5.1
|
154
|
+
signing_key:
|
155
|
+
specification_version: 4
|
156
|
+
summary: Generates heroics-powered API client gem wrappers from JSON Schema
|
157
|
+
test_files: []
|