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.
- checksums.yaml +4 -4
- data/.github/workflows/unit_tests.yml +30 -0
- data/.gitignore +7 -3
- data/.ruby-version +1 -1
- data/Changelog.adoc +61 -0
- data/README.adoc +267 -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 +47 -29
- 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 +168 -73
- 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
@@ -0,0 +1,50 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
#
|
3
|
+
# this hook runs a script which, in turn, generates html documentation
|
4
|
+
# and publishes them to the given destination.
|
5
|
+
#
|
6
|
+
|
7
|
+
# the git refs that should trigger a doc generation at update
|
8
|
+
TRIGGERING_REFS_REGEX=$'main'
|
9
|
+
|
10
|
+
# the staging repo root (where the working tree exists)
|
11
|
+
STAGING_REPO="/usr/local/git_staging/myrepo_staging"
|
12
|
+
|
13
|
+
# The web-server top dir for the published documents
|
14
|
+
DST_DIR="/var/www/mysite/html/public/docs"
|
15
|
+
|
16
|
+
# "true" runs an 'rm -rf' of the destination dir before generating new htmls
|
17
|
+
CLEAR_DST="false"
|
18
|
+
|
19
|
+
echo "post-receive hook running..."
|
20
|
+
|
21
|
+
# read the input that git sends to this hook
|
22
|
+
read oldrev newrev ref
|
23
|
+
|
24
|
+
# remove the 'refs/heads/' prefix from the git ref
|
25
|
+
ref="${ref/refs\/heads\//}"
|
26
|
+
|
27
|
+
# filter out refs that are irrelevant for doc generation
|
28
|
+
if [[ ! "${ref}" =~ "${TRIGGERING_REFS_REGEX}" ]]; then
|
29
|
+
echo "Ref '${ref}' received. Doing nothing: only refs matching the regex: /${TRIGGERING_REFS_REGEX}/ will trigger a doc generation."
|
30
|
+
exit 0
|
31
|
+
fi
|
32
|
+
|
33
|
+
echo "Document generation triggered by an update to ${ref}."
|
34
|
+
echo ""
|
35
|
+
|
36
|
+
# use a subshell with the correct working dir for the actual doc generation
|
37
|
+
(
|
38
|
+
cd "${STAGING_REPO}"
|
39
|
+
|
40
|
+
# need to unset the GIT_DIR env set by the invoking hook for giblish to work correctly
|
41
|
+
unset GIT_DIR
|
42
|
+
|
43
|
+
if [[ "${CLEAR_DST}" -eq "true" ]]; then
|
44
|
+
echo "Remove everything under ${DST_DIR}/"
|
45
|
+
rm -rf ${DST_DIR}/*
|
46
|
+
fi
|
47
|
+
|
48
|
+
# Generate html docs
|
49
|
+
giblish --copy-asset-folders "_assets$" -g "${TRIGGERING_REFS_REGEX}" -r scripts/resources -s mystyle . "${DST_DIR}"
|
50
|
+
)
|
@@ -0,0 +1,22 @@
|
|
1
|
+
= Tree flow
|
2
|
+
|
3
|
+
== Algorithm
|
4
|
+
|
5
|
+
Preconditions::
|
6
|
+
* No padding
|
7
|
+
* Left-to-right filling
|
8
|
+
* 1 sublevel
|
9
|
+
* Width for outer box is fixed, height is variable
|
10
|
+
|
11
|
+
Outer box = B [bx, by, bw, bh]
|
12
|
+
Inner boxes = In [In_x, In_y, In_w, In_h]
|
13
|
+
|
14
|
+
Horizontal strips = Sn
|
15
|
+
|
16
|
+
foreach In in I
|
17
|
+
if In_w > S_free_width
|
18
|
+
S = S(n+1)
|
19
|
+
end
|
20
|
+
In_coord = S_free_coord
|
21
|
+
end
|
22
|
+
|
@@ -0,0 +1,185 @@
|
|
1
|
+
= Text search spec for giblish
|
2
|
+
:docid: G-002
|
3
|
+
|
4
|
+
== Information expected to be included in a search request
|
5
|
+
|
6
|
+
URL endpoint for the search service::
|
7
|
+
When a search is triggered, the correct URL for triggering the search service must be POSTed to.
|
8
|
+
|
9
|
+
URI parameters::
|
10
|
+
The search service expects a number of parameters as part of the search query, see <<uri_params>>.
|
11
|
+
|
12
|
+
.URI parameters
|
13
|
+
[[uri_params]]
|
14
|
+
[cols="2,2,5,3"]
|
15
|
+
|===
|
16
|
+
|name |status |comment |example
|
17
|
+
|
18
|
+
|calling-url
|
19
|
+
|required
|
20
|
+
|the URL to the file from which the search request originated
|
21
|
+
|www.example.com/my/doc/site/subdir/file_1.html
|
22
|
+
|
23
|
+
|search-assets-top-rel
|
24
|
+
|required
|
25
|
+
|the relative path from the originating file's directory to the top dir of the search assets. The default implementation in giblish uses the name `gibsearch_assets` for this directory.
|
26
|
+
|../../gibsearch_assets
|
27
|
+
|
28
|
+
|search-phrase
|
29
|
+
|required
|
30
|
+
|a string with the phrase to search for
|
31
|
+
|meaning of life
|
32
|
+
|
33
|
+
|css-path
|
34
|
+
|optional
|
35
|
+
a|the path to the css file to use when generating the result.
|
36
|
+
|
37
|
+
absolute::
|
38
|
+
the path is used as-is.
|
39
|
+
|
40
|
+
relative::
|
41
|
+
the relative path to the css file from the originating file's directory.
|
42
|
+
|
43
|
+
not set::
|
44
|
+
the styling is left to the search implementation.
|
45
|
+
|
46
|
+
a| * *absolute* - /var/www/html/my/site/style.css
|
47
|
+
* *relative* - ../../web_assets/css/style.css
|
48
|
+
|
49
|
+
|consider-case
|
50
|
+
|optional
|
51
|
+
a|
|
52
|
+
if set::
|
53
|
+
search case sensitive
|
54
|
+
|
55
|
+
not set::
|
56
|
+
ignore case during search
|
57
|
+
|
58
|
+
|true
|
59
|
+
|
60
|
+
|as-regexp
|
61
|
+
|optional
|
62
|
+
a|
|
63
|
+
if set::
|
64
|
+
treat the search phrase as a regexp
|
65
|
+
|
66
|
+
not set::
|
67
|
+
treat the search phrase as a string
|
68
|
+
|true
|
69
|
+
|
70
|
+
|===
|
71
|
+
|
72
|
+
== The implementation in giblish
|
73
|
+
|
74
|
+
=== At document generation
|
75
|
+
|
76
|
+
. Collect all adoc docs in a search asset directory.
|
77
|
+
. Embed html code for a search form as part of running gibish on the source tree. During generation, the following search parameters are known for each document to be generated:
|
78
|
+
.. search-assets-top-rel
|
79
|
+
.. css-path
|
80
|
+
. The `calling-url` is not known but it is possible to embed javascript code as part of the search form code that will resolve the url at runtime.
|
81
|
+
. The URL for the search service endpoint must be given by the user or hard-coded in giblish.
|
82
|
+
|
83
|
+
=== At a user search query
|
84
|
+
|
85
|
+
When a user submit a 'search' query, the following parameters must be filled in and submitted to the text search service:
|
86
|
+
|
87
|
+
. searchphrase
|
88
|
+
. usecase (optional)
|
89
|
+
. useregexp (optional)
|
90
|
+
|
91
|
+
The other required parameters comes from the generated document itself.
|
92
|
+
|
93
|
+
=== The search index
|
94
|
+
|
95
|
+
The search index is created by giblish during html generation and consists of
|
96
|
+
|
97
|
+
. the adoc source files (when `include` directives have been resolved)
|
98
|
+
. a `heading_db.json` file mapping sections in the source files to line numbers
|
99
|
+
|
100
|
+
.The storage location for the search index information
|
101
|
+
----
|
102
|
+
|- <top_path>
|
103
|
+
| |- file1.html
|
104
|
+
| |- subdir
|
105
|
+
| |- file2.html
|
106
|
+
| |- web_assets
|
107
|
+
| |- mystyle.css
|
108
|
+
| |- gibsearch_assets
|
109
|
+
| |- heading_db.json
|
110
|
+
| |- file1.adoc
|
111
|
+
| |- subdir
|
112
|
+
| |file2.adoc
|
113
|
+
----
|
114
|
+
|
115
|
+
.The format of the heading_db.json file
|
116
|
+
[source,json]
|
117
|
+
----
|
118
|
+
{
|
119
|
+
fileinfos : [
|
120
|
+
{
|
121
|
+
filepath : "file1.adoc",
|
122
|
+
title : "File 1 Title",
|
123
|
+
sections : [
|
124
|
+
{
|
125
|
+
id : "section_id_1",
|
126
|
+
title : "Purpose",
|
127
|
+
line_no : 10
|
128
|
+
},
|
129
|
+
{
|
130
|
+
id : "section_id_2",
|
131
|
+
...
|
132
|
+
}
|
133
|
+
]
|
134
|
+
},
|
135
|
+
{
|
136
|
+
filepath: "subdir/file2.adoc",
|
137
|
+
...
|
138
|
+
}
|
139
|
+
]
|
140
|
+
}
|
141
|
+
----
|
142
|
+
|
143
|
+
=== The search form
|
144
|
+
|
145
|
+
giblish inserts the below html/JavaScript at the top of each generated html document.
|
146
|
+
|
147
|
+
.A minimal search form
|
148
|
+
[source,html]
|
149
|
+
----
|
150
|
+
<script type="text/javascript">
|
151
|
+
window.onload = function () {
|
152
|
+
document.getElementById("calingurl_input").value = window.location.href;
|
153
|
+
};
|
154
|
+
</script>
|
155
|
+
|
156
|
+
<style>
|
157
|
+
#gibsearch-form {
|
158
|
+
position:fixed;
|
159
|
+
top:0.5rem;
|
160
|
+
left:70%;
|
161
|
+
width:30%;
|
162
|
+
height:3rem;
|
163
|
+
background:white;
|
164
|
+
z-index:2000;
|
165
|
+
}
|
166
|
+
</style>
|
167
|
+
|
168
|
+
<div id=gibsearch-form>
|
169
|
+
<form class="gibsearch" action="<%=action_path%>">
|
170
|
+
<input type="search" placeholder="Search the docs.." name="search-phrase" />
|
171
|
+
<button type="submit">Search</button>
|
172
|
+
<br>
|
173
|
+
|
174
|
+
<input type="checkbox" id="consider-case" name="consider-case" />
|
175
|
+
<label for="consider-case">case sensitive</label>
|
176
|
+
|
177
|
+
<input type="checkbox" id="as-regexp" name="as-regexp" />
|
178
|
+
<label for="as-regexp">use regexp</label>
|
179
|
+
|
180
|
+
<input type="hidden" name="calling-url" id=calingurl_input />
|
181
|
+
<input type="hidden" name="search-assets-top-rel" value="<%=sa_top_rel%>"/>
|
182
|
+
<input type="hidden" name="css-path" value="<%=css_path%>"/>
|
183
|
+
</form>
|
184
|
+
</div>
|
185
|
+
----
|
data/giblish.gemspec
CHANGED
@@ -1,24 +1,28 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
require "giblish/version"
|
1
|
+
begin
|
2
|
+
require_relative "lib/giblish/version"
|
3
|
+
rescue LoadError
|
4
|
+
require "giblish/version"
|
5
|
+
end
|
7
6
|
|
8
7
|
Gem::Specification.new do |spec|
|
9
|
-
spec.name
|
10
|
-
spec.version
|
11
|
-
spec.
|
12
|
-
spec.
|
8
|
+
spec.name = "giblish"
|
9
|
+
spec.version = Giblish::VERSION
|
10
|
+
spec.summary = "A tool for publishing asciidoc docs stored in git repos"
|
11
|
+
spec.description = <<~EOF
|
12
|
+
giblish generates indexed and searchable documents from a tree of
|
13
|
+
asciidoc files.
|
14
|
+
EOF
|
15
|
+
spec.authors = ["Anders Rillbert"]
|
16
|
+
spec.email = ["anders.rillbert@kutso.se"]
|
17
|
+
spec.homepage = "https://github.com/rillbert/giblish"
|
18
|
+
spec.license = "MIT"
|
19
|
+
# NOTE required ruby version is informational only; it's not enforced since it can't be overridden and can cause builds to break
|
20
|
+
# spec.required_ruby_version = ">= 2.7"
|
13
21
|
|
14
|
-
spec.
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
EOF
|
19
|
-
spec.homepage = "https://github.com/rillbert/giblish"
|
20
|
-
spec.license = "MIT"
|
21
|
-
spec.required_ruby_version = ">= 2.7"
|
22
|
+
spec.metadata = {
|
23
|
+
"bug_tracker_uri" => "https://github.com/rillbert/giblish/issues",
|
24
|
+
"source_code_uri" => "https://github.com/rillbert/giblish"
|
25
|
+
}
|
22
26
|
|
23
27
|
# Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
|
24
28
|
# delete this section to allow pushing this gem to any host.
|
@@ -28,22 +32,36 @@ Gem::Specification.new do |spec|
|
|
28
32
|
# raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
|
29
33
|
# end
|
30
34
|
|
31
|
-
|
32
|
-
spec.
|
33
|
-
|
35
|
+
# filter out files not included in the shipped gem
|
36
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
37
|
+
skip_dirs = %r{^(data|bin|test|spec|features)/}
|
38
|
+
skip_files = %r{^(Rakefile|Gemfile)}
|
39
|
+
f.match(skip_dirs) || f.match(skip_files)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Follow the bundler convention to have the exe:s in "exe" instead of 'bin'
|
43
|
+
spec.bindir = "exe"
|
44
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
34
45
|
spec.require_paths = ["lib"]
|
35
46
|
|
36
|
-
|
47
|
+
# Development deps
|
37
48
|
spec.add_development_dependency "minitest", "~> 5.0"
|
38
|
-
spec.add_development_dependency "
|
39
|
-
spec.add_development_dependency "
|
40
|
-
spec.add_development_dependency
|
49
|
+
spec.add_development_dependency "standard", "~> 1.1"
|
50
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
51
|
+
spec.add_development_dependency "oga", "~> 3.3"
|
52
|
+
spec.add_development_dependency "thor", "~> 0.20.3"
|
41
53
|
spec.add_development_dependency "asciidoctor-mathematical", "~> 0.3.5"
|
54
|
+
# needed for the sinatra-based apps
|
55
|
+
spec.add_development_dependency "sinatra", "~>2.1"
|
56
|
+
spec.add_development_dependency "thin", "~>1.8"
|
57
|
+
spec.add_development_dependency "rack", "2.2.3"
|
58
|
+
spec.add_development_dependency "rack-test", "1.1"
|
42
59
|
|
43
|
-
#
|
44
|
-
spec.add_runtime_dependency "
|
45
|
-
spec.add_runtime_dependency "asciidoctor
|
46
|
-
spec.add_runtime_dependency "asciidoctor-
|
60
|
+
# Run-time deps
|
61
|
+
spec.add_runtime_dependency "warning", "~>1.2"
|
62
|
+
spec.add_runtime_dependency "asciidoctor", "~>2.0", ">= 2.0.17"
|
63
|
+
spec.add_runtime_dependency "asciidoctor-diagram", ["~> 2.2"]
|
64
|
+
spec.add_runtime_dependency "asciidoctor-pdf", ["~> 1.6", ">= 1.6.2"]
|
47
65
|
spec.add_runtime_dependency "git", "~> 1.9"
|
48
66
|
spec.add_runtime_dependency "rouge", "~> 3.0"
|
49
67
|
spec.add_runtime_dependency "prawn-svg", "~> 0.32.0"
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Giblish
|
2
|
+
class AdocSrcItf
|
3
|
+
def adoc_source(src_node, dst_node, dst_top)
|
4
|
+
raise NotImplementedError
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
class SrcFromFile < AdocSrcItf
|
9
|
+
def adoc_source(src_node, dst_node, dst_top)
|
10
|
+
File.read(src_node.pathname)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class SrcFromString < AdocSrcItf
|
15
|
+
def initialize(src_str)
|
16
|
+
@adoc_source = src_str
|
17
|
+
end
|
18
|
+
|
19
|
+
def adoc_source(src_node, dst_node, dst_top)
|
20
|
+
@adoc_source
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/giblish/application.rb
CHANGED
@@ -1,68 +1,241 @@
|
|
1
1
|
require_relative "cmdline"
|
2
|
-
require_relative "
|
3
|
-
require_relative "
|
2
|
+
require_relative "configurator"
|
3
|
+
require_relative "treeconverter"
|
4
|
+
require_relative "gitrepos/checkoutmanager"
|
4
5
|
|
5
6
|
module Giblish
|
6
|
-
# The
|
7
|
+
# The app class for the giblish application
|
7
8
|
class Application
|
8
|
-
#
|
9
|
-
def run_from_cmd_line
|
10
|
-
status = run(ARGV)
|
11
|
-
exit(status)
|
12
|
-
end
|
13
|
-
|
14
|
-
# return exit status (0 for success)
|
9
|
+
# returns on success, raises otherwise
|
15
10
|
def run(args)
|
16
11
|
# force immediate output
|
17
12
|
$stdout.sync = true
|
18
13
|
|
19
14
|
# setup logging
|
20
15
|
Giblog.setup
|
16
|
+
Giblog.logger.level = Logger::INFO
|
21
17
|
|
22
18
|
# Parse cmd line
|
23
|
-
cmdline =
|
24
|
-
Giblog.logger.
|
19
|
+
cmdline = CmdLine.new.parse(args)
|
20
|
+
Giblog.logger.level = cmdline.log_level
|
21
|
+
|
22
|
+
Giblog.logger.debug { "cmd line args: #{cmdline.inspect}" }
|
23
|
+
|
24
|
+
# build a tree of files matching user's regexp selection
|
25
|
+
src_tree = PathTree.build_from_fs(cmdline.srcdir) do |p|
|
26
|
+
if cmdline.exclude_regex&.match(p.to_s)
|
27
|
+
false
|
28
|
+
else
|
29
|
+
(cmdline.include_regex =~ p.to_s)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
if src_tree.nil?
|
33
|
+
Giblog.logger.warn { "Did not find any files to convert" }
|
34
|
+
return
|
35
|
+
end
|
36
|
+
|
37
|
+
app = Configurator.new(cmdline, src_tree)
|
38
|
+
app.tree_converter.run
|
25
39
|
|
26
|
-
|
27
|
-
|
28
|
-
|
40
|
+
Giblog.logger.info { "Giblish is done!" }
|
41
|
+
end
|
42
|
+
|
43
|
+
# does not return, exits with status code
|
44
|
+
def run_from_cmd_line
|
45
|
+
begin
|
46
|
+
run(ARGV)
|
47
|
+
exit_code = 0
|
48
|
+
rescue => exc
|
49
|
+
Giblog.logger.error { exc.message }
|
50
|
+
Giblog.logger.error { exc.backtrace }
|
51
|
+
exit_code = 1
|
52
|
+
end
|
53
|
+
exit(exit_code)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class DirTreeConvert
|
58
|
+
# This class provides a file as the source for the asciidoc info and
|
59
|
+
# sets the document attributes required by Asciidoctor to resolve
|
60
|
+
# 'imagesdir' et al.
|
61
|
+
class AdocFileProvider
|
62
|
+
def adoc_source(src_node, dst_node, dst_top)
|
63
|
+
File.read(src_node.pathname)
|
64
|
+
end
|
65
|
+
|
66
|
+
def document_attributes(src_node, dst_node, dst_top)
|
67
|
+
p = src_node.pathname
|
68
|
+
{
|
69
|
+
"docfile" => p.to_s,
|
70
|
+
"docdir" => p.dirname.to_s,
|
71
|
+
"docname" => p.basename.to_s
|
72
|
+
}
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def initialize(user_opts)
|
77
|
+
@user_opts = user_opts.dup
|
78
|
+
|
79
|
+
# get all adoc source files from disk
|
80
|
+
o = @user_opts
|
81
|
+
@src_tree = build_src_tree(o.srcdir, o.include_regex, o.exclude_regex)
|
82
|
+
end
|
83
|
+
|
84
|
+
# returns on success, raises otherwise
|
85
|
+
def run(configurator = nil)
|
86
|
+
return if @src_tree.nil?
|
87
|
+
|
88
|
+
# assign/setup a configurator containing all api options and doc attributes
|
89
|
+
build_config = configurator || Configurator.new(@user_opts)
|
90
|
+
|
91
|
+
tc = setup_converter(@src_tree, AdocFileProvider.new, build_config)
|
92
|
+
tc.run
|
29
93
|
end
|
30
94
|
|
31
95
|
private
|
32
96
|
|
33
|
-
#
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
97
|
+
# build a tree of files matching user's regexp selection
|
98
|
+
def build_src_tree(srcdir, include_regex, exclude_regex)
|
99
|
+
pt = PathTree.build_from_fs(srcdir) do |p|
|
100
|
+
if exclude_regex&.match(p.to_s)
|
101
|
+
false
|
102
|
+
else
|
103
|
+
include_regex =~ p.to_s
|
104
|
+
end
|
105
|
+
end
|
106
|
+
if pt.nil?
|
107
|
+
Giblog.logger.warn { "Did not find any files to convert!" }
|
108
|
+
Giblog.logger.warn { "Built srctree using srcdir: #{srcdir} include_regex: #{include_regex} exclude_regex: #{exclude_regex}" }
|
109
|
+
end
|
110
|
+
pt
|
111
|
+
end
|
112
|
+
|
113
|
+
def setup_converter(src_tree, adoc_src_provider, configurator)
|
114
|
+
# compose the doc attribute provider.
|
115
|
+
configurator.doc_attr.add_doc_attr_providers(adoc_src_provider)
|
116
|
+
# NOTE: The order in the line below is important!
|
117
|
+
data_provider = DataDelegator.new(configurator.doc_attr, adoc_src_provider)
|
118
|
+
|
119
|
+
# associate the data providers with each source node in the tree
|
120
|
+
src_tree.traverse_preorder do |level, node|
|
121
|
+
next unless node.leaf?
|
122
|
+
|
123
|
+
node.data = data_provider
|
42
124
|
end
|
43
|
-
|
125
|
+
|
126
|
+
TreeConverter.new(src_tree, @user_opts.dstdir, configurator.build_options)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# Converts a number of branches/tags in a gitrepo according to the given
|
131
|
+
# options.
|
132
|
+
#
|
133
|
+
# Each branch/tag is converted into a subdir of the given root dir and a
|
134
|
+
# summary page with links to the converted docs for each branch/tag is
|
135
|
+
# generated within the root dir.
|
136
|
+
class GitRepoConvert
|
137
|
+
def initialize(user_opts)
|
138
|
+
raise ArgumentError, "No selection for git branches or tags were found!" unless user_opts.branch_regex || user_opts.tag_regex
|
139
|
+
|
140
|
+
@user_opts = user_opts.dup
|
141
|
+
|
142
|
+
# cache the root dir
|
143
|
+
@dst_topdir = @user_opts.dstdir
|
144
|
+
|
145
|
+
@gm = GitCheckoutManager.new(@user_opts)
|
44
146
|
end
|
45
147
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
148
|
+
def run
|
149
|
+
# convert all docs found in the branches/tags that the user asked to parse
|
150
|
+
@gm.each_checkout do |name|
|
151
|
+
# tweak the destination dir to a subdir per branch/tag
|
152
|
+
@user_opts.dstdir = @dst_topdir / Giblish.to_fs_str(name)
|
153
|
+
|
154
|
+
Giblog.logger.debug { "cmdline: #{@user_opts.inspect}" }
|
155
|
+
configurator = GitRepoConfigurator.new(@user_opts, @gm.repo_root)
|
156
|
+
DirTreeConvert.new(@user_opts).run(configurator)
|
157
|
+
rescue => e
|
158
|
+
Giblog.logger.error { "Conversion of #{name} failed!" }
|
159
|
+
raise e if @user_opts.abort_on_error
|
160
|
+
Giblog.logger.error { e.message }
|
54
161
|
end
|
162
|
+
make_summary
|
163
|
+
end
|
164
|
+
|
165
|
+
def make_summary
|
166
|
+
# reset the dst dir to the user-given-top
|
167
|
+
@user_opts.dstdir = @dst_topdir
|
168
|
+
|
169
|
+
# Make sure the summary page is just 'bare-bone'
|
170
|
+
@user_opts.make_searchable = nil
|
171
|
+
@user_opts.copy_asset_folders = nil
|
172
|
+
@user_opts.no_index = true
|
173
|
+
@user_opts.resolve_docid = false
|
174
|
+
@user_opts.doc_attributes["table-caption"] = nil
|
175
|
+
|
176
|
+
# assign/setup the doc_attr and layout using the same user options as
|
177
|
+
# for the adoc source files on each checkout
|
178
|
+
conf = Configurator.new(@user_opts)
|
179
|
+
s = @gm.summary_provider
|
180
|
+
s.index_basename = conf.config_opts.index_basename
|
181
|
+
data_provider = DataDelegator.new(
|
182
|
+
SrcFromString.new(s.source),
|
183
|
+
conf.doc_attr
|
184
|
+
)
|
185
|
+
srctree = PathTree.new("/" + conf.config_opts.index_basename + ".adoc", data_provider)
|
186
|
+
TreeConverter.new(srctree, @dst_topdir, conf.build_options).run
|
55
187
|
end
|
188
|
+
end
|
189
|
+
|
190
|
+
class EntryPoint
|
191
|
+
def initialize(args, logger = nil)
|
192
|
+
# force immediate output
|
193
|
+
# $stdout.sync = true
|
56
194
|
|
57
|
-
|
58
|
-
Giblog.logger
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
195
|
+
# setup logging
|
196
|
+
Giblog.setup(logger)
|
197
|
+
Giblog.logger.level = Logger::INFO
|
198
|
+
|
199
|
+
# Parse cmd line
|
200
|
+
user_opts = CmdLine.new.parse(args)
|
201
|
+
Giblog.logger.level = user_opts.log_level
|
202
|
+
Giblog.logger.debug { "cmd line args: #{user_opts.inspect}" }
|
203
|
+
|
204
|
+
# Select the coversion instance to use
|
205
|
+
@converter = select_conversion(user_opts)
|
206
|
+
end
|
207
|
+
|
208
|
+
def run
|
209
|
+
# do the conversion
|
210
|
+
@converter.run
|
211
|
+
end
|
212
|
+
|
213
|
+
def self.run(args, logger = nil)
|
214
|
+
EntryPoint.new(args, logger).run
|
215
|
+
end
|
216
|
+
|
217
|
+
# does not return, exits with status code
|
218
|
+
def self.run_from_cmd_line
|
219
|
+
begin
|
220
|
+
EntryPoint.run(ARGV)
|
221
|
+
Giblog.logger.info { "Giblish is done!" }
|
222
|
+
exit_code = 0
|
223
|
+
rescue => exc
|
224
|
+
Giblog.logger.error { exc.message }
|
225
|
+
Giblog.logger.error { exc.backtrace }
|
226
|
+
exit_code = 1
|
227
|
+
end
|
228
|
+
exit(exit_code)
|
229
|
+
end
|
230
|
+
|
231
|
+
private
|
63
232
|
|
64
|
-
|
65
|
-
|
233
|
+
def select_conversion(user_opts)
|
234
|
+
case user_opts
|
235
|
+
in {branch_regex: _} | {tag_regex: _}
|
236
|
+
GitRepoConvert.new(user_opts)
|
237
|
+
else
|
238
|
+
DirTreeConvert.new(user_opts)
|
66
239
|
end
|
67
240
|
end
|
68
241
|
end
|