fontist 3.0.0 → 3.0.2

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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/discover-fonts.yml +76 -0
  3. data/.github/workflows/rake.yml +103 -8
  4. data/.rubocop_todo.yml +179 -139
  5. data/TODO.audit-docs.md +164 -0
  6. data/TODO.improve-docs.md +114 -0
  7. data/TODO.upgrade-excavate.md +107 -0
  8. data/docs/guide/formulas.md +37 -1
  9. data/docs/guide/how-it-works.md +13 -0
  10. data/docs/guide/platforms/windows.md +67 -0
  11. data/fontist.gemspec +2 -2
  12. data/lib/fontist/cache/store.rb +1 -1
  13. data/lib/fontist/cli.rb +2 -1
  14. data/lib/fontist/errors.rb +24 -3
  15. data/lib/fontist/extract.rb +1 -0
  16. data/lib/fontist/font.rb +2 -2
  17. data/lib/fontist/font_finder.rb +1 -2
  18. data/lib/fontist/font_installer.rb +16 -14
  19. data/lib/fontist/format_matcher.rb +4 -2
  20. data/lib/fontist/format_spec.rb +1 -1
  21. data/lib/fontist/formula.rb +15 -3
  22. data/lib/fontist/formula_picker.rb +5 -3
  23. data/lib/fontist/import/create_formula.rb +5 -0
  24. data/lib/fontist/import/formula_builder.rb +10 -1
  25. data/lib/fontist/import/google/data_sources/github.rb +4 -4
  26. data/lib/fontist/import/google/font_database.rb +8 -8
  27. data/lib/fontist/import/google/formula_builders/formula_builder_v4.rb +1 -1
  28. data/lib/fontist/import/google/formula_builders/formula_builder_v5.rb +9 -3
  29. data/lib/fontist/import/google/metadata_adapter.rb +6 -6
  30. data/lib/fontist/import/google/models/font_family.rb +1 -1
  31. data/lib/fontist/import/import_display.rb +5 -5
  32. data/lib/fontist/import/macos_importer.rb +1 -1
  33. data/lib/fontist/import/upgrade_formulas.rb +1 -3
  34. data/lib/fontist/import/v4_to_v5_migrator.rb +2 -1
  35. data/lib/fontist/import/windows/fod_capabilities.yml +654 -0
  36. data/lib/fontist/import/windows/windows_license.txt +4 -0
  37. data/lib/fontist/import/windows.rb +162 -0
  38. data/lib/fontist/import.rb +3 -1
  39. data/lib/fontist/import_source.rb +1 -0
  40. data/lib/fontist/indexes/directory_snapshot.rb +2 -2
  41. data/lib/fontist/indexes/incremental_scanner.rb +2 -2
  42. data/lib/fontist/indexes.rb +8 -4
  43. data/lib/fontist/macos/catalog/asset.rb +2 -2
  44. data/lib/fontist/macos_import_source.rb +0 -1
  45. data/lib/fontist/repo.rb +1 -1
  46. data/lib/fontist/resource.rb +5 -1
  47. data/lib/fontist/resources/windows_fod_resource.rb +51 -0
  48. data/lib/fontist/resources.rb +1 -0
  49. data/lib/fontist/system_index.rb +5 -5
  50. data/lib/fontist/utils/downloader.rb +8 -3
  51. data/lib/fontist/utils/system.rb +19 -2
  52. data/lib/fontist/validation.rb +1 -1
  53. data/lib/fontist/validator.rb +2 -2
  54. data/lib/fontist/version.rb +1 -1
  55. data/lib/fontist/windows_fod_metadata.rb +83 -0
  56. data/lib/fontist/windows_import_source.rb +54 -0
  57. data/lib/fontist.rb +4 -1
  58. data/script/generate_windows_formulas.rb +24 -0
  59. data/script/validate_windows_fod_ci.rb +175 -0
  60. metadata +17 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ab7d070a986f52cb3b93a83eeef69a76b72ef07881276a5090e373bc4758f682
4
- data.tar.gz: eb5eeceeb19c10b0d3537549067e2e8332253dc864c722873c1e39ca50a800bd
3
+ metadata.gz: b68f4d4d083a0e2f73df389c0698800b4a4d519428cbf59ddd98f493630a3342
4
+ data.tar.gz: 76cc6dd8420deb15d8b5fd872e17550c4b31dc31585834f2290a0e3f36d130ba
5
5
  SHA512:
