fontist 1.8.7 → 1.8.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rspec.yml +1 -10
  3. data/.rubocop.yml +3 -3
  4. data/README.md +3 -3
  5. data/fontist.gemspec +2 -6
  6. data/lib/fontist/cli.rb +3 -1
  7. data/lib/fontist/font.rb +2 -1
  8. data/lib/fontist/font_installer.rb +40 -39
  9. data/lib/fontist/formula_paths.rb +1 -0
  10. data/lib/fontist/import/helpers/system_helper.rb +1 -3
  11. data/lib/fontist/import/recursive_extraction.rb +25 -119
  12. data/lib/fontist/manifest/install.rb +11 -4
  13. data/lib/fontist/manifest/locations.rb +20 -6
  14. data/lib/fontist/system_font.rb +4 -12
  15. data/lib/fontist/utils.rb +0 -8
  16. data/lib/fontist/utils/cache.rb +27 -8
  17. data/lib/fontist/utils/downloader.rb +74 -32
  18. data/lib/fontist/version.rb +1 -1
  19. metadata +12 -87
  20. data/lib/fontist/import/extractors.rb +0 -9
  21. data/lib/fontist/import/extractors/cab_extractor.rb +0 -37
  22. data/lib/fontist/import/extractors/cpio_extractor.rb +0 -39
  23. data/lib/fontist/import/extractors/extractor.rb +0 -19
  24. data/lib/fontist/import/extractors/gzip_extractor.rb +0 -27
  25. data/lib/fontist/import/extractors/ole_extractor.rb +0 -41
  26. data/lib/fontist/import/extractors/rpm_extractor.rb +0 -45
  27. data/lib/fontist/import/extractors/seven_zip_extractor.rb +0 -44
  28. data/lib/fontist/import/extractors/tar_extractor.rb +0 -47
  29. data/lib/fontist/import/extractors/zip_extractor.rb +0 -31
  30. data/lib/fontist/utils/cpio/cpio.rb +0 -199
  31. data/lib/fontist/utils/cpio_extractor.rb +0 -47
  32. data/lib/fontist/utils/exe_extractor.rb +0 -75
  33. data/lib/fontist/utils/gzip_extractor.rb +0 -24
  34. data/lib/fontist/utils/msi_extractor.rb +0 -31
  35. data/lib/fontist/utils/rpm_extractor.rb +0 -44
  36. data/lib/fontist/utils/seven_zip_extractor.rb +0 -41
  37. data/lib/fontist/utils/tar_extractor.rb +0 -61
  38. data/lib/fontist/utils/zip_extractor.rb +0 -52
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 69bc4225a7dac5b44f92364344568e4990ec3917631febbab1739a4980890308
4
- data.tar.gz: b1bd65c7db74152b911375a6990cda7dd23f849291feeb00edd3fddda5b93f4d
3
+ metadata.gz: d1ece96735fa8114f5ce56d56217b20208e8c5dced1c8d0b4092094ebac4ec17
4
+ data.tar.gz: 30e6189789d580d5c6bd56aa12d02c91057a05a286ec513469c4897d193a2542
5
5
  SHA512:
6
- metadata.gz: 298d8927f07494407568e35fea9a3ed6fc26a725df7dcd9f4a6f3e134be628bc38bc315b0d61bac63c15c92501396b04c8e59dcad59429420785fdeaf9d4ac22
7
- data.tar.gz: 27f7bf0e155c8c3210030de3e5d1f140b4b0cee26214ca48c5cf34136eb09f8850f80178aa331b608c61583af003c8d7ca4ac071601e3fe8dbbebd25e6e15e9d
6
+ metadata.gz: 20044f9435f70398c851eca878a846dad762c065ace4de9efcd6b1c05a3b5c6e9ab1f6bef4aefdf6231db020f3d5cb4454c5a2e4cf4c1f151f19288890449b11
7
+ data.tar.gz: d93ca29eedc83eeb4fb60b574ae254b277eb210e2e1e8fbcad68ad6a15d86f3f2fe981f549444fdfb13f559221cd2bc03b73f0a00a89496f7a22482c6493afa3
@@ -33,20 +33,11 @@ jobs:
33
33
  - uses: ruby/setup-ruby@v1
