fontist 1.8.2 → 1.8.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rspec.yml +6 -6
  3. data/fontist.gemspec +7 -6
  4. data/lib/fontist.rb +4 -0
  5. data/lib/fontist/cli.rb +16 -24
  6. data/lib/fontist/errors.rb +51 -2
  7. data/lib/fontist/font.rb +39 -56
  8. data/lib/fontist/font_installer.rb +4 -0
  9. data/lib/fontist/font_path.rb +29 -0
  10. data/lib/fontist/formula.rb +8 -4
  11. data/lib/fontist/import/extractors.rb +4 -0
  12. data/lib/fontist/import/extractors/cpio_extractor.rb +39 -0
  13. data/lib/fontist/import/extractors/gzip_extractor.rb +27 -0
  14. data/lib/fontist/import/extractors/rpm_extractor.rb +45 -0
  15. data/lib/fontist/import/extractors/tar_extractor.rb +47 -0
  16. data/lib/fontist/import/recursive_extraction.rb +20 -6
  17. data/lib/fontist/index.rb +4 -65
  18. data/lib/fontist/indexes/base_index.rb +82 -0
  19. data/lib/fontist/indexes/filename_index.rb +19 -0
  20. data/lib/fontist/indexes/font_index.rb +21 -0
  21. data/lib/fontist/indexes/index_formula.rb +36 -0
  22. data/lib/fontist/manifest/install.rb +3 -2
  23. data/lib/fontist/manifest/locations.rb +1 -1
  24. data/lib/fontist/system_font.rb +33 -36
  25. data/lib/fontist/system_index.rb +46 -4
  26. data/lib/fontist/utils.rb +5 -0
  27. data/lib/fontist/utils/cache.rb +12 -4
  28. data/lib/fontist/utils/cpio/cpio.rb +199 -0
  29. data/lib/fontist/utils/cpio_extractor.rb +47 -0
  30. data/lib/fontist/utils/downloader.rb +7 -4
  31. data/lib/fontist/utils/gzip_extractor.rb +24 -0
  32. data/lib/fontist/utils/locking.rb +17 -0
  33. data/lib/fontist/utils/rpm_extractor.rb +44 -0
  34. data/lib/fontist/utils/tar_extractor.rb +61 -0
  35. data/lib/fontist/version.rb +1 -1
  36. metadata +37 -11
  37. data/lib/fontist/index_formula.rb +0 -30
@@ -0,0 +1,29 @@
1
+ require "fontist/indexes/filename_index"
2
+
3
+ module Fontist
4
+ class FontPath
5
+ def initialize(path)
6
+ @path = path
7
+ end
8
+
9
+ def to_s
10
+ [].tap do |s|
11
+ s << "-"
12
+ s << @path
13
+ s << "(from #{formulas.join(' or ')} formula)" if formulas.any?
14
+ end.join(" ")
15
+ end
16
+
17
+ def formulas
18
+ @formulas ||= if fontist_font?
19
+ Indexes::FilenameIndex.from_yaml.load_index_formulas(File.basename(@path)).map(&:name)
20
+ else
21
+ []
22
+ end
23
+ end
24
+
25
+ def fontist_font?
26
+ @path.start_with?(Fontist.fonts_path.to_s)
27
+ end
28
+ end
29
+ end
@@ -21,11 +21,15 @@ module Fontist
21
21
  end
22
22
 
23
23
  def self.find(font_name)
24
- Index.from_yaml.load_formulas(font_name).first
24
+ Indexes::FontIndex.from_yaml.load_formulas(font_name).first
25
+ end
26
+
27
+ def self.find_many(font_name)
28
+ Indexes::FontIndex.from_yaml.load_formulas(font_name)
25
29
  end
26
30
 
27
31
  def self.find_fonts(font_name)
28
- formulas = Index.from_yaml.load_formulas(font_name)
32
+ formulas = Indexes::FontIndex.from_yaml.load_formulas(font_name)
29
33
 
30
34
  formulas.map do |formula|
31
35
  formula.fonts.select do |f|
@@ -35,7 +39,7 @@ module Fontist
35
39
  end
36
40
 
37
41
  def self.find_styles(font_name, style_name)
38
- formulas = Index.from_yaml.load_formulas(font_name)
42
+ formulas = Indexes::FontIndex.from_yaml.load_formulas(font_name)
39
43
 
40
44
  formulas.map do |formula|
41
45
  formula.fonts.map do |f|
@@ -57,7 +61,7 @@ module Fontist
57
61
  end
58
62
 
59
63
  def to_index_formula
60
- IndexFormula.new(path)
64
+ Indexes::IndexFormula.new(path)
61
65
  end
62
66
 
63
67
  def path
@@ -3,3 +3,7 @@ require_relative "extractors/zip_extractor"
3
3
  require_relative "extractors/ole_extractor"
4
4
  require_relative "extractors/seven_zip_extractor"
5
5
  require_relative "extractors/cab_extractor"
