giblish 0.8.2 → 1.0.0.rc2

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 (113) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/unit_tests.yml +30 -0
  3. data/.gitignore +7 -3
  4. data/.ruby-version +1 -1
  5. data/Changelog.adoc +61 -0
  6. data/README.adoc +267 -0
  7. data/docs/concepts/text_search.adoc +213 -0
  8. data/docs/concepts/text_search_im/cgi-search_request.puml +35 -0
  9. data/docs/concepts/text_search_im/cgi-search_request.svg +397 -0
  10. data/docs/concepts/text_search_im/search_request.puml +40 -0
  11. data/docs/concepts/text_search_im/search_request.svg +408 -0
  12. data/docs/howtos/trigger_generation.adoc +180 -0
  13. data/docs/{setup_server_assets → howtos/trigger_generation_im}/Render Documents.png +0 -0
  14. data/docs/{setup_server_assets → howtos/trigger_generation_im}/View Documents.png +0 -0
  15. data/docs/{setup_server_assets → howtos/trigger_generation_im}/deploy_with_hooks.graphml +0 -0
  16. data/docs/{setup_server_assets → howtos/trigger_generation_im}/deploy_with_hooks.svg +0 -0
  17. data/docs/{setup_server_assets → howtos/trigger_generation_im}/deploy_with_jenkins.graphml +0 -0
  18. data/docs/{setup_server_assets → howtos/trigger_generation_im}/deploy_with_jenkins.svg +0 -0
  19. data/docs/howtos/trigger_generation_im/docgen_github.puml +51 -0
  20. data/docs/{setup_server_assets → howtos/trigger_generation_im}/giblish_deployment.graphml +0 -0
  21. data/docs/howtos/trigger_generation_im/post-receive-example.sh +50 -0
  22. data/docs/reference/box_flow_spec.adoc +22 -0
  23. data/docs/reference/search_spec.adoc +185 -0
  24. data/giblish.gemspec +47 -29
  25. data/lib/giblish/adocsrc_providers.rb +23 -0
  26. data/lib/giblish/application.rb +214 -41
  27. data/lib/giblish/cmdline.rb +273 -259
  28. data/lib/giblish/config_utils.rb +41 -0
  29. data/lib/giblish/configurator.rb +163 -0
  30. data/lib/giblish/conversion_info.rb +120 -0
  31. data/lib/giblish/docattr_providers.rb +125 -0
  32. data/lib/giblish/docid/docid.rb +181 -0
  33. data/lib/giblish/github_trigger/webhook_manager.rb +64 -0
  34. data/lib/giblish/gitrepos/checkoutmanager.rb +124 -0
  35. data/lib/giblish/{gititf.rb → gitrepos/gititf.rb} +30 -4
  36. data/lib/giblish/gitrepos/gitsummary.erb +61 -0
  37. data/lib/giblish/gitrepos/gitsummaryprovider.rb +78 -0
  38. data/lib/giblish/gitrepos/history_pb.rb +41 -0
  39. data/lib/giblish/indexbuilders/d3treegraph.rb +88 -0
  40. data/lib/giblish/indexbuilders/depgraphbuilder.rb +109 -0
  41. data/lib/giblish/indexbuilders/dotdigraphadoc.rb +174 -0
  42. data/lib/giblish/indexbuilders/standard_index.erb +10 -0
  43. data/lib/giblish/indexbuilders/subtree_indices.rb +132 -0
  44. data/lib/giblish/indexbuilders/templates/circles.html.erb +111 -0
  45. data/lib/giblish/indexbuilders/templates/flame.html.erb +61 -0
  46. data/lib/giblish/indexbuilders/templates/tree.html.erb +366 -0
  47. data/lib/giblish/indexbuilders/templates/treemap.html.erb +127 -0
  48. data/lib/giblish/indexbuilders/verbatimtree.rb +94 -0
  49. data/lib/giblish/pathtree.rb +473 -74
  50. data/lib/giblish/resourcepaths.rb +150 -0
  51. data/lib/giblish/search/expand_adoc.rb +55 -0
  52. data/lib/giblish/search/headingindexer.rb +312 -0
  53. data/lib/giblish/search/request_manager.rb +110 -0
  54. data/lib/giblish/search/searchquery.rb +68 -0
  55. data/lib/giblish/search/textsearcher.rb +349 -0
  56. data/lib/giblish/subtreeinfobuilder.rb +77 -0
  57. data/lib/giblish/treeconverter.rb +272 -0
  58. data/lib/giblish/utils.rb +142 -294
  59. data/lib/giblish/version.rb +1 -1
  60. data/lib/giblish.rb +10 -7
  61. data/scripts/hooks/post-receive.example +66 -0
  62. data/{docgen/scripts/githook_examples → scripts/hooks}/post-update.example +0 -0
  63. data/{docgen → scripts}/resources/css/adoc-colony.css +0 -0
  64. data/scripts/resources/css/giblish-serif.css +419 -0
  65. data/scripts/resources/css/giblish.css +1979 -419
  66. data/{docgen → scripts}/resources/fonts/Ubuntu-B.ttf +0 -0
  67. data/{docgen → scripts}/resources/fonts/Ubuntu-BI.ttf +0 -0
  68. data/{docgen → scripts}/resources/fonts/Ubuntu-R.ttf +0 -0
  69. data/{docgen → scripts}/resources/fonts/Ubuntu-RI.ttf +0 -0
  70. data/{docgen → scripts}/resources/fonts/mplus1p-regular-fallback.ttf +0 -0
  71. data/{docgen → scripts}/resources/images/giblish_logo.png +0 -0
  72. data/{docgen → scripts}/resources/images/giblish_logo.svg +0 -0
  73. data/{docgen → scripts}/resources/themes/giblish.yml +0 -0
  74. data/scripts/wserv_development.rb +32 -0
  75. data/web_apps/cgi_search/gibsearch.rb +43 -0
  76. data/web_apps/gh_webhook_trigger/config.ru +2 -0
  77. data/web_apps/gh_webhook_trigger/gh_webhook_trigger.rb +73 -0
  78. data/web_apps/gh_webhook_trigger/public/dummy.txt +3 -0
  79. data/web_apps/sinatra_search/config.ru +2 -0
  80. data/web_apps/sinatra_search/public/dummy.txt +3 -0
  81. data/web_apps/sinatra_search/sinatra_search.rb +34 -0
  82. data/web_apps/sinatra_search/tmp/restart.txt +0 -0
  83. metadata +168 -73
  84. data/.rubocop.yml +0 -7
  85. data/.travis.yml +0 -3
  86. data/Changelog +0 -16
  87. data/Gemfile +0 -4
  88. data/README.adoc +0 -1
  89. data/Rakefile +0 -41
  90. data/bin/console +0 -14
  91. data/bin/setup +0 -8
  92. data/data/testdocs/malformed/no_header.adoc +0 -5
  93. data/data/testdocs/toplevel.adoc +0 -19
  94. data/data/testdocs/wellformed/adorned_purpose.adoc +0 -17
  95. data/data/testdocs/wellformed/docidtest/docid_1.adoc +0 -24
  96. data/data/testdocs/wellformed/docidtest/docid_2.adoc +0 -8
  97. data/data/testdocs/wellformed/simple.adoc +0 -14
  98. data/data/testdocs/wellformed/source_highlighting/highlight_source.adoc +0 -38
  99. data/docgen/resources/css/giblish.css +0 -1979
  100. data/docgen/scripts/Jenkinsfile +0 -18
  101. data/docgen/scripts/gen_adoc_org.sh +0 -58
  102. data/docs/README.adoc +0 -387
  103. data/docs/setup_server.adoc +0 -202
  104. data/lib/giblish/buildgraph.rb +0 -216
  105. data/lib/giblish/buildindex.rb +0 -459
  106. data/lib/giblish/core.rb +0 -451
  107. data/lib/giblish/docconverter.rb +0 -308
  108. data/lib/giblish/docid.rb +0 -180
  109. data/lib/giblish/docinfo.rb +0 -75
  110. data/lib/giblish/indexheadings.rb +0 -251
  111. data/lib/giblish-search.cgi +0 -459
  112. data/scripts/hooks/post-receive +0 -57
  113. data/scripts/publish_html.sh +0 -99
