fontist 1.12.0 → 1.13.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/.rubocop.yml +2 -2
- data/README.adoc +19 -0
- data/lib/fontist/cli.rb +38 -12
- data/lib/fontist/errors.rb +2 -0
- data/lib/fontist/font.rb +17 -2
- data/lib/fontist/formula.rb +49 -3
- data/lib/fontist/formula_picker.rb +126 -0
- data/lib/fontist/import/formula_builder.rb +6 -2
- data/lib/fontist/indexes/default_family_font_index.rb +4 -1
- data/lib/fontist/style_version.rb +39 -0
- data/lib/fontist/version.rb +1 -1
- data/lib/fontist.rb +4 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 43f3bc7643cf7694fb753d9c62509f7134a26d68fb41a2e06c9c9e25f33ae2c5
|
4
|
+
data.tar.gz: 3269f7aedc78eed761697ff862701bf6ca27679e9be90972d8983e913a15beea
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a92d2d69bed9e8e33fc9785f198c9878d1a02dda4de65f290ecff30336adec6117cfd18cc09d52545f318a917b40e02b4d796049384b6b6c12fee05d2056283f
|
7
|
+
data.tar.gz: ffdb9a02c723a5a8c04c26c3f3d5a0d0bba4e875fd750bee67a3c68698d2f2e9057ff936019523d3eb9a359bbbf19de566c45acb99fff99b745952039add7e30
|
data/.rubocop.yml
CHANGED
data/README.adoc
CHANGED
@@ -117,6 +117,25 @@ NOTE: Specifying the formula's name or the font's filename is not supported.
|
|
117
117
|
|
118
118
|
NOTE: The `install` command is similar to the `Font.install` library call.
|
119
119
|
|
120
|
+
If there are several formulas with a requested font, then `fontist` searches
|
121
|
+
for the newest version of the font among formulas with size below a limit
|
122
|
+
(300 MB). This behavior can be changed with options.
|
123
|
+
|
124
|
+
NOTE: If styles of a font are spread among several formulas, then all
|
125
|
+
available formulas would be installed.
|
126
|
+
|
127
|
+
Supported options:
|
128
|
+
|
129
|
+
-f, [--force]:: Install even if it's already installed in system
|
130
|
+
-a, [--accept-all-licenses]:: Accept all license agreements
|
131
|
+
-h, [--hide-licenses]:: Hide license texts
|
132
|
+
-p, [--no-progress]:: Hide download progress
|
133
|
+
-V, [--version=VERSION]:: Install particular version of a font
|
134
|
+
-s, [--smallest]:: Install the smallest formula
|
135
|
+
-n, [--newest]:: Install the newest version of a font
|
136
|
+
-S, [--size-limit=N]:: Specify size limit for a formula to be installed
|
137
|
+
(default is 300 MB)
|
138
|
+
|
120
139
|
=== Uninstall fonts
|
121
140
|
|
122
141
|
Uninstalls any font supported by Fontist.
|
data/lib/fontist/cli.rb
CHANGED
@@ -17,15 +17,24 @@ module Fontist
|
|
17
17
|
STATUS_MAIN_REPO_NOT_FOUND = 9
|
18
18
|
STATUS_REPO_COULD_NOT_BE_UPDATED = 10
|
19
19
|
STATUS_MANUAL_FONT_ERROR = 11
|
20
|
+
STATUS_SIZE_LIMIT_ERROR = 12
|
20
21
|
|
21
22
|
ERROR_TO_STATUS = {
|
22
23
|
Fontist::Errors::UnsupportedFontError => [STATUS_NON_SUPPORTED_FONT_ERROR],
|
23
24
|
Fontist::Errors::MissingFontError => [STATUS_MISSING_FONT_ERROR],
|
25
|
+
Fontist::Errors::SizeLimitError => [
|
26
|
+
STATUS_SIZE_LIMIT_ERROR,
|
27
|
+
:append,
|
28
|
+
"Please specify higher `--size-limit`, or use the `--newest` or " \
|
29
|
+
"`--smallest` options.",
|
30
|
+
],
|
24
31
|
Fontist::Errors::ManualFontError => [STATUS_MANUAL_FONT_ERROR],
|
25
32
|
Fontist::Errors::LicensingError => [STATUS_LICENSING_ERROR],
|
26
33
|
Fontist::Errors::ManifestCouldNotBeFoundError => [STATUS_MANIFEST_COULD_NOT_BE_FOUND_ERROR,
|
34
|
+
:overwrite,
|
27
35
|
"Manifest could not be found."],
|
28
36
|
Fontist::Errors::ManifestCouldNotBeReadError => [STATUS_MANIFEST_COULD_NOT_BE_READ_ERROR,
|
37
|
+
:overwrite,
|
29
38
|
"Manifest could not be read."],
|
30
39
|
Fontist::Errors::FontIndexCorrupted => [STATUS_FONT_INDEX_CORRUPTED],
|
31
40
|
Fontist::Errors::RepoNotFoundError => [STATUS_REPO_NOT_FOUND],
|
@@ -43,18 +52,27 @@ module Fontist
|
|
43
52
|
desc "install FONT", "Install font"
|
44
53
|
option :force, type: :boolean, aliases: :f,
|
45
54
|
desc: "Install even if it's already installed in system"
|
46
|
-
option :accept_all_licenses, type: :boolean,
|
47
|
-
|
48
|
-
|
55
|
+
option :accept_all_licenses, type: :boolean,
|
56
|
+
aliases: ["--confirm-license", :a],
|
57
|
+
desc: "Accept all license agreements"
|
58
|
+
option :hide_licenses, type: :boolean, aliases: :h,
|
59
|
+
desc: "Hide license texts"
|
60
|
+
option :no_progress, type: :boolean, aliases: :p,
|
61
|
+
desc: "Hide download progress"
|
62
|
+
option :version, type: :string, aliases: :V,
|
63
|
+
desc: "Specify particular version of a font"
|
64
|
+
option :smallest, type: :boolean, aliases: :s,
|
65
|
+
desc: "Install the smallest formula if several"
|
66
|
+
option :newest, type: :boolean, aliases: :n,
|
67
|
+
desc: "Install the newest version of a font if several"
|
68
|
+
option :size_limit,
|
69
|
+
type: :numeric, aliases: :S,
|
70
|
+
desc: "Specify size limit for formula " \
|
71
|
+
"(default is #{Fontist.formula_size_limit_in_megabytes} MB)"
|
49
72
|
def install(font)
|
50
73
|
handle_class_options(options)
|
51
|
-
|
52
|
-
|
53
|
-
force: options[:force],
|
54
|
-
confirmation: options[:accept_all_licenses] ? "yes" : "no",
|
55
|
-
hide_licenses: options[:hide_licenses],
|
56
|
-
no_progress: options[:no_progress]
|
57
|
-
)
|
74
|
+
confirmation = options[:accept_all_licenses] ? "yes" : "no"
|
75
|
+
Fontist::Font.install(font, options.merge(confirmation: confirmation))
|
58
76
|
success
|
59
77
|
rescue Fontist::Errors::GeneralError => e
|
60
78
|
handle_error(e)
|
@@ -187,10 +205,18 @@ module Fontist
|
|
187
205
|
end
|
188
206
|
|
189
207
|
def handle_error(exception)
|
190
|
-
status, message = ERROR_TO_STATUS[exception.class]
|
208
|
+
status, mode, message = ERROR_TO_STATUS[exception.class]
|
191
209
|
raise exception unless status
|
192
210
|
|
193
|
-
|
211
|
+
text = if message && mode == :overwrite
|
212
|
+
message
|
213
|
+
elsif message
|
214
|
+
"#{exception.message} #{message}"
|
215
|
+
else
|
216
|
+
exception.message
|
217
|
+
end
|
218
|
+
|
219
|
+
error(text, status)
|
194
220
|
end
|
195
221
|
|
196
222
|
def error(message, status)
|
data/lib/fontist/errors.rb
CHANGED
data/lib/fontist/font.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "fontist/font_installer"
|
2
2
|
require "fontist/font_path"
|
3
|
+
require "fontist/formula_picker"
|
3
4
|
|
4
5
|
module Fontist
|
5
6
|
class Font
|
@@ -9,6 +10,10 @@ module Fontist
|
|
9
10
|
@hide_licenses = options[:hide_licenses]
|
10
11
|
@no_progress = options[:no_progress] || false
|
11
12
|
@force = options[:force] || false
|
13
|
+
@version = options[:version]
|
14
|
+
@smallest = options[:smallest]
|
15
|
+
@newest = options[:newest]
|
16
|
+
@size_limit = options[:size_limit]
|
12
17
|
|
13
18
|
check_or_create_fontist_path!
|
14
19
|
end
|
@@ -102,6 +107,16 @@ module Fontist
|
|
102
107
|
FontInstaller.new(formula, no_progress: @no_progress)
|
103
108
|
end
|
104
109
|
|
110
|
+
def sufficient_formulas
|
111
|
+
@sufficient_formulas ||=
|
112
|
+
FormulaPicker.new(@name,
|
113
|
+
size_limit: @size_limit,
|
114
|
+
version: @version,
|
115
|
+
smallest: @smallest,
|
116
|
+
newest: @newest)
|
117
|
+
.call(downloadable_formulas)
|
118
|
+
end
|
119
|
+
|
105
120
|
def downloadable_formulas
|
106
121
|
@downloadable_formulas ||= formulas.select(&:downloadable?)
|
107
122
|
end
|
@@ -130,9 +145,9 @@ module Fontist
|
|
130
145
|
end
|
131
146
|
|
132
147
|
def download_font
|
133
|
-
return if
|
148
|
+
return if sufficient_formulas.empty?
|
134
149
|
|
135
|
-
|
150
|
+
sufficient_formulas.flat_map do |formula|
|
136
151
|
confirmation = check_and_confirm_required_license(formula)
|
137
152
|
paths = font_installer(formula).install(confirmation: confirmation)
|
138
153
|
|
data/lib/fontist/formula.rb
CHANGED
@@ -107,6 +107,12 @@ module Fontist
|
|
107
107
|
Helpers.parse_to_object(@data["extract"])
|
108
108
|
end
|
109
109
|
|
110
|
+
def file_size
|
111
|
+
return unless @data["resources"]
|
112
|
+
|
113
|
+
@data["resources"].values.first["file_size"]&.to_i
|
114
|
+
end
|
115
|
+
|
110
116
|
def resources
|
111
117
|
Helpers.parse_to_object(@data["resources"]&.values)
|
112
118
|
end
|
@@ -115,8 +121,14 @@ module Fontist
|
|
115
121
|
@data["instructions"]
|
116
122
|
end
|
117
123
|
|
124
|
+
def fonts_by_name(name)
|
125
|
+
fonts.select do |font|
|
126
|
+
font.name.casecmp?(name)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
118
130
|
def fonts
|
119
|
-
@fonts ||= Helpers.parse_to_object(
|
131
|
+
@fonts ||= Helpers.parse_to_object(fonts_by_family)
|
120
132
|
end
|
121
133
|
|
122
134
|
def digest
|
@@ -130,6 +142,41 @@ module Fontist
|
|
130
142
|
@path.sub(Regexp.new("^" + escaped), "").sub(/\.yml$/, "")
|
131
143
|
end
|
132
144
|
|
145
|
+
def fonts_by_family
|
146
|
+
return hash_all_fonts unless Fontist.preferred_family?
|
147
|
+
|
148
|
+
preferred_family_fonts
|
149
|
+
end
|
150
|
+
|
151
|
+
def preferred_family_fonts
|
152
|
+
groups = preferred_family_styles.group_by do |style|
|
153
|
+
style["family_name"]
|
154
|
+
end
|
155
|
+
|
156
|
+
groups.map do |font_name, font_styles|
|
157
|
+
{ "name" => font_name, "styles" => font_styles }
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def preferred_family_styles
|
162
|
+
hash_all_fonts.flat_map do |font|
|
163
|
+
font["styles"].map do |style|
|
164
|
+
style.merge(preferred_style(style))
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def preferred_style(style)
|
170
|
+
{ "family_name" => style["preferred_family_name"] || style["family_name"],
|
171
|
+
"type" => style["preferred_type"] || style["type"],
|
172
|
+
"default_family_name" => style["family_name"],
|
173
|
+
"default_type" => style["type"] }
|
174
|
+
end
|
175
|
+
|
176
|
+
def hash_all_fonts
|
177
|
+
hash_collection_fonts + hash_fonts
|
178
|
+
end
|
179
|
+
|
133
180
|
def hash_collection_fonts
|
134
181
|
return [] unless @data["font_collections"]
|
135
182
|
|
@@ -138,8 +185,7 @@ module Fontist
|
|
138
185
|
"source_font" => coll["source_filename"] }
|
139
186
|
|
140
187
|
coll["fonts"].map do |font|
|
141
|
-
|
142
|
-
"styles" => font["styles"].map { |s| filenames.merge(s) } }
|
188
|
+
font.merge("styles" => font["styles"].map { |s| filenames.merge(s) })
|
143
189
|
end
|
144
190
|
end
|
145
191
|
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require "fontist/style_version"
|
2
|
+
|
3
|
+
module Fontist
|
4
|
+
class FormulaPicker
|
5
|
+
def initialize(font_name, size_limit:, version:, smallest:, newest:)
|
6
|
+
@font_name = font_name
|
7
|
+
@size_limit = size_limit || Fontist.formula_size_limit_in_megabytes
|
8
|
+
@version = version
|
9
|
+
@smallest = smallest
|
10
|
+
@newest = newest
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(formulas)
|
14
|
+
return [] if formulas.size.zero?
|
15
|
+
return formulas if contain_different_styles?(formulas)
|
16
|
+
return by_version(formulas) if version_is_passed?
|
17
|
+
return newest(formulas) if newest_is_passed?
|
18
|
+
return smallest(formulas) if smallest_is_passed?
|
19
|
+
|
20
|
+
default_way(formulas)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def version_is_passed?
|
26
|
+
!@version.nil?
|
27
|
+
end
|
28
|
+
|
29
|
+
def by_version(formulas)
|
30
|
+
formulas.each do |formula|
|
31
|
+
fonts = formula.fonts_by_name(@font_name)
|
32
|
+
fonts.each do |font|
|
33
|
+
font.styles.each do |style|
|
34
|
+
version = StyleVersion.new(style.version)
|
35
|
+
return [formula] if version == passed_version
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
[]
|
41
|
+
end
|
42
|
+
|
43
|
+
def passed_version
|
44
|
+
@passed_version ||= StyleVersion.new(@version)
|
45
|
+
end
|
46
|
+
|
47
|
+
def newest_is_passed?
|
48
|
+
@newest
|
49
|
+
end
|
50
|
+
|
51
|
+
def newest(formulas)
|
52
|
+
newest_formulas = filter_by_max_version(formulas)
|
53
|
+
smallest(newest_formulas)
|
54
|
+
end
|
55
|
+
|
56
|
+
def smallest_is_passed?
|
57
|
+
@smallest
|
58
|
+
end
|
59
|
+
|
60
|
+
def smallest(formulas)
|
61
|
+
[choose_smallest_formula(formulas)]
|
62
|
+
end
|
63
|
+
|
64
|
+
def default_way(formulas)
|
65
|
+
size_limited_formulas = filter_by_size_limit(formulas)
|
66
|
+
raise_size_limit_error if size_limited_formulas.empty?
|
67
|
+
newest(size_limited_formulas)
|
68
|
+
end
|
69
|
+
|
70
|
+
def contain_different_styles?(formulas)
|
71
|
+
styles_by_formula = formulas.map do |formula|
|
72
|
+
fonts = formula.fonts_by_name(@font_name)
|
73
|
+
styles = fonts.flat_map do |font|
|
74
|
+
font.styles.map(&:type)
|
75
|
+
end
|
76
|
+
|
77
|
+
styles.uniq.sort
|
78
|
+
end
|
79
|
+
|
80
|
+
styles_by_formula.uniq.size > 1
|
81
|
+
end
|
82
|
+
|
83
|
+
def filter_by_size_limit(formulas)
|
84
|
+
formulas.select do |formula|
|
85
|
+
formula.file_size.nil? || formula.file_size < size_limit_in_bytes
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def size_limit_in_bytes
|
90
|
+
@size_limit_in_bytes ||= @size_limit * 1024 * 1024
|
91
|
+
end
|
92
|
+
|
93
|
+
def raise_size_limit_error
|
94
|
+
raise Errors::SizeLimitError,
|
95
|
+
"There are only formulas above the size limit " \
|
96
|
+
"(#{@size_limit} MB)."
|
97
|
+
end
|
98
|
+
|
99
|
+
def filter_by_max_version(formulas)
|
100
|
+
formulas_with_version = detect_formula_version(formulas)
|
101
|
+
max_version = formulas_with_version.map(&:first).max
|
102
|
+
formulas_with_version.select do |version, _formula|
|
103
|
+
version == max_version
|
104
|
+
end.map(&:last)
|
105
|
+
end
|
106
|
+
|
107
|
+
def detect_formula_version(formulas)
|
108
|
+
formulas.map do |formula|
|
109
|
+
fonts = formula.fonts_by_name(@font_name)
|
110
|
+
versions = fonts.flat_map do |font|
|
111
|
+
font.styles.map do |style|
|
112
|
+
StyleVersion.new(style.version)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
[versions.max, formula]
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def choose_smallest_formula(formulas)
|
121
|
+
formulas.min_by do |formula|
|
122
|
+
formula.file_size || 0
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -73,7 +73,7 @@ module Fontist
|
|
73
73
|
end
|
74
74
|
|
75
75
|
def resource_options_without_sha
|
76
|
-
{ urls: [@url] + mirrors }
|
76
|
+
{ urls: [@url] + mirrors, file_size: file_size }
|
77
77
|
end
|
78
78
|
|
79
79
|
def resource_options_with_sha
|
@@ -86,7 +86,7 @@ module Fontist
|
|
86
86
|
|
87
87
|
sha = prepare_sha256(sha)
|
88
88
|
|
89
|
-
{ urls: urls, sha256: sha }
|
89
|
+
{ urls: urls, sha256: sha, file_size: file_size }
|
90
90
|
end
|
91
91
|
|
92
92
|
def downloads
|
@@ -120,6 +120,10 @@ module Fontist
|
|
120
120
|
output
|
121
121
|
end
|
122
122
|
|
123
|
+
def file_size
|
124
|
+
File.size(@archive)
|
125
|
+
end
|
126
|
+
|
123
127
|
def font_collections
|
124
128
|
return if @font_collection_files.empty?
|
125
129
|
|
@@ -9,7 +9,10 @@ module Fontist
|
|
9
9
|
|
10
10
|
def add_formula(formula)
|
11
11
|
formula.fonts.each do |font|
|
12
|
-
|
12
|
+
font.styles.each do |style|
|
13
|
+
font_name = style.default_family_name || font.name
|
14
|
+
add_index_formula(font_name, formula.to_index_formula)
|
15
|
+
end
|
13
16
|
end
|
14
17
|
end
|
15
18
|
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Fontist
|
2
|
+
class StyleVersion
|
3
|
+
def initialize(text)
|
4
|
+
@text = text
|
5
|
+
end
|
6
|
+
|
7
|
+
def value
|
8
|
+
@value ||= numbers || default_value
|
9
|
+
end
|
10
|
+
|
11
|
+
def numbers
|
12
|
+
string_version&.split(".")&.map(&:strip)
|
13
|
+
end
|
14
|
+
|
15
|
+
def string_version
|
16
|
+
@text&.split(";")&.first
|
17
|
+
end
|
18
|
+
|
19
|
+
def default_value
|
20
|
+
["0"]
|
21
|
+
end
|
22
|
+
|
23
|
+
def <=>(other)
|
24
|
+
value <=> other.value
|
25
|
+
end
|
26
|
+
|
27
|
+
def ==(other)
|
28
|
+
value == other.value
|
29
|
+
end
|
30
|
+
|
31
|
+
def eql?(other)
|
32
|
+
value.eql?(other.value)
|
33
|
+
end
|
34
|
+
|
35
|
+
def hash
|
36
|
+
value.hash
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/fontist/version.rb
CHANGED
data/lib/fontist.rb
CHANGED
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: 1.
|
4
|
+
version: 1.13.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ribose Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-12-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: down
|
@@ -304,6 +304,7 @@ files:
|
|
304
304
|
- lib/fontist/font_installer.rb
|
305
305
|
- lib/fontist/font_path.rb
|
306
306
|
- lib/fontist/formula.rb
|
307
|
+
- lib/fontist/formula_picker.rb
|
307
308
|
- lib/fontist/google_cli.rb
|
308
309
|
- lib/fontist/helpers.rb
|
309
310
|
- lib/fontist/import.rb
|
@@ -346,6 +347,7 @@ files:
|
|
346
347
|
- lib/fontist/manifest/locations.rb
|
347
348
|
- lib/fontist/repo.rb
|
348
349
|
- lib/fontist/repo_cli.rb
|
350
|
+
- lib/fontist/style_version.rb
|
349
351
|
- lib/fontist/system.yml
|
350
352
|
- lib/fontist/system_font.rb
|
351
353
|
- lib/fontist/system_index.rb
|