fontist 1.7.3 → 1.8.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/release.yml +38 -0
  3. data/.github/workflows/rspec.yml +58 -0
  4. data/README.md +48 -4
  5. data/{bin → exe}/fontist +0 -0
  6. data/fontist.gemspec +10 -7
  7. data/lib/fontist.rb +9 -2
  8. data/lib/fontist/cli.rb +64 -55
  9. data/lib/fontist/errors.rb +63 -12
  10. data/lib/fontist/font.rb +33 -64
  11. data/lib/fontist/font_installer.rb +118 -0
  12. data/lib/fontist/font_path.rb +29 -0
  13. data/lib/fontist/fontist_font.rb +3 -49
  14. data/lib/fontist/formula.rb +101 -35
  15. data/lib/fontist/formula_paths.rb +43 -0
  16. data/lib/fontist/helpers.rb +7 -0
  17. data/lib/fontist/import/create_formula.rb +3 -2
  18. data/lib/fontist/import/extractors.rb +4 -0
  19. data/lib/fontist/import/extractors/cpio_extractor.rb +39 -0
  20. data/lib/fontist/import/extractors/gzip_extractor.rb +27 -0
  21. data/lib/fontist/import/extractors/rpm_extractor.rb +45 -0
  22. data/lib/fontist/import/extractors/tar_extractor.rb +47 -0
  23. data/lib/fontist/import/google/skiplist.yml +3 -0
  24. data/lib/fontist/import/google_check.rb +1 -1
  25. data/lib/fontist/import/google_import.rb +3 -4
  26. data/lib/fontist/import/otfinfo_generate.rb +1 -1
  27. data/lib/fontist/import/recursive_extraction.rb +26 -8
  28. data/lib/fontist/import/sil_import.rb +99 -0
  29. data/lib/fontist/index.rb +11 -0
  30. data/lib/fontist/indexes/base_index.rb +82 -0
  31. data/lib/fontist/indexes/filename_index.rb +19 -0
  32. data/lib/fontist/indexes/font_index.rb +21 -0
  33. data/lib/fontist/indexes/index_formula.rb +36 -0
  34. data/lib/fontist/manifest/install.rb +4 -5
  35. data/lib/fontist/manifest/locations.rb +9 -1
  36. data/lib/fontist/system_font.rb +32 -62
  37. data/lib/fontist/system_index.rb +47 -5
  38. data/lib/fontist/utils.rb +5 -0
  39. data/lib/fontist/utils/cache.rb +12 -4
  40. data/lib/fontist/utils/cpio/cpio.rb +199 -0
  41. data/lib/fontist/utils/cpio_extractor.rb +47 -0
  42. data/lib/fontist/utils/exe_extractor.rb +1 -1
  43. data/lib/fontist/utils/gzip_extractor.rb +24 -0
  44. data/lib/fontist/utils/locking.rb +17 -0
  45. data/lib/fontist/utils/rpm_extractor.rb +37 -0
  46. data/lib/fontist/utils/tar_extractor.rb +61 -0
  47. data/lib/fontist/utils/zip_extractor.rb +1 -1
  48. data/lib/fontist/version.rb +1 -1
  49. metadata +74 -26
  50. data/.github/workflows/macosx.yml +0 -33
  51. data/.github/workflows/ubuntu.yml +0 -30
  52. data/.github/workflows/windows.yml +0 -32
  53. data/bin/check_google +0 -8
  54. data/bin/console +0 -11
  55. data/bin/convert_formulas +0 -8
  56. data/bin/generate_otfinfo +0 -8
  57. data/bin/import_google +0 -8
  58. data/bin/rspec +0 -29
  59. data/bin/setup +0 -7
  60. data/lib/fontist/font_formula.rb +0 -169
  61. data/lib/fontist/formula_template.rb +0 -122
  62. data/lib/fontist/formulas.rb +0 -56
  63. data/lib/fontist/registry.rb +0 -43
@@ -1,50 +1,43 @@
1
+ require "fontist/index"
2
+ require "fontist/helpers"
3
+ require "git"
4
+
1
5
  module Fontist
