jekyll-namespaces 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/jekyll-namespaces/site.rb +12 -0
- data/lib/jekyll-namespaces/tree.rb +168 -0
- data/lib/jekyll-namespaces/version.rb +6 -2
- data/lib/jekyll-namespaces.rb +69 -209
- metadata +5 -4
- data/lib/jekyll-namespaces/node.rb +0 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6a486b2fb9c89ac6247a8650948f1111e81836bb374afe532cb08e254dccd831
|
4
|
+
data.tar.gz: 94e8c5b5404a1f4550fe2cc6fc06f40df372f61c7ba65a901bda40b4cca6766c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c214a76c788e7fe52bc27ec85977546237f714be562973c433fa94f94764c8c88fdf0202a595f9845b85a43b8549c23b9707b05b33176d2f13014395d0da03cb
|
7
|
+
data.tar.gz: e0a73b6a22a2c80d32f8142152d46da831f32e73989daa0271766c894cd1debe5245bf36d6aa750556a494ec6560248a98b3144af3edccbd4fa1bfec7ee7c962
|
@@ -0,0 +1,168 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "jekyll"
|
3
|
+
|
4
|
+
module Jekyll
|
5
|
+
|
6
|
+
class Tree
|
7
|
+
attr_reader :root
|
8
|
+
|
9
|
+
def initialize(root_doc, md_docs)
|
10
|
+
@root = Node.new('root', root_doc.data['id'], root_doc.data['title'], root_doc.url, root_doc)
|
11
|
+
|
12
|
+
md_docs.each do |doc|
|
13
|
+
if doc != @root.doc
|
14
|
+
# jekyll pages don't have the slug attribute: https://github.com/jekyll/jekyll/blob/master/lib/jekyll/page.rb#L8
|
15
|
+
if doc.type == :pages
|
16
|
+
page_basename = File.basename(doc.name, File.extname(doc.name))
|
17
|
+
doc.data['slug'] = Jekyll::Utils.slugify(page_basename)
|
18
|
+
end
|
19
|
+
self.add_path(doc)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# print_tree(root)
|
24
|
+
end
|
25
|
+
|
26
|
+
# add unique path for the given doc to tree (node-class).
|
27
|
+
def add_path(doc, node=nil, depth=1)
|
28
|
+
node = @root if depth == 1
|
29
|
+
Jekyll.logger.error("Incorrect node in tree.add_path") if node == nil
|
30
|
+
levels = doc.data['slug'].split(/\s|\./)
|
31
|
+
# handle doc if the given node was not root and we are at depth
|
32
|
+
if depth == levels.length
|
33
|
+
cur_nd_namespace = 'root' + '.' + doc.data['slug']
|
34
|
+
cur_nd_id = doc.data['id']
|
35
|
+
cur_nd_title = doc.data['title']
|
36
|
+
cur_nd_url = doc.url
|
37
|
+
|
38
|
+
cur_node = node.children.detect {|c| c.namespace == cur_nd_namespace }
|
39
|
+
# create node if one does not exist
|
40
|
+
if cur_node.nil?
|
41
|
+
new_node = Node.new(cur_nd_namespace, cur_nd_id, cur_nd_title, cur_nd_url, doc)
|
42
|
+
node.children << new_node
|
43
|
+
# fill-in node if one already exists
|
44
|
+
else
|
45
|
+
cur_node.fill(cur_nd_id, cur_nd_title, cur_nd_url, doc)
|
46
|
+
end
|
47
|
+
return
|
48
|
+
# create temp node and recurse
|
49
|
+
else
|
50
|
+
cur_namespace = 'root' + '.' + levels[0..(depth - 1)].join('.')
|
51
|
+
unless node.children.any? { |c| c.namespace == cur_namespace }
|
52
|
+
new_node = Node.new(cur_namespace)
|
53
|
+
node.children << new_node
|
54
|
+
else
|
55
|
+
new_node = node.children.detect { |c| c.namespace == cur_namespace }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
self.add_path(doc, new_node, depth + 1)
|
59
|
+
end
|
60
|
+
|
61
|
+
def get_all_relative_ids(target_node_id, node=@root, ancestors=[], descendents=[], found=false)
|
62
|
+
# found target node, stop adding ancestors and build descendents
|
63
|
+
if target_node_id == node.url || target_node_id == node.namespace || found
|
64
|
+
node.children.each do |child_node|
|
65
|
+
# if the child document is an empty string, it is a missing node
|
66
|
+
if child_node.missing
|
67
|
+
descendents << child_node.namespace
|
68
|
+
else
|
69
|
+
descendents << child_node.doc.url
|
70
|
+
end
|
71
|
+
self.get_all_relative_ids(target_node_id, child_node, ancestors.clone, descendents, found=true)
|
72
|
+
end
|
73
|
+
return ancestors, descendents
|
74
|
+
# target node not yet found, build ancestors
|
75
|
+
else
|
76
|
+
# if the node document is an empty string, it is a missing node
|
77
|
+
if node.missing
|
78
|
+
ancestors << node.namespace
|
79
|
+
else
|
80
|
+
ancestors << node.doc.url
|
81
|
+
end
|
82
|
+
results = []
|
83
|
+
node.children.each do |child_node|
|
84
|
+
results.concat(self.get_all_relative_ids(target_node_id, child_node, ancestors.clone))
|
85
|
+
end
|
86
|
+
return results.select { |r| !r.nil? }
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# find the parent and children of the 'target_doc'.
|
91
|
+
# ('node' as in the current node, which first is root.)
|
92
|
+
def find_doc_immediate_relatives(target_doc, node=nil, ancestors=[])
|
93
|
+
node = @root if ancestors == []
|
94
|
+
Jekyll.logger.error("Incorrect node in tree.find_doc_immediate_relatives") if node == nil
|
95
|
+
if target_doc == node.doc
|
96
|
+
children = []
|
97
|
+
node.children.each do |child|
|
98
|
+
# if the child document is an empty string, it is a missing node
|
99
|
+
if child.missing
|
100
|
+
children << child.namespace
|
101
|
+
else
|
102
|
+
children << child.doc.url
|
103
|
+
end
|
104
|
+
end
|
105
|
+
return ancestors, children
|
106
|
+
else
|
107
|
+
# if the node document is an empty string, it is a missing node
|
108
|
+
if node.missing
|
109
|
+
ancestors << node.namespace
|
110
|
+
else
|
111
|
+
ancestors << node.doc.url
|
112
|
+
end
|
113
|
+
results = []
|
114
|
+
node.children.each do |child_node|
|
115
|
+
results.concat(self.find_doc_immediate_relatives(target_doc, child_node, ancestors.clone))
|
116
|
+
end
|
117
|
+
return results.select { |r| !r.nil? }
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# ...for debugging
|
122
|
+
def print_tree(node, ancestors=[])
|
123
|
+
Jekyll.logger.warn "Ancestors: ", ancestors.length
|
124
|
+
Jekyll.logger.warn node
|
125
|
+
Jekyll.logger.warn "Children: ", node.children
|
126
|
+
ancestors.append(node.id)
|
127
|
+
node.children.each do |child_node|
|
128
|
+
self.print_tree(child_node, ancestors.clone)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
class Node
|
134
|
+
attr_accessor :namespace, :id, :title, :children, :url, :doc
|
135
|
+
|
136
|
+
def initialize(namespace, id="", title="", url="", doc="")
|
137
|
+
# mandatory
|
138
|
+
@namespace = namespace
|
139
|
+
# optional
|
140
|
+
@id = id.to_s
|
141
|
+
@title = title
|
142
|
+
@url = url.nil? ? "" : url
|
143
|
+
@doc = doc
|
144
|
+
# auto-init
|
145
|
+
@children = []
|
146
|
+
end
|
147
|
+
|
148
|
+
def fill(id, title, url, doc)
|
149
|
+
@id = id
|
150
|
+
@title = title
|
151
|
+
@url = url
|
152
|
+
@doc = doc
|
153
|
+
end
|
154
|
+
|
155
|
+
def missing
|
156
|
+
return @doc == ""
|
157
|
+
end
|
158
|
+
|
159
|
+
def type
|
160
|
+
return @doc.type
|
161
|
+
end
|
162
|
+
|
163
|
+
def to_s
|
164
|
+
"namespace: #{@namespace}"
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|
data/lib/jekyll-namespaces.rb
CHANGED
@@ -2,237 +2,97 @@
|
|
2
2
|
require "jekyll"
|
3
3
|
|
4
4
|
require_relative "jekyll-namespaces/context"
|
5
|
-
require_relative "jekyll-namespaces/
|
5
|
+
require_relative "jekyll-namespaces/site"
|
6
|
+
require_relative "jekyll-namespaces/tree"
|
6
7
|
require_relative "jekyll-namespaces/version"
|
7
8
|
|
8
|
-
module
|
9
|
-
|
10
|
-
attr_accessor :site, :config
|
11
|
-
|
12
|
-
# Use Jekyll's native relative_url filter
|
13
|
-
include Jekyll::Filters::URLFilters
|
14
|
-
|
15
|
-
CONVERTER_CLASS = Jekyll::Converters::Markdown
|
16
|
-
# config
|
17
|
-
CONFIG_KEY = "namespaces"
|
18
|
-
ENABLED_KEY = "enabled"
|
19
|
-
INCLUDE_KEY = "include"
|
20
|
-
# graph config
|
21
|
-
GRAPH_DATA_KEY = "d3_graph_data"
|
22
|
-
ENABLED_GRAPH_DATA_KEY = "enabled"
|
23
|
-
EXCLUDE_GRAPH_KEY = "exclude"
|
24
|
-
GRAPH_ASSETS_LOCATION_KEY = "path"
|
25
|
-
|
26
|
-
def initialize(config)
|
27
|
-
@config ||= config
|
28
|
-
@testing ||= config['testing'] if config.keys.include?('testing')
|
29
|
-
end
|
30
|
-
|
31
|
-
def generate(site)
|
32
|
-
return if disabled?
|
33
|
-
|
34
|
-
# setup site
|
35
|
-
@site = site
|
36
|
-
@context ||= Context.new(site)
|
37
|
-
|
38
|
-
# setup markdown docs
|
39
|
-
docs = []
|
40
|
-
docs += site.pages if include?(:pages)
|
41
|
-
docs += site.docs_to_write.filter { |d| include?(d.type) }
|
42
|
-
@md_docs = docs.filter {|doc| markdown_extension?(doc.extname) }
|
43
|
-
|
44
|
-
# setup tree
|
45
|
-
root_doc = @md_docs.detect {|doc| doc.data['slug'] == 'root' }
|
46
|
-
root = Node.new(root_doc.data['id'], 'root', root_doc.data['title'], root_doc)
|
47
|
-
# build tree
|
48
|
-
@md_docs.each do |cur_doc|
|
49
|
-
# add path to tree
|
50
|
-
if !cur_doc.data['slug'].nil? and cur_doc.data['slug'] != 'root'
|
51
|
-
self.add_path(root, cur_doc)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
# print_tree(root)
|
56
|
-
|
57
|
-
# generate tree metadata
|
58
|
-
@md_docs.each do |cur_doc|
|
59
|
-
if !excluded_in_graph?(cur_doc)
|
60
|
-
# TODO: cur_doc.data['namespace'] = cur_doc.basename_without_ext
|
61
|
-
cur_doc.data['namespace'] = cur_doc.basename[0...-3]
|
62
|
-
cur_doc.data['ancestors'], cur_doc.data['children'] = self.find_doc_immediate_relatives(cur_doc, root)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
# graph
|
66
|
-
if !disabled_graph_data?
|
67
|
-
self.write_graph(root)
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
# config helpers
|
72
|
-
|
73
|
-
def disabled?
|
74
|
-
option(ENABLED_KEY) == false
|
75
|
-
end
|
9
|
+
module Jekyll
|
10
|
+
module Namespaces
|
76
11
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
end
|
12
|
+
class Generator < Jekyll::Generator
|
13
|
+
# for testing
|
14
|
+
attr_reader :config
|
81
15
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
@markdown_converter ||= @site.find_converter_instance(CONVERTER_CLASS)
|
88
|
-
end
|
16
|
+
CONVERTER_CLASS = Jekyll::Converters::Markdown
|
17
|
+
# config
|
18
|
+
CONFIG_KEY = "namespaces"
|
19
|
+
ENABLED_KEY = "enabled"
|
20
|
+
EXCLUDE_KEY = "exclude"
|
89
21
|
|
90
|
-
|
91
|
-
|
92
|
-
|
22
|
+
def initialize(config)
|
23
|
+
@config ||= config
|
24
|
+
end
|
93
25
|
|
94
|
-
|
26
|
+
def generate(site)
|
27
|
+
return if disabled?
|
28
|
+
self.old_config_warn()
|
29
|
+
|
30
|
+
# setup site
|
31
|
+
@site = site
|
32
|
+
@context ||= Context.new(site)
|
33
|
+
|
34
|
+
# setup markdown docs
|
35
|
+
docs = []
|
36
|
+
docs += @site.pages if !excluded?(:pages)
|
37
|
+
docs += @site.docs_to_write.filter { |d| !excluded?(d.type) }
|
38
|
+
@md_docs = docs.filter { |doc| markdown_extension?(doc.extname) }
|
39
|
+
if @md_docs.empty?
|
40
|
+
Jekyll.logger.debug("No documents to process.")
|
41
|
+
end
|
95
42
|
|
96
|
-
|
97
|
-
|
98
|
-
|
43
|
+
# tree setup
|
44
|
+
root_doc = @md_docs.detect { |d| d.data['slug'] == 'root' }
|
45
|
+
if root_doc.nil?
|
46
|
+
Jekyll.logger.debug("No root.md detected.")
|
47
|
+
end
|
48
|
+
@site.tree = Tree.new(root_doc, @md_docs)
|
99
49
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
50
|
+
# generate metadata
|
51
|
+
@md_docs.each do |doc|
|
52
|
+
doc.data['namespace'] = doc.data['slug']
|
53
|
+
doc.data['ancestors'], doc.data['children'] = @site.tree.find_doc_immediate_relatives(doc)
|
54
|
+
end
|
104
55
|
|
105
|
-
|
106
|
-
return !!option_graph(GRAPH_ASSETS_LOCATION_KEY)
|
107
|
-
end
|
56
|
+
end
|
108
57
|
|
109
|
-
|
110
|
-
config[GRAPH_DATA_KEY] && config[GRAPH_DATA_KEY][key]
|
111
|
-
end
|
58
|
+
# config helpers
|
112
59
|
|
113
|
-
|
114
|
-
|
115
|
-
# add unique path for the given doc to tree (node-class).
|
116
|
-
def add_path(node, doc, depth=1)
|
117
|
-
chunked_namespace = doc.data['slug'].split(/\s|\./)
|
118
|
-
# handle doc if the given node was not root and we are at depth
|
119
|
-
if depth == chunked_namespace.length
|
120
|
-
cur_nd_namespace = 'root' + '.' + doc.data['slug']
|
121
|
-
cur_nd_id = doc.data['id']
|
122
|
-
cur_nd_title = doc.data['title']
|
123
|
-
# create node if one does not exist
|
124
|
-
unless node.children.any?{ |c| c.namespace == cur_nd_namespace }
|
125
|
-
new_node = Node.new(cur_nd_id, cur_nd_namespace, cur_nd_title, doc)
|
126
|
-
node.children << new_node
|
127
|
-
# fill-in node if one already exists
|
128
|
-
else
|
129
|
-
cur_node = node.children.detect {|c| c.namespace == cur_nd_namespace }
|
130
|
-
cur_node.id = cur_nd_id
|
131
|
-
cur_node.title = cur_nd_title
|
132
|
-
cur_node.doc = doc
|
133
|
-
end
|
134
|
-
return
|
135
|
-
# create temp node and recurse
|
136
|
-
else
|
137
|
-
cur_namespace = 'root' + '.' + chunked_namespace[0..(depth - 1)].join('.')
|
138
|
-
unless node.children.any?{ |c| c.namespace == cur_namespace }
|
139
|
-
new_node = Node.new('', cur_namespace, '', '')
|
140
|
-
node.children << new_node
|
141
|
-
else
|
142
|
-
new_node = node.children.detect {|c| c.namespace == cur_namespace }
|
143
|
-
end
|
60
|
+
def disabled?
|
61
|
+
option(ENABLED_KEY) == false
|
144
62
|
end
|
145
|
-
self.add_path(new_node, doc, depth + 1)
|
146
|
-
end
|
147
63
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
if target_doc.data['id'] == node.id
|
152
|
-
children = []
|
153
|
-
node.children.each do |child|
|
154
|
-
if child.id == ''
|
155
|
-
children << {
|
156
|
-
'id' => '',
|
157
|
-
'title' => child.namespace.match('([^.]*$)')[0].gsub('-', ' ')
|
158
|
-
}
|
159
|
-
else
|
160
|
-
children << child.doc
|
161
|
-
end
|
162
|
-
end
|
163
|
-
return ancestors, children
|
164
|
-
else
|
165
|
-
if node.id == ''
|
166
|
-
ancestors << {
|
167
|
-
'id' => '',
|
168
|
-
'title' => node.namespace.match('([^.]*$)')[0].gsub('-', ' ')
|
169
|
-
}
|
170
|
-
else
|
171
|
-
ancestors << node.doc
|
172
|
-
end
|
173
|
-
results = []
|
174
|
-
node.children.each do |child_node|
|
175
|
-
results.concat self.find_doc_immediate_relatives(target_doc, child_node, ancestors.clone)
|
176
|
-
end
|
177
|
-
return results.select { |r| !r.nil? }
|
64
|
+
def excluded?(type)
|
65
|
+
return false unless option(EXCLUDE_KEY)
|
66
|
+
return option(EXCLUDE_KEY).include?(type.to_s)
|
178
67
|
end
|
179
|
-
end
|
180
68
|
|
181
|
-
|
182
|
-
|
183
|
-
Jekyll.logger.warn "Ancestors: ", ancestors.length
|
184
|
-
Jekyll.logger.warn node
|
185
|
-
Jekyll.logger.warn "Children: ", node.children
|
186
|
-
ancestors.append(node.id)
|
187
|
-
node.children.each do |child_node|
|
188
|
-
self.print_tree(child_node, ancestors.clone)
|
69
|
+
def markdown_extension?(extension)
|
70
|
+
markdown_converter.matches(extension)
|
189
71
|
end
|
190
|
-
end
|
191
72
|
|
192
|
-
|
193
|
-
|
194
|
-
# convert tree (node-class) to json
|
195
|
-
def tree_to_json(baseurl, node, json_node={})
|
196
|
-
if node.id.empty?
|
197
|
-
Jekyll.logger.warn "Tree node missing: ", node.namespace
|
198
|
-
label = node.namespace.match('([^.]*$)')[0].gsub('-', ' ')
|
199
|
-
node_url = ''
|
200
|
-
else
|
201
|
-
label = node.title
|
202
|
-
node_url = relative_url(node.doc.url)
|
73
|
+
def markdown_converter
|
74
|
+
@markdown_converter ||= @site.find_converter_instance(CONVERTER_CLASS)
|
203
75
|
end
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
json_children.append(new_child)
|
76
|
+
|
77
|
+
def option(key)
|
78
|
+
@config[CONFIG_KEY] && @config[CONFIG_KEY][key]
|
208
79
|
end
|
209
|
-
json_node = {
|
210
|
-
# "id": node.id,
|
211
|
-
"id": node_url,
|
212
|
-
"namespace": node.namespace,
|
213
|
-
"label": label,
|
214
|
-
"children": json_children,
|
215
|
-
"url": node_url,
|
216
|
-
}
|
217
|
-
return json_node
|
218
|
-
end
|
219
80
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
81
|
+
# !! deprecated !!
|
82
|
+
|
83
|
+
def option_exist?(key)
|
84
|
+
@config[CONFIG_KEY] && @config[CONFIG_KEY].include?(key)
|
224
85
|
end
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
if @testing
|
234
|
-
@site.static_files << static_file if !@site.static_files.include?(static_file)
|
86
|
+
|
87
|
+
def old_config_warn()
|
88
|
+
if @config.include?("d3_graph_data")
|
89
|
+
Jekyll.logger.warn "As of 0.0.2, 'd3_graph_data' should now be 'd3' and requires the 'jekyll-d3' plugin."
|
90
|
+
end
|
91
|
+
if option_exist?("include")
|
92
|
+
Jekyll.logger.warn "As of 0.0.2, all markdown files are processed by default. Use 'exclude' config to exclude document types."
|
93
|
+
end
|
235
94
|
end
|
236
95
|
end
|
96
|
+
|
237
97
|
end
|
238
98
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jekyll-namespaces
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- manunamz
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-09-17 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email:
|
@@ -19,11 +19,12 @@ extra_rdoc_files: []
|
|
19
19
|
files:
|
20
20
|
- lib/jekyll-namespaces.rb
|
21
21
|
- lib/jekyll-namespaces/context.rb
|
22
|
-
- lib/jekyll-namespaces/
|
22
|
+
- lib/jekyll-namespaces/site.rb
|
23
|
+
- lib/jekyll-namespaces/tree.rb
|
23
24
|
- lib/jekyll-namespaces/version.rb
|
24
25
|
homepage: https://github.com/manunamz/jekyll-namespaces
|
25
26
|
licenses:
|
26
|
-
-
|
27
|
+
- GPL3
|
27
28
|
metadata:
|
28
29
|
homepage_uri: https://github.com/manunamz/jekyll-namespaces
|
29
30
|
source_code_uri: https://github.com/manunamz/jekyll-namespaces
|
@@ -1,22 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# helper class for tree-building.
|
4
|
-
class Node
|
5
|
-
attr_accessor :id, :namespace, :title, :children, :doc
|
6
|
-
|
7
|
-
def initialize(id, namespace, title, doc)
|
8
|
-
@id = id
|
9
|
-
@children = []
|
10
|
-
@namespace = namespace
|
11
|
-
@title = title
|
12
|
-
@doc = doc
|
13
|
-
end
|
14
|
-
|
15
|
-
def type
|
16
|
-
return doc.type
|
17
|
-
end
|
18
|
-
|
19
|
-
def to_s
|
20
|
-
"namespace: #{@namespace}"
|
21
|
-
end
|
22
|
-
end
|