bitclust-core 1.6.1 → 1.8.0
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/Rakefile +1 -0
- data/data/bitclust/catalog/ja_JP.UTF-8 +4 -2
- data/data/bitclust/template/class-index +0 -1
- data/data/bitclust/template/function-index +1 -0
- data/data/bitclust/template/layout +1 -0
- data/data/bitclust/template.epub/class +5 -5
- data/data/bitclust/template.epub/class-index +0 -1
- data/data/bitclust/template.epub/contents +7 -4
- data/data/bitclust/template.epub/layout +4 -4
- data/data/bitclust/template.offline/class-index +0 -1
- data/data/bitclust/template.offline/function-index +1 -0
- data/data/bitclust/template.offline/layout +3 -0
- data/lib/bitclust/classentry.rb +1 -1
- data/lib/bitclust/docentry.rb +1 -1
- data/lib/bitclust/functionentry.rb +1 -1
- data/lib/bitclust/generators/epub.rb +69 -5
- data/lib/bitclust/irb.rb +74 -0
- data/lib/bitclust/markdown_bridge.rb +11 -6
- data/lib/bitclust/markdown_exporter.rb +311 -0
- data/lib/bitclust/markdown_tree.rb +118 -11
- data/lib/bitclust/mdcompiler.rb +15 -1
- data/lib/bitclust/mdparser.rb +42 -1
- data/lib/bitclust/methoddatabase.rb +17 -4
- data/lib/bitclust/methodentry.rb +24 -0
- data/lib/bitclust/methodsignature.rb +1 -1
- data/lib/bitclust/nameutils.rb +13 -0
- data/lib/bitclust/preprocessor.rb +4 -37
- data/lib/bitclust/rbs_overload_matcher.rb +179 -0
- data/lib/bitclust/rbs_sig_importer.rb +276 -0
- data/lib/bitclust/rbs_signatures.rb +125 -0
- data/lib/bitclust/rdcompiler.rb +12 -1
- data/lib/bitclust/remote.rb +405 -0
- data/lib/bitclust/runner.rb +7 -10
- data/lib/bitclust/screen.rb +6 -1
- data/lib/bitclust/search_index_generator.rb +28 -10
- data/lib/bitclust/searcher.rb +54 -25
- data/lib/bitclust/subcommands/chm_command.rb +1 -1
- data/lib/bitclust/subcommands/epub_command.rb +2 -2
- data/lib/bitclust/subcommands/extract_command.rb +7 -0
- data/lib/bitclust/subcommands/htmlfile_command.rb +7 -0
- data/lib/bitclust/subcommands/methods_command.rb +5 -28
- data/lib/bitclust/subcommands/query_command.rb +1 -0
- data/lib/bitclust/subcommands/rbssig_command.rb +99 -0
- data/lib/bitclust/subcommands/server_command.rb +21 -10
- data/lib/bitclust/subcommands/setup_command.rb +32 -11
- data/lib/bitclust/subcommands/statichtml_command.rb +59 -0
- data/lib/bitclust/syntax_highlighter.rb +65 -4
- data/lib/bitclust/user_dirs.rb +62 -0
- data/lib/bitclust/version.rb +1 -1
- data/lib/bitclust-irb.rb +2 -0
- data/test/test_chm_command.rb +22 -0
- data/test/test_epub_command.rb +60 -0
- data/test/test_epub_generator.rb +330 -0
- data/test/test_extract_command.rb +45 -0
- data/test/test_irb_plugin.rb +212 -0
- data/test/test_link_checker.rb +1 -1
- data/test/test_markdown_bridge.rb +35 -0
- data/test/test_markdown_exporter.rb +260 -0
- data/test/test_markdown_tree.rb +144 -0
- data/test/test_mdcompiler.rb +47 -5
- data/test/test_mdparser.rb +223 -4
- data/test/test_methodentry.rb +111 -0
- data/test/test_methods_command.rb +32 -0
- data/test/test_methodsignature.rb +3 -1
- data/test/test_opensearchdescription_screen.rb +39 -0
- data/test/test_preprocessor.rb +26 -0
- data/test/test_query_command.rb +30 -0
- data/test/test_rbs_overload_matcher.rb +170 -0
- data/test/test_rbs_sig_importer.rb +237 -0
- data/test/test_rbssig_command.rb +186 -0
- data/test/test_rdcompiler.rb +99 -1
- data/test/test_remote.rb +374 -0
- data/test/test_runner.rb +61 -1
- data/test/test_search_index_generator.rb +81 -0
- data/test/test_searcher.rb +63 -0
- data/test/test_server_command.rb +41 -0
- data/test/test_setup_command.rb +164 -0
- data/test/test_statichtml_command.rb +137 -0
- data/test/test_syntax_highlighter.rb +124 -0
- data/test/test_user_dirs.rb +62 -0
- data/theme/default/js/run.js +14 -0
- data/theme/default/js/search_init.js +3 -1
- data/theme/default/js/search_page.js +7 -1
- data/theme/default/js/version_switcher.js +147 -0
- data/theme/default/search.css +21 -0
- data/theme/default/style.css +83 -7
- data/theme/lillia/style.css +26 -0
- metadata +71 -2
- data/lib/bitclust/ridatabase.rb +0 -359
data/lib/bitclust/searcher.rb
CHANGED
|
@@ -9,10 +9,12 @@
|
|
|
9
9
|
#
|
|
10
10
|
|
|
11
11
|
require 'bitclust/methoddatabase'
|
|
12
|
+
require 'bitclust/remote'
|
|
12
13
|
require 'bitclust/functiondatabase'
|
|
13
14
|
require 'bitclust/nameutils'
|
|
14
15
|
require 'bitclust/methodid'
|
|
15
16
|
require 'bitclust/exception'
|
|
17
|
+
require 'bitclust/user_dirs'
|
|
16
18
|
require 'uri'
|
|
17
19
|
require 'rbconfig'
|
|
18
20
|
require 'optparse'
|
|
@@ -36,6 +38,7 @@ module BitClust
|
|
|
36
38
|
@target_type = nil
|
|
37
39
|
@listen_url = nil
|
|
38
40
|
@foreground = false
|
|
41
|
+
@remote = Remote.default
|
|
39
42
|
@parser = OptionParser.new {|parser|
|
|
40
43
|
parser.banner = "Usage: #{@name} <pattern>"
|
|
41
44
|
unless cmd == 'bitclust'
|
|
@@ -91,6 +94,10 @@ module BitClust
|
|
|
91
94
|
|
|
92
95
|
attr_reader :parser
|
|
93
96
|
|
|
97
|
+
# ローカル DB が無いときに使うリモート検索(BitClust::Remote)。nil なら
|
|
98
|
+
# DB が無いことをエラーにする
|
|
99
|
+
attr_accessor :remote
|
|
100
|
+
|
|
94
101
|
def parse(argv)
|
|
95
102
|
@parser.parse! argv
|
|
96
103
|
if @listen_url # server mode
|
|
@@ -121,6 +128,22 @@ module BitClust
|
|
|
121
128
|
@parser.help
|
|
122
129
|
end
|
|
123
130
|
|
|
131
|
+
# irb プラグインなど組み込み利用向けの入口。argv のパターンを db から
|
|
132
|
+
# 検索し、結果を view(TerminalView)へ出力する。db が nil なら
|
|
133
|
+
# 既定の場所(環境変数 BITCLUST_DATADIR など・設定ファイル(UserDirs))
|
|
134
|
+
# から探す
|
|
135
|
+
def run_query(db, argv, view)
|
|
136
|
+
@view = view
|
|
137
|
+
search_pattern db, argv
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# 既定の場所(環境変数 BITCLUST_DATADIR など・設定ファイル(UserDirs))に
|
|
141
|
+
# ローカル DB があるか。irb プラグインが HTTP フォールバックへ切り替える
|
|
142
|
+
# 判定に使う。環境変数が不正な DB を指していれば InvalidDatabase
|
|
143
|
+
def local_database?
|
|
144
|
+
!find_dblocation().nil?
|
|
145
|
+
end
|
|
146
|
+
|
|
124
147
|
private
|
|
125
148
|
|
|
126
149
|
def server_mode_check(argv)
|
|
@@ -243,15 +266,23 @@ module BitClust
|
|
|
243
266
|
[ "#{datadir}/refe2", "#{datadir}/bitclust" ].each do |path|
|
|
244
267
|
return path if MethodDatabase.datadir?(path)
|
|
245
268
|
end
|
|
246
|
-
|
|
247
|
-
if
|
|
248
|
-
config = YAML.load_file(config_path)
|
|
269
|
+
config = UserDirs.load_config
|
|
270
|
+
if config
|
|
249
271
|
return "#{config[:database_prefix]}-#{config[:default_version]}"
|
|
250
272
|
end
|
|
251
273
|
nil
|
|
252
274
|
end
|
|
253
275
|
|
|
254
276
|
def search_pattern(db, argv)
|
|
277
|
+
if db.nil? && !find_dblocation
|
|
278
|
+
remote = @remote
|
|
279
|
+
unless remote
|
|
280
|
+
raise InvalidDatabase, "no database found: run `bitclust setup` to create one (remote search is disabled by BITCLUST_REMOTE_URL)"
|
|
281
|
+
end
|
|
282
|
+
remote.lookup(argv, @view.io, describe_all: @describe_all, line: @linep,
|
|
283
|
+
class_only: @target_type == :class)
|
|
284
|
+
return
|
|
285
|
+
end
|
|
255
286
|
db ||= new_database()
|
|
256
287
|
@view.database ||= db if @view
|
|
257
288
|
# FIXME なぜか else 節にきかないのでここに書いておく
|
|
@@ -352,16 +383,6 @@ module BitClust
|
|
|
352
383
|
find_method db, cnames.join('::'), '::', name
|
|
353
384
|
end
|
|
354
385
|
|
|
355
|
-
# 区切りは反転文字列上で探す。"?." は 4.0 以降の module function の
|
|
356
|
-
# 表示形式(反転すると ".?")で、内部表記の ".#" に正規化する
|
|
357
|
-
def parse_method_spec_pattern(pat)
|
|
358
|
-
_m, _t, _c = pat.reverse.split(/([\#,]\.|\.[\#,]|\.\?|[\#\.\,])/, 2)
|
|
359
|
-
c = (_c || raise).reverse
|
|
360
|
-
t = (_t || raise).tr(',', '#').sub(/\#\.|\.\?/, '.#')
|
|
361
|
-
m = (_m || raise).reverse
|
|
362
|
-
return c, t, m
|
|
363
|
-
end
|
|
364
|
-
|
|
365
386
|
end
|
|
366
387
|
|
|
367
388
|
|
|
@@ -374,16 +395,34 @@ module BitClust
|
|
|
374
395
|
|
|
375
396
|
class TerminalView
|
|
376
397
|
|
|
377
|
-
|
|
398
|
+
# io を省略すると出力先は呼び出し時点の $stdout(従来挙動)
|
|
399
|
+
def initialize(compiler, opts, io: nil)
|
|
378
400
|
@compiler = compiler
|
|
379
401
|
@describe_all = opts[:describe_all]
|
|
380
402
|
@line = opts[:line]
|
|
381
403
|
@encoding = opts[:encoding]
|
|
382
404
|
@database = nil
|
|
405
|
+
@io = io
|
|
383
406
|
end
|
|
384
407
|
|
|
385
408
|
attr_accessor :database
|
|
386
409
|
|
|
410
|
+
# 出力先(io: 省略時は $stdout)
|
|
411
|
+
def io
|
|
412
|
+
@io || $stdout
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
# 名前の一覧を表示する(-l なら 1 行 1 件、それ以外は端末幅に詰める)
|
|
416
|
+
def print_names(names)
|
|
417
|
+
if @line
|
|
418
|
+
names.sort.each do |n|
|
|
419
|
+
puts n
|
|
420
|
+
end
|
|
421
|
+
else
|
|
422
|
+
print_packed_names names.sort
|
|
423
|
+
end
|
|
424
|
+
end
|
|
425
|
+
|
|
387
426
|
def show_class(cs)
|
|
388
427
|
if cs.size == 1
|
|
389
428
|
if @line
|
|
@@ -440,16 +479,6 @@ module BitClust
|
|
|
440
479
|
|
|
441
480
|
private
|
|
442
481
|
|
|
443
|
-
def print_names(names)
|
|
444
|
-
if @line
|
|
445
|
-
names.sort.each do |n|
|
|
446
|
-
puts n
|
|
447
|
-
end
|
|
448
|
-
else
|
|
449
|
-
print_packed_names names.sort
|
|
450
|
-
end
|
|
451
|
-
end
|
|
452
|
-
|
|
453
482
|
def print_packed_names(names)
|
|
454
483
|
max = terminal_column()
|
|
455
484
|
buf = +''
|
|
@@ -546,7 +575,7 @@ module BitClust
|
|
|
546
575
|
end
|
|
547
576
|
|
|
548
577
|
def puts(*args)
|
|
549
|
-
|
|
578
|
+
(@io || $stdout).puts(*args.collect {|arg| convert(arg)})
|
|
550
579
|
end
|
|
551
580
|
|
|
552
581
|
def convert(string)
|
|
@@ -102,7 +102,7 @@ EOS
|
|
|
102
102
|
end
|
|
103
103
|
|
|
104
104
|
def to_html
|
|
105
|
-
str = "<LI> <OBJECT type=\"text/sitemap\">\n"
|
|
105
|
+
str = +"<LI> <OBJECT type=\"text/sitemap\">\n"
|
|
106
106
|
str << " <param name=\"Name\" value=\"<%=h @name%>\">\n"
|
|
107
107
|
if @local
|
|
108
108
|
str << " <param name=\"Local\" value=\"<%=@local%>\">\n"
|
|
@@ -12,7 +12,7 @@ module BitClust
|
|
|
12
12
|
def initialize
|
|
13
13
|
super
|
|
14
14
|
@verbose = true
|
|
15
|
-
@catalogdir =
|
|
15
|
+
@catalogdir = srcdir_root + "data/bitclust/catalog"
|
|
16
16
|
@templatedir = srcdir_root + "data/bitclust/template.epub"
|
|
17
17
|
@themedir = srcdir_root + "theme/default"
|
|
18
18
|
@filename = "rurema-#{Date.today}.epub"
|
|
@@ -54,7 +54,7 @@ module BitClust
|
|
|
54
54
|
generator = BitClust::Generators::EPUB.new(:prefix => options[:prefix],
|
|
55
55
|
:capi => options[:capi],
|
|
56
56
|
:outputdir => @outputdir,
|
|
57
|
-
:catalog => @
|
|
57
|
+
:catalog => @catalogdir,
|
|
58
58
|
:templatedir => @templatedir,
|
|
59
59
|
:themedir => @themedir,
|
|
60
60
|
:fs_casesensitive => @fs_casesensitive,
|
|
@@ -25,6 +25,7 @@ module BitClust
|
|
|
25
25
|
def exec(argv, options)
|
|
26
26
|
success = true
|
|
27
27
|
argv.each do |path|
|
|
28
|
+
reject_markdown_source(path)
|
|
28
29
|
begin
|
|
29
30
|
lib = RRDParser.parse_stdlib_file(path)
|
|
30
31
|
if @check_only
|
|
@@ -41,6 +42,12 @@ module BitClust
|
|
|
41
42
|
exit success
|
|
42
43
|
end
|
|
43
44
|
|
|
45
|
+
# 旧 RD ソース(refm)専用なので、Markdown は未対応として案内する
|
|
46
|
+
def reject_markdown_source(path)
|
|
47
|
+
return unless path.end_with?('.md')
|
|
48
|
+
error "#{path}: extract は旧 RD ソース(refm)専用で、Markdown(manual/ の .md)には未対応です。manual/ の内容は doctree の rake generate:X.Y と bitclust server で確認してください"
|
|
49
|
+
end
|
|
50
|
+
|
|
44
51
|
def show_library(lib)
|
|
45
52
|
puts "= Library #{lib.name}"
|
|
46
53
|
lib.classes.each do |c|
|
|
@@ -47,6 +47,7 @@ module BitClust
|
|
|
47
47
|
end
|
|
48
48
|
@capi = options[:capi]
|
|
49
49
|
target_file = argv[0]
|
|
50
|
+
reject_markdown_source(target_file)
|
|
50
51
|
if /refm\/doc\// =~ target_file
|
|
51
52
|
@rd_file = true if @rd_file.nil?
|
|
52
53
|
end
|
|
@@ -88,6 +89,12 @@ module BitClust
|
|
|
88
89
|
|
|
89
90
|
private
|
|
90
91
|
|
|
92
|
+
# 旧 RD ソース(refm)専用なので、Markdown は未対応として案内する
|
|
93
|
+
def reject_markdown_source(path)
|
|
94
|
+
return unless path && path.end_with?('.md')
|
|
95
|
+
error "#{path}: htmlfile は旧 RD ソース(refm)専用で、Markdown(manual/ の .md)には未対応です。manual/ の内容は doctree の rake generate:X.Y と bitclust server(または rake statichtml:X.Y)で確認してください"
|
|
96
|
+
end
|
|
97
|
+
|
|
91
98
|
def lookup(lib, key)
|
|
92
99
|
case
|
|
93
100
|
when @capi && NameUtils.functionname?(key)
|
|
@@ -29,16 +29,9 @@ module BitClust
|
|
|
29
29
|
@mode = :diff
|
|
30
30
|
@target = path
|
|
31
31
|
}
|
|
32
|
-
@parser.on('-c', '') {
|
|
33
|
-
@content = true
|
|
34
|
-
require 'bitclust/ridatabase'
|
|
35
|
-
}
|
|
36
32
|
@parser.on('--ruby=[VER]', "The version of Ruby interpreter"){|version|
|
|
37
33
|
@version = version
|
|
38
34
|
}
|
|
39
|
-
@parser.on('--ri-database', 'The path of ri database'){|path|
|
|
40
|
-
@ri_path = path
|
|
41
|
-
}
|
|
42
35
|
end
|
|
43
36
|
|
|
44
37
|
def parse(argv)
|
|
@@ -67,27 +60,11 @@ module BitClust
|
|
|
67
60
|
list0 = c.entries + list0
|
|
68
61
|
# @type var list: Array[String]
|
|
69
62
|
list = list0.map {|ent| ent.labels.map {|n| expand_mf(n) } }.flatten
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
(keys - list).sort.each do |name|
|
|
76
|
-
mthd = mthds.find{|m| name == m.fullname }
|
|
77
|
-
if mthd
|
|
78
|
-
puts fmt.method_info(mthd.entry)
|
|
79
|
-
else
|
|
80
|
-
name = name.sub(/\A\w+#/, '')
|
|
81
|
-
puts "--- #{name}\n#%todo\n\n"
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
else
|
|
85
|
-
(keys - list).sort.each do |name|
|
|
86
|
-
puts "-#{name}"
|
|
87
|
-
end
|
|
88
|
-
(list - keys).sort.each do |name|
|
|
89
|
-
puts "+#{name}"
|
|
90
|
-
end
|
|
63
|
+
(keys - list).sort.each do |name|
|
|
64
|
+
puts "-#{name}"
|
|
65
|
+
end
|
|
66
|
+
(list - keys).sort.each do |name|
|
|
67
|
+
puts "+#{name}"
|
|
91
68
|
end
|
|
92
69
|
else
|
|
93
70
|
raise "must not happen: #{@mode.inspect}"
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
#
|
|
3
|
+
# bitclust/subcommands/rbssig_command.rb
|
|
4
|
+
#
|
|
5
|
+
# RBS 型シグネチャを DB のメソッドエントリに書き込む(rbs_sig property):
|
|
6
|
+
#
|
|
7
|
+
# bitclust rbssig --sig-root=RBS_CHECKOUT <dbpath>
|
|
8
|
+
# bitclust rbssig --sig-dir=DIR [--sig-dir=DIR ...] <dbpath>
|
|
9
|
+
#
|
|
10
|
+
# DB 構築(update)後・statichtml 前に実行する(methodsince と同じ位置)。
|
|
11
|
+
# --sig-root には対象 Ruby バージョンに同梱される rbs のチェックアウト
|
|
12
|
+
# (core/ と stdlib/ を含む)を渡す。表示は 4.0 以降のドキュメント専用
|
|
13
|
+
# なので、DB の version が 4.0 未満ならエラーにする。
|
|
14
|
+
|
|
15
|
+
require 'bitclust'
|
|
16
|
+
require 'bitclust/subcommand'
|
|
17
|
+
require 'bitclust/rbs_sig_importer'
|
|
18
|
+
require 'tmpdir'
|
|
19
|
+
require 'fileutils'
|
|
20
|
+
|
|
21
|
+
module BitClust
|
|
22
|
+
module Subcommands
|
|
23
|
+
class RbssigCommand < Subcommand
|
|
24
|
+
MINIMUM_VERSION = Gem::Version.new('4.0')
|
|
25
|
+
|
|
26
|
+
def initialize
|
|
27
|
+
super
|
|
28
|
+
@sig_root = nil
|
|
29
|
+
@sig_dirs = []
|
|
30
|
+
@dry_run = false
|
|
31
|
+
@parser.banner = "Usage: #{File.basename($0, '.*')} rbssig [options] <dbpath>"
|
|
32
|
+
@parser.on('--sig-root=PATH', 'ruby/rbs checkout containing core/ and stdlib/.') {|path|
|
|
33
|
+
@sig_root = path
|
|
34
|
+
}
|
|
35
|
+
@parser.on('--sig-dir=PATH', 'Directory of extra .rbs files (repeatable).') {|path|
|
|
36
|
+
@sig_dirs.push path
|
|
37
|
+
}
|
|
38
|
+
@parser.on('--dry-run', 'Compute and print stats without saving.') {
|
|
39
|
+
@dry_run = true
|
|
40
|
+
}
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# DB パスは位置引数で受けるのでグローバル --database は不要
|
|
44
|
+
def needs_database?
|
|
45
|
+
false
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def exec(argv, options)
|
|
49
|
+
error('no --sig-root or --sig-dir given') if @sig_root.nil? && @sig_dirs.empty?
|
|
50
|
+
error("wrong number of arguments (#{argv.size} for 1)") unless argv.size == 1
|
|
51
|
+
path = argv.first
|
|
52
|
+
version = check_version(path)
|
|
53
|
+
|
|
54
|
+
sig_root = @sig_root
|
|
55
|
+
importer = RbsSigImporter.new(
|
|
56
|
+
core_root: sig_root && File.join(sig_root, 'core'),
|
|
57
|
+
repository_root: sig_root && File.join(sig_root, 'stdlib'),
|
|
58
|
+
sig_dirs: @sig_dirs)
|
|
59
|
+
stats =
|
|
60
|
+
if @dry_run
|
|
61
|
+
apply_dry_run(importer, path)
|
|
62
|
+
else
|
|
63
|
+
importer.apply(MethodDatabase.new(path))
|
|
64
|
+
end
|
|
65
|
+
puts "#{File.basename(path)} (version #{version}): " \
|
|
66
|
+
"entries_updated=#{stats[:entries_updated]} sigs_matched=#{stats[:sigs_matched]} " \
|
|
67
|
+
"methods_missed=#{stats[:methods_missed]}"
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
private
|
|
71
|
+
|
|
72
|
+
# RBS シグネチャ表示は 4.0 以降のドキュメント専用。比較は
|
|
73
|
+
# display_typemark(nameutils.rb)と同じく Gem::Version で行う
|
|
74
|
+
# (文字列比較だと "10.0" が "4.0" より小さく見える)
|
|
75
|
+
def check_version(path)
|
|
76
|
+
version = MethodDatabase.new(path).propget('version') or
|
|
77
|
+
error("#{path}: no version property (not a bitclust database?)")
|
|
78
|
+
begin
|
|
79
|
+
if Gem::Version.new(version) < MINIMUM_VERSION
|
|
80
|
+
error("#{path}: version #{version} is before 4.0; RBS signatures are only for 4.0+ databases")
|
|
81
|
+
end
|
|
82
|
+
rescue ArgumentError
|
|
83
|
+
error("#{path}: malformed version property: #{version.inspect}")
|
|
84
|
+
end
|
|
85
|
+
version
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# --dry-run: 実 DB には書き込まず、複製に apply した統計だけを見せる
|
|
89
|
+
# (methodsince の apply_dry_run と同じ手口)
|
|
90
|
+
def apply_dry_run(importer, path)
|
|
91
|
+
Dir.mktmpdir do |tmp|
|
|
92
|
+
copy = File.join(tmp, 'db')
|
|
93
|
+
FileUtils.cp_r(path, copy)
|
|
94
|
+
importer.apply(MethodDatabase.new(copy))
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -9,6 +9,7 @@ require 'uri'
|
|
|
9
9
|
|
|
10
10
|
require 'bitclust'
|
|
11
11
|
require 'bitclust/subcommand'
|
|
12
|
+
require 'bitclust/user_dirs'
|
|
12
13
|
|
|
13
14
|
module BitClust
|
|
14
15
|
module Subcommands
|
|
@@ -50,7 +51,7 @@ module BitClust
|
|
|
50
51
|
@parser.on('--baseurl=URL', 'The base URL to host.') {|url|
|
|
51
52
|
@baseurl = url
|
|
52
53
|
}
|
|
53
|
-
@parser.on('--database=PATH', 'MethodDatabase root directory.') {|path|
|
|
54
|
+
@parser.on('-d', '--database=PATH', 'MethodDatabase root directory.') {|path|
|
|
54
55
|
@dbpath = path
|
|
55
56
|
}
|
|
56
57
|
@parser.on('--srcdir=PATH', 'BitClust source directory.') {|path|
|
|
@@ -85,17 +86,20 @@ module BitClust
|
|
|
85
86
|
}
|
|
86
87
|
end
|
|
87
88
|
|
|
89
|
+
# DB はサブコマンド自身の -d/--database か、グローバル --database
|
|
90
|
+
# (options[:prefix])のどちらでも受ける。runner にはグローバル側を
|
|
91
|
+
# 要求させない(ancestors と同じ扱い)
|
|
92
|
+
def needs_database?
|
|
93
|
+
false
|
|
94
|
+
end
|
|
95
|
+
|
|
88
96
|
def parse(argv)
|
|
89
97
|
super
|
|
90
98
|
load_config_file
|
|
91
99
|
set_srcdir(srcdir_root) unless @srcdir
|
|
92
100
|
|
|
93
101
|
unless @baseurl
|
|
94
|
-
$stderr.puts "missing base URL. Use --baseurl or check
|
|
95
|
-
exit 1
|
|
96
|
-
end
|
|
97
|
-
unless @dbpath || @autop
|
|
98
|
-
$stderr.puts "missing database path. Use --database"
|
|
102
|
+
$stderr.puts "missing base URL. Use --baseurl or check the config file (bitclust setup)"
|
|
99
103
|
exit 1
|
|
100
104
|
end
|
|
101
105
|
unless @datadir
|
|
@@ -116,6 +120,7 @@ module BitClust
|
|
|
116
120
|
end
|
|
117
121
|
|
|
118
122
|
def exec(argv, options)
|
|
123
|
+
@dbpath = resolve_dbpath(options)
|
|
119
124
|
begin
|
|
120
125
|
require 'webrick'
|
|
121
126
|
rescue LoadError
|
|
@@ -210,11 +215,17 @@ module BitClust
|
|
|
210
215
|
@themedir ||= "#{@srcdir}/theme"
|
|
211
216
|
end
|
|
212
217
|
|
|
218
|
+
# サブコマンド側の --database が無ければグローバル --database
|
|
219
|
+
# (runner の options[:prefix])を使う。--auto のときは不要
|
|
220
|
+
def resolve_dbpath(options)
|
|
221
|
+
dbpath = @dbpath || options[:prefix]
|
|
222
|
+
abort "missing database path. Use --database (-d)" unless dbpath || @autop
|
|
223
|
+
dbpath
|
|
224
|
+
end
|
|
225
|
+
|
|
213
226
|
def load_config_file
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
if config_path.exist?
|
|
217
|
-
config = YAML.load_file(config_path)
|
|
227
|
+
config = UserDirs.load_config
|
|
228
|
+
if config
|
|
218
229
|
@baseurl ||= config[:baseurl]
|
|
219
230
|
@dbpath ||= "#{config[:database_prefix]}-#{config[:default_version]}"
|
|
220
231
|
@port ||= config[:port]
|
|
@@ -8,6 +8,7 @@ require 'yaml'
|
|
|
8
8
|
|
|
9
9
|
require 'bitclust'
|
|
10
10
|
require 'bitclust/subcommand'
|
|
11
|
+
require 'bitclust/user_dirs'
|
|
11
12
|
|
|
12
13
|
module BitClust
|
|
13
14
|
module Subcommands
|
|
@@ -20,7 +21,10 @@ module BitClust
|
|
|
20
21
|
@prepare = nil
|
|
21
22
|
@cleanup = nil
|
|
22
23
|
@purge = nil
|
|
23
|
-
|
|
24
|
+
# teeny は付けない。#%if (version == "V") や #%version V の等値ゲートは
|
|
25
|
+
# 文字列一致なので、teeny 付きの版名で DB を作ると doctree CI・
|
|
26
|
+
# 生成済みドキュメントとゲートの判定がずれる
|
|
27
|
+
@versions = ["3.3", "3.4", "4.0"]
|
|
24
28
|
@update = true
|
|
25
29
|
@parser.banner = "Usage: #{File.basename($0, '.*')} setup [options]"
|
|
26
30
|
@parser.on('--prepare', 'Prepare config file and checkout repository. Do not create database.') {
|
|
@@ -40,7 +44,9 @@ module BitClust
|
|
|
40
44
|
}
|
|
41
45
|
end
|
|
42
46
|
|
|
43
|
-
# DB
|
|
47
|
+
# DB は設定ファイル(UserDirs)が示す場所(既定は $XDG_DATA_HOME/bitclust、
|
|
48
|
+
# 旧 ~/.bitclust があればそちら)に自前で作るのでグローバル --database
|
|
49
|
+
# は不要
|
|
44
50
|
def needs_database?
|
|
45
51
|
false
|
|
46
52
|
end
|
|
@@ -65,22 +71,37 @@ module BitClust
|
|
|
65
71
|
private
|
|
66
72
|
|
|
67
73
|
def purge
|
|
68
|
-
home_directory = Pathname(ENV.fetch("HOME"))
|
|
69
|
-
config_dir = home_directory + ".bitclust"
|
|
70
74
|
print "Remove all generated files..."
|
|
71
|
-
|
|
75
|
+
puts
|
|
76
|
+
[UserDirs.legacy_dir, UserDirs.config_home, UserDirs.data_home, UserDirs.cache_home].each do |dir|
|
|
77
|
+
next unless dir.exist?
|
|
78
|
+
FileUtils.rm_rf(dir.to_s)
|
|
79
|
+
puts " removed #{dir}"
|
|
80
|
+
end
|
|
72
81
|
puts "done!"
|
|
73
82
|
exit 0
|
|
74
83
|
end
|
|
75
84
|
|
|
85
|
+
# 設定ファイル・DB・doctree checkout の置き場所を選ぶ。既に旧
|
|
86
|
+
# ~/.bitclust/config があり、まだ XDG 側の設定ファイルが無ければ
|
|
87
|
+
# 互換のため旧レイアウトを維持する。それ以外は XDG レイアウトを使う
|
|
88
|
+
def layout
|
|
89
|
+
legacy_config = UserDirs.legacy_dir + "config"
|
|
90
|
+
xdg_config = UserDirs.config_home + "config"
|
|
91
|
+
if legacy_config.exist? && !xdg_config.exist?
|
|
92
|
+
config_dir = UserDirs.legacy_dir
|
|
93
|
+
[config_dir + "config", (config_dir + "db").to_s, config_dir + "rubydoc"]
|
|
94
|
+
else
|
|
95
|
+
[xdg_config, (UserDirs.data_home + "db").to_s, UserDirs.data_home + "rubydoc"]
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
76
99
|
def prepare
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
config_path = config_dir + "config"
|
|
81
|
-
rubydoc_dir = config_dir + "rubydoc"
|
|
100
|
+
config_path, database_prefix, rubydoc_dir = layout
|
|
101
|
+
config_path.dirname.mkpath
|
|
102
|
+
rubydoc_dir.dirname.mkpath
|
|
82
103
|
@config = {
|
|
83
|
-
:database_prefix =>
|
|
104
|
+
:database_prefix => database_prefix,
|
|
84
105
|
:encoding => "utf-8",
|
|
85
106
|
:versions => @versions,
|
|
86
107
|
:default_version => @versions.max,
|
|
@@ -13,6 +13,7 @@ require 'bitclust/subcommand'
|
|
|
13
13
|
require 'bitclust/progress_bar'
|
|
14
14
|
require 'bitclust/silent_progress_bar'
|
|
15
15
|
require 'bitclust/search_index_generator'
|
|
16
|
+
require 'bitclust/markdown_exporter'
|
|
16
17
|
|
|
17
18
|
module BitClust
|
|
18
19
|
module Subcommands
|
|
@@ -125,6 +126,7 @@ module BitClust
|
|
|
125
126
|
@run_ruby_wasm = nil
|
|
126
127
|
@sitemap_baseurl = nil
|
|
127
128
|
@sitemap_paths = []
|
|
129
|
+
@markdown_output = false
|
|
128
130
|
@parser.banner = "Usage: #{File.basename($0, '.*')} statichtml [options]"
|
|
129
131
|
@parser.on('-o', '--outputdir=PATH', 'Output directory') do |path|
|
|
130
132
|
begin
|
|
@@ -170,6 +172,9 @@ module BitClust
|
|
|
170
172
|
@parser.on('--sitemap-baseurl=URL', 'Generate sitemap.xml under the output directory, with <loc> built from this base URL (e.g. https://docs.ruby-lang.org/ja/3.4/). Omit to skip sitemap.xml generation (default)') do |url|
|
|
171
173
|
@sitemap_baseurl = url
|
|
172
174
|
end
|
|
175
|
+
@parser.on('--markdown-output', 'Also write each page as Markdown (.md next to the .html), assembled from the preprocessed Markdown sources. Ignored for databases not created from a Markdown tree') do
|
|
176
|
+
@markdown_output = true
|
|
177
|
+
end
|
|
173
178
|
@parser.on('--no-stop-on-syntax-error', 'Do not stop on syntax error') do |boolean|
|
|
174
179
|
@stop_on_syntax_error = boolean
|
|
175
180
|
end
|
|
@@ -185,8 +190,10 @@ module BitClust
|
|
|
185
190
|
db = MethodDatabase.new(prefix.to_s)
|
|
186
191
|
fdb = FunctionDatabase.new(prefix.to_s)
|
|
187
192
|
manager = ScreenManager.new(@manager_config)
|
|
193
|
+
@markdown_exporter = MarkdownExporter.new(@urlmapper, @suffix) if @markdown_output
|
|
188
194
|
|
|
189
195
|
db.transaction do
|
|
196
|
+
warn_markdown_output_skipped(db, "the method database")
|
|
190
197
|
methods = {} #: Hash[String, Array[MethodEntry]]
|
|
191
198
|
db.methods.each_with_index do |entry, i|
|
|
192
199
|
next if entry.undefined?
|
|
@@ -203,6 +210,7 @@ module BitClust
|
|
|
203
210
|
end
|
|
204
211
|
|
|
205
212
|
fdb.transaction do
|
|
213
|
+
warn_markdown_output_skipped(fdb, "the function database")
|
|
206
214
|
create_html_entries("capi", fdb.functions, manager, fdb)
|
|
207
215
|
end
|
|
208
216
|
|
|
@@ -234,6 +242,7 @@ module BitClust
|
|
|
234
242
|
FileUtils.cp(@manager_config[:themedir] + "script.js",
|
|
235
243
|
@outputdir.to_s, :verbose => @verbose, :preserve => true)
|
|
236
244
|
copy_run_ruby_wasm_script if @run_ruby_wasm
|
|
245
|
+
copy_version_switcher_script
|
|
237
246
|
FileUtils.cp(@manager_config[:themedir] + @manager_config[:favicon_url],
|
|
238
247
|
@outputdir.to_s, :verbose => @verbose, :preserve => true)
|
|
239
248
|
Dir.mktmpdir do |tmpdir|
|
|
@@ -412,6 +421,19 @@ HERE
|
|
|
412
421
|
end
|
|
413
422
|
end
|
|
414
423
|
|
|
424
|
+
# Copy the version-switcher script. A themedir without it is
|
|
425
|
+
# tolerated: warn and skip instead of aborting the whole build.
|
|
426
|
+
def copy_version_switcher_script
|
|
427
|
+
src = @manager_config[:themedir] + "js" + "version_switcher.js"
|
|
428
|
+
unless src.file?
|
|
429
|
+
$stderr.puts "warning: #{src} not found; version switcher script not copied"
|
|
430
|
+
return
|
|
431
|
+
end
|
|
432
|
+
jsdir = @outputdir + "js"
|
|
433
|
+
FileUtils.mkdir_p(jsdir) unless jsdir.directory?
|
|
434
|
+
FileUtils.cp(src.to_s, jsdir.to_s, :verbose => @verbose, :preserve => true)
|
|
435
|
+
end
|
|
436
|
+
|
|
415
437
|
def create_html_file(entry, manager, outputdir, db)
|
|
416
438
|
e = entry.is_a?(Array) ? entry.sort.first : entry
|
|
417
439
|
case e.type_id
|
|
@@ -419,6 +441,7 @@ HERE
|
|
|
419
441
|
@urlmapper.bitclust_html_base = '..'
|
|
420
442
|
path = outputdir + e.type_id.to_s + html_filename(encodename_package(e.name), @suffix)
|
|
421
443
|
create_html_file_p(entry, manager, path, db)
|
|
444
|
+
create_markdown_file_p(e, path, db)
|
|
422
445
|
when :function
|
|
423
446
|
create_html_function_file(entry, manager, outputdir, db)
|
|
424
447
|
else
|
|
@@ -435,6 +458,11 @@ HERE
|
|
|
435
458
|
path = outputdir + e.type_id.to_s + encodename_package(e.klass.name) +
|
|
436
459
|
e.typechar + html_filename(encodename_package(name), @suffix)
|
|
437
460
|
create_html_file_p(entries, manager, path, db)
|
|
461
|
+
if markdown_export?(db)
|
|
462
|
+
create_file(markdown_path(path),
|
|
463
|
+
@markdown_exporter.method_page(method_name, entries.sort),
|
|
464
|
+
:verbose => @verbose)
|
|
465
|
+
end
|
|
438
466
|
end
|
|
439
467
|
|
|
440
468
|
def create_html_function_file(entry, manager, outputdir, db)
|
|
@@ -442,6 +470,7 @@ HERE
|
|
|
442
470
|
@urlmapper.bitclust_html_base = '..'
|
|
443
471
|
path = outputdir + entry.type_id.to_s + html_filename(entry.name, @suffix)
|
|
444
472
|
create_html_file_p(entry, manager, path, db)
|
|
473
|
+
create_markdown_file_p(entry, path, db)
|
|
445
474
|
end
|
|
446
475
|
|
|
447
476
|
def create_html_file_p(entry, manager, path, db)
|
|
@@ -453,6 +482,36 @@ HERE
|
|
|
453
482
|
record_sitemap_path(path)
|
|
454
483
|
end
|
|
455
484
|
|
|
485
|
+
# --markdown-output は Markdown ツリー由来の DB でのみ有効。
|
|
486
|
+
# ソースが md でない(凍結版 RD など)DB では何も出力しない
|
|
487
|
+
def markdown_export?(db)
|
|
488
|
+
@markdown_output && db.properties['source_format'] == 'markdown'
|
|
489
|
+
end
|
|
490
|
+
|
|
491
|
+
def warn_markdown_output_skipped(db, label)
|
|
492
|
+
return if !@markdown_output || db.properties['source_format'] == 'markdown'
|
|
493
|
+
$stderr.puts "warning: --markdown-output is ignored for #{label}: it was not created from a Markdown tree"
|
|
494
|
+
end
|
|
495
|
+
|
|
496
|
+
def create_markdown_file_p(entry, html_path, db)
|
|
497
|
+
return unless markdown_export?(db)
|
|
498
|
+
content =
|
|
499
|
+
case entry.type_id
|
|
500
|
+
when :library then @markdown_exporter.library_page(_ = entry)
|
|
501
|
+
when :class then @markdown_exporter.class_page(_ = entry)
|
|
502
|
+
when :doc then @markdown_exporter.doc_page(_ = entry)
|
|
503
|
+
when :function then @markdown_exporter.function_page(_ = entry)
|
|
504
|
+
else return
|
|
505
|
+
end
|
|
506
|
+
create_file(markdown_path(html_path), content, :verbose => @verbose)
|
|
507
|
+
end
|
|
508
|
+
|
|
509
|
+
def markdown_path(html_path)
|
|
510
|
+
s = html_path.to_s
|
|
511
|
+
s = s.end_with?(@suffix) ? s[0, s.length - @suffix.length].to_s : s
|
|
512
|
+
Pathname.new("#{s}.md")
|
|
513
|
+
end
|
|
514
|
+
|
|
456
515
|
def create_file(path, str, options = {})
|
|
457
516
|
verbose = options[:verbose]
|
|
458
517
|
$stderr.print("creating #{path} ...") if verbose
|