clerq 0.1.0 → 0.3.3

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.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -3
  3. data/CHANGELOG.md +49 -0
  4. data/Gemfile.lock +9 -9
  5. data/README.md +260 -133
  6. data/Rakefile +1 -0
  7. data/clerq.gemspec +6 -6
  8. data/clerq.thor +28 -0
  9. data/docs/README.md +408 -0
  10. data/lib/assets/knb/SRS-IEEE-830-1998.md +293 -0
  11. data/lib/assets/knb/SRS-RUP.md +283 -0
  12. data/lib/assets/knb/business-case.md +135 -0
  13. data/lib/assets/knb/ears-with-examples.md +101 -0
  14. data/lib/assets/knb/problem-statement.md +8 -0
  15. data/lib/assets/knb/product-statement.md +8 -0
  16. data/lib/assets/knb/requirement-attributes.md +26 -0
  17. data/lib/assets/knb/requirement-classification.md +27 -0
  18. data/lib/assets/knb/requirement-life-cycle.md +47 -0
  19. data/lib/assets/knb/requirement-quality.md +13 -0
  20. data/lib/assets/knb/use-case.md +39 -0
  21. data/lib/assets/knb/vision-document.md +191 -0
  22. data/lib/assets/lib/clerq_doc.thor +119 -0
  23. data/lib/assets/lib/colonize_repo.rb +82 -0
  24. data/lib/assets/lib/spec/colonize_repo_spec.rb +85 -0
  25. data/lib/assets/new/clerq.thor.tt +32 -5
  26. data/lib/assets/new/content.md.tt +3 -40
  27. data/lib/assets/tt/default.md.erb +23 -42
  28. data/lib/assets/tt/pandoc.md.erb +11 -8
  29. data/lib/clerq.rb +57 -12
  30. data/lib/clerq/cli.rb +77 -60
  31. data/lib/clerq/entities.rb +0 -1
  32. data/lib/clerq/entities/node.rb +135 -115
  33. data/lib/clerq/properties.rb +1 -3
  34. data/lib/clerq/repositories.rb +2 -4
  35. data/lib/clerq/repositories/file_repository.rb +59 -0
  36. data/lib/clerq/repositories/node_repository.rb +72 -30
  37. data/lib/clerq/repositories/text_repository.rb +47 -0
  38. data/lib/clerq/services.rb +8 -0
  39. data/lib/clerq/services/check_assembly.rb +108 -0
  40. data/lib/clerq/{interactors → services}/create_node.rb +12 -11
  41. data/lib/clerq/services/load_assembly.rb +54 -0
  42. data/lib/clerq/services/query_node.rb +72 -0
  43. data/lib/clerq/services/query_template.rb +26 -0
  44. data/lib/clerq/services/read_node.rb +101 -0
  45. data/lib/clerq/services/render_erb.rb +29 -0
  46. data/lib/clerq/services/render_node.rb +37 -0
  47. data/lib/clerq/services/service.rb +19 -0
  48. data/lib/clerq/settings.rb +2 -2
  49. data/lib/clerq/version.rb +1 -1
  50. metadata +49 -37
  51. data/TODO.md +0 -3
  52. data/lib/assets/tt/gitlab.md.erb +0 -93
  53. data/lib/assets/tt/raw.md.erb +0 -23
  54. data/lib/clerq/entities/template.rb +0 -19
  55. data/lib/clerq/gateways.rb +0 -3
  56. data/lib/clerq/gateways/gateway.rb +0 -17
  57. data/lib/clerq/gateways/in_files.rb +0 -36
  58. data/lib/clerq/gateways/in_memory.rb +0 -35
  59. data/lib/clerq/interactors.rb +0 -5
  60. data/lib/clerq/interactors/check_nodes.rb +0 -81
  61. data/lib/clerq/interactors/compile_nodes.rb +0 -31
  62. data/lib/clerq/interactors/interactor.rb +0 -28
  63. data/lib/clerq/interactors/join_nodes.rb +0 -59
  64. data/lib/clerq/interactors/query_nodes.rb +0 -62
  65. data/lib/clerq/repositories/in_memory.rb +0 -45
  66. data/lib/clerq/repositories/node_reader.rb +0 -107
  67. data/lib/clerq/repositories/repository.rb +0 -11
  68. data/lib/clerq/repositories/template_repository.rb +0 -53
  69. data/lib/clerq/templater.rb +0 -32