data/lib/giblish/core.rb DELETED
@@ -1,451 +0,0 @@
1
- require "find"
2
- require "fileutils"
3
- require "logger"
4
- require "pathname"
5
-
6
- require_relative "buildindex"
7
- require_relative "docconverter"
8
- require_relative "docid"
9
- require_relative "indexheadings"
10
- require_relative "docinfo"
11
- require_relative "buildgraph"
12
-
13
- module Giblish
14
- # Parse a directory tree and convert all asciidoc files matching the
15
- # supplied critera to the supplied format
16
- class FileTreeConverter
17
- attr_reader :converter
18
-
19
- # Required options:
20
- # srcDirRoot
21
- # dstDirRoot
22
- # resourceDir
23
- def initialize(options)
24
- @options = options.dup
25
-
26
- @paths = Giblish::PathManager.new(
27
- @options[:srcDirRoot],
28
- @options[:dstDirRoot],
29
- @options[:resourceDir],
30
- @options[:makeSearchable]
31
- )
32
-
33
- # set the path to the search data that will be sent to the cgi search script
34
- deploy_search_path = if @options[:makeSearchable]
35
- if @options[:searchAssetsDeploy].nil?
36
- @paths.search_assets_abs
37
- else
38
- Pathname.new(@options[:searchAssetsDeploy]).join("search_assets")
39
- end
40
- end
41
-
42
- @deploy_info = Giblish::DeploymentPaths.new(
43
- @options[:webPath],
44
- deploy_search_path
45
- )
46
- @processed_docs = []
47
- @converter = converter_factory
48
- end
49
-
50
- # convert all adoc files
51
- # return true if all conversions went ok, false if at least one
52
- # failed
53
- def convert
54
- # collect all doc ids and enable replacement of known doc ids with
55
- # valid references to adoc files
56
- manage_doc_ids if @options[:resolveDocid]
57
-
58
- # register add-on for handling searchability
59
- manage_searchability(@options) if @options[:makeSearchable]
60
-
61
- # traverse the src file tree and convert all files deemed as
62
- # adoc files
63
- conv_error = false
64
- if @paths.src_root_abs.directory?
65
- Find.find(@paths.src_root_abs) do |path|
66
- p = Pathname.new(path)
67
- begin
68
- to_asciidoc(p) if adocfile? p
69
- rescue StandardError => e
70
- str = String.new("Error when converting file "\
71
- "#{path}: #{e.message}\nBacktrace:\n")
72
- e.backtrace.each { |l| str << " #{l}\n" }
73
- Giblog.logger.error { str }
74
- conv_error = true
75
- end
76
- end
77
- end
78
-
79
- # create necessary search assets if needed
80
- create_search_assets if @options[:makeSearchable]
81
-
82
- # build index and other fancy stuff if not suppressed
83
- unless @options[:suppressBuildRef]
84
- # build a dependency graph (only if we resolve docids...)
85
- dep_graph_exist = @options[:resolveDocid] && build_graph_page
86
-
87
- # build a reference index
88
- build_index_page(dep_graph_exist)
89
- end
90
- conv_error
91
- end
92
-
93
- protected
94
-
95
- def build_graph_page
96
- begin
97
- adoc_logger = Giblish::AsciidoctorLogger.new Logger::Severity::WARN
98
- gb = graph_builder_factory
99
- errors = @converter.convert_str(
100
- gb.source(make_searchable: @options[:makeSearchable]),
101
- @paths.dst_root_abs,
102
- "graph",
103
- logger: adoc_logger
104
- )
105
- gb.cleanup
106
- !errors
107
- rescue StandardError => e
108
- Giblog.logger.warn { e.message }
109
- Giblog.logger.warn { "The dependency graph will not be generated !!" }
110
- end
111
- false
112
- end
113
-
114
- def build_index_page(dep_graph_exist)
115
- # build a reference index
116
- adoc_logger = Giblish::AsciidoctorLogger.new Logger::Severity::WARN
117
- ib = index_factory
118
- @converter.convert_str(
119
- ib.source(
120
- dep_graph_exists: dep_graph_exist,
121
- make_searchable: @options[:makeSearchable]
122
- ),
123
- @paths.dst_root_abs,
124
- @options[:indexBaseName],
125
- logger: adoc_logger
126
- )
127
-
128
- # clean up cached files and adoc resources
129
- GC.start
130
- end
131
-
132
- # get the correct index builder type depending on supplied
133
- # user options
134
- def index_factory
135
- raise "Internal logic error!" if @options[:suppressBuildRef]
136
-
137
- SimpleIndexBuilder.new(@processed_docs, @converter, @paths, @deploy_info,
138
- @options[:resolveDocid])
139
- end
140
-
141
- def graph_builder_factory
142
- Giblish::GraphBuilderGraphviz.new @processed_docs, @paths, @deploy_info,
143
- @converter.converter_options
144
- end
145
-
146
- # get the correct converter type
147
- def converter_factory
148
- case @options[:format]
149
- when "html"
150
- HtmlConverter.new @paths, @deploy_info, @options
151
- when "pdf"
152
- PdfConverter.new @paths, @deploy_info, @options
153
- else
154
- raise ArgumentError, "Unknown conversion format: #{@options[:format]}"
155
- end
156
- end
157
-
158
- # creates a DocInfo instance, fills it with basic info and
159
- # returns the filled in instance so that derived implementations can
160
- # add more data
161
- def add_doc(adoc, adoc_stderr)
162
- Giblog.logger.debug do
163
- "Adding adoc: #{adoc} Asciidoctor stderr: #{adoc_stderr}"
164
- end
165
- Giblog.logger.debug { "Doc attributes: #{adoc.attributes}" }
166
-
167
- info = DocInfo.new(adoc: adoc, dst_root_abs: @paths.dst_root_abs, adoc_stderr: adoc_stderr)
168
- @processed_docs << info
169
- info
170
- end
171
-
172
- def add_doc_fail(filepath, exception)
173
- info = DocInfo.new
174
-
175
- # the only info we have is the source file name
176
- info.converted = false
177
- info.src_file = filepath.to_s
178
- info.error_msg = exception.message
179
-
180
- @processed_docs << info
181
- info
182
- end
183
-
184
- private
185
-
186
- # convert a single adoc doc to whatever the user wants
187
- def to_asciidoc(filepath)
188
- adoc_logger = Giblish::AsciidoctorLogger.new Logger::Severity::WARN
189
- adoc = @converter.convert(filepath, logger: adoc_logger)
190
-
191
- add_doc(adoc, adoc_logger.user_info_str.string)
192
- rescue StandardError => e
193
- add_doc_fail(filepath, e)
194
- raise
195
- end
196
-
197
- # predicate that decides if a path is a asciidoc file or not
198
- def adocfile?(path)
199
- fs = path.to_s
200
- unless @options[:excludeRegexp].nil?
201
- # exclude file if user wishes
202
- er = Regexp.new @options[:excludeRegexp]
203
- return false unless er.match(fs).nil?
204
- end
205
-
206
- # only include files matching the include regexp
207
- ir = Regexp.new @options[:includeRegexp]
208
- !ir.match(fs).nil?
209
- end
210
-
211
- def manage_searchability(opts)
212
- # register the extension
213
- Giblish.register_index_heading_extension
214
-
215
- # make sure we start from a clean slate
216
- IndexHeadings.clear_index
217
-
218
- # propagate user-given id attributes to the indexing class
219
- # if there are any
220
- attr = opts[:attributes]
221
- return if attr.nil?
222
-
223
- IndexHeadings.id_elements[:id_prefix] = attr["idprefix"] if attr.key?("idprefix")
224
- IndexHeadings.id_elements[:id_separator] = attr["idseparator"] if attr.key?("idseparator")
225
- end
226
-
227
- # top_dir
228
- # |- web_assets
229
- # |- branch_1_top_dir
230
- # | |- index.html
231
- # | |- file1.html
232
- # | |- dir_1
233
- # | | |- file2.html
234
- # |- search_assets
235
- # | |- branch_1
236
- # | |- heading_index.json
237
- # | |- file1.adoc
238
- # | |- dir_1
239
- # | | |- file2.html
240
- # | |- ...
241
- # | |- branch_2
242
- # | | ...
243
- # |- branch_2_top_dir
244
- # | ...
245
- def create_search_assets
246
- # get the proper dir for the search assets
247
- assets_dir = @paths.search_assets_abs
248
-
249
- # store the JSON file
250
- IndexHeadings.serialize assets_dir, @paths.src_root_abs
251
-
252
- # traverse the src file tree and copy all published adoc files
253
- # to the search_assets dir
254
- return unless @paths.src_root_abs.directory?
255
-
256
- Find.find(@paths.src_root_abs) do |path|
257
- p = Pathname.new(path)
258
- next unless adocfile? p
259
-
260
- dst_dir = assets_dir.join(@paths.reldir_from_src_root(p))
261
- FileUtils.mkdir_p(dst_dir)
262
- FileUtils.cp(p.to_s, dst_dir)
263
- end
264
- end
265
-
266
- # Register the asciidoctor extension that handles doc ids and traverse
267
- # the source tree to collect all :docid: attributes found in document
268
- # headers.
269
- def manage_doc_ids
270
- # Register the docid preprocessor hook
271
- Giblish.register_docid_extension
272
-
273
- # Make sure that no prior docid's are hangning around
274
- DocidCollector.clear_cache
275
- DocidCollector.clear_deps
276
- idc = DocidCollector.new
277
-
278
- # traverse the src file tree and collect ids from all
279
- # .adoc or .ADOC files
280
- if @paths.src_root_abs.directory?
281
- Find.find(@paths.src_root_abs) do |path|
282
- p = Pathname.new(path)
283
- idc.parse_file(p) if adocfile? p
284
- end
285
- end
286
- idc
287
- end
288
- end
289
-
290
- # Converts all adoc files within a git repo
291
- class GitRepoConverter < FileTreeConverter
292
- def initialize(options)
293
- super(options)
294
- # cache the top of the tree since we need to redefine the
295
- # paths per branch/tag later on.
296
- @master_paths = @paths.dup
297
- @master_deployment_info = @deploy_info.dup
298
- @git_repo_root = options[:gitRepoRoot]
299
- @git_repo = init_git_repo @git_repo_root, options[:localRepoOnly]
300
- @user_branches = select_user_branches(options[:gitBranchRegexp])
301
- @user_tags = select_user_tags(options[:gitTagRegexp])
302
- end
303
-
304
- # Convert the docs from each branch/tag and add info to the
305
- # summary page.
306
- # return true if all conversions went ok, false if at least one
307
- # failed
308
- def convert
309
- conv_error = false
310
- (@user_branches + @user_tags).each do |co|
311
- has_error = convert_one_checkout(co)
312
- if has_error == true
313
- conv_error = true
314
- end
315
- rescue
316
- conv_error = true
317
- next
318
- end
319
-
320
- # Render the summary page
321
- index_builder = GitSummaryIndexBuilder.new @git_repo,
322
- @user_branches,
323
- @user_tags
324
-
325
- conv_error ||= @converter.convert_str(
326
- index_builder.source,
327
- @master_paths.dst_root_abs,
328
- "index"
329
- )
330
-
331
- # clean up
332
- GC.start
333
-
334
- conv_error
335
- end
336
-
337
- protected
338
-
339
- def index_factory
340
- GitRepoIndexBuilder.new(@processed_docs, @converter, @paths, @deploy_info,
341
- @options[:resolveDocid], @options[:gitRepoRoot])
342
- end
343
-
344
- def graph_builder_factory
345
- Giblish::GitGraphBuilderGraphviz.new @processed_docs, @paths, @deploy_info,
346
- @converter.converter_options, @git_repo
347
- end
348
-
349
- def add_doc(adoc, adoc_stderr)
350
- info = super(adoc, adoc_stderr)
351
-
352
- # Redefine the srcFile to mean the relative path to the git repo root
353
- src_file = Pathname.new(info.src_file).relative_path_from(@git_repo_root).to_s
354
- # Get the commit history of the doc
355
- # (use a homegrown git log to get 'follow' flag)
356
- gi = Giblish::GitItf.new(@git_repo_root)
357
- gi.file_log(src_file).each do |i|
358
- h = DocInfo::DocHistory.new
359
- h.date = i["date"]
360
- h.message = i["message"]
361
- h.author = i["author"]
362
- info.history << h
363
- end
364
- end
365
-
366
- private
367
-
368
- def init_git_repo(git_repo_root, local_only)
369
- # Sanity check git repo root
370
- git_repo_root || raise(ArgumentError("No git repo root dir given"))
371
-
372
- # Connect to the git repo
373
- begin
374
- git_repo = Git.open(git_repo_root)
375
- rescue StandardError => e
376
- raise "Could not find a git repo at #{git_repo_root} !"\
377
- "\n\n(#{e.message})"
378
- end
379
-
380
- # fetch all remote refs if ok with user
381
- begin
382
- git_repo.fetch unless local_only
383
- rescue StandardError => e
384
- raise "Could not fetch from origin"\
385
- "(do you need '--local-only'?)!\n\n(#{e.message})"
386
- end
387
- git_repo
388
- end
389
-
390
- # Get the branches/tags the user wants to parse
391
- def select_user_branches(checkout_regexp)
392
- return [] unless @options[:gitBranchRegexp]
393
-
394
- regexp = Regexp.new checkout_regexp
395
- user_checkouts = @git_repo.branches.remote.select do |b|
396
- # match branches but remove eventual HEAD -> ... entry
397
- regexp.match b.name unless b.name =~ /^HEAD/
398
- end
399
- Giblog.logger.debug { "selected git branches: #{user_checkouts}" }
400
- user_checkouts
401
- end
402
-
403
- def select_user_tags(tag_regexp)
404
- return [] unless tag_regexp
405
-
406
- regexp = Regexp.new @options[:gitTagRegexp]
407
- @git_repo.tags.select do |t|
408
- regexp.match t.name
409
- end
410
- end
411
-
412
- # convert all docs from one particular git commit
413
- # returns true if at least one doc failed to convert
414
- # and false if everything went ok.
415
- def convert_one_checkout(checkout)
416
- # determine if we are called with a tag or a branch
417
- is_tag = (checkout.respond_to?(:tag?) && checkout.tag?)
418
-
419
- Giblog.logger.info { "Checking out #{checkout.name}" }
420
- @git_repo.checkout checkout.name
421
-
422
- unless is_tag
423
- # if this is a branch, make sure it is up-to-date
424
- Giblog.logger.info { "Merging with origin/#{checkout.name}" }
425
- @git_repo.merge "origin/#{checkout.name}"
426
- end
427
-
428
- # assign a checkout-unique dst-dir
429
- dir_name = checkout.name.tr("/", "_") << "/"
430
-
431
- # Update needed base class members before converting a new checkout
432
- @processed_docs = []
433
- @paths.dst_root_abs = @master_paths.dst_root_abs.realpath.join(dir_name)
434
-
435
- if @options[:makeSearchable] && !@master_deployment_info.search_assets_path.nil?
436
- @paths.search_assets_abs = @master_paths.search_assets_abs.join(dir_name)
437
- @deploy_info.search_assets_path = @master_deployment_info.search_assets_path.join(dir_name)
438
- Giblog.logger.info { "will store search data in #{@paths.search_assets_abs}" }
439
- end
440
-
441
- # Parse and convert docs using given args
442
- Giblog.logger.info { "Convert docs into dir #{@paths.dst_root_abs}" }
443
- # parent_convert
444
- begin
445
- FileTreeConverter.instance_method(:convert).bind_call(self)
446
- rescue => e
447
- raise "convert_one_checkout has a failure with #{co}!\n\n(#{e.message})"
448
- end
449
- end
450
- end
451
- end