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.
- checksums.yaml +4 -4
- data/.github/workflows/discover-fonts.yml +76 -0
- data/.github/workflows/rake.yml +103 -8
- data/.rubocop_todo.yml +179 -139
- data/TODO.audit-docs.md +164 -0
- data/TODO.improve-docs.md +114 -0
- data/TODO.upgrade-excavate.md +107 -0
- data/docs/guide/formulas.md +37 -1
- data/docs/guide/how-it-works.md +13 -0
- data/docs/guide/platforms/windows.md +67 -0
- data/fontist.gemspec +2 -2
- data/lib/fontist/cache/store.rb +1 -1
- data/lib/fontist/cli.rb +2 -1
- data/lib/fontist/errors.rb +24 -3
- data/lib/fontist/extract.rb +1 -0
- data/lib/fontist/font.rb +2 -2
- data/lib/fontist/font_finder.rb +1 -2
- data/lib/fontist/font_installer.rb +16 -14
- data/lib/fontist/format_matcher.rb +4 -2
- data/lib/fontist/format_spec.rb +1 -1
- data/lib/fontist/formula.rb +15 -3
- data/lib/fontist/formula_picker.rb +5 -3
- data/lib/fontist/import/create_formula.rb +5 -0
- data/lib/fontist/import/formula_builder.rb +10 -1
- data/lib/fontist/import/google/data_sources/github.rb +4 -4
- data/lib/fontist/import/google/font_database.rb +8 -8
- data/lib/fontist/import/google/formula_builders/formula_builder_v4.rb +1 -1
- data/lib/fontist/import/google/formula_builders/formula_builder_v5.rb +9 -3
- data/lib/fontist/import/google/metadata_adapter.rb +6 -6
- data/lib/fontist/import/google/models/font_family.rb +1 -1
- data/lib/fontist/import/import_display.rb +5 -5
- data/lib/fontist/import/macos_importer.rb +1 -1
- data/lib/fontist/import/upgrade_formulas.rb +1 -3
- data/lib/fontist/import/v4_to_v5_migrator.rb +2 -1
- data/lib/fontist/import/windows/fod_capabilities.yml +654 -0
- data/lib/fontist/import/windows/windows_license.txt +4 -0
- data/lib/fontist/import/windows.rb +162 -0
- data/lib/fontist/import.rb +3 -1
- data/lib/fontist/import_source.rb +1 -0
- data/lib/fontist/indexes/directory_snapshot.rb +2 -2
- data/lib/fontist/indexes/incremental_scanner.rb +2 -2
- data/lib/fontist/indexes.rb +8 -4
- data/lib/fontist/macos/catalog/asset.rb +2 -2
- data/lib/fontist/macos_import_source.rb +0 -1
- data/lib/fontist/repo.rb +1 -1
- data/lib/fontist/resource.rb +5 -1
- data/lib/fontist/resources/windows_fod_resource.rb +51 -0
- data/lib/fontist/resources.rb +1 -0
- data/lib/fontist/system_index.rb +5 -5
- data/lib/fontist/utils/downloader.rb +8 -3
- data/lib/fontist/utils/system.rb +19 -2
- data/lib/fontist/validation.rb +1 -1
- data/lib/fontist/validator.rb +2 -2
- data/lib/fontist/version.rb +1 -1
- data/lib/fontist/windows_fod_metadata.rb +83 -0
- data/lib/fontist/windows_import_source.rb +54 -0
- data/lib/fontist.rb +4 -1
- data/script/generate_windows_formulas.rb +24 -0
- data/script/validate_windows_fod_ci.rb +175 -0
- metadata +17 -6
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# Validate Windows FOD capabilities against live Windows system
|
|
5
|
+
#
|
|
6
|
+
# Usage:
|
|
7
|
+
# bundle exec ruby script/validate_windows_fod_ci.rb
|
|
8
|
+
#
|
|
9
|
+
# This script:
|
|
10
|
+
# 1. Loads fod_capabilities.yml
|
|
11
|
+
# 2. Queries Windows for real FOD capabilities via PowerShell
|
|
12
|
+
# 3. Compares our YAML capability names against what Windows reports
|
|
13
|
+
# 4. For installed capabilities, checks that expected font files exist
|
|
14
|
+
# 5. Exits 0 on success, 1 on critical mismatches
|
|
15
|
+
|
|
16
|
+
require "yaml"
|
|
17
|
+
require "set"
|
|
18
|
+
|
|
19
|
+
FONTS_DIR = 'C:\Windows\Fonts'
|
|
20
|
+
YAML_PATH = File.expand_path(
|
|
21
|
+
"../lib/fontist/import/windows/fod_capabilities.yml",
|
|
22
|
+
__dir__,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
def main
|
|
26
|
+
unless Gem.win_platform?
|
|
27
|
+
puts "SKIP: Not running on Windows"
|
|
28
|
+
exit 0
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
puts "=== Windows FOD Capability Validation ==="
|
|
32
|
+
puts ""
|
|
33
|
+
|
|
34
|
+
yaml_caps = load_yaml_capabilities
|
|
35
|
+
live_caps = query_live_capabilities
|
|
36
|
+
|
|
37
|
+
puts "YAML capabilities: #{yaml_caps.size}"
|
|
38
|
+
puts "Live capabilities: #{live_caps.size}"
|
|
39
|
+
puts ""
|
|
40
|
+
|
|
41
|
+
matched, missing_from_yaml, extra_in_yaml = compare(yaml_caps, live_caps)
|
|
42
|
+
|
|
43
|
+
print_results(matched, missing_from_yaml, extra_in_yaml)
|
|
44
|
+
|
|
45
|
+
errors = check_installed_fonts(yaml_caps, live_caps)
|
|
46
|
+
|
|
47
|
+
puts ""
|
|
48
|
+
summarize(matched, missing_from_yaml, extra_in_yaml, errors)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def load_yaml_capabilities
|
|
52
|
+
data = YAML.safe_load(File.read(YAML_PATH))
|
|
53
|
+
data.fetch("capabilities", {})
|
|
54
|
+
rescue StandardError => e
|
|
55
|
+
puts "ERROR: Failed to load YAML: #{e.message}"
|
|
56
|
+
exit 1
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def query_live_capabilities
|
|
60
|
+
output = `powershell -NoProfile -Command "Get-WindowsCapability -Online -Name 'Language.Fonts.*' | Select-Object Name, State | ConvertTo-Csv -NoTypeInformation"`
|
|
61
|
+
|
|
62
|
+
unless $?.success?
|
|
63
|
+
puts "ERROR: PowerShell command failed (exit #{$?.exitstatus})"
|
|
64
|
+
exit 1
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
caps = {}
|
|
68
|
+
output.each_line do |line|
|
|
69
|
+
line = line.strip.delete('"')
|
|
70
|
+
next if line.empty? || line.start_with?("Name")
|
|
71
|
+
|
|
72
|
+
name, state = line.split(",", 2)
|
|
73
|
+
caps[name] = state if name && state
|
|
74
|
+
end
|
|
75
|
+
caps
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def compare(yaml_caps, live_caps)
|
|
79
|
+
yaml_names = yaml_caps.keys.to_set
|
|
80
|
+
live_names = live_caps.keys.to_set
|
|
81
|
+
|
|
82
|
+
matched = yaml_names & live_names
|
|
83
|
+
missing_from_yaml = live_names - yaml_names
|
|
84
|
+
extra_in_yaml = yaml_names - live_names
|
|
85
|
+
|
|
86
|
+
[matched, missing_from_yaml, extra_in_yaml]
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def print_results(matched, missing_from_yaml, extra_in_yaml)
|
|
90
|
+
puts "=== Matched (#{matched.size}) ==="
|
|
91
|
+
matched.sort.each { |name| puts " OK: #{name}" }
|
|
92
|
+
|
|
93
|
+
if missing_from_yaml.any?
|
|
94
|
+
puts ""
|
|
95
|
+
puts "=== Missing from our YAML (#{missing_from_yaml.size}) ==="
|
|
96
|
+
missing_from_yaml.sort.each { |name| puts " MISSING: #{name}" }
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
if extra_in_yaml.any?
|
|
100
|
+
puts ""
|
|
101
|
+
puts "=== Extra in our YAML (#{extra_in_yaml.size}) ==="
|
|
102
|
+
extra_in_yaml.sort.each { |name| puts " EXTRA: #{name}" }
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def check_installed_fonts(yaml_caps, live_caps)
|
|
107
|
+
installed = live_caps.select { |_, state| state == "Installed" }
|
|
108
|
+
return [] if installed.empty?
|
|
109
|
+
|
|
110
|
+
puts ""
|
|
111
|
+
puts "=== Font File Checks for Installed Capabilities ==="
|
|
112
|
+
|
|
113
|
+
errors = []
|
|
114
|
+
|
|
115
|
+
installed.each_key do |cap_name|
|
|
116
|
+
cap_data = yaml_caps[cap_name]
|
|
117
|
+
next unless cap_data
|
|
118
|
+
|
|
119
|
+
fonts = cap_data.fetch("fonts", {})
|
|
120
|
+
fonts.each do |family_name, data|
|
|
121
|
+
files = data.fetch("files", [])
|
|
122
|
+
files.each do |filename|
|
|
123
|
+
path = File.join(FONTS_DIR, filename)
|
|
124
|
+
if File.exist?(path)
|
|
125
|
+
puts " OK: #{filename} (#{family_name})"
|
|
126
|
+
else
|
|
127
|
+
puts " MISSING: #{filename} (#{family_name}) — expected at #{path}"
|
|
128
|
+
errors << "#{cap_name}: #{filename} not found"
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
errors
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def summarize(matched, missing_from_yaml, extra_in_yaml, font_errors)
|
|
138
|
+
puts "========================================="
|
|
139
|
+
puts " Validation Summary"
|
|
140
|
+
puts "========================================="
|
|
141
|
+
puts " Capability matches: #{matched.size}"
|
|
142
|
+
puts " Missing from our YAML: #{missing_from_yaml.size}"
|
|
143
|
+
puts " Extra in our YAML: #{extra_in_yaml.size}"
|
|
144
|
+
puts " Font file errors: #{font_errors.size}"
|
|
145
|
+
puts ""
|
|
146
|
+
|
|
147
|
+
if missing_from_yaml.any?
|
|
148
|
+
puts "WARNING: #{missing_from_yaml.size} capabilities exist on Windows but not in our YAML."
|
|
149
|
+
puts " Consider adding them to fod_capabilities.yml"
|
|
150
|
+
puts ""
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
if extra_in_yaml.any?
|
|
154
|
+
puts "WARNING: #{extra_in_yaml.size} capabilities in our YAML not found on this Windows version."
|
|
155
|
+
puts " These may be version-specific or renamed."
|
|
156
|
+
puts ""
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
if font_errors.any?
|
|
160
|
+
puts "WARNING: #{font_errors.size} font files missing for installed capabilities."
|
|
161
|
+
font_errors.each { |e| puts " - #{e}" }
|
|
162
|
+
puts ""
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# Exit 1 only if we have zero matches (indicates a fundamental problem)
|
|
166
|
+
if matched.empty? && (missing_from_yaml.any? || extra_in_yaml.any?)
|
|
167
|
+
puts "CRITICAL: No capability names matched — our YAML may be completely wrong."
|
|
168
|
+
exit 1
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
puts "Validation passed."
|
|
172
|
+
exit 0
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
main
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: fontist
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.0.
|
|
4
|
+
version: 3.0.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-05-05 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: down
|
|
@@ -53,7 +53,7 @@ dependencies:
|
|
|
53
53
|
version: '0.2'
|
|
54
54
|
- - ">="
|
|
55
55
|
- !ruby/object:Gem::Version
|
|
56
|
-
version: 0.2.
|
|
56
|
+
version: 0.2.16
|
|
57
57
|
type: :runtime
|
|
58
58
|
prerelease: false
|
|
59
59
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -63,7 +63,7 @@ dependencies:
|
|
|
63
63
|
version: '0.2'
|
|
64
64
|
- - ">="
|
|
65
65
|
- !ruby/object:Gem::Version
|
|
66
|
-
version: 0.2.
|
|
66
|
+
version: 0.2.16
|
|
67
67
|
- !ruby/object:Gem::Dependency
|
|
68
68
|
name: fuzzy_match
|
|
69
69
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -112,14 +112,14 @@ dependencies:
|
|
|
112
112
|
requirements:
|
|
113
113
|
- - "~>"
|
|
114
114
|
- !ruby/object:Gem::Version
|
|
115
|
-
version:
|
|
115
|
+
version: 0.8.0
|
|
116
116
|
type: :runtime
|
|
117
117
|
prerelease: false
|
|
118
118
|
version_requirements: !ruby/object:Gem::Requirement
|
|
119
119
|
requirements:
|
|
120
120
|
- - "~>"
|
|
121
121
|
- !ruby/object:Gem::Version
|
|
122
|
-
version:
|
|
122
|
+
version: 0.8.0
|
|
123
123
|
- !ruby/object:Gem::Dependency
|
|
124
124
|
name: marcel
|
|
125
125
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -273,7 +273,10 @@ files:
|
|
|
273
273
|
- LICENSE.txt
|
|
274
274
|
- README.adoc
|
|
275
275
|
- Rakefile
|
|
276
|
+
- TODO.audit-docs.md
|
|
276
277
|
- TODO.fontist-v5.md
|
|
278
|
+
- TODO.improve-docs.md
|
|
279
|
+
- TODO.upgrade-excavate.md
|
|
277
280
|
- docs/.gitignore
|
|
278
281
|
- docs/.vitepress/config.ts
|
|
279
282
|
- docs/.vitepress/data/cli-commands.json
|
|
@@ -434,6 +437,9 @@ files:
|
|
|
434
437
|
- lib/fontist/import/text_helper.rb
|
|
435
438
|
- lib/fontist/import/upgrade_formulas.rb
|
|
436
439
|
- lib/fontist/import/v4_to_v5_migrator.rb
|
|
440
|
+
- lib/fontist/import/windows.rb
|
|
441
|
+
- lib/fontist/import/windows/fod_capabilities.yml
|
|
442
|
+
- lib/fontist/import/windows/windows_license.txt
|
|
437
443
|
- lib/fontist/import_cli.rb
|
|
438
444
|
- lib/fontist/import_source.rb
|
|
439
445
|
- lib/fontist/index.rb
|
|
@@ -486,6 +492,7 @@ files:
|
|
|
486
492
|
- lib/fontist/resources/apple_cdn_resource.rb
|
|
487
493
|
- lib/fontist/resources/archive_resource.rb
|
|
488
494
|
- lib/fontist/resources/google_resource.rb
|
|
495
|
+
- lib/fontist/resources/windows_fod_resource.rb
|
|
489
496
|
- lib/fontist/sil_import_source.rb
|
|
490
497
|
- lib/fontist/style_version.rb
|
|
491
498
|
- lib/fontist/system.yml
|
|
@@ -506,9 +513,13 @@ files:
|
|
|
506
513
|
- lib/fontist/validation.rb
|
|
507
514
|
- lib/fontist/validator.rb
|
|
508
515
|
- lib/fontist/version.rb
|
|
516
|
+
- lib/fontist/windows_fod_metadata.rb
|
|
517
|
+
- lib/fontist/windows_import_source.rb
|
|
509
518
|
- lib/tasks/system_fonts.rake
|
|
510
519
|
- script/capture_system_fonts
|
|
511
520
|
- script/download_system_indexes
|
|
521
|
+
- script/generate_windows_formulas.rb
|
|
522
|
+
- script/validate_windows_fod_ci.rb
|
|
512
523
|
homepage: https://github.com/fontist/fontist
|
|
513
524
|
licenses:
|
|
514
525
|
- BSD-2-Clause
|