kanpachi 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.travis.yml +13 -0
  4. data/CHANGELOG.md +5 -0
  5. data/Gemfile +6 -0
  6. data/Guardfile +14 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +131 -0
  9. data/Rakefile +10 -0
  10. data/bin/kanpachi +17 -0
  11. data/examples/twitter.rb +122 -0
  12. data/kanpachi.gemspec +45 -0
  13. data/lib/base_hash.rb +41 -0
  14. data/lib/kanpachi/api.rb +22 -0
  15. data/lib/kanpachi/api_list.rb +61 -0
  16. data/lib/kanpachi/cli/doc.rb +62 -0
  17. data/lib/kanpachi/cli.rb +32 -0
  18. data/lib/kanpachi/commands/new.rb +26 -0
  19. data/lib/kanpachi/documentation/config.rb +84 -0
  20. data/lib/kanpachi/documentation/source/fonts/glyphicons-halflings-regular.eot +0 -0
  21. data/lib/kanpachi/documentation/source/fonts/glyphicons-halflings-regular.svg +228 -0
  22. data/lib/kanpachi/documentation/source/fonts/glyphicons-halflings-regular.ttf +0 -0
  23. data/lib/kanpachi/documentation/source/fonts/glyphicons-halflings-regular.woff +0 -0
  24. data/lib/kanpachi/documentation/source/images/background.png +0 -0
  25. data/lib/kanpachi/documentation/source/images/middleman.png +0 -0
  26. data/lib/kanpachi/documentation/source/index.html.slim +25 -0
  27. data/lib/kanpachi/documentation/source/javascripts/all.js +1 -0
  28. data/lib/kanpachi/documentation/source/javascripts/bootstrap.js +1999 -0
  29. data/lib/kanpachi/documentation/source/javascripts/bootstrap.min.js +6 -0
  30. data/lib/kanpachi/documentation/source/javascripts/html5shiv.js +9 -0
  31. data/lib/kanpachi/documentation/source/javascripts/jquery-1.10.2.min.js +6 -0
  32. data/lib/kanpachi/documentation/source/javascripts/respond.min.js +7 -0
  33. data/lib/kanpachi/documentation/source/layouts/layout.slim +55 -0
  34. data/lib/kanpachi/documentation/source/resource.html.slim +61 -0
  35. data/lib/kanpachi/documentation/source/stylesheets/bootstrap-theme.css +384 -0
  36. data/lib/kanpachi/documentation/source/stylesheets/bootstrap-theme.min.css +1 -0
  37. data/lib/kanpachi/documentation/source/stylesheets/bootstrap.css +6805 -0
  38. data/lib/kanpachi/documentation/source/stylesheets/bootstrap.min.css +9 -0
  39. data/lib/kanpachi/documentation/source/stylesheets/jumbotron.css +5 -0
  40. data/lib/kanpachi/dsl/api.rb +90 -0
  41. data/lib/kanpachi/dsl/error.rb +37 -0
  42. data/lib/kanpachi/dsl/resource.rb +110 -0
  43. data/lib/kanpachi/dsl/response.rb +21 -0
  44. data/lib/kanpachi/dsl/section.rb +29 -0
  45. data/lib/kanpachi/dsl.rb +24 -0
  46. data/lib/kanpachi/error.rb +14 -0
  47. data/lib/kanpachi/error_list.rb +51 -0
  48. data/lib/kanpachi/markdown.rb +11 -0
  49. data/lib/kanpachi/resource/params.rb +9 -0
  50. data/lib/kanpachi/resource.rb +56 -0
  51. data/lib/kanpachi/resource_list.rb +71 -0
  52. data/lib/kanpachi/response.rb +68 -0
  53. data/lib/kanpachi/response_list.rb +51 -0
  54. data/lib/kanpachi/section.rb +15 -0
  55. data/lib/kanpachi/section_list.rb +46 -0
  56. data/lib/kanpachi/templates/.gitignore +19 -0
  57. data/lib/kanpachi/templates/Gemfile +4 -0
  58. data/lib/kanpachi/templates/api/api.rb +17 -0
  59. data/lib/kanpachi/templates/api/errors.rb +13 -0
  60. data/lib/kanpachi/templates/api/posts.rb +32 -0
  61. data/lib/kanpachi/templates/api/users.rb +38 -0
  62. data/lib/kanpachi/version.rb +3 -0
  63. data/lib/kanpachi.rb +7 -0
  64. data/spec/api_list_spec.rb +55 -0
  65. data/spec/api_spec.rb +56 -0
  66. data/spec/dsl/api_spec.rb +74 -0
  67. data/spec/dsl/error_spec.rb +38 -0
  68. data/spec/dsl/resource_spec.rb +77 -0
  69. data/spec/dsl/response_spec.rb +31 -0
  70. data/spec/dsl/section_spec.rb +49 -0
  71. data/spec/dsl_spec.rb +46 -0
  72. data/spec/error_list_spec.rb +43 -0
  73. data/spec/error_spec.rb +34 -0
  74. data/spec/full_api_spec.rb +130 -0
  75. data/spec/markdown_spec.rb +12 -0
  76. data/spec/resource/params_spec.rb +11 -0
  77. data/spec/resource_list_spec.rb +53 -0
  78. data/spec/resource_spec.rb +144 -0
  79. data/spec/response_spec.rb +57 -0
  80. data/spec/section_list_spec.rb +39 -0
  81. data/spec/section_spec.rb +20 -0
  82. data/spec/spec_helper.rb +4 -0
  83. metadata +384 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6e70d69f07c62ef21800d0be7c54619c19e3fdad