34
34
  with:
35
35
  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 }}
36
+ bundler-cache: true
42
37
 
43
38
  - if: matrix.os == 'macos-latest'
44
39
  run: brew install lcdf-typetools
45
40
 
46
- - run: bundle config set path 'vendor/bundle'
47
-
48
- - run: bundle install --jobs 4 --retry 3
49
-
50
41
  - if: matrix.os == 'macos-latest'
51
42
  run: bundle exec rspec
52
43
  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
 
data/fontist.gemspec CHANGED
@@ -27,15 +27,11 @@ Gem::Specification.new do |spec|
27
27
  spec.executables = ["fontist"]
28
28
  spec.test_files = `git ls-files -- {spec}/*`.split("\n")
29
29
 
30
- spec.add_runtime_dependency "arr-pm", "~> 0.0.1"
31
30
  spec.add_runtime_dependency "down", "~> 5.0"
32
- spec.add_runtime_dependency "libmspack", "~> 0.1.0"
33
- spec.add_runtime_dependency "rubyzip", "~> 2.3.0"
34
- spec.add_runtime_dependency "seven_zip_ruby", "~> 1.0"
35
- spec.add_runtime_dependency "ruby-ole", "~> 1.0"
36
31
  spec.add_runtime_dependency "thor", "~> 1.0.1"
37
32
  spec.add_runtime_dependency "git", "~> 1.0"
38
- spec.add_runtime_dependency "ttfunk", "~> 1.0"
33
+ spec.add_runtime_dependency "ttfunk", "~> 1.6"
34
+ spec.add_runtime_dependency "excavate", "~> 0.1"
39
35
 
40
36
  spec.add_development_dependency "extract_ttc", "~> 0.1"
41
37
  spec.add_development_dependency "pry"
data/lib/fontist/cli.rb CHANGED
@@ -31,12 +31,14 @@ module Fontist
31
31
  desc: "Install even if it's already installed in system"
32
32
  option :accept_all_licenses, type: :boolean, aliases: "--confirm-license", desc: "Accept all license agreements"
33
33
  option :hide_licenses, type: :boolean, desc: "Hide license texts"
34
+ option :no_progress, type: :boolean, desc: "Hide download progress"
34
35
  def install(font)
35
36
  Fontist::Font.install(
36
37
  font,
37
38
  force: options[:force],
38
39
  confirmation: options[:accept_all_licenses] ? "yes" : "no",
39
- hide_licenses: options[:hide_licenses]
40
+ hide_licenses: options[:hide_licenses],
41
+ no_progress: options[:no_progress]
40
42
  )
41
43
  success
42
44
  rescue Fontist::Errors::GeneralError => e
data/lib/fontist/font.rb CHANGED
@@ -7,6 +7,7 @@ module Fontist
7
7
  @name = options[:name]
8
8
  @confirmation = options[:confirmation] || "no"
9
9
  @hide_licenses = options[:hide_licenses]
10
+ @no_progress = options[:no_progress] || false
10
11
  @force = options[:force] || false
11
12
 
12
13
  check_or_create_fontist_path!
@@ -94,7 +95,7 @@ module Fontist
94
95
  end
95
96
 
96
97
  def font_installer(formula)
97
- FontInstaller.new(formula)
98
+ FontInstaller.new(formula, no_progress: @no_progress)
98
99
  end
99
100
 
100
101
  def formula
@@ -1,18 +1,11 @@
1
1
  require "fontist/utils"
2
+ require "excavate"
2
3
 
3
4
  module Fontist
4
5
  class FontInstaller