2
6
  class Formula
3
- def initialize(options = {})
4
- @font_name = options.fetch(:font_name, nil)
5
- @style_name = options.fetch(:style_name, nil)
6
-
7
- check_and_register_font_formulas
7
+ 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
8
15
  end
9
16
 
10
17
  def self.all
11
- new.all
18
+ Dir[Fontist.formulas_path.join("**/*.yml").to_s].map do |path|
19
+ Formula.new_from_file(path)
20
+ end
12
21
  end
13
22
 
14
23
  def self.find(font_name)
15
- new(font_name: font_name).find
24
+ Indexes::FontIndex.from_yaml.load_formulas(font_name).first
16
25
  end
17
26
 
18
- def self.find_fonts(name)
19
- new(font_name: name).find_fonts
20
- end
21
-
22
- def self.find_styles(font, style)
23
- new(font_name: font, style_name: style).find_styles
24
- end
27
+ def self.find_fonts(font_name)
28
+ formulas = Indexes::FontIndex.from_yaml.load_formulas(font_name)
25
29
 
26
- def all
27
- @all ||= Fontist::Registry.instance.formulas
28
- end
29
-
30
- def find
31
- formulas.values.detect do |formula|
32
- formula.fonts.any? do |f|
33
- f.name.casecmp?(font_name)
34
- end
35
- end
36
- end
37
-
38
- def find_fonts
39
- formulas.values.map do |formula|
30
+ formulas.map do |formula|
40
31
  formula.fonts.select do |f|
41
32
  f.name.casecmp?(font_name)
42
33
  end
43
34
  end.flatten
44
35
  end
45
36
 
46
- def find_styles
47
- formulas.values.map do |formula|
37
+ def self.find_styles(font_name, style_name)
38
+ formulas = Indexes::FontIndex.from_yaml.load_formulas(font_name)
39
+
40
+ formulas.map do |formula|
48
41
  formula.fonts.map do |f|
49
42
  f.styles.select do |s|
50
43
  f.name.casecmp?(font_name) && s.type.casecmp?(style_name)
@@ -53,16 +46,89 @@ module Fontist
53
46
  end.flatten
54
47
  end
55
48
 
49
+ def self.new_from_file(path)
50
+ data = YAML.load_file(path)
51
+ new(data, path)
52
+ end
53
+
54
+ def initialize(data, path)
55
+ @data = data
56
+ @path = path
57
+ end
58
+
59
+ def to_index_formula
60
+ Indexes::IndexFormula.new(path)
61
+ end
62
+
63
+ def path
64
+ @path
65
+ end
66
+
67
+ def key
68
+ @data["key"] || default_key
69
+ end
70
+
71
+ def description
72
+ @data["description"]
73
+ end
74
+
75
+ def homepage
76
+ @data["homepage"]
77
+ end
78
+
79
+ def copyright
80
+ @data["copyright"]
81
+ end
82
+
83
+ def license_url
84
+ @data["license_url"]
85
+ end
86
+
87
+ def license
88
+ @data["open_license"] || @data["requires_license_agreement"]
89
+ end
90
+
91
+ def license_required
92
+ @data["requires_license_agreement"] ? true : false
93
+ end
94
+
95
+ def extract
96
+ Helpers.parse_to_object(@data["extract"])
97
+ end
98
+
99
+ def resources
100
+ Helpers.parse_to_object(@data["resources"].values)
101
+ end
102
+
103
+ def fonts
104
+ @fonts ||= Helpers.parse_to_object(hash_collection_fonts + hash_fonts)
105
+ end
106
+
56
107
  private
57
108
 
58
- attr_reader :font_name, :style_name
109
+ def default_key
110
+ escaped = Regexp.escape(Fontist.formulas_path.to_s + "/")
111
+ @path.sub(Regexp.new("^" + escaped), "").sub(/\.yml$/, "")
112
+ end
113
+
114
+ def hash_collection_fonts
115
+ return [] unless @data["font_collections"]
116
+
117
+ @data["font_collections"].flat_map do |coll|
118
+ filenames = { "font" => coll["filename"],
119
+ "source_font" => coll["source_filename"] }
59
120
 