4
+ data.tar.gz: ff42d674ead45d9b803056b26f9abcacc412fc05
5
+ SHA512:
6
+ metadata.gz: 7de088c8bd7856c838b41d9c5918b3a153152779500f3bbb94c4d94ad667e7bf322ca5fe391e763696a80d46d7e18196a78ebbc3d7b609384308e18b04a29629
7
+ data.tar.gz: 01289cc3cdc94e99c2a2fc1c082420c78ba031ec0413634f5c25744120450bcbdac5f3b2d7146cd0351d65ba1209c0408c90783f43f02b29b8fb42df9755ec7d
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ .DS_Store
2
+ *.gem
3
+ *.rbc
4
+ .bundle
5
+ .config
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
data/.travis.yml ADDED
@@ -0,0 +1,13 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - jruby
6
+ - rbx-19mode
7
+ - ruby-head
8
+ - jruby-head
9
+
10
+ matrix:
11
+ allow_failures:
12
+ - rvm: ruby-head
13
+ - rvm: jruby-head
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ # Kanpachi Changelog
2
+
3
+ ## 0.0.1
4
+
5
+ * First version.
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in kanpachi.gemspec
4
+ gemspec
5
+
6
+ gem 'coercible', git: 'https://github.com/solnic/coercible.git'
data/Guardfile ADDED
@@ -0,0 +1,14 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard :minitest do
5
+ # with Minitest::Unit
6
+ watch(%r{^test/(.*)\/?test_(.*)\.rb})
7
+ watch(%r{^lib/kanpachi/(.*/)?([^/]+)\.rb}) { |m| "test/#{m[1]}test_#{m[2]}.rb" }
8
+ watch(%r{^test/test_helper\.rb}) { 'test' }
9
+
10
+ # with Minitest::Spec
11
+ watch(%r{^spec/(.*)_spec\.rb})
12
+ watch(%r{^lib/kanpachi/(.+)\.rb}) { |m| "spec/#{m[1]}_spec.rb" }
13
+ watch(%r{^spec/spec_helper\.rb}) { 'spec' }
14
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Jack Chu
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,131 @@
1
+ # Kanpachi
2
+
3
+ [![CI Build Status](https://secure.travis-ci.org/kamui/kanpachi.png?branch=master)](http://travis-ci.org/kamui/kanpachi)
4
+
5
+ Kanpachi is a ruby gem that provides a DSL to describe your web API, generate documentation, and will even eventually
6
+ help you implement it.
7
+
8
+ Resource input parameters are defiend with the [mutations](https://github.com/cypriss/mutations) gem. You can refer to
9
+ their [wiki](https://github.com/cypriss/mutations/wiki/Filtering-Input) to find out how to use their DSL.
10
+
11
+ Response representations are defined as [Roar](https://github.com/apotonick/roar) representers. You can check out the
12
+ [representable docs](https://github.com/apotonick/representable) to figure out how to customize your responses.
13
+
14
+ To check out an example API project, checkout [kanpachi-example](https://github.com/kamui/kanpachi-example).
15
+
16
+ ## Example
17
+
18
+ Below is an example of one of Twitter's API endpoints partially described in Kanpachi.
19
+
20
+ ```ruby
21
+ api 'Twitter' do
22
+ # API meta data
23
+ title 'REST API v1.1 Resources'
24
+ description 'This describes the resources that make up the official Twitter API v1.1'
25
+ host 'api.twitter.com'
26
+
27
+ # Define global error responses
28
+ error :malformed_params do
29
+ description 'Sending invalid JSON will result in a 400 Bad Request response.'
30
+
31
+ response do
32
+ status 400
33
+ header 'Content-Type', 'application/json'
34
+ representation do
35
+ property :message, type: String
36
+ end
37
+ end
38
+ end
39
+
40
+ section 'Timelines' do
41
+ description 'Timelines are collections of Tweets, ordered with the most recent first.'
42
+
43
+ resource :get, '/statuses/mentions_timeline' do
44
+ name 'Mentions timeline'
45
+ description <<-TEXT
46
+ Returns the 20 most recent mentions (tweets containing a users's @screen_name) for the authenticating user.
47
+
48
+ The timeline returned is the equivalent of the one seen when you view [your mentions](https://twitter.com/mentions) on twitter.com.
49
+
50
+ This method can only return up to 800 tweets.
51
+
52
+ See [__Working with Timelines__](https://dev.twitter.com/docs/working-with-timelines) for instructions on traversing timelines.
53
+ TEXT
54
+ versions '1.1', 1.0
55
+ ssl true
56
+ formats :json
57
+
58
+ # Params are a subclass of Mutations::Command
59
+ params do
60
+ required do
61
+ end
62
+
63
+ optional do
64
+ integer :count, doc: 'Specifies the number of tweets to try and retrieve, up to a maximum of 200. The value of count is best thought of as a limit to the number of tweets to return because suspended or deleted content is removed after the count has been applied. We include retweets in the count, even if `include_rts` is not supplied. It is recommended you always send `include_rts=1` when using this API method.'
65
+ integer :since_id, doc: 'Returns results with an ID greater than (that is, more recent than) the specified ID. There are limits to the number of Tweets which can be accessed through the API. If the limit of Tweets has occured since the since_id, the since_id will be forced to the oldest ID available.', example: 12345
66
+ integer :max_id, doc: 'Returns results with an ID less than (that is, older than) or equal to the specified ID.', example: 54321
67
+ boolean :trim_user, doc: 'When set to either true, t or 1, each tweet returned in a timeline will include a user object including only the status authors numerical ID. Omit this parameter to receive the complete user object.', example: true
68
+ boolean :contributor_details, doc: 'This parameter enhances the contributors element of the status response to include the screen_name of the contributor. By default only the user_id of the contributor is included.', example: true
69
+ boolean :include_entities, doc: 'The `entities` node will be disincluded when set to false.', example: false
70
+ end
71
+ end
72
+
73
+ # Multiple responses are supported
74
+ response :default do
75
+ status 200
76
+ header 'Content-Type', 'application/json'
77
+
78
+ # Response representations include Roar::Representer
79
+ representation do
80
+ include ::Representable::JSON::Collection
81
+ property :title, type: String, doc: "it's the title", example: 'The Title'
82
+ collection :coordinates, doc: "it's the coordinates", example: [100.4, 45.1]
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+ ```
89
+
90
+ ## Installation
91
+
92
+ Add this line to your application's Gemfile:
93
+
94
+ gem 'kanpachi'
95
+
96
+ And then execute:
97
+
98
+ $ bundle
99
+
100
+ Or install it yourself as:
101
+
102
+ $ gem install kanpachi
103
+
104
+ ## Usage
105
+
106
+ Create a new API
107
+
108
+ ```bash
109
+ $ kanpachi new my_api
110
+ $ cd my_api
111
+ ```
112
+
113
+ Build HTML documentation
114
+
115
+ ```bash
116
+ $ kanpachi build
117
+ ```
118
+
119
+ Start a documentation server
120
+
121
+ ```bash
122
+ $ kanpachi server
123
+ ```
124
+
125
+ ## Contributing
126
+
127
+ 1. Fork it
128
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
129
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
130
+ 4. Push to the branch (`git push origin my-new-feature`)
131
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs.push 'lib'
6
+ t.test_files = FileList['spec/**/*_spec.rb']
7
+ t.verbose = true
8
+ end
9
+
10
+ task default: :test
data/bin/kanpachi ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require_relative '../lib/kanpachi/cli'
4
+
5
+ # Hack to populate options['reload_paths'] with api path
6
+ if ARGV[0] == 'server'
7
+ reload_paths = false
8
+ ARGV.each_with_index do |arg, i|
9
+ if arg.start_with?('--reload_paths=')
10
+ ARGV[i] = "#{ARGV[i]},api/[^\.](.*)\.rb$"
11
+ reload_paths = true
12
+ end
13
+ end
14
+ ARGV << "--reload_paths=api/[^\.](.*)\.rb$" unless reload_paths
15
+ end
16
+
17
+ Kanpachi::CLI.start(ARGV)
@@ -0,0 +1,122 @@
1
+ require 'roar/representer/json'
2
+ require 'roar/representer/feature/hypermedia'
3
+
4
+ module UserRepresenter
5
+ include Roar::Representer::JSON
6
+ include Roar::Representer::Feature::Hypermedia
7
+ property :first_name, type: String, required: true, doc: "it's the first name"
8
+ property :last_name, type: String, required: true, doc: "it's the last name"
9
+ end
10
+
11
+ api 'Twitter' do
12
+ title 'REST API v1.1 Resources'
13
+ description 'This describes the resources that make up the official Twitter API v1.1'
14
+ host 'api.twitter.com'
15
+
16
+ error :malformed_params do
17
+ description 'Sending invalid JSON will result in a 400 Bad Request response.'
18
+
19
+ response do
20
+ status 400
21
+ header 'Content-Type', 'application/json'
22
+ representation do
23
+ property :message, type: String
24
+ end
25
+ end
26
+ end
27
+
28
+ section 'Timelines' do
29
+ description 'Timelines are collections of Tweets, ordered with the most recent first.'
30
+
31
+ resource :get, '/statuses/mentions_timeline' do
32
+ name 'Mentions timeline'
33
+ description <<-TEXT
34
+ Returns the 20 most recent mentions (tweets containing a users's @screen_name) for the authenticating user.
35
+
36
+ The timeline returned is the equivalent of the one seen when you view your mentions on twitter.com.
37
+
38
+ This method can only return up to 800 tweets.
39
+
40
+ See __Working with Timelines__ for instructions on traversing timelines.
41
+ TEXT
42
+ versions '1.1'
43
+ ssl true
44
+ formats :json
45
+
46
+ params do
47
+ optional do
48
+ integer :count, doc: 'Specifies the number of tweets to try and retrieve, up to a maximum of 200. The value of count is best thought of as a limit to the number of tweets to return because suspended or deleted content is removed after the count has been applied. We include retweets in the count, even if `include_rts` is not supplied. It is recommended you always send `include_rts=1` when using this API method.'
49
+ integer :since_id, doc: 'Returns results with an ID greater than (that is, more recent than) the specified ID. There are limits to the number of Tweets which can be accessed through the API. If the limit of Tweets has occured since the since_id, the since_id will be forced to the oldest ID available.
50
+
51
+ __Example Values__: 12345'
52
+ integer :max_id, doc: 'Returns results with an ID less than (that is, older than) or equal to the specified ID.
53
+
54
+ __Example Values__: 54321'
55
+ boolean :trim_user, doc: 'When set to either true, t or 1, each tweet returned in a timeline will include a user object including only the status authors numerical ID. Omit this parameter to receive the complete user object.
56
+
57
+ __Example Values__: true'
58
+ boolean :contributor_details, doc: 'This parameter enhances the contributors element of the status response to include the screen_name of the contributor. By default only the user_id of the contributor is included.
59
+
60
+ __Example Values__: true'
61
+ boolean :include_entities, doc: 'The `entities` node will be disincluded when set to false.
62
+
63
+ __Example Values__: false'
64
+ end
65
+ end
66
+
67
+ response do
68
+ status 200
69
+ header 'Content-Type', 'application/json'
70
+ representation do
71
+ property :id, type: Integer, doc: "it's the id"
72
+ property :title, type: String, doc: "it's the title"
73
+ collection :users, extend: UserRepresenter, doc: "it's the users"
74
+ end
75
+ end
76
+ end
77
+
78
+ resource :get, '/statuses/user_timeline' do
79
+ name 'User timeline'
80
+ description <<-TEXT
81
+ Returns a collection of the most recent Tweets posted by the user indicated by the screen_name or user_id parameters.
82
+
83
+ User timelines belonging to protected users may only be requested when the authenticated user either "owns" the timeline or is an approved follower of the owner.
84
+
85
+ The timeline returned is the equivalent of the one seen when you view a user's profile on twitter.com.
86
+
87
+ This method can only return up to 3,200 of a user's most recent Tweets. Native retweets of other statuses by the user is included in this total, regardless of whether include_rts is set to false when requesting this resource.
88
+
89
+ See Working with Timelines for instructions on traversing timelines.
90
+
91
+ See Embeddable Timelines, Embeddable Tweets, and GET statuses/oembed for tools to render Tweets according to Display Requirements.
92
+ TEXT
93
+ versions '1.1'
94
+ ssl true
95
+ formats :json
96
+
97
+ params do
98
+ optional do
99
+ integer :user_id
100
+ string :screen_name
101
+ integer :since_id
102
+ integer :count
103
+ integer :max_id
104
+ boolean :trim_user
105
+ boolean :exclude_replies
106
+ boolean :contributor_details
107
+ boolean :include_rts
108
+ end
109
+ end
110
+
111
+ response do
112
+ status 200
113
+ header 'Content-Type', 'application/json'
114
+ representation do
115
+ property :id, type: Integer, doc: "it's the id"
116
+ property :title, type: String, doc: "it's the title"
117
+ collection :users, extend: UserRepresenter, doc: "it's the users"
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
data/kanpachi.gemspec ADDED
@@ -0,0 +1,45 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'kanpachi/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "kanpachi"
8
+ spec.version = Kanpachi::VERSION
9
+ spec.authors = ["Jack Chu"]
10
+ spec.email = ["kamuigt@gmail.com"]
11
+ spec.description = %q{Web API DSL}
12
+ spec.summary = %q{DSL for describing Web APIs}
13
+ spec.homepage = "https://github.com/kamui/kanpachi"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency 'thor'
22
+ spec.add_dependency 'slim'
23
+ spec.add_dependency 'roar'
24
+ spec.add_dependency 'representable'
25
+ spec.add_dependency 'mutations'
26
+ spec.add_dependency 'virtus', '>= 1.0.0.beta7'
27
+ spec.add_dependency 'coercible'
28
+ spec.add_dependency 'kramdown'
29
+ spec.add_dependency 'inflecto'
30
+ spec.add_dependency 'middleman', '>= 3.1.5'
31
+ spec.add_dependency 'slim', '>= 1.3.6'
32
+
33
+ # Live-reloading plugin
34
+ spec.add_dependency 'middleman-livereload', '>= 3.1.0'
35
+
36
+ spec.add_development_dependency 'bundler'
37
+ spec.add_development_dependency 'rake'
38
+ spec.add_development_dependency 'minitest'
39
+ spec.add_development_dependency 'guard', '>= 2.0.0.beta.3'
40
+ spec.add_development_dependency 'guard-minitest'
41
+
42
+ # For faster file watcher updates on Windows:
43
+ # spec.add_development_dependency 'wdm', '>= 0.1.0'
44
+ # gem "wdm", "~> 0.1.0", :platforms => [:mswin, :mingw]
45
+ end
data/lib/base_hash.rb ADDED
@@ -0,0 +1,41 @@
1
+ module Kanpachi
2
+ class BaseHash
3
+ class UnknownKey < StandardError; end
4
+ class DuplicateKey < StandardError; end
5
+
6
+ def initialize
7
+ @hash = {}
8
+ end
9
+
10
+ # Returns a hash of hash
11
+ #
12
+ # @return [Hash<Object>] Internal hash.
13
+ # @api public
14
+ def all
15
+ @hash
16
+ end
17
+
18
+ # Add a resource to the list
19
+ #
20
+ # @param [Object] The resource to add.
21
+ # @return [Hash<Object>] Internal hash.
22
+ # @raise DuplicateKey If a resource is being duplicated.
23
+ # @api public
24
+ def add(key, value)
25
+ if @hash.key?(attr_key)
26
+ raise DuplicateKey, 'The key #{attr_key} already exists'
27
+ end
28
+ @hash[key] = value
29
+ end
30
+
31
+ # Returns value based on its key
32
+ #
33
+ # @param [String, Symbol] key The key of the value you are looking for.
34
+ # @return [Object] The value returned from the hash.
35
+ #
36
+ # @api public
37
+ def find(key)
38
+ all[key]
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,22 @@
1
+ require 'kanpachi/error_list'
2
+ require 'kanpachi/section_list'
3
+ require 'kanpachi/resource_list'
4
+
5
+ module Kanpachi
6
+ class API
7
+ attr_reader :name
8
+ attr_reader :errors
9
+ attr_reader :sections
10
+ attr_reader :resources
11
+ attr_accessor :title
12
+ attr_accessor :description
13
+ attr_accessor :host
14
+
15
+ def initialize(name)
16
+ @name = name
17
+ @errors = ErrorList.new
18
+ @sections = SectionList.new
19
+ @resources = ResourceList.new
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,61 @@
1
+ module Kanpachi
2
+ # Module to keep track of all APIs
3
+ #
4
+ # @api public
5
+ module APIList
6
+ module_function
7
+
8
+ @list ||= {}
9
+
10
+ # Returns a hash of APIs
11
+ #
12
+ # @return [Hash<Kanpachi::API>] All the added APIs.
13
+ # @api public
14
+ def to_hash
15
+ @list
16
+ end
17
+
18
+ # Returns an array of APIs
19
+ #
20
+ # @return [Array<Kanpachi::API>] List of added APIs.
21
+ # @api public
22
+ def all
23
+ @list.values
24
+ end
25
+
26
+ # Add a resource to the list
27
+ #
28
+ # @param [Kanpachi::API] The API to add.
29
+ # @return [Hash<Kanpachi::API>] All the added APIs.
30
+ # @raise DuplicateAPI If a resource is being duplicated.
31
+ # @api public
32
+ def add(api)
33
+ @list[api.name] = api
34
+ end
35
+
36
+ # Delete a resource to the list
37
+ #
38
+ # @param [String] The name of the API to delete.
39
+ # @api public
40
+ def delete(name)
41
+ @list.delete(name)
42
+ end
43
+
44
+ # Returns a API based on its name
45
+ #
46
+ # @param [String] name The name of the API you are looking for.
47
+ # @return [Kanpachi::API] The found API.
48
+ #
49
+ # @api public
50
+ def find(name)
51
+ @list[name]
52
+ end
53
+
54
+ # Clears all APIs
55
+ #
56
+ # @api public
57
+ def clear
58
+ @list = {}
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,62 @@
1
+ ENV['MM_ROOT'] = '/Users/jack/Development/kanpachi/lib/kanpachi/doc'
2
+
3
+ module Kanpachi
4
+ module SubCommand
5
+ # class CLI < Thor
6
+ class Doc < Thor
7
+ namespace :doc
8
+
9
+ desc "doc:generate_doc API_NAME, SOURCE_PATH DESTINATION_PATH", "Generate HTML documentation for Kanpachi web services"
10
+ def generate_doc(api_name, source_path, destination_path="doc")
11
+ puts "Starting"
12
+ api_files = Dir.glob(File.join(destination_root, source_path, "**", "*.rb"))
13
+ if api_files.empty?
14
+ puts "No ruby files in source_path: #{File.join(destination_root, source_path)}"
15
+ return
16
+ end
17
+ api_files.each do |file|
18
+ require file
19
+ end
20
+
21
+ api = APIList.find(api_name)
22
+
23
+ require 'fileutils'
24
+ destination = File.join(destination_root, destination_path)
25
+ FileUtils.mkdir_p(destination) unless File.exist?(destination)
26
+ File.open("#{destination}/index.html", "w"){|f| f << doc_template.result(binding)}
27
+ puts "Documentation available there: #{destination}/index.html"
28
+ `open #{destination}/index.html` if RUBY_PLATFORM =~ /darwin/ && !ENV['DONT_OPEN']
29
+ end
30
+
31
+ private
32
+
33
+ def response_html(attrs)
34
+ response_template.result(binding)
35
+ end
36
+
37
+ def input_params_html(required, optional)
38
+ input_params_template.result(binding)
39
+ end
40
+
41
+ def input_params_template
42
+ file = resources.join '_input_params.erb'
43
+ ERB.new File.read(file)
44
+ end
45
+
46
+ def response_template
47
+ file = resources.join '_response.erb'
48
+ ERB.new File.read(file)
49
+ end
50
+
51
+ def doc_template
52
+ file = resources.join 'template.erb'
53
+ ERB.new File.read(file)
54
+ end
55
+
56
+ def resources
57
+ require 'pathname'
58
+ @resources ||= Pathname.new(File.join(File.dirname(__FILE__), 'doc_generator'))
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,32 @@
1
+ require 'thor'
2
+ require 'inflecto'
3
+ require 'json'
4
+ require 'middleman-core'
5
+ require 'middleman-core/cli'
6
+ require 'middleman-core/profiling'
7
+ require_relative '../kanpachi'
8
+ require_relative 'commands/new'
9
+
10
+ ENV['MM_ROOT'] = File.join(File.expand_path(File.dirname(__FILE__)), 'documentation')
11
+
12
+ class Middleman::Cli::Server
13
+ default_task :server
14
+ end
15
+
16
+ class Middleman::Cli::Build
17
+ default_task :build
18
+ end
19
+
20
+ module Kanpachi
21
+ class CLI < Thor
22
+ namespace :kanpachi
23
+
24
+ register Commands::New, 'new', 'new [NAME]', 'Generate a new API'
25
+
26
+ task = ::Middleman::Cli::Server.tasks['server']
27
+ register ::Middleman::Cli::Server, 'server', task.usage, task.description, task.options
28
+
29
+ task = ::Middleman::Cli::Build.tasks['build']
30
+ register ::Middleman::Cli::Build, 'build', task.usage, task.description, task.options
31
+ end
32
+ end
@@ -0,0 +1,26 @@
1
+ require 'thor/group'
2
+
3
+ module Kanpachi
4
+ module Commands
5
+ class New < Thor::Group
6
+ include Thor::Actions
7
+
8
+ desc 'Generate a new API'
9
+ argument :name, type: :string, desc: "The name of the API to generate"
10
+ class_option :test_framework, default: :minitest
11
+
12
+ def self.source_root
13
+ File.expand_path(File.join('..', 'templates'), File.dirname(__FILE__))
14
+ end
15
+
16
+ def create_app
17
+ directory ".", "#{name}"
18
+ end
19
+
20
+ protected
21
+ def name_const
22
+ @name_const ||= Inflecto.camelize(name.gsub(/\W/, '_').squeeze('_'))
23
+ end
24
+ end
25
+ end
26
+ end