5
- include Utils::ZipExtractor
6
- include Utils::ExeExtractor
7
- include Utils::MsiExtractor
8
- include Utils::SevenZipExtractor
9
- include Utils::RpmExtractor
10
- include Utils::GzipExtractor
11
- include Utils::CpioExtractor
12
- include Utils::TarExtractor
13
-
14
- def initialize(formula)
6
+ def initialize(formula, no_progress: false)
15
7
  @formula = formula
8
+ @no_progress = no_progress
16
9
  end
17
10
 
18
11
  def install(confirmation:)
@@ -20,7 +13,6 @@ module Fontist
20
13
  raise(Fontist::Errors::LicensingError)
21
14
  end
22
15
 
23
- reinitialize
24
16
  install_font
25
17
  end
26
18
 
@@ -28,10 +20,6 @@ module Fontist
28
20
 
29
21
  attr_reader :formula
30
22
 
31
- def reinitialize
32
- @downloaded = false
33
- end
34
-
35
23
  def install_font
36
24
  fonts_paths = run_in_temp_dir { extract }
37
25
  fonts_paths.empty? ? nil : fonts_paths
@@ -50,47 +38,39 @@ module Fontist
50
38
  end
51
39
 
52
40
  def extract
53
- resource = @formula.resources.first
54
-
55
- [@formula.extract].flatten.each do |operation|
56
- resource = extract_by_operation(operation, resource)
57
- end
58
-
59
- fonts_paths = resource
41
+ archive = download_file(@formula.resources.first)
60
42
 
61
- fonts_paths
43
+ install_fonts_from_archive(archive)
62
44
  end
63
45
 
64
- def extract_by_operation(operation, resource)
65
- method = "#{operation.format}_extract"
66
- if operation.options
67
- send(method, resource, **operation.options.to_h)
68
- else
69
- send(method, resource)
70
- end
71
- end
46
+ def install_fonts_from_archive(archive)
47
+ Fontist.ui.say(%(Installing font "#{@formula.key}".))
72
48
 
73
- def fonts_path
74
- Fontist.fonts_path
49
+ Array.new.tap do |fonts_paths|
50
+ Excavate::Archive.new(archive.path).files(recursive_packages: true) do |path|
51
+ fonts_paths << install_font_file(path) if font_file?(path)
52
+ end
53
+ end
75
54
  end
76
55
 
77
56
  def download_file(source)
78
57
  url = source.urls.first