data/TODO.md DELETED
@@ -1,3 +0,0 @@
1
- % TODO
2
-
3
- [ ] Fix minitest "DEPRECATE" warning
@@ -1,93 +0,0 @@
1
- <%
2
- require 'delegate'
3
- # Template for generate documents by Pandoc
4
- class MarkupNode < SimpleDelegator
5
- def title
6
- [].tap do |ary|
7
- ary << '#' * (nesting_level + 1)
8
- ary << '[' + id + ']' unless __getobj__.meta[:skip_meta]
9
- ary << super
10
- end.join(' ')
11
- end
12
-
13
- def meta
14
- return '' if nesting_level == 0
15
- return '' if super[:skip_meta]
16
-
17
- hsh = {}.merge(super)
18
- hsh.delete(:order_index)
19
- hsh.delete(:file_name)
20
- hsh.delete(:parent)
21
- return '' if hsh.empty?
22
-
23
- [].tap{|ary|
24
- ary << "Attribute | Value"
25
- ary << "--------- | -----"
26
- hsh.each{|k,v| ary << "#{k} | #{v}"}
27
- }.join("\n")
28
- end
29
-
30
- def body
31
- # links replacement
32
- txt = String.new(super)
33
- links.each{|l| txt.gsub! "[[#{l}]]", link(l)}
34
- # macro substitution
35
- macro.each{|m| txt.gsub! m.regex, m.substitution}
36
- txt
37
- end
38
-
39
- def link(ref)
40
- node = root.find{|n| n.id == ref}
41
- return "[#{ref}](#unknown)" unless node
42
- "[#{node.title}](##{url(node.title)})"
43
- end
44
-
45
- def url(id)
46
- id.downcase
47
- .gsub(/[^A-Za-z0-9]{1,}/, '-')
48
- .gsub(/^-/, '')
49
- .gsub(/-$/, '')
50
- end
51
-
52
- class Macro
53
- attr_reader :regex
54
- def initialize(regex, &substitution)
55
- @regex, @substitution = regex, substitution
56
- end
57
-
58
- def substitution
59
- @substitution.call()
60
- end
61
- end
62
-
63
- def macro
64
- [].tap do |ary|
65
- ary << Macro.new(/{{@@skip[\s\S]*?}}/, &Proc.new{ '' })
66
- ary << Macro.new("{{@@list}}", &Proc.new{list})
67
- ary << Macro.new("{{@@tree}}", &Proc.new{tree})
68
- end
69
- end
70
-
71
- def tree
72
- this_level = nesting_level + 1
73
- to_a.drop(1).inject([]) do |ary, n|
74
- lead_spaces = ' ' * (n.nesting_level - this_level)
75
- ary << "#{lead_spaces}* [#{n.title}](##{url(n.id)})"
76
- end.join("\n")
77
- end
78
-
79
- def list
80
- items.inject([]) do |ary, n|
81
- ary << "* [#{n.title}](##{url(n.id)})"
82
- end.join("\n")
83
- end
84
- end
85
- -%>
86
- % <%= @object.title %>
87
- % generated by Clerq on <%= Time.now.strftime('%B %e, %Y at %H:%M') %>
88
-
89
- <% for @node in @object.to_a.drop(1) -%>
90
- <% n = MarkupNode.new(@node) -%>
91
- <%= [n.title, n.meta, n.body].select{|t| !t.empty?}.join("\n\n") %>
92
-
93
- <% end %>
@@ -1,23 +0,0 @@
1
- <%
2
- # template for saving created nodes
3
- require 'delegate'
4
- class MarkupNode < SimpleDelegator
5
- def title
6
- '#' * (nesting_level + 1) + ' [' + id + '] ' + super
7
- end
8
-
9
- def meta
10
- return '' if super.empty?
11
- [].tap{|ary|
12
- ary << '{{'
13
- hsh.each{|k,v| ary << "#{k}: #{v}"}
14
- ary << '}}'
15
- }.join("\n")
16
- end
17
- end
18
- -%>
19
- <% for @node in @object.to_a.drop(1) -%>
20
- <% n = MarkupNode.new(@node) -%>
21
- <%= [n.title, n.meta, n.body].select{|t| !t.empty?}.join("\n\n") %>
22
-
23
- <% end %>
@@ -1,19 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- module Clerq
4
- module Entities
5
-
6
- class Template
7
- attr_reader :id
8
- attr_reader :body
9
-
10
- def initialize(id:, body: '')
11
- raise ArgumentError, "Invalid argument :id" if !(id.is_a?(String) && !id.empty?)
12
- raise ArgumentError, "Invalid argument :body" unless body.is_a? String
13
- @id = id
14
- @body = body
15
- end
16
- end
17
-
18
- end
19
- end
@@ -1,3 +0,0 @@
1
- require_relative 'gateways/gateway'
2
- require_relative 'gateways/in_memory'
3
- require_relative 'gateways/in_files'
@@ -1,17 +0,0 @@
1
- module Clerq
2
- module Gateways
3
-
4
- class Gateway
5
- # @return [Array<Node>]
6
- def nodes; end
7
-
8
- # @return [Array<Template>]
9
- def templates; end
10
-
11
- # @param obj [Node or Template]
12
- def save(obj); end
13
-
14
- end
15
-
16
- end
17
- end
@@ -1,36 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require "forwardable"
4
- require_relative '../repositories'
5
- require_relative 'gateway'
6
-
7
- module Clerq
8
- module Gateways
9
-
10
- class InFiles < Gateway
11
- extend Forwardable
12
-
13
- attr_reader :node_repo, :tplt_repo
14
-
15
- def_delegator :@node_repo, :items, :nodes
16
- def_delegator :@tplt_repo, :items, :templates
17
-
18
- def initialize
19
- settings = Clerq.settings
20
- @node_repo = Clerq::Repositories::NodeRepository.new(settings.src)
21
- @tplt_repo = Clerq::Repositories::TemplateRepository.new(settings.tt)
22
- @repositories = {}
23
- @repositories[Clerq::Entities::Node] = @node_repo
24
- @repositories[Clerq::Entities::Template] = @tplt_repo
25
- end
26
-
27
- def save(obj)
28
- repo = @repositories[obj.class]
29
- raise ArgumentError, "Repository for #{obj.class} not found" unless repo
30
- repo.save(obj)
31
- end
32
-
33
- end
34
-
35
- end
36
- end
@@ -1,35 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require "forwardable"
4
- require_relative "gateway"
5
- require_relative "../repositories/in_memory"
6
-
7
- module Clerq
8
- module Gateways
9
-
10
- class InMemory < Gateway
11
- extend Forwardable
12
-
13
- attr_reader :node_repo, :template_repo
14
-
15
- def_delegator :@node_repo, :items, :nodes
16
- def_delegator :@template_repo, :items, :templates
17
-
18
- def initialize
19
- @node_repo = Clerq::Repositories::InMemory.new
20
- @template_repo = Clerq::Repositories::InMemory.new
21
- @repositories = {}
22
- @repositories[Clerq::Entities::Node] = @node_repo
23
- @repositories[Clerq::Entities::Template] = @template_repo
24
- end
25
-
26
- def save(obj)
27
- repo = @repositories[obj.class]
28
- raise ArgumentError, "Repository for #{obj.class} not found" unless repo
29
- repo.save(obj)
30
- end
31
-
32
- end
33
-
34
- end
35
- end
@@ -1,5 +0,0 @@
1
- require_relative "interactors/join_nodes"
2
- require_relative "interactors/query_nodes"
3
- require_relative "interactors/check_nodes"
4
- require_relative "interactors/create_node"
5
- require_relative "interactors/compile_nodes"
@@ -1,81 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require_relative "interactor"
4
- require_relative "join_nodes"
5
-
6
- module Clerq
7
- module Interactors
8
-
9
- # TODO: maybe it needs QueryNodes instead of JoinNodes?
10
- # TODO: add check for empty node content - @items.empty && @body.empty?
11
- class CheckNodes < Interactor
12
-
13
- def call
14
- # TODO: query parameter for each interactor
15
- @node = JoinNodes.()
16
- {}.tap do |errors|
17
- nonuniq = nonuniq_ids
18
- errors.merge!(nonuniq_ids: nonuniq) unless nonuniq.empty?
19
- parents = unknown_parents
20
- errors.merge!(unknown_parents: parents) unless parents.empty?
21
- references = unknown_references
22
- errors.merge!(unknown_references: references) unless references.empty?
23
- order = unknown_order_index
24
- errors.merge!(unknown_order_index: order) unless order.empty?
25
- end
26
- end
27
-
28
- protected
29
-
30
- # @return [Hash<node id, Array<file_name>>] node ids and array of file_names
31
- def nonuniq_ids
32
- @node.each_with_object({}){|node, hsh|
33
- hsh[node.id] ||= []
34
- # TODO that way CheckNodes depends on files!?
35
- hsh[node.id] << node[:file_name]
36
- }.select{|k, v| v.size > 1}
37
- .each{|k, v| v.uniq!}
38
- end
39
-
40
- # @return [Hash<parent, Array<node id>>] unknown meta[:parent] and
41
- # array of nodes those have this meta attribute
42
- def unknown_parents
43
- @node # .drop(1)?
44
- .select{|node| node[:parent] && node.parent.id != node[:parent]}
45
- .each_with_object({}){|node, hsh|
46
- hsh[node[:parent]] ||= []
47
- hsh[node[:parent]] << node.id
48
- }
49
- end
50
-
51
- # @return [Hash<node_id, Array<node_id>>] node ids that noe found
52
- # in hierarchy and array of node ids those have links to corresponding
53
- # unknown node
54
- def unknown_references
55
- index = @node.map(&:id).drop(1)
56
- @node.each_with_object({}) do |node, hsh|
57
- node.links
58
- .reject {|lnk| index.include?(lnk)}
59
- .each do |lnk|
60
- hsh[lnk] ||= []
61
- hsh[lnk] << node.id
62
- end
63
- end
64
- end
65
-
66
- # @return [Hash<node_id, Array<node_id>>] node ids and array of
67
- # unknown links in :order_index
68
- def unknown_order_index
69
- @node
70
- .select{|node| node[:order_index]}
71
- .each_with_object({}){|node, hsh|
72
- order = node[:order_index].split(/ /)
73
- wrong = order.select{|o| node.item(o).nil?}
74
- hsh[node.id] = wrong unless wrong.empty?
75
- }
76
- end
77
-
78
- end
79
-
80
- end
81
- end
@@ -1,31 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require_relative "interactor"
4
- require_relative "join_nodes"
5
- require_relative "query_nodes"
6
-
7
- module Clerq
8
- module Interactors
9
-
10
- class CompileNodes < Interactor
11
-
12
- # @return [String] document body
13
- def call
14
- tt = gateway.templates(@template)
15
- raise Failure, "Template '#{@template}' not found" unless tt
16
- node = @query.empty? ? JoinNodes.() : QueryNodes.(query: @query)
17
- Clerq::Templater.(tt.body, node)
18
- end
19
-
20
- protected
21
-
22
- def initialize(template:, query: '')
23
- raise ArgumentError, "Invalid argument :query" unless query.is_a? String
24
- raise ArgumentError, "Invalid argument :template" if !(template.is_a?(String) && !template.empty?)
25
- @query = query
26
- @template = template
27
- end
28
- end
29
-
30
- end
31
- end
@@ -1,28 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- module Clerq
4
- module Interactors
5
-
6
- class Interactor
7
- Failure = Class.new(StandardError)
8
-
9
- def self.inherited(klass)
10
- klass.const_set(:Failure, Class.new(klass::Failure))
11
- end
12
-
13
- def self.call(*args)
14
- new(*args).call
15
- end
16
-
17
- # Should be implemented in subclasses
18
- def call; end
19
-
20
- protected
21
-
22
- def gateway
23
- Clerq.gateway
24
- end
25
- end
26
-
27
- end
28
- end
@@ -1,59 +0,0 @@
1
- # encoding: UTF-8
2
-
3
- require_relative "interactor"
4
-
5
- module Clerq
6
- module Interactors
7
-
8
- # Combine all nodes in one root node (document)
9
- class JoinNodes < Interactor
10
-
11
- # @return [Node]
12
- def call
13
- @node = join(gateway.nodes)
14
- subordinate!
15
- equip_ident!
16
- @node
17
- end
18
-
19
- protected
20
-
21
- def join(nodes)
22
- return nodes.first if nodes.size == 1
23
- node = Clerq::Entities::Node.new(id: 'join', title: Clerq.settings.title)
24
- node.tap{|node| nodes.each{|n| node << n}}
25
- end
26
-
27
- def subordinate!
28
- @node.items
29
- .select{|n| n[:parent] && n[:parent] != n.parent.id}
30
- .each{|n|
31
- parent = @node.node(n[:parent])
32
- next unless parent
33
- parent << n
34
- @node.items.delete(n)
35
- n.meta.delete(:parent)
36
- }
37
- # if @node.id == 'join' && @node.items.size == 1
38
- # @node = @node.items.first
39
- # @node.orphan!
40
- # end
41
- end
42
-
43
- # equips nodes with autogenerated id
44
- # @param [Node] node
45
- def equip_ident!
46
- counter = {}
47
- @node.select{|n| n.id.empty?}.each do |n|
48
- next if n == @node
49
- index = counter[n.parent] || 1
50
- counter[n.parent] = index + 1
51
- id = index.to_s.rjust(2, '0')
52
- id = '.' + id unless n.parent == @node
53
- n.id = id
54
- end
55
- end
56
-
57
- end
58
- end
59
- end