k_doc 0.0.8 → 0.0.15

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5f42e0aaa27cf50c5ee0fa56385d3cc492f7b8b01cb7abe9877300a785fa6313
4
- data.tar.gz: 27c280e4d65360589f0c52a95fc4f43c1dfc88ab60e20685502f9b18a7ab5de0
3
+ metadata.gz: 6b4d2d8600ef139ecfe4ebc33df2a6fec04f28d014b92dde485bd03c3f50fc9a
4
+ data.tar.gz: 6395ffd44207e6d247ca612a5af8c610856185e1d6dc8d4034cfb9f4be5104e7
5
5
  SHA512:
6
- metadata.gz: 7e40236d4c57ff7cdf5dfa782f2380c53cf8744b84253f18ba49c9a486be97b75f9d28396cfb07649ec7b8fc6d7b0f30967ceee65039d05b1c491ca97e552aca
7
- data.tar.gz: 6068509f1ec674f7a0d71a7ca7e919ee302d5b4805507ebf89efab4f92ede36074de4a5ce9749c266c56020fe86199618482818839219f66ec1281a0471b688b
6
+ metadata.gz: 6698d8bd459a9bc19ed6f3882258851a7779bf4be4eab13fed6cfd19870f2311b5f60ec618b1ddd6619e154c16da15f21f80bb4b4a5527d7e42d4ac71c254a02
7
+ data.tar.gz: d5bb18b0271b810a1f795537d6a9ae430dc8f7d82f940be5cfbb6c1dc28b7916c0d7f279ccd8f42be4d35f53a2822d6e43b2280dfc1e7fe8a2f2fe35b8d0f47c
data/CODE_OF_CONDUCT.md CHANGED
@@ -11,7 +11,7 @@ orientation.
11
11
 
12
12
  ## Our Standards
13
13
 
14
- Examples of behavior that contributes to creating a positive environment
14
+ Examples of behaviour that contributes to creating a positive environment
15
15
  include:
16
16
 
17
17
  - Using welcoming and inclusive language
@@ -20,7 +20,7 @@ include:
20
20
  - Focusing on what is best for the community
21
21
  - Showing empathy towards other community members
22
22
 
23
- Examples of unacceptable behavior by participants include:
23
+ Examples of unacceptable behaviour by participants include:
24
24
 
25
25
  - The use of sexualized language or imagery and unwelcome sexual attention or
26
26
  advances
@@ -34,13 +34,13 @@ Examples of unacceptable behavior by participants include:
34
34
  ## Our Responsibilities
35
35
 
36
36
  Project maintainers are responsible for clarifying the standards of acceptable
37
- behavior and are expected to take appropriate and fair corrective action in
38
- response to any instances of unacceptable behavior.
37
+ behaviour and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behaviour.
39
39
 
40
40
  Project maintainers have the right and responsibility to remove, edit, or
41
41
  reject comments, commits, code, wiki edits, issues, and other contributions
42
42
  that are not aligned to this Code of Conduct, or to ban temporarily or
43
- permanently any contributor for other behaviors that they deem inappropriate,
43
+ permanently any contributor for other behaviours that they deem inappropriate,
44
44
  threatening, offensive, or harmful.
45
45
 
46
46
  ## Scope
@@ -54,7 +54,7 @@ further defined and clarified by project maintainers.
54
54
 
55
55
  ## Enforcement
56
56
 
57
- Instances of abusive, harassing, or otherwise unacceptable behavior may be
57
+ Instances of abusive, harassing, or otherwise unacceptable behaviour may be
58
58
  reported by contacting the project team at david.cruwys@bugcrowd.com. All
59
59
  complaints will be reviewed and investigated and will result in a response that
60
60
  is deemed necessary and appropriate to the circumstances. The project team is