6
+ require_relative "extractors/rpm_extractor"
7
+ require_relative "extractors/gzip_extractor"
8
+ require_relative "extractors/cpio_extractor"
9
+ require_relative "extractors/tar_extractor"
@@ -0,0 +1,39 @@
1
+ module Fontist
2
+ module Import
3
+ module Extractors
4
+ class CpioExtractor < Extractor
5
+ def extract
6
+ dir = Dir.mktmpdir
7
+ extract_cpio(@archive, dir)
8
+ dir
9
+ end
10
+
11
+ def format
12
+ "cpio"
13
+ end
14
+
15
+ private
16
+
17
+ def extract_cpio(archive, dir)
18
+ archive_file = File.open(archive, "rb")
19
+
20
+ reader_class.new(archive_file).each do |entry, file|
21
+ path = File.join(dir, entry.name)
22
+ if entry.directory?
23
+ FileUtils.mkdir_p(path)
24
+ else
25
+ File.write(path, file.read)
26
+ end
27
+ end
28
+ end
29
+
30
+ def reader_class
31
+ @reader_class ||= begin
32
+ require "fontist/utils/cpio/cpio"
33
+ CPIO::ASCIIReader
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,27 @@
1
+ module Fontist
2
+ module Import
3
+ module Extractors
4
+ class GzipExtractor < Extractor
5
+ def extract
6
+ dir = Dir.mktmpdir
7
+ extract_gzip(@archive, dir)
8
+ dir
9
+ end
10
+
11
+ def format
12
+ "gzip"
13
+ end
14
+
15
+ private
16
+
17
+ def extract_gzip(archive, dir)
18
+ Zlib::GzipReader.open(archive) do |gz|
19
+ basename = File.basename(archive, ".*")
20
+ path = File.join(dir, basename)
21
+ File.write(path, gz.read)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,45 @@
1
+ module Fontist
2
+ module Import
3
+ module Extractors
4
+ class RpmExtractor < Extractor
5
+ def extract
6
+ dir = Dir.mktmpdir
7
+ extract_rpm(@archive, dir)
8
+ dir
9
+ end
10
+
11
+ def format
12
+ "rpm"
13
+ end
14
+
15
+ private
16
+
17
+ def extract_rpm(archive, dir)
18
+ file = File.open(archive, "rb")
19
+ rpm = rpm_class.new(file)
20
+ content = rpm.payload.read
21
+ path = target_path(archive, rpm.tags, dir)
22
+
23
+ File.write(path, content)
24
+ ensure
25
+ file.close
26
+ end
27
+
28
+ def rpm_class
29
+ @rpm_class ||= begin
30
+ require "arr-pm"
31
+ RPM::File
32
+ end
33
+ end
34
+
35
+ def target_path(archive, tags, dir)
36
+ archive_format = tags[:payloadformat]
37
+ compression_format = tags[:payloadcompressor] == "gzip" ? "gz" : tags[:payloadcompressor]
38
+ basename = File.basename(archive, ".*")
39
+ filename = basename + "." + archive_format + "." + compression_format
40
+ File.join(dir, filename)
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,47 @@
1
+ module Fontist
2
+ module Import
3
+ module Extractors
4
+ class TarExtractor < Extractor
5
+ def extract
6
+ dir = Dir.mktmpdir
7
+ extract_tar(@archive, dir)
8
+ dir
9
+ end
10
+
11
+ def format
12
+ "tar"
13
+ end
14
+
15
+ private
16
+
17
+ def extract_tar(archive, dir)
18
+ archive_file = File.open(archive, "rb")
19
+ reader_class.new(archive_file) do |tar|
20
+ tar.each do |tarfile|
21
+ save_tar_file(tarfile, dir)
22
+ end
23
+ end
24
+ end
25
+
26
+ def reader_class
27
+ @reader_class ||= begin
28
+ require "rubygems/package"
29
+ Gem::Package::TarReader
30
+ end
31
+ end
32
+
33
+ def save_tar_file(file, dir)
34
+ path = File.join(dir, file.full_name)
35
+
36
+ if file.directory?
37
+ FileUtils.mkdir_p(path)
38
+ else
39
+ File.open(path, "wb") do |f|
40
+ f.print(file.read)
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -19,7 +19,7 @@ module Fontist
19
19
  end
20
20
 
21
21
  def extension
22
- File.extname(filename(@archive)).sub(/^\./, "")
22
+ fetch_extension(@archive)
23
23
  end
24
24
 
25
25
  def font_files
@@ -44,6 +44,10 @@ module Fontist
44
44
 
45
45
  private
46
46
 
47
+ def fetch_extension(file)
48
+ File.extname(filename(file)).sub(/^\./, "")
49
+ end
50
+
47
51
  def filename(file)
48
52
  if file.respond_to?(:original_filename)
49
53
  file.original_filename
@@ -82,16 +86,26 @@ module Fontist
82
86
 
83
87
  # rubocop:disable Metrics/MethodLength
84
88
  def choose_extractor(archive)
85
- case filename(archive)
86
- when /\.msi$/i
89
+ case fetch_extension(archive).downcase
90
+ when "msi"
87
91
  Extractors::OleExtractor.new(archive)
