brainstem 1.0.0.pre.1 → 1.0.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 +4 -4
- data/CHANGELOG.md +12 -0
- data/Gemfile.lock +1 -1
- data/README.md +383 -32
- data/bin/brainstem +6 -0
- data/brainstem.gemspec +2 -0
- data/docs/api_doc_generator.markdown +175 -0
- data/docs/brainstem_executable.markdown +32 -0
- data/docs/docgen.png +0 -0
- data/docs/docgen_ascii.txt +63 -0
- data/docs/executable.png +0 -0
- data/docs/executable_ascii.txt +10 -0
- data/lib/brainstem/api_docs.rb +146 -0
- data/lib/brainstem/api_docs/abstract_collection.rb +116 -0
- data/lib/brainstem/api_docs/atlas.rb +158 -0
- data/lib/brainstem/api_docs/builder.rb +167 -0
- data/lib/brainstem/api_docs/controller.rb +122 -0
- data/lib/brainstem/api_docs/controller_collection.rb +40 -0
- data/lib/brainstem/api_docs/endpoint.rb +234 -0
- data/lib/brainstem/api_docs/endpoint_collection.rb +58 -0
- data/lib/brainstem/api_docs/exceptions.rb +8 -0
- data/lib/brainstem/api_docs/formatters/abstract_formatter.rb +64 -0
- data/lib/brainstem/api_docs/formatters/markdown/controller_formatter.rb +76 -0
- data/lib/brainstem/api_docs/formatters/markdown/endpoint_collection_formatter.rb +73 -0
- data/lib/brainstem/api_docs/formatters/markdown/endpoint_formatter.rb +169 -0
- data/lib/brainstem/api_docs/formatters/markdown/helper.rb +76 -0
- data/lib/brainstem/api_docs/formatters/markdown/presenter_formatter.rb +200 -0
- data/lib/brainstem/api_docs/introspectors/abstract_introspector.rb +100 -0
- data/lib/brainstem/api_docs/introspectors/rails_introspector.rb +232 -0
- data/lib/brainstem/api_docs/presenter.rb +225 -0
- data/lib/brainstem/api_docs/presenter_collection.rb +97 -0
- data/lib/brainstem/api_docs/resolver.rb +73 -0
- data/lib/brainstem/api_docs/sinks/abstract_sink.rb +37 -0
- data/lib/brainstem/api_docs/sinks/controller_presenter_multifile_sink.rb +93 -0
- data/lib/brainstem/api_docs/sinks/stdout_sink.rb +44 -0
- data/lib/brainstem/cli.rb +146 -0
- data/lib/brainstem/cli/abstract_command.rb +97 -0
- data/lib/brainstem/cli/generate_api_docs_command.rb +169 -0
- data/lib/brainstem/concerns/controller_dsl.rb +300 -0
- data/lib/brainstem/concerns/controller_param_management.rb +30 -9
- data/lib/brainstem/concerns/formattable.rb +38 -0
- data/lib/brainstem/concerns/inheritable_configuration.rb +3 -2
- data/lib/brainstem/concerns/optional.rb +43 -0
- data/lib/brainstem/concerns/presenter_dsl.rb +76 -15
- data/lib/brainstem/controller_methods.rb +6 -3
- data/lib/brainstem/dsl/association.rb +6 -3
- data/lib/brainstem/dsl/associations_block.rb +6 -3
- data/lib/brainstem/dsl/base_block.rb +2 -4
- data/lib/brainstem/dsl/conditional.rb +7 -3
- data/lib/brainstem/dsl/conditionals_block.rb +4 -4
- data/lib/brainstem/dsl/configuration.rb +184 -8
- data/lib/brainstem/dsl/field.rb +6 -3
- data/lib/brainstem/dsl/fields_block.rb +2 -3
- data/lib/brainstem/help_text.txt +8 -0
- data/lib/brainstem/presenter.rb +27 -6
- data/lib/brainstem/presenter_validator.rb +5 -2
- data/lib/brainstem/time_classes.rb +1 -1
- data/lib/brainstem/version.rb +1 -1
- data/spec/brainstem/api_docs/abstract_collection_spec.rb +156 -0
- data/spec/brainstem/api_docs/atlas_spec.rb +353 -0
- data/spec/brainstem/api_docs/builder_spec.rb +100 -0
- data/spec/brainstem/api_docs/controller_collection_spec.rb +92 -0
- data/spec/brainstem/api_docs/controller_spec.rb +225 -0
- data/spec/brainstem/api_docs/endpoint_collection_spec.rb +144 -0
- data/spec/brainstem/api_docs/endpoint_spec.rb +346 -0
- data/spec/brainstem/api_docs/formatters/abstract_formatter_spec.rb +30 -0
- data/spec/brainstem/api_docs/formatters/markdown/controller_formatter_spec.rb +126 -0
- data/spec/brainstem/api_docs/formatters/markdown/endpoint_collection_formatter_spec.rb +85 -0
- data/spec/brainstem/api_docs/formatters/markdown/endpoint_formatter_spec.rb +261 -0
- data/spec/brainstem/api_docs/formatters/markdown/helper_spec.rb +100 -0
- data/spec/brainstem/api_docs/formatters/markdown/presenter_formatter_spec.rb +485 -0
- data/spec/brainstem/api_docs/introspectors/abstract_introspector_spec.rb +192 -0
- data/spec/brainstem/api_docs/introspectors/rails_introspector_spec.rb +170 -0
- data/spec/brainstem/api_docs/presenter_collection_spec.rb +84 -0
- data/spec/brainstem/api_docs/presenter_spec.rb +519 -0
- data/spec/brainstem/api_docs/resolver_spec.rb +72 -0
- data/spec/brainstem/api_docs/sinks/abstract_sink_spec.rb +16 -0
- data/spec/brainstem/api_docs/sinks/controller_presenter_multifile_sink_spec.rb +56 -0
- data/spec/brainstem/api_docs/sinks/stdout_sink_spec.rb +22 -0
- data/spec/brainstem/api_docs_spec.rb +58 -0
- data/spec/brainstem/cli/abstract_command_spec.rb +91 -0
- data/spec/brainstem/cli/generate_api_docs_command_spec.rb +125 -0
- data/spec/brainstem/cli_spec.rb +67 -0
- data/spec/brainstem/concerns/controller_dsl_spec.rb +471 -0
- data/spec/brainstem/concerns/controller_param_management_spec.rb +36 -16
- data/spec/brainstem/concerns/formattable_spec.rb +30 -0
- data/spec/brainstem/concerns/inheritable_configuration_spec.rb +104 -4
- data/spec/brainstem/concerns/optional_spec.rb +48 -0
- data/spec/brainstem/concerns/presenter_dsl_spec.rb +202 -31
- data/spec/brainstem/dsl/association_spec.rb +18 -2
- data/spec/brainstem/dsl/conditional_spec.rb +25 -2
- data/spec/brainstem/dsl/configuration_spec.rb +1 -1
- data/spec/brainstem/dsl/field_spec.rb +18 -2
- data/spec/brainstem/presenter_collection_spec.rb +10 -2
- data/spec/brainstem/presenter_spec.rb +32 -0
- data/spec/brainstem/presenter_validator_spec.rb +12 -7
- data/spec/dummy/rails.rb +49 -0
- data/spec/shared/atlas_taker.rb +18 -0
- data/spec/shared/formattable.rb +14 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/spec_helpers/db.rb +1 -1
- data/spec/spec_helpers/presenters.rb +20 -14
- metadata +106 -6
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
require 'active_support/inflector/inflections'
|
|
2
|
+
require 'brainstem/api_docs/abstract_collection'
|
|
3
|
+
require 'brainstem/api_docs/presenter'
|
|
4
|
+
require 'brainstem/concerns/formattable'
|
|
5
|
+
|
|
6
|
+
module Brainstem
|
|
7
|
+
module ApiDocs
|
|
8
|
+
class PresenterCollection < AbstractCollection
|
|
9
|
+
include Concerns::Formattable
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def valid_options
|
|
13
|
+
super | [ :presenter_constant_lookup_method ]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
attr_writer :presenter_constant_lookup_method
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
#
|
|
20
|
+
# Finds or creates a presenter with the given target class and appends it to the
|
|
21
|
+
# members list if it is new.
|
|
22
|
+
#
|
|
23
|
+
def find_or_create_from_target_class(target_class)
|
|
24
|
+
find_by_target_class(target_class) ||
|
|
25
|
+
create_from_target_class(target_class)
|
|
26
|
+
end
|
|
27
|
+
alias_method :find_or_create_by_target_class,
|
|
28
|
+
:find_or_create_from_target_class
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
#
|
|
32
|
+
# Finds a presenter for the given class
|
|
33
|
+
#
|
|
34
|
+
def find_by_target_class(target_class)
|
|
35
|
+
find { |p| p.target_class == target_class }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
#
|
|
40
|
+
# Creates a new +Presenter+ wrapper and appends it to the collection. If
|
|
41
|
+
# the constant lookup for the actual presenter class fails, returns nil.
|
|
42
|
+
#
|
|
43
|
+
def create_from_target_class(target_class)
|
|
44
|
+
::Brainstem::ApiDocs::Presenter.new(atlas,
|
|
45
|
+
target_class: target_class,
|
|
46
|
+
const: target_class_to_const(target_class)
|
|
47
|
+
).tap { |p| self.<< p }
|
|
48
|
+
rescue KeyError
|
|
49
|
+
nil
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def find_or_create_from_presenter_collection(target_class, const)
|
|
54
|
+
find_by_target_class(target_class) ||
|
|
55
|
+
create_from_presenter_collection(target_class, const)
|
|
56
|
+
end
|
|
57
|
+
alias_method :find_or_create_by_presenter_collection,
|
|
58
|
+
:find_or_create_from_presenter_collection
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def create_from_presenter_collection(target_class, const)
|
|
62
|
+
::Brainstem::ApiDocs::Presenter.new(atlas,
|
|
63
|
+
target_class: target_class,
|
|
64
|
+
const: const
|
|
65
|
+
).tap { |p| self.<< p }
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
#########################################################################
|
|
70
|
+
private
|
|
71
|
+
#########################################################################
|
|
72
|
+
|
|
73
|
+
#
|
|
74
|
+
# Converts a target class into a presenter constant. Raises an error
|
|
75
|
+
# if not found.
|
|
76
|
+
#
|
|
77
|
+
def target_class_to_const(target_class)
|
|
78
|
+
presenter_constant_lookup_method.call(target_class.to_s)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
#
|
|
83
|
+
# A callable method by which presenter constants can be looked up from
|
|
84
|
+
# their human name.
|
|
85
|
+
#
|
|
86
|
+
# In future, it might be worth unifying this method with `find_by_class`
|
|
87
|
+
# to reduce total surface.
|
|
88
|
+
#
|
|
89
|
+
def presenter_constant_lookup_method
|
|
90
|
+
@presenter_constant_lookup_method ||= \
|
|
91
|
+
Brainstem.presenter_collection.presenters.method(:fetch)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
require 'brainstem/concerns/optional'
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# The Resolver is responsible for taking a non-ApiDocs class and turning it
|
|
5
|
+
# into an ApiDocs wrapper class (such as a Presenter, Controller, or Endpoint).
|
|
6
|
+
#
|
|
7
|
+
# It's useful for doing object lookups for associated objects where we only
|
|
8
|
+
# have the original class or constant to look up the relationship.
|
|
9
|
+
#
|
|
10
|
+
module Brainstem
|
|
11
|
+
module ApiDocs
|
|
12
|
+
class Resolver
|
|
13
|
+
include Brainstem::Concerns::Optional
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def valid_options
|
|
17
|
+
[
|
|
18
|
+
:presenter_constant_lookup_method,
|
|
19
|
+
]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def initialize(atlas, options = {})
|
|
23
|
+
self.atlas = atlas
|
|
24
|
+
super options
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
attr_accessor :atlas,
|
|
29
|
+
:presenter_constant_lookup_method
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def find_by_class(klass)
|
|
33
|
+
if klass == :polymorphic
|
|
34
|
+
nil
|
|
35
|
+
elsif klass < ActiveRecord::Base
|
|
36
|
+
find_presenter_from_target_class(klass)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
#########################################################################
|
|
42
|
+
private
|
|
43
|
+
#########################################################################
|
|
44
|
+
|
|
45
|
+
def find_presenter_from_target_class(klass)
|
|
46
|
+
const = presenter_target_class_to_const(klass)
|
|
47
|
+
atlas.presenters.find {|p| p.const == const }
|
|
48
|
+
rescue
|
|
49
|
+
nil
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
#
|
|
54
|
+
# Converts a class into a presenter constant. Raises an error
|
|
55
|
+
# if not found.
|
|
56
|
+
#
|
|
57
|
+
def presenter_target_class_to_const(target_class)
|
|
58
|
+
presenter_constant_lookup_method.call(target_class.to_s)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
#
|
|
63
|
+
# A callable method by which presenter constants can be looked up from
|
|
64
|
+
# their human name.
|
|
65
|
+
#
|
|
66
|
+
def presenter_constant_lookup_method
|
|
67
|
+
@presenter_constant_lookup_method ||= \
|
|
68
|
+
Brainstem.presenter_collection.presenters.method(:fetch)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
require 'brainstem/concerns/optional'
|
|
2
|
+
|
|
3
|
+
module Brainstem
|
|
4
|
+
module ApiDocs
|
|
5
|
+
module Sinks
|
|
6
|
+
class AbstractSink
|
|
7
|
+
include Concerns::Optional
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
#
|
|
11
|
+
# Primary method for putting the atlas into the sink.
|
|
12
|
+
#
|
|
13
|
+
# @param [Brainstem::ApiDocs::Atlas] the atlas
|
|
14
|
+
#
|
|
15
|
+
def <<(atlas)
|
|
16
|
+
raise NotImplementedError
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
#######################################################################$
|
|
21
|
+
private
|
|
22
|
+
########################################################################
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
#
|
|
26
|
+
# Whitelist of options which can be set on an instance.
|
|
27
|
+
#
|
|
28
|
+
# @return [Array<Symbol>] valid options
|
|
29
|
+
#
|
|
30
|
+
def valid_options
|
|
31
|
+
[]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
require 'brainstem/api_docs/sinks/abstract_sink'
|
|
2
|
+
require 'fileutils'
|
|
3
|
+
require 'forwardable'
|
|
4
|
+
|
|
5
|
+
module Brainstem
|
|
6
|
+
module ApiDocs
|
|
7
|
+
module Sinks
|
|
8
|
+
class ControllerPresenterMultifileSink < AbstractSink
|
|
9
|
+
extend Forwardable
|
|
10
|
+
|
|
11
|
+
delegate [:controllers, :presenters] => :atlas
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def <<(atlas)
|
|
15
|
+
self.atlas = atlas
|
|
16
|
+
|
|
17
|
+
write_controller_files
|
|
18
|
+
write_presenter_files
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def valid_options
|
|
23
|
+
super | [ :write_method, :format, :write_path ]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
attr_writer :write_method,
|
|
28
|
+
:write_path
|
|
29
|
+
|
|
30
|
+
attr_accessor :atlas,
|
|
31
|
+
:format
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
#######################################################################
|
|
35
|
+
private
|
|
36
|
+
#######################################################################
|
|
37
|
+
|
|
38
|
+
#
|
|
39
|
+
# Dumps each formatted controller to a file.
|
|
40
|
+
#
|
|
41
|
+
def write_controller_files
|
|
42
|
+
controllers.each_formatted_with_filename(
|
|
43
|
+
format,
|
|
44
|
+
include_actions: true,
|
|
45
|
+
&method(:write_buffer_to_file)
|
|
46
|
+
)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
#
|
|
51
|
+
# Dumps each formatted presenter to a file.
|
|
52
|
+
#
|
|
53
|
+
def write_presenter_files
|
|
54
|
+
presenters.each_formatted_with_filename(format, &method(:write_buffer_to_file))
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
#
|
|
59
|
+
# Writes a given bufer to a filename within the base path.
|
|
60
|
+
#
|
|
61
|
+
def write_buffer_to_file(buffer, filename)
|
|
62
|
+
abs_path = File.join(write_path, filename)
|
|
63
|
+
assert_directory_exists!(abs_path)
|
|
64
|
+
write_method.call(abs_path, buffer)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
#
|
|
69
|
+
# Asserts that a directory exists, creating it if it does not.
|
|
70
|
+
#
|
|
71
|
+
def assert_directory_exists!(path)
|
|
72
|
+
dir = File.dirname(path)
|
|
73
|
+
FileUtils.mkdir_p(dir) unless File.directory?(dir)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
#
|
|
78
|
+
# Defines how we write out the files.
|
|
79
|
+
#
|
|
80
|
+
def write_method
|
|
81
|
+
@write_method ||= Proc.new do |name, buff|
|
|
82
|
+
File.write(name, buff, mode: 'w')
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def write_path
|
|
88
|
+
@write_path ||= ::Brainstem::ApiDocs.write_path
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require 'brainstem/api_docs/sinks/abstract_sink'
|
|
2
|
+
|
|
3
|
+
module Brainstem
|
|
4
|
+
module ApiDocs
|
|
5
|
+
module Sinks
|
|
6
|
+
class StdoutSink < AbstractSink
|
|
7
|
+
|
|
8
|
+
#
|
|
9
|
+
# Writes the output using stdout.puts.
|
|
10
|
+
#
|
|
11
|
+
def <<(output)
|
|
12
|
+
puts_method.call(output)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
########################################################################
|
|
17
|
+
private
|
|
18
|
+
########################################################################
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def valid_options
|
|
22
|
+
super | [ :puts_method ]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
#
|
|
27
|
+
# Storage for holding the writing method.
|
|
28
|
+
#
|
|
29
|
+
attr_writer :puts_method
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
#
|
|
33
|
+
# Callable method for writing data to a buffer (by default stdout).
|
|
34
|
+
#
|
|
35
|
+
# @return [Proc] a method which writes data to a buffer when called.
|
|
36
|
+
#
|
|
37
|
+
def puts_method
|
|
38
|
+
@puts_method ||= $stdout.method(:puts)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# Require all CLI commands.
|
|
2
|
+
Dir.glob(File.expand_path('../cli/**/*.rb', __FILE__)).each { |f| require f }
|
|
3
|
+
require 'brainstem/concerns/optional'
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
#
|
|
7
|
+
# General manager for CLI requests. Takes incoming user input and routes to a
|
|
8
|
+
# subcommand.
|
|
9
|
+
module Brainstem
|
|
10
|
+
class Cli
|
|
11
|
+
include Concerns::Optional
|
|
12
|
+
|
|
13
|
+
EXECUTABLE_NAME = 'brainstem'
|
|
14
|
+
|
|
15
|
+
#
|
|
16
|
+
# Convenience for instantiating and calling the Cli object.
|
|
17
|
+
#
|
|
18
|
+
# @return [Brainstem::Cli] the created instance
|
|
19
|
+
#
|
|
20
|
+
def self.call(args, options = {})
|
|
21
|
+
new(args, options).call
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
#
|
|
26
|
+
# Creates a new instance of the Cli to respond to user input.
|
|
27
|
+
#
|
|
28
|
+
# Input is expected to be the name of the subcommand, followed by any
|
|
29
|
+
# additional arguments.
|
|
30
|
+
#
|
|
31
|
+
def initialize(args, options = {})
|
|
32
|
+
super options
|
|
33
|
+
|
|
34
|
+
self._args = args.dup.freeze
|
|
35
|
+
self.requested_command = args.shift
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
#
|
|
40
|
+
# Routes to an application endpoint depending on given options.
|
|
41
|
+
#
|
|
42
|
+
# @return [Brainstem::Cli] the instance
|
|
43
|
+
#
|
|
44
|
+
def call
|
|
45
|
+
if requested_command && commands.has_key?(requested_command)
|
|
46
|
+
self.command_method = commands[requested_command].method(:call)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
command_method.call(_args.drop(1))
|
|
50
|
+
|
|
51
|
+
self
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
#
|
|
56
|
+
# Holds a copy of the initial given args for debugging purposes.
|
|
57
|
+
#
|
|
58
|
+
attr_accessor :_args
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
#
|
|
62
|
+
# Storage for the extracted command.
|
|
63
|
+
#
|
|
64
|
+
attr_accessor :requested_command
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
################################################################################
|
|
68
|
+
private
|
|
69
|
+
################################################################################
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
#
|
|
73
|
+
# A whitelist of valid options that can be applied to the instance.
|
|
74
|
+
#
|
|
75
|
+
# @returns [Array<String>]
|
|
76
|
+
#
|
|
77
|
+
def valid_options
|
|
78
|
+
super | [
|
|
79
|
+
:log_method
|
|
80
|
+
]
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
#
|
|
85
|
+
# A basic routing table where the keys are the command to invoke, and where
|
|
86
|
+
# the value is a callable object or class that will be called with the
|
|
87
|
+
# +command_options+.
|
|
88
|
+
#
|
|
89
|
+
# @return [Hash] A hash of +'command' => Callable+
|
|
90
|
+
#
|
|
91
|
+
def commands
|
|
92
|
+
{ 'generate' => Brainstem::CLI::GenerateApiDocsCommand }
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
#
|
|
97
|
+
# Retrieves the help text and subs any placeholder values.
|
|
98
|
+
#
|
|
99
|
+
def help_text
|
|
100
|
+
@help_text ||= File.read(File.expand_path('../help_text.txt', __FILE__))
|
|
101
|
+
.gsub('EXECUTABLE_NAME', EXECUTABLE_NAME)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
#
|
|
106
|
+
# Stores the method we should call to run the user command.
|
|
107
|
+
#
|
|
108
|
+
attr_writer :command_method
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
#
|
|
112
|
+
# Reader for the method to invoke. By default, will output the help text
|
|
113
|
+
# when called.
|
|
114
|
+
#
|
|
115
|
+
# @return [Proc] An object responding to +#call+ that is used as the main
|
|
116
|
+
# point execution.
|
|
117
|
+
#
|
|
118
|
+
def command_method
|
|
119
|
+
@command_method ||= Proc.new do
|
|
120
|
+
# By default, serve help.
|
|
121
|
+
log_method.call(help_text)
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
#
|
|
127
|
+
# Stores the method we should use to log messages.
|
|
128
|
+
#
|
|
129
|
+
attr_writer :log_method
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
#
|
|
133
|
+
# Reader for the method to log. By default, will print to stdout when
|
|
134
|
+
# called.
|
|
135
|
+
#
|
|
136
|
+
# We return a proc here because it's much tricker to make assertions
|
|
137
|
+
# against stdout than it is to allow ourselves to inject a proc.
|
|
138
|
+
#
|
|
139
|
+
# @return [Proc] An object responding to +#call+ that is used to print
|
|
140
|
+
# information.
|
|
141
|
+
#
|
|
142
|
+
def log_method
|
|
143
|
+
@log_method ||= $stdout.method(:puts)
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|