dbdoc 0.1.0 → 0.3.5
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.
- checksums.yaml +4 -4
- data/.github/FUNDING.yml +2 -0
- data/.rubocop.yml +25 -0
- data/Gemfile +3 -3
- data/Gemfile.lock +5 -2
- data/README.md +5 -1
- data/Rakefile +2 -0
- data/bin/dbdoc +2 -0
- data/dbdoc.gemspec +5 -0
- data/doc_files/columns.md.erb +2 -2
- data/doc_files/columns.yml.erb +1 -0
- data/doc_files/table_description.md +5 -1
- data/doc_files/table_example.md +3 -5
- data/lib/confluence/api.rb +10 -5
- data/lib/confluence/markdown_converter.rb +94 -0
- data/lib/{dbdoc → confluence}/uploader.rb +76 -26
- data/lib/dbdoc.rb +4 -1
- data/lib/dbdoc/cli.rb +83 -97
- data/lib/dbdoc/config.rb +14 -17
- data/lib/dbdoc/constants.rb +2 -0
- data/lib/dbdoc/folder_initializer.rb +61 -0
- data/lib/dbdoc/manager.rb +85 -51
- data/lib/dbdoc/version.rb +3 -1
- metadata +35 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c25899d4d18291f22be12f731230d64669f353e422f63d069791bd030ba3d9a8
|
4
|
+
data.tar.gz: be30d30193572b1b4dcf5141c010e9593e373d90c099f5e41ab40f5a06cf7e40
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ecc79a5cabb4a5cea63e5ae92c9b2c5b331c539590da6464aef4a789c96167a50a9aa876a840186b8e4ac3d29c5db4db6024b0bc5c2183c02bf44037c89cf09b
|
7
|
+
data.tar.gz: d7b19650e610c9a2b0c4b7c26250571f3811f459016740b85925d6e82d56d8c72b7119a2b0c6c14237638b295d832156e7a4ab7784da9748670e290a96a33618
|
data/.github/FUNDING.yml
ADDED
data/.rubocop.yml
CHANGED
@@ -1,2 +1,27 @@
|
|
1
1
|
Style/StringLiterals:
|
2
2
|
EnforcedStyle: double_quotes
|
3
|
+
|
4
|
+
Metrics/ClassLength:
|
5
|
+
Max: 200
|
6
|
+
|
7
|
+
Metrics/MethodLength:
|
8
|
+
Max: 50
|
9
|
+
|
10
|
+
Style/Documentation:
|
11
|
+
Exclude:
|
12
|
+
- lib/confluence/api.rb
|
13
|
+
- lib/dbdoc/cli.rb
|
14
|
+
|
15
|
+
Metrics/AbcSize:
|
16
|
+
Exclude:
|
17
|
+
- lib/dbdoc/cli.rb
|
18
|
+
|
19
|
+
Layout/FirstHashElementIndentation:
|
20
|
+
EnforcedStyle: consistent
|
21
|
+
|
22
|
+
Metrics/BlockLength:
|
23
|
+
Exclude:
|
24
|
+
- spec/**/*_spec.rb
|
25
|
+
|
26
|
+
Security/YAMLLoad:
|
27
|
+
Enabled: false
|
data/Gemfile
CHANGED
@@ -1,13 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
source "https://rubygems.org"
|
2
4
|
|
3
5
|
gemspec
|
4
6
|
|
5
|
-
gem "httparty"
|
6
|
-
|
7
7
|
group :development do
|
8
8
|
gem "byebug"
|
9
9
|
gem "coveralls", require: false
|
10
|
-
gem "rubocop"
|
11
10
|
gem "rake", "~> 12.0"
|
12
11
|
gem "rspec", "~> 3.0"
|
12
|
+
gem "rubocop"
|
13
13
|
end
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
dbdoc (0.
|
4
|
+
dbdoc (0.3.5)
|
5
|
+
httparty (~> 0.18)
|
6
|
+
kramdown (~> 2.3)
|
5
7
|
|
6
8
|
GEM
|
7
9
|
remote: https://rubygems.org/
|
@@ -20,6 +22,8 @@ GEM
|
|
20
22
|
mime-types (~> 3.0)
|
21
23
|
multi_xml (>= 0.5.2)
|
22
24
|
json (2.3.1)
|
25
|
+
kramdown (2.3.0)
|
26
|
+
rexml
|
23
27
|
mime-types (3.3.1)
|
24
28
|
mime-types-data (~> 3.2015)
|
25
29
|
mime-types-data (3.2020.0512)
|
@@ -76,7 +80,6 @@ DEPENDENCIES
|
|
76
80
|
byebug
|
77
81
|
coveralls
|
78
82
|
dbdoc!
|
79
|
-
httparty
|
80
83
|
rake (~> 12.0)
|
81
84
|
rspec (~> 3.0)
|
82
85
|
rubocop
|
data/README.md
CHANGED
@@ -40,7 +40,11 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
|
40
40
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
41
41
|
|
42
42
|
```
|
43
|
-
gem uninstall dbdoc && gem build dbdoc.gemspec && bundle && rake build && rake install && dbdoc help
|
43
|
+
Y | gem uninstall dbdoc && gem build dbdoc.gemspec && bundle && rake build && rake install && dbdoc help
|
44
|
+
```
|
45
|
+
|
46
|
+
```
|
47
|
+
Y | gem uninstall dbdoc && gem build dbdoc.gemspec && bundle && rake build && rake release
|
44
48
|
```
|
45
49
|
|
46
50
|
## Contributing
|
data/Rakefile
CHANGED
data/bin/dbdoc
CHANGED
data/dbdoc.gemspec
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative "lib/dbdoc/version"
|
2
4
|
|
3
5
|
Gem::Specification.new do |spec|
|
@@ -22,4 +24,7 @@ Gem::Specification.new do |spec|
|
|
22
24
|
|
23
25
|
spec.executables = ["dbdoc"]
|
24
26
|
spec.require_paths = ["lib"]
|
27
|
+
|
28
|
+
spec.add_runtime_dependency "httparty", "~> 0.18"
|
29
|
+
spec.add_runtime_dependency "kramdown", "~> 2.3"
|
25
30
|
end
|
data/doc_files/columns.md.erb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
||Name||Type||Description||
|
1
|
+
||Name||Type||Foreign Key||Description||
|
2
2
|
<%- columns.each do |column| -%>
|
3
|
-
|<%= column[:name] %>|<%= column[:type] %>|<%= column[:description].strip %>|
|
3
|
+
|<%= column[:name] %>|<%= column[:type] %>|<%= column[:foreign_key] || " " %>|<%= column[:description].strip %>|
|
4
4
|
<%- end -%>
|
data/doc_files/columns.yml.erb
CHANGED
data/doc_files/table_example.md
CHANGED
data/lib/confluence/api.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "httparty"
|
2
4
|
require "json"
|
3
5
|
require "yaml"
|
@@ -18,22 +20,25 @@ module Confluence
|
|
18
20
|
end
|
19
21
|
|
20
22
|
def delete_page(page_id:)
|
21
|
-
HTTParty.delete(
|
23
|
+
response = HTTParty.delete(
|
22
24
|
"https://dbdoc.atlassian.net/wiki/rest/api/content/#{page_id}", {
|
23
25
|
headers: {
|
24
26
|
"Authorization" => "Basic #{basic_auth}",
|
25
|
-
"Content-Type"
|
27
|
+
"Content-Type" => "application/json"
|
26
28
|
}
|
27
29
|
}
|
28
30
|
)
|
31
|
+
|
32
|
+
response.code == 200
|
29
33
|
end
|
30
34
|
|
31
35
|
def existing_pages
|
36
|
+
# TODO: paginate over all pages in the space
|
32
37
|
response = HTTParty.get(
|
33
38
|
"https://dbdoc.atlassian.net/wiki/rest/api/content/?&spaceKey=#{@space}", {
|
34
39
|
headers: {
|
35
40
|
"Authorization" => "Basic #{basic_auth}",
|
36
|
-
"Content-Type"
|
41
|
+
"Content-Type" => "application/json"
|
37
42
|
}
|
38
43
|
}
|
39
44
|
)
|
@@ -64,7 +69,7 @@ module Confluence
|
|
64
69
|
"https://dbdoc.atlassian.net/wiki/rest/api/content/#{page_id}", {
|
65
70
|
headers: {
|
66
71
|
"Authorization" => "Basic #{basic_auth}",
|
67
|
-
"Content-Type"
|
72
|
+
"Content-Type" => "application/json"
|
68
73
|
},
|
69
74
|
body: payload.to_json
|
70
75
|
}
|
@@ -112,7 +117,7 @@ module Confluence
|
|
112
117
|
"https://dbdoc.atlassian.net/wiki/rest/api/content/", {
|
113
118
|
headers: {
|
114
119
|
"Authorization" => "Basic #{basic_auth}",
|
115
|
-
"Content-Type"
|
120
|
+
"Content-Type" => "application/json"
|
116
121
|
},
|
117
122
|
body: payload.to_json
|
118
123
|
}
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "kramdown"
|
4
|
+
|
5
|
+
module Confluence
|
6
|
+
# By default, all documentation should be written in a normal
|
7
|
+
# Markdown format. Later, when we're generating/uploading final documentation,
|
8
|
+
# we'll use Confluence::MarkdownConverter to convert normal Markdown
|
9
|
+
# into Confluence specific Markdown
|
10
|
+
# https://confluence.atlassian.com/bitbucketserver/markdown-syntax-guide-776639995.html
|
11
|
+
class MarkdownConverter
|
12
|
+
CONVERTERS = %w[
|
13
|
+
convert_h1
|
14
|
+
convert_h2
|
15
|
+
convert_h3
|
16
|
+
convert_h4
|
17
|
+
convert_h5
|
18
|
+
convert_bold
|
19
|
+
convert_italic
|
20
|
+
convert_code
|
21
|
+
convert_unordered_list
|
22
|
+
].freeze
|
23
|
+
|
24
|
+
def convert(original_markdown)
|
25
|
+
return if original_markdown.nil?
|
26
|
+
|
27
|
+
output = original_markdown
|
28
|
+
|
29
|
+
CONVERTERS.each do |converter_method|
|
30
|
+
output = send(converter_method, output)
|
31
|
+
end
|
32
|
+
|
33
|
+
output
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def convert_h1(markdown)
|
39
|
+
markdown.gsub(/^(#)([^#].+)$/, 'h1.\2')
|
40
|
+
end
|
41
|
+
|
42
|
+
def convert_h2(markdown)
|
43
|
+
markdown.gsub(/^(##)([^\#].+)$/, 'h2.\2')
|
44
|
+
end
|
45
|
+
|
46
|
+
def convert_h3(markdown)
|
47
|
+
markdown.gsub(/^(###)([^\#].+)$/, 'h3.\2')
|
48
|
+
end
|
49
|
+
|
50
|
+
def convert_h4(markdown)
|
51
|
+
markdown.gsub(/^(####)([^\#].+)$/, 'h4.\2')
|
52
|
+
end
|
53
|
+
|
54
|
+
def convert_h5(markdown)
|
55
|
+
markdown.gsub(/^(#####)([^\#].+)$/, 'h5.\2')
|
56
|
+
end
|
57
|
+
|
58
|
+
def convert_bold(markdown)
|
59
|
+
markdown.gsub(/(\*\*)(\w+)(\*\*)/, '*\2*')
|
60
|
+
end
|
61
|
+
|
62
|
+
def convert_italic(markdown)
|
63
|
+
markdown.gsub(/(\*)(\w+)(\*)/, '_\2_')
|
64
|
+
end
|
65
|
+
|
66
|
+
def convert_code(markdown)
|
67
|
+
output_lines = []
|
68
|
+
|
69
|
+
markdown.each_line do |line|
|
70
|
+
if line =~ /^\~{3}\w+$/
|
71
|
+
language = line.gsub("~~~", "").strip
|
72
|
+
|
73
|
+
output_lines.push("{code:language=#{language}}\n")
|
74
|
+
elsif line =~ /^\~{3}$/
|
75
|
+
output_lines.push("{code}")
|
76
|
+
else
|
77
|
+
output_lines.push(line)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
output_lines.join
|
82
|
+
end
|
83
|
+
|
84
|
+
def convert_unordered_list(markdown)
|
85
|
+
markdown.gsub(/^\*\s(.+)$/, '- \1')
|
86
|
+
end
|
87
|
+
|
88
|
+
# TODO: add nested list convertion
|
89
|
+
# TODO: add numbered list convertion
|
90
|
+
|
91
|
+
# TODO: add emoji
|
92
|
+
# https://support.atlassian.com/confluence-cloud/docs/use-symbols-emojis-and-special-characters/
|
93
|
+
end
|
94
|
+
end
|
@@ -1,10 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "dbdoc/constants"
|
4
|
+
require_relative "../confluence/markdown_converter"
|
2
5
|
require_relative "../confluence/api"
|
3
6
|
|
4
|
-
module
|
7
|
+
module Confluence
|
8
|
+
# Confluence::Uploader class knows how to uploaded
|
9
|
+
# documentation to the Confluence Space provided in the config.yml.
|
10
|
+
#
|
11
|
+
# Uploader creates a root page with the database name from config.yml
|
12
|
+
# and creates nested pages for schemas and tables.
|
13
|
+
#
|
14
|
+
# A Confluence ID of each page created by dbdoc
|
15
|
+
# is logged to pages.yml file stored in the user's folder
|
16
|
+
# with the documentation.
|
5
17
|
class Uploader
|
6
|
-
def initialize(
|
7
|
-
@config =
|
18
|
+
def initialize(local_path: Dir.pwd)
|
19
|
+
@config = Dbdoc::Config.new(local_path: local_path).load
|
8
20
|
@confluence_api = Confluence::Api.new
|
9
21
|
@doc_folder = File.join(Dir.pwd, "doc")
|
10
22
|
end
|
@@ -14,24 +26,45 @@ module Dbdoc
|
|
14
26
|
delete_pages_for_dropped_schemas_or_tables
|
15
27
|
end
|
16
28
|
|
29
|
+
def space_pages
|
30
|
+
@confluence_api.existing_pages["results"]
|
31
|
+
end
|
32
|
+
|
33
|
+
def print_space_pages
|
34
|
+
space_pages.each do |page|
|
35
|
+
page_title = page["title"]
|
36
|
+
page_id = page["id"]
|
37
|
+
|
38
|
+
puts "#{page_title}: #{page_id}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
17
42
|
def clear_confluence_space
|
18
|
-
|
19
|
-
|
20
|
-
|
43
|
+
YAML.load(File.read(page_ids_file))
|
44
|
+
|
45
|
+
space_pages.each do |page|
|
46
|
+
page_key = page["title"]
|
47
|
+
page_id = page["id"]
|
48
|
+
|
49
|
+
puts "--> Deleting #{page_key} #{page_id}"
|
50
|
+
|
51
|
+
unlog_page_id(key: page_key) if @confluence_api.delete_page(page_id: page_id)
|
52
|
+
end
|
21
53
|
end
|
22
54
|
|
23
55
|
private
|
24
56
|
|
57
|
+
# rubocop:disable Metrics/AbcSize
|
25
58
|
def delete_pages_for_dropped_schemas_or_tables
|
26
59
|
uploaded_pages = YAML.load(File.read(page_ids_file))
|
27
60
|
|
28
|
-
uploaded_pages.each do |key,
|
61
|
+
uploaded_pages.each do |key, _params|
|
29
62
|
next if key == "root"
|
30
63
|
|
31
64
|
if key.start_with?("schema:")
|
32
65
|
schema_name = key.gsub("schema:", "")
|
33
66
|
|
34
|
-
unless Dir.
|
67
|
+
unless Dir.exist?(File.join(@doc_folder, schema_name))
|
35
68
|
page_id = uploaded_pages[key][:page_id]
|
36
69
|
puts "--> delete page #{key}: #{page_id}"
|
37
70
|
@confluence_api.delete_page(page_id: page_id)
|
@@ -40,7 +73,7 @@ module Dbdoc
|
|
40
73
|
elsif key.start_with?("table:")
|
41
74
|
schema_name, table_name = key.gsub("table:", "").split(".")
|
42
75
|
|
43
|
-
unless Dir.
|
76
|
+
unless Dir.exist?(File.join(@doc_folder, schema_name, table_name))
|
44
77
|
page_id = uploaded_pages[key][:page_id]
|
45
78
|
puts "--> delete page #{key}: #{page_id}"
|
46
79
|
@confluence_api.delete_page(page_id: page_id)
|
@@ -49,6 +82,7 @@ module Dbdoc
|
|
49
82
|
end
|
50
83
|
end
|
51
84
|
end
|
85
|
+
# rubocop:enable Metrics/AbcSize
|
52
86
|
|
53
87
|
def create_or_updates_pages
|
54
88
|
root_page_id = create_root_db_page[:page_id]
|
@@ -71,7 +105,7 @@ module Dbdoc
|
|
71
105
|
def page_ids_file
|
72
106
|
file = File.join(Dir.pwd, "page_ids.yml")
|
73
107
|
|
74
|
-
unless File.
|
108
|
+
unless File.exist?(file)
|
75
109
|
File.open(file, "w") do |f|
|
76
110
|
f.puts("--- {}")
|
77
111
|
end
|
@@ -97,7 +131,7 @@ module Dbdoc
|
|
97
131
|
version: 0
|
98
132
|
}
|
99
133
|
|
100
|
-
if page_ids
|
134
|
+
if page_ids.dig(key, :version).zero?
|
101
135
|
puts "--> create page #{key}: #{page_id}"
|
102
136
|
else
|
103
137
|
puts "--> update page #{key}: #{page_id}"
|
@@ -123,9 +157,11 @@ module Dbdoc
|
|
123
157
|
def create_root_db_page
|
124
158
|
page_id = latest_page_id(key: "root")
|
125
159
|
|
126
|
-
|
127
|
-
|
128
|
-
|
160
|
+
if page_id
|
161
|
+
return {
|
162
|
+
page_id: page_id
|
163
|
+
}
|
164
|
+
end
|
129
165
|
|
130
166
|
db_name = @config["db"]["name"]
|
131
167
|
@confluence_api.create_page(
|
@@ -162,37 +198,50 @@ module Dbdoc
|
|
162
198
|
end
|
163
199
|
end
|
164
200
|
|
201
|
+
def markdown(input)
|
202
|
+
Confluence::MarkdownConverter.new.convert(input)
|
203
|
+
end
|
204
|
+
|
205
|
+
# rubocop:disable Metrics/AbcSize
|
165
206
|
def upload_table(schema_name:, table_name:, schema_page_id:)
|
166
207
|
table_folder = File.join(@doc_folder, schema_name, table_name)
|
167
208
|
|
168
|
-
table_description = File.read(File.join(table_folder, "description.md"))
|
209
|
+
table_description = markdown(File.read(File.join(table_folder, "description.md")))
|
169
210
|
|
170
211
|
examples_folder = File.join(table_folder, "examples")
|
171
|
-
table_examples = Dir[File.join(examples_folder, "*.md")].map
|
212
|
+
table_examples = Dir[File.join(examples_folder, "*.md")].map do |f|
|
213
|
+
markdown(File.read(f))
|
214
|
+
end
|
172
215
|
|
173
|
-
columns_markdown_template_file = File.join(DBDOC_HOME, "doc_files", "columns.md.erb")
|
216
|
+
columns_markdown_template_file = File.join(Dbdoc::DBDOC_HOME, "doc_files", "columns.md.erb")
|
174
217
|
|
175
218
|
columns_table_template = ERB.new(
|
176
219
|
File.read(columns_markdown_template_file),
|
177
220
|
nil,
|
178
221
|
"-"
|
179
222
|
)
|
223
|
+
|
224
|
+
columns_doc = YAML.load(File.read(File.join(table_folder, "columns.yml")))
|
225
|
+
columns_doc.each do |col|
|
226
|
+
col[:description] = markdown(col[:description])
|
227
|
+
end
|
228
|
+
|
180
229
|
columns_table = columns_table_template.result_with_hash({
|
181
|
-
columns:
|
230
|
+
columns: columns_doc
|
182
231
|
})
|
183
232
|
|
184
|
-
page_body =
|
185
|
-
h2. Description
|
233
|
+
page_body = <<~MARKDOWN
|
234
|
+
h2. Description
|
186
235
|
|
187
|
-
#{table_description}
|
236
|
+
#{table_description}
|
188
237
|
|
189
|
-
h2. Columns
|
238
|
+
h2. Columns
|
190
239
|
|
191
|
-
#{columns_table}
|
240
|
+
#{columns_table}
|
192
241
|
|
193
|
-
h2. Examples
|
242
|
+
h2. Examples
|
194
243
|
|
195
|
-
#{table_examples.join("\n")
|
244
|
+
#{table_examples.join("\n")}
|
196
245
|
MARKDOWN
|
197
246
|
|
198
247
|
page_title = schema_name == "public" ? table_name : "#{schema_name}.#{table_name}"
|
@@ -201,7 +250,7 @@ h2. Examples
|
|
201
250
|
page_id = latest_page_id(key: page_key)
|
202
251
|
|
203
252
|
if page_id
|
204
|
-
|
253
|
+
@confluence_api.update_page(
|
205
254
|
page_id: page_id,
|
206
255
|
page_title: page_title,
|
207
256
|
body: page_body,
|
@@ -221,5 +270,6 @@ h2. Examples
|
|
221
270
|
log_page_id(key: "table:#{schema_name}.#{table_name}", page_id: table_page_id)
|
222
271
|
end
|
223
272
|
end
|
273
|
+
# rubocop:enable Metrics/AbcSize
|
224
274
|
end
|
225
275
|
end
|
data/lib/dbdoc.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "dbdoc/constants"
|
2
4
|
require "dbdoc/version"
|
3
5
|
require "dbdoc/config"
|
4
6
|
require "dbdoc/manager"
|
5
|
-
require "dbdoc/
|
7
|
+
require "dbdoc/folder_initializer"
|
8
|
+
require "confluence/uploader"
|
6
9
|
|
7
10
|
module Dbdoc
|
8
11
|
class Error < StandardError; end
|
data/lib/dbdoc/cli.rb
CHANGED
@@ -1,130 +1,116 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "optparse"
|
2
4
|
|
3
5
|
$LOAD_PATH << File.expand_path(__dir__)
|
4
6
|
|
5
7
|
module Dbdoc
|
6
8
|
class CLI
|
9
|
+
COMMANDS = {
|
10
|
+
install: %(
|
11
|
+
Generates all necessary config files and documentation folders.
|
12
|
+
|
13
|
+
Run this command in an empty directory.
|
14
|
+
),
|
15
|
+
query: %(
|
16
|
+
Prints a query that you need to run in the database \
|
17
|
+
you're going to document.
|
18
|
+
|
19
|
+
Export the result of this query to the "schema.csv" file \
|
20
|
+
and copy it over to the "schema" folder for processing.
|
21
|
+
),
|
22
|
+
plan: %(
|
23
|
+
Shows you what columns/tables/schemas are new and \
|
24
|
+
going to be added/deleted from the documentation.
|
25
|
+
),
|
26
|
+
apply: %(
|
27
|
+
Generates boilerplate documentation for newly added \
|
28
|
+
columns/tables/schemas.
|
29
|
+
|
30
|
+
Drops documentation for columns/tables/schemas that \
|
31
|
+
were deleted from the database.
|
32
|
+
),
|
33
|
+
"confluence:upload": %(
|
34
|
+
Uploads current documentation to Confluence: pages for \
|
35
|
+
new tables/schemas will be added, pages for dropped tables/schemas \
|
36
|
+
will be deleted from your Confluence space.
|
37
|
+
),
|
38
|
+
"confluece:pages": %(
|
39
|
+
Lists all pages in your dbdoc Confluence space \
|
40
|
+
(created manually or via dbdoc).
|
41
|
+
),
|
42
|
+
"confluence:clear": %(
|
43
|
+
IMPORTANT This command will delete ALL pages from \
|
44
|
+
the Confluence space (pages created via dbdoc AND pages that were added manually).
|
45
|
+
),
|
46
|
+
todo: %(
|
47
|
+
Shows you the documentation that needs to be written.
|
48
|
+
)
|
49
|
+
}.freeze
|
50
|
+
|
51
|
+
# rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
7
52
|
def run(args = [])
|
8
|
-
if args.first == "
|
9
|
-
|
10
|
-
|
11
|
-
schema_folder = File.join(Dir.pwd, "schema")
|
12
|
-
unless Dir.exists?(schema_folder)
|
13
|
-
Dir.mkdir(schema_folder)
|
14
|
-
end
|
15
|
-
|
16
|
-
doc_folder = File.join(Dir.pwd, "doc")
|
17
|
-
unless Dir.exists?(doc_folder)
|
18
|
-
Dir.mkdir(doc_folder)
|
19
|
-
end
|
20
|
-
|
21
|
-
target_file = File.join(Dir.pwd, "config.yml")
|
22
|
-
config_file = File.join(File.expand_path(__dir__), "../..", "config", "default.yml")
|
23
|
-
|
24
|
-
FileUtils.cp(config_file, target_file) unless File.exists?(target_file)
|
25
|
-
|
26
|
-
target_file = File.join(Dir.pwd, ".gitignore")
|
27
|
-
config_file = File.join(File.expand_path(__dir__), "../..", "config", "gitignore.template")
|
28
|
-
|
29
|
-
FileUtils.cp(config_file, target_file) unless File.exists?(target_file)
|
30
|
-
|
31
|
-
target_file = File.join(Dir.pwd, "confluence.yml")
|
32
|
-
config_file = File.join(File.expand_path(__dir__), "../..", "config", "confluence.yml")
|
33
|
-
|
34
|
-
FileUtils.cp(config_file, target_file) unless File.exists?(target_file)
|
35
|
-
|
36
|
-
0
|
53
|
+
if args.first == "install"
|
54
|
+
Dbdoc::FolderInitializer.new.init
|
37
55
|
elsif args.first == "query"
|
38
|
-
|
39
|
-
|
40
|
-
config = Dbdoc::Config.load
|
41
|
-
config.merge!(options)
|
42
|
-
|
43
|
-
db_type = config["db"]["type"]
|
44
|
-
query_file = File.join(File.expand_path(__dir__), "../..", "config", "schema_queries", "#{db_type}.sql")
|
45
|
-
query = File.read(query_file)
|
46
|
-
|
47
|
-
puts query
|
48
|
-
|
49
|
-
0
|
56
|
+
puts manager.query
|
50
57
|
elsif args.first == "plan"
|
51
|
-
|
58
|
+
plan = manager.plan
|
52
59
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
manager.plan
|
60
|
+
puts "--> New columns:"
|
61
|
+
plan[:new_columns].each do |column|
|
62
|
+
puts column
|
63
|
+
end
|
58
64
|
|
59
|
-
|
65
|
+
puts "--> Columns to drop:"
|
66
|
+
plan[:columns_to_drop].each do |column|
|
67
|
+
puts column
|
68
|
+
end
|
60
69
|
elsif args.first == "apply"
|
61
|
-
options = extract_options(args)
|
62
|
-
|
63
|
-
config = Dbdoc::Config.load
|
64
|
-
config.merge!(options)
|
65
|
-
|
66
|
-
manager = Dbdoc::Manager.new(config: config)
|
67
70
|
manager.apply
|
68
|
-
|
69
|
-
0
|
70
|
-
elsif args.first == "upload"
|
71
|
-
options = extract_options(args)
|
72
|
-
|
73
|
-
config = Dbdoc::Config.load
|
74
|
-
config.merge!(options)
|
75
|
-
|
76
|
-
uploader = Dbdoc::Uploader.new(config: config)
|
71
|
+
elsif args.first == "confluence:upload"
|
77
72
|
uploader.upload
|
78
|
-
|
79
|
-
|
80
|
-
elsif args.first == "
|
81
|
-
options = extract_options(args)
|
82
|
-
|
83
|
-
config = Dbdoc::Config.load
|
84
|
-
config.merge!(options)
|
85
|
-
|
86
|
-
uploader = Dbdoc::Uploader.new(config: config)
|
73
|
+
elsif args.first == "confluence:pages"
|
74
|
+
uploader.print_space_pages
|
75
|
+
elsif args.first == "confluence:clear"
|
87
76
|
uploader.clear_confluence_space
|
88
|
-
|
89
|
-
|
77
|
+
elsif args.first == "todo"
|
78
|
+
manager.todo
|
90
79
|
elsif args.first == "help"
|
91
|
-
|
92
|
-
|
93
|
-
|
80
|
+
print_help
|
81
|
+
elsif args.first == "version"
|
82
|
+
puts Dbdoc::VERSION
|
94
83
|
end
|
95
84
|
|
96
85
|
0
|
97
86
|
end
|
87
|
+
# rubocop:enable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
98
88
|
|
99
89
|
private
|
100
90
|
|
101
|
-
# This method is needed to unindent
|
102
|
-
# ["here document"](https://en.wikibooks.org/wiki/Ruby_Programming/Here_documents)
|
103
|
-
# help description.
|
104
|
-
#
|
105
91
|
def unindent(str)
|
106
92
|
str.gsub(/^#{str.scan(/^[ \t]+(?=\S)/).min}/, "")
|
107
93
|
end
|
108
94
|
|
109
|
-
def
|
110
|
-
|
111
|
-
|
112
|
-
OptionParser.new do |opts|
|
113
|
-
opts.banner = unindent(<<-TEXT)
|
114
|
-
dbdoc help
|
115
|
-
|
116
|
-
1. dbdoc query
|
95
|
+
def manager
|
96
|
+
@manager ||= Dbdoc::Manager.new
|
97
|
+
end
|
117
98
|
|
118
|
-
|
119
|
-
|
99
|
+
def uploader
|
100
|
+
@uploader ||= Confluence::Uploader.new
|
101
|
+
end
|
120
102
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
103
|
+
def print_help
|
104
|
+
puts unindent <<-TEXT
|
105
|
+
Usage: dbdoc [command]
|
106
|
+
TEXT
|
107
|
+
puts
|
126
108
|
|
127
|
-
|
109
|
+
COMMANDS.each do |command, description|
|
110
|
+
puts "dbdoc #{command}"
|
111
|
+
puts
|
112
|
+
puts unindent(description)
|
113
|
+
end
|
128
114
|
end
|
129
115
|
end
|
130
116
|
end
|
data/lib/dbdoc/config.rb
CHANGED
@@ -1,27 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "yaml"
|
2
4
|
require "dbdoc/constants"
|
3
5
|
|
4
6
|
module Dbdoc
|
7
|
+
# Dbdoc::Config class knows how to load the default config from the
|
8
|
+
# dbdoc gem folder. Later, if needed, this class could be used to merge
|
9
|
+
# user-defined config with the default one.
|
5
10
|
class Config
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
class << self
|
10
|
-
# Be default gem will try to load config file in user's project folder.
|
11
|
-
# Then user's config (or empty object) will be merge with the default config
|
12
|
-
# from gem's folder.
|
13
|
-
#
|
14
|
-
def load
|
15
|
-
user_config = File.exist?(user_file) ? YAML.safe_load(File.read(user_file)) : {}
|
16
|
-
default_config = YAML.safe_load(File.read(DEFAULT_FILE))
|
17
|
-
|
18
|
-
default_config.merge(user_config)
|
19
|
-
end
|
11
|
+
def initialize(local_path: Dir.pwd)
|
12
|
+
@local_path = local_path
|
13
|
+
end
|
20
14
|
|
21
|
-
|
15
|
+
def load
|
16
|
+
local_config_file = File.join(@local_path, "config.yml")
|
22
17
|
|
23
|
-
|
24
|
-
File.
|
18
|
+
if File.exist?(local_config_file)
|
19
|
+
YAML.load(File.read(local_config_file))
|
20
|
+
else
|
21
|
+
{}
|
25
22
|
end
|
26
23
|
end
|
27
24
|
end
|
data/lib/dbdoc/constants.rb
CHANGED
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "yaml"
|
4
|
+
require "fileutils"
|
5
|
+
require "dbdoc/constants"
|
6
|
+
|
7
|
+
module Dbdoc
|
8
|
+
# Dbdoc::FolderInitializer class knows how to turn an emtpy
|
9
|
+
# folder into a dbdoc folder.
|
10
|
+
#
|
11
|
+
class FolderInitializer
|
12
|
+
def initialize(local_path: Dir.pwd)
|
13
|
+
@config = Dbdoc::Config.new(local_path: local_path).load
|
14
|
+
end
|
15
|
+
|
16
|
+
def init
|
17
|
+
create_schema_folder
|
18
|
+
create_doc_folder
|
19
|
+
create_config_file
|
20
|
+
create_gitignore_file
|
21
|
+
create_confluence_config_file
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
# schema folder is the one user copies the schema.csv to
|
27
|
+
# before updating/generating documentation
|
28
|
+
def create_schema_folder
|
29
|
+
schema_folder = File.join(Dir.pwd, "schema")
|
30
|
+
Dir.mkdir(schema_folder) unless Dir.exist?(schema_folder)
|
31
|
+
end
|
32
|
+
|
33
|
+
# doc folder stores all the database documentation files
|
34
|
+
def create_doc_folder
|
35
|
+
doc_folder = File.join(Dir.pwd, "doc")
|
36
|
+
Dir.mkdir(doc_folder) unless Dir.exist?(doc_folder)
|
37
|
+
end
|
38
|
+
|
39
|
+
def create_file(default_file_name, target_file_name)
|
40
|
+
target_file = File.join(Dir.pwd, target_file_name)
|
41
|
+
|
42
|
+
return if File.exist?(target_file)
|
43
|
+
|
44
|
+
config_file = File.join(File.expand_path(__dir__), "../..", "config", default_file_name)
|
45
|
+
|
46
|
+
FileUtils.cp(config_file, target_file)
|
47
|
+
end
|
48
|
+
|
49
|
+
def create_config_file
|
50
|
+
create_file("default.yml", "config.yml")
|
51
|
+
end
|
52
|
+
|
53
|
+
def create_gitignore_file
|
54
|
+
create_file("gitignore.template", ".gitignore")
|
55
|
+
end
|
56
|
+
|
57
|
+
def create_confluence_config_file
|
58
|
+
create_file("confluence.yml", "confluence.yml")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/dbdoc/manager.rb
CHANGED
@@ -1,30 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "yaml"
|
4
|
+
require "erb"
|
5
|
+
require "fileutils"
|
2
6
|
require "dbdoc/constants"
|
3
7
|
|
4
8
|
module Dbdoc
|
9
|
+
# Dbdoc::Manager class manages database schema documentation.
|
10
|
+
#
|
11
|
+
# It knows how to generate and update documentation based on the database
|
12
|
+
# schema generated by the schema query for user's database.
|
5
13
|
class Manager
|
6
|
-
def initialize(
|
7
|
-
@
|
14
|
+
def initialize(local_path: Dir.pwd)
|
15
|
+
@local_path = local_path
|
16
|
+
@config = Dbdoc::Config.new(local_path: local_path).load
|
8
17
|
end
|
9
18
|
|
10
|
-
def plan
|
11
|
-
|
12
|
-
puts
|
13
|
-
puts
|
14
|
-
|
15
|
-
input_schema = read_input_schema.map { |r| r.first(4) }.map { |r| r.join(":") }
|
19
|
+
def plan
|
20
|
+
input_schema = read_input_schema.map { |r| r.first(4).join(":") }
|
16
21
|
current_schema = read_documented_schema
|
17
22
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
23
|
+
{
|
24
|
+
new_columns: input_schema - current_schema,
|
25
|
+
columns_to_drop: current_schema - input_schema
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
def todo
|
30
|
+
doc_folder_files = File.join(@local_path, "doc", "**/*")
|
31
|
+
|
32
|
+
Dir[doc_folder_files].each do |file|
|
33
|
+
next if file == "."
|
34
|
+
next if file == ".."
|
35
|
+
next if File.directory?(file)
|
22
36
|
|
23
|
-
|
24
|
-
|
37
|
+
File.read(file).split("\n").each_with_index do |line, i|
|
38
|
+
next unless line.include?("TODO")
|
39
|
+
|
40
|
+
relative_path = file.gsub(@local_path, "")
|
41
|
+
|
42
|
+
puts "#{relative_path}:#{i + 1}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def query
|
48
|
+
db_type = @config["db"]["type"]
|
49
|
+
query_file = File.join(File.expand_path(__dir__), "../..", "config", "schema_queries", "#{db_type}.sql")
|
50
|
+
|
51
|
+
File.read(query_file)
|
25
52
|
end
|
26
53
|
|
27
|
-
|
54
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/AbcSize, Metrics/PerceivedComplexity
|
55
|
+
def apply
|
28
56
|
puts "--> APPLY"
|
29
57
|
puts
|
30
58
|
puts
|
@@ -35,14 +63,16 @@ module Dbdoc
|
|
35
63
|
added_columns = input_schema - current_schema
|
36
64
|
dropped_columns = current_schema - input_schema
|
37
65
|
|
38
|
-
doc_folder = File.join(
|
66
|
+
doc_folder = File.join(@local_path, "doc")
|
67
|
+
|
68
|
+
Dir.mkdir(doc_folder) unless Dir.exist?(doc_folder)
|
39
69
|
|
40
70
|
## DROP COLUMNS
|
41
71
|
dropped_columns.each do |column|
|
42
|
-
schema_name, table_name, column_name
|
72
|
+
schema_name, table_name, column_name = column.split(":")
|
43
73
|
|
44
74
|
columns_file = File.join(doc_folder, schema_name, table_name, "columns.yml")
|
45
|
-
next unless File.
|
75
|
+
next unless File.exist?(columns_file)
|
46
76
|
|
47
77
|
columns = YAML.load(File.read(columns_file))
|
48
78
|
columns.reject! { |c| c[:name] == column_name }
|
@@ -69,7 +99,7 @@ module Dbdoc
|
|
69
99
|
next unless File.directory?(table_folder)
|
70
100
|
|
71
101
|
columns_file = File.join(table_folder, "columns.yml")
|
72
|
-
next unless File.
|
102
|
+
next unless File.exist?(columns_file)
|
73
103
|
|
74
104
|
columns = YAML.load(File.read(columns_file))
|
75
105
|
|
@@ -93,16 +123,18 @@ module Dbdoc
|
|
93
123
|
|
94
124
|
create_new_columns(added_columns)
|
95
125
|
end
|
126
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/AbcSize, Metrics/PerceivedComplexity
|
96
127
|
|
97
128
|
private
|
98
129
|
|
99
130
|
def input_schema
|
100
|
-
File.read(File.join(
|
131
|
+
File.read(File.join(@local_path, "schema", "schema.csv"))
|
101
132
|
end
|
102
133
|
|
134
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/AbcSize, Metrics/PerceivedComplexity
|
103
135
|
def read_input_schema
|
104
136
|
rows = input_schema.split("\n")
|
105
|
-
with_header = rows[0].include?("
|
137
|
+
with_header = rows[0].include?("table_schema")
|
106
138
|
|
107
139
|
rows.shift if with_header
|
108
140
|
|
@@ -110,38 +142,37 @@ module Dbdoc
|
|
110
142
|
r.split(",").map(&:strip).map { |c| c.gsub('"', "") }.first(5)
|
111
143
|
end
|
112
144
|
|
113
|
-
config
|
114
|
-
|
115
|
-
if @config["ignorelist"]
|
116
|
-
@config["ignorelist"].map { |r| r.split(/[\.\#]/) }.each do |b|
|
117
|
-
schema_pattern, table_pattern, column_pattern = b
|
145
|
+
@config["ignorelist"]&.map { |r| r.split(/[\.\#]/) }&.each do |b|
|
146
|
+
schema_pattern, table_pattern, column_pattern = b
|
118
147
|
|
119
|
-
|
120
|
-
|
148
|
+
rows.reject! do |row|
|
149
|
+
schema_name, table_name, column_name, = row
|
121
150
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
if table_pattern
|
127
|
-
next unless table_name =~ Regexp.new(table_pattern.gsub("*", ".*"))
|
128
|
-
end
|
151
|
+
if column_pattern
|
152
|
+
next unless column_name =~ Regexp.new(column_pattern.gsub("*", ".*"))
|
153
|
+
end
|
129
154
|
|
130
|
-
|
131
|
-
|
132
|
-
|
155
|
+
if table_pattern
|
156
|
+
next unless table_name =~ Regexp.new(table_pattern.gsub("*", ".*"))
|
157
|
+
end
|
133
158
|
|
134
|
-
|
159
|
+
if schema_pattern
|
160
|
+
next unless schema_name =~ Regexp.new(schema_pattern.gsub("*", ".*"))
|
135
161
|
end
|
162
|
+
|
163
|
+
true
|
136
164
|
end
|
137
165
|
end
|
138
166
|
|
139
167
|
rows
|
140
168
|
end
|
169
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/AbcSize, Metrics/PerceivedComplexity
|
141
170
|
|
171
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/AbcSize, Metrics/PerceivedComplexity
|
142
172
|
def read_documented_schema
|
143
|
-
doc_folder = File.join(
|
173
|
+
doc_folder = File.join(@local_path, "doc")
|
144
174
|
|
175
|
+
return [] unless Dir.exist?(doc_folder)
|
145
176
|
return [] if Dir.empty?(doc_folder)
|
146
177
|
|
147
178
|
keys = []
|
@@ -160,9 +191,9 @@ module Dbdoc
|
|
160
191
|
next unless File.directory?(table_folder)
|
161
192
|
|
162
193
|
columns_file = File.join(table_folder, "columns.yml")
|
163
|
-
next unless File.
|
194
|
+
next unless File.exist?(columns_file)
|
164
195
|
|
165
|
-
columns = YAML.load(File.read(columns_file))
|
196
|
+
columns = YAML.load(File.read(columns_file), [Symbol])
|
166
197
|
columns.each do |column|
|
167
198
|
keys.push([
|
168
199
|
schema_name,
|
@@ -176,9 +207,11 @@ module Dbdoc
|
|
176
207
|
|
177
208
|
keys
|
178
209
|
end
|
210
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/AbcSize, Metrics/PerceivedComplexity
|
179
211
|
|
212
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/AbcSize
|
180
213
|
def create_new_columns(added_columns)
|
181
|
-
doc_folder = File.join(
|
214
|
+
doc_folder = File.join(@local_path, "doc")
|
182
215
|
|
183
216
|
added_columns.map! { |r| r.split(":") }
|
184
217
|
new_columns = read_input_schema.select do |row|
|
@@ -224,17 +257,18 @@ module Dbdoc
|
|
224
257
|
# 4. create table columns.yml
|
225
258
|
columns_yaml = File.join(table_folder, "columns.yml")
|
226
259
|
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
260
|
+
next if File.exist?(columns_yaml)
|
261
|
+
|
262
|
+
columns_erb_tamplate_file = File.join(DBDOC_HOME, "doc_files", "columns.yml.erb")
|
263
|
+
columns_yaml_template = ERB.new(File.read(columns_erb_tamplate_file), nil, "-")
|
264
|
+
File.open(columns_yaml, "w") do |f|
|
265
|
+
f.puts columns_yaml_template.result_with_hash({
|
266
|
+
columns: columns
|
267
|
+
})
|
235
268
|
end
|
236
269
|
end
|
237
270
|
end
|
238
271
|
end
|
272
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/AbcSize
|
239
273
|
end
|
240
274
|
end
|
data/lib/dbdoc/version.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dbdoc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Anatoli Makarevich
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
12
|
-
dependencies:
|
11
|
+
date: 2020-09-01 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: httparty
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.18'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.18'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: kramdown
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.3'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.3'
|
13
41
|
description: Dbdoc is a tool to keep your database documentation up-to-date and version
|
14
42
|
controlled.
|
15
43
|
email:
|
@@ -19,6 +47,7 @@ executables:
|
|
19
47
|
extensions: []
|
20
48
|
extra_rdoc_files: []
|
21
49
|
files:
|
50
|
+
- ".github/FUNDING.yml"
|
22
51
|
- ".gitignore"
|
23
52
|
- ".rspec"
|
24
53
|
- ".rubocop.yml"
|
@@ -43,12 +72,14 @@ files:
|
|
43
72
|
- doc_files/table_description.md
|
44
73
|
- doc_files/table_example.md
|
45
74
|
- lib/confluence/api.rb
|
75
|
+
- lib/confluence/markdown_converter.rb
|
76
|
+
- lib/confluence/uploader.rb
|
46
77
|
- lib/dbdoc.rb
|
47
78
|
- lib/dbdoc/cli.rb
|
48
79
|
- lib/dbdoc/config.rb
|
49
80
|
- lib/dbdoc/constants.rb
|
81
|
+
- lib/dbdoc/folder_initializer.rb
|
50
82
|
- lib/dbdoc/manager.rb
|
51
|
-
- lib/dbdoc/uploader.rb
|
52
83
|
- lib/dbdoc/version.rb
|
53
84
|
homepage: https://github.com/sqlhabit/dbdoc
|
54
85
|
licenses:
|