60
- def formulas
61
- @formulas ||= all.to_h
121
+ coll["fonts"].map do |font|
122
+ { "name" => font["name"],
123
+ "styles" => font["styles"].map { |s| filenames.merge(s) } }
124
+ end
125
+ end
62
126
  end
63
127
 
64
- def check_and_register_font_formulas
65
- $check_and_register_font_formulas ||= Fontist::Formulas.register_formulas
128
+ def hash_fonts
129
+ return [] unless @data["fonts"]
130
+
131
+ @data["fonts"]
66
132
  end
67
133
  end
68
134
  end
@@ -0,0 +1,43 @@
1
+ module Fontist
2
+ class FormulaPaths
3
+ attr_reader :font_paths
4
+
5
+ def initialize(font_paths)
6
+ @font_paths = font_paths
7
+ end
8
+
9
+ def find(font, style = nil)
10
+ styles = find_styles_by_formulas(font, style)
11
+ return if styles.empty?
12
+
13
+ fonts = styles.uniq { |s| s["font"] }.flat_map do |s|
14
+ paths = search_font_paths(s["font"])
15
+ paths.map do |path|
16
+ { full_name: s["full_name"],
17
+ path: path }
18
+ end
19
+ end
20
+
21
+ fonts.empty? ? nil : fonts
22
+ end
23
+
24
+ private
25
+
26
+ def find_styles_by_formulas(font, style)
27
+ if style
28
+ Formula.find_styles(font, style)
29
+ else
30
+ fonts = Formula.find_fonts(font)
31
+ return [] unless fonts
32
+
33
+ fonts.flat_map(&:styles)
34
+ end
35
+ end
36
+
37
+ def search_font_paths(filename)
38
+ font_paths.select do |path|
39
+ File.basename(path) == filename
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,7 @@
1
+ module Fontist
2
+ module Helpers
3
+ def self.parse_to_object(data)
4
+ JSON.parse(data.to_json, object_class: OpenStruct)
5
+ end
6
+ end
7
+ end
@@ -50,9 +50,10 @@ module Fontist
50
50
 
51
51
  def save(hash)
52
52
  filename = Import.name_to_filename(hash[:name])
53
+ path = @options[:formula_dir] ? File.join(@options[:formula_dir], filename) : filename
53
54
  yaml = YAML.dump(Helpers::HashHelper.stringify_keys(hash))
54
- File.write(filename, yaml)
55
- filename
55
+ File.write(path, yaml)
56
+ path
56
57
  end
57
58
  end
58
59
  end
@@ -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
@@ -6,3 +6,6 @@
6
6
  - Open Sans
7
7
  - Work Sans
8
8
  - Fira Code
9
+ - Andika
10
+ - Harmattan
11
+ - Padauk
@@ -12,7 +12,7 @@ module Fontist
12
12
  private
13
13
 
14
14
  def fetch_formulas
15
- Formulas.fetch_formulas
15
+ Formula.update_formulas_repo
16
16
  end
17
17
 
18
18
  def new_fonts
@@ -156,10 +156,9 @@ module Fontist
156
156
  h.merge!(family_name: style.family_name,
157
157
  type: style.style,
158
158
  full_name: style.full_name)
159
- h.merge!(style.to_h.slice(:post_script_name,
160
- :version,
161
- :description,
162
- :copyright).compact)
159
+ h.merge!(style.to_h.select do |k, _|
160
+ %i(post_script_name version description copyright).include?(k)
161
+ end.compact)
163
162
  h.merge!(font: fix_variable_filename(style.filename))
164
163
  end
165
164
  end
@@ -25,7 +25,7 @@ module Fontist
25
25
  def font_paths(font)
26
26
  formula = Fontist::Formula.find(font)
27
27
  font_formula = Object.const_get(formula.installer)
28
- font_formula.fetch_font(nil, confirmation: "yes")
28
+ font_formula.install(confirmation: "yes")
29
29
  end
30
30
 
31
31
  def generate_styles(paths)