fontist 1.11.1 → 1.11.6

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: 2f06401d4ccf76cfda39bcd4eae443dbfb2f5284876c4f5a9361fcb56bb97f5a
4
- data.tar.gz: 5730fc169549b7b3dda74f6e9cae5d3fb3b15c27d1f7d107f16ab5b1be9cdeb8
3
+ metadata.gz: ebc9110896000190889a313f291012ebc3b84a7296230398ee61c9822c44ea87
4
+ data.tar.gz: 9de28427a3a46124e8ded2880de764ad9bb632bc9c919babe15123fc38eebdb3
5
5
  SHA512:
6
- metadata.gz: bcc0837022c84b93e97e07a19494cd2b28bd51a41834809d4833fb1a453a0314fa37f6249ddb171e6b8f12e8f31c56fa660f661376895c7d9f1a417542626a1c
7
- data.tar.gz: c46f1f7610213bf168f485d724e215bd2fd5f276802481a647eba9580e4dfc8d0307e3b014a3ee29ceda992548f294251d1600a64efc3086ff1b101420ced3a1
6
+ metadata.gz: 005c1c9a434bbfa11da8602be4180e20056798afccf4c302204e6d986c6a288d7ee6cbfb387c597db79fe4ae86e50aa22729d4553813b7f025d27a1033c83f19
7
+ data.tar.gz: 8584ca32768a87ce2ddfd95275e6f22a9b61074df2db8b407f587931cc2729b444dd257f6435fd564bd0588a2bcf5d6e2634f611cf73a87d76ec517a86de4edf
@@ -2,11 +2,8 @@ name: metanorma
2
2
 
3
3
  on:
4
4
  push:
5
- # restore the main branch after metanorma upgrade
6
- # branches: [ main ]
7
- branches: [ unknown ]
8
- # restore after metanorma upgrade
9
- # pull_request:
5
+ branches: [ main ]
6
+ pull_request:
10
7
 
11
8
  jobs:
12
9
  test:
@@ -14,7 +14,7 @@ jobs:
14
14
  fail-fast: false
15
15
  matrix:
16
16
  ruby: [ '2.4', '2.5', '2.6', '2.7', '3.0' ]
17
- os: [ ubuntu-latest, windows-latest, macos-latest ]
17
+ os: [ ubuntu-18.04, ubuntu-latest, windows-latest, macos-latest ]
18
18
  experimental: [ false ]
19
19
 
20
20
  steps:
data/README.adoc CHANGED
@@ -51,6 +51,34 @@ has the following requirements:
51
51
 
52
52
  These dependencies are generally present on all systems.
53
53
 
54
+ === Upgrading Fontist
55
+
56
+ ==== To v1.10+
57
+
58
+ Fontist versions beyond v1.10 utilize a new formula format.
59
+ After the upgrade, please run `fontist update` to fetch the latest formulas.
60
+
61
+ Starting from v1.10, Fontist uses the "`default family`" instead of the "`preferred family`"
62
+ when grouping styles.
63
+
64
+ For example, a request for the "`Lato`" font prior to v1.10 will return all
65
+ styles: "`Black`", "`Black Italic`", "`Bold`", and 15 other styles.
66
+
67
+ From v1.10 onwards, Fontist will return _only_ the 4 default styles:
68
+ "`Regular`", "`Italic`", "`Bold`" and "`Bold Italic`".
69
+
70
+ In order to fetch other styles, you have to specify the exact font
71
+ "`subfamily`", such as "`Lato Black`", or "`Lato Heavy`", or use
72
+ the `--preferred-family` option with CLI and `Fontist.preferred_family = true`
73
+ with the Ruby library.
74
+
75
+ NOTE: Prior to v1.10 there was a bug with the "`Courier`" font formula, which
76
+ allowed the font to be installed when requesting the font name "`Courier`", but
77
+ its font location was only obtainable using the full "`Courier New`" font name.
78
+ From v1.10 onwards the behavior has been made consistent -- only the proper
79
+ "`Courier New`" name should be used.
80
+
81
+
54
82
  == Usage of the `fontist` command
55
83
 
56
84
  === Fontist command-line interface
@@ -62,13 +90,18 @@ code higher or equal than 1.
62
90
 
63
91
  All searches are case-insensitive for ease of use.
