fontist 1.8.10 → 1.9.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5a61fbcb4c7c4242df9816a14e4b38ef2a0653f2979d60351ff46e2afd534287
4
- data.tar.gz: 117b390025eb49b700213b9964aa7134c39d9945b1aed822e7b92e36295b750f
3
+ metadata.gz: 06c95de209b578a95a9b0d2bf19d196164ece01155a61685060c638af668743c
4
+ data.tar.gz: a2d621f546be67a09e94c4cad68f432642ec6c47d745c688e919652e3049ec7a
5
5
  SHA512:
6
- metadata.gz: c77e83a9a67f3782bbf4eb8c3d3de30ebb0db904c6429e6d83bc457e9651125acee7528b5503ab51fac3dfc6a4441e966cc8596aa70455dc1181f2c866f0cdae
7
- data.tar.gz: 1b542a3e06a395198277e5ac34d7615fa25f95bd7da1a3fcbd6e819a572871b3d0ca4ad51678859eeae180c0b76b586d6c815b1807ac82b3f79e703eef5bffde
6
+ metadata.gz: 938f320740216d01c7dc7e48b7a4a6070bba45d437be0e3b2c5846b3d1c28321967653b4b1ad13a6f112cab3e7ae72e74f708bd027022e875b2e4268693200bb
7
+ data.tar.gz: 602c750adddfc95ed2b7d83257a085b69c464c563ccbd314dc120f86c074d1e0aec243aacafba5bf4e73969ade9bc953b360764209db78fce7362102d1bff8fc
@@ -0,0 +1,35 @@
1
+ name: metanorma
2
+
3
+ on:
4
+ push:
5
+ branches: [ main ]
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ name: Test on Ruby ${{ matrix.ruby }} ${{ matrix.os }}
11
+ runs-on: ${{ matrix.os }}
12
+ continue-on-error: ${{ matrix.experimental }}
13
+ strategy:
14
+ fail-fast: false
15
+ matrix:
16
+ ruby: [ '2.5', '2.6', '2.7', '3.0' ]
17
+ os: [ ubuntu-latest, windows-latest, macos-latest ]
18
+ experimental: [ true ]
19
+ steps:
20
+ - uses: actions/checkout@master
21
+ with:
22
+ repository: metanorma/metanorma
23
+
24
+ - uses: actions/checkout@master
25
+ with:
26
+ path: "fontist"
27
+
28
+ - run: 'echo ''gem "fontist", path: "./fontist"'' > Gemfile.devel'
29
+
30
+ - uses: ruby/setup-ruby@v1
31
+ with:
32
+ ruby-version: ${{ matrix.ruby }}
33
+ bundler-cache: true
34
+
35
+ - run: bundle exec rake
@@ -2,7 +2,7 @@ name: rspec
2
2
 
3
3
  on:
4
4
  push:
5
- branches: [ master ]
5
+ branches: [ main ]
6
6
  pull_request:
7
7
 
8
8
  jobs:
@@ -13,19 +13,9 @@ jobs:
13
13
  strategy:
14
14
  fail-fast: false
15
15
  matrix:
16
- ruby: [ '2.4', '2.5', '2.6', '2.7' ]
16
+ ruby: [ '2.4', '2.5', '2.6', '2.7', '3.0' ]
17
17
  os: [ ubuntu-latest, windows-latest, macos-latest ]
18
18
  experimental: [ false ]
19
- # include:
20
- # - ruby: '3.0'
21
- # os: 'ubuntu-latest'
22
- # experimental: true
23
- # - ruby: '3.0'
24
- # os: 'windows-latest'
25
- # experimental: true
26
- # - ruby: '3.0'
27
- # os: 'macos-latest'
28
- # experimental: true
29
19
 
30
20
  steps:
31
21
  - uses: actions/checkout@master
@@ -33,20 +23,11 @@ jobs:
33
23
  - uses: ruby/setup-ruby@v1
34
24
  with:
35
25
  ruby-version: ${{ matrix.ruby }}
