serialbench 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/benchmark.yml +273 -220
  3. data/.github/workflows/rake.yml +26 -0
  4. data/.github/workflows/windows-debug.yml +171 -0
  5. data/.gitignore +32 -0
  6. data/.rubocop.yml +1 -0
  7. data/.rubocop_todo.yml +274 -0
  8. data/Gemfile +14 -1
  9. data/README.adoc +292 -1118
  10. data/Rakefile +0 -55
  11. data/config/benchmarks/full.yml +29 -0
  12. data/config/benchmarks/short.yml +26 -0
  13. data/config/environments/asdf-ruby-3.2.yml +8 -0
  14. data/config/environments/asdf-ruby-3.3.yml +8 -0
  15. data/config/environments/docker-ruby-3.0.yml +9 -0
  16. data/config/environments/docker-ruby-3.1.yml +9 -0
  17. data/config/environments/docker-ruby-3.2.yml +9 -0
  18. data/config/environments/docker-ruby-3.3.yml +9 -0
  19. data/config/environments/docker-ruby-3.4.yml +9 -0
  20. data/data/schemas/result.yml +29 -0
  21. data/docker/Dockerfile.alpine +33 -0
  22. data/docker/{Dockerfile.benchmark → Dockerfile.ubuntu} +4 -3
  23. data/docker/README.md +2 -2
  24. data/docs/PLATFORM_VALIDATION_FIX.md +79 -0
  25. data/docs/SYCK_YAML_FIX.md +91 -0
  26. data/docs/WEBSITE_COMPLETION_PLAN.md +440 -0
  27. data/docs/WINDOWS_LIBXML_FIX.md +136 -0
  28. data/docs/WINDOWS_SETUP.md +122 -0
  29. data/exe/serialbench +1 -1
  30. data/lib/serialbench/benchmark_runner.rb +261 -423
  31. data/lib/serialbench/cli/base_cli.rb +51 -0
  32. data/lib/serialbench/cli/benchmark_cli.rb +453 -0
  33. data/lib/serialbench/cli/environment_cli.rb +181 -0
  34. data/lib/serialbench/cli/resultset_cli.rb +261 -0
  35. data/lib/serialbench/cli/ruby_build_cli.rb +225 -0
  36. data/lib/serialbench/cli/validate_cli.rb +88 -0
  37. data/lib/serialbench/cli.rb +61 -600
  38. data/lib/serialbench/config_manager.rb +129 -0
  39. data/lib/serialbench/models/benchmark_config.rb +75 -0
  40. data/lib/serialbench/models/benchmark_result.rb +81 -0
  41. data/lib/serialbench/models/environment_config.rb +72 -0
  42. data/lib/serialbench/models/platform.rb +111 -0
  43. data/lib/serialbench/models/result.rb +80 -0
  44. data/lib/serialbench/models/result_set.rb +79 -0
  45. data/lib/serialbench/models/result_store.rb +108 -0
  46. data/lib/serialbench/models.rb +54 -0
  47. data/lib/serialbench/ruby_build_manager.rb +149 -0
  48. data/lib/serialbench/runners/asdf_runner.rb +296 -0
  49. data/lib/serialbench/runners/base.rb +32 -0
  50. data/lib/serialbench/runners/docker_runner.rb +140 -0
  51. data/lib/serialbench/runners/local_runner.rb +71 -0
  52. data/lib/serialbench/serializers/base_serializer.rb +9 -17
  53. data/lib/serialbench/serializers/json/base_json_serializer.rb +4 -4
  54. data/lib/serialbench/serializers/json/json_serializer.rb +0 -2
  55. data/lib/serialbench/serializers/json/oj_serializer.rb +0 -2
  56. data/lib/serialbench/serializers/json/rapidjson_serializer.rb +1 -1
  57. data/lib/serialbench/serializers/json/yajl_serializer.rb +0 -2
  58. data/lib/serialbench/serializers/toml/base_toml_serializer.rb +5 -5
  59. data/lib/serialbench/serializers/toml/toml_rb_serializer.rb +1 -3
  60. data/lib/serialbench/serializers/toml/tomlib_serializer.rb +1 -3
  61. data/lib/serialbench/serializers/toml/tomlrb_serializer.rb +56 -0
  62. data/lib/serialbench/serializers/xml/base_xml_serializer.rb +4 -9
  63. data/lib/serialbench/serializers/xml/libxml_serializer.rb +4 -10
  64. data/lib/serialbench/serializers/xml/nokogiri_serializer.rb +2 -4
  65. data/lib/serialbench/serializers/xml/oga_serializer.rb +4 -10
  66. data/lib/serialbench/serializers/xml/ox_serializer.rb +2 -4
  67. data/lib/serialbench/serializers/xml/rexml_serializer.rb +3 -5
  68. data/lib/serialbench/serializers/yaml/base_yaml_serializer.rb +5 -1
  69. data/lib/serialbench/serializers/yaml/psych_serializer.rb +1 -1
  70. data/lib/serialbench/serializers/yaml/syck_serializer.rb +60 -23
  71. data/lib/serialbench/serializers.rb +23 -6
  72. data/lib/serialbench/site_generator.rb +283 -0
  73. data/lib/serialbench/templates/assets/css/benchmark_report.css +535 -0
  74. data/lib/serialbench/templates/assets/css/format_based.css +474 -0
  75. data/lib/serialbench/templates/assets/css/themes.css +589 -0
  76. data/lib/serialbench/templates/assets/js/chart_helpers.js +411 -0
  77. data/lib/serialbench/templates/assets/js/dashboard.js +795 -0
  78. data/lib/serialbench/templates/assets/js/navigation.js +142 -0
  79. data/lib/serialbench/templates/base.liquid +49 -0
  80. data/lib/serialbench/templates/format_based.liquid +507 -0
  81. data/lib/serialbench/templates/partials/chart_section.liquid +4 -0
  82. data/lib/serialbench/version.rb +1 -1
  83. data/lib/serialbench/yaml_validator.rb +36 -0
  84. data/lib/serialbench.rb +2 -31
  85. data/serialbench.gemspec +15 -3
  86. metadata +106 -25
  87. data/.github/workflows/ci.yml +0 -74
  88. data/.github/workflows/docker.yml +0 -246
  89. data/config/ci.yml +0 -22
  90. data/config/full.yml +0 -30
  91. data/docker/run-benchmarks.sh +0 -356
  92. data/lib/serialbench/chart_generator.rb +0 -821
  93. data/lib/serialbench/result_formatter.rb +0 -182
  94. data/lib/serialbench/result_merger.rb +0 -1201
  95. data/lib/serialbench/serializers/xml/base_parser.rb +0 -69
  96. data/lib/serialbench/serializers/xml/libxml_parser.rb +0 -98
  97. data/lib/serialbench/serializers/xml/nokogiri_parser.rb +0 -111
  98. data/lib/serialbench/serializers/xml/oga_parser.rb +0 -85
  99. data/lib/serialbench/serializers/xml/ox_parser.rb +0 -64
  100. data/lib/serialbench/serializers/xml/rexml_parser.rb +0 -129