64
92
 
93
+ === Global options
94
+
95
+ All commands support the following options:
96
+
97
+ * `--preferred-family` Use the preferred family names when searching for fonts. This format was used prior to v1.10.
98
+
65
99
  === Install fonts
66
100
 
67
101
  Fontist checks whether this font is already installed, and if not, then installs
68
102
  the font and returns its installed paths.
69
103
 
70
- Only the font name (not formula name, nor font filename) could be used as its
71
- argument.
104
+ The font name is the only argument to be supplied (the font family name).
72
105
 
73
106
  [source,sh]
74
107
  ----
@@ -80,6 +113,8 @@ These fonts are found or installed:
80
113
  /Users/user/.fontist/fonts/SEGOEUIZ.TTF
81
114
  ----
82
115
 
116
+ NOTE: Specifying the formula's name or the font's filename is not supported.
117
+
83
118
  NOTE: The `install` command is similar to the `Font.install` library call.
84
119
 
85
120
  === Uninstall fonts
@@ -350,6 +385,16 @@ operation you would do in any ruby object.
350
385
 
351
386
  === `Fontist::Manifest`
352
387
 
388
+ ==== Global options
389
+
390
+ Fontist can be switched to use the preferred family names. This format was
391
+ used prior to v1.10.
392
+
393
+ [source,ruby]
394
+ ----
395
+ Fontist.preferred_family = true
396
+ ----
397
+
353
398
  [[fontist-locations]]
354
399
  ==== `Fontist::Manifest::Locations`
355
400
 
@@ -565,7 +610,7 @@ In case an update is found, it could be fetched to the library by:
565
610
 
566
611
  [source,sh]
567
612
  ----
568
- bin/import_google
613
+ bin/fontist google import
569
614
  ----
570
615
 
571
616
  The script would update formulas which should be committed to a separate
@@ -573,8 +618,8 @@ repository https://github.com/fontist/formulas[formulas]:
573
618
 
574
619
  [source,sh]
575
620
  ----
576
- cd ~/.fontist/formulas
577
- git add Formulas/google index.yml filename_index.yml
621
+ cd ~/.fontist/versions/v2/formulas
622
+ git add Formulas/google
578
623
  git commit -m "Google Fonts update"
579
624
  git push
580
625
  ----
@@ -640,8 +685,8 @@ one, please refer to its documentation.
640
685
  There is an ability to use private fonts via private Fontist repositories.
641
686
 
642
687
  A Fontist repository is a Git repo which contains YAML formula files. Formulas can be created
