fontist 1.9.0 → 1.11.1

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.
data/README.md CHANGED
@@ -399,16 +399,20 @@ bin/rspec
399
399
  All formulas are kept in the [formulas][fontist-formulas] repository. If you'd
400
400
  like to add a new one or change any existing, please refer to its documentation.
401
401
 
402
- ### Privare repos
402
+ ### Private repos
403
403
 
404
404
  There is an ability to use private fonts via private fontist repo. Fontist repo
405
405
  is a git repo which contains YAML formula files. Formulas can be created
406
406
  manually (see [examples](https://github.com/fontist/formulas/tree/master/Formulas)),
407
407
  or [auto-generated from an archive](#auto-generate-a-formula).
408
408
 
409
- A corresponding SSH key should be setup with ssh-agent in order to access this private repo.
409
+ A repo can be either HTTPS or SSH Git repo. In case of SSH, a corresponding SSH key
410
+ should be setup with ssh-agent in order to access this private repo.
410
411
 
411
- Private fontist repo can be set up with:
412
+ The `repo setup` command fetches a repo's formulas, and saves repo's name and url
413
+ for later use.
414
+
415
+ Internally all repos are stored at `~/.fontist/formulas/Formulas/private`.
412
416
 
413
417
  ```sh
414
418
  fontist repo setup NAME URL
@@ -418,15 +422,24 @@ E.g.
418
422
 
419
423
  ```sh
420
424
  fontist repo setup acme https://example.com/acme/formulas.git
425
+ # or
426
+ fontist repo setup acme git@example.com:acme/formulas.git
427
+ ```
428
+
429
+ Then you can just install fonts from this repo:
430
+
431
+ ```sh
432
+ fontist install "private font"
421
433
  ```
422
434
 
423
- Later, to fetch changes the following command can be used:
435
+ There is no need in any additional command to be run, but if you add new
436
+ formulas to your repo, you can fetch them with the `repo update` command:
424
437
 
425
438
  ```sh
426
439
  fontist repo update acme
427
440
  ```
428
441
 
429
- If there is a need to avoid using these formulas, the repo can be removed with:
442
+ If there is a need to avoid using private formulas, the repo can be removed with:
430
443
 
431
444
  ```sh
432
445
  fontist repo remove acme
@@ -511,6 +524,18 @@ git commit -m "SIL fonts update"
511
524
  git push
512
525
  ```
513
526
 
527
+ ### Using with proxy
528
+
529
+ `fontist` can read proxy settings from environemnt variables:
530
+
531
+ * `HTTP_PROXY`
532
+ * `SOCKS_PROXY`
533
+
534
+ Also because `fontist` uses git under the hood, proxy must be configured in `~/.gitconfig` separately.
535
+ Check [nice guide](https://gist.github.com/evantoli/f8c23a37eb3558ab8765) about how it can be configured for more details
536
+
537
+ Also as for regular URL you can pass username and password, like `http://username:password@example.com/` for SOCKS it's similar
538
+
514
539
  ### Releasing
515
540
 
516
541
  Releasing is done automatically with GitHub Action. Just bump and tag with `gem-release`.
data/exe/fontist CHANGED
@@ -3,5 +3,27 @@
3
3
  require "fontist"
4
4
  require "fontist/cli"
5
5
 
6
- status_code = Fontist::CLI.start(ARGV)
7
- exit status_code.is_a?(Integer) ? status_code : 1
6
+ fontist_cli = proc {
7
+ status_code = Fontist::CLI.start(ARGV)
8
+ exit status_code.is_a?(Integer) ? status_code : 1
9
+ }
10
+
11
+ if ENV["SOCKS_PROXY"]
12
+ require "socksify"
13
+ require "uri"
14
+ begin
15
+ proxy = URI.parse(ENV["SOCKS_PROXY"])
16
+ if proxy.userinfo
17
+ user, pass = proxy.userinfo.split(":")
18
+ TCPSocket::socks_username = user
19
+ TCPSocket::socks_password = pass
20
+ end
21
+ Socksify::proxy(proxy.host, proxy.port, &fontist_cli)
22
+ rescue URI::InvalidURIError
23
+ warn "Value of ENV.SOCKS_PROXY=#{ENV['SOCKS_PROXY']} is invalid! Droping it"
24
+ ENV.delete("SOCKS_PROXY")
25
+ fontist_cli.call
26
+ end
27
+ else
28
+ fontist_cli.call
29
+ end
data/fontist.gemspec CHANGED
@@ -44,4 +44,6 @@ Gem::Specification.new do |spec|
44
44
  spec.add_development_dependency "rubocop-rails"
45
45
  spec.add_development_dependency "rubocop-performance"
46
46
  spec.add_development_dependency "ruby-protocol-buffers", "~> 1.0"
47
+
48
+ spec.add_runtime_dependency "socksify"
47
49
  end
data/lib/fontist.rb CHANGED
@@ -11,7 +11,6 @@ require "fontist/repo"
11
11
  require "fontist/font"
12
12
  require "fontist/formula"
13
13
  require "fontist/system_font"
14
- require "fontist/fontist_font"
15
14
  require "fontist/manifest"
16
15
  require "fontist/helpers"
17
16
 
@@ -65,15 +64,32 @@ module Fontist
65
64
  end
66
65
 
67
66
  def self.system_index_path
68
- Fontist.fontist_path.join("system_index.yml")
67
+ Fontist.fontist_path.join("system_index.default_family.yml")
68
+ end
69
+
70
+ def self.system_preferred_family_index_path
71
+ Fontist.fontist_path.join("system_index.preferred_family.yml")
72
+ end
73
+
74
+ def self.fontist_index_path
75
+ Fontist.fontist_path.join("fontist_index.default_family.yml")
76
+ end
77
+
78
+ def self.fontist_preferred_family_index_path
79
+ Fontist.fontist_path.join("fontist_index.preferred_family.yml")
69
80
  end
70
81
 
71
82
  def self.formula_index_path
72
- @formula_index_path || Fontist.formula_index_dir.join("formula_index.yml")
83
+ Fontist.formula_index_dir.join("formula_index.default_family.yml")
73
84
  end
74
85
 
75
- def self.formula_index_path=(path)
76
- @formula_index_path = path
86
+ def self.formula_preferred_family_index_path
87
+ @formula_preferred_family_index_path ||
88
+ Fontist.formula_index_dir.join("formula_index.preferred_family.yml")
89
+ end
90
+
91
+ def self.formula_preferred_family_index_path=(path)
92
+ @formula_preferred_family_index_path = path
77
93
  end
78
94
 
79
95
  def self.formula_filename_index_path
@@ -88,4 +104,12 @@ module Fontist
88
104
  def self.formula_index_dir
89
105
  Fontist.fontist_path
90
106
  end
107
+
108
+ def self.preferred_family?
109
+ !!@preferred_family
110
+ end
111
+
112
+ def self.preferred_family=(bool)
113
+ @preferred_family = bool
114
+ end
91
115
  end
data/lib/fontist/cli.rb CHANGED
@@ -13,6 +13,7 @@ module Fontist
13
13
  STATUS_FONT_INDEX_CORRUPTED = 7
14
14
  STATUS_REPO_NOT_FOUND = 8
15
15
  STATUS_MAIN_REPO_NOT_FOUND = 9
16
+ STATUS_REPO_COULD_NOT_BE_UPDATED = 10
16
17
 
17
18
  ERROR_TO_STATUS = {
18
19
  Fontist::Errors::UnsupportedFontError => [STATUS_NON_SUPPORTED_FONT_ERROR],
@@ -31,6 +32,10 @@ module Fontist
31
32
  false
32
33
  end
33
34
 
35
+ class_option :preferred_family,
36
+ type: :boolean,
37
+ desc: "Use Preferred Family when available"
38
+
34
39
  desc "install FONT", "Install font"
35
40
  option :force, type: :boolean, aliases: :f,
36
41
  desc: "Install even if it's already installed in system"
@@ -38,6 +43,7 @@ module Fontist
38
43
  option :hide_licenses, type: :boolean, desc: "Hide license texts"
39
44
  option :no_progress, type: :boolean, desc: "Hide download progress"
40
45
  def install(font)
46
+ handle_class_options(options)
41
47
  Fontist::Font.install(
42
48
  font,
43
49
  force: options[:force],
@@ -52,6 +58,7 @@ module Fontist
52
58
 
53
59
  desc "uninstall/remove FONT", "Uninstall font by font or formula"
54
60
  def uninstall(font)
61
+ handle_class_options(options)
55
62
  fonts_paths = Fontist::Font.uninstall(font)
56
63
  Fontist.ui.success("These fonts are removed:")
57
64
  Fontist.ui.success(fonts_paths.join("\n"))
@@ -63,6 +70,7 @@ module Fontist
63
70
 
64
71
  desc "status [FONT]", "Show paths of FONT or all fonts"
65
72
  def status(font = nil)
73
+ handle_class_options(options)
66
74
  paths = Fontist::Font.status(font)
67
75
  return error("No font is installed.", STATUS_MISSING_FONT_ERROR) if paths.empty?
68
76
 
@@ -73,6 +81,7 @@ module Fontist
73
81
 
74
82
  desc "list [FONT]", "List installation status of FONT or fonts in fontist"
75
83
  def list(font = nil)
84
+ handle_class_options(options)
76
85
  formulas = Fontist::Font.list(font)
77
86
  print_list(formulas)
78
87
  success
@@ -82,14 +91,19 @@ module Fontist
82
91
 
83
92
  desc "update", "Update formulas"
84
93
  def update
94
+ handle_class_options(options)
85
95
  Formula.update_formulas_repo
86
- Fontist.ui.say("Formulas have been successfully updated")
96
+ Fontist.ui.success("Formulas have been successfully updated.")
87
97
  success
98
+ rescue Fontist::Errors::RepoCouldNotBeUpdatedError => e
99
+ Fontist.ui.error(e.message)
100
+ STATUS_REPO_COULD_NOT_BE_UPDATED
88
101
  end
89
102
 
90
103
  desc "manifest-locations MANIFEST",
91
104
  "Get locations of fonts from MANIFEST (yaml)"
92
105
  def manifest_locations(manifest)
106
+ handle_class_options(options)
93
107
  paths = Fontist::Manifest::Locations.from_file(manifest)
94
108
  print_yaml(paths)
95
109
  success
@@ -101,6 +115,7 @@ module Fontist
101
115
  option :accept_all_licenses, type: :boolean, aliases: "--confirm-license", desc: "Accept all license agreements"
102
116
  option :hide_licenses, type: :boolean, desc: "Hide license texts"
103
117
  def manifest_install(manifest)
118
+ handle_class_options(options)
104
119
  paths = Fontist::Manifest::Install.from_file(
105
120
  manifest,
106
121
  confirmation: options[:accept_all_licenses] ? "yes" : "no",
@@ -120,6 +135,7 @@ module Fontist
120
135
  option :subdir, desc: "Subdirectory to take fonts from, starting with the " \
121
136
  "root dir, e.g.: stixfonts-2.10/fonts/static_otf. May include `fnmatch` patterns."
122
137
  def create_formula(url)
138
+ handle_class_options(options)
123
139
  require "fontist/import/create_formula"
124
140
  name = Fontist::Import::CreateFormula.new(url, options).call
125
141
  Fontist.ui.say("#{name} formula has been successfully created")
@@ -137,6 +153,8 @@ module Fontist
137
153
  desc: "Updates indexes in the main repo (for backward " \
138
154
  "compatibility with versions prior to 1.9)"
139
155
  def rebuild_index
156
+ handle_class_options(options)
157
+
140
158
  if options[:main_repo]
141
159
  Fontist::Index.rebuild_for_main_repo
142
160
  else
@@ -149,6 +167,7 @@ module Fontist
149
167
 
150
168
  desc "import-sil", "Import formulas from SIL"
151
169
  def import_sil
170
+ handle_class_options(options)
152
171
  require "fontist/import/sil_import"
153
172
  Fontist::Import::SilImport.new.call
154
173
  end
@@ -158,6 +177,10 @@ module Fontist
158
177
 
159
178
  private
160
179
 
180
+ def handle_class_options(options)
181
+ Fontist.preferred_family = options[:preferred_family]
182
+ end
183
+
161
184
  def success
162
185
  STATUS_SUCCESS
163
186
  end
@@ -26,6 +26,8 @@ module Fontist
26
26
 
27
27
  class RepoNotFoundError < GeneralError; end
28
28
 
29
+ class RepoCouldNotBeUpdatedError < GeneralError; end
30
+
29
31
  class TamperedFileError < GeneralError; end
30
32
 
31
33
  class TimeoutError < GeneralError; end
data/lib/fontist/font.rb CHANGED
@@ -166,7 +166,7 @@ module Fontist
166
166
  end
167
167
 
168
168
  def uninstall_font
169
- paths = find_fontist_font
169
+ paths = find_fontist_paths
170
170
  return unless paths
171
171
 
172
172
  paths.each do |path|
@@ -176,8 +176,13 @@ module Fontist
176
176
  paths
177
177
  end
178
178
 
179
- def find_fontist_font
180
- Fontist::FontistFont.find(name)
179
+ def find_fontist_paths
180
+ fonts = Fontist::SystemIndex.fontist_index.find(name, nil)
181
+ return unless fonts
182
+
183
+ fonts.map do |font|
184
+ font[:path]
185
+ end
181
186
  end
182
187
 
183
188
  def installed_paths
@@ -1,22 +1,12 @@
1
1
  require "fontist/index"
2
2
  require "fontist/helpers"
3
+ require "fontist/update"
3
4
  require "git"
4
5
 
5
6
  module Fontist
6
7
  class Formula
7
8
  def self.update_formulas_repo
8
- dir = File.dirname(Fontist.formulas_repo_path)
9
- FileUtils.mkdir_p(dir) unless File.exist?(dir)
10
-
11
- if Dir.exist?(Fontist.formulas_repo_path)
12
- Git.open(Fontist.formulas_repo_path).pull
13
- else
14
- Git.clone(Fontist.formulas_repo_url,
15
- Fontist.formulas_repo_path,
16
- depth: 1)
17
- end
18
-
19
- Index.rebuild
9
+ Update.call
20
10
  end
21
11
 
22
12
  def self.all
@@ -11,7 +11,7 @@ module Fontist
11
11
  def initialize(path)
12
12
  @path = path
13
13
  @fonts = read
14
- @extension = "ttc"
14
+ @extension = detect_extension
15
15
  end
16
16
 
17
17
  def filename
@@ -46,6 +46,15 @@ module Fontist
46
46
  File.join(tmp_dir, filename)
47
47
  end
48
48
  end
49
+
50
+ def detect_extension
51
+ base_extension = "ttc"
52
+
53
+ file_extension = File.extname(File.basename(@path)).sub(/^\./, "")
54
+ return file_extension if file_extension.casecmp?(base_extension)
55
+
56
+ base_extension
57
+ end
49
58
  end
50
59
  end
51
60
  end
@@ -1,3 +1,4 @@
1
+ require "shellwords"
1
2
  require_relative "text_helper"
2
3
 
3
4
  module Fontist
@@ -5,7 +6,7 @@ module Fontist
5
6
  class FormulaBuilder
6
7
  FORMULA_ATTRIBUTES = %i[name description homepage resources
7
8
  font_collections fonts extract copyright
8
- license_url open_license].freeze
9
+ license_url open_license command].freeze
9
10
 
10
11
  attr_accessor :archive,
11
12
  :url,
@@ -49,7 +50,7 @@ module Fontist
49
50
  end
50
51
 
51
52
  def homepage
52
- both_fonts.first.homepage
53
+ both_fonts.map(&:homepage).compact.first
53
54
  end
54
55
 
55
56
  def resources
@@ -129,7 +130,7 @@ module Fontist
129
130
 
130
131
  fonts = groups.map do |name, group|
131
132
  { name: name,
132
- styles: group.map(&style_type) }
133
+ styles: styles_from_files(group, style_type) }
133
134
  end
134
135
 
135
136
  fonts.sort_by do |x|
@@ -137,16 +138,20 @@ module Fontist
137
138
  end
138
139
  end
139
140
 
141
+ def styles_from_files(files, style_type)
142
+ files.map(&style_type).sort_by { |x| x[:type] }
143
+ end
144
+
140
145
  def extract
141
146
  @extractor.operations
142
147
  end
143
148
 
144
149
  def copyright
145
- both_fonts.first.copyright
150
+ both_fonts.map(&:copyright).compact.first
146
151
  end
147
152
 
148
153
  def license_url
149
- both_fonts.first.license_url
154
+ both_fonts.map(&:license_url).compact.first
150
155
  end
151
156
 
152
157
  def open_license
@@ -161,6 +166,10 @@ module Fontist
161
166
 
162
167
  TextHelper.cleanup(@license_text)
163
168
  end
169
+
170
+ def command
171
+ Shellwords.shelljoin(ARGV)
172
+ end
164
173
  end
165
174
  end
166
175
  end
@@ -156,6 +156,10 @@ module Fontist
156
156
  h.merge!(family_name: style.family_name,
157
157
  type: style.style,
158
158
  full_name: style.full_name)
159
+ if style.preferred_family_name
160
+ h[:preferred_family_name] = style.preferred_family_name
161
+ end
162
+ h[:preferred_type] = style.preferred_style if style.preferred_style
159
163
  h.merge!(style.to_h.select do |k, _|
160
164
  %i(post_script_name version description copyright).include?(k)
161
165
  end.compact)
@@ -10,7 +10,8 @@ module Fontist
10
10
  otfinfo: Otfinfo::OtfinfoRequirement.new,
11
11
  }.freeze
12
12
 
13
- STYLE_ATTRIBUTES = %i[family_name type full_name post_script_name
13
+ STYLE_ATTRIBUTES = %i[family_name type preferred_family_name
14
+ preferred_type full_name post_script_name
14
15
  version description copyright font
15
16
  source_font].freeze
16
17
 
@@ -35,11 +36,19 @@ module Fontist
35
36
  end
36
37
 
37
38
  def family_name
38
- info["Preferred family"] || info["Family"]
39
+ info["Family"]
39
40
  end
40
41
 
41
42
  def type
42
- info["Preferred subfamily"] || info["Subfamily"]
43
+ info["Subfamily"]
44
+ end
45
+
46
+ def preferred_family_name
47
+ info["Preferred family"]
48
+ end
49
+
50
+ def preferred_type
51
+ info["Preferred subfamily"]
43
52
  end
44
53
 
45
54
  def full_name
@@ -97,7 +106,11 @@ module Fontist
97
106
  end
98
107
 
99
108
  def detect_extension
100
- Files::FontDetector.standard_extension(@path)
109
+ detected = Files::FontDetector.standard_extension(@path)
110
+ file_extension = File.extname(File.basename(@path)).sub(/^\./, "")
111
+ return file_extension if file_extension.casecmp?(detected)
112
+
113
+ detected
101
114
  end
102
115
  end
103
116
  end