fontist 1.8.13 → 1.10.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/metanorma.yml +2 -2
- data/.github/workflows/rspec.yml +1 -1
- data/README.adoc +758 -0
- data/README.md +83 -7
- data/exe/fontist +24 -2
- data/fontist.gemspec +3 -1
- data/lib/fontist.rb +51 -5
- data/lib/fontist/cli.rb +45 -4
- data/lib/fontist/errors.rb +20 -0
- data/lib/fontist/font.rb +10 -5
- data/lib/fontist/font_installer.rb +3 -2
- data/lib/fontist/formula.rb +2 -7
- data/lib/fontist/import/formula_builder.rb +5 -1
- data/lib/fontist/import/google_import.rb +4 -0
- data/lib/fontist/import/otf/font_file.rb +12 -3
- data/lib/fontist/import/otf_style.rb +10 -2
- data/lib/fontist/import/otfinfo/template.erb +6 -0
- data/lib/fontist/index.rb +33 -2
- data/lib/fontist/indexes/base_index.rb +8 -2
- data/lib/fontist/indexes/default_family_font_index.rb +21 -0
- data/lib/fontist/indexes/font_index.rb +8 -13
- data/lib/fontist/indexes/preferred_family_font_index.rb +24 -0
- data/lib/fontist/repo.rb +60 -0
- data/lib/fontist/repo_cli.rb +51 -0
- data/lib/fontist/system_font.rb +6 -11
- data/lib/fontist/system_index.rb +106 -26
- data/lib/fontist/update.rb +64 -0
- data/lib/fontist/utils/downloader.rb +14 -2
- data/lib/fontist/utils/locking.rb +1 -0
- data/lib/fontist/version.rb +1 -1
- metadata +27 -8
- data/lib/fontist/fontist_font.rb +0 -24
data/README.md
CHANGED
@@ -399,6 +399,70 @@ 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
|
+
### Private repos
|
403
|
+
|
404
|
+
There is an ability to use private fonts via private fontist repo. Fontist repo
|
405
|
+
is a git repo which contains YAML formula files. Formulas can be created
|
406
|
+
manually (see [examples](https://github.com/fontist/formulas/tree/master/Formulas)),
|
407
|
+
or [auto-generated from an archive](#auto-generate-a-formula).
|
408
|
+
|
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.
|
411
|
+
|
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`.
|
416
|
+
|
417
|
+
```sh
|
418
|
+
fontist repo setup NAME URL
|
419
|
+
```
|
420
|
+
|
421
|
+
E.g.
|
422
|
+
|
423
|
+
```sh
|
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"
|
433
|
+
```
|
434
|
+
|
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:
|
437
|
+
|
438
|
+
```sh
|
439
|
+
fontist repo update acme
|
440
|
+
```
|
441
|
+
|
442
|
+
If there is a need to avoid using private formulas, the repo can be removed with:
|
443
|
+
|
444
|
+
```sh
|
445
|
+
fontist repo remove acme
|
446
|
+
```
|
447
|
+
|
448
|
+
### Private formulas
|
449
|
+
|
450
|
+
Authorization of private archives in private formulas can be implemented with
|
451
|
+
headers. Here is an example which works with Github releases:
|
452
|
+
|
453
|
+
```yaml
|
454
|
+
resources:
|
455
|
+
fonts.zip:
|
456
|
+
urls:
|
457
|
+
- url: https://example.com/repos/acme/formulas/releases/assets/38777461
|
458
|
+
headers:
|
459
|
+
Accept: application/octet-stream
|
460
|
+
Authorization: token ghp_1234567890abcdefghi
|
461
|
+
```
|
462
|
+
|
463
|
+
A token can be obtained on [this page](https://github.com/settings/tokens).
|
464
|
+
It should have at least the `repo` scope.
|
465
|
+
|
402
466
|
### Auto-generate a formula
|
403
467
|
|
404
468
|
A formula could be generated from a fonts archive. Just specify a URL to the
|
@@ -409,20 +473,21 @@ fontist create-formula https://www.latofonts.com/download/lato2ofl-zip/
|
|
409
473
|
cp lato.yml ~/.fontist/formulas/Formulas/
|
410
474
|
```
|
411
475
|
|
476
|
+
Though indexes are auto-generated now, maintainers should rebuild indexes
|
477
|
+
in the main repo for backward compatibility with fontist prior to 1.9.x versions.
|
412
478
|
A formula index should be rebuild, when a new formula is generated or an
|
413
479
|
existing one changed:
|
414
480
|
|
415
481
|
```sh
|
416
|
-
fontist rebuild-index
|
482
|
+
fontist rebuild-index --main-repo
|
417
483
|
```
|
418
484
|
|
419
|
-
Then, both the formula and the updated
|
485
|
+
Then, both the formula and the updated indexes should be commited and pushed to
|
420
486
|
the formula repository:
|
421
487
|
|
422
488
|
```sh
|
423
489
|
cd ~/.fontist/formulas
|
424
|
-
git add Formulas/lato.yml
|
425
|
-
git add index.yml
|
490
|
+
git add Formulas/lato.yml index.yml filename_index.yml
|
426
491
|
git commit -m "Add Lato formula"
|
427
492
|
```
|
428
493
|
|
@@ -441,7 +506,7 @@ repository [formulas][fontist-formulas]:
|
|
441
506
|
|
442
507
|
```
|
443
508
|
cd ~/.fontist/formulas
|
444
|
-
git add Formulas/google
|
509
|
+
git add Formulas/google index.yml filename_index.yml
|
445
510
|
git commit -m "Google Fonts update"
|
446
511
|
git push
|
447
512
|
```
|
@@ -454,12 +519,23 @@ can be updated with:
|
|
454
519
|
```sh
|
455
520
|
fontist import-sil
|
456
521
|
cd ~/.fontist/formulas
|
457
|
-
git add Formulas/sil
|
458
|
-
git add index.yml
|
522
|
+
git add Formulas/sil index.yml filename_index.yml
|
459
523
|
git commit -m "SIL fonts update"
|
460
524
|
git push
|
461
525
|
```
|
462
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
|
+
|
463
539
|
### Releasing
|
464
540
|
|
465
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
|
-
|
7
|
-
|
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
@@ -40,8 +40,10 @@ Gem::Specification.new do |spec|
|
|
40
40
|
spec.add_development_dependency "nokogiri", "~> 1.0"
|
41
41
|
spec.add_development_dependency "rake", "~> 13"
|
42
42
|
spec.add_development_dependency "rspec", "~> 3.0"
|
43
|
-
spec.add_development_dependency "rubocop", "
|
43
|
+
spec.add_development_dependency "rubocop", "1.5.2"
|
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
@@ -7,10 +7,10 @@ require "singleton"
|
|
7
7
|
require "fontist/errors"
|
8
8
|
require "fontist/version"
|
9
9
|
|
10
|
+
require "fontist/repo"
|
10
11
|
require "fontist/font"
|
11
12
|
require "fontist/formula"
|
12
13
|
require "fontist/system_font"
|
13
|
-
require "fontist/fontist_font"
|
14
14
|
require "fontist/manifest"
|
15
15
|
require "fontist/helpers"
|
16
16
|
|
@@ -28,7 +28,11 @@ module Fontist
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def self.fontist_path
|
31
|
-
Pathname.new(ENV["FONTIST_PATH"] ||
|
31
|
+
Pathname.new(ENV["FONTIST_PATH"] || default_fontist_path)
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.default_fontist_path
|
35
|
+
Pathname.new(File.join(Dir.home, ".fontist"))
|
32
36
|
end
|
33
37
|
|
34
38
|
def self.fonts_path
|
@@ -47,6 +51,10 @@ module Fontist
|
|
47
51
|
Fontist.formulas_repo_path.join("Formulas")
|
48
52
|
end
|
49
53
|
|
54
|
+
def self.private_formulas_path
|
55
|
+
Fontist.formulas_path.join("private")
|
56
|
+
end
|
57
|
+
|
50
58
|
def self.downloads_path
|
51
59
|
Fontist.fontist_path.join("downloads")
|
52
60
|
end
|
@@ -56,14 +64,52 @@ module Fontist
|
|
56
64
|
end
|
57
65
|
|
58
66
|
def self.system_index_path
|
59
|
-
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")
|
60
80
|
end
|
61
81
|
|
62
82
|
def self.formula_index_path
|
63
|
-
Fontist.
|
83
|
+
Fontist.formula_index_dir.join("formula_index.default_family.yml")
|
84
|
+
end
|
85
|
+
|
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
|
64
93
|
end
|
65
94
|
|
66
95
|
def self.formula_filename_index_path
|
67
|
-
|
96
|
+
@formula_filename_index_path ||
|
97
|
+
Fontist.formula_index_dir.join("filename_index.yml")
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.formula_filename_index_path=(path)
|
101
|
+
@formula_filename_index_path = path
|
102
|
+
end
|
103
|
+
|
104
|
+
def self.formula_index_dir
|
105
|
+
Fontist.fontist_path
|
106
|
+
end
|
107
|
+
|
108
|
+
def self.preferred_family?
|
109
|
+
!!@preferred_family
|
110
|
+
end
|
111
|
+
|
112
|
+
def self.preferred_family=(bool)
|
113
|
+
@preferred_family = bool
|
68
114
|
end
|
69
115
|
end
|
data/lib/fontist/cli.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require "thor"
|
2
|
+
require "fontist/repo_cli"
|
2
3
|
|
3
4
|
module Fontist
|
4
5
|
class CLI < Thor
|
@@ -10,6 +11,9 @@ module Fontist
|
|
10
11
|
STATUS_MANIFEST_COULD_NOT_BE_FOUND_ERROR = 5
|
11
12
|
STATUS_MANIFEST_COULD_NOT_BE_READ_ERROR = 6
|
12
13
|
STATUS_FONT_INDEX_CORRUPTED = 7
|
14
|
+
STATUS_REPO_NOT_FOUND = 8
|
15
|
+
STATUS_MAIN_REPO_NOT_FOUND = 9
|
16
|
+
STATUS_REPO_COULD_NOT_BE_UPDATED = 10
|
13
17
|
|
14
18
|
ERROR_TO_STATUS = {
|
15
19
|
Fontist::Errors::UnsupportedFontError => [STATUS_NON_SUPPORTED_FONT_ERROR],
|
@@ -20,12 +24,18 @@ module Fontist
|
|
20
24
|
Fontist::Errors::ManifestCouldNotBeReadError => [STATUS_MANIFEST_COULD_NOT_BE_READ_ERROR,
|
21
25
|
"Manifest could not be read."],
|
22
26
|
Fontist::Errors::FontIndexCorrupted => [STATUS_FONT_INDEX_CORRUPTED],
|
27
|
+
Fontist::Errors::RepoNotFoundError => [STATUS_REPO_NOT_FOUND],
|
28
|
+
Fontist::Errors::MainRepoNotFoundError => [STATUS_MAIN_REPO_NOT_FOUND],
|
23
29
|
}.freeze
|
24
30
|
|
25
31
|
def self.exit_on_failure?
|
26
32
|
false
|
27
33
|
end
|
28
34
|
|
35
|
+
class_option :preferred_family,
|
36
|
+
type: :boolean,
|
37
|
+
desc: "Use Preferred Family when available"
|
38
|
+
|
29
39
|
desc "install FONT", "Install font"
|
30
40
|
option :force, type: :boolean, aliases: :f,
|
31
41
|
desc: "Install even if it's already installed in system"
|
@@ -33,6 +43,7 @@ module Fontist
|
|
33
43
|
option :hide_licenses, type: :boolean, desc: "Hide license texts"
|
34
44
|
option :no_progress, type: :boolean, desc: "Hide download progress"
|
35
45
|
def install(font)
|
46
|
+
handle_class_options(options)
|
36
47
|
Fontist::Font.install(
|
37
48
|
font,
|
38
49
|
force: options[:force],
|
@@ -47,6 +58,7 @@ module Fontist
|
|
47
58
|
|
48
59
|
desc "uninstall/remove FONT", "Uninstall font by font or formula"
|
49
60
|
def uninstall(font)
|
61
|
+
handle_class_options(options)
|
50
62
|
fonts_paths = Fontist::Font.uninstall(font)
|
51
63
|
Fontist.ui.success("These fonts are removed:")
|
52
64
|
Fontist.ui.success(fonts_paths.join("\n"))
|
@@ -58,6 +70,7 @@ module Fontist
|
|
58
70
|
|
59
71
|
desc "status [FONT]", "Show paths of FONT or all fonts"
|
60
72
|
def status(font = nil)
|
73
|
+
handle_class_options(options)
|
61
74
|
paths = Fontist::Font.status(font)
|
62
75
|
return error("No font is installed.", STATUS_MISSING_FONT_ERROR) if paths.empty?
|
63
76
|
|
@@ -68,6 +81,7 @@ module Fontist
|
|
68
81
|
|
69
82
|
desc "list [FONT]", "List installation status of FONT or fonts in fontist"
|
70
83
|
def list(font = nil)
|
84
|
+
handle_class_options(options)
|
71
85
|
formulas = Fontist::Font.list(font)
|
72
86
|
print_list(formulas)
|
73
87
|
success
|
@@ -77,14 +91,19 @@ module Fontist
|
|
77
91
|
|
78
92
|
desc "update", "Update formulas"
|
79
93
|
def update
|
94
|
+
handle_class_options(options)
|
80
95
|
Formula.update_formulas_repo
|
81
|
-
Fontist.ui.
|
96
|
+
Fontist.ui.success("Formulas have been successfully updated.")
|
82
97
|
success
|
98
|
+
rescue Fontist::Errors::RepoCouldNotBeUpdatedError => e
|
99
|
+
Fontist.ui.error(e.message)
|
100
|
+
STATUS_REPO_COULD_NOT_BE_UPDATED
|
83
101
|
end
|
84
102
|
|
85
103
|
desc "manifest-locations MANIFEST",
|
86
104
|
"Get locations of fonts from MANIFEST (yaml)"
|
87
105
|
def manifest_locations(manifest)
|
106
|
+
handle_class_options(options)
|
88
107
|
paths = Fontist::Manifest::Locations.from_file(manifest)
|
89
108
|
print_yaml(paths)
|
90
109
|
success
|
@@ -96,6 +115,7 @@ module Fontist
|
|
96
115
|
option :accept_all_licenses, type: :boolean, aliases: "--confirm-license", desc: "Accept all license agreements"
|
97
116
|
option :hide_licenses, type: :boolean, desc: "Hide license texts"
|
98
117
|
def manifest_install(manifest)
|
118
|
+
handle_class_options(options)
|
99
119
|
paths = Fontist::Manifest::Install.from_file(
|
100
120
|
manifest,
|
101
121
|
confirmation: options[:accept_all_licenses] ? "yes" : "no",
|
@@ -115,6 +135,7 @@ module Fontist
|
|
115
135
|
option :subdir, desc: "Subdirectory to take fonts from, starting with the " \
|
116
136
|
"root dir, e.g.: stixfonts-2.10/fonts/static_otf. May include `fnmatch` patterns."
|
117
137
|
def create_formula(url)
|
138
|
+
handle_class_options(options)
|
118
139
|
require "fontist/import/create_formula"
|
119
140
|
name = Fontist::Import::CreateFormula.new(url, options).call
|
120
141
|
Fontist.ui.say("#{name} formula has been successfully created")
|
@@ -123,23 +144,43 @@ module Fontist
|
|
123
144
|
|
124
145
|
desc "rebuild-index", "Rebuild formula index (used by formulas maintainers)"
|
125
146
|
long_desc <<-LONGDESC
|
126
|
-
|
127
|
-
|
147
|
+
Index should be rebuilt when any formula changes.
|
148
|
+
|
149
|
+
It is done automatically when formulas are updated, or private formulas
|
150
|
+
are set up.
|
128
151
|
LONGDESC
|
152
|
+
option :main_repo, type: :boolean,
|
153
|
+
desc: "Updates indexes in the main repo (for backward " \
|
154
|
+
"compatibility with versions prior to 1.9)"
|
129
155
|
def rebuild_index
|
130
|
-
|
156
|
+
handle_class_options(options)
|
157
|
+
|
158
|
+
if options[:main_repo]
|
159
|
+
Fontist::Index.rebuild_for_main_repo
|
160
|
+
else
|
161
|
+
Fontist::Index.rebuild
|
162
|
+
end
|
163
|
+
|
131
164
|
Fontist.ui.say("Formula index has been rebuilt.")
|
132
165
|
STATUS_SUCCESS
|
133
166
|
end
|
134
167
|
|
135
168
|
desc "import-sil", "Import formulas from SIL"
|
136
169
|
def import_sil
|
170
|
+
handle_class_options(options)
|
137
171
|
require "fontist/import/sil_import"
|
138
172
|
Fontist::Import::SilImport.new.call
|
139
173
|
end
|
140
174
|
|
175
|
+
desc "repo SUBCOMMAND ...ARGS", "Manage custom repositories"
|
176
|
+
subcommand "repo", Fontist::RepoCLI
|
177
|
+
|
141
178
|
private
|
142
179
|
|
180
|
+
def handle_class_options(options)
|
181
|
+
Fontist.preferred_family = options[:preferred_family]
|
182
|
+
end
|
183
|
+
|
143
184
|
def success
|
144
185
|
STATUS_SUCCESS
|
145
186
|
end
|
data/lib/fontist/errors.rb
CHANGED
@@ -3,17 +3,37 @@ module Fontist
|
|
3
3
|
class GeneralError < StandardError; end
|
4
4
|
|
5
5
|
class BinaryCallError < GeneralError; end
|
6
|
+
|
6
7
|
class FontIndexCorrupted < GeneralError; end
|
8
|
+
|
7
9
|
class FontNotFoundError < GeneralError; end
|
10
|
+
|
11
|
+
# for backward compatibility with metanorma,
|
12
|
+
# it depends on this exception to automatically download formulas
|
8
13
|
class FormulaIndexNotFoundError < GeneralError; end
|
14
|
+
|
15
|
+
class MainRepoNotFoundError < FormulaIndexNotFoundError; end
|
16
|
+
|
9
17
|
class InvalidResourceError < GeneralError; end
|
18
|
+
|
10
19
|
class LicensingError < GeneralError; end
|
20
|
+
|
11
21
|
class ManifestCouldNotBeFoundError < GeneralError; end
|
22
|
+
|
12
23
|
class ManifestCouldNotBeReadError < GeneralError; end
|
24
|
+
|
13
25
|
class MissingAttributeError < GeneralError; end
|
26
|
+
|
27
|
+
class RepoNotFoundError < GeneralError; end
|
28
|
+
|
29
|
+
class RepoCouldNotBeUpdatedError < GeneralError; end
|
30
|
+
|
14
31
|
class TamperedFileError < GeneralError; end
|
32
|
+
|
15
33
|
class TimeoutError < GeneralError; end
|
34
|
+
|
16
35
|
class UnknownFontTypeError < GeneralError; end
|
36
|
+
|
17
37
|
class UnknownArchiveError < GeneralError; end
|
18
38
|
|
19
39
|
class FontError < GeneralError
|