88
- when /\.cab$/i
92
+ when "cab"
89
93
  Extractors::CabExtractor.new(archive)
90
- when /\.exe$/i
94
+ when "exe"
91
95
  extractor = Extractors::SevenZipExtractor.new(archive)
92
96
  extractor.try ? extractor : Extractors::CabExtractor.new(archive)
93
- else
97
+ when "zip"
94
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)}`."
95
109
  end
96
110
  end
97
111
  # rubocop:enable Metrics/MethodLength
data/lib/fontist/index.rb CHANGED
@@ -1,72 +1,11 @@
1
- require_relative "index_formula"
1
+ require_relative "indexes/font_index"
2
+ require_relative "indexes/filename_index"
2
3
 
3
4
  module Fontist
4
5
  class Index
5
- def self.from_yaml
6
- unless File.exist?(Fontist.formula_index_path)
7
- raise Errors::FormulaIndexNotFoundError.new("Please fetch index with `fontist update`.")
8
- end
9
-
10
- data = YAML.load_file(Fontist.formula_index_path)
11
- new(data)
12
- end
13
-
14
6
  def self.rebuild
15
- index = new
16
- index.build
17
- index.to_yaml
18
- end
19
-
20
- def initialize(data = {})
21
- @index = {}
22
-
23
- data.each_pair do |font, paths|
24
- paths.each do |path|
25
- add_index_formula(font, IndexFormula.new(path))
26
- end
27
- end
28
- end
29
-
30
- def build
31
- Formula.all.each do |formula|
32
- add_formula(formula)
33
- end
34
- end
35
-
36
- def add_formula(formula)
37
- formula.fonts.each do |font|
38
- add_index_formula(font.name, formula.to_index_formula)
39
- end
40
- end
41
-
42
- def add_index_formula(font_raw, index_formula)
43
- font = normalize_font(font_raw)
44
- @index[font] ||= []
45
- @index[font] << index_formula unless @index[font].include?(index_formula)
46
- end
47
-
48
- def load_formulas(font)
49
- index_formulas(font).map(&:to_full)
50
- end
51
-
52
- def to_yaml
53
- File.write(Fontist.formula_index_path, YAML.dump(to_h))
54
- end
55
-
56
- def to_h
57
- @index.map do |font, index_formulas|
58
- [font, index_formulas.map(&:to_s)]
59
- end.to_h
60
- end
61
-
62
- private
63
-
64
- def index_formulas(font)
65
- @index[normalize_font(font)] || []
66
- end
67
-
68
- def normalize_font(font)
69
- font.downcase
7
+ Fontist::Indexes::FontIndex.rebuild
8
+ Fontist::Indexes::FilenameIndex.rebuild
70
9
  end
71
10
  end
72
11
  end
@@ -0,0 +1,82 @@
1
+ require_relative "index_formula"
2
+
3
+ module Fontist
4
+ module Indexes
5
+ class BaseIndex
6
+ def self.from_yaml
7
+ @from_yaml ||= begin
8
+ unless File.exist?(path)
9
+ raise Errors::FormulaIndexNotFoundError.new("Please fetch `#{path}` index with `fontist update`.")
10
+ end
11
+
12
+ data = YAML.load_file(path)
13
+ new(data)
14
+ end
15
+ end
16
+
17
+ def self.path
18
+ raise NotImplementedError, "Please define path of an index"
19
+ end
20
+
21
+ def self.rebuild
22
+ index = new
23
+ index.build
24
+ index.to_yaml
25
+ end
26
+
27
+ def initialize(data = {})
28
+ @index = {}
29
+
30
+ data.each_pair do |key, paths|
31
+ paths.each do |path|
32
+ add_index_formula(key, IndexFormula.new(path))
33
+ end
34
+ end
35
+ end
36
+
37
+ def build
38
+ Formula.all.each do |formula|
39
+ add_formula(formula)
40
+ end
41
+ end
42
+
43
+ def add_formula(_formula)
44
+ raise NotImplementedError, "Please define how to add formula to an index, use #add_index_formula"
45
+ end
46
+
47
+ def add_index_formula(key_raw, index_formula)
48
+ key = normalize_key(key_raw)
49
+ @index[key] ||= []
50
+ @index[key] << index_formula unless @index[key].include?(index_formula)
51
+ end
52
+
53
+ def load_formulas(key)
54
+ index_formulas(key).map(&:to_full)
55
+ end
56
+
57
+ def load_index_formulas(key)
58
+ index_formulas(key)
59
+ end
60
+
61
+ def to_yaml
62
+ File.write(self.class.path, YAML.dump(to_h))
63
+ end
64
+
65
+ def to_h
66
+ @index.map do |key, index_formulas|
67
+ [key, index_formulas.map(&:to_s)]
68
+ end.to_h
69
+ end
70
+
71
+ private
72
+
73
+ def index_formulas(key)
74
+ @index[normalize_key(key)] || []
75
+ end
76
+
77
+ def normalize_key(key)
78
+ key
79
+ end
80
+ end
81
+ end
82
+ end