fontist 1.9.0 → 1.11.1

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