fontist 1.12.0 → 1.13.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|