6
- metadata.gz: abf247ac6988a9f812c04c265a07d8f397e5f80eb874471b0c354d523de94f66ccc66ab6e6708560698e50008e413c8e07054632a6c3aff6d5f6e1b80dacef58
7
- data.tar.gz: 138d53e9d110fe58520360adbdc37a5c7c6f0aacee634cb269ed706fd6eeb319c7add2873646adec2009431e469189c051d92c2d80de3e59f6d7060ee1ca8894
6
+ metadata.gz: 72c687e0c3c81823d1e0edf131f9af115564e5d7b60b296d84dad7c297e5ea6e8f5fd6995f18961b6a6d048fb630eeba1e74d7beb942bad0abf97b9922112435
7
+ data.tar.gz: 57c8dde9259414c129e83c5fea0b7d50b2970c0062a756ffd9f8dbf91738508c154e0372f7b4a9d30139abb17d650a98954db0cc8764bd8871c7c5611221e4f9
@@ -69,6 +69,8 @@ jobs:
69
69
  version: [2022, 2025]
70
70
  fail-fast: false
71
71
  steps:
72
+ - uses: actions/checkout@v6
73
+
72
74
  - name: List ALL Windows Fonts
73
75
  shell: pwsh
74
76
  run: |
@@ -78,6 +80,80 @@ jobs:
78
80
  Write-Host "=== Total Count ==="
