fontist 1.8.6 → 1.8.11

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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rspec.yml +5 -14
  3. data/README.md +3 -3
  4. data/fontist.gemspec +3 -7
  5. data/lib/fontist/cli.rb +3 -1
  6. data/lib/fontist/font.rb +20 -15
  7. data/lib/fontist/font_installer.rb +40 -39
  8. data/lib/fontist/formula.rb +4 -0
  9. data/lib/fontist/import/helpers/system_helper.rb +1 -3
  10. data/lib/fontist/import/recursive_extraction.rb +25 -119
  11. data/lib/fontist/manifest/install.rb +10 -3
  12. data/lib/fontist/utils.rb +0 -8
  13. data/lib/fontist/utils/cache.rb +27 -8
  14. data/lib/fontist/utils/downloader.rb +81 -36
  15. data/lib/fontist/version.rb +1 -1
  16. metadata +14 -89
  17. data/lib/fontist/import/extractors.rb +0 -9
  18. data/lib/fontist/import/extractors/cab_extractor.rb +0 -37
  19. data/lib/fontist/import/extractors/cpio_extractor.rb +0 -39
  20. data/lib/fontist/import/extractors/extractor.rb +0 -19
  21. data/lib/fontist/import/extractors/gzip_extractor.rb +0 -27
  22. data/lib/fontist/import/extractors/ole_extractor.rb +0 -41
  23. data/lib/fontist/import/extractors/rpm_extractor.rb +0 -45
  24. data/lib/fontist/import/extractors/seven_zip_extractor.rb +0 -44
  25. data/lib/fontist/import/extractors/tar_extractor.rb +0 -47
  26. data/lib/fontist/import/extractors/zip_extractor.rb +0 -31
  27. data/lib/fontist/utils/cpio/cpio.rb +0 -199
  28. data/lib/fontist/utils/cpio_extractor.rb +0 -47
  29. data/lib/fontist/utils/exe_extractor.rb +0 -75
  30. data/lib/fontist/utils/gzip_extractor.rb +0 -24
  31. data/lib/fontist/utils/msi_extractor.rb +0 -31
  32. data/lib/fontist/utils/rpm_extractor.rb +0 -37
  33. data/lib/fontist/utils/seven_zip_extractor.rb +0 -41
  34. data/lib/fontist/utils/tar_extractor.rb +0 -61
  35. data/lib/fontist/utils/zip_extractor.rb +0 -52