643
- manually (see https://github.com/fontist/formulas/tree/master/Formulas)[examples],
644
- or #auto-generate-a-formula[auto-generated from an archive].
688
+ manually (see https://github.com/fontist/formulas/tree/master/Formulas[examples]),
689
+ or xref:Authoring Fontist formulas[auto-generated from an archive].
645
690
 
646
691
  A repository can be either a HTTPS or SSH Git repo. In case of SSH, a
647
692
  corresponding SSH key should be setup with `ssh-agent` in order to access this
@@ -740,9 +785,10 @@ sub-licenses to third parties, under the copyright covering the contribution to
740
785
  use the contribution by all means.
741
786
 
742
787
  We are following Sandi Metz's Rules for this gem, you can read the
743
- http://robots.thoughtbot.com/post/50655960596/sandi-metz-rules-for-developers[description of the rules here] All new code should follow these
744
- rules. If you make changes in a pre-existing file that violates these rules you
745
- should fix the violations as part of your contribution.
788
+ http://robots.thoughtbot.com/post/50655960596/sandi-metz-rules-for-developers[description of the rules here].
789
+ All new code should follow these rules. If you make changes in a pre-existing
790
+ file that violates these rules you should fix the violations as part of your
791
+ contribution.
746
792
 
747
793
  Here are a few technical guidelines to follow:
748
794
 
data/fontist.gemspec CHANGED
@@ -28,22 +28,22 @@ Gem::Specification.new do |spec|
28
28
  spec.test_files = `git ls-files -- {spec}/*`.split("\n")
29
29
 
30
30
  spec.add_runtime_dependency "down", "~> 5.0"
31
+ spec.add_runtime_dependency "extract_ttc", "~> 0.1"
31
32
  spec.add_runtime_dependency "thor", "~> 1.0.1"
32
33
  spec.add_runtime_dependency "git", "~> 1.0"
33
34
  spec.add_runtime_dependency "ttfunk", "~> 1.6"
34
35
  spec.add_runtime_dependency "excavate", "~> 0.1"
35
36
 
36
- spec.add_development_dependency "extract_ttc", "~> 0.1"
37
37
  spec.add_development_dependency "pry"
38
38
  spec.add_development_dependency "bundler", "~> 2.0"
39
39
  spec.add_development_dependency "gem-release"
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 "rspec-benchmark", "~> 0.6"
43
44
  spec.add_development_dependency "rubocop", "1.5.2"
44
45
  spec.add_development_dependency "rubocop-rails"
45
46
  spec.add_development_dependency "rubocop-performance"
46
- spec.add_development_dependency "ruby-protocol-buffers", "~> 1.0"
47
47
 
48
48
  spec.add_runtime_dependency "socksify"
49
49
  end
data/lib/fontist/cli.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require "thor"
2
2
  require "fontist/repo_cli"
3
+ require "fontist/google_cli"
3
4
 
4
5
  module Fontist
5
6
  class CLI < Thor
@@ -149,18 +150,9 @@ module Fontist
149
150
  It is done automatically when formulas are updated, or private formulas
150
151
  are set up.
151
152
  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)"
155
153
  def rebuild_index
156
154
  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
-
155
+ Fontist::Index.rebuild
164
156
  Fontist.ui.say("Formula index has been rebuilt.")
165
157
  STATUS_SUCCESS
166
158
  end
@@ -175,6 +167,9 @@ module Fontist
175
167
  desc "repo SUBCOMMAND ...ARGS", "Manage custom repositories"
176
168
  subcommand "repo", Fontist::RepoCLI
177
169
 
170
+ desc "google SUBCOMMAND ...ARGS", "Manage Google formulas"
171
+ subcommand "google", Fontist::GoogleCLI
172
+
178
173
  private
179
174
 
180
175
  def handle_class_options(options)
@@ -54,16 +54,30 @@ module Fontist
54
54
  end
55
55
 
56
56
  def download_file(source)
57
- request = source.urls.first
58
- url = request.respond_to?(:url) ? request.url : request
59
- Fontist.ui.say(%(Downloading font "#{@formula.key}" from #{url}))
57
+ errors = []
58
+ source.urls.each do |request|
59
+ url = request.respond_to?(:url) ? request.url : request
60
+ Fontist.ui.say(%(Downloading font "#{@formula.key}" from #{url}))
60
61
 
62
+ result = try_download_file(request, source)
63
+ return result unless result.is_a?(Errors::InvalidResourceError)
64
+
65
+ errors << result
66
+ end
67
+
68
+ raise Errors::InvalidResourceError, errors.join(" ")
69
+ end
70
+
71
+ def try_download_file(request, source)
61
72
  Fontist::Utils::Downloader.download(
62
73
  request,
63
74
  sha: source.sha256,
64
75
  file_size: source.file_size,
65
76
  progress_bar: !@no_progress
66
77
  )
78
+ rescue Errors::InvalidResourceError => e
79
+ Fontist.ui.say(e.message)
80
+ e
67
81
  end
68
82
 
69
83
  def font_file?(path)
@@ -103,6 +103,10 @@ module Fontist
103
103
  @fonts ||= Helpers.parse_to_object(hash_collection_fonts + hash_fonts)
104
104
  end
105
105
 
106
+ def digest
107
+ @data["digest"]
108
+ end
109
+
106
110
  private
107
111
 
108
112
  def default_key
@@ -0,0 +1,29 @@
1
+ module Fontist
2
+ class GoogleCLI < Thor
3
+ class_option :formulas_path, type: :string, desc: "Path to formulas"
4
+
5
+ desc "check", "Check Google fonts for updates"
6
+ def check
7
+ handle_class_options(options)
8
+ require "fontist/import/google_check"
9
+ Fontist::Import::GoogleCheck.new.call
10
+ CLI::STATUS_SUCCESS
11
+ end
12
+
13
+ desc "import", "Import Google fonts"
14
+ def import
15
+ handle_class_options(options)
16
+ require "fontist/import/google_import"
17
+ Fontist::Import::GoogleImport.new.call
18
+ CLI::STATUS_SUCCESS
19
+ end
20
+
21
+ private
22
+
23
+ def handle_class_options(options)
24
+ if options[:formulas_path]
25
+ Fontist.formulas_path = Pathname.new(options[:formulas_path])
26
+ end
27
+ end
28
+ end
29
+ end
@@ -6,7 +6,7 @@ module Fontist
6
6
  class FormulaBuilder
7
7
  FORMULA_ATTRIBUTES = %i[name description homepage resources
8
8
  font_collections fonts extract copyright
9
- license_url open_license command].freeze
9
+ license_url open_license digest command].freeze
10
10
 
11
11
  attr_accessor :archive,
12
12
  :url,
@@ -60,6 +60,18 @@ module Fontist
60
60
  end
61
61
 
62
62
  def resource_options
63
+ if @options[:skip_sha]
64
+ resource_options_without_sha
65
+ else
66
+ resource_options_with_sha
67
+ end
68
+ end
69
+
70
+ def resource_options_without_sha
71
+ { urls: [@url] + mirrors }
72
+ end
73
+
74
+ def resource_options_with_sha
63
75
  urls = []
64
76
  sha = []
65
77
  downloads do |url, path|
@@ -167,6 +179,10 @@ module Fontist
167
179
  TextHelper.cleanup(@license_text)
168
180
  end
169
181
 
182
+ def digest
183
+ @options[:digest]
184
+ end
185
+
170
186
  def command
171
187
  Shellwords.shelljoin(ARGV)
172
188
  end
@@ -1,4 +1,3 @@
1
- require_relative "fonts_public.pb"
2
1
  require_relative "../google"
3
2
  require_relative "../otf_parser"
4
3
 
@@ -6,7 +5,7 @@ module Fontist
6
5
  module Import
7
6
  module Google
8
7
  class NewFontsFetcher
9
- REPO_PATH = Fontist.root_path.join("tmp", "fonts")
8
+ REPO_PATH = Fontist.fontist_path.join("google", "fonts")
10
9
  REPO_URL = "https://github.com/google/fonts.git".freeze
11
10
  SKIPLIST_PATH = File.expand_path("skiplist.yml", __dir__)
12
11
 
@@ -25,7 +24,8 @@ module Fontist
25
24
  if Dir.exist?(REPO_PATH)
26
25
  `cd #{REPO_PATH} && git pull`
27
26
  else
28
- `git clone #{REPO_URL} #{REPO_PATH}`
27
+ FileUtils.mkdir_p(File.dirname(REPO_PATH))
28
+ `git clone --depth 1 #{REPO_URL} #{REPO_PATH}`
29
29
  end
30
30
  end
31
31
 
@@ -53,23 +53,11 @@ module Fontist
53
53
  end
54
54
 
55
55
  def new?(path)
56
- metadata = fetch_metadata(path)
57
- return unless metadata
58
-
59
- font_new?(metadata, path)
60
- end
61
-
62
- def fetch_metadata(path)
63
- metadata_path = File.join(path, "METADATA.pb")
64
- return unless File.exists?(metadata_path)
65
-
66
- ::Google::Fonts::FamilyProto.parse_from_text(File.read(metadata_path))
67
- end
68
-
69
- def font_new?(metadata, path)
70
- return if in_skiplist?(metadata.name)
71
- return if up_to_date?(metadata, path)
72
- return unless downloadable?(metadata.name)
56
+ metadata_name = Google.metadata_name(path)
57
+ return unless metadata_name
58
+ return if in_skiplist?(metadata_name)
59
+ return if up_to_date?(metadata_name, path)
60
+ return unless downloadable?(metadata_name)
73
61
 
74
62
  true
75
63
  end
@@ -79,29 +67,47 @@ module Fontist
79
67
  @skiplist.include?(name)
80
68
  end
81
69
 
82
- def up_to_date?(metadata, path)
83
- formula = formula(metadata.name)
70
+ def up_to_date?(metadata_name, path)
71
+ formula = formula(metadata_name)
84
72
  return false unless formula
85
73
 
86
- styles = formula.fonts.map(&:styles).flatten
74
+ repo_digest_up_to_date?(formula, path) ||
75
+ fonts_up_to_date?(formula, path)
76
+ end
77
+
78
+ def repo_digest_up_to_date?(formula, path)
79
+ return unless formula.digest
87
80
 
88
- styles.all? do |style|
89
- style.version == otfinfo_version(font_path(style.font, path))
81
+ formula.digest == Google.digest(path)
82
+ end
83
+
84
+ def fonts_up_to_date?(formula, path)
85
+ styles = formula_styles(formula)
86
+ repo_fonts(path).all? do |font|
87
+ style = styles.find { |s| s.font == repo_to_archive_name(font) }
88
+ return false unless style
89
+
90
+ otfinfo_version(font) == style.version
90
91
  end
91
92
  end
92
93
 
93
- def formula(font_name)
94
- klass = font_name.gsub(/ /, "").sub(/\S/, &:upcase)
95
- @formulas ||= Fontist::Formula.all
96
- @formulas["Fontist::Formulas::#{klass}Font"]
94
+ def formula_styles(formula)
95
+ formula.fonts.map(&:styles).flatten
97
96
  end
98
97
 
99
- def font_path(filename, directory)
100
- File.join(directory, fix_variable_filename(filename))
98
+ def repo_fonts(path)
99
+ Dir.glob(File.join(path, "*.{ttf,otf}"))
101
100
  end
102
101
 
103
- def fix_variable_filename(filename)
104
- filename.sub("-VariableFont_wght", "[wght]")
102
+ def repo_to_archive_name(font_path)
103
+ File.basename(font_path)
104
+ .sub("[wght]", "-VariableFont_wght")
105
+ .sub("[opsz]", "-Regular-VariableFont_opsz")
106
+ end
107
+
108
+ def formula(font_name)
109
+ path = Fontist::Import::Google.formula_path(font_name)
110
+ Formula.new_from_file(path) if File.exist?(path)
105
111
  end
106
112
 
107
113
  def otfinfo_version(path)
@@ -110,10 +116,15 @@ module Fontist
110
116
  end
111
117
 
112
118
  def downloadable?(name)
119
+ retries ||= 0
120
+ retries += 1
113
121
  Down.open("https://fonts.google.com/download?family=#{name}")
114
122
  true
115
123
  rescue Down::NotFound
116
124
  false
125
+ rescue Down::TimeoutError
126
+ retry unless retries >= 3
127
+ false
117
128
  end
118
129
  end
119
130
  end
@@ -1,11 +1,29 @@
1
1
  module Fontist
2
2
  module Import
3
3
  module Google
4
+ def self.metadata_name(path)
5
+ metadata_path = File.join(path, "METADATA.pb")
6
+ return unless File.exists?(metadata_path)
7
+
8
+ File.foreach(metadata_path) do |line|
9
+ name = line.match(/^name: "(.+)"/)
10
+ return name[1] if name
11
+ end
12
+ end
13
+
4
14
  def self.formula_path(name)
5
15
  filename = name.downcase.gsub(" ", "_") + ".yml"
6
16
  Fontist.formulas_path.join("google", filename)
7
17
  end
8
18
 
19
+ def self.digest(path)
20
+ checksums = Dir.glob(File.join(path, "*.{ttf,otf,ttc}"))
21
+ .sort
22
+ .map { |x| Digest::SHA256.file(x).to_s }
23
+
24
+ Digest::SHA256.hexdigest(checksums.to_s)
25
+ end
26
+
9
27
  def self.style_version(text)
10
28
  return unless text
11
29
 
@@ -4,17 +4,12 @@ module Fontist
4
4
  module Import
5
5
  class GoogleCheck
6
6
  def call
7
- fetch_formulas
8
7
  fonts = new_fonts
9
8
  indicate(fonts)
10
9
  end
11
10
 
12
11
  private
13
12
 
14
- def fetch_formulas
15
- Formula.update_formulas_repo
16
- end
17
-
18
13
  def new_fonts
19
14
  Fontist::Import::Google::NewFontsFetcher.new(logging: true).call
20
15
  end
@@ -26,8 +21,6 @@ module Fontist
26
21
  new_paths.each do |path|
27
22
  puts path
28
23
  end
29
-
30
- abort
31
24
  end
32
25
  end
33
26
  end