k_doc 0.0.1 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/Guardfile +30 -0
- data/README.md +10 -3
- data/STORIES.md +44 -0
- data/USAGE.md +19 -0
- data/k_doc.gemspec +2 -0
- data/lib/k_doc.rb +37 -1
- data/lib/k_doc/document.rb +200 -0
- data/lib/k_doc/fake_opinion.rb +27 -0
- data/lib/k_doc/settings.rb +133 -0
- data/lib/k_doc/table.rb +115 -0
- data/lib/k_doc/util.rb +14 -0
- data/lib/k_doc/version.rb +1 -1
- metadata +39 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5f42e0aaa27cf50c5ee0fa56385d3cc492f7b8b01cb7abe9877300a785fa6313
|
4
|
+
data.tar.gz: 27c280e4d65360589f0c52a95fc4f43c1dfc88ab60e20685502f9b18a7ab5de0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7e40236d4c57ff7cdf5dfa782f2380c53cf8744b84253f18ba49c9a486be97b75f9d28396cfb07649ec7b8fc6d7b0f30967ceee65039d05b1c491ca97e552aca
|
7
|
+
data.tar.gz: 6068509f1ec674f7a0d71a7ca7e919ee302d5b4805507ebf89efab4f92ede36074de4a5ce9749c266c56020fe86199618482818839219f66ec1281a0471b688b
|
data/.rubocop.yml
CHANGED
data/Guardfile
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
guard :bundler, cmd: 'bundle install' do
|
4
|
+
watch('Gemfile')
|
5
|
+
watch('k_doc.gemspec')
|
6
|
+
end
|
7
|
+
|
8
|
+
group :green_pass_then_cop, halt_on_fail: true do
|
9
|
+
guard :rspec, cmd: 'bundle exec rspec -f doc' do
|
10
|
+
require 'guard/rspec/dsl'
|
11
|
+
dsl = Guard::RSpec::Dsl.new(self)
|
12
|
+
|
13
|
+
# RSpec files
|
14
|
+
rspec = dsl.rspec
|
15
|
+
watch(rspec.spec_helper) { rspec.spec_dir }
|
16
|
+
watch(rspec.spec_support) { rspec.spec_dir }
|
17
|
+
watch(rspec.spec_files)
|
18
|
+
|
19
|
+
# Ruby files
|
20
|
+
ruby = dsl.ruby
|
21
|
+
dsl.watch_spec_files_for(ruby.lib_files)
|
22
|
+
watch(%r{^lib/k_doc/(.+)\.rb$}) { |m| "spec/unit/#{m[1]}_spec.rb" }
|
23
|
+
watch(%r{^lib/k_doc/commands/(.+)\.rb$}) { |m| "spec/unit/commands/#{m[1]}_spec.rb" }
|
24
|
+
end
|
25
|
+
|
26
|
+
guard :rubocop, all_on_start: false, cli: ['--format', 'clang'] do
|
27
|
+
watch(/{.+\.rb$/)
|
28
|
+
watch(%r{(?:.+/)?\.rubocop(?:_todo)?\.yml$}) { |m| File.dirname(m[0]) }
|
29
|
+
end
|
30
|
+
end
|
data/README.md
CHANGED
@@ -26,16 +26,23 @@ gem install k_doc
|
|
26
26
|
|
27
27
|
### Main Story
|
28
28
|
|
29
|
-
|
29
|
+
As a Developer, I need flexible data structures defined in DSL, so can model rich documents
|
30
30
|
|
31
31
|
See all [stories](./STORIES.md)
|
32
32
|
|
33
|
-
|
34
33
|
## Usage
|
35
34
|
|
36
35
|
See all [usage examples](./USAGE.md)
|
37
36
|
|
37
|
+
### Basic Example
|
38
|
+
|
39
|
+
#### Basic example
|
38
40
|
|
41
|
+
Description for a basic example to be featured in the main README.MD file
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
class SomeRuby; end
|
45
|
+
```
|
39
46
|
|
40
47
|
## Development
|
41
48
|
|
@@ -45,7 +52,7 @@ Checkout the repo
|
|
45
52
|
git clone klueless-io/k_doc
|
46
53
|
```
|
47
54
|
|
48
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests.
|
55
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests.
|
49
56
|
|
50
57
|
You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
51
58
|
|
data/STORIES.md
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# K Doc
|
2
|
+
|
3
|
+
> KDoc provides a document in the form a DSL that contains flexible key/value and tabular data
|
4
|
+
|
5
|
+
As a Developer, I need flexible data structures defined in DSL, so can model rich documents
|
6
|
+
|
7
|
+
## Development radar
|
8
|
+
|
9
|
+
### Stories next on list
|
10
|
+
|
11
|
+
As a Developer, I need flexible data structures defined in DSL, so can model rich documents
|
12
|
+
|
13
|
+
### Tasks next on list
|
14
|
+
|
15
|
+
Setup RubyGems and RubyDoc
|
16
|
+
|
17
|
+
- Build and deploy gem to [rubygems.org](https://rubygems.org/gems/k_doc)
|
18
|
+
- Attach documentation to [rubydoc.info](https://rubydoc.info/github/to-do-/k_doc/master)
|
19
|
+
|
20
|
+
Setup GitHub Action (test and lint)
|
21
|
+
|
22
|
+
- Setup Rspec action
|
23
|
+
- Setup RuboCop action
|
24
|
+
|
25
|
+
## Stories and tasks
|
26
|
+
|
27
|
+
### Tasks - completed
|
28
|
+
|
29
|
+
Setup project management, requirement and SCRUM documents
|
30
|
+
|
31
|
+
- Setup readme file
|
32
|
+
- Setup user stories and tasks
|
33
|
+
- Setup a project backlog
|
34
|
+
- Setup an examples/usage document
|
35
|
+
|
36
|
+
Setup new Ruby GEM
|
37
|
+
|
38
|
+
- Build out a standard GEM structure
|
39
|
+
- Add automated semantic versioning
|
40
|
+
- Add Rspec unit testing framework
|
41
|
+
- Add RuboCop linting
|
42
|
+
- Add Guard for automatic watch and test
|
43
|
+
- Add GitFlow support
|
44
|
+
- Add GitHub Repository
|
data/USAGE.md
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# K Doc
|
2
|
+
|
3
|
+
> KDoc provides a document in the form a DSL that contains flexible key/value and tabular data
|
4
|
+
|
5
|
+
As a Developer, I need flexible data structures defined in DSL, so can model rich documents
|
6
|
+
|
7
|
+
## Usage
|
8
|
+
|
9
|
+
### Sample Classes
|
10
|
+
|
11
|
+
#### Simple example
|
12
|
+
|
13
|
+
Description for a simple example that shows up in the USAGE.MD
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
class SomeRuby
|
17
|
+
def initialize; end
|
18
|
+
end
|
19
|
+
```
|
data/k_doc.gemspec
CHANGED
data/lib/k_doc.rb
CHANGED
@@ -1,10 +1,46 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'securerandom'
|
4
|
+
|
5
|
+
require 'logger'
|
6
|
+
require 'table_print'
|
7
|
+
require 'k_log'
|
8
|
+
require 'k_util'
|
9
|
+
require 'k_log/log_formatter'
|
10
|
+
require 'k_log/log_helper'
|
11
|
+
require 'k_log/log_util'
|
12
|
+
|
3
13
|
require 'k_doc/version'
|
14
|
+
require 'k_doc/document'
|
15
|
+
require 'k_doc/fake_opinion'
|
16
|
+
require 'k_doc/settings'
|
17
|
+
require 'k_doc/table'
|
18
|
+
require 'k_doc/util'
|
4
19
|
|
5
20
|
module KDoc
|
6
21
|
# raise KDoc::Error, 'Sample message'
|
7
22
|
class Error < StandardError; end
|
8
23
|
|
9
|
-
|
24
|
+
class << self
|
25
|
+
# Factory method to create a new document
|
26
|
+
def doc(key = nil, **options, &block)
|
27
|
+
doc = KDoc::Document.new(key, **options, &block)
|
28
|
+
doc.execute_block
|
29
|
+
doc
|
30
|
+
end
|
31
|
+
|
32
|
+
attr_accessor :opinion
|
33
|
+
attr_accessor :util
|
34
|
+
attr_accessor :log
|
35
|
+
end
|
36
|
+
|
37
|
+
KDoc.opinion = KDoc::FakeOpinion.new
|
38
|
+
KDoc.util = KDoc::Util.new
|
39
|
+
end
|
40
|
+
|
41
|
+
if ENV['KLUE_DEBUG']&.to_s&.downcase == 'true'
|
42
|
+
namespace = 'KDoc::Version'
|
43
|
+
file_path = $LOADED_FEATURES.find { |f| f.include?('k_doc/version') }
|
44
|
+
version = KDoc::VERSION.ljust(9)
|
45
|
+
puts "#{namespace.ljust(40)} : #{version.ljust(9)} : #{file_path}"
|
10
46
|
end
|
@@ -0,0 +1,200 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KDoc
|
4
|
+
# General purpose document DSL
|
5
|
+
#
|
6
|
+
# Made up of 0 or more setting groups and table groups
|
7
|
+
class Document
|
8
|
+
include KLog::Logging
|
9
|
+
|
10
|
+
# include KType::Error
|
11
|
+
# include KType::ManagedState
|
12
|
+
# include KType::NamedFolder
|
13
|
+
# include KType::LayeredFolder
|
14
|
+
|
15
|
+
attr_reader :key
|
16
|
+
attr_reader :type
|
17
|
+
attr_reader :namespace
|
18
|
+
attr_reader :options
|
19
|
+
attr_reader :error
|
20
|
+
|
21
|
+
# Create document
|
22
|
+
#
|
23
|
+
# @param [String|Symbol] name Name of the document
|
24
|
+
# @param args[0] Type of the document, defaults to KDoc:: FakeOpinion.new.default_document_type if not set
|
25
|
+
# @param default: Default value (using named params), as above
|
26
|
+
def initialize(key = SecureRandom.alphanumeric(8), **options, &block)
|
27
|
+
initialize_attributes(key, **options)
|
28
|
+
|
29
|
+
@block = block if block_given?
|
30
|
+
end
|
31
|
+
|
32
|
+
def execute_block(run_actions: nil)
|
33
|
+
return if @block.nil?
|
34
|
+
|
35
|
+
# The DSL actions method will only run on run_actions: true
|
36
|
+
@run_actions = run_actions
|
37
|
+
|
38
|
+
instance_eval(&@block)
|
39
|
+
|
40
|
+
on_action if run_actions && respond_to?(:on_action)
|
41
|
+
# rescue KDoc::Error => e
|
42
|
+
# puts('KDoc::Error in document')
|
43
|
+
# puts "key #{unique_key}"
|
44
|
+
# # puts "file #{KUtil.data.console_file_hyperlink(resource.file, resource.file)}"
|
45
|
+
# puts(e.message)
|
46
|
+
# @error = e
|
47
|
+
# raise
|
48
|
+
rescue StandardError => e
|
49
|
+
log.error('Standard error in document')
|
50
|
+
puts "key #{unique_key}"
|
51
|
+
# puts "file #{KUtil.data.console_file_hyperlink(resource.file, resource.file)}"
|
52
|
+
log.error(e.message)
|
53
|
+
@error = e
|
54
|
+
# log.exception exception2
|
55
|
+
raise
|
56
|
+
ensure
|
57
|
+
@run_actions = nil
|
58
|
+
end
|
59
|
+
|
60
|
+
def unique_key
|
61
|
+
@unique_key ||= KDoc.util.build_unique_key(key, type, namespace)
|
62
|
+
end
|
63
|
+
|
64
|
+
def settings(key = nil, **options, &block)
|
65
|
+
options ||= {}
|
66
|
+
|
67
|
+
opts = {}.merge(@options) # Document Options
|
68
|
+
.merge(options) # Settings Options
|
69
|
+
.merge(parent: self)
|
70
|
+
|
71
|
+
settings_instance(@data, key, **opts, &block)
|
72
|
+
# settings.run_decorators(opts)
|
73
|
+
end
|
74
|
+
|
75
|
+
def table(key = :table, **options, &block)
|
76
|
+
# NEED to add support for run_decorators I think
|
77
|
+
options.merge(parent: self)
|
78
|
+
table_instance(@data, key, **options, &block)
|
79
|
+
end
|
80
|
+
alias rows table
|
81
|
+
|
82
|
+
# Sweet add-on would be builders
|
83
|
+
# def builder(key, &block)
|
84
|
+
# # example
|
85
|
+
# KDoc::Builder::Shotstack.new(@data, key, &block)
|
86
|
+
# end
|
87
|
+
|
88
|
+
# def set_data(data)
|
89
|
+
# @data = data
|
90
|
+
# end
|
91
|
+
|
92
|
+
def data
|
93
|
+
@data.clone
|
94
|
+
end
|
95
|
+
|
96
|
+
def data_struct
|
97
|
+
KUtil.data.to_open_struct(data)
|
98
|
+
end
|
99
|
+
# alias d data_struct
|
100
|
+
|
101
|
+
def raw_data_struct
|
102
|
+
KUtil.data.to_open_struct(raw_data)
|
103
|
+
end
|
104
|
+
|
105
|
+
def get_node_type(node_name)
|
106
|
+
node_name = KUtil.data.clean_symbol(node_name)
|
107
|
+
node_data = @data[node_name]
|
108
|
+
|
109
|
+
raise KDoc::Error, "Node not found: #{node_name}" if node_data.nil?
|
110
|
+
|
111
|
+
if node_data.keys.length == 2 && (node_data.key?('fields') && node_data.key?('rows'))
|
112
|
+
:table
|
113
|
+
else
|
114
|
+
:settings
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# Removes any meta data eg. "fields" from a table and just returns the raw data
|
119
|
+
def raw_data
|
120
|
+
# REFACT, what if this is CSV, meaning it is just an array?
|
121
|
+
# add specs
|
122
|
+
result = data
|
123
|
+
|
124
|
+
result.each_key do |key|
|
125
|
+
# ANTI: get_node_type uses @data while we are using @data.clone here
|
126
|
+
result[key] = if get_node_type(key) == :table
|
127
|
+
# Old format was to keep the rows and delete the fields
|
128
|
+
# Now the format is to pull the row_value up to the key and remove rows and fields
|
129
|
+
# result[key].delete('fields')
|
130
|
+
result[key]['rows']
|
131
|
+
else
|
132
|
+
result[key]
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
result
|
137
|
+
end
|
138
|
+
|
139
|
+
# Move this out to the logger function when it has been refactor
|
140
|
+
def debug(include_header: false)
|
141
|
+
debug_header if include_header
|
142
|
+
|
143
|
+
# tp dsls.values, :k_key, :k_type, :state, :save_at, :last_at, :data, :last_data, :source, { :file => { :width => 150 } }
|
144
|
+
# puts JSON.pretty_generate(data)
|
145
|
+
log.o(raw_data_struct)
|
146
|
+
end
|
147
|
+
|
148
|
+
# rubocop:disable Metrics/AbcSize
|
149
|
+
def debug_header
|
150
|
+
log.heading self.class.name
|
151
|
+
log.kv 'key', key
|
152
|
+
log.kv 'type', type
|
153
|
+
log.kv 'namespace', namespace
|
154
|
+
log.kv 'error', error
|
155
|
+
|
156
|
+
debug_header_keys
|
157
|
+
|
158
|
+
log.line
|
159
|
+
end
|
160
|
+
# rubocop:enable Metrics/AbcSize
|
161
|
+
|
162
|
+
def debug_header_keys
|
163
|
+
options&.keys&.reject { |k| k == :namespace }&.each do |key|
|
164
|
+
log.kv key, options[key]
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
private
|
169
|
+
|
170
|
+
def initialize_attributes(key = nil, **options)
|
171
|
+
@key = key
|
172
|
+
|
173
|
+
@options = options || {}
|
174
|
+
@type = slice_option(:type) || KDoc.opinion.default_document_type
|
175
|
+
@namespace = slice_option(:namespace) || ''
|
176
|
+
@parent = slice_option(:parent)
|
177
|
+
|
178
|
+
# Most documents live within a hash, some tabular documents such as CSV will use an []
|
179
|
+
@data = slice_option(:default_data) || {}
|
180
|
+
|
181
|
+
@error = nil
|
182
|
+
end
|
183
|
+
|
184
|
+
def settings_instance(data, key, **options, &block)
|
185
|
+
KDoc.opinion.settings_class.new(data, key, **options, &block)
|
186
|
+
end
|
187
|
+
|
188
|
+
def table_instance(data, key, **options, &block)
|
189
|
+
KDoc.opinion.table_class.new(data, key, **options, &block)
|
190
|
+
end
|
191
|
+
|
192
|
+
def slice_option(key)
|
193
|
+
return nil unless @options.key?(key)
|
194
|
+
|
195
|
+
result = @options[key]
|
196
|
+
@options.delete(key)
|
197
|
+
result
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module KDoc
|
6
|
+
# This is called fake opinion because I have not figured out
|
7
|
+
# how I want to implement this
|
8
|
+
class FakeOpinion
|
9
|
+
attr_accessor :default_document_type
|
10
|
+
attr_accessor :default_settings_key
|
11
|
+
attr_accessor :default_table_key
|
12
|
+
|
13
|
+
attr_accessor :document_class
|
14
|
+
attr_accessor :settings_class
|
15
|
+
attr_accessor :table_class
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@default_document_type = :entity
|
19
|
+
@default_settings_key = :settings
|
20
|
+
@default_table_key = :table
|
21
|
+
|
22
|
+
@document_class = KDoc::Document
|
23
|
+
@table_class = KDoc::Table
|
24
|
+
@settings_class = KDoc::Settings
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module KDoc
|
6
|
+
# Builds up key/value settings from the block
|
7
|
+
# and applies them to a key coded node on the hash
|
8
|
+
class Settings
|
9
|
+
include KLog::Logging
|
10
|
+
|
11
|
+
attr_reader :parent
|
12
|
+
attr_reader :key
|
13
|
+
|
14
|
+
alias kp parent
|
15
|
+
|
16
|
+
def initialize(data, key = nil, **options, &block)
|
17
|
+
initialize_attributes(data, key, **options)
|
18
|
+
|
19
|
+
# Need a way to find out the line number for errors and report it correctly
|
20
|
+
begin
|
21
|
+
instance_eval(&block) if block_given?
|
22
|
+
# rubocop:disable Style/RescueStandardError
|
23
|
+
rescue => e
|
24
|
+
# rubocop:enable Style/RescueStandardError
|
25
|
+
puts "Invalid code block in settings_dsl: #{@key}"
|
26
|
+
puts e.message
|
27
|
+
raise
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def my_data
|
32
|
+
@data[@key]
|
33
|
+
end
|
34
|
+
|
35
|
+
# def run_decorators(opts)
|
36
|
+
# decorators = KDoc::Decorator.decorate.decorators(opts[:decorators])
|
37
|
+
|
38
|
+
# return if decorators.empty?
|
39
|
+
|
40
|
+
# decorators.each do |decorator|
|
41
|
+
# decorator.send(:update, my_data) if decorator.respond_to?(:update)
|
42
|
+
# decorator.send(:call, my_data) if decorator.respond_to?(:call)
|
43
|
+
# end
|
44
|
+
# end
|
45
|
+
|
46
|
+
def respond_to_missing?(name, *_args, &_block)
|
47
|
+
# puts 'respond_to_missing?'
|
48
|
+
# puts "respond_to_missing: #{name}"
|
49
|
+
n = name.to_s
|
50
|
+
n = n[0..-2] if n.end_with?('=')
|
51
|
+
my_data.key?(n.to_s) || (!@parent.nil? && @parent.respond_to?(name, true)) || super
|
52
|
+
end
|
53
|
+
|
54
|
+
# rubocop:disable Metrics/AbcSize
|
55
|
+
def method_missing(name, *args, &_block)
|
56
|
+
# puts "method_missing: #{name}"
|
57
|
+
# puts "args.length : #{args.length}"
|
58
|
+
|
59
|
+
if name != :type && !@parent.nil? && @parent.respond_to?(name)
|
60
|
+
puts "NAME: #{name}"
|
61
|
+
return @parent.public_send(name, *args, &block)
|
62
|
+
end
|
63
|
+
raise KDoc::Error, 'Multiple setting values is not supported' if args.length > 1
|
64
|
+
|
65
|
+
add_getter_or_param_method(name)
|
66
|
+
add_setter_method(name)
|
67
|
+
|
68
|
+
send(name, args[0]) if args.length == 1 # name.end_with?('=')
|
69
|
+
|
70
|
+
super unless self.class.method_defined?(name)
|
71
|
+
end
|
72
|
+
# rubocop:enable Metrics/AbcSize
|
73
|
+
|
74
|
+
# Handles Getter method and method with single parameter
|
75
|
+
# object.my_name
|
76
|
+
# object.my_name('david')
|
77
|
+
def add_getter_or_param_method(name)
|
78
|
+
# log.progress(1, 'add_getter_or_param_method')
|
79
|
+
self.class.class_eval do
|
80
|
+
# log.progress(2, 'add_getter_or_param_method')
|
81
|
+
name = name.to_s.gsub(/=$/, '')
|
82
|
+
# log.progress(3, 'add_getter_or_param_method')
|
83
|
+
define_method(name) do |*args|
|
84
|
+
# log.progress(4, 'add_getter_or_param_method')
|
85
|
+
# log.kv 'add_getter_or_param_method', name
|
86
|
+
raise KDoc::Error, 'Multiple setting values is not supported' if args.length > 1
|
87
|
+
|
88
|
+
if args.length.zero?
|
89
|
+
get_value(name)
|
90
|
+
else
|
91
|
+
send("#{name}=", args[0])
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# Handles Setter method
|
98
|
+
# object.my_name = 'david'
|
99
|
+
def add_setter_method(name)
|
100
|
+
# log.progress(1, 'add_setter_method')
|
101
|
+
self.class.class_eval do
|
102
|
+
# log.progress(2, 'add_setter_method')
|
103
|
+
name = name.to_s.gsub(/=$/, '')
|
104
|
+
# log.progress(3, 'add_setter_method')
|
105
|
+
# log.kv 'add_setter_method', name
|
106
|
+
define_method("#{name}=") do |value|
|
107
|
+
# log.progress(4, 'add_setter_method')
|
108
|
+
# log.kv 'value', value
|
109
|
+
my_data[name.to_s] = value
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def get_value(name)
|
115
|
+
my_data[name.to_s]
|
116
|
+
end
|
117
|
+
|
118
|
+
def debug
|
119
|
+
puts JSON.pretty_generate(my_data)
|
120
|
+
end
|
121
|
+
|
122
|
+
private
|
123
|
+
|
124
|
+
def initialize_attributes(data, key = nil, **options)
|
125
|
+
@data = data
|
126
|
+
@key = (key || FakeOpinion.new.default_settings_key).to_s
|
127
|
+
|
128
|
+
@parent = options[:parent] if !options.nil? && options.key?(:parent)
|
129
|
+
|
130
|
+
@data[@key] = {}
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
data/lib/k_doc/table.rb
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KDoc
|
4
|
+
# Build rows (aka DataTable) with field definitions and rows of data
|
5
|
+
class Table
|
6
|
+
attr_reader :parent
|
7
|
+
attr_reader :name
|
8
|
+
|
9
|
+
def initialize(data, name = nil, **options, &block)
|
10
|
+
initialize_attributes(data, name, **options)
|
11
|
+
|
12
|
+
instance_eval(&block) if block_given?
|
13
|
+
end
|
14
|
+
|
15
|
+
def fields(field_definitions)
|
16
|
+
fields = @data[@name]['fields']
|
17
|
+
|
18
|
+
field_definitions.each do |fd|
|
19
|
+
fields << if fd.is_a?(String) || fd.is_a?(Symbol)
|
20
|
+
field(fd, nil, :string)
|
21
|
+
else
|
22
|
+
fd
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# rubocop:disable Metrics/AbcSize
|
28
|
+
def row(*args, **named_args)
|
29
|
+
fields = @data[@name]['fields']
|
30
|
+
|
31
|
+
raise "To many values for row, argument #{i}" if args.length > fields.length
|
32
|
+
|
33
|
+
# Apply column names with defaults
|
34
|
+
row = fields.each_with_object({}) do |f, hash|
|
35
|
+
hash[f['name']] = f['default']
|
36
|
+
end
|
37
|
+
|
38
|
+
# Override with positional arguments
|
39
|
+
args.each_with_index do |arg, i|
|
40
|
+
row[fields[i]['name']] = KUtil.data.clean_symbol(arg)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Override with named args
|
44
|
+
named_args.each_key do |key|
|
45
|
+
row[key.to_s] = named_args[key]
|
46
|
+
end
|
47
|
+
|
48
|
+
@data[@name]['rows'] << row
|
49
|
+
row
|
50
|
+
end
|
51
|
+
# rubocop:enable Metrics/AbcSize
|
52
|
+
|
53
|
+
# rubocop:disable Naming/AccessorMethodName
|
54
|
+
def get_fields
|
55
|
+
@data[@name]['fields']
|
56
|
+
end
|
57
|
+
|
58
|
+
def get_rows
|
59
|
+
@data[@name]['rows']
|
60
|
+
end
|
61
|
+
# rubocop:enable Naming/AccessorMethodName
|
62
|
+
|
63
|
+
def find_row(key, value)
|
64
|
+
@data[@name]['rows'].find { |r| r[key] == value }
|
65
|
+
end
|
66
|
+
|
67
|
+
# Field definition
|
68
|
+
#
|
69
|
+
# @param [String|Symbol] name Name of the field
|
70
|
+
# @param args[0] Default value if not specified, nil if not set
|
71
|
+
# @param args[1] Type of data, string if not set
|
72
|
+
# @param default: Default value (using named params), as above
|
73
|
+
# @param type: Type of data (using named params), as above
|
74
|
+
# @return [Hash] Field definition
|
75
|
+
def field(name, *args, default: nil, type: nil)
|
76
|
+
# default value can be found at position 0 or default: tag (see unit test edge cases)
|
77
|
+
default_value = if args.length.positive?
|
78
|
+
args[0].nil? ? default : args[0]
|
79
|
+
else
|
80
|
+
default
|
81
|
+
end
|
82
|
+
|
83
|
+
# type can be found at position 1 or type: tag
|
84
|
+
type_value = (args.length > 1 ? args[1] : type) || :string
|
85
|
+
|
86
|
+
{
|
87
|
+
'name' => KUtil.data.clean_symbol(name),
|
88
|
+
'default' => KUtil.data.clean_symbol(default_value),
|
89
|
+
'type' => KUtil.data.clean_symbol(type_value)
|
90
|
+
}
|
91
|
+
end
|
92
|
+
alias f field
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def initialize_attributes(data, name = nil, **options)
|
97
|
+
@data = data
|
98
|
+
@name = (name || FakeOpinion.new.default_table_key.to_s).to_s
|
99
|
+
|
100
|
+
@parent = options[:parent] if !options.nil? && options.key?(:parent)
|
101
|
+
|
102
|
+
@data[@name] = { 'fields' => [], 'rows' => [] }
|
103
|
+
end
|
104
|
+
|
105
|
+
def respond_to_missing?(name, *_args, &_block)
|
106
|
+
(!@parent.nil? && @parent.respond_to?(name, true)) || super
|
107
|
+
end
|
108
|
+
|
109
|
+
def method_missing(name, *args, &block)
|
110
|
+
return super unless @parent.respond_to?(name)
|
111
|
+
|
112
|
+
@parent.public_send(name, *args, &block)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
data/lib/k_doc/util.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KDoc
|
4
|
+
# Utility helper methods for KDoc
|
5
|
+
class Util
|
6
|
+
def build_unique_key(key, type = nil, namespace = nil)
|
7
|
+
raise KDoc::Error, 'key is required when generating unique key' if key.nil? || key.empty?
|
8
|
+
|
9
|
+
type ||= KDoc.opinion.default_document_type
|
10
|
+
|
11
|
+
namespace.nil? || namespace.empty? ? "#{key}_#{type}" : "#{namespace}_#{key}_#{type}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/k_doc/version.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: k_doc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Cruwys
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
12
|
-
dependencies:
|
11
|
+
date: 2021-04-05 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: k_log
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.0.0
|
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.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: k_util
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.0.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.0.0
|
13
41
|
description: " KDoc provides a document in the form a DSL that contains flexible
|
14
42
|
key/value and tabular data\n"
|
15
43
|
email:
|
@@ -24,9 +52,12 @@ files:
|
|
24
52
|
- ".rubocop.yml"
|
25
53
|
- CODE_OF_CONDUCT.md
|
26
54
|
- Gemfile
|
55
|
+
- Guardfile
|
27
56
|
- LICENSE.txt
|
28
57
|
- README.md
|
29
58
|
- Rakefile
|
59
|
+
- STORIES.md
|
60
|
+
- USAGE.md
|
30
61
|
- bin/console
|
31
62
|
- bin/k
|
32
63
|
- bin/kgitsync
|
@@ -36,6 +67,11 @@ files:
|
|
36
67
|
- hooks/update-version
|
37
68
|
- k_doc.gemspec
|
38
69
|
- lib/k_doc.rb
|
70
|
+
- lib/k_doc/document.rb
|
71
|
+
- lib/k_doc/fake_opinion.rb
|
72
|
+
- lib/k_doc/settings.rb
|
73
|
+
- lib/k_doc/table.rb
|
74
|
+
- lib/k_doc/util.rb
|
39
75
|
- lib/k_doc/version.rb
|
40
76
|
homepage: http://appydave.com/gems/k-doc
|
41
77
|
licenses:
|