giblish 0.8.2 → 2.0.0.pre.alpha1
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/workflows/unit_tests.yml +30 -0
- data/.gitignore +7 -3
- data/.ruby-version +1 -1
- data/Changelog.adoc +59 -0
- data/README.adoc +261 -0
- data/docs/concepts/text_search.adoc +213 -0
- data/docs/concepts/text_search_im/cgi-search_request.puml +35 -0
- data/docs/concepts/text_search_im/cgi-search_request.svg +397 -0
- data/docs/concepts/text_search_im/search_request.puml +40 -0
- data/docs/concepts/text_search_im/search_request.svg +408 -0
- data/docs/howtos/trigger_generation.adoc +180 -0
- data/docs/{setup_server_assets → howtos/trigger_generation_im}/Render Documents.png +0 -0
- data/docs/{setup_server_assets → howtos/trigger_generation_im}/View Documents.png +0 -0
- data/docs/{setup_server_assets → howtos/trigger_generation_im}/deploy_with_hooks.graphml +0 -0
- data/docs/{setup_server_assets → howtos/trigger_generation_im}/deploy_with_hooks.svg +0 -0
- data/docs/{setup_server_assets → howtos/trigger_generation_im}/deploy_with_jenkins.graphml +0 -0
- data/docs/{setup_server_assets → howtos/trigger_generation_im}/deploy_with_jenkins.svg +0 -0
- data/docs/howtos/trigger_generation_im/docgen_github.puml +51 -0
- data/docs/{setup_server_assets → howtos/trigger_generation_im}/giblish_deployment.graphml +0 -0
- data/docs/howtos/trigger_generation_im/post-receive-example.sh +50 -0
- data/docs/reference/box_flow_spec.adoc +22 -0
- data/docs/reference/search_spec.adoc +185 -0
- data/giblish.gemspec +54 -32
- data/lib/giblish/adocsrc_providers.rb +23 -0
- data/lib/giblish/application.rb +214 -41
- data/lib/giblish/cmdline.rb +273 -259
- data/lib/giblish/config_utils.rb +41 -0
- data/lib/giblish/configurator.rb +163 -0
- data/lib/giblish/conversion_info.rb +120 -0
- data/lib/giblish/docattr_providers.rb +125 -0
- data/lib/giblish/docid/docid.rb +181 -0
- data/lib/giblish/github_trigger/webhook_manager.rb +64 -0
- data/lib/giblish/gitrepos/checkoutmanager.rb +124 -0
- data/lib/giblish/{gititf.rb → gitrepos/gititf.rb} +30 -4
- data/lib/giblish/gitrepos/gitsummary.erb +61 -0
- data/lib/giblish/gitrepos/gitsummaryprovider.rb +78 -0
- data/lib/giblish/gitrepos/history_pb.rb +41 -0
- data/lib/giblish/indexbuilders/d3treegraph.rb +88 -0
- data/lib/giblish/indexbuilders/depgraphbuilder.rb +109 -0
- data/lib/giblish/indexbuilders/dotdigraphadoc.rb +174 -0
- data/lib/giblish/indexbuilders/standard_index.erb +10 -0
- data/lib/giblish/indexbuilders/subtree_indices.rb +132 -0
- data/lib/giblish/indexbuilders/templates/circles.html.erb +111 -0
- data/lib/giblish/indexbuilders/templates/flame.html.erb +61 -0
- data/lib/giblish/indexbuilders/templates/tree.html.erb +366 -0
- data/lib/giblish/indexbuilders/templates/treemap.html.erb +127 -0
- data/lib/giblish/indexbuilders/verbatimtree.rb +94 -0
- data/lib/giblish/pathtree.rb +473 -74
- data/lib/giblish/resourcepaths.rb +150 -0
- data/lib/giblish/search/expand_adoc.rb +55 -0
- data/lib/giblish/search/headingindexer.rb +312 -0
- data/lib/giblish/search/request_manager.rb +110 -0
- data/lib/giblish/search/searchquery.rb +68 -0
- data/lib/giblish/search/textsearcher.rb +349 -0
- data/lib/giblish/subtreeinfobuilder.rb +77 -0
- data/lib/giblish/treeconverter.rb +272 -0
- data/lib/giblish/utils.rb +142 -294
- data/lib/giblish/version.rb +1 -1
- data/lib/giblish.rb +10 -7
- data/scripts/hooks/post-receive.example +66 -0
- data/{docgen/scripts/githook_examples → scripts/hooks}/post-update.example +0 -0
- data/{docgen → scripts}/resources/css/adoc-colony.css +0 -0
- data/scripts/resources/css/giblish-serif.css +419 -0
- data/scripts/resources/css/giblish.css +1979 -419
- data/{docgen → scripts}/resources/fonts/Ubuntu-B.ttf +0 -0
- data/{docgen → scripts}/resources/fonts/Ubuntu-BI.ttf +0 -0
- data/{docgen → scripts}/resources/fonts/Ubuntu-R.ttf +0 -0
- data/{docgen → scripts}/resources/fonts/Ubuntu-RI.ttf +0 -0
- data/{docgen → scripts}/resources/fonts/mplus1p-regular-fallback.ttf +0 -0
- data/{docgen → scripts}/resources/images/giblish_logo.png +0 -0
- data/{docgen → scripts}/resources/images/giblish_logo.svg +0 -0
- data/{docgen → scripts}/resources/themes/giblish.yml +0 -0
- data/scripts/wserv_development.rb +32 -0
- data/web_apps/cgi_search/gibsearch.rb +43 -0
- data/web_apps/gh_webhook_trigger/config.ru +2 -0
- data/web_apps/gh_webhook_trigger/gh_webhook_trigger.rb +73 -0
- data/web_apps/gh_webhook_trigger/public/dummy.txt +3 -0
- data/web_apps/sinatra_search/config.ru +2 -0
- data/web_apps/sinatra_search/public/dummy.txt +3 -0
- data/web_apps/sinatra_search/sinatra_search.rb +34 -0
- data/web_apps/sinatra_search/tmp/restart.txt +0 -0
- metadata +188 -85
- data/.rubocop.yml +0 -7
- data/.travis.yml +0 -3
- data/Changelog +0 -16
- data/Gemfile +0 -4
- data/README.adoc +0 -1
- data/Rakefile +0 -41
- data/bin/console +0 -14
- data/bin/setup +0 -8
- data/data/testdocs/malformed/no_header.adoc +0 -5
- data/data/testdocs/toplevel.adoc +0 -19
- data/data/testdocs/wellformed/adorned_purpose.adoc +0 -17
- data/data/testdocs/wellformed/docidtest/docid_1.adoc +0 -24
- data/data/testdocs/wellformed/docidtest/docid_2.adoc +0 -8
- data/data/testdocs/wellformed/simple.adoc +0 -14
- data/data/testdocs/wellformed/source_highlighting/highlight_source.adoc +0 -38
- data/docgen/resources/css/giblish.css +0 -1979
- data/docgen/scripts/Jenkinsfile +0 -18
- data/docgen/scripts/gen_adoc_org.sh +0 -58
- data/docs/README.adoc +0 -387
- data/docs/setup_server.adoc +0 -202
- data/lib/giblish/buildgraph.rb +0 -216
- data/lib/giblish/buildindex.rb +0 -459
- data/lib/giblish/core.rb +0 -451
- data/lib/giblish/docconverter.rb +0 -308
- data/lib/giblish/docid.rb +0 -180
- data/lib/giblish/docinfo.rb +0 -75
- data/lib/giblish/indexheadings.rb +0 -251
- data/lib/giblish-search.cgi +0 -459
- data/scripts/hooks/post-receive +0 -57
- data/scripts/publish_html.sh +0 -99
data/lib/giblish/utils.rb
CHANGED
@@ -1,18 +1,20 @@
|
|
1
1
|
require "logger"
|
2
2
|
require "pathname"
|
3
3
|
require "fileutils"
|
4
|
+
require "find"
|
4
5
|
|
5
6
|
# The logger used from within giblish
|
6
7
|
class Giblog
|
7
8
|
# Defines the format for log messages from giblish.
|
8
9
|
class GiblogFormatter
|
9
10
|
def call(severity, datetime, _progname, msg)
|
10
|
-
"#{datetime.strftime(
|
11
|
+
"#{datetime.strftime("%H:%M:%S")} #{severity} - #{msg}\n"
|
11
12
|
end
|
12
13
|
end
|
13
14
|
|
14
15
|
# bootstrap the application-wide logger object
|
15
|
-
def self.setup
|
16
|
+
def self.setup(logger = nil)
|
17
|
+
@logger = logger unless logger.nil?
|
16
18
|
return if defined? @logger
|
17
19
|
|
18
20
|
@logger = Logger.new($stdout)
|
@@ -32,13 +34,24 @@ end
|
|
32
34
|
|
33
35
|
# Public: Contains a number of generic utility methods.
|
34
36
|
module Giblish
|
35
|
-
#
|
36
|
-
#
|
37
|
+
# This logger is customized to receive log messages via the Asciidoctor API.
|
38
|
+
# It parses the messages and 'source_location' objects from the Asciidoctor API
|
39
|
+
# into messages using an opinionated format.
|
40
|
+
#
|
41
|
+
# The output is written to both $stdout and an in-memory StringIO instance. The log level
|
42
|
+
# can be set separately for each of these output channels.
|
37
43
|
class AsciidoctorLogger < ::Logger
|
44
|
+
attr_reader :max_severity, :in_mem_storage
|
45
|
+
|
38
46
|
# log formatter specialized for formatting messages from
|
39
|
-
# asciidoctor's stdout
|
47
|
+
# asciidoctor's stdout, handles the different log record types that Asciidoctor
|
48
|
+
# emits
|
40
49
|
class UserInfoFormatter
|
41
|
-
SEVERITY_LABELS = {
|
50
|
+
SEVERITY_LABELS = {"WARN" => "WARNING", "FATAL" => "FAILED"}.freeze
|
51
|
+
|
52
|
+
def call(severity, datetime, progname, msg)
|
53
|
+
%(#{datetime.strftime("%H:%M:%S")} #{progname}: #{SEVERITY_LABELS[severity] || severity}: #{UserInfoFormatter.adoc_to_message(msg)}\n)
|
54
|
+
end
|
42
55
|
|
43
56
|
# The hash that can be emitted as the msg from asciidoctor have the
|
44
57
|
# following format:
|
@@ -49,260 +62,58 @@ module Giblish
|
|
49
62
|
# @path="<only file name>",
|
50
63
|
# @lineno=<src line no>
|
51
64
|
# }
|
52
|
-
def
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
attr_reader :max_severity, :user_info_str
|
73
|
-
|
74
|
-
def initialize(user_info_log_level)
|
75
|
-
super($stdout, progname: "(from asciidoctor)", formatter: UserInfoFormatter.new)
|
76
|
-
@user_info_str = StringIO.new
|
77
|
-
@user_info_logger = ::Logger.new(@user_info_str, formatter: UserInfoFormatter.new, level: user_info_log_level)
|
78
|
-
end
|
79
|
-
|
80
|
-
def add(severity, message = nil, progname = nil)
|
81
|
-
if (severity ||= UNKNOWN) > (@max_severity ||= severity)
|
82
|
-
@max_severity = severity
|
83
|
-
end
|
84
|
-
@user_info_logger.add(severity, message, progname)
|
85
|
-
super
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
# returns the paths to the search assets and web assets
|
90
|
-
# in the deployment machine's file system.
|
91
|
-
class DeploymentPaths
|
92
|
-
attr_reader :web_path
|
93
|
-
|
94
|
-
def initialize(web_path, search_asset_path)
|
95
|
-
@search_assets_path = if search_asset_path.nil?
|
96
|
-
nil
|
97
|
-
else
|
98
|
-
Pathname.new("/#{search_asset_path}").cleanpath
|
99
|
-
end
|
100
|
-
@web_path = if web_path.nil?
|
101
|
-
nil
|
102
|
-
else
|
103
|
-
Pathname.new("/#{web_path}/web_assets").cleanpath
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
def search_assets_path(branch_dir = nil)
|
108
|
-
if branch_dir.nil?
|
109
|
-
@search_assets_path
|
110
|
-
else
|
111
|
-
@search_assets_path.join(branch_dir)
|
65
|
+
def self.adoc_to_message(msg)
|
66
|
+
case msg
|
67
|
+
when ::String
|
68
|
+
msg
|
69
|
+
when ::Hash
|
70
|
+
# asciidoctor seem to emit a hash with the following structure on errors:
|
71
|
+
# :text => String
|
72
|
+
# :source_location => Reader::Cursor with the following props:
|
73
|
+
# dir, file, lineno, path
|
74
|
+
# Only the lineno prop can be trusted when Asciidoctor is used via Giblish
|
75
|
+
#
|
76
|
+
src_loc = msg.fetch(:source_location, nil)
|
77
|
+
err_txt = msg.fetch(:text, "")
|
78
|
+
str = ""
|
79
|
+
str << "Line #{src_loc.lineno} - " if src_loc.lineno
|
80
|
+
str << err_txt
|
81
|
+
str
|
82
|
+
else
|
83
|
+
msg.inspect
|
84
|
+
end
|
112
85
|
end
|
113
86
|
end
|
114
87
|
|
115
|
-
|
116
|
-
end
|
117
|
-
|
118
|
-
# Helper class to ease construction of different paths for input and output
|
119
|
-
# files and directories
|
120
|
-
class PathManager
|
121
|
-
attr_reader :src_root_abs, :dst_root_abs, :resource_dir_abs, :search_assets_abs
|
122
|
-
|
123
|
-
# Public:
|
88
|
+
# The level is one of the standard ::Logger levels
|
124
89
|
#
|
125
|
-
#
|
126
|
-
#
|
127
|
-
#
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
# Make sure that the resource dir exists if user gives a path to it
|
141
|
-
resource_dir && (@resource_dir_abs = Pathname.new(resource_dir).realpath)
|
142
|
-
end
|
143
|
-
|
144
|
-
def search_assets_abs=(path)
|
145
|
-
if path.nil?
|
146
|
-
@search_assets_abs = nil
|
147
|
-
return
|
148
|
-
end
|
149
|
-
# Make sure that the destination root exists and expand it to an
|
150
|
-
# absolute path
|
151
|
-
dir = Pathname.new(path)
|
152
|
-
dir.mkpath
|
153
|
-
@search_assets_abs = dir.realpath
|
90
|
+
# stdout_level:: the log level to use for gating the messages to stdout
|
91
|
+
# string_level:: the log level to use for gating the messages to the in-memory string.
|
92
|
+
# defaults to 'stdout_level' if not set.
|
93
|
+
def initialize(user_logger, string_level = nil)
|
94
|
+
# def initialize(stdout_level, string_level = nil)
|
95
|
+
string_level = stdout_level if string_level.nil?
|
96
|
+
@user_logger = user_logger
|
97
|
+
|
98
|
+
@max_severity = UNKNOWN
|
99
|
+
|
100
|
+
# create a new, internal logger that echos messages to an in-memory string
|
101
|
+
@in_mem_storage = StringIO.new
|
102
|
+
# @in_mem_logger = ::Logger.new(@in_mem_storage, formatter: UserInfoFormatter.new, level: string_level)
|
103
|
+
super(@in_mem_storage, progname: "(asciidoctor)", formatter: UserInfoFormatter.new, level: string_level)
|
154
104
|
end
|
155
105
|
|
156
|
-
def
|
157
|
-
#
|
158
|
-
|
159
|
-
Pathname.new(dst_root).mkpath
|
160
|
-
@dst_root_abs = Pathname.new(dst_root).realpath
|
161
|
-
end
|
106
|
+
def add(severity, message = nil, progname = nil, &block)
|
107
|
+
# add message to adoc log
|
108
|
+
super(severity, message.dup, progname)
|
162
109
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
def reldir_from_src_root(in_path)
|
168
|
-
p = self.class.closest_dir in_path
|
169
|
-
p.relative_path_from(@src_root_abs)
|
170
|
-
end
|
171
|
-
|
172
|
-
# Public: Get the relative path from the
|
173
|
-
# directory where the supplied path points to
|
174
|
-
# the src root dir
|
175
|
-
#
|
176
|
-
# path - an absolute or relative path to a file or dir
|
177
|
-
def reldir_to_src_root(path)
|
178
|
-
src = self.class.closest_dir path
|
179
|
-
@src_root_abs.relative_path_from(src)
|
180
|
-
end
|
181
|
-
|
182
|
-
# Public: Get the relative path from the dst root dir to the
|
183
|
-
# directory where the supplied path points.
|
184
|
-
#
|
185
|
-
# path - an absolute or relative path to a file or dir
|
186
|
-
def reldir_from_dst_root(path)
|
187
|
-
dst = self.class.closest_dir path
|
188
|
-
dst.relative_path_from(@dst_root_abs)
|
189
|
-
end
|
190
|
-
|
191
|
-
# Public: Get the relative path from the
|
192
|
-
# directory where the supplied path points to
|
193
|
-
# the dst root dir
|
194
|
-
#
|
195
|
-
# path - an absolute or relative path to a file or dir
|
196
|
-
def reldir_to_dst_root(path)
|
197
|
-
dst = self.class.closest_dir path
|
198
|
-
@dst_root_abs.relative_path_from(dst)
|
199
|
-
end
|
110
|
+
# add message to user log (wierd interface... see Logger::add(...))
|
111
|
+
message = yield if block
|
112
|
+
message ||= progname
|
113
|
+
@user_logger&.add(severity, "(asciidoctor) #{UserInfoFormatter.adoc_to_message(message)}")
|
200
114
|
|
201
|
-
|
202
|
-
|
203
|
-
def dst_abs_from_src_abs(src_path)
|
204
|
-
src_abs = (self.class.to_pathname src_path).realpath
|
205
|
-
src_rel = reldir_from_src_root src_abs
|
206
|
-
@dst_root_abs.join(src_rel)
|
207
|
-
end
|
208
|
-
|
209
|
-
# return the relative path from a generated document to
|
210
|
-
# the supplied folder given the corresponding absolute source
|
211
|
-
# file path
|
212
|
-
def relpath_to_dir_after_generate(src_filepath, dir_path)
|
213
|
-
dst_abs = dst_abs_from_src_abs(src_filepath)
|
214
|
-
dir = self.class.to_pathname(dir_path)
|
215
|
-
dir.relative_path_from(dst_abs)
|
216
|
-
end
|
217
|
-
|
218
|
-
def adoc_output_file(infile_path, extension)
|
219
|
-
# Get absolute source dir path
|
220
|
-
src_dir_abs = self.class.closest_dir infile_path
|
221
|
-
|
222
|
-
# Get relative path from source root dir
|
223
|
-
src_dir_rel = src_dir_abs.relative_path_from(@src_root_abs)
|
224
|
-
|
225
|
-
# Get the destination path relative the absolute source
|
226
|
-
# root
|
227
|
-
dst_dir_abs = @dst_root_abs.realpath.join(src_dir_rel)
|
228
|
-
|
229
|
-
# return full file path with correct extension
|
230
|
-
dst_dir_abs + get_new_basename(infile_path, extension)
|
231
|
-
end
|
232
|
-
|
233
|
-
# Public: Get the path to the directory where to generate the given
|
234
|
-
# file. The path is given as the relative path from the source adoc
|
235
|
-
# file to the desired output directory (required by the Asciidoctor
|
236
|
-
# API).
|
237
|
-
#
|
238
|
-
# infile_path - a string or Pathname containing the absolute path of the
|
239
|
-
# source adoc file
|
240
|
-
#
|
241
|
-
# Returns: a Pathname with the relative path from the source file to the
|
242
|
-
# output directory
|
243
|
-
def adoc_output_dir(infile_path)
|
244
|
-
# Get absolute source dir path
|
245
|
-
src_abs = self.class.closest_dir infile_path
|
246
|
-
|
247
|
-
# Get relative path from source root dir
|
248
|
-
src_rel = src_abs.relative_path_from(@src_root_abs)
|
249
|
-
|
250
|
-
# Get the destination path relative the absolute source
|
251
|
-
# root
|
252
|
-
dst_abs = @dst_root_abs.realpath.join(src_rel)
|
253
|
-
dst_abs.relative_path_from(src_abs)
|
254
|
-
end
|
255
|
-
|
256
|
-
# return a pathname, regardless if the given path is a Pathname or
|
257
|
-
# a string
|
258
|
-
def self.to_pathname(path)
|
259
|
-
path.is_a?(Pathname) ? path : Pathname.new(path)
|
260
|
-
end
|
261
|
-
|
262
|
-
# Public: Get the basename for a file by replacing the file
|
263
|
-
# extention of the source file with the supplied one.
|
264
|
-
#
|
265
|
-
# src_filepath - the full path of the source file
|
266
|
-
# file_ext - the file extention of the resulting file name
|
267
|
-
#
|
268
|
-
# Example
|
269
|
-
#
|
270
|
-
# Giblish::PathManager.get_new_basename(
|
271
|
-
# "/my/old/file.txt","pdf") => "file.pdf"
|
272
|
-
#
|
273
|
-
# Returns: the basename of a file that uses the supplied file extention.
|
274
|
-
def self.get_new_basename(src_filepath, file_ext)
|
275
|
-
p = Pathname.new src_filepath
|
276
|
-
newname = p.basename.to_s.reverse.sub(p.extname.reverse, ".").reverse
|
277
|
-
newname << file_ext
|
278
|
-
end
|
279
|
-
|
280
|
-
# Public: Return the absolute path to the closest directory (defined as
|
281
|
-
# - the parent dir when called with an existing file
|
282
|
-
# - the directory itself when called with an existing directory
|
283
|
-
# - the parent dir when called with a non-existing file/directory
|
284
|
-
def self.closest_dir(in_path)
|
285
|
-
sr = to_pathname(in_path)
|
286
|
-
if sr.exist?
|
287
|
-
sr.directory? ? sr.realpath : sr.dirname.realpath
|
288
|
-
else
|
289
|
-
sr.parent.expand_path
|
290
|
-
end
|
291
|
-
end
|
292
|
-
|
293
|
-
# Public: Find the root directory of the git repo in which the
|
294
|
-
# given dirpath resides.
|
295
|
-
#
|
296
|
-
# dirpath - a relative or absolute path to a directory that resides
|
297
|
-
# within a git repo.
|
298
|
-
#
|
299
|
-
# Returns: the root direcotry of the git repo or nil if the input path
|
300
|
-
# does not reside within a git repo.
|
301
|
-
def self.find_gitrepo_root(dirpath)
|
302
|
-
Pathname.new(dirpath).realpath.ascend do |p|
|
303
|
-
git_dir = p.join(".git")
|
304
|
-
return p if git_dir.directory?
|
305
|
-
end
|
115
|
+
# update the maximum severity received by this logger
|
116
|
+
@max_severity = severity if severity != UNKNOWN && severity > @max_severity
|
306
117
|
end
|
307
118
|
end
|
308
119
|
|
@@ -313,13 +124,15 @@ module Giblish
|
|
313
124
|
# ex:
|
314
125
|
# process_header_lines(file_path) do |line|
|
315
126
|
# if line == "Quack!"
|
316
|
-
#
|
127
|
+
# myvar = "Donald!"
|
317
128
|
# 1
|
318
129
|
# else
|
319
130
|
# nil
|
320
131
|
# end
|
321
132
|
# end
|
322
|
-
def process_header_lines(lines)
|
133
|
+
def process_header_lines(lines, &block)
|
134
|
+
return unless block
|
135
|
+
|
323
136
|
state = "before_header"
|
324
137
|
lines.each do |line|
|
325
138
|
case state
|
@@ -338,15 +151,17 @@ module Giblish
|
|
338
151
|
# ex:
|
339
152
|
# process_header_lines_from_file(file_path) do |line|
|
340
153
|
# if line == "Quack!"
|
341
|
-
#
|
154
|
+
# myvar = "Donald!"
|
342
155
|
# 1
|
343
156
|
# else
|
344
157
|
# nil
|
345
158
|
# end
|
346
159
|
# end
|
347
|
-
def process_header_lines_from_file(path)
|
160
|
+
def process_header_lines_from_file(path, &block)
|
161
|
+
return unless block
|
162
|
+
|
348
163
|
lines = File.readlines(path)
|
349
|
-
process_header_lines(lines, &
|
164
|
+
process_header_lines(lines, &block)
|
350
165
|
end
|
351
166
|
module_function :process_header_lines_from_file
|
352
167
|
|
@@ -363,9 +178,15 @@ module Giblish
|
|
363
178
|
module_function :with_captured_stderr
|
364
179
|
|
365
180
|
# transforms strings to valid asciidoctor id strings
|
366
|
-
|
181
|
+
# in some cases you want to add a semi-unique checksum. If you do, you are no longer
|
182
|
+
# compatible with asciidoctor's generated ids
|
183
|
+
def to_valid_id(input_str, id_prefix = "_", id_separator = "_", use_checksum = false)
|
184
|
+
# use a basic checksum to reduce the risk for duplicate ids
|
185
|
+
check_sum = use_checksum ? input_str.chars.reduce(0) { |sum, c| sum + c.ord } : ""
|
186
|
+
|
367
187
|
id_str = input_str.strip.downcase.gsub(/[^a-z0-9]+/, id_separator)
|
368
|
-
id_str = "#{id_prefix}#{id_str}"
|
188
|
+
id_str = "#{id_prefix}#{check_sum}#{id_prefix}#{id_str}"
|
189
|
+
id_str.gsub!(/#{Regexp.quote(id_separator)}+/, id_separator)
|
369
190
|
id_str.chomp(id_separator)
|
370
191
|
end
|
371
192
|
module_function :to_valid_id
|
@@ -387,44 +208,71 @@ module Giblish
|
|
387
208
|
end
|
388
209
|
module_function :which
|
389
210
|
|
390
|
-
#
|
391
|
-
#
|
211
|
+
# Convert a string into a string where all characters forbidden as part of
|
212
|
+
# filenames are replaced by an underscore '_'.
|
392
213
|
#
|
393
|
-
#
|
394
|
-
#
|
395
|
-
#
|
396
|
-
#
|
397
|
-
#
|
398
|
-
#
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
#
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
<button id="search" type="submit"><i class="fa fa-search"></i></button>
|
413
|
-
<br>
|
214
|
+
# returns:: a String most likely a valid filename in windows & linux
|
215
|
+
#
|
216
|
+
# A comprehensive list of forbidden chars in different file systems can be
|
217
|
+
# found here: https://stackoverflow.com/a/31976060
|
218
|
+
# In short, chars forbidden in any of Windows and Linux are:
|
219
|
+
# / < > : " \\ | ? *
|
220
|
+
def to_fs_str(str)
|
221
|
+
# printable chars -> '_'
|
222
|
+
tmp = str.gsub(/[\/<>:"\\|?*]/, "_")
|
223
|
+
# non-printable chars -> '_'
|
224
|
+
tmp.gsub!(/[\x00-\x1F]/, "_")
|
225
|
+
# remove heading/trailing spaces
|
226
|
+
tmp.strip!
|
227
|
+
# Windows disallows files ending in '.'
|
228
|
+
tmp += "_" if tmp.end_with?(".")
|
229
|
+
|
230
|
+
tmp
|
231
|
+
end
|
232
|
+
module_function :to_fs_str
|
414
233
|
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
234
|
+
# Break a line into rows of max_length, using '-' semi-intelligently
|
235
|
+
# to split words if needed
|
236
|
+
#
|
237
|
+
# return:: an Array with the resulting rows
|
238
|
+
def break_line(line, max_length)
|
239
|
+
too_short = 3
|
240
|
+
return [line] if line.length <= too_short
|
241
|
+
raise ArgumentError, "max_length must be larger than #{too_short - 1}" if max_length < too_short
|
242
|
+
|
243
|
+
rows = []
|
244
|
+
row = ""
|
245
|
+
|
246
|
+
until line.empty?
|
247
|
+
word, _sep, _remaining = line.strip.partition(" ")
|
248
|
+
row_space = max_length - row.length
|
249
|
+
|
250
|
+
# start word with a space if row is not empty
|
251
|
+
sep = row.empty? ? "" : " "
|
252
|
+
|
253
|
+
# if word fits in row, just insert it and take next word
|
254
|
+
if row_space - (word.length + sep.length) >= 0
|
255
|
+
row = "#{row}#{sep}#{word}"
|
256
|
+
line = line.sub(word, "").strip
|
257
|
+
next
|
258
|
+
end
|
420
259
|
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
260
|
+
# shall we split word or just move it to next row?
|
261
|
+
if (row_space == max_length && word.length > row_space) ||
|
262
|
+
(word.length > too_short && (row_space > too_short) && (word.length - row_space).abs > too_short)
|
263
|
+
# we will split the word, using a '-'
|
264
|
+
first_part = word[0..row_space - (1 + sep.length)]
|
265
|
+
row = "#{row}#{sep}#{first_part}-"
|
266
|
+
line = line.sub(first_part, "").strip
|
267
|
+
end
|
426
268
|
|
427
|
-
|
269
|
+
# start a new row
|
270
|
+
rows << row
|
271
|
+
row = ""
|
272
|
+
end
|
273
|
+
# need to add unfinished row if any
|
274
|
+
rows << row unless row.empty?
|
275
|
+
rows
|
428
276
|
end
|
429
|
-
module_function :
|
277
|
+
module_function :break_line
|
430
278
|
end
|
data/lib/giblish/version.rb
CHANGED
data/lib/giblish.rb
CHANGED
@@ -1,18 +1,21 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
if /^2/.match?(RUBY_VERSION)
|
3
|
+
# suppress warnings for 'experimental' pattern matching
|
4
|
+
# for ruby versions < 3.x
|
5
|
+
require "warning"
|
6
|
+
Warning.ignore(/Pattern matching/)
|
7
|
+
end
|
2
8
|
|
3
9
|
require_relative "giblish/version"
|
4
|
-
require_relative "giblish/utils"
|
5
|
-
require_relative "giblish/core"
|
6
|
-
require_relative "giblish/buildindex"
|
7
|
-
require_relative "giblish/cmdline"
|
8
|
-
require_relative "giblish/pathtree"
|
9
10
|
require_relative "giblish/application"
|
11
|
+
require_relative "giblish/search/request_manager"
|
12
|
+
require_relative "giblish/github_trigger/webhook_manager"
|
10
13
|
|
11
14
|
module Giblish
|
15
|
+
# The main entry point to the giblish application
|
12
16
|
class << self
|
13
|
-
|
14
17
|
def application
|
15
|
-
@application ||= Giblish::
|
18
|
+
@application ||= Giblish::EntryPoint
|
16
19
|
end
|
17
20
|
end
|
18
21
|
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
#
|
3
|
+
# this hook runs giblish on a document tree according to the
|
4
|
+
# users settings.
|
5
|
+
# Typically used to publish html documents when a push to a matching
|
6
|
+
# branch is detected.
|
7
|
+
|
8
|
+
# the git refs that should trigger a doc generation at update
|
9
|
+
TRIGGERING_REFS_REGEX=$'main'
|
10
|
+
|
11
|
+
# the relative path to a subfolder in the repo where the docs are
|
12
|
+
REPO_DOC_SUBFOLDER="docs"
|
13
|
+
|
14
|
+
# the staging repo root (where the working tree exists)
|
15
|
+
STAGING_REPO="/usr/local/git_staging/rillbert_se_staging"
|
16
|
+
|
17
|
+
# The web-server top dir for the published documents
|
18
|
+
DST_DIR="/var/www/rillbert_se/html/public/docs"
|
19
|
+
|
20
|
+
# path to a top dir of the styling css and other resources
|
21
|
+
RESOURCE_DIR="scripts/resources"
|
22
|
+
|
23
|
+
# the name of the css file to use for styling, without the 'css' extension
|
24
|
+
LAYOUT_STYLE="giblish"
|
25
|
+
|
26
|
+
# "true" runs an 'rm -rf' of the destination dir before generating new htmls
|
27
|
+
CLEAR_DST="true"
|
28
|
+
|
29
|
+
echo "post-receive hook running..."
|
30
|
+
|
31
|
+
# read the input that git sends to this hook
|
32
|
+
read oldrev newrev ref
|
33
|
+
|
34
|
+
# remove the 'refs/heads/' prefix from the git ref
|
35
|
+
ref="${ref/refs\/heads\//}"
|
36
|
+
|
37
|
+
# filter out refs that are irrelevant for doc generation
|
38
|
+
if [[ ! "${ref}" =~ "${TRIGGERING_REFS_REGEX}" ]]; then
|
39
|
+
echo "Ref '${ref}' received. Doing nothing: only refs matching the regex: /${TRIGGERING_REFS_REGEX}/ will trigger a doc generation."
|
40
|
+
exit 0
|
41
|
+
fi
|
42
|
+
|
43
|
+
echo "Document generation triggered by an update to ${ref}."
|
44
|
+
echo ""
|
45
|
+
|
46
|
+
# use a subshell with the correct working dir for the actual doc generation
|
47
|
+
(
|
48
|
+
cd "${STAGING_REPO}"
|
49
|
+
|
50
|
+
# need to unset the GIT_DIR env set by the invoking hook for giblish to work correctly
|
51
|
+
unset GIT_DIR
|
52
|
+
|
53
|
+
if [[ "${CLEAR_DST}" -eq "true" ]]; then
|
54
|
+
echo "Remove everything under ${DST_DIR}/"
|
55
|
+
rm -rf ${DST_DIR}/*
|
56
|
+
fi
|
57
|
+
|
58
|
+
# Generate html docs
|
59
|
+
echo "running giblish..."
|
60
|
+
giblish -a xrefstyle=basic \
|
61
|
+
--copy-asset-folders "_assets$" \
|
62
|
+
-g "${TRIGGERING_REFS_REGEX}" \
|
63
|
+
-r "${RESOURCE_DIR}" \
|
64
|
+
-s "${LAYOUT_STYLE}" \
|
65
|
+
"${REPO_DOC_SUBFOLDER}" "${DST_DIR}"
|
66
|
+
)
|
File without changes
|
File without changes
|