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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 709582759b1009bae25d302ab0590ed5f6fe92fe55d68d1cb57c918942b4f005
4
- data.tar.gz: 165f75a0625995d8fcc388d46a26168008383d98d2705cb1ea5ed519abe41e80
3
+ metadata.gz: 43f3bc7643cf7694fb753d9c62509f7134a26d68fb41a2e06c9c9e25f33ae2c5
4
+ data.tar.gz: 3269f7aedc78eed761697ff862701bf6ca27679e9be90972d8983e913a15beea
5
5
  SHA512:
6
- metadata.gz: fd3d62de512ff44e1d9b47c192889fdcefa5db9abea1f0966ac3d761c4ef5567fa547b7d57b4eda52720040d3ca82a03eec2e3d72b24d1f9522dbde1e092c625
7
- data.tar.gz: 3adf2dcebf7714cc81fc3a6955ac69fdf7affe3e90a845f011f52d284332c856112bef7f8e98cf6d96175c043df299ad0965148ef96308b38c6eace46547ef52
6
+ metadata.gz: a92d2d69bed9e8e33fc9785f198c9878d1a02dda4de65f290ecff30336adec6117cfd18cc09d52545f318a917b40e02b4d796049384b6b6c12fee05d2056283f
7
+ data.tar.gz: ffdb9a02c723a5a8c04c26c3f3d5a0d0bba4e875fd750bee67a3c68698d2f2e9057ff936019523d3eb9a359bbbf19de566c45acb99fff99b745952039add7e30
data/.rubocop.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  inherit_from:
2
2
  - 'https://raw.githubusercontent.com/fontist/oss-guides/master/ci/rubocop.yml'
3
3
 
4
- Rails:
5
- Enabled: false
4
+ AllCops:
5
+ SuggestExtensions: false
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, aliases: "--confirm-license", desc: "Accept all license agreements"
47
- option :hide_licenses, type: :boolean, desc: "Hide license texts"
48
- option :no_progress, type: :boolean, desc: "Hide download progress"
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
- Fontist::Font.install(
52
- font,
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
- error(message || exception.message, status)
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)
@@ -28,6 +28,8 @@ module Fontist
28
28
 
29
29
  class RepoCouldNotBeUpdatedError < GeneralError; end
30
30
 
31
+ class SizeLimitError < GeneralError; end
32
+
31
33
  class TamperedFileError < GeneralError; end
32
34
 
33
35
  class TimeoutError < GeneralError; end
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 downloadable_formulas.empty?
148
+ return if sufficient_formulas.empty?
134
149
 
135
- downloadable_formulas.flat_map do |formula|
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
 
@@ -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(hash_collection_fonts + hash_fonts)
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
- { "name" => font["name"],
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
- add_index_formula(font.name, formula.to_index_formula)
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
@@ -1,3 +1,3 @@
1
1
  module Fontist
2
- VERSION = "1.12.0".freeze
2
+ VERSION = "1.13.0".freeze
3
3
  end
data/lib/fontist.rb CHANGED
@@ -107,6 +107,10 @@ module Fontist
107
107
  Fontist.fontist_version_path
108
108
  end
109
109
 
110
+ def self.formula_size_limit_in_megabytes
111
+ 300
112
+ end
113
+
110
114
  def self.preferred_family?
111
115
  !!@preferred_family
112
116
  end
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.12.0
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-23 00:00:00.000000000 Z
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