79
81
  (Get-ChildItem -Path "C:\Windows\Fonts\" -Include *.ttf,*.ttc,*.otf -Recurse).Count
80
82
 
83
+ - name: List FOD font capabilities
84
+ shell: pwsh
85
+ run: |
86
+ Write-Host "=== Windows FOD Font Capabilities ==="
87
+ $caps = Get-WindowsCapability -Online -Name "Language.Fonts.*"
88
+ $caps | Format-Table -AutoSize Name, State
89
+ Write-Host ""
90
+ Write-Host "=== Summary ==="
91
+ $installed = ($caps | Where-Object { $_.State -eq "Installed" }).Count
92
+ $notPresent = ($caps | Where-Object { $_.State -eq "NotPresent" }).Count
93
+ $staged = ($caps | Where-Object { $_.State -eq "Staged" }).Count
94
+ Write-Host "Installed: $installed"
95
+ Write-Host "NotPresent: $notPresent"
96
+ Write-Host "Staged: $staged"
97
+ Write-Host "Total: $($caps.Count)"
98
+ Write-Host ""
99
+ Write-Host "=== Saving results ==="
100
+ New-Item -ItemType Directory -Force -Path artifacts | Out-Null
101
+ $caps | Select-Object Name, State | ConvertTo-Csv -NoTypeInformation | Out-File -FilePath artifacts/fod-capabilities.csv
102
+ $caps | ConvertTo-Json | Out-File -FilePath artifacts/fod-capabilities.json
103
+ Write-Host "Saved to artifacts/fod-capabilities.csv and artifacts/fod-capabilities.json"
104
+
105
+ - name: Cross-check FOD capabilities with our YAML
106
+ shell: pwsh
107
+ run: |
108
+ Write-Host "=== Cross-checking fod_capabilities.yml against live Windows ==="
109
+
110
+ # Get live capabilities from Windows
111
+ $liveCaps = Get-WindowsCapability -Online -Name "Language.Fonts.*"
112
+ $liveNames = $liveCaps | ForEach-Object { $_.Name }
113
+
114
+ # Parse our YAML capability names (simple text extraction)
115
+ $yamlPath = "lib/fontist/import/windows/fod_capabilities.yml"
116
+ $yamlContent = Get-Content $yamlPath -Raw
117
+ $yamlNames = [regex]::Matches($yamlContent, '^\s+"([^"]+)":', [System.Text.RegularExpressions.RegexOptions]::Multiline) |
118
+ ForEach-Object { $_.Groups[1].Value }
119
+
120
+ Write-Host ""
121
+ Write-Host "Live capabilities: $($liveNames.Count)"
122
+ Write-Host "YAML capabilities: $($yamlNames.Count)"
123
+ Write-Host ""
124
+
125
+ # Find matches
126
+ $matched = $yamlNames | Where-Object { $liveNames -contains $_ }
127
+ Write-Host "=== Matched ($($matched.Count)) ==="
128
+ $matched | ForEach-Object { Write-Host " OK: $_" }
129
+
130
+ # Find missing from our YAML (present on Windows but not in our file)
131
+ $missingFromYaml = $liveNames | Where-Object { $yamlNames -notcontains $_ }
132
+ if ($missingFromYaml.Count -gt 0) {
133
+ Write-Host ""
134
+ Write-Host "=== Missing from our YAML ($($missingFromYaml.Count)) ==="
135
+ $missingFromYaml | ForEach-Object { Write-Host " MISSING: $_" }
136
+ }
137
+
138
+ # Find extra in our YAML (in our file but not on Windows)
139
+ $extraInYaml = $yamlNames | Where-Object { $liveNames -notcontains $_ }
140
+ if ($extraInYaml.Count -gt 0) {
141
+ Write-Host ""
142
+ Write-Host "=== Extra in our YAML ($($extraInYaml.Count)) ==="
143
+ $extraInYaml | ForEach-Object { Write-Host " EXTRA: $_" }
144
+ }
145
+
146
+ Write-Host ""
147
+ Write-Host "=== Cross-check complete ==="
148
+
149
+ - name: Upload FOD capability results
150
+ if: always()
151
+ uses: actions/upload-artifact@v4
152
+ with:
153
+ name: windows-fod-capabilities-${{ matrix.version }}
154
+ path: artifacts/
155
+ if-no-files-found: warn
156
+
81
157
  discover-linux:
82
158
  name: Linux fonts
83
159
  runs-on: ubuntu-latest
@@ -214,6 +214,104 @@ jobs:
214
214
  echo " Test Complete"
215
215
  echo "========================================================================="
216
216
 
217
+ - name: Test Windows FOD font installation
218
+ if: startsWith(matrix.os, 'windows')
219
+ continue-on-error: true
220
+ shell: pwsh
221
+ run: |
222
+ Write-Host "========================================================================="
223
+ Write-Host " Windows FOD (Features on Demand) Font Installation Test"
224
+ Write-Host "========================================================================="
225
+ Write-Host ""
226
+ Write-Host "Platform: Windows $(([System.Environment]::OSVersion.Version).ToString())"
227
+ Write-Host "Runner: ${{ matrix.os }}"
228
+ Write-Host ""
229
+
230
+ Write-Host "--- Step 1: Generate Windows FOD Formulas into formulas repo ---"
231
+ $formulasRepo = bundle exec ruby -e "require 'fontist'; puts Fontist.formulas_path"
232
+ $formulasRepo = $formulasRepo.Trim()
233
+ $windowsDir = Join-Path $formulasRepo "windows"
234
+ Write-Host "Formulas path: $formulasRepo"
235
+ Write-Host "Generating FOD formulas into: $windowsDir"
236
+ bundle exec ruby script/generate_windows_formulas.rb $windowsDir
237
+ $formulaCount = (Get-ChildItem -Path $windowsDir -Filter "*.yml" -ErrorAction SilentlyContinue).Count
238
+ Write-Host "Generated $formulaCount formula files"
239
+ Write-Host ""
240
+
241
+ Write-Host "--- Step 2: Rebuild formula index to include FOD formulas ---"
242
+ bundle exec ruby -e "require 'fontist'; Fontist::Index.rebuild; puts 'Formula index rebuilt'; f = Fontist::Formula.find('Arial Nova'); puts f ? 'Verified: Arial Nova found -> ' + f.name : 'WARNING: Arial Nova NOT found in index'"
243
+ if ($LASTEXITCODE -ne 0) {
244
+ Write-Host "WARNING: Formula index rebuild failed with exit code $LASTEXITCODE"
245
+ }
246
+ Write-Host ""
247
+
248
+ Write-Host "--- Step 2b: Verify formula index ---"
249
+ $indexPath = bundle exec ruby -e "require 'fontist'; puts Fontist.formula_index_path"
250
+ $indexPath = $indexPath.Trim()
251
+ Write-Host "Formula index path: $indexPath"
252
+ if (Test-Path $indexPath) {
253
+ $lineCount = (Get-Content $indexPath).Count
254
+ Write-Host "Formula index exists: $lineCount lines"
255
+ Write-Host "First 20 lines:"
256
+ Get-Content $indexPath -Head 20
257
+ } else {
258
+ Write-Host "WARNING: Formula index file does NOT exist at $indexPath"
259
+ }
260
+ Write-Host ""
261
+
262
+ Write-Host "--- Step 2c: Verify formula files on disk ---"
263
+ $formulasDir = bundle exec ruby -e "require 'fontist'; puts Fontist.formulas_path"
264
+ $formulasDir = $formulasDir.Trim()
265
+ Write-Host "Formulas directory: $formulasDir"
266
+ if (Test-Path $formulasDir) {
267
+ $ymlFiles = Get-ChildItem -Path $formulasDir -Filter "*.yml" -Recurse
268
+ Write-Host "Total .yml files: $($ymlFiles.Count)"
269
+ $ymlFiles | Select-Object -First 30 | ForEach-Object { Write-Host " $($_.FullName)" }
270
+ } else {
271
+ Write-Host "WARNING: Formulas directory does NOT exist"
272
+ }
273
+ Write-Host ""
274
+
275
+ Write-Host "--- Step 3: List FOD Font Capabilities ---"
276
+ $caps = Get-WindowsCapability -Online -Name "Language.Fonts.*"
277
+ $installed = ($caps | Where-Object { $_.State -eq "Installed" })
278
+ $notPresent = ($caps | Where-Object { $_.State -eq "NotPresent" })
279
+ Write-Host "Installed: $($installed.Count)"
280
+ Write-Host "NotPresent: $($notPresent.Count)"
281
+ Write-Host "Total: $($caps.Count)"
282
+ Write-Host ""
283
+
284
+ Write-Host "--- Step 4: Run Cross-Check Validation ---"
285
+ bundle exec ruby script/validate_windows_fod_ci.rb
286
+ Write-Host ""
287
+
288
+ Write-Host "--- Step 5: Install Plantagenet Cherokee via fontist (small FOD) ---"
289
+ Write-Host "Running: fontist install 'Plantagenet Cherokee' --accept-all-licenses"
290
+ bundle exec fontist install "Plantagenet Cherokee" --accept-all-licenses
291
+ if ($LASTEXITCODE -eq 0) {
292
+ Write-Host "fontist install succeeded"
293
+ } else {
294
+ Write-Host "WARNING: fontist install exited with code $LASTEXITCODE"
295
+ }
296
+ Write-Host ""
297
+
298
+ Write-Host "--- Step 6: Verify Plantagenet Cherokee via fontist list ---"
299
+ bundle exec fontist list "Plantagenet Cherokee"
300
+ Write-Host ""
301
+
302
+ Write-Host "--- Step 7: Verify font file on disk ---"
303
+ $path = Join-Path "C:\Windows\Fonts" "Plantc.ttf"
304
+ if (Test-Path $path) {
305
+ Write-Host " OK: Plantc.ttf"
306
+ } else {
307
+ Write-Host " MISSING: Plantc.ttf"
308
+ }
309
+ Write-Host ""
310
+
311
+ Write-Host "========================================================================="
312
+ Write-Host " Test Complete"
313
+ Write-Host "========================================================================="
314
+
217
315
  - name: Upload system index as artifact
218
316
  if: always()
219
317
  uses: actions/upload-artifact@v4
@@ -237,17 +335,14 @@ jobs:
237
335
 
238
336
  steps:
239
337
  - name: Setup packages
240
- run: pacman -Syu --noconfirm git binutils gcc autoconf make libffi libyaml gmp
338
+ run: |
339
+ pacman -Syu --noconfirm git binutils gcc autoconf make libffi libyaml gmp ruby ruby-stdlib
241
340
 
242
341
  - uses: actions/checkout@v4
243
342
 
244
- - uses: asdf-vm/actions/install@v3
245
- with:
246
- tool_versions: ruby ${{ needs.prepare.outputs.default-ruby-version }}
247
-
248
343
  - run: |
249
- gem install bundler
250
- bundle install
344
+ gem install --no-document --user-install bundler
345
+ PATH="$(ruby -e 'puts Gem.user_dir')/bin:$PATH" bundle install
251
346
 
252
347
  - name: Test
253
- run: bundle exec rake
348
+ run: PATH="$(ruby -e 'puts Gem.user_dir')/bin:$PATH" bundle exec rake