data/README.md CHANGED
@@ -68,10 +68,8 @@ Aaa::Bbb::Program.execute()
68
68
  To release a new version, update the version number in `version.rb`, build the gem and push the `.gem` file to [rubygems.org](https://rubygems.org).
69
69
 
70
70
  ```bash
71
- gem build
72
- gem push rspec-usecases-?.?.??.gem
73
- # or push the latest gem
74
- ls *.gem | sort -r | head -1 | xargs gem push
71
+ rake publish
72
+ rake clean
75
73
  ```
76
74
 
77
75
  ## Contributing
data/STORIES.md CHANGED
@@ -10,22 +10,27 @@ As a Developer, I need flexible data structures defined in DSL, so can model ric
10
10
 
11
11
  As a Developer, I need flexible data structures defined in DSL, so can model rich documents
12
12
 
13
- ### Tasks next on list
13
+ ## Stories and tasks
14
14
 
15
- Setup RubyGems and RubyDoc
15
+ ### Stories - completed
16
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)
17
+ As a Domain Modeler, I can define flexible tabular structures, so I can access dynamic tabular arrays
19
18
 
20
- Setup GitHub Action (test and lint)
19
+ - add DSL for table with columns and rows
20
+ - add support for data decorators
21
21
 
22
- - Setup Rspec action
23
- - Setup RuboCop action
22
+ As a Domain Modeler, I can define flexible key/value stores, so I can access settings data
24
23
 
25
- ## Stories and tasks
24
+ - add DSL for key/value settings
25
+ - add support for data decorators
26
26
 
27
27
  ### Tasks - completed
28
28
 
