xlsxrb 0.1.11 → 0.1.13
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/CHANGELOG.md +86 -34
- data/README.md +26 -21
- data/lib/xlsxrb/chart_builder.rb +18 -18
- data/lib/xlsxrb/dsl_helpers.rb +175 -0
- data/lib/xlsxrb/elements/cell.rb +56 -22
- data/lib/xlsxrb/elements/column.rb +27 -3
- data/lib/xlsxrb/elements/row.rb +27 -8
- data/lib/xlsxrb/elements/workbook.rb +27 -14
- data/lib/xlsxrb/elements/worksheet.rb +17 -1
- data/lib/xlsxrb/ooxml/cfb.rb +9 -6
- data/lib/xlsxrb/ooxml/crypto/agile.rb +5 -5
- data/lib/xlsxrb/ooxml/reader/listeners/core_listeners.rb +784 -0
- data/lib/xlsxrb/ooxml/reader/listeners/drawing_listeners.rb +3478 -0
- data/lib/xlsxrb/ooxml/reader/listeners/feature_listeners.rb +1796 -0
- data/lib/xlsxrb/ooxml/reader/listeners/style_listeners.rb +428 -0
- data/lib/xlsxrb/ooxml/reader/listeners.rb +4 -6446
- data/lib/xlsxrb/ooxml/shared_strings_parser.rb +3 -5
- data/lib/xlsxrb/ooxml/utils.rb +5 -6
- data/lib/xlsxrb/ooxml/workbook_writer.rb +5 -7
- data/lib/xlsxrb/ooxml/worksheet_parser.rb +172 -9
- data/lib/xlsxrb/ooxml/writer/drawing_xml.rb +1602 -0
- data/lib/xlsxrb/ooxml/writer/features_xml.rb +731 -0
- data/lib/xlsxrb/ooxml/writer/styles_xml.rb +348 -0
- data/lib/xlsxrb/ooxml/writer.rb +9 -2646
- data/lib/xlsxrb/ooxml/xml_builder.rb +31 -2
- data/lib/xlsxrb/ooxml/zip_generator.rb +26 -5
- data/lib/xlsxrb/ooxml/zip_reader.rb +364 -78
- data/lib/xlsxrb/ooxml/zip_writer.rb +32 -5
- data/lib/xlsxrb/stream_sheet.rb +94 -6
- data/lib/xlsxrb/stream_writer.rb +48 -115
- data/lib/xlsxrb/style_builder.rb +10 -1
- data/lib/xlsxrb/version.rb +1 -1
- data/lib/xlsxrb/workbook_builder.rb +1 -1
- data/lib/xlsxrb/worksheet_builder.rb +19 -81
- data/lib/xlsxrb.rb +449 -171
- data/sig/generated/xlsxrb/chart_builder.rbs +36 -36
- data/sig/generated/xlsxrb/dsl_helpers.rbs +92 -0
- data/sig/generated/xlsxrb/elements/cell.rbs +29 -0
- data/sig/generated/xlsxrb/elements/column.rbs +32 -21
- data/sig/generated/xlsxrb/elements/row.rbs +94 -14
- data/sig/generated/xlsxrb/elements/workbook.rbs +102 -10
- data/sig/generated/xlsxrb/elements/worksheet.rbs +9 -0
- data/sig/generated/xlsxrb/ooxml/reader/listeners/core_listeners.rbs +173 -0
- data/sig/generated/xlsxrb/ooxml/reader/listeners/drawing_listeners.rbs +400 -0
- data/sig/generated/xlsxrb/ooxml/reader/listeners/feature_listeners.rbs +442 -0
- data/sig/generated/xlsxrb/ooxml/reader/listeners/style_listeners.rbs +80 -0
- data/sig/generated/xlsxrb/ooxml/reader/listeners.rbs +0 -1072
- data/sig/generated/xlsxrb/ooxml/shared_strings_parser.rbs +0 -2
- data/sig/generated/xlsxrb/ooxml/utils.rbs +2 -0
- data/sig/generated/xlsxrb/ooxml/worksheet_parser.rbs +5 -4
- data/sig/generated/xlsxrb/ooxml/writer/drawing_xml.rbs +79 -0
- data/sig/generated/xlsxrb/ooxml/writer/features_xml.rbs +83 -0
- data/sig/generated/xlsxrb/ooxml/writer/styles_xml.rbs +53 -0
- data/sig/generated/xlsxrb/ooxml/writer.rbs +6 -185
- data/sig/generated/xlsxrb/ooxml/xml_builder.rbs +18 -0
- data/sig/generated/xlsxrb/ooxml/zip_generator.rbs +15 -0
- data/sig/generated/xlsxrb/ooxml/zip_reader.rbs +96 -8
- data/sig/generated/xlsxrb/ooxml/zip_writer.rbs +5 -1
- data/sig/generated/xlsxrb/stream_sheet.rbs +43 -3
- data/sig/generated/xlsxrb/style_builder.rbs +7 -0
- data/sig/generated/xlsxrb.rbs +18 -11
- metadata +22 -144
- data/.devcontainer/Dockerfile +0 -65
- data/.devcontainer/devcontainer.json +0 -17
- data/.gem_rbs_collection/ast/2.4/.rbs_meta.yaml +0 -9
- data/.gem_rbs_collection/ast/2.4/ast.rbs +0 -73
- data/.gem_rbs_collection/concurrent-ruby/1.1/.rbs_meta.yaml +0 -9
- data/.gem_rbs_collection/concurrent-ruby/1.1/array.rbs +0 -4
- data/.gem_rbs_collection/concurrent-ruby/1.1/atomic_reference.rbs +0 -16
- data/.gem_rbs_collection/concurrent-ruby/1.1/executor.rbs +0 -96
- data/.gem_rbs_collection/concurrent-ruby/1.1/hash.rbs +0 -4
- data/.gem_rbs_collection/concurrent-ruby/1.1/map.rbs +0 -68
- data/.gem_rbs_collection/concurrent-ruby/1.1/promises.rbs +0 -249
- data/.gem_rbs_collection/concurrent-ruby/1.1/set.rbs +0 -4
- data/.gem_rbs_collection/concurrent-ruby/1.1/timer_task.rbs +0 -47
- data/.gem_rbs_collection/concurrent-ruby/1.1/utility/processor_counter.rbs +0 -5
- data/.gem_rbs_collection/csv/3.3/.rbs_meta.yaml +0 -9
- data/.gem_rbs_collection/csv/3.3/csv.rbs +0 -3871
- data/.gem_rbs_collection/csv/3.3/manifest.yaml +0 -3
- data/.gem_rbs_collection/lint_roller/1.1/.rbs_meta.yaml +0 -9
- data/.gem_rbs_collection/lint_roller/1.1/lint_roller.rbs +0 -48
- data/.gem_rbs_collection/listen/3.9/.rbs_meta.yaml +0 -9
- data/.gem_rbs_collection/listen/3.9/listen.rbs +0 -25
- data/.gem_rbs_collection/listen/3.9/listener.rbs +0 -24
- data/.gem_rbs_collection/logger/1.7/.rbs_meta.yaml +0 -9
- data/.gem_rbs_collection/logger/1.7/formatter.rbs +0 -45
- data/.gem_rbs_collection/logger/1.7/log_device.rbs +0 -100
- data/.gem_rbs_collection/logger/1.7/logger.rbs +0 -796
- data/.gem_rbs_collection/logger/1.7/manifest.yaml +0 -2
- data/.gem_rbs_collection/logger/1.7/period.rbs +0 -17
- data/.gem_rbs_collection/logger/1.7/severity.rbs +0 -34
- data/.gem_rbs_collection/nokogiri/1.11/.rbs_meta.yaml +0 -9
- data/.gem_rbs_collection/nokogiri/1.11/nokogiri.rbs +0 -2332
- data/.gem_rbs_collection/nokogiri/1.11/patch.rbs +0 -4
- data/.gem_rbs_collection/parallel/1.20/.rbs_meta.yaml +0 -9
- data/.gem_rbs_collection/parallel/1.20/parallel.rbs +0 -86
- data/.gem_rbs_collection/parser/3.2/.rbs_meta.yaml +0 -9
- data/.gem_rbs_collection/parser/3.2/manifest.yaml +0 -7
- data/.gem_rbs_collection/parser/3.2/parser.rbs +0 -194
- data/.gem_rbs_collection/parser/3.2/polyfill.rbs +0 -4
- data/.gem_rbs_collection/rainbow/3.0/.rbs_meta.yaml +0 -9
- data/.gem_rbs_collection/rainbow/3.0/global.rbs +0 -7
- data/.gem_rbs_collection/rainbow/3.0/presenter.rbs +0 -209
- data/.gem_rbs_collection/rainbow/3.0/rainbow.rbs +0 -5
- data/.gem_rbs_collection/rake/13.0/.rbs_meta.yaml +0 -9
- data/.gem_rbs_collection/rake/13.0/manifest.yaml +0 -2
- data/.gem_rbs_collection/rake/13.0/rake.rbs +0 -39
- data/.gem_rbs_collection/regexp_parser/2.8/.rbs_meta.yaml +0 -9
- data/.gem_rbs_collection/regexp_parser/2.8/regexp_parser.rbs +0 -17
- data/.gem_rbs_collection/rubocop/1.57/.rbs_meta.yaml +0 -9
- data/.gem_rbs_collection/rubocop/1.57/rubocop.rbs +0 -208
- data/.gem_rbs_collection/rubocop-ast/1.46/.rbs_meta.yaml +0 -9
- data/.gem_rbs_collection/rubocop-ast/1.46/rubocop-ast.rbs +0 -903
- data/.gem_rbs_collection/rubyzip/3.2/.rbs_meta.yaml +0 -9
- data/.gem_rbs_collection/rubyzip/3.2/manifest.yaml +0 -8
- data/.gem_rbs_collection/rubyzip/3.2/zip/central_directory.rbs +0 -42
- data/.gem_rbs_collection/rubyzip/3.2/zip/compressor.rbs +0 -5
- data/.gem_rbs_collection/rubyzip/3.2/zip/constants.rbs +0 -47
- data/.gem_rbs_collection/rubyzip/3.2/zip/crypto/aes_encryption.rbs +0 -30
- data/.gem_rbs_collection/rubyzip/3.2/zip/crypto/decrypted_io.rbs +0 -9
- data/.gem_rbs_collection/rubyzip/3.2/zip/crypto/encryption.rbs +0 -7
- data/.gem_rbs_collection/rubyzip/3.2/zip/crypto/null_encryption.rbs +0 -19
- data/.gem_rbs_collection/rubyzip/3.2/zip/crypto/traditional_encryption.rbs +0 -31
- data/.gem_rbs_collection/rubyzip/3.2/zip/decompressor.rbs +0 -18
- data/.gem_rbs_collection/rubyzip/3.2/zip/deflater.rbs +0 -12
- data/.gem_rbs_collection/rubyzip/3.2/zip/dirtyable.rbs +0 -11
- data/.gem_rbs_collection/rubyzip/3.2/zip/dos_time.rbs +0 -13
- data/.gem_rbs_collection/rubyzip/3.2/zip/entry.rbs +0 -95
- data/.gem_rbs_collection/rubyzip/3.2/zip/entry_set.rbs +0 -31
- data/.gem_rbs_collection/rubyzip/3.2/zip/errors.rbs +0 -58
- data/.gem_rbs_collection/rubyzip/3.2/zip/extra_field/aes.rbs +0 -24
- data/.gem_rbs_collection/rubyzip/3.2/zip/extra_field/generic.rbs +0 -17
- data/.gem_rbs_collection/rubyzip/3.2/zip/extra_field/ntfs.rbs +0 -23
- data/.gem_rbs_collection/rubyzip/3.2/zip/extra_field/old_unix.rbs +0 -22
- data/.gem_rbs_collection/rubyzip/3.2/zip/extra_field/universal_time.rbs +0 -30
- data/.gem_rbs_collection/rubyzip/3.2/zip/extra_field/unix.rbs +0 -20
- data/.gem_rbs_collection/rubyzip/3.2/zip/extra_field/unknown.rbs +0 -15
- data/.gem_rbs_collection/rubyzip/3.2/zip/extra_field/zip64.rbs +0 -26
- data/.gem_rbs_collection/rubyzip/3.2/zip/extra_field.rbs +0 -21
- data/.gem_rbs_collection/rubyzip/3.2/zip/file.rbs +0 -131
- data/.gem_rbs_collection/rubyzip/3.2/zip/file_split.rbs +0 -14
- data/.gem_rbs_collection/rubyzip/3.2/zip/filesystem/dir.rbs +0 -33
- data/.gem_rbs_collection/rubyzip/3.2/zip/filesystem/directory_iterator.rbs +0 -21
- data/.gem_rbs_collection/rubyzip/3.2/zip/filesystem/file.rbs +0 -63
- data/.gem_rbs_collection/rubyzip/3.2/zip/filesystem/file_stat.rbs +0 -55
- data/.gem_rbs_collection/rubyzip/3.2/zip/filesystem/zip_file_name_mapper.rbs +0 -35
- data/.gem_rbs_collection/rubyzip/3.2/zip/filesystem.rbs +0 -7
- data/.gem_rbs_collection/rubyzip/3.2/zip/inflater.rbs +0 -10
- data/.gem_rbs_collection/rubyzip/3.2/zip/input_stream.rbs +0 -22
- data/.gem_rbs_collection/rubyzip/3.2/zip/ioextras/abstract_input_stream.rbs +0 -29
- data/.gem_rbs_collection/rubyzip/3.2/zip/ioextras/abstract_output_stream.rbs +0 -17
- data/.gem_rbs_collection/rubyzip/3.2/zip/ioextras.rbs +0 -13
- data/.gem_rbs_collection/rubyzip/3.2/zip/null_compressor.rbs +0 -10
- data/.gem_rbs_collection/rubyzip/3.2/zip/null_decompressor.rbs +0 -8
- data/.gem_rbs_collection/rubyzip/3.2/zip/null_input_stream.rbs +0 -6
- data/.gem_rbs_collection/rubyzip/3.2/zip/output_stream.rbs +0 -30
- data/.gem_rbs_collection/rubyzip/3.2/zip/pass_thru_compressor.rbs +0 -10
- data/.gem_rbs_collection/rubyzip/3.2/zip/pass_thru_decompressor.rbs +0 -10
- data/.gem_rbs_collection/rubyzip/3.2/zip/streamable_directory.rbs +0 -5
- data/.gem_rbs_collection/rubyzip/3.2/zip/streamable_stream.rbs +0 -15
- data/.gem_rbs_collection/rubyzip/3.2/zip/version.rbs +0 -3
- data/.gem_rbs_collection/rubyzip/3.2/zip.rbs +0 -40
- data/Rakefile +0 -567
- data/Steepfile +0 -18
- data/benchmark.rb +0 -406
- data/docs/ARCHITECTURE.md +0 -514
- data/docs/DEVELOPMENT.md +0 -133
- data/docs/PEER_LIBRARIES.md +0 -121
- data/docs/QUALITY_ASSURANCE.md +0 -25
- data/docs/SPEC_SOURCES.md +0 -48
- data/docs/assets/benchmark_results.svg +0 -144
- data/docs/assets/lsp_autocompletion.png +0 -0
- data/docs/assets/playground_preview.png +0 -0
- data/docs/coi-serviceworker.js +0 -82
- data/docs/office_thread.js +0 -77
- data/docs/preview.html +0 -719
- data/docs/visual/VisualGallery.md +0 -4672
- data/docs/wasm/ruby.wasm +0 -0
- data/docs/wasm/wasm_doc_helper.css +0 -351
- data/docs/wasm/wasm_doc_helper.js +0 -439
- data/docs/zeta.js +0 -1107
- data/rbs_collection.lock.yaml +0 -252
- data/rbs_collection.yaml +0 -19
- data/vendor/sdk_runner/Program.cs +0 -93
- data/vendor/sdk_runner/sdk_runner.csproj +0 -13
data/Rakefile
DELETED
|
@@ -1,567 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "bundler/gem_tasks"
|
|
4
|
-
require "rake/testtask"
|
|
5
|
-
require "etc"
|
|
6
|
-
require "fileutils"
|
|
7
|
-
require "open3"
|
|
8
|
-
require "tmpdir"
|
|
9
|
-
|
|
10
|
-
def dotnet_available?
|
|
11
|
-
system("which dotnet > /dev/null 2>&1")
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
desc "Build the Open XML SDK runner"
|
|
15
|
-
task :build_sdk_runner do
|
|
16
|
-
if dotnet_available?
|
|
17
|
-
sh "dotnet build vendor/sdk_runner/sdk_runner.csproj -c Release"
|
|
18
|
-
elsif File.exist?(sdk_runner_dll)
|
|
19
|
-
puts "dotnet not found in PATH, but pre-built sdk_runner.dll exists. Skipping build."
|
|
20
|
-
else
|
|
21
|
-
warn "dotnet command not found and sdk_runner.dll is missing. Cannot build SDK runner."
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def reader_fixture_dir
|
|
26
|
-
File.expand_path("test/fixtures/reader_generated", __dir__)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def sdk_scenario_dir
|
|
30
|
-
File.expand_path("test/fixtures/sdk_scenarios", __dir__)
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def sdk_runner_dll
|
|
34
|
-
File.expand_path("vendor/sdk_runner/bin/Release/net8.0/sdk_runner.dll", __dir__)
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def reader_fixture_specs
|
|
38
|
-
Dir.glob(File.join(sdk_scenario_dir, "reader_*_generated_by_sdk.cs")).map do |scenario_path|
|
|
39
|
-
scenario_name = File.basename(scenario_path, ".cs")
|
|
40
|
-
[scenario_name, File.join(reader_fixture_dir, "#{scenario_name}.xlsx")]
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def reader_fixture_workers
|
|
45
|
-
Integer(ENV.fetch("READER_FIXTURE_WORKERS", Etc.nprocessors))
|
|
46
|
-
rescue ArgumentError
|
|
47
|
-
Etc.nprocessors
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
desc "Ensure SDK-generated reader fixtures exist"
|
|
51
|
-
task :ensure_reader_fixtures do
|
|
52
|
-
missing_specs = reader_fixture_specs.reject { |_scenario_name, fixture_path| File.exist?(fixture_path) }
|
|
53
|
-
next if missing_specs.empty?
|
|
54
|
-
|
|
55
|
-
Rake::Task[:build_sdk_runner].invoke
|
|
56
|
-
raise "Cannot generate #{missing_specs.size} missing reader fixture(s) because dotnet is not installed." unless dotnet_available?
|
|
57
|
-
|
|
58
|
-
FileUtils.mkdir_p(reader_fixture_dir)
|
|
59
|
-
|
|
60
|
-
queue = Queue.new
|
|
61
|
-
missing_specs.each { |spec| queue << spec }
|
|
62
|
-
failures = Queue.new
|
|
63
|
-
|
|
64
|
-
worker_count = [reader_fixture_workers, missing_specs.size].min
|
|
65
|
-
threads = Array.new(worker_count) do
|
|
66
|
-
Thread.new do
|
|
67
|
-
loop do
|
|
68
|
-
scenario_name, fixture_path = queue.pop(true)
|
|
69
|
-
scenario_path = File.join(sdk_scenario_dir, "#{scenario_name}.cs")
|
|
70
|
-
FileUtils.touch(fixture_path)
|
|
71
|
-
|
|
72
|
-
stdout, stderr, status = Open3.capture3(
|
|
73
|
-
"dotnet", sdk_runner_dll, scenario_path, fixture_path
|
|
74
|
-
)
|
|
75
|
-
|
|
76
|
-
next if status.success?
|
|
77
|
-
|
|
78
|
-
FileUtils.rm_f(fixture_path)
|
|
79
|
-
message = stderr.to_s.strip.empty? ? stdout : stderr
|
|
80
|
-
failures << "Failed to generate reader fixture #{scenario_name}: #{message}"
|
|
81
|
-
rescue ThreadError
|
|
82
|
-
break
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
threads.each(&:join)
|
|
88
|
-
next if failures.empty?
|
|
89
|
-
|
|
90
|
-
raise failures.pop
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
Rake::TestTask.new(test: :ensure_reader_fixtures) do |t|
|
|
94
|
-
t.libs << "test"
|
|
95
|
-
t.libs << "lib"
|
|
96
|
-
t.test_files = FileList["test/xlsxrb/**/*_test.rb", "test/*_test.rb", "test/contract/**/*_test.rb"]
|
|
97
|
-
workers = ENV.fetch("TEST_WORKERS", [Etc.nprocessors, 4].min)
|
|
98
|
-
t.options = "--parallel --n-workers=#{workers}"
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
namespace :test do
|
|
102
|
-
desc "Run tests with runtime type checking enabled (RBS_TEST=1)"
|
|
103
|
-
task :rbs do
|
|
104
|
-
ENV["RBS_TEST"] = "1"
|
|
105
|
-
Rake::Task["test:unit"].invoke
|
|
106
|
-
Rake::Task["test:contract"].invoke
|
|
107
|
-
end
|
|
108
|
-
Rake::TestTask.new(:unit) do |t|
|
|
109
|
-
t.libs << "test"
|
|
110
|
-
t.libs << "lib"
|
|
111
|
-
t.test_files = FileList["test/xlsxrb/**/*_test.rb", "test/*_test.rb"]
|
|
112
|
-
workers = ENV.fetch("TEST_WORKERS", Etc.nprocessors)
|
|
113
|
-
t.options = "--parallel --n-workers=#{workers}"
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
Rake::TestTask.new(:contract) do |t|
|
|
117
|
-
t.libs << "test"
|
|
118
|
-
t.libs << "lib"
|
|
119
|
-
t.test_files = FileList["test/contract/**/*_test.rb"]
|
|
120
|
-
workers = ENV.fetch("TEST_WORKERS", Etc.nprocessors)
|
|
121
|
-
t.options = "--parallel --n-workers=#{workers}"
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
desc "Run property-based tests (PBT)"
|
|
125
|
-
Rake::TestTask.new(:pbt) do |t|
|
|
126
|
-
t.libs << "test"
|
|
127
|
-
t.libs << "lib"
|
|
128
|
-
t.test_files = FileList["test/pbt/**/*_test.rb"]
|
|
129
|
-
workers = ENV.fetch("TEST_WORKERS", Etc.nprocessors)
|
|
130
|
-
t.options = "--parallel --n-workers=#{workers}"
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
desc "Run memory and performance tests"
|
|
134
|
-
Rake::TestTask.new(:performance) do |t|
|
|
135
|
-
t.libs << "test"
|
|
136
|
-
t.libs << "lib"
|
|
137
|
-
t.test_files = FileList["test/performance/**/*_test.rb"]
|
|
138
|
-
end
|
|
139
|
-
desc "Alias for test:performance"
|
|
140
|
-
task perf: :performance
|
|
141
|
-
|
|
142
|
-
Rake::TestTask.new(:e2e) do |t|
|
|
143
|
-
t.libs << "test"
|
|
144
|
-
t.libs << "lib"
|
|
145
|
-
t.test_files = FileList["test/e2e/**/*_test.rb"]
|
|
146
|
-
workers = ENV.fetch("TEST_WORKERS", Etc.nprocessors)
|
|
147
|
-
t.options = "--parallel --n-workers=#{workers}"
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
Rake::TestTask.new(:visual) do |t|
|
|
151
|
-
t.libs << "test"
|
|
152
|
-
t.libs << "lib"
|
|
153
|
-
t.test_files = FileList["test/visual/**/*_test.rb"]
|
|
154
|
-
workers = ENV.fetch("TEST_WORKERS", Etc.nprocessors)
|
|
155
|
-
t.options = "--parallel --n-workers=#{workers}"
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
namespace :fixtures do
|
|
159
|
-
namespace :reader do
|
|
160
|
-
desc "Generate reader fixture XLSX files from SDK scenarios"
|
|
161
|
-
task generate: :ensure_reader_fixtures
|
|
162
|
-
|
|
163
|
-
desc "Remove generated reader fixture XLSX files"
|
|
164
|
-
task :clean do
|
|
165
|
-
FileUtils.rm_rf(reader_fixture_dir)
|
|
166
|
-
end
|
|
167
|
-
end
|
|
168
|
-
end
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
task "test:e2e" => %i[build_sdk_runner ensure_reader_fixtures]
|
|
172
|
-
|
|
173
|
-
require "rubocop/rake_task"
|
|
174
|
-
|
|
175
|
-
RuboCop::RakeTask.new
|
|
176
|
-
|
|
177
|
-
require "bundler/audit/task"
|
|
178
|
-
Bundler::Audit::Task.new
|
|
179
|
-
|
|
180
|
-
task default: %i[bundle:audit rubocop typecheck test]
|
|
181
|
-
|
|
182
|
-
namespace :visual do
|
|
183
|
-
desc "Generate docs/visual/ README.md explanation gallery"
|
|
184
|
-
task :gallery do
|
|
185
|
-
require_relative "test/visual/support/gallery_generator"
|
|
186
|
-
Xlsxrb::Visual::GalleryGenerator.generate
|
|
187
|
-
end
|
|
188
|
-
|
|
189
|
-
desc "Generate / update VRT baselines in test/visual/baselines/"
|
|
190
|
-
task :baseline do
|
|
191
|
-
require_relative "test/visual/support/renderer"
|
|
192
|
-
require "securerandom"
|
|
193
|
-
examples = Dir.glob(File.expand_path("examples/visual/*.rb", __dir__))
|
|
194
|
-
baselines_dir = File.expand_path("test/visual/baselines", __dir__)
|
|
195
|
-
|
|
196
|
-
FileUtils.rm_rf(baselines_dir)
|
|
197
|
-
FileUtils.mkdir_p(baselines_dir)
|
|
198
|
-
|
|
199
|
-
examples.each do |example_path|
|
|
200
|
-
name = File.basename(example_path, ".rb")
|
|
201
|
-
puts "Generating baseline for #{name}..."
|
|
202
|
-
|
|
203
|
-
example_tmp_dir = File.join(Dir.tmpdir, "xlsxrb_baselines_build_#{name}_#{SecureRandom.hex(4)}")
|
|
204
|
-
FileUtils.mkdir_p(example_tmp_dir)
|
|
205
|
-
|
|
206
|
-
xlsx_path = File.join(example_tmp_dir, "#{name}.xlsx")
|
|
207
|
-
system("ruby", "-Ilib", example_path, xlsx_path)
|
|
208
|
-
|
|
209
|
-
dest_dir = File.join(baselines_dir, name)
|
|
210
|
-
begin
|
|
211
|
-
Xlsxrb::Visual::Renderer.render(xlsx_path, dest_dir)
|
|
212
|
-
ensure
|
|
213
|
-
FileUtils.rm_rf(example_tmp_dir)
|
|
214
|
-
end
|
|
215
|
-
end
|
|
216
|
-
puts "Baselines generated successfully."
|
|
217
|
-
end
|
|
218
|
-
end
|
|
219
|
-
|
|
220
|
-
desc "Build custom packed ruby.wasm from staging bundle"
|
|
221
|
-
task :wasm do
|
|
222
|
-
original_wasm_cache = File.expand_path("tmp/test_env/ruby.wasm", __dir__)
|
|
223
|
-
packed_wasm_path = File.expand_path("docs/wasm/ruby.wasm", __dir__)
|
|
224
|
-
wasm_bundle_dir = File.expand_path("tmp/wasm_bundle", __dir__)
|
|
225
|
-
bundle_assets_dir = File.expand_path("docs/wasm/bundle_assets", __dir__)
|
|
226
|
-
|
|
227
|
-
# 1. Download original base Wasm if not cached locally
|
|
228
|
-
unless File.exist?(original_wasm_cache)
|
|
229
|
-
puts "Downloading original ruby.wasm for caching..."
|
|
230
|
-
require "open-uri"
|
|
231
|
-
wasm_url = "https://cdn.jsdelivr.net/npm/@ruby/4.0-wasm-wasi@2.9.3-2.9.4/dist/ruby.wasm"
|
|
232
|
-
FileUtils.mkdir_p(File.dirname(original_wasm_cache))
|
|
233
|
-
# rubocop:disable Security/Open
|
|
234
|
-
URI.open(wasm_url) do |stream|
|
|
235
|
-
File.open(original_wasm_cache, "wb") do |file|
|
|
236
|
-
IO.copy_stream(stream, file)
|
|
237
|
-
end
|
|
238
|
-
end
|
|
239
|
-
# rubocop:enable Security/Open
|
|
240
|
-
puts "Original ruby.wasm cached successfully."
|
|
241
|
-
end
|
|
242
|
-
|
|
243
|
-
# 2. Recreate and populate the staging bundle directories
|
|
244
|
-
FileUtils.rm_rf(wasm_bundle_dir)
|
|
245
|
-
FileUtils.rm_rf(bundle_assets_dir)
|
|
246
|
-
FileUtils.mkdir_p(wasm_bundle_dir)
|
|
247
|
-
FileUtils.mkdir_p(bundle_assets_dir)
|
|
248
|
-
|
|
249
|
-
# A. Write custom static stubs and gateways dynamically
|
|
250
|
-
File.write(File.join(bundle_assets_dir, "openssl.rb"), "# frozen_string_literal: true\n")
|
|
251
|
-
time_rb_path = $LOAD_PATH.lazy.map { |p| File.join(p, "time.rb") }.find { |f| File.exist?(f) }
|
|
252
|
-
FileUtils.cp(time_rb_path, bundle_assets_dir) if time_rb_path
|
|
253
|
-
|
|
254
|
-
File.write(File.join(bundle_assets_dir, "opentelemetry.rb"), <<~RUBY)
|
|
255
|
-
# frozen_string_literal: true
|
|
256
|
-
module OpenTelemetry
|
|
257
|
-
def self.tracer_provider
|
|
258
|
-
@tracer_provider ||= Class.new {
|
|
259
|
-
def tracer(*args)
|
|
260
|
-
Class.new {
|
|
261
|
-
def in_span(*args)
|
|
262
|
-
yield Class.new { def record_exception(*args); end; def status=(*args); end }.new
|
|
263
|
-
end
|
|
264
|
-
}.new
|
|
265
|
-
end
|
|
266
|
-
}.new
|
|
267
|
-
end
|
|
268
|
-
end
|
|
269
|
-
RUBY
|
|
270
|
-
|
|
271
|
-
# Gateway for REXML
|
|
272
|
-
File.write(File.join(bundle_assets_dir, "rexml.rb"), "# frozen_string_literal: true\nrequire \"rexml/rexml\"\n")
|
|
273
|
-
|
|
274
|
-
# Resolve and copy host's rexml files
|
|
275
|
-
rexml_spec_path = $LOAD_PATH.find { |p| File.exist?(File.join(p, "rexml/rexml.rb")) }
|
|
276
|
-
FileUtils.cp_r(File.join(rexml_spec_path, "rexml"), bundle_assets_dir) if rexml_spec_path
|
|
277
|
-
|
|
278
|
-
# Gateway for strscan
|
|
279
|
-
File.write(File.join(bundle_assets_dir, "strscan.rb"), <<~RUBY)
|
|
280
|
-
# frozen_string_literal: true
|
|
281
|
-
begin
|
|
282
|
-
require "strscan.so"
|
|
283
|
-
rescue LoadError
|
|
284
|
-
end
|
|
285
|
-
require "strscan/strscan"
|
|
286
|
-
RUBY
|
|
287
|
-
|
|
288
|
-
# Resolve and copy host's strscan files
|
|
289
|
-
strscan_spec_path = $LOAD_PATH.find { |p| File.exist?(File.join(p, "strscan/strscan.rb")) }
|
|
290
|
-
if strscan_spec_path
|
|
291
|
-
FileUtils.mkdir_p(File.join(bundle_assets_dir, "strscan"))
|
|
292
|
-
FileUtils.cp(File.join(strscan_spec_path, "strscan/strscan.rb"), File.join(bundle_assets_dir, "strscan/strscan.rb"))
|
|
293
|
-
end
|
|
294
|
-
|
|
295
|
-
# B. Copy necessary standard libraries dynamically from host's $LOAD_PATH
|
|
296
|
-
stdlib_files = [
|
|
297
|
-
"date.rb", "delegate.rb", "forwardable.rb", "securerandom.rb",
|
|
298
|
-
"random/formatter.rb", "set.rb", "tempfile.rb", "tmpdir.rb", "fileutils.rb",
|
|
299
|
-
"pp.rb", "prettyprint.rb"
|
|
300
|
-
]
|
|
301
|
-
stdlib_files.each do |name|
|
|
302
|
-
path = $LOAD_PATH.find { |p| File.exist?(File.join(p, name)) }
|
|
303
|
-
next unless path
|
|
304
|
-
|
|
305
|
-
dest_path = File.join(bundle_assets_dir, name)
|
|
306
|
-
FileUtils.mkdir_p(File.dirname(dest_path))
|
|
307
|
-
FileUtils.cp(File.join(path, name), dest_path)
|
|
308
|
-
end
|
|
309
|
-
|
|
310
|
-
# C. Patch tmpdir.rb to automatically create /tmp in Wasm virtual filesystem (since Wasm has no writable /tmp by default)
|
|
311
|
-
tmpdir_path = File.join(bundle_assets_dir, "tmpdir.rb")
|
|
312
|
-
if File.exist?(tmpdir_path)
|
|
313
|
-
File.open(tmpdir_path, "a") do |f|
|
|
314
|
-
f.puts "\nclass Dir\n def self.tmpdir\n Dir.mkdir(\"/tmp\") rescue nil unless File.directory?(\"/tmp\")\n \"/tmp\"\n end\nend\n"
|
|
315
|
-
end
|
|
316
|
-
end
|
|
317
|
-
|
|
318
|
-
# D. Copy everything from bundle_assets_dir to wasm_bundle_dir
|
|
319
|
-
FileUtils.cp_r(File.join(bundle_assets_dir, "."), wasm_bundle_dir)
|
|
320
|
-
|
|
321
|
-
# E. Copy latest xlsxrb implementation files from lib/
|
|
322
|
-
FileUtils.cp(File.expand_path("lib/xlsxrb.rb", __dir__), File.join(wasm_bundle_dir, "xlsxrb.rb"))
|
|
323
|
-
FileUtils.cp_r(File.expand_path("lib/xlsxrb", __dir__), wasm_bundle_dir)
|
|
324
|
-
|
|
325
|
-
# 3. Compile custom ruby.wasm packaging staging libs
|
|
326
|
-
FileUtils.mkdir_p(File.dirname(packed_wasm_path))
|
|
327
|
-
puts "Building packed ruby.wasm from staging bundle..."
|
|
328
|
-
cmd = "bundle exec rbwasm pack #{original_wasm_cache} --dir #{wasm_bundle_dir}::/usr/local/lib/ruby/site_ruby -o #{packed_wasm_path}"
|
|
329
|
-
puts "Executing: #{cmd}"
|
|
330
|
-
raise "Failed to build packed ruby.wasm using rbwasm pack!" unless system(cmd)
|
|
331
|
-
end
|
|
332
|
-
|
|
333
|
-
def download_file(url, dest)
|
|
334
|
-
# Check if the file exists and is not a tiny placeholder/error document
|
|
335
|
-
return if File.exist?(dest) && File.size(dest) > 1024
|
|
336
|
-
|
|
337
|
-
puts "Downloading #{url} to #{dest}..."
|
|
338
|
-
FileUtils.mkdir_p(File.dirname(dest))
|
|
339
|
-
|
|
340
|
-
require "net/http"
|
|
341
|
-
uri = URI.parse(url)
|
|
342
|
-
temp_dest = "#{dest}.tmp"
|
|
343
|
-
|
|
344
|
-
begin
|
|
345
|
-
Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https", open_timeout: 15, read_timeout: 90) do |http|
|
|
346
|
-
request = Net::HTTP::Get.new(uri)
|
|
347
|
-
# Specify User-Agent to bypass scraping prevention on CDNs and act as a normal browser
|
|
348
|
-
request["User-Agent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
|
|
349
|
-
# Force raw (identity) encoding to prevent receiving Brotli-compressed (.br) data,
|
|
350
|
-
# which Ruby's Net::HTTP cannot decode automatically, leading to corrupted Wasm files.
|
|
351
|
-
request["Accept-Encoding"] = "identity"
|
|
352
|
-
|
|
353
|
-
http.request(request) do |response|
|
|
354
|
-
raise "HTTP error #{response.code}: #{response.message}" if response.code.to_i != 200
|
|
355
|
-
|
|
356
|
-
File.open(temp_dest, "wb") do |output|
|
|
357
|
-
response.read_body do |chunk|
|
|
358
|
-
output.write(chunk)
|
|
359
|
-
end
|
|
360
|
-
end
|
|
361
|
-
end
|
|
362
|
-
end
|
|
363
|
-
# Atomic rename to prevent leaving incomplete files on failure
|
|
364
|
-
File.rename(temp_dest, dest)
|
|
365
|
-
puts "Downloaded successfully."
|
|
366
|
-
|
|
367
|
-
# Dynamic Brotli Decompression if the server ignored identity encoding and sent Brotli (.br) data
|
|
368
|
-
if File.exist?(dest) && File.binread(dest, 4)&.bytes == [0xCF, 0xFF, 0xFF, 0x7F]
|
|
369
|
-
puts "Detected Brotli compression on #{dest}. Decompressing..."
|
|
370
|
-
|
|
371
|
-
unpacked = "#{dest}.unpacked"
|
|
372
|
-
if system("brotli -d -f -o #{unpacked} #{dest}")
|
|
373
|
-
File.rename(unpacked, dest)
|
|
374
|
-
puts "Decompressed #{dest} successfully."
|
|
375
|
-
else
|
|
376
|
-
FileUtils.rm_f(unpacked)
|
|
377
|
-
raise "Failed to decompress Brotli file: #{dest}"
|
|
378
|
-
end
|
|
379
|
-
end
|
|
380
|
-
rescue StandardError => e
|
|
381
|
-
puts "Failed to download #{url}: #{e.message}"
|
|
382
|
-
FileUtils.rm_f(temp_dest)
|
|
383
|
-
FileUtils.rm_f(dest)
|
|
384
|
-
raise "Required asset download failed. Build aborted."
|
|
385
|
-
end
|
|
386
|
-
end
|
|
387
|
-
|
|
388
|
-
def fetch_google_fonts
|
|
389
|
-
css_dest = "docs/fonts/fonts.css"
|
|
390
|
-
return if File.exist?(css_dest)
|
|
391
|
-
|
|
392
|
-
puts "Fetching and localizing Google Fonts..."
|
|
393
|
-
font_url = "https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;700&family=JetBrains+Mono:wght@400;500&display=swap"
|
|
394
|
-
|
|
395
|
-
css_content = nil
|
|
396
|
-
begin
|
|
397
|
-
# Specify Chrome User-Agent to ensure Google Fonts returns modern and lightweight .woff2 formats
|
|
398
|
-
# instead of legacy formats (like .ttf or .eot) designed for older browsers
|
|
399
|
-
# rubocop:disable Security/Open
|
|
400
|
-
URI.open(font_url, "User-Agent" => "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36") do |f|
|
|
401
|
-
css_content = f.read
|
|
402
|
-
end
|
|
403
|
-
# rubocop:enable Security/Open
|
|
404
|
-
rescue StandardError => e
|
|
405
|
-
puts "Failed to fetch Google Fonts CSS: #{e.message}"
|
|
406
|
-
return
|
|
407
|
-
end
|
|
408
|
-
|
|
409
|
-
urls = css_content.scan(%r{url\((https://fonts\.gstatic\.com/[^)]+)\)}).flatten
|
|
410
|
-
|
|
411
|
-
urls.uniq.each do |url|
|
|
412
|
-
filename = url.split("/").last
|
|
413
|
-
local_path = "docs/fonts/#{filename}"
|
|
414
|
-
download_file(url, local_path)
|
|
415
|
-
css_content.gsub!(url, filename)
|
|
416
|
-
end
|
|
417
|
-
|
|
418
|
-
FileUtils.mkdir_p("docs/fonts")
|
|
419
|
-
File.write(css_dest, css_content)
|
|
420
|
-
puts "Google Fonts localized successfully."
|
|
421
|
-
end
|
|
422
|
-
|
|
423
|
-
desc "Fetch required external assets for offline usage"
|
|
424
|
-
task :fetch_assets do
|
|
425
|
-
require "open-uri"
|
|
426
|
-
require "fileutils"
|
|
427
|
-
|
|
428
|
-
# Fetch Ruby WASI JS
|
|
429
|
-
download_file(
|
|
430
|
-
"https://cdn.jsdelivr.net/npm/@ruby/wasm-wasi@2.9.3-2.9.4/dist/browser.umd.js",
|
|
431
|
-
"docs/wasm/browser.umd.js"
|
|
432
|
-
)
|
|
433
|
-
|
|
434
|
-
# Fetch ZetaOffice Wasm
|
|
435
|
-
base_zeta_url = "https://cdn.zetaoffice.net/zetaoffice_latest/"
|
|
436
|
-
%w[soffice.js soffice.wasm soffice.data soffice.data.js.metadata qtloader.js].each do |file|
|
|
437
|
-
download_file(base_zeta_url + file, "docs/zetaoffice/#{file}")
|
|
438
|
-
end
|
|
439
|
-
|
|
440
|
-
# Fetch and localize Google Fonts
|
|
441
|
-
fetch_google_fonts
|
|
442
|
-
end
|
|
443
|
-
|
|
444
|
-
desc "Generate RDoc documentation including Visual Gallery"
|
|
445
|
-
task doc: %i[wasm fetch_assets] do
|
|
446
|
-
FileUtils.rm_rf("doc")
|
|
447
|
-
|
|
448
|
-
# RDoc コマンドを実行 (--exclude を指定して docs 配下のプレビュー用アセットの誤パースを回避)
|
|
449
|
-
sh "bundle exec rdoc --op doc " \
|
|
450
|
-
"--exclude 'docs/coi-serviceworker\\.js' " \
|
|
451
|
-
"--exclude 'docs/zeta\\.js' " \
|
|
452
|
-
"--exclude 'docs/office_thread\\.js' " \
|
|
453
|
-
"--exclude 'docs/preview\\.html' " \
|
|
454
|
-
"--title 'xlsxrb Documentation' --main README.md README.md CHANGELOG.md CODE_OF_CONDUCT.md docs/*.md \"docs/visual/VisualGallery.md\" lib/"
|
|
455
|
-
|
|
456
|
-
# Copy visual gallery images and files so they are available in RDoc output
|
|
457
|
-
FileUtils.mkdir_p("doc/test/visual/baselines")
|
|
458
|
-
FileUtils.mkdir_p("doc/test/visual/support/illustrations")
|
|
459
|
-
FileUtils.cp_r(Dir.glob("test/visual/baselines/*"), "doc/test/visual/baselines")
|
|
460
|
-
FileUtils.cp_r(Dir.glob("test/visual/support/illustrations/*.png"), "doc/test/visual/support/illustrations")
|
|
461
|
-
|
|
462
|
-
FileUtils.mkdir_p("doc/docs/visual/files")
|
|
463
|
-
FileUtils.cp_r(Dir.glob("docs/visual/files/*"), "doc/docs/visual/files")
|
|
464
|
-
|
|
465
|
-
# --- WebAssembly Playground Integration ---
|
|
466
|
-
puts "Integrating WebAssembly Playground..."
|
|
467
|
-
|
|
468
|
-
# Copy playground helper assets and custom Wasm binary to doc directory
|
|
469
|
-
FileUtils.mkdir_p("doc/css")
|
|
470
|
-
FileUtils.mkdir_p("doc/js")
|
|
471
|
-
FileUtils.mkdir_p("doc/wasm")
|
|
472
|
-
FileUtils.mkdir_p("doc/zetaoffice")
|
|
473
|
-
FileUtils.mkdir_p("doc/fonts")
|
|
474
|
-
|
|
475
|
-
FileUtils.cp("docs/wasm/wasm_doc_helper.js", "doc/js/wasm_doc_helper.js")
|
|
476
|
-
FileUtils.cp("docs/wasm/wasm_doc_helper.css", "doc/css/wasm_doc_helper.css")
|
|
477
|
-
FileUtils.cp("docs/wasm/ruby.wasm", "doc/wasm/ruby.wasm")
|
|
478
|
-
FileUtils.cp("docs/wasm/browser.umd.js", "doc/wasm/browser.umd.js")
|
|
479
|
-
FileUtils.cp_r(Dir.glob("docs/zetaoffice/*"), "doc/zetaoffice")
|
|
480
|
-
FileUtils.cp_r(Dir.glob("docs/fonts/*"), "doc/fonts")
|
|
481
|
-
|
|
482
|
-
# Copy LibreOffice Wasm Preview assets to doc directory
|
|
483
|
-
FileUtils.cp("docs/preview.html", "doc/preview.html")
|
|
484
|
-
FileUtils.cp("docs/coi-serviceworker.js", "doc/coi-serviceworker.js")
|
|
485
|
-
FileUtils.cp("docs/zeta.js", "doc/zeta.js")
|
|
486
|
-
FileUtils.cp("docs/office_thread.js", "doc/office_thread.js")
|
|
487
|
-
|
|
488
|
-
# Inject stylesheet and javascript loading tags to all generated HTML docs
|
|
489
|
-
Dir.glob("doc/**/*.html").each do |html_path|
|
|
490
|
-
next if File.basename(html_path) == "preview.html"
|
|
491
|
-
|
|
492
|
-
html_content = File.read(html_path)
|
|
493
|
-
depth = html_path.sub(%r{\Adoc/}, "").count("/")
|
|
494
|
-
rel_prefix = "../" * depth
|
|
495
|
-
|
|
496
|
-
coi_tag = %(<script src="#{rel_prefix}coi-serviceworker.js"></script>)
|
|
497
|
-
js_tag = %(<script src="#{rel_prefix}js/wasm_doc_helper.js" defer></script>)
|
|
498
|
-
css_tag = %(<link href="#{rel_prefix}css/wasm_doc_helper.css" rel="stylesheet">)
|
|
499
|
-
|
|
500
|
-
if html_content.include?("<body")
|
|
501
|
-
modified = html_content.sub("<body", "#{coi_tag}\n#{js_tag}\n#{css_tag}\n<body")
|
|
502
|
-
File.write(html_path, modified)
|
|
503
|
-
end
|
|
504
|
-
end
|
|
505
|
-
puts "WebAssembly Playground integrated successfully!"
|
|
506
|
-
puts "RDoc documentation generated successfully at doc/"
|
|
507
|
-
end
|
|
508
|
-
|
|
509
|
-
namespace :doc do
|
|
510
|
-
desc "Build and preview RDoc documentation locally"
|
|
511
|
-
task preview: :doc do
|
|
512
|
-
require "webrick"
|
|
513
|
-
|
|
514
|
-
port = ENV.fetch("PORT", "8000").to_i
|
|
515
|
-
|
|
516
|
-
# Configure WEBrick to serve 'doc' directory
|
|
517
|
-
server = WEBrick::HTTPServer.new(
|
|
518
|
-
Port: port,
|
|
519
|
-
DocumentRoot: File.expand_path("doc", __dir__),
|
|
520
|
-
Logger: WEBrick::Log.new(nil, WEBrick::BasicLog::WARN),
|
|
521
|
-
AccessLog: [],
|
|
522
|
-
# If the file is a Brotli-compressed Wasm/Data asset (checked via magic bytes),
|
|
523
|
-
# dynamically inject 'Content-Encoding: br' header so the browser decompresses it natively.
|
|
524
|
-
RequestCallback: lambda { |req, res|
|
|
525
|
-
if req.path.end_with?(".wasm") || req.path.end_with?(".data")
|
|
526
|
-
# Resolve physical file path from req.path manually since res.filename is nil at this stage
|
|
527
|
-
local_path = File.join(File.expand_path("doc", __dir__), req.path)
|
|
528
|
-
if File.exist?(local_path)
|
|
529
|
-
first_bytes = begin
|
|
530
|
-
File.binread(local_path, 4)
|
|
531
|
-
rescue StandardError
|
|
532
|
-
nil
|
|
533
|
-
end
|
|
534
|
-
res["Content-Encoding"] = "br" if first_bytes != "\x00asm"
|
|
535
|
-
end
|
|
536
|
-
end
|
|
537
|
-
}
|
|
538
|
-
)
|
|
539
|
-
|
|
540
|
-
puts "=================================================="
|
|
541
|
-
puts " Starting local documentation server at:"
|
|
542
|
-
puts " http://localhost:#{port}/"
|
|
543
|
-
puts " Press Ctrl+C to stop the server"
|
|
544
|
-
puts "=================================================="
|
|
545
|
-
|
|
546
|
-
trap("INT") { server.shutdown }
|
|
547
|
-
|
|
548
|
-
begin
|
|
549
|
-
server.start
|
|
550
|
-
rescue Errno::EADDRINUSE
|
|
551
|
-
warn "\n[Error] Port #{port} is already in use by another process."
|
|
552
|
-
warn "Please stop the other process or specify a different port."
|
|
553
|
-
warn "Example: PORT=8080 bundle exec rake doc:preview\n\n"
|
|
554
|
-
exit 1
|
|
555
|
-
end
|
|
556
|
-
end
|
|
557
|
-
end
|
|
558
|
-
desc "Generate RBS signature files from inline annotations"
|
|
559
|
-
task :sig do
|
|
560
|
-
files = FileList["lib/**/*.rb"].to_a
|
|
561
|
-
sh "bundle", "exec", "rbs-inline", "--output=sig/generated", "--base=lib", *files
|
|
562
|
-
end
|
|
563
|
-
|
|
564
|
-
desc "Run static type checking with Steep"
|
|
565
|
-
task typecheck: :sig do
|
|
566
|
-
sh "bundle exec steep check"
|
|
567
|
-
end
|
data/Steepfile
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
target :lib do
|
|
4
|
-
signature "sig"
|
|
5
|
-
check "lib"
|
|
6
|
-
|
|
7
|
-
library "date"
|
|
8
|
-
library "time"
|
|
9
|
-
library "securerandom"
|
|
10
|
-
library "openssl"
|
|
11
|
-
library "pathname"
|
|
12
|
-
library "tempfile"
|
|
13
|
-
library "bigdecimal"
|
|
14
|
-
|
|
15
|
-
repo_path "sig"
|
|
16
|
-
|
|
17
|
-
configure_code_diagnostics(Steep::Diagnostic::Ruby.lenient)
|
|
18
|
-
end
|