@@ -1,9 +0,0 @@
1
- require_relative "extractors/extractor"
2
- require_relative "extractors/zip_extractor"
3
- require_relative "extractors/ole_extractor"
4
- require_relative "extractors/seven_zip_extractor"
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"
@@ -1,37 +0,0 @@
1
- module Fontist
2
- module Import
3
- module Extractors
4
- class CabExtractor < Extractor
5
- def extract
6
- dir = Dir.mktmpdir
7
- extract_exe(@archive, dir)
8
- dir
9
- end
10
-
11
- def format
12
- File.extname(@archive) == ".exe" ? "exe" : "cab"
13
- end
14
-
15
- private
16
-
17
- def extract_exe(archive, dir)
18
- opened = decompressor.search(archive)
19
- file = opened.files
20
-
21
- while file
22
- path = File.join(dir, file.filename)
23
- decompressor.extract(file, path)
24
- file = file.next
25
- end
26
- end
27
-
28
- def decompressor
29
- @decompressor ||= begin
30
- require "libmspack"
31
- LibMsPack::CabDecompressor.new
32
- end
33
- end
34
- end
35
- end
36
- end
37
- end
@@ -1,39 +0,0 @@
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
@@ -1,19 +0,0 @@
1
- module Fontist
2
- module Import
3
- module Extractors
4
- class Extractor
5
- def initialize(archive)
6
- @archive = archive
7
- end
8
-
9
- def extract
10
- raise NotImplementedError.new("You must implement this method")
11
- end
12
-
13
- def format
14
- raise NotImplementedError.new("You must implement this method")
15
- end
16
- end
17
- end
18
- end
19
- end
@@ -1,27 +0,0 @@
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
@@ -1,41 +0,0 @@
1
- module Fontist
2
- module Import
3
- module Extractors
4
- class OleExtractor < Extractor
5
- def extract
6
- dir = Dir.mktmpdir
7
- extract_ole(@archive, dir)
8
- dir
9
- end
10
-
11
- def format
12
- "msi"
13
- end
14
-
15
- private
16
-
17
- def extract_ole(archive, dir)
18
- ole = storage.open(archive)
19
- file = the_largest_file(ole)
20
-
21
- content = ole.file.read(file)
22
- path = File.join(dir, "data.cab")
23
- File.open(path, "wb") { |f| f.write(content) }
24
- end
25
-
26
- def storage
27
- @storage ||= begin
28
- require "ole/storage"
29
- Ole::Storage
30
- end
31
- end
32
-
33
- def the_largest_file(ole)
34
- ole.dir.entries(".").max_by do |x|
35
- ole.file.size(x)
36
- end
37
- end
38
- end
39
- end
40
- end
41
- end
@@ -1,45 +0,0 @@
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
@@ -1,44 +0,0 @@
1
- module Fontist
2
- module Import
3
- module Extractors
4
- class SevenZipExtractor < Extractor
5
- def extract
6
- dir = Dir.mktmpdir
7
- extract_7z(@archive, dir)
8
- dir
9
- end
10
-
11
- def try
12
- File.open(@archive, "rb") do |file|
13
- reader.open(file)
14
- end
15
-
16
- true
17
- rescue StandardError => e
18
- return false if e.message.start_with?("Invalid file format")
19
-
20
- raise
21
- end
22
-
23
- def format
24
- "seven_zip"
25
- end
26
-
27
- private
28
-
29
- def extract_7z(archive, dir)
30
- File.open(archive, "rb") do |file|
31
- reader.extract_all(file, dir)
32
- end
33
- end
34
-
35
- def reader
36
- @reader ||= begin
37
- require "seven_zip_ruby"
38
- SevenZipRuby::Reader
39
- end
40
- end
41
- end
42
- end
43
- end
44
- end
@@ -1,47 +0,0 @@
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
@@ -1,31 +0,0 @@
1
- require "zip"
2
-
3
- module Fontist
4
- module Import
5
- module Extractors
6
- class ZipExtractor < Extractor
7
- def extract
8
- dir = Dir.mktmpdir
9
- extract_zip(@archive, dir)
10
- dir
11
- end
12
-
13
- def format
14
- "zip"
15
- end
16
-
17
- private
18
-
19
- def extract_zip(archive, dir)
20
- Zip::File.open(archive) do |zip_file|
21
- zip_file.each do |entry|
22
- path = File.join(dir, entry.name)
23
- FileUtils.mkdir_p(File.dirname(path))
24
- entry.extract(path)
25
- end
26
- end
27
- end
28
- end
29
- end
30
- end
31
- end
@@ -1,199 +0,0 @@
1
- # code is obtained from https://github.com/jordansissel/ruby-arr-pm/blob/8071591173ebb90dea27d5acfdde69a37dcb2744/cpio.rb
2
- # rubocop:disable all
3
- class BoundedIO
4
- attr_reader :length
5
- attr_reader :remaining
6
-
7
- def initialize(io, length, &eof_callback)
8
- @io = io
9
- @length = length
10
- @remaining = length
11
-
12
- @eof_callback = eof_callback
13
- @eof = false
14
- end
15
-
16
- def read(size=nil)
17
- return nil if eof?
18
- size = @remaining if size.nil?
19
- data = @io.read(size)
20
- @remaining -= data.bytesize
21
- eof?
22
- data
23
- end
24
-
25
- def sysread(size)
26
- raise EOFError, "end of file reached" if eof?
27
- read(size)
28
- end
29
-
30
- def eof?
31
- return false if @remaining > 0
32
- return @eof if @eof
33
-
34
- @eof_callback.call
35
- @eof = true
36
- end
37
- end
38
-
39
- module CPIO
40
- FIELDS = [
41
- :magic, :ino, :mode, :uid, :gid, :nlink, :mtime, :filesize, :devmajor,
42
- :devminor, :rdevmajor, :rdevminor, :namesize, :check
43
- ]
44
- end
45
-
46
- class CPIO::ASCIIReader
47
- FIELD_SIZES = {
48
- :magic => 6,
49
- :ino => 8,
50
- :mode => 8,
51
- :uid => 8,
52
- :gid => 8,
53
- :nlink => 8,
54
- :mtime => 8,
55
- :filesize => 8,
56
- :devmajor => 8,
57
- :devminor => 8,
58
- :rdevmajor => 8,
59
- :rdevminor => 8,
60
- :namesize => 8,
61
- :check => 8
62
- }
63
- HEADER_LENGTH = FIELD_SIZES.reduce(0) { |m, (_, v)| m + v }
64
- HEADER_PACK = FIELD_SIZES.collect { |_, v| "A#{v}" }.join
65
-
66
- FIELD_ORDER = [
67
- :magic, :ino, :mode, :uid, :gid, :nlink, :mtime, :filesize, :devmajor,
68
- :devminor, :rdevmajor, :rdevminor, :namesize, :check
69
- ]
70
-
71
- def initialize(io)
72
- @io = io
73
- end
74
-
75
- private
76
-
77
- def io
78
- @io
79
- end
80
-
81
- def each(&block)
82
- while true
83
- entry = read
84
- break if entry.nil?
85
- # The CPIO format has the end-of-stream marker as a file called "TRAILER!!!"
86
- break if entry.name == "TRAILER!!!"
87
- block.call(entry, entry.file)
88
- verify_correct_read(entry) unless entry.directory?
89
- end
90
- end
91
-
92
- def verify_correct_read(entry)
93
- # Read and throw away the whole file if not read at all.
94
- entry.file.tap do |file|
95
- if file.nil? || file.remaining == 0
96
- # All OK! :)
97
- elsif file.remaining == file.length
98
- file.read(16384) while !file.eof?
99
- else
100
- # The file was only partially read? This should be an error by the
101
- # user.
102
- consumed = file.length - file.remaining
103
- raise BadState, "Only #{consumed} bytes were read of the #{file.length} byte file: #{entry.name}"
104
- end
105
- end
106
- end
107
-
108
- def read
109
- entry = CPIOEntry.new
110
- header = io.read(HEADER_LENGTH)
111
- return nil if header.nil?
112
- FIELD_ORDER.zip(header.unpack(HEADER_PACK)).each do |field, value|
113
- entry.send("#{field}=", value.to_i(16))
114
- end
115
-
116
- entry.validate
117
- entry.mtime = Time.at(entry.mtime)
118
- read_name(entry, @io)
119
- read_file(entry, @io)
120
- entry
121
- end
122
-
123
- def read_name(entry, io)
124
- entry.name = io.read(entry.namesize - 1) # - 1 for null terminator
125
- nul = io.read(1)
126
- raise ArgumentError, "Corrupt CPIO or bug? Name null terminator was not null: #{nul.inspect}" if nul != "\0"
127
- padding_data = io.read(padding_name(entry))
128
- # Padding should be all null bytes
129
- if padding_data != ("\0" * padding_data.bytesize)
130
- raise ArgumentError, "Corrupt CPIO or bug? Name null padding was #{padding_name(entry)} bytes: #{padding_data.inspect}"
131
- end
132
- end
133
-
134
- def read_file(entry, io)
135
- if entry.directory?
136
- entry.file = nil
137
- #read_file_padding(entry, io)
138
- nil
139
- else
140
- entry.file = BoundedIO.new(io, entry.filesize) do
141
- read_file_padding(entry, io)
142
- end
143
- end
144
- end
145
-
146
- def read_file_padding(entry, io)
147
- padding_data = io.read(padding_file(entry))
148
- if padding_data != ("\0" * padding_data.bytesize)
149
- raise ArgumentError, "Corrupt CPIO or bug? File null padding was #{padding_file(entry)} bytes: #{padding_data.inspect}"
150
- end
151
- end
152
-
153
- def padding_name(entry)
154
- # name padding is padding up to a multiple of 4 after header+namesize
155
- -(HEADER_LENGTH + entry.namesize) % 4
156
- end
157
-
158
- def padding_file(entry)
159
- (-(HEADER_LENGTH + entry.filesize + 2) % 4)
160
- end
161
- public(:each)
162
- end
163
-
164
- class CPIOEntry
165
- CPIO::FIELDS.each do |field|
166
- attr_accessor field
167
- end
168
-
169
- attr_accessor :name
170
- attr_accessor :file
171
-
172
- DIRECTORY_FLAG = 0040000
173
-
174
- def validate
175
- raise "Invalid magic #{magic.inspect}" if magic != 0x070701
176
- raise "Invalid ino #{ino.inspect}" if ino < 0
177
- raise "Invalid mode #{mode.inspect}" if mode < 0
178
- raise "Invalid uid #{uid.inspect}" if uid < 0
179
- raise "Invalid gid #{gid.inspect}" if gid < 0
180
- raise "Invalid nlink #{nlink.inspect}" if nlink < 0
181
- raise "Invalid mtime #{mtime.inspect}" if mtime < 0
182
- raise "Invalid filesize #{filesize.inspect}" if filesize < 0
183
- raise "Invalid devmajor #{devmajor.inspect}" if devmajor < 0
184
- raise "Invalid devminor #{devminor.inspect}" if devminor < 0
185
- raise "Invalid rdevmajor #{rdevmajor.inspect}" if rdevmajor < 0
186
- raise "Invalid rdevminor #{rdevminor.inspect}" if rdevminor < 0
187
- raise "Invalid namesize #{namesize.inspect}" if namesize < 0
188
- raise "Invalid check #{check.inspect}" if check < 0
189
- end # def validate
190
-
191
- def read(*args)
192
- return nil if directory?
193
- file.read(*args)
194
- end
195
-
196
- def directory?
197
- mode & DIRECTORY_FLAG > 0
198
- end
199
- end