36
-
37
- - uses: actions/cache@v1
38
- with:
39
- path: vendor/bundle
40
- key: bundle-v2-${{ matrix.os }}-${{ matrix.ruby }}-${{ hashFiles('**/*.gemspec') }}
41
- restore-keys: bundle-v2-${{ matrix.os }}-${{ matrix.ruby }}
26
+ bundler-cache: true
42
27
 
43
28
  - if: matrix.os == 'macos-latest'
44
29
  run: brew install lcdf-typetools
45
30
 
46
- - run: bundle config set path 'vendor/bundle'
47
-
48
- - run: bundle install --jobs 4 --retry 3
49
-
50
31
  - if: matrix.os == 'macos-latest'
51
32
  run: bundle exec rspec
52
33
  env:
data/.rubocop.yml CHANGED
@@ -9,14 +9,14 @@ AllCops:
9
9
  Rails:
10
10
  Enabled: false
11
11
 
12
- Metrics/LineLength:
12
+ Layout/LineLength:
13
13
  Exclude:
14
14
  - 'lib/fontist/formulas/**/*.rb'
15
15
 
16
- Layout/IndentFirstHashElement:
16
+ Layout/FirstHashElementIndentation:
17
17
  Exclude:
18
18
  - 'lib/fontist/formulas/**/*.rb'
19
19
 
20
- Layout/IndentHeredoc:
20
+ Layout/HeredocIndentation:
21
21
  Exclude:
22
22
  - 'lib/fontist/formulas/**/*.rb'
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # Fontist
2
2
 