29
+ Setup RubyGems and RubyDoc
30
+
31
+ - Build and deploy gem to [rubygems.org](https://rubygems.org/gems/k_doc)
32
+ - Attach documentation to [rubydoc.info](https://rubydoc.info/github/to-do-/k_doc/master)
33
+
29
34
  Setup project management, requirement and SCRUM documents
30
35
 
31
36
  - Setup readme file
@@ -33,6 +38,11 @@ Setup project management, requirement and SCRUM documents
33
38
  - Setup a project backlog
34
39
  - Setup an examples/usage document
35
40
 
41
+ Setup GitHub Action (test and lint)
42
+
43
+ - Setup Rspec action
44
+ - Setup RuboCop action
45
+
36
46
  Setup new Ruby GEM
37
47
 
38
48
  - Build out a standard GEM structure
data/ToDo.md ADDED
@@ -0,0 +1,91 @@
1
+ # K Doc
2
+
3
+ > KDoc provides a document in the form a DSL that contains flexible key/value and tabular data
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'k_doc'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ ```bash
16
+ bundle install
17
+ ```
18
+
19
+ Or install it yourself as:
20
+
21
+ ```bash
22
+ gem install k_doc
23
+ ```
24
+
25
+ ## Stories
26
+
27
+ ### Main Story
28
+
29
+ As a Developer, I need flexible data structures defined in DSL, so can model rich documents
30
+
31
+ See all [stories](./STORIES.md)
32
+
33
+ ## Usage
34
+
35
+ See all [usage examples](./USAGE.md)
36
+
37
+ ### Basic Example
38
+
39
+ #### Basic example
40
+
41
+ Description for a basic example to be featured in the main README.MD file
42
+
43
+ ```ruby
44
+ class SomeRuby; end
45
+ ```
46
+
47
+ ## Development
48
+
49
+ Checkout the repo
50
+
51
+ ```bash
52
+ git clone klueless-io/k_doc
53
+ ```
54
+
55
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests.
56
+
57
+ You can also run `bin/console` for an interactive prompt that will allow you to experiment.
58
+
59
+ ```bash
60
+ bin/console
61
+
62
+ Aaa::Bbb::Program.execute()
63
+ # => ""
64
+ ```
65
+
66
+ `k_doc` is setup with Guard, run `guard`, this will watch development file changes and run tests automatically, if successful, it will then run rubocop for style quality.
67
+
68
+ To release a new version, update the version number in `version.rb`, build the gem and push the `.gem` file to [rubygems.org](https://rubygems.org).
69
+
70
+ ```bash
71
+ gem build
72
+ gem push rspec-usecases-?.?.??.gem
73
+ # or push the latest gem
74
+ ls *.gem | sort -r | head -1 | xargs gem push
75
+ ```
76
+
77
+ ## Contributing
78
+
79
+ Bug reports and pull requests are welcome on GitHub at https://github.com/klueless-io/k_doc. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
80
+
81
+ ## License
82
+
83
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
84
+
85
+ ## Code of Conduct
86
+
87
+ Everyone interacting in the K Doc project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/klueless-io/k_doc/blob/master/CODE_OF_CONDUCT.md).
88
+
89
+ ## Copyright
90
+
91
+ Copyright (c) David Cruwys. See [MIT License](LICENSE.txt) for further details.
data/k_doc.gemspec CHANGED
@@ -38,7 +38,10 @@ Gem::Specification.new do |spec|
38
38
  spec.require_paths = ['lib']
39
39
  # spec.extensions = ['ext/k_doc/extconf.rb']
40
40
 
41
+ spec.add_dependency 'activesupport' , '~> 6'
42
+ spec.add_dependency 'k_decor' , '~> 0.0.0'
41
43
  spec.add_dependency 'k_log' , '~> 0.0.0'
44
+ spec.add_dependency 'k_type' , '~> 0.0.0'
42
45
  spec.add_dependency 'k_util' , '~> 0.0.0'
43
46
  # spec.add_dependency 'tty-box', '~> 0.5.0'
44
47
  end
data/lib/k_doc.rb CHANGED
@@ -2,31 +2,34 @@
2
2
 
3
3
  require 'securerandom'
4
4
 
5
- require 'logger'
6
5
  require 'table_print'
7
6
  require 'k_log'
7
+ require 'k_type'
8
8
  require 'k_util'
9
- require 'k_log/log_formatter'
10
- require 'k_log/log_helper'
11
- require 'k_log/log_util'
9
+ require 'k_decor'
12
10
 
13
11
  require 'k_doc/version'
14
- require 'k_doc/document'
12
+ require 'k_doc/container'
13
+ # require 'k_doc/data'
14
+ require 'k_doc/model'
15
15
  require 'k_doc/fake_opinion'
16
16
  require 'k_doc/settings'
17
17
  require 'k_doc/table'
18
18
  require 'k_doc/util'
19
19
 
20
+ require 'k_doc/decorators/settings_decorator'
21
+ require 'k_doc/decorators/table_decorator'
22
+
20
23
  module KDoc
21
24
  # raise KDoc::Error, 'Sample message'
22
25
  class Error < StandardError; end
23
26
 
24
27
  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
28
+ # Factory method to create a new model
29
+ def model(key = nil, **options, &block)
30
+ model = KDoc::Model.new(key, **options, &block)
31
+ model.execute_block
32
+ model
30
33
  end
31
34
 
32
35
  attr_accessor :opinion
@@ -42,5 +45,5 @@ if ENV['KLUE_DEBUG']&.to_s&.downcase == 'true'
42
45
  namespace = 'KDoc::Version'
43
46
  file_path = $LOADED_FEATURES.find { |f| f.include?('k_doc/version') }
44
47
  version = KDoc::VERSION.ljust(9)
45
- puts "#{namespace.ljust(40)} : #{version.ljust(9)} : #{file_path}"
48
+ puts "#{namespace.ljust(35)} : #{version.ljust(9)} : #{file_path}"
46
49
  end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KDoc
4
+ # A data acts a base data object for any data requires tagging such as
5
+ # unique key, type and namespace.
6
+ class Container
7
+ # include KLog::Logging
8
+
9
+ # Seems like there is way too much data here
10
+ # Firstly it should probably be in an interface
11
+ # Secondly some of this (namespace, project_key, error) belongs in k_manager
12
+ # So container would be better off just being key, type, data
13
+ attr_reader :key
14
+
15
+ # NOTE: This should not be using an opinion in this project
16
+ attr_reader :type
17
+
18
+ # Move this up to k_manager
19
+ # attr_reader :namespace
20
+ # attr_reader :project_key
21
+ attr_reader :error
22
+
23
+ # Create container for storing data/documents.
24
+ #
25
+ # Any container can be uniquely identified via it's
26
+ # key, type, namespace and project_key attributes
27
+ #
28
+ # @param [Hash] **opts The options
29
+ # @option opts [String|Symbol] name Name of the container
30
+ # @option opts [String|Symbol] type Type of the container, defaults to KDoc:: FakeOpinion.new.default_document_type if not set
31
+ # @option opts [String|Symbol] namespace Namespace that the container belongs to
32
+ # @option opts [String|Symbol] project_key Project that the container belongs to
33
+ def initialize(**opts)
34
+ @key = opts[:key] || SecureRandom.alphanumeric(4)
35
+ @type = opts[:type] || '' # KDoc.opinion.default_document_type
36
+ # @namespace = opts[:namespace] || ''
37
+ # @project_key = opts[:project_key] || ''
38
+
39
+ # Old name is default_data, wonder if I still need that idea?
40
+ # Most documents live within a hash, some tabular documents such as CSV will use an []
41
+ # @data = slice_option(:default_data) || {}
42
+ @data = opts[:data] || {}
43
+ end
44
+
45
+ # def unique_key
46
+ # @unique_key ||= KDoc.util.build_unique_key(key, type, namespace, project_key)
47
+ # end
48
+
49
+ def debug_header
50
+ log.kv 'key', key
51
+ log.kv 'type', type
52
+ # log.kv 'namespace', namespace
53
+ # log.kv 'project_key', namespace
54
+ # log.kv 'error', error
55
+ end
56
+
57
+ attr_writer :data
58
+
59
+ def data
60
+ @data.clone
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This could move into KDecor
4
+ module KDoc
5
+ module Decorators
6
+ class SettingsDecorator < KDecor::BaseDecorator
7
+ def initialize
8
+ super(KDoc::Settings)
9
+ end
10
+
11
+ # def update(target, behaviour)
12
+ # update_settings(target, target.internal_data) if %i[all default].include?(behaviour)
13
+
14
+ # target
15
+ # end
16
+
17
+ # # What responsibility will this SettingsDecorator take on?
18
+ # def update(target, **_opts)
19
+ # def update_settings(_target, _settings)
20
+ # log.warn('Override this method in your descendant implementation')
21
+ # end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KDoc
4
+ module Decorators
5
+ class TableDecorator < KDecor::BaseDecorator
6
+ def initialize
7
+ super(KDoc::Table)
8
+
9
+ self.implemented_behaviours = %i[update_fields update_rows]
10
+ end
11
+
12
+ def update(target, **opts)
13
+ behaviour = opts[:behaviour]
14
+
15
+ update_fields(target, target.get_fields) if %i[all update_fields].include?(behaviour)
16
+ update_rows(target, target.get_rows) if %i[all update_rows].include?(behaviour)
17
+
18
+ target
19
+ end
20
+
21
+ # What responsibility will this TableDecorator take on?
22
+ # Update fields/columns, or/and
23
+ def update_fields(_target, _fields)
24
+ raise KType::Error, 'Update fields not implement, you need to implement this method and '
25
+ end
26
+
27
+ # Update row values/structure
28
+ def update_rows(_target, _rows); end
29
+ end
30
+ end
31
+ end
@@ -10,7 +10,7 @@ module KDoc
10
10
  attr_accessor :default_settings_key
11
11
  attr_accessor :default_table_key
12
12
 
13
- attr_accessor :document_class
13
+ # attr_accessor :document_class
14
14
  attr_accessor :settings_class
15
15
  attr_accessor :table_class
16
16
 
@@ -19,7 +19,7 @@ module KDoc
19
19
  @default_settings_key = :settings
20
20
  @default_table_key = :table
21
21
 
22
- @document_class = KDoc::Document
22
+ # @document_class = KDoc::Document
23
23
  @table_class = KDoc::Table
24
24
  @settings_class = KDoc::Settings
25
25
  end
@@ -1,10 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module KDoc
4
- # General purpose document DSL
4
+ # Model is a DSL for modeling general purpose data objects
5
5
  #
6
- # Made up of 0 or more setting groups and table groups
7
- class Document
6
+ # A mode can have
7
+ # - 0 or more named setting groups each with their key/value pairs
8
+ # - 0 or more named table groups each with their own columns and rows
9
+ #
10
+ # A settings group without a name will default to name: :settings
11
+ # A table group without a name will default to name: :table
12
+ class Model < KDoc::Container
8
13
  include KLog::Logging
9
14
 
10
15
  # include KType::Error
@@ -12,23 +17,21 @@ module KDoc
12
17
  # include KType::NamedFolder
13
18
  # include KType::LayeredFolder
14
19
 
15
- attr_reader :key
16
- attr_reader :type
17
- attr_reader :namespace
18
20
  attr_reader :options
19
- attr_reader :error
20
21
 
21
22
  # Create document
22
23
  #
23
24
  # @param [String|Symbol] name Name of the document
24
25
  # @param args[0] Type of the document, defaults to KDoc:: FakeOpinion.new.default_document_type if not set
25
26
  # @param default: Default value (using named params), as above
26
- def initialize(key = SecureRandom.alphanumeric(8), **options, &block)
27
- initialize_attributes(key, **options)
27
+ def initialize(key = nil, **options, &block)
28
+ super(key: key, type: options[:type], namespace: options[:namespace], project_key: options[:project_key])
29
+ initialize_attributes(**options)
28
30
 
29
31
  @block = block if block_given?
30
32
  end
31
33
 
34
+ # NOTE: Can this be moved out of the is object?
32
35
  def execute_block(run_actions: nil)
33
36
  return if @block.nil?
34
37
 
@@ -57,14 +60,15 @@ module KDoc
57
60
  @run_actions = nil
58
61
  end
59
62
 
60
- def unique_key
61
- @unique_key ||= KDoc.util.build_unique_key(key, type, namespace)
62
- end
63
+ # Move this up to k_manager
64
+ # def unique_key
65
+ # @unique_key ||= KDoc.util.build_unique_key(key, type, namespace)
66
+ # end
63
67
 
64
68
  def settings(key = nil, **options, &block)
65
69
  options ||= {}
66
70
 
67
- opts = {}.merge(@options) # Document Options
71
+ opts = {}.merge(@options) # Data Options
68
72
  .merge(options) # Settings Options
69
73
  .merge(parent: self)
70
74
 
@@ -85,14 +89,6 @@ module KDoc
85
89
  # KDoc::Builder::Shotstack.new(@data, key, &block)
86
90
  # end
87
91
 
88
- # def set_data(data)
89
- # @data = data
90
- # end
91
-
92
- def data
93
- @data.clone
94
- end
95
-
96
92
  def data_struct
97
93
  KUtil.data.to_open_struct(data)
98
94
  end
@@ -116,6 +112,7 @@ module KDoc
116
112
  end
117
113
 
118
114
  # Removes any meta data eg. "fields" from a table and just returns the raw data
115
+ # REFACTOR: IT MAY BE BEST TO MOVE raw_data into each of the node_types
119
116
  def raw_data
120
117
  # REFACT, what if this is CSV, meaning it is just an array?
121
118
  # add specs
@@ -145,19 +142,17 @@ module KDoc
145
142
  log.o(raw_data_struct)
146
143
  end
147
144
 
148
- # rubocop:disable Metrics/AbcSize
149
145
  def debug_header
150
146
  log.heading self.class.name
151
147
  log.kv 'key', key
152
148
  log.kv 'type', type
153
- log.kv 'namespace', namespace
149
+ # log.kv 'namespace', namespace
154
150
  log.kv 'error', error
155
151
 
156
152
  debug_header_keys
157
153
 
158
154
  log.line
159
155
  end
160
- # rubocop:enable Metrics/AbcSize
161
156
 
162
157
  def debug_header_keys
163
158
  options&.keys&.reject { |k| k == :namespace }&.each do |key|
@@ -167,18 +162,12 @@ module KDoc
167
162
 
168
163
  private
169
164
 
170
- def initialize_attributes(key = nil, **options)
171
- @key = key
172
-
165
+ def initialize_attributes(**options)
173
166
  @options = options || {}
174
- @type = slice_option(:type) || KDoc.opinion.default_document_type
175
- @namespace = slice_option(:namespace) || ''
176
167
  @parent = slice_option(:parent)
177
168
 
178
169
  # Most documents live within a hash, some tabular documents such as CSV will use an []
179
170
  @data = slice_option(:default_data) || {}
180
-
181
- @error = nil
182
171
  end
183
172
 
184
173
  def settings_instance(data, key, **options, &block)
@@ -7,9 +7,11 @@ module KDoc
7
7
  # and applies them to a key coded node on the hash
8
8
  class Settings
9
9
  include KLog::Logging
10
+ # include KDoc::Decorators
10
11
 
11
12
  attr_reader :parent
12
13
  attr_reader :key
14
+ attr_reader :decorators
13
15
 
14
16
  alias kp parent
15
17
 
@@ -19,6 +21,9 @@ module KDoc
19
21
  # Need a way to find out the line number for errors and report it correctly
20
22
  begin
21
23
  instance_eval(&block) if block_given?
24
+
25
+ run_decorators
26
+
22
27
  # rubocop:disable Style/RescueStandardError
23
28
  rescue => e
24
29
  # rubocop:enable Style/RescueStandardError
@@ -28,27 +33,19 @@ module KDoc
28
33
  end
29
34
  end
30
35
 
31
- def my_data
36
+ # Return these settings which are attached to a data container using :key
37
+ # internal_data is a bad name, but it is unlikely to interfere with any setting names
38
+ # Maybe I rename this to raw_data
39
+ def internal_data
32
40
  @data[@key]
33
41
  end
34
42
 
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
43
  def respond_to_missing?(name, *_args, &_block)
47
44
  # puts 'respond_to_missing?'
48
45
  # puts "respond_to_missing: #{name}"
49
46
  n = name.to_s
50
47
  n = n[0..-2] if n.end_with?('=')
51
- my_data.key?(n.to_s) || (!@parent.nil? && @parent.respond_to?(name, true)) || super
48
+ internal_data.key?(n.to_s) || (!@parent.nil? && @parent.respond_to?(name, true)) || super
52
49
  end
53
50
 
54
51
  # rubocop:disable Metrics/AbcSize
@@ -106,26 +103,39 @@ module KDoc
106
103
  define_method("#{name}=") do |value|
107
104
  # log.progress(4, 'add_setter_method')
108
105
  # log.kv 'value', value
109
- my_data[name.to_s] = value
106
+ internal_data[name.to_s] = value
110
107
  end
111
108
  end
112
109
  end
113
110
 
114
111
  def get_value(name)
115
- my_data[name.to_s]
112
+ internal_data[name.to_s]
116
113
  end
117
114
 
118
115
  def debug
119
- puts JSON.pretty_generate(my_data)
116
+ puts JSON.pretty_generate(internal_data)
120
117
  end
121
118
 
122
119
  private
123
120
 
121
+ # This method can move into decorator helpers
122
+ def run_decorators
123
+ decorators.each { |decorator| decorator.decorate(self, :settings) }
124
+ end
125
+
124
126
  def initialize_attributes(data, key = nil, **options)
125
127
  @data = data
126
128
  @key = (key || FakeOpinion.new.default_settings_key).to_s
127
129
 
128
- @parent = options[:parent] if !options.nil? && options.key?(:parent)
130
+ @parent = options[:parent] if options.key?(:parent)
131
+
132
+ decorator_list = options[:decorators].nil? ? [] : options[:decorators]
133
+
134
+ # This code needs to work differently, it needs to support the 3 different types
135
+ # Move the query into helpers
136
+ @decorators = decorator_list
137
+ .map(&:new)
138
+ .select { |decorator| decorator.compatible?(self) }
129
139
 
130
140
  @data[@key] = {}
131
141
  end
data/lib/k_doc/table.rb CHANGED
@@ -3,16 +3,33 @@
3
3
  module KDoc
4
4
  # Build rows (aka DataTable) with field definitions and rows of data
5
5
  class Table
6
+ include KLog::Logging
7
+
6
8
  attr_reader :parent
7
9
  attr_reader :name
10
+ attr_reader :decorators
8
11
 
9
12
  def initialize(data, name = nil, **options, &block)
10
13
  initialize_attributes(data, name, **options)
11
14
 
15
+ @has_executed_field_decorators = false
16
+ @has_executed_row_decorators = false
17
+
12
18
  instance_eval(&block) if block_given?
19
+
20
+ run_decorators(:update_rows)
13
21
  end
14
22
 
15
- def fields(field_definitions)
23
+ # Pass fields in using the following format
24
+ # fields :name, f(:type, :string), :db_type
25
+ #
26
+ # The older format of an array is supported via a splat conversion
27
+ def fields(*field_definitions)
28
+ if field_definitions.length == 1 && field_definitions[0].is_a?(Array)
29
+ log.warn('avoid supplying field definitions with array. *Splat fields is the preferred technique.')
30
+ field_definitions = *field_definitions[0]
31
+ end
32
+
16
33
  fields = @data[@name]['fields']
17
34
 
18
35
  field_definitions.each do |fd|
@@ -22,15 +39,18 @@ module KDoc
22
39
  fd
23
40
  end
24
41
  end
42
+
43
+ run_decorators(:update_fields)
25
44
  end
26
45
 
27
46
  # rubocop:disable Metrics/AbcSize
28
47
  def row(*args, **named_args)
29
48
  fields = @data[@name]['fields']
30
49
 
31
- raise "To many values for row, argument #{i}" if args.length > fields.length
50
+ raise KType::Error, "To many values for row, argument #{args.length}" if args.length > fields.length
32
51
 
33
52
  # Apply column names with defaults
53
+
34
54
  row = fields.each_with_object({}) do |f, hash|
35
55
  hash[f['name']] = f['default']
36
56
  end
@@ -60,6 +80,10 @@ module KDoc
60
80
  end
61
81
  # rubocop:enable Naming/AccessorMethodName
62
82
 
83
+ def internal_data
84
+ @data[@name]
85
+ end
86
+
63
87
  def find_row(key, value)
64
88
  @data[@name]['rows'].find { |r| r[key] == value }
65
89
  end
@@ -91,16 +115,45 @@ module KDoc
91
115
  end
92
116
  alias f field
93
117
 
118
+ def debug
119
+ log.o(KUtil.data.to_open_struct(internal_data))
120
+ end
121
+
94
122
  private
95
123
 
124
+ # This method can move into decorator helpers
125
+ # Run decorators a maximum of once for each behaviour
126
+ # rubocop:disable Metrics/CyclomaticComplexity
127
+ def run_decorators(behaviour)
128
+ return if behaviour == :update_fields && @has_executed_field_decorators
129
+ return if behaviour == :update_rows && @has_executed_row_decorators
130
+
131
+ @has_executed_field_decorators = true if behaviour == :update_fields
132
+
133
+ @has_executed_rows_decorators = true if behaviour == :update_rows
134
+
135
+ decorators.each { |decorator| decorator.decorate(self, behaviour) }
136
+ end
137
+ # rubocop:enable Metrics/CyclomaticComplexity
138
+
139
+ # rubocop:disable Metrics/AbcSize
96
140
  def initialize_attributes(data, name = nil, **options)
97
141
  @data = data
98
142
  @name = (name || FakeOpinion.new.default_table_key.to_s).to_s
99
143
 
100
144
  @parent = options[:parent] if !options.nil? && options.key?(:parent)
101
145
 
146
+ # This code needs to work differently, it needs to support the 3 different types
147
+ # Move the query into helpers
148
+ decorator_list = options[:decorators].nil? ? [] : options[:decorators]
149
+
150
+ @decorators = decorator_list
151
+ .map(&:new)
152
+ .select { |decorator| decorator.compatible?(self) }
153
+
102
154
  @data[@name] = { 'fields' => [], 'rows' => [] }
103
155
  end
156
+ # rubocop:enable Metrics/AbcSize
104
157
 
105
158
  def respond_to_missing?(name, *_args, &_block)
106
159
  (!@parent.nil? && @parent.respond_to?(name, true)) || super
data/lib/k_doc/util.rb CHANGED
@@ -3,12 +3,18 @@
3
3
  module KDoc
4
4
  # Utility helper methods for KDoc
5
5
  class Util
6
- def build_unique_key(key, type = nil, namespace = nil)
6
+ # Build a unique key so that resources of the same key do not conflict with
7
+ # one another across projects, namespaces or types
8
+ #
9
+ # @param [String] param_name Param description
10
+ def build_unique_key(key, type = nil, namespace = nil, project_key = nil)
7
11
  raise KDoc::Error, 'key is required when generating unique key' if key.nil? || key.empty?
8
12
 
9
13
  type ||= KDoc.opinion.default_document_type
10
14
 
11
- namespace.nil? || namespace.empty? ? "#{key}_#{type}" : "#{namespace}_#{key}_#{type}"
15
+ keys = [project_key, namespace, key, type].reject { |k| k.nil? || k == '' }.map { |k| k.to_s.gsub('_', '-') }
16
+
17
+ keys.join('-')
12
18
  end
13
19
  end
14
20
  end
data/lib/k_doc/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module KDoc
4
- VERSION = '0.0.8'
4
+ VERSION = '0.0.15'
5
5
  end
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.8
4
+ version: 0.0.15
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-04-05 00:00:00.000000000 Z
11
+ date: 2021-04-24 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '6'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: k_decor
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
  - !ruby/object:Gem::Dependency
14
42
  name: k_log
15
43
  requirement: !ruby/object:Gem::Requirement
@@ -24,6 +52,20 @@ dependencies:
24
52
  - - "~>"
25
53
  - !ruby/object:Gem::Version
26
54
  version: 0.0.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: k_type
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.0.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.0.0
27
69
  - !ruby/object:Gem::Dependency
28
70
  name: k_util
29
71
  requirement: !ruby/object:Gem::Requirement
@@ -57,6 +99,7 @@ files:
57
99
  - README.md
58
100
  - Rakefile
59
101
  - STORIES.md
102
+ - ToDo.md
60
103
  - USAGE.md
61
104
  - bin/console
62
105
  - bin/k
@@ -67,8 +110,11 @@ files:
67
110
  - hooks/update-version
68
111
  - k_doc.gemspec
69
112
  - lib/k_doc.rb
70
- - lib/k_doc/document.rb
113
+ - lib/k_doc/container.rb
114
+ - lib/k_doc/decorators/settings_decorator.rb
115
+ - lib/k_doc/decorators/table_decorator.rb
71
116
  - lib/k_doc/fake_opinion.rb
117
+ - lib/k_doc/model.rb
72
118
  - lib/k_doc/settings.rb
73
119
  - lib/k_doc/table.rb
74
120
  - lib/k_doc/util.rb