@@ -0,0 +1,440 @@
1
+ # SerialBench Website Completion Plan
2
+
3
+ ## Executive Summary
4
+
5
+ This document outlines the plan to complete the SerialBench results website,
6
+ which will display performance benchmarks for Ruby serialization libraries
7
+ across different formats (XML, JSON, YAML, TOML).
8
+
9
+ ## Current State
10
+
11
+ ### Completed Components
12
+
13
+ 1. **Core Infrastructure**
14
+ - Lutaml::Model-based data models for benchmark results
15
+ - CLI interface using Thor for benchmark execution
16
+ - Docker and ASDF runners for multi-environment testing
17
+ - Result storage and aggregation via ResultSet
18
+ - GitHub Actions workflow for weekly automated benchmarks
19
+
20
+ 2. **Website Generation**
21
+ - Liquid templating engine integration
22
+ - Base template structure (base.liquid)
23
+ - Format-based view template (format_based.liquid)
24
+ - CSS styling with theme support
25
+ - JavaScript for Chart.js integration
26
+ - Metadata population from benchmark data
27
+
28
+ 3. **Deployment**
29
+ - GitHub Pages deployment via GitHub Actions
30
+ - Weekly schedule (Sundays at 2 AM UTC)
31
+ - Multi-platform matrix (Ruby 3.1-3.4 × Ubuntu/macOS)
32
+
33
+ ### Current Issues
34
+
35
+ 1. **Limited Visualization Options**
36
+ - Only format-based view available
37
+ - No serializer-focused comparisons
38
+ - Missing historical trend analysis
39
+
40
+ 2. **Incomplete Documentation**
41
+ - Website lacks explanatory text
42
+ - No methodology documentation
43
+ - Missing interpretation guidelines
44
+
45
+ 3. **Limited Interactivity**
46
+ - Static charts only
47
+ - No filtering or search capabilities
48
+ - No download options for raw data
49
+
50
+ ## Proposed Enhancements
51
+
52
+ ### Phase 1: Core Website Functionality (Priority: HIGH)
53
+
54
+ #### 1.1 Multiple View Templates
55
+
56
+ **Objective**: Provide different perspectives on benchmark data
57
+
58
+ **Tasks**:
59
+ - Create `serializer_based.liquid` template
60
+ - Group by serializer instead of format
61
+ - Show cross-format performance for each serializer
62
+ - Useful for comparing Nokogiri vs Ox vs REXML
63
+
64
+ - Create `platform_based.liquid` template
65
+ - Group by Ruby version and OS
66
+ - Show how performance varies across platforms
67
+ - Useful for identifying platform-specific optimizations
68
+
69
+ - Create `historical.liquid` template
70
+ - Time-series visualization
71
+ - Show performance trends over weekly runs
72
+ - Identify improvements or regressions
73
+
74
+ **Implementation**:
75
+ ```ruby
76
+ # In lib/serialbench/site_generator.rb
77
+ def generate_views
78
+ ['format_based', 'serializer_based', 'platform_based',
79
+ 'historical'].each do |view|
80
+ generate_view(view)
81
+ end
82
+ end
83
+ ```
84
+
85
+ **Estimated Effort**: 2-3 days
86
+
87
+ #### 1.2 Navigation and Layout
88
+
89
+ **Objective**: Cohesive multi-page website structure
90
+
91
+ **Tasks**:
92
+ - Update `base.liquid` with:
93
+ - Top navigation menu
94
+ - View switcher tabs
95
+ - Footer with methodology link
96
+ - Responsive mobile layout
97
+
98
+ - Add breadcrumb navigation
99
+ - Add page metadata (titles, descriptions)
100
+
101
+ **Implementation**:
102
+ ```html
103
+ <nav class="main-navigation">
104
+ <ul>
105
+ <li><a href="index.html">Format View</a></li>
106
+ <li><a href="serializer_view.html">Serializer View</a></li>
107
+ <li><a href="platform_view.html">Platform View</a></li>
108
+ <li><a href="historical.html">Trends</a></li>
109
+ <li><a href="methodology.html">Methodology</a></li>
110
+ </ul>
111
+ </nav>
112
+ ```
113
+
114
+ **Estimated Effort**: 1 day
115
+
116
+ #### 1.3 Enhanced Data Tables
117
+
118
+ **Objective**: Sortable, searchable result tables
119
+
120
+ **Tasks**:
121
+ - Integrate DataTables.js or similar library
122
+ - Add sorting by any column
123
+ - Add search/filter functionality
124
+ - Add CSV export option
125
+ - Add copy-to-clipboard for sharing
126
+
127
+ **Implementation**:
128
+ ```javascript
129
+ $('.benchmark-table').DataTable({
130
+ order: [[2, 'asc']], // Sort by i/s descending
131
+ pageLength: 25,
132
+ buttons: ['copy', 'csv', 'excel']
133
+ });
134
+ ```
135
+
136
+ **Estimated Effort**: 1 day
137
+
138
+ ### Phase 2: Documentation and Context (Priority: HIGH)
139
+
140
+ #### 2.1 Methodology Page
141
+
142
+ **Objective**: Explain how benchmarks are conducted
143
+
144
+ **Tasks**:
145
+ - Create `methodology.liquid` template
146
+ - Document:
147
+ - Benchmark environment setup
148
+ - Test data characteristics
149
+ - Measurement methodology
150
+ - Statistical approach
151
+ - Limitations and caveats
152
+
153
+ **Content Structure**:
154
+ ```markdown
155
+ ## Benchmark Methodology
156
+
157
+ ### Environment
158
+ - Ruby versions tested
159
+ - Operating systems
160
+ - Hardware specifications (GitHub Actions runners)
161
+
162
+ ### Test Data
163
+ - Sample size and structure
164
+ - Complexity levels
165
+ - Real-world representativeness
166
+
167
+ ### Measurements
168
+ - Iterations per second (throughput)
169
+ - Memory allocation (bytes)
170
+ - Statistical significance
171
+
172
+ ### Limitations
173
+ - Single-threaded only
174
+ - Memory profiling overhead
175
+ - GitHub Actions runner variability
176
+ ```
177
+
178
+ **Estimated Effort**: 1 day
179
+
180
+ #### 2.2 Interpretation Guide
181
+
182
+ **Objective**: Help users understand results
183
+
184
+ **Tasks**:
185
+ - Add tooltips to charts
186
+ - Add explanatory text to each view
187
+ - Create "How to Read This Chart" sections
188
+ - Add recommendations section
189
+
190
+ **Example**:
191
+ ```html
192
+ <div class="interpretation-guide">
193
+ <h3>Understanding the Results</h3>
194
+ <ul>
195
+ <li><strong>Higher i/s is better</strong>: More iterations per
196
+ second means faster serialization</li>
197
+ <li><strong>Lower memory is better</strong>: Less allocation
198
+ reduces GC pressure</li>
199
+ <li><strong>Trade-offs exist</strong>: Fastest may not be
200
+ most memory-efficient</li>
201
+ </ul>
202
+ </div>
203
+ ```
204
+
205
+ **Estimated Effort**: 0.5 days
206
+
207
+ #### 2.3 Library Information
208
+
209
+ **Objective**: Provide context about each serializer
210
+
211
+ **Tasks**:
212
+ - Add library descriptions
213
+ - Link to official documentation
214
+ - Show gem versions tested
215
+ - List known issues or limitations
216
+
217
+ **Implementation**:
218
+ ```ruby
219
+ SERIALIZER_INFO = {
220
+ 'nokogiri' => {
221
+ description: 'XML parsing using libxml2',
222
+ homepage: 'https://nokogiri.org',
223
+ features: ['XPath', 'CSS selectors', 'SAX parsing'],
224
+ notes: 'Most popular Ruby XML library'
225
+ },
226
+ # ... more serializers
227
+ }
228
+ ```
229
+
230
+ **Estimated Effort**: 1 day
231
+
232
+ ### Phase 3: Advanced Features (Priority: MEDIUM)
233
+
234
+ #### 3.1 Historical Trend Analysis
235
+
236
+ **Objective**: Track performance over time
237
+
238
+ **Tasks**:
239
+ - Store all historical benchmark runs
240
+ - Create time-series database of results
241
+ - Generate trend charts
242
+ - Highlight significant changes
243
+ - Add regression detection
244
+
245
+ **Implementation**:
246
+ ```javascript
247
+ // Chart.js line chart for trends
248
+ const trendChart = new Chart(ctx, {
249
+ type: 'line',
250
+ data: {
251
+ labels: timestamps,
252
+ datasets: [{
253
+ label: 'Nokogiri (parse)',
254
+ data: nokogiriParseResults,
255
+ borderColor: 'rgb(75, 192, 192)'
256
+ }]
257
+ }
258
+ });
259
+ ```
260
+
261
+ **Estimated Effort**: 2 days
262
+
263
+ #### 3.2 Comparison Matrix
264
+
265
+ **Objective**: Side-by-side serializer comparisons
266
+
267
+ **Tasks**:
268
+ - Create comparison view
269
+ - Allow selecting 2-4 serializers
270
+ - Show radar chart of characteristics
271
+ - Highlight strengths/weaknesses
272
+
273
+ **Estimated Effort**: 1-2 days
274
+
275
+ #### 3.3 Custom Benchmark Runs
276
+
277
+ **Objective**: Allow users to run specific benchmarks
278
+
279
+ **Tasks**:
280
+ - Add configuration UI
281
+ - Generate custom benchmark commands
282
+ - Provide Docker commands for local execution
283
+ - Document how to submit results
284
+
285
+ **Note**: This would be documentation only, not actual execution on
286
+ the website
287
+
288
+ **Estimated Effort**: 1 day
289
+
290
+ ### Phase 4: Performance and Polish (Priority: LOW)
291
+
292
+ #### 4.1 Performance Optimization
293
+
294
+ **Tasks**:
295
+ - Minimize JavaScript/CSS
296
+ - Lazy load charts
297
+ - Optimize image assets
298
+ - Add service worker for caching
299
+ - Compress result data
300
+
301
+ **Estimated Effort**: 1 day
302
+
303
+ #### 4.2 Accessibility
304
+
305
+ **Tasks**:
306
+ - Add ARIA labels
307
+ - Ensure keyboard navigation
308
+ - Test with screen readers
309
+ - Add alternative text descriptions of charts
310
+ - Ensure sufficient color contrast
311
+
312
+ **Estimated Effort**: 1 day
313
+
314
+ #### 4.3 Mobile Optimization
315
+
316
+ **Tasks**:
317
+ - Responsive chart sizes
318
+ - Touch-friendly interactions
319
+ - Mobile navigation menu
320
+ - Optimize for smaller screens
321
+
322
+ **Estimated Effort**: 0.5 days
323
+
324
+ ## Implementation Priority
325
+
326
+ ### Immediate (Next Sprint)
327
+
328
+ 1. Create serializer_based.liquid template
329
+ 2. Add methodology page
330
+ 3. Enhance navigation in base.liquid
331
+ 4. Add interpretation guides to existing charts
332
+
333
+ ### Short-term (1-2 Weeks)
334
+
335
+ 1. Implement historical trend tracking
336
+ 2. Add DataTables for sortable results
337
+ 3. Create platform_based view
338
+ 4. Add library information sections
339
+
340
+ ### Medium-term (1 Month)
341
+
342
+ 1. Comparison matrix feature
343
+ 2. Performance optimizations
344
+ 3. Accessibility improvements
345
+ 4. Mobile optimization
346
+
347
+ ### Long-term (Ongoing)
348
+
349
+ 1. Monitor weekly benchmark runs
350
+ 2. Add new serializers as they emerge
351
+ 3. Update methodology as needed
352
+ 4. Community feedback integration
353
+
354
+ ## Technical Requirements
355
+
356
+ ### Dependencies to Add
357
+
358
+ ```ruby
359
+ # Gemfile additions for enhanced website
360
+ gem 'rouge', '~> 4.0' # Syntax highlighting for code examples
361
+ ```
362
+
363
+ ### JavaScript Libraries
364
+
365
+ - Chart.js (already included)
366
+ - DataTables.js (for sortable tables)
367
+ - Lodash (for data manipulation)
368
+
369
+ ### Build Process Updates
370
+
371
+ ```ruby
372
+ # lib/serialbench/site_generator.rb enhancements
373
+ class SiteGenerator
374
+ def generate
375
+ copy_assets
376
+ generate_views
377
+ generate_methodology_page
378
+ generate_index_redirect
379
+ optimize_assets
380
+ end
381
+
382
+ private
383
+
384
+ def generate_views
385
+ %w[format_based serializer_based platform_based
386
+ historical].each do |view|
387
+ generate_view(view)
388
+ end
389
+ end
390
+ end
391
+ ```
392
+
393
+ ## Success Metrics
394
+
395
+ 1. **Functionality**
396
+ - All views generate without errors
397
+ - Charts render correctly in all major browsers
398
+ - Mobile experience is usable
399
+
400
+ 2. **Usability**
401
+ - Users can find information in < 3 clicks
402
+ - Charts are self-explanatory
403
+ - Methodology is clear and comprehensive
404
+
405
+ 3. **Performance**
406
+ - Page load < 2 seconds
407
+ - Time to interactive < 3 seconds
408
+ - Lighthouse score > 90
409
+
410
+ 4. **Accessibility**
411
+ - WCAG 2.1 Level AA compliance
412
+ - Screen reader compatible
413
+ - Keyboard navigation functional
414
+
415
+ ## Risk Mitigation
416
+
417
+ 1. **Data Volume Growth**
418
+ - Risk: Historical data grows unbounded
419
+ - Mitigation: Implement data retention policy (e.g., keep 52 weeks)
420
+
421
+ 2. **GitHub Pages Limits**
422
+ - Risk: Site exceeds 1GB limit
423
+ - Mitigation: Compress data, archive old results
424
+
425
+ 3. **Breaking Changes**
426
+ - Risk: Lutaml::Model API changes
427
+ - Mitigation: Pin versions, test before updates
428
+
429
+ 4. **Runner Variability**
430
+ - Risk: Inconsistent benchmark results
431
+ - Mitigation: Document variance, run multiple times, use statistics
432
+
433
+ ## Conclusion
434
+
435
+ This plan provides a structured approach to completing the SerialBench
436
+ results website. The phased approach allows for incremental delivery
437
+ of value while maintaining quality and usability standards.
438
+
439
+ **Next Immediate Action**: Push changes and verify GitHub Actions
440
+ workflow executes successfully.
@@ -0,0 +1,136 @@
1
+ # Windows libxml2 Installation Fix
2
+
3
+ ## Issue
4
+
5
+ The `libxml-ruby` gem was failing to install on Windows in GitHub Actions for Ruby 3.1 and 3.4 due to missing native libxml2 libraries.
6
+
7
+ **Error:**
8
+ ```
9
+ extconf failure: Cannot find libxml2.
10
+ Install the library or try one of the following options to extconf.rb:
11
+ --with-xml2-config=/path/to/xml2-config
12
+ --with-xml2-dir=/path/to/libxml2
13
+ ```
14
+
15
+ **Root Cause:**
16
+ The `libxml-ruby` gem requires native C libraries (libxml2) that are not available by default on Windows. The gem's native extension compilation fails because:
17
+ 1. libxml2 development headers are not found
18
+ 2. libxml2 shared libraries are not in the system path
19
+ 3. pkg-config cannot locate the libxml2 package
20
+
21
+ ## Solution
22
+
23
+ ### Approach
24
+
25
+ Instead of excluding `libxml-ruby` from Windows builds, we install the required native libraries using Chocolatey package manager, which is pre-installed on GitHub Actions Windows runners.
26
+
27
+ ### Implementation
28
+
29
+ #### 1. New GitHub Actions Workflow (`.github/workflows/windows-setup.yml`)
30
+
31
+ Created a dedicated Windows workflow that:
32
+ - Installs libxml2 via Chocolatey before Ruby setup
33
+ - Dynamically locates the libxml2 installation directory
34
+ - Configures environment variables (PKG_CONFIG_PATH, PATH)
35
+ - Passes library paths to bundler for gem compilation
36
+ - Runs tests to verify the setup
37
+
38
+ Key features:
39
+ - **Dynamic path detection**: Uses PowerShell to find the actual libxml2 installation directory
40
+ - **Robust configuration**: Sets multiple environment variables to ensure gem compilation succeeds
41
+ - **Bundler configuration**: Explicitly passes include and lib paths to the gem build process
42
+
43
+ #### 2. Documentation (`docs/WINDOWS_SETUP.md`)
44
+
45
+ Comprehensive guide covering:
46
+ - Problem explanation
47
+ - Multiple installation options (Chocolatey, vcpkg)
48
+ - Step-by-step setup instructions
49
+ - Environment variable configuration
50
+ - Troubleshooting common issues
51
+ - CI/CD integration
52
+
53
+ ## Technical Details
54
+
55
+ ### Chocolatey Package
56
+
57
+ The libxml2 Chocolatey package installs to:
58
+ ```
59
+ C:\ProgramData\chocolatey\lib\libxml2\tools\libxml2-{version}-win32-x86_64\
60
+ ```
61
+
62
+ Required components:
63
+ - `bin/` - DLL files (libxml2.dll, etc.)
64
+ - `include/libxml2/` - Header files for compilation
65
+ - `lib/` - Link libraries and pkg-config files
66
+ - `lib/pkgconfig/` - libxml-2.0.pc file
67
+
68
+ ### Environment Variables
69
+
70
+ The workflow sets:
71
+ - `PKG_CONFIG_PATH`: Points to the pkgconfig directory
72
+ - `PATH`: Includes the bin directory for DLLs
73
+ - `LIBXML2_INCLUDE`: Header file location for gem compilation
74
+ - `LIBXML2_LIB`: Library file location for gem compilation
75
+
76
+ ### Bundler Configuration
77
+
78
+ ```powershell
79
+ bundle config build.libxml-ruby "--with-xml2-include=<path> --with-xml2-lib=<path>"
80
+ ```
81
+
82
+ This passes the library locations directly to the gem's extconf.rb during native extension compilation.
83
+
84
+ ## Testing
85
+
86
+ The fix can be tested by:
87
+
88
+ 1. **Local Windows testing:**
89
+ ```powershell
90
+ choco install libxml2
91
+ choco install pkgconfiglite
92
+ bundle install
93
+ bundle exec rake spec
94
+ ```
95
+
96
+ 2. **GitHub Actions:**
97
+ - Push changes to trigger the `windows-setup` workflow
98
+ - Verify both Ruby 3.1 and 3.4 builds succeed
99
+ - Check that libxml-ruby tests pass
100
+
101
+ ## Benefits
102
+
103
+ 1. **Complete testing**: Windows builds now test libxml-ruby serializer
104
+ 2. **No platform exclusions**: Maintains consistency across all platforms
105
+ 3. **Automated setup**: CI/CD handles installation automatically
106
+ 4. **Documented process**: Clear guidance for local development
107
+
108
+ ## Alternative Approaches Considered
109
+
110
+ ### 1. Platform-conditional dependency (rejected)
111
+ ```ruby
112
+ spec.add_dependency 'libxml-ruby' unless Gem.win_platform?
113
+ ```
114
+ **Pros:** Simple, no setup required
115
+ **Cons:** Reduces test coverage, inconsistent behavior across platforms
116
+
117
+ ### 2. Pre-built binary gems (not available)
118
+ The libxml-ruby gem doesn't provide pre-built Windows binaries, requiring source compilation.
119
+
120
+ ### 3. WSL-only testing (rejected)
121
+ **Pros:** Linux-like environment
122
+ **Cons:** Doesn't test native Windows Ruby installations
123
+
124
+ ## Future Considerations
125
+
126
+ 1. **Caching**: Consider caching the Chocolatey packages to speed up CI runs
127
+ 2. **Version pinning**: May want to pin libxml2 version for reproducibility
128
+ 3. **Alternative packages**: Monitor for official pre-built binaries
129
+ 4. **Ruby 3.2/3.3**: Extend testing to additional Ruby versions if needed
130
+
131
+ ## References
132
+
133
+ - GitHub Actions issue: https://github.com/metanorma/serialbench/actions/runs/18628094589
134
+ - libxml-ruby gem: https://github.com/xml4r/libxml-ruby
135
+ - Chocolatey libxml2 package: https://community.chocolatey.org/packages/libxml2
136
+ - Windows setup documentation: `docs/WINDOWS_SETUP.md`
@@ -0,0 +1,122 @@
1
+ # Windows Setup Guide for Serialbench
2
+
3
+ This guide explains how to set up serialbench on Windows, particularly for installing the `libxml-ruby` gem which requires native libxml2 libraries.
4
+
5
+ ## Problem
6
+
7
+ The `libxml-ruby` gem requires native C libraries (libxml2) that need to be installed separately on Windows. Without these libraries, bundler will fail when trying to install the gem.
8
+
9
+ ## Solution
10
+
11
+ ### Option 1: Using Chocolatey (Recommended)
12
+
13
+ 1. Install [Chocolatey](https://chocolatey.org/install) if you haven't already:
14
+
15
+ ```powershell
16
+ Set-ExecutionPolicy Bypass -Scope Process -Force
17
+ [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
18
+ iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
19
+ ```
20
+
21
+ 2. Install libxml2 and required tools:
22
+
23
+ ```powershell
24
+ choco install -y libxml2
25
+ choco install -y pkgconfiglite
26
+ ```
27
+
28
+ 3. Set environment variables (you may need to adjust paths based on your installation):
29
+
30
+ ```powershell
31
+ # Find the actual libxml2 installation path
32
+ $libxmlPath = (Get-ChildItem "C:\ProgramData\chocolatey\lib\libxml2" -Recurse -Filter "libxml2.dll" | Select-Object -First 1).Directory.Parent.FullName
33
+
34
+ # Set PKG_CONFIG_PATH
35
+ $env:PKG_CONFIG_PATH = "$libxmlPath\lib\pkgconfig"
36
+ [System.Environment]::SetEnvironmentVariable('PKG_CONFIG_PATH', $env:PKG_CONFIG_PATH, 'User')
37
+
38
+ # Add to PATH
39
+ $env:PATH = "$libxmlPath\bin;$env:PATH"
40
+ $currentPath = [System.Environment]::GetEnvironmentVariable('PATH', 'User')
41
+ [System.Environment]::SetEnvironmentVariable('PATH', "$libxmlPath\bin;$currentPath", 'User')
42
+ ```
43
+
44
+ 4. Install Ruby dependencies:
45
+
46
+ ```powershell
47
+ bundle install
48
+ ```
49
+
50
+ ### Option 2: Using vcpkg
51
+
52
+ 1. Install vcpkg:
53
+
54
+ ```powershell
55
+ git clone https://github.com/Microsoft/vcpkg.git
56
+ cd vcpkg
57
+ .\bootstrap-vcpkg.bat
58
+ .\vcpkg integrate install
59
+ ```
60
+
61
+ 2. Install libxml2:
62
+
63
+ ```powershell
64
+ .\vcpkg install libxml2:x64-windows
65
+ ```
66
+
67
+ 3. Set environment variables:
68
+
69
+ ```powershell
70
+ $vcpkgPath = "C:\path\to\vcpkg\installed\x64-windows"
71
+ $env:PKG_CONFIG_PATH = "$vcpkgPath\lib\pkgconfig"
72
+ $env:PATH = "$vcpkgPath\bin;$env:PATH"
73
+ ```
74
+
75
+ ### Option 3: Skip libxml-ruby (Testing Only)
76
+
77
+ If you don't need to test the libxml serializer, you can temporarily exclude it:
78
+
79
+ ```ruby
80
+ # In Gemfile or when installing
81
+ bundle install --without libxml
82
+ ```
83
+
84
+ Or remove it from the gemspec temporarily (not recommended for CI).
85
+
86
+ ## Troubleshooting
87
+
88
+ ### Error: "Cannot find libxml2"
89
+
90
+ This means the libxml2 libraries are not in the expected locations. Try:
91
+
92
+ 1. Verify libxml2 is installed:
93
+ ```powershell
94
+ where libxml2.dll
95
+ ```
96
+
97
+ 2. Check pkg-config can find it:
98
+ ```powershell
99
+ pkg-config --libs libxml-2.0
100
+ ```
101
+
102
+ 3. Manually specify the path when installing the gem:
103
+ ```powershell
104
+ gem install libxml-ruby -- --with-xml2-dir="C:\path\to\libxml2"
105
+ ```
106
+
107
+ ### Error: "mkmf.log shows missing headers"
108
+
109
+ The development headers aren't found. Make sure you installed the complete libxml2 package including headers.
110
+
111
+ ## GitHub Actions CI
112
+
113
+ For CI/CD on GitHub Actions, see `.github/workflows/windows-setup.yml` for the complete setup that:
114
+
115
+ 1. Installs libxml2 via Chocolatey
116
+ 2. Configures environment paths
117
+ 3. Runs bundle install
118
+ 4. Executes tests
119
+
120
+ ## Local Development
121
+
122
+ For local development on Windows, follow the Chocolatey or vcpkg installation steps above. There is no automated Rake task - you must manually install libxml2 before running `bundle install`.
data/exe/serialbench CHANGED
@@ -3,4 +3,4 @@
3
3
 
4
4
  require_relative '../lib/serialbench'
5
5
 
6
- Serialbench::Cli.start(ARGV)
6
+ Serialbench::CLI.start(ARGV)