79
58
  Fontist.ui.say(%(Downloading font "#{@formula.key}" from #{url}))
80
59
 
81
- downloaded_file = Fontist::Utils::Downloader.download(
60
+ Fontist::Utils::Downloader.download(
82
61
  url,
83
62
  sha: source.sha256,
84
63
  file_size: source.file_size,
85
- progress_bar: true
64
+ progress_bar: !@no_progress
86
65
  )
66
+ end
87
67
 
88
- @downloaded = true
89
- downloaded_file
68
+ def font_file?(path)
69
+ source_file?(path) && font_directory?(path)
90
70
  end
91
71
 
92
- def font_file?(filename)
93
- source_files.include?(filename)
72
+ def source_file?(path)
73
+ source_files.include?(File.basename(path))
94
74
  end
95
75
 
96
76
  def source_files
@@ -101,6 +81,27 @@ module Fontist
101
81
  end
102
82
  end
103
83
 
84
+ def font_directory?(path)
85
+ return true unless subdirectory_pattern
86
+
87
+ File.fnmatch?(subdirectory_pattern, File.dirname(path))
88
+ end
89
+
90
+ def subdirectory_pattern
91
+ @subdirectory_pattern ||= "*" + subdirectories.first.chomp("/") unless subdirectories.empty?
92
+ end
93
+
94
+ def subdirectories
95
+ @subdirectories ||= [@formula.extract].flatten.map(&:options).compact.map(&:fonts_sub_dir).compact
96
+ end
97
+
98
+ def install_font_file(source)
99
+ target = Fontist.fonts_path.join(target_filename(File.basename(source))).to_s
100
+ FileUtils.mv(source, target)
101
+
102
+ target
103
+ end
104
+
104
105
  def target_filename(source_filename)
105
106
  target_filenames[source_filename]
106
107
  end
@@ -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
@@ -4,9 +4,7 @@ module Fontist
4
4
  module SystemHelper
5
5
  class << self
6
6
  def run(command)
7
- unless ENV.fetch("TEST_ENV", "") === "CI"
8
- Fontist.ui.say("Run `#{command}`")
9
- end
7
+ Fontist.ui.say("Run `#{command}`")
10
8
 
11
9
  result = `#{command}`
12
10
  unless $CHILD_STATUS.to_i.zero?
@@ -1,21 +1,18 @@
1
- require "find"
2
- require_relative "extractors"
3
1
  require_relative "files/font_detector"
4
2
 
5
3
  module Fontist
6
4
  module Import
7
5
  class RecursiveExtraction
8
- FONTS_PATTERN = "**/*.{ttf,otf,ttc}".freeze
9
- ARCHIVE_EXTENSIONS = %w[zip msi exe cab].freeze
10
6
  LICENSE_PATTERN = /(ofl\.txt|ufl\.txt|licenses?\.txt|copying)$/i.freeze
11
7
 
12
8
  def initialize(archive, subarchive: nil, subdir: nil)
13
9
  @archive = archive
14
- @subarchive = subarchive
15
10
  @subdir = subdir
16
- @operations = []
11
+ @operations = {}
17
12
  @font_files = []
18
13
  @collection_files = []
14
+
15
+ save_operation_subdir
19
16
  end
20
17
 
21
18
  def extension
@@ -39,11 +36,18 @@ module Fontist
39
36
 
40
37
  def operations
41
38
  ensure_extracted
42
- @operations.size == 1 ? @operations.first : @operations
39
+ @operations
43
40
  end
44
41
 
45
42
  private
46
43
 
44
+ def save_operation_subdir
45
+ return unless @subdir
46
+
47
+ @operations[:options] ||= {}
48
+ @operations[:options][:fonts_sub_dir] = @subdir
49
+ end
50
+
47
51
  def fetch_extension(file)
48
52
  File.extname(filename(file)).sub(/^\./, "")
49
53
  end
@@ -57,68 +61,21 @@ module Fontist
57
61
  end
58
62
 
59
63
  def ensure_extracted
60
- extracted_path
61
- end
64
+ return if @extracted
62
65
 
63
- def extracted_path
64
- @extracted_path ||= extract_recursively(@archive)
66
+ extract_data(@archive)
67
+ @extracted = true
65
68
  end
66
69
 
67
- def extract_recursively(archive)
68
- path = operate_on_archive(archive)
69
- match_files(path)
70
- if matched?
71
- save_operation_subdir
72
- return path
73
- end
74
-
75
- next_archive = find_archive(path)
76
- extract_recursively(next_archive)
77
- end
78
-
79
- def operate_on_archive(archive)
80
- extractor = choose_extractor(archive)
81
- Fontist.ui.say("Extracting #{archive} with #{extractor.class.name}")
82
-
83
- save_operation(extractor)
84
- extractor.extract
85
- end
86
-
87
- # rubocop:disable Metrics/MethodLength
88
- def choose_extractor(archive)
89
- case fetch_extension(archive).downcase
90
- when "msi"
91
- Extractors::OleExtractor.new(archive)
92
- when "cab"
93
- Extractors::CabExtractor.new(archive)
94
- when "exe"
95
- extractor = Extractors::SevenZipExtractor.new(archive)
96
- extractor.try ? extractor : Extractors::CabExtractor.new(archive)
97
- when "zip"
98
- Extractors::ZipExtractor.new(archive)
99
- when "rpm"
100
- Extractors::RpmExtractor.new(archive)
101
- when "gz"
102
- Extractors::GzipExtractor.new(archive)
103
- when "cpio"
104
- Extractors::CpioExtractor.new(archive)
105
- when "tar"
106
- Extractors::TarExtractor.new(archive)
107
- else
108
- raise Errors::UnknownArchiveError, "Could not unarchive `#{filename(archive)}`."
70
+ def extract_data(archive)
71
+ Excavate::Archive.new(path(archive)).files(recursive_packages: true) do |path|
72
+ match_license(path)
73
+ match_font(path) if font_directory?(path)
109
74
  end
110
75
  end
111
- # rubocop:enable Metrics/MethodLength
112
76
 
113
- def save_operation(extractor)
114
- @operations << { format: extractor.format }
115
- end
116
-
117
- def match_files(dir_path)
118
- Find.find(dir_path) do |entry_path| # rubocop:disable Style/CollectionMethods
119
- match_license(entry_path)
120
- match_font(entry_path) if font_directory?(entry_path, dir_path)
121
- end
77
+ def path(file)
78
+ file.respond_to?(:path) ? file.path : file
122
79
  end
123
80
 
124
81
  def match_license(path)
@@ -129,18 +86,6 @@ module Fontist
129
86
  file.match?(LICENSE_PATTERN)
130
87
  end
131
88
 
132
- def font_directory?(path, base_path)
133
- return true unless @subdir
134
-
135
- # https://bugs.ruby-lang.org/issues/10011
136
- base_path = Pathname.new(base_path)
137
-
138
- relative_path = Pathname.new(path).relative_path_from(base_path).to_s
139
- dirname = File.dirname(relative_path)
140
- normalized_pattern = @subdir.chomp("/")
141
- File.fnmatch?(normalized_pattern, dirname)
142
- end
143
-
144
89
  def match_font(path)
145
90
  case Files::FontDetector.detect(path)
146
91
  when :font
@@ -150,53 +95,14 @@ module Fontist
150
95
  end
151
96
  end
152
97
 
153
- def matched?
154
- [@font_files, @collection_files].any? do |files|
155
- files.size.positive?
156
- end
157
- end
158
-
159
- def save_operation_subdir
160
- return unless @subdir
161
-
162
- @operations.last[:options] ||= {}
163
- @operations.last[:options][:fonts_sub_dir] = @subdir
164
- end
165
-
166
- def find_archive(path)
167
- children = Dir.entries(path) - [".", ".."] # ruby 2.4 compat
168
- paths = children.map { |file| File.join(path, file) }
169
- by_subarchive(paths) || by_size(paths)
170
- end
171
-
172
- def by_subarchive(paths)
173
- return unless @subarchive
174
-
175
- path_found = paths.detect do |path|
176
- @subarchive == File.basename(path)
177
- end
178
-
179
- return unless path_found
180
-
181
- save_operation_subarchive(path_found)
182
-
183
- path_found
184
- end
185
-
186
- def save_operation_subarchive(path)
187
- @operations.last[:options] ||= {}
188
- @operations.last[:options][:subarchive] = File.basename(path)
189
- end
98
+ def font_directory?(path)
99
+ return true unless subdirectory_pattern
190
100
 
191
- def by_size(paths)
192
- paths.max_by do |path|
193
- [file_type(path), File.size(path)]
194
- end
101
+ File.fnmatch?(subdirectory_pattern, File.dirname(path))
195
102
  end
196
103
 
197
- def file_type(file_path)
198
- extension = File.extname(file_path).delete(".")
199
- ARCHIVE_EXTENSIONS.include?(extension) ? 1 : 0
104
+ def subdirectory_pattern
105
+ @subdirectory_pattern ||= "*" + @subdir.chomp("/") if @subdir
200
106
  end
201
107
  end
202
108
  end