3
- ![windows](https://github.com/fontist/fontist/workflows/windows/badge.svg)
4
- ![macos](https://github.com/fontist/fontist/workflows/macos/badge.svg)
5
- ![ubuntu](https://github.com/fontist/fontist/workflows/ubuntu/badge.svg)
3
+ [![Build Status](https://github.com/fontist/fontist/actions/workflows/rspec.yml/badge.svg)](https://github.com/fontist/fontist/actions/workflows/rspec.yml)
4
+ [![Gem Version](https://img.shields.io/gem/v/fontist.svg)](https://rubygems.org/gems/fontist)
5
+ [![Pull Requests](https://img.shields.io/github/issues-pr-raw/fontist/fontist.svg)](https://github.com/fontist/fontist/pulls)
6
6
 
7
7
  A simple library to find and download fonts for Windows, Linux and Mac.
8
8
 
@@ -34,6 +34,18 @@ After installation please fetch formulas to your system:
34
34
  fontist update
35
35
  ```
36
36
 
37
+ ### Dependencies
38
+
39
+ Depends on
40
+ [ffi-libarchive-binary](https://github.com/fontist/ffi-libarchive-binary) which
41
+ has the following requirements:
42
+
43
+ * zlib
44
+ * Expat
45
+ * OpenSSL (for Linux only)
46
+
47
+ These dependencies are generally present on all systems.
48
+
37
49
  ## Usage
38
50
 
39
51
  ### Font
@@ -387,6 +399,70 @@ bin/rspec
387
399
  All formulas are kept in the [formulas][fontist-formulas] repository. If you'd
388
400
  like to add a new one or change any existing, please refer to its documentation.
389
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
+
390
466
  ### Auto-generate a formula
391
467
 
392
468
  A formula could be generated from a fonts archive. Just specify a URL to the
@@ -397,20 +473,21 @@ fontist create-formula https://www.latofonts.com/download/lato2ofl-zip/
397
473
  cp lato.yml ~/.fontist/formulas/Formulas/
398
474
  ```
399
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.
400
478
  A formula index should be rebuild, when a new formula is generated or an
401
479
  existing one changed:
402
480
 
403
481
  ```sh
404
- fontist rebuild-index
482
+ fontist rebuild-index --main-repo
405
483
  ```
406
484
 
407
- Then, both the formula and the updated index should be commited and pushed to
485
+ Then, both the formula and the updated indexes should be commited and pushed to
408
486
  the formula repository:
409
487
 
410
488
  ```sh
411
489
  cd ~/.fontist/formulas
412
- git add Formulas/lato.yml
413
- git add index.yml
490
+ git add Formulas/lato.yml index.yml filename_index.yml
414
491
  git commit -m "Add Lato formula"
415
492
  ```
416
493
 
@@ -429,7 +506,7 @@ repository [formulas][fontist-formulas]:
429
506
 
430
507
  ```
431
508
  cd ~/.fontist/formulas
432
- git add Formulas/google
509
+ git add Formulas/google index.yml filename_index.yml
433
510
  git commit -m "Google Fonts update"
434
511
  git push
435
512
  ```
@@ -442,8 +519,7 @@ can be updated with:
442
519
  ```sh
443
520
  fontist import-sil
444
521
  cd ~/.fontist/formulas
445
- git add Formulas/sil
446
- git add index.yml
522
+ git add Formulas/sil index.yml filename_index.yml
447
523
  git commit -m "SIL fonts update"
448
524
  git push
449
525
  ```
data/fontist.gemspec CHANGED
@@ -30,7 +30,7 @@ Gem::Specification.new do |spec|
30
30
  spec.add_runtime_dependency "down", "~> 5.0"
31
31
  spec.add_runtime_dependency "thor", "~> 1.0.1"
32
32
  spec.add_runtime_dependency "git", "~> 1.0"
33
- spec.add_runtime_dependency "ttfunk", "~> 1.6.2"
33
+ spec.add_runtime_dependency "ttfunk", "~> 1.6"
34
34
  spec.add_runtime_dependency "excavate", "~> 0.1"
35
35
 
36
36
  spec.add_development_dependency "extract_ttc", "~> 0.1"
@@ -40,7 +40,7 @@ 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", "0.75.0"
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"
data/lib/fontist.rb CHANGED
@@ -7,6 +7,7 @@ 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"
@@ -28,7 +29,11 @@ module Fontist
28
29
  end
29
30
 
30
31
  def self.fontist_path
31
- Pathname.new(ENV["FONTIST_PATH"] || File.join(Dir.home, ".fontist"))
32
+ Pathname.new(ENV["FONTIST_PATH"] || default_fontist_path)
33
+ end
34
+
35
+ def self.default_fontist_path
36
+ Pathname.new(File.join(Dir.home, ".fontist"))
32
37
  end
33
38
 
34
39
  def self.fonts_path
@@ -47,6 +52,10 @@ module Fontist
47
52
  Fontist.formulas_repo_path.join("Formulas")
48
53
  end
49
54
 
55
+ def self.private_formulas_path
56
+ Fontist.formulas_path.join("private")
57
+ end
58
+
50
59
  def self.downloads_path
51
60
  Fontist.fontist_path.join("downloads")
52
61
  end
@@ -60,10 +69,23 @@ module Fontist
60
69
  end
61
70
 
62
71
  def self.formula_index_path
63
- Fontist.formulas_repo_path.join("index.yml")
72
+ @formula_index_path || Fontist.formula_index_dir.join("formula_index.yml")
73
+ end
74
+
75
+ def self.formula_index_path=(path)
76
+ @formula_index_path = path
64
77
  end
65
78
 
66
79
  def self.formula_filename_index_path
67
- Fontist.formulas_repo_path.join("filename_index.yml")
80
+ @formula_filename_index_path ||
81
+ Fontist.formula_index_dir.join("filename_index.yml")
82
+ end
83
+
84
+ def self.formula_filename_index_path=(path)
85
+ @formula_filename_index_path = path
86
+ end
87
+
88
+ def self.formula_index_dir
89
+ Fontist.fontist_path
68
90
  end
69
91
  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,6 +24,8 @@ 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?
@@ -78,8 +84,11 @@ module Fontist
78
84
  desc "update", "Update formulas"
79
85
  def update
80
86
  Formula.update_formulas_repo
81
- Fontist.ui.say("Formulas have been successfully updated")
87
+ Fontist.ui.success("Formulas have been successfully updated.")
82
88
  success
89
+ rescue Fontist::Errors::RepoCouldNotBeUpdatedError => e
90
+ Fontist.ui.error(e.message)
91
+ STATUS_REPO_COULD_NOT_BE_UPDATED
83
92
  end
84
93
 
85
94
  desc "manifest-locations MANIFEST",
@@ -123,11 +132,21 @@ module Fontist
123
132
 
124
133
  desc "rebuild-index", "Rebuild formula index (used by formulas maintainers)"
125
134
  long_desc <<-LONGDESC
126
- This index is pre-built and served with formulas, so there is no need
127
- update it unless something changes in the formulas repo.
135
+ Index should be rebuilt when any formula changes.
136
+
137
+ It is done automatically when formulas are updated, or private formulas
138
+ are set up.
128
139
  LONGDESC
140
+ option :main_repo, type: :boolean,
141
+ desc: "Updates indexes in the main repo (for backward " \
142
+ "compatibility with versions prior to 1.9)"
129
143
  def rebuild_index
130
- Fontist::Index.rebuild
144
+ if options[:main_repo]
145
+ Fontist::Index.rebuild_for_main_repo
146
+ else
147
+ Fontist::Index.rebuild
148
+ end
149
+
131
150
  Fontist.ui.say("Formula index has been rebuilt.")
132
151
  STATUS_SUCCESS
133
152
  end
@@ -138,6 +157,9 @@ module Fontist
138
157
  Fontist::Import::SilImport.new.call
139
158
  end
140
159
 
160
+ desc "repo SUBCOMMAND ...ARGS", "Manage custom repositories"
161
+ subcommand "repo", Fontist::RepoCLI
162
+
141
163
  private
142
164
 
143
165
  def success
@@ -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
data/lib/fontist/font.rb CHANGED
@@ -203,9 +203,9 @@ module Fontist
203
203
  end
204
204
 
205
205
  def font_list
206
- return unless formula
206
+ return if formulas.empty?
207
207
 
208
- list_styles([formula])
208
+ list_styles(formulas)
209
209
  end
210
210
 
211
211
  def list_styles(formulas)
@@ -54,11 +54,12 @@ module Fontist
54
54
  end
55
55
 
56
56
  def download_file(source)
57
- url = source.urls.first
57
+ request = source.urls.first
58
+ url = request.respond_to?(:url) ? request.url : request
58
59
  Fontist.ui.say(%(Downloading font "#{@formula.key}" from #{url}))
59
60
 
60
61
  Fontist::Utils::Downloader.download(
61
- url,
62
+ request,
62
63
  sha: source.sha256,
63
64
  file_size: source.file_size,
64
65
  progress_bar: !@no_progress
@@ -1,17 +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
- if Dir.exist?(Fontist.formulas_repo_path)
9
- Git.open(Fontist.formulas_repo_path).pull
10
- else
11
- Git.clone(Fontist.formulas_repo_url,
12
- Fontist.formulas_repo_path,
13
- depth: 1)
14
- end
9
+ Update.call
15
10
  end
16
11
 
17
12
  def self.all
@@ -14,6 +14,7 @@ module Fontist
14
14
  paths = search_font_paths(s["font"])
15
15
  paths.map do |path|
16
16
  { full_name: s["full_name"],
17
+ type: s["type"],
17
18
  path: path }
18
19
  end
19
20
  end
data/lib/fontist/index.rb CHANGED
@@ -3,9 +3,42 @@ require_relative "indexes/filename_index"
3
3
 
4
4
  module Fontist
5
5
  class Index
6
+ def self.rebuild_for_main_repo
7
+ unless Dir.exist?(Fontist.private_formulas_path)
8
+ return do_rebuild_for_main_repo_with
9
+ end
10
+
11
+ Dir.mktmpdir do |dir|
12
+ tmp_private_path = File.join(dir, "private")
13
+ FileUtils.mv(Fontist.private_formulas_path, tmp_private_path)
14
+
15
+ do_rebuild_for_main_repo_with
16
+
17
+ FileUtils.mv(tmp_private_path, Fontist.private_formulas_path)
18
+ end
19
+ end
20
+
21
+ def self.do_rebuild_for_main_repo_with
22
+ Fontist.formula_index_path = Fontist.formulas_repo_path.join("index.yml")
23
+ Fontist.formula_filename_index_path =
24
+ Fontist.formulas_repo_path.join("filename_index.yml")
25
+
26
+ rebuild
27
+
28
+ Fontist.formula_index_path = nil
29
+ Fontist.formula_filename_index_path = nil
30
+ end
31
+
6
32
  def self.rebuild
7
33
  Fontist::Indexes::FontIndex.rebuild
8
34
  Fontist::Indexes::FilenameIndex.rebuild
35
+
36
+ reset_cache
37
+ end
38
+
39
+ def self.reset_cache
40
+ Fontist::Indexes::FontIndex.reset_cache
41
+ Fontist::Indexes::FilenameIndex.reset_cache
9
42
  end
10
43
  end
11
44
  end
@@ -5,10 +5,14 @@ module Fontist
5
5
  class BaseIndex
6
6
  def self.from_yaml
7
7
  @from_yaml ||= begin
8
- unless File.exist?(path)
9
- raise Errors::FormulaIndexNotFoundError.new("Please fetch `#{path}` index with `fontist update`.")
8
+ unless Dir.exist?(Fontist.formulas_repo_path)
9
+ raise Errors::MainRepoNotFoundError.new(
10
+ "Please fetch formulas with `fontist update`.",
11
+ )
10
12
  end
11
13
 
14
+ rebuild unless File.exist?(path)
15
+
12
16
  data = YAML.load_file(path)
13
17
  new(data)
14
18
  end
@@ -18,6 +22,10 @@ module Fontist
18
22
  raise NotImplementedError, "Please define path of an index"
19
23
  end
20
24
 
25
+ def self.reset_cache
26
+ @from_yaml = nil
27
+ end
28
+
21
29
  def self.rebuild
22
30
  index = new
23
31
  index.build
@@ -59,6 +67,8 @@ module Fontist
59
67
  end
60
68
 
61
69
  def to_yaml
70
+ dir = File.dirname(self.class.path)
71
+ FileUtils.mkdir_p(dir) unless File.exist?(dir)
62
72
  File.write(self.class.path, YAML.dump(to_h))
63
73
  end
64
74
 
@@ -14,7 +14,7 @@ module Fontist
14
14
 
15
15
  def file_paths(font, style)
16
16
  paths = find_font_with_name(font, style)
17
- return paths unless paths["paths"].empty?
17
+ return paths unless paths.nil?
18
18
 
19
19
  install_font(font)
20
20
 
@@ -42,26 +42,40 @@ module Fontist
42
42
  end
43
43
 
44
44
  def style_paths_map(font, names)
45
- paths = style_paths(font, names)
46
- names.zip(paths).to_h
45
+ styles = style_paths(font, names)
46
+ group_paths(styles)
47
47
  end
48
48
 
49
49
  def style_paths(font, names)
50
- names.map do |style|
51
- file_paths(font, style)
50
+ names.flat_map do |style|
51
+ file_paths(font, style) || empty_paths(style)
52
52
  end
53
53
  end
54
54
 
55
+ def group_paths(styles)
56
+ styles.group_by { |s| s[:type] }
57
+ .transform_values { |group| style(group) }
58
+ end
59
+
60
+ def style(styles)
61
+ { "full_name" => styles.first[:full_name],
62
+ "paths" => styles.map { |x| x[:path] } }.compact
63
+ end
64
+
55
65
  def file_paths(font, style)
56
66
  find_font_with_name(font, style).tap do |x|
57
- if x["paths"].empty?
67
+ if x.nil?
58
68
  raise Errors::MissingFontError.new(font, style)
59
69
  end
60
70
  end
61
71
  end
62
72
 
63
73
  def find_font_with_name(font, style)
64
- Fontist::SystemFont.find_with_name(font, style).map { |k, v| [k.to_s, v] }.to_h
74
+ Fontist::SystemFont.find_styles(font, style)
75
+ end
76
+
77
+ def empty_paths(style)
78
+ [{ "full_name" => nil, "type" => style, "path" => nil }]
65
79
  end
66
80
  end
67
81
  end
@@ -0,0 +1,60 @@
1
+ require "git"
2
+
3
+ module Fontist
4
+ class Repo
5
+ class << self
6
+ def setup(name, url)
7
+ ensure_private_formulas_path_exists
8
+ fetch_repo(name, url)
9
+ Index.rebuild
10
+ end
11
+
12
+ def update(name)
13
+ path = repo_path(name)
14
+ unless Dir.exist?(path)
15
+ raise(Errors::RepoNotFoundError, "No such repo '#{name}'.")
16
+ end
17
+
18
+ Git.open(path).pull
19
+ Index.rebuild
20
+ end
21
+
22
+ def remove(name)
23
+ path = repo_path(name)
24
+ unless Dir.exist?(path)
25
+ raise(Errors::RepoNotFoundError, "No such repo '#{name}'.")
26
+ end
27
+
28
+ FileUtils.rm_r(path)
29
+ Index.rebuild
30
+ end
31
+
32
+ def list
33
+ Dir.glob(Fontist.private_formulas_path.join("*"))
34
+ .select { |path| File.directory?(path) }
35
+ .map { |path| File.basename(path) }
36
+ end
37
+
38
+ private
39
+
40
+ def ensure_private_formulas_path_exists
41
+ Fontist.private_formulas_path.tap do |path|
42
+ FileUtils.mkdir_p(path) unless Dir.exist?(path)
43
+ end
44
+ end
45
+
46
+ def fetch_repo(name, url)
47
+ path = repo_path(name)
48
+ if Dir.exist?(path)
49
+ Git.open(path).pull
50
+ else
51
+ Git.clone(url, path, depth: 1)
52
+ end
53
+ end
54
+
55
+ def repo_path(name)
56
+ Fontist.private_formulas_path.join(name)
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,51 @@
1
+ module Fontist
2
+ class RepoCLI < Thor
3
+ desc "setup NAME URL",
4
+ "Setup a custom fontist repo named NAME for the repository at URL " \
5
+ "and fetches its formulas"
6
+ def setup(name, url)
7
+ Repo.setup(name, url)
8
+ Fontist.ui.success(
9
+ "Fontist repo '#{name}' from '#{url}' has been successfully set up.",
10
+ )
11
+ CLI::STATUS_SUCCESS
12
+ end
13
+
14
+ desc "update NAME", "Update formulas in a fontist repo named NAME"
15
+ def update(name)
16
+ Repo.update(name)
17
+ Fontist.ui.success(
18
+ "Fontist repo '#{name}' has been successfully updated.",
19
+ )
20
+ CLI::STATUS_SUCCESS
21
+ rescue Errors::RepoNotFoundError
22
+ handle_repo_not_found(name)
23
+ end
24
+
25
+ desc "remove NAME", "Remove fontist repo named NAME"
26
+ def remove(name)
27
+ Repo.remove(name)
28
+ Fontist.ui.success(
29
+ "Fontist repo '#{name}' has been successfully removed.",
30
+ )
31
+ CLI::STATUS_SUCCESS
32
+ rescue Errors::RepoNotFoundError
33
+ handle_repo_not_found(name)
34
+ end
35
+
36
+ desc "list", "List fontist repos"
37
+ def list
38
+ Repo.list.each do |name|
39
+ Fontist.ui.say(name)
40
+ end
41
+ CLI::STATUS_SUCCESS
42
+ end
43
+
44
+ private
45
+
46
+ def handle_repo_not_found(name)
47
+ Fontist.ui.error("Fontist repo '#{name}' is not found.")
48
+ CLI::STATUS_REPO_NOT_FOUND
49
+ end
50
+ end
51
+ end
@@ -40,8 +40,8 @@ module Fontist
40
40
  new(font: font, sources: sources).find
41
41
  end
42
42
 
43
- def self.find_with_name(font, style)
44
- new(font: font, style: style).find_with_name
43
+ def self.find_styles(font, style)
44
+ new(font: font, style: style).find_styles
45
45
  end
46
46
 
47
47
  def find
@@ -51,22 +51,14 @@ module Fontist
51
51
  styles.map { |x| x[:path] }
52
52
  end
53
53
 
54
- def find_with_name
55
- styles = find_styles
56
- return { full_name: nil, paths: [] } unless styles
57
-
58
- { full_name: styles.first[:full_name],
59
- paths: styles.map { |x| x[:path] } }
54
+ def find_styles
55
+ find_by_index || find_by_formulas
60
56
  end
61
57
 
62
58
  private
63
59
 
64
60
  attr_reader :font, :style, :user_sources
65
61
 
66
- def find_styles
67
- find_by_index || find_by_formulas
68
- end
69
-
70
62
  def find_by_index
71
63
  SystemIndex.new(all_paths).find(font, style)
72
64
  end
@@ -83,7 +83,7 @@ module Fontist
83
83
  next by_path[path] if by_path[path]
84
84
 
85
85
  detect_fonts(path)
86
- end
86
+ end.compact
87
87
  end
88
88
 
89
89
  def detect_fonts(path)
@@ -100,6 +100,9 @@ module Fontist
100
100
  def detect_file_font(path)
101
101
  file = TTFunk::File.open(path)
102
102
  parse_font(file, path)
103
+ rescue StandardError
104
+ warn $!.message
105
+ warn "Warning: File at #{path} not recognized as a font file."
103
106
  end
104
107
 
105
108
  def detect_collection_fonts(path)
@@ -0,0 +1,64 @@
1
+ module Fontist
2
+ class Update
3
+ def self.call
4
+ new.call
5
+ end
6
+
7
+ def call
8
+ update_main_repo
9
+ update_private_repos
10
+ ensure
11
+ rebuild_index
12
+ end
13
+
14
+ private
15
+
16
+ def update_main_repo
17
+ dir = File.dirname(Fontist.formulas_repo_path)
18
+ FileUtils.mkdir_p(dir) unless File.exist?(dir)
19
+
20
+ if Dir.exist?(Fontist.formulas_repo_path)
21
+ Git.open(Fontist.formulas_repo_path).pull
22
+ else
23
+ Git.clone(Fontist.formulas_repo_url,
24
+ Fontist.formulas_repo_path,
25
+ depth: 1)
26
+ end
27
+ end
28
+
29
+ def update_private_repos
30
+ private_repos.each do |path|
31
+ update_repo(path)
32
+ end
33
+ end
34
+
35
+ def update_repo(path)
36
+ Git.open(path).pull
37
+ rescue Git::GitExecuteError => e
38
+ name = repo_name(path)
39
+ raise Errors::RepoCouldNotBeUpdatedError.new(<<~MSG.chomp)
40
+ Formulas repo '#{name}' could not be updated.
41
+ Please consider reinitializing it with:
42
+ fontist remove #{name}
43
+ fontist setup #{name} REPO_URL
44
+
45
+ Git error:
46
+ #{e.message}
47
+ MSG
48
+ end
49
+
50
+ def private_repos
51
+ Dir.glob(Fontist.private_formulas_path.join("*")).select do |path|
52
+ File.directory?(path)
53
+ end
54
+ end
55
+
56
+ def repo_name(path)
57
+ File.basename(path)
58
+ end
59
+
60
+ def rebuild_index
61
+ Index.rebuild
62
+ end
63
+ end
64
+ end
@@ -20,7 +20,7 @@ module Fontist
20
20
  end
21
21
 
22
22
  def download
23
- file = @cache.fetch(@file) do
23
+ file = @cache.fetch(url) do
24
24
  download_file
25
25
  end
26
26
 
@@ -56,9 +56,10 @@ module Fontist
56
56
 
57
57
  def download_file
58
58
  file = Down.download(
59
- @file,
59
+ url,
60
60
  open_timeout: 10,
61
61
  read_timeout: 10,
62
+ headers: headers,
62
63
  content_length_proc: ->(content_length) {
63
64
  @progress_bar.total = content_length if content_length
64
65
  },
@@ -73,6 +74,17 @@ module Fontist
73
74
  rescue Down::NotFound
74
75
  raise(Fontist::Errors::InvalidResourceError.new("Invalid URL: #{@file}"))
75
76
  end
77
+
78
+ def url
79
+ @file.respond_to?(:url) ? @file.url : @file
80
+ end
81
+
82
+ def headers
83
+ @file.respond_to?(:headers) &&
84
+ @file.headers &&
85
+ @file.headers.to_h.map { |k, v| [k.to_s, v] }.to_h || # rubocop:disable Style/HashTransformKeys, Metrics/LineLength
86
+ {}
87
+ end
76
88
  end
77
89
 
78
90
  class ProgressBar
@@ -11,6 +11,7 @@ module Fontist
11
11
  yield
12
12
  ensure
13
13
  f.flock(File::LOCK_UN)
14
+ f.close
14
15
  end
15
16
  end
16
17
  end
@@ -1,3 +1,3 @@
1
1
  module Fontist
2
- VERSION = "1.8.10".freeze
2
+ VERSION = "1.9.1".freeze
3
3
  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.8.10
4
+ version: 1.9.1
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-03-17 00:00:00.000000000 Z
11
+ date: 2021-07-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: down
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 1.6.2
61
+ version: '1.6'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 1.6.2
68
+ version: '1.6'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: excavate
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -184,14 +184,14 @@ dependencies:
184
184
  requirements:
185
185
  - - '='
186
186
  - !ruby/object:Gem::Version
187
- version: 0.75.0
187
+ version: 1.5.2
188
188
  type: :development
189
189
  prerelease: false
190
190
  version_requirements: !ruby/object:Gem::Requirement
191
191
  requirements:
192
192
  - - '='
193
193
  - !ruby/object:Gem::Version
194
- version: 0.75.0
194
+ version: 1.5.2
195
195
  - !ruby/object:Gem::Dependency
196
196
  name: rubocop-rails
197
197
  requirement: !ruby/object:Gem::Requirement
@@ -243,6 +243,7 @@ extensions: []
243
243
  extra_rdoc_files: []
244
244
  files:
245
245
  - ".github/workflows/check_google.yml"
246
+ - ".github/workflows/metanorma.yml"
246
247
  - ".github/workflows/release.yml"
247
248
  - ".github/workflows/rspec.yml"
248
249
  - ".gitignore"
@@ -301,9 +302,12 @@ files:
301
302
  - lib/fontist/manifest.rb
302
303
  - lib/fontist/manifest/install.rb
303
304
  - lib/fontist/manifest/locations.rb
305
+ - lib/fontist/repo.rb
306
+ - lib/fontist/repo_cli.rb
304
307
  - lib/fontist/system.yml
305
308
  - lib/fontist/system_font.rb
306
309
  - lib/fontist/system_index.rb
310
+ - lib/fontist/update.rb
307
311
  - lib/fontist/utils.rb
308
312
  - lib/fontist/utils/cache.rb
309
313
  - lib/fontist/utils/downloader.rb
@@ -336,7 +340,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
336
340
  - !ruby/object:Gem::Version
337
341
  version: '0'
338
342
  requirements: []
339
- rubygems_version: 3.0.3
343
+ rubygems_version: 3.0.3.1
340
344
  signing_key:
341
345
  specification_version: 4
342
346
  summary: Install openly-licensed fonts on Windows, Linux and Mac!