clerq 0.1.0 → 0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +4 -3
- data/CHANGELOG.md +49 -0
- data/Gemfile.lock +9 -9
- data/README.md +260 -133
- data/Rakefile +1 -0
- data/clerq.gemspec +6 -6
- data/clerq.thor +28 -0
- data/docs/README.md +408 -0
- data/lib/assets/knb/SRS-IEEE-830-1998.md +293 -0
- data/lib/assets/knb/SRS-RUP.md +283 -0
- data/lib/assets/knb/business-case.md +135 -0
- data/lib/assets/knb/ears-with-examples.md +101 -0
- data/lib/assets/knb/problem-statement.md +8 -0
- data/lib/assets/knb/product-statement.md +8 -0
- data/lib/assets/knb/requirement-attributes.md +26 -0
- data/lib/assets/knb/requirement-classification.md +27 -0
- data/lib/assets/knb/requirement-life-cycle.md +47 -0
- data/lib/assets/knb/requirement-quality.md +13 -0
- data/lib/assets/knb/use-case.md +39 -0
- data/lib/assets/knb/vision-document.md +191 -0
- data/lib/assets/lib/clerq_doc.thor +119 -0
- data/lib/assets/lib/colonize_repo.rb +82 -0
- data/lib/assets/lib/spec/colonize_repo_spec.rb +85 -0
- data/lib/assets/new/clerq.thor.tt +32 -5
- data/lib/assets/new/content.md.tt +3 -40
- data/lib/assets/tt/default.md.erb +23 -42
- data/lib/assets/tt/pandoc.md.erb +11 -8
- data/lib/clerq.rb +57 -12
- data/lib/clerq/cli.rb +77 -60
- data/lib/clerq/entities.rb +0 -1
- data/lib/clerq/entities/node.rb +135 -115
- data/lib/clerq/properties.rb +1 -3
- data/lib/clerq/repositories.rb +2 -4
- data/lib/clerq/repositories/file_repository.rb +59 -0
- data/lib/clerq/repositories/node_repository.rb +72 -30
- data/lib/clerq/repositories/text_repository.rb +47 -0
- data/lib/clerq/services.rb +8 -0
- data/lib/clerq/services/check_assembly.rb +108 -0
- data/lib/clerq/{interactors → services}/create_node.rb +12 -11
- data/lib/clerq/services/load_assembly.rb +54 -0
- data/lib/clerq/services/query_node.rb +72 -0
- data/lib/clerq/services/query_template.rb +26 -0
- data/lib/clerq/services/read_node.rb +101 -0
- data/lib/clerq/services/render_erb.rb +29 -0
- data/lib/clerq/services/render_node.rb +37 -0
- data/lib/clerq/services/service.rb +19 -0
- data/lib/clerq/settings.rb +2 -2
- data/lib/clerq/version.rb +1 -1
- metadata +49 -37
- data/TODO.md +0 -3
- data/lib/assets/tt/gitlab.md.erb +0 -93
- data/lib/assets/tt/raw.md.erb +0 -23
- data/lib/clerq/entities/template.rb +0 -19
- data/lib/clerq/gateways.rb +0 -3
- data/lib/clerq/gateways/gateway.rb +0 -17
- data/lib/clerq/gateways/in_files.rb +0 -36
- data/lib/clerq/gateways/in_memory.rb +0 -35
- data/lib/clerq/interactors.rb +0 -5
- data/lib/clerq/interactors/check_nodes.rb +0 -81
- data/lib/clerq/interactors/compile_nodes.rb +0 -31
- data/lib/clerq/interactors/interactor.rb +0 -28
- data/lib/clerq/interactors/join_nodes.rb +0 -59
- data/lib/clerq/interactors/query_nodes.rb +0 -62
- data/lib/clerq/repositories/in_memory.rb +0 -45
- data/lib/clerq/repositories/node_reader.rb +0 -107
- data/lib/clerq/repositories/repository.rb +0 -11
- data/lib/clerq/repositories/template_repository.rb +0 -53
- data/lib/clerq/templater.rb +0 -32
@@ -1,62 +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
|
-
class QueryNodes < Interactor
|
10
|
-
|
11
|
-
def call
|
12
|
-
proc = prepare_query
|
13
|
-
join = JoinNodes.()
|
14
|
-
list = join.select{|node| proc.call(node)}
|
15
|
-
return Node.new(title: "#{Clerq.settings.title}. Query: #{@query}") if list.empty?
|
16
|
-
make_response(list)
|
17
|
-
end
|
18
|
-
|
19
|
-
protected
|
20
|
-
|
21
|
-
def initialize(query:)
|
22
|
-
raise ArgumentError, "Invalid argument :query" if !(query.is_a?(String) && !query.empty?)
|
23
|
-
@query = query
|
24
|
-
end
|
25
|
-
|
26
|
-
def prepare_query
|
27
|
-
proc = Proc.new {|node| eval(@query)}
|
28
|
-
test = Node.new
|
29
|
-
test.select{|node| proc.call(node)}
|
30
|
-
proc
|
31
|
-
rescue Exception => e
|
32
|
-
msg = <<~EOF
|
33
|
-
Invalid query #{@query} (#{e.message})
|
34
|
-
It must eval as 'Proc.new{|node| eval(<query>)}'
|
35
|
-
Valid query examples are following:
|
36
|
-
node.id == 'uc'
|
37
|
-
node.belong?('uc')
|
38
|
-
node.belong?('ud') && node[:source] == 'sales'
|
39
|
-
EOF
|
40
|
-
raise self.class::Failure, msg
|
41
|
-
end
|
42
|
-
|
43
|
-
# @param nodes [Array<Node>] result of node.select
|
44
|
-
# @return [Node] node that includes all selected nodes
|
45
|
-
def make_response(nodes)
|
46
|
-
if nodes.size == 1
|
47
|
-
node = nodes.first
|
48
|
-
node.orphan!
|
49
|
-
return node
|
50
|
-
end
|
51
|
-
Node.new(id: @query).tap{|node|
|
52
|
-
nodes.each{|n|
|
53
|
-
n.orphan!
|
54
|
-
node << n
|
55
|
-
}
|
56
|
-
}
|
57
|
-
end
|
58
|
-
|
59
|
-
end
|
60
|
-
|
61
|
-
end
|
62
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
require_relative 'repository'
|
2
|
-
|
3
|
-
module Clerq
|
4
|
-
module Repositories
|
5
|
-
|
6
|
-
class InMemory < Repository
|
7
|
-
|
8
|
-
def initialize
|
9
|
-
@counter = 0
|
10
|
-
@items = {}
|
11
|
-
end
|
12
|
-
|
13
|
-
def items(id = nil)
|
14
|
-
return @items[id] if id
|
15
|
-
@items.values
|
16
|
-
end
|
17
|
-
|
18
|
-
def find(id)
|
19
|
-
@items[id]
|
20
|
-
end
|
21
|
-
|
22
|
-
def save(e)
|
23
|
-
raise ArgumentError, "Invalid argument" unless entity?(e)
|
24
|
-
id = has_id?(e) ? e.id : counter
|
25
|
-
@items[id] = e
|
26
|
-
end
|
27
|
-
|
28
|
-
protected
|
29
|
-
|
30
|
-
def counter
|
31
|
-
@counter += 1
|
32
|
-
end
|
33
|
-
|
34
|
-
def has_id?(e)
|
35
|
-
e.id && !e.id.empty?
|
36
|
-
end
|
37
|
-
|
38
|
-
def entity?(e)
|
39
|
-
e.is_a?(Object) && e.respond_to?(:id)
|
40
|
-
end
|
41
|
-
|
42
|
-
end
|
43
|
-
|
44
|
-
end
|
45
|
-
end
|
@@ -1,107 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
require_relative '../entities'
|
4
|
-
include Clerq::Entities
|
5
|
-
|
6
|
-
module Clerq
|
7
|
-
module Repositories
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
class Clerq::Repositories::NodeReader
|
12
|
-
|
13
|
-
# @param [String] file_name with node
|
14
|
-
# @return [Array<Node>] from file
|
15
|
-
def self.call(file_name)
|
16
|
-
new(file_name).call
|
17
|
-
end
|
18
|
-
|
19
|
-
# @param [Enumerator] lines; for testing purpose
|
20
|
-
# @return [Array<Node>] from file
|
21
|
-
def call(text = File.foreach(@file_name))
|
22
|
-
STDOUT.print "Reading #{@file_name} ..."
|
23
|
-
|
24
|
-
read_nodes(text).each do |node_text|
|
25
|
-
level, node = parse_node(node_text)
|
26
|
-
next unless node
|
27
|
-
node[:file_name] = @file_name
|
28
|
-
insert_node(node, level)
|
29
|
-
end
|
30
|
-
|
31
|
-
STDOUT.puts @errors.empty? ? "OK" : "Errors found"
|
32
|
-
unless @errors.empty?
|
33
|
-
STDERR.puts "Errors reading #{@file_name}"
|
34
|
-
STDERR.puts @errors.map{|e| "\t#{e}"}.join("\n")
|
35
|
-
end
|
36
|
-
|
37
|
-
nodes = Array.new(@node.items)
|
38
|
-
nodes.each(&:orphan!)
|
39
|
-
nodes
|
40
|
-
end
|
41
|
-
|
42
|
-
protected
|
43
|
-
|
44
|
-
def initialize(file_name)
|
45
|
-
@file_name = file_name
|
46
|
-
@node = Node.new(id: file_name)
|
47
|
-
@errors = []
|
48
|
-
end
|
49
|
-
|
50
|
-
# @param [Enumerator<String>] text
|
51
|
-
# @return [Array<String>] where each item represents one node
|
52
|
-
def read_nodes(text)
|
53
|
-
[].tap do |nodes|
|
54
|
-
quote, body = false, ''
|
55
|
-
text.each do |line|
|
56
|
-
if line.start_with?('#') && !quote && !body.empty?
|
57
|
-
nodes << body
|
58
|
-
body = ''
|
59
|
-
end
|
60
|
-
body << line
|
61
|
-
quote = !quote if line.start_with?('```')
|
62
|
-
end
|
63
|
-
nodes << body unless body.empty?
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def insert_node(node, level)
|
68
|
-
parent = @node
|
69
|
-
while parent.last_item && (parent.nesting_level + 1) < level
|
70
|
-
parent = parent.last_item
|
71
|
-
end
|
72
|
-
unless (parent.nesting_level + 1) == level
|
73
|
-
@errors << "invalid header level: #{'#' * level} [#{node.id}]"
|
74
|
-
parent = @node
|
75
|
-
end
|
76
|
-
parent << node
|
77
|
-
end
|
78
|
-
|
79
|
-
def parse_node(text)
|
80
|
-
text += "\n" unless text.end_with?("\n")
|
81
|
-
parts = NODE_REGX.match(text)
|
82
|
-
lv = parts[1] || ''
|
83
|
-
id = parts[3] || ''
|
84
|
-
title = parts[4] || ''
|
85
|
-
body = parts[7] || ''
|
86
|
-
meta = {}
|
87
|
-
meta.merge!(parse_meta(parts[6])) if parts[6]
|
88
|
-
[lv.size, Node.new(id: id, title: title, body: body.strip, meta: meta)]
|
89
|
-
rescue StandardError
|
90
|
-
@errors << "invalid node format:\n#{text}"
|
91
|
-
[nil, nil]
|
92
|
-
end
|
93
|
-
|
94
|
-
def parse_meta(text)
|
95
|
-
text.strip.split(/[;\n]/).inject({}) do |h, i|
|
96
|
-
pair = /\s?(\w*):\s*(.*)/.match(i)
|
97
|
-
h.merge(pair[1].to_sym => pair[2])
|
98
|
-
end || {}
|
99
|
-
rescue StandardError
|
100
|
-
@errors << "invalid meta format:\n{{#{text}}}"
|
101
|
-
{}
|
102
|
-
end
|
103
|
-
|
104
|
-
NODE_REGX =
|
105
|
-
/^(\#+)[ ]*(\[([^\[\]\s]*)\][ ]*)?([\s\S]*?)\n({{([\s\S]*?)}})?(.*)$/m
|
106
|
-
|
107
|
-
end
|
@@ -1,53 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
require_relative '../entities'
|
4
|
-
require_relative 'repository'
|
5
|
-
include Clerq::Entities
|
6
|
-
|
7
|
-
module Clerq
|
8
|
-
module Repositories
|
9
|
-
|
10
|
-
class TemplateRepository < Repository
|
11
|
-
attr_reader :path
|
12
|
-
def initialize(path = Dir.pwd)
|
13
|
-
@items = {}
|
14
|
-
@path = path
|
15
|
-
end
|
16
|
-
|
17
|
-
# TODO move id parameter to #find
|
18
|
-
def items(id = nil)
|
19
|
-
load if @items.empty?
|
20
|
-
return find(id) if id
|
21
|
-
@items.values
|
22
|
-
end
|
23
|
-
|
24
|
-
def find(id)
|
25
|
-
return @items[id] if @items[id]
|
26
|
-
PATTERNS.each do |p|
|
27
|
-
i0 = "#{id}#{p[1..-1]}"
|
28
|
-
return @items[i0] if @items[i0]
|
29
|
-
end
|
30
|
-
return nil
|
31
|
-
end
|
32
|
-
|
33
|
-
def save(tt)
|
34
|
-
raise ArgumentError, "Invalid argument" unless tt.is_a? Template
|
35
|
-
Dir.chdir(@path){ File.write(tt.id, tt.body) }
|
36
|
-
end
|
37
|
-
|
38
|
-
protected
|
39
|
-
|
40
|
-
def load
|
41
|
-
Dir.chdir(@path) do
|
42
|
-
Dir.glob(PATTERNS)
|
43
|
-
.map {|f| Template.new(id: f, body: File.read(f))}
|
44
|
-
.each{|t| @items[t.id] = t}
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
PATTERNS = ['*.tt', '*.erb']
|
49
|
-
|
50
|
-
end
|
51
|
-
|
52
|
-
end
|
53
|
-
end
|
data/lib/clerq/templater.rb
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
require 'erb'
|
4
|
-
|
5
|
-
module Clerq
|
6
|
-
|
7
|
-
# Compile @object to text in accordance with @template
|
8
|
-
# Usage
|
9
|
-
# tt = "id: <%= @object.id %>\ntitle: <%= @object.title %>\n"
|
10
|
-
# n = Node.new(id: 'uc', title: 'Use Cases', meta: {skip_meta: true})
|
11
|
-
# text = Templater.call(tt, n) # or Templater.(tt, n)
|
12
|
-
class Templater
|
13
|
-
|
14
|
-
# @param tt [Template]
|
15
|
-
# @param object [Object]
|
16
|
-
# @result [String?]
|
17
|
-
def self.call(template, object)
|
18
|
-
new(template, object).call
|
19
|
-
end
|
20
|
-
|
21
|
-
def call
|
22
|
-
tt = ERB.new(@template, nil, "-")
|
23
|
-
tt.result(binding)
|
24
|
-
end
|
25
|
-
|
26
|
-
def initialize(template, object)
|
27
|
-
@template = template
|
28
|
-
@object = object
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
end
|