fontist 1.7.1 → 1.8.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) 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 +123 -32
  5. data/{bin → exe}/fontist +0 -0
  6. data/fontist.gemspec +4 -2
  7. data/lib/fontist.rb +6 -3
  8. data/lib/fontist/cli.rb +66 -42
  9. data/lib/fontist/errors.rb +62 -12
  10. data/lib/fontist/font.rb +23 -37
  11. data/lib/fontist/font_installer.rb +114 -0
  12. data/lib/fontist/fontist_font.rb +3 -49
  13. data/lib/fontist/formula.rb +89 -63
  14. data/lib/fontist/formula_paths.rb +43 -0
  15. data/lib/fontist/helpers.rb +7 -0
  16. data/lib/fontist/import/create_formula.rb +3 -2
  17. data/lib/fontist/import/google/skiplist.yml +3 -0
  18. data/lib/fontist/import/google_check.rb +1 -1
  19. data/lib/fontist/import/google_import.rb +3 -4
  20. data/lib/fontist/import/otfinfo_generate.rb +1 -1
  21. data/lib/fontist/import/recursive_extraction.rb +6 -2
  22. data/lib/fontist/import/sil_import.rb +99 -0
  23. data/lib/fontist/index.rb +72 -0
  24. data/lib/fontist/index_formula.rb +30 -0
  25. data/lib/fontist/manifest/install.rb +4 -9
  26. data/lib/fontist/manifest/locations.rb +28 -20
  27. data/lib/fontist/system_font.rb +32 -91
  28. data/lib/fontist/system_index.rb +47 -5
  29. data/lib/fontist/utils.rb +1 -0
  30. data/lib/fontist/utils/cache.rb +11 -3
  31. data/lib/fontist/utils/exe_extractor.rb +1 -1
  32. data/lib/fontist/utils/locking.rb +17 -0
  33. data/lib/fontist/utils/zip_extractor.rb +1 -1
  34. data/lib/fontist/version.rb +1 -1
  35. metadata +43 -20
  36. data/.github/workflows/macosx.yml +0 -33
  37. data/.github/workflows/ubuntu.yml +0 -30
  38. data/.github/workflows/windows.yml +0 -32
  39. data/bin/check_google +0 -8
  40. data/bin/console +0 -11
  41. data/bin/convert_formulas +0 -8
  42. data/bin/generate_otfinfo +0 -8
  43. data/bin/import_google +0 -8
  44. data/bin/rspec +0 -29
  45. data/bin/setup +0 -7
  46. data/lib/fontist/font_formula.rb +0 -158
  47. data/lib/fontist/formula_template.rb +0 -122
  48. data/lib/fontist/formulas.rb +0 -56
  49. data/lib/fontist/registry.rb +0 -43
data/bin/rspec DELETED
@@ -1,29 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- #
5
- # This file was generated by Bundler.
6
- #
7
- # The application 'rspec' is installed as part of a gem, and
8
- # this file is here to facilitate running it.
9
- #
10
-
11
- require "pathname"
12
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
- Pathname.new(__FILE__).realpath)
14
-
15
- bundle_binstub = File.expand_path("../bundle", __FILE__)
16
-
17
- if File.file?(bundle_binstub)
18
- if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
- load(bundle_binstub)
20
- else
21
- abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
- Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
- end
24
- end
25
-
26
- require "rubygems"
27
- require "bundler/setup"
28
-
29
- load Gem.bin_path("rspec-core", "rspec")
data/bin/setup DELETED
@@ -1,7 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- gem install bundler --conservative
7
- bundle check || bundle install
@@ -1,158 +0,0 @@
1
- module Fontist
2
- class FontFormula
3
- include Singleton
4
- extend Fontist::Utils::Dsl
5
- include Fontist::Utils::ZipExtractor
6
- include Fontist::Utils::ExeExtractor
7
- include Fontist::Utils::MsiExtractor
8
- include Fontist::Utils::SevenZipExtractor
9
-
10
- attr_accessor :license, :license_url, :license_required, :copyright
11
- attr_accessor :key, :homepage, :description, :options, :temp_resource
12
-
13
- def font_list
14
- @font_list ||= []
15
- end
16
-
17
- def resources
18
- @resources ||= {}
19
- end
20
-
21
- def fonts
22
- @fonts ||= font_list.uniq
23
- end
24
-
25
- def extract_font_styles(options)
26
- extract_from_file(options) ||
27
- extract_from_collection(options) || default_font
28
- end
29
-
30
- def reinitialize
31
- @downloaded = false
32
- @matched_fonts = []
33
- end
34
-
35
- def self.fetch_font(name, confirmation:)
36
- if instance.license_required && confirmation.downcase != "yes"
37
- raise(Fontist::Errors::LicensingError)
38
- end
39
-
40
- instance.reinitialize
41
- instance.install_font(name, confirmation)
42
- end
43
-
44
- def install_font(name, confirmation)
45
- run_in_temp_dir { extract }
46
- matched_fonts_uniq = matched_fonts.flatten.uniq
47
- matched_fonts_uniq.empty? ? nil : matched_fonts_uniq
48
- end
49
-
50
- private
51
-
52
- attr_reader :downloaded, :matched_fonts
53
-
54
- def resource(name, &block)
55
- source = resources[name]
56
- block_given? ? yield(source) : source
57
- end
58
-
59
- def fonts_path
60
- @fonts_path = Fontist.fonts_path
61
- end
62
-
63
- def default_font
64
- [{ type: "Regular", font: temp_resource[:filename] }]
65
- end
66
-
67
- def run_in_temp_dir(&block)
68
- Dir.mktmpdir(nil, Dir.tmpdir) do |dir|
69
- @temp_dir = Pathname.new(dir)
70
-
71
- yield
72
- @temp_dir = nil
73
- end
74
- end
75
-
76
- def extract_from_file(options)
77
- styles = options.fetch(:match_styles_from_file, [])
78
-
79
- unless styles.empty?
80
- styles.map do |attributes|
81
- Fontist::Utils::Dsl::Font.new(attributes).attributes
82
- end
83
- end
84
- end
85
-
86
- def match_fonts(fonts_dir, font_name)
87
- fonts = map_names_to_fonts(font_name).join("|")
88
- font = fonts_dir.grep(/#{fonts}/i)
89
- @matched_fonts.push(font) if font
90
-
91
- font
92
- end
93
-
94
- def extract_from_collection(options)
95
- styles = options.fetch(:extract_styles_from_collection, [])
96
-
97
- unless styles.empty?
98
- styles.map do |attributes|
99
- filenames = temp_resource.slice(:filename, :source_filename)
100
- Fontist::Utils::Dsl::CollectionFont.new(attributes.merge(filenames))
101
- .attributes
102
- end
103
- end
104
- end
105
-
106
- def map_names_to_fonts(font_name)
107
- fonts = Fontist::Formula.find_fonts(font_name)
108
- fonts = fonts.map { |font| font.styles.map(&:font) }.flatten if fonts
109
-
110
- fonts || []
111
- end
112
-
113
- def download_file(source)
114
- url = source[:urls].first
115
- Fontist.ui.say(%(Downloading font "#{key}" from #{url}))
116
-
117
- downloaded_file = Fontist::Utils::Downloader.download(
118
- url,
119
- sha: source[:sha256],
120
- file_size: source[:file_size],
121
- progress_bar: is_progress_bar_enabled
122
- )
123
-
124
- @downloaded = true
125
- downloaded_file
126
- end
127
-
128
- def is_progress_bar_enabled
129
- options.nil? ? true : options.fetch(:progress_bar, true)
130
- end
131
-
132
- def font_file?(filename)
133
- source_files.include?(filename)
134
- end
135
-
136
- def source_files
137
- @source_files ||= fonts.flat_map do |font|
138
- font[:styles].map do |style|
139
- style[:source_font] || style[:font]
140
- end
141
- end
142
- end
143
-
144
- def target_filename(source_filename)
145
- target_filenames[source_filename]
146
- end
147
-
148
- def target_filenames
149
- @target_filenames ||= fonts.flat_map do |font|
150
- font[:styles].map do |style|
151
- source = style[:source_font] || style[:font]
152
- target = style[:font]
153
- [source, target]
154
- end
155
- end.to_h
156
- end
157
- end
158
- end
@@ -1,122 +0,0 @@
1
- module Fontist
2
- class FormulaTemplate
3
- def self.create_formula_class(formula)
4
- Class.new(FontFormula) do |klass|
5
- first_font = (formula.fonts || formula.font_collections.first.fonts).first
6
- cleanname = first_font.name.gsub(/ /, "")
7
- resource_name = formula.resources.to_h.keys.first
8
- font_filename = first_font.styles.first.font
9
-
10
- key formula.key&.to_sym || formula.name.gsub(/ /, "_").downcase.to_sym
11
- display_progress_bar formula.display_progress_bar if formula.display_progress_bar
12
- desc formula.description
13
- homepage formula.homepage
14
-
15
- formula.resources.to_h.each do |filename, options|
16
- resource filename do
17
- urls options.urls
18
- sha256 options.sha256
19
- end
20
- end
21
-
22
- if formula.font_collections
23
- formula.font_collections.each do |collection|
24
- provides_font_collection do
25
- filename collection.filename
26
- source_filename collection.source_filename
27
-
28
- collection.fonts.each do |font|
29
- provides_font(
30
- font.name,
31
- extract_styles_from_collection: font.styles.map do |style|
32
- {
33
- family_name: style.family_name,
34
- style: style.type,
35
- full_name: style.full_name,
36
- post_script_name: style.post_script_name,
37
- version: style.version,
38
- description: style.description,
39
- copyright: style.copyright,
40
- }
41
- end
42
- )
43
- end
44
- end
45
- end
46
- end
47
-
48
- if formula.fonts
49
- formula.fonts.each do |font|
50
- provides_font(
51
- font.name,
52
- match_styles_from_file: font.styles.map do |style|
53
- {
54
- family_name: style.family_name,
55
- style: style.type,
56
- full_name: style.full_name,
57
- post_script_name: style.post_script_name,
58
- version: style.version,
59
- description: style.description,
60
- filename: style.font,
61
- source_filename: style.source_font,
62
- copyright: style.copyright,
63
- }
64
- end
65
- )
66
- end
67
- end
68
-
69
- klass.define_method :extract do
70
- resource = resource(resource_name)
71
-
72
- [formula.extract].flatten.each do |operation|
73
- method = "#{operation.format}_extract"
74
- resource = if operation.options
75
- send(method, resource, **operation.options.to_h)
76
- else
77
- send(method, resource)
78
- end
79
- end
80
-
81
- if formula.fonts
82
- formula.fonts.each do |font|
83
- match_fonts(resource, font.name)
84
- end
85
- end
86
-
87
- if formula.font_collections
88
- formula.font_collections.each do |collection|
89
- collection.fonts.each do |font|
90
- match_fonts(resource, font.name)
91
- end
92
- end
93
- end
94
- end
95
-
96
- klass.define_method :install do
97
- case platform
98
- when :macos
99
- install_matched_fonts "$HOME/Library/Fonts/#{cleanname}"
100
- when :linux
101
- install_matched_fonts "/usr/share/fonts/truetype/#{cleanname.downcase}"
102
- end
103
- end
104
-
105
- test do
106
- case platform
107
- when :macos
108
- assert_predicate "$HOME/Library/Fonts/#{cleanname}/#{font_filename}", :exist?
109
- when :linux
110
- assert_predicate "/usr/share/fonts/truetype/#{cleanname.downcase}/#{font_filename}", :exist?
111
- end
112
- end
113
-
114
- copyright formula.copyright
115
- license_url formula.license_url
116
-
117
- open_license formula.open_license if formula.open_license
118
- requires_license_agreement formula.requires_license_agreement if formula.requires_license_agreement
119
- end
120
- end
121
- end
122
- end
@@ -1,56 +0,0 @@
1
- require "git"
2
- require "fontist/utils"
3
- require "fontist/font_formula"
4
- require "fontist/formula_template"
5
-
6
- module Fontist
7
- module Formulas
8
- def self.register_formulas
9
- load_formulas
10
- update_registry
11
- end
12
-
13
- def self.fetch_formulas
14
- if Dir.exist?(Fontist.formulas_repo_path)
15
- Git.open(Fontist.formulas_repo_path).pull
16
- else
17
- Git.clone(Fontist.formulas_repo_url,
18
- Fontist.formulas_repo_path,
19
- depth: 1)
20
- end
21
- end
22
-
23
- def self.load_formulas
24
- Dir[Fontist.formulas_path.join("**/*.yml").to_s].sort.each do |file|
25
- create_formula_class(file)
26
- end
27
- end
28
-
29
- def self.create_formula_class(file)
30
- formula = parse_to_object(YAML.load_file(file))
31
- class_name = name_to_classname(formula.name)
32
- return if Formulas.const_defined?(class_name)
33
-
34
- klass = FormulaTemplate.create_formula_class(formula)
35
- Formulas.const_set(class_name, klass)
36
- end
37
-
38
- def self.parse_to_object(hash)
39
- JSON.parse(hash.to_json, object_class: OpenStruct)
40
- end
41
-
42
- def self.update_registry
43
- Formulas.constants.select do |constant|
44
- if Formulas.const_get(constant).is_a?(Class)
45
- klass = "Fontist::Formulas::#{constant}"
46
- Fontist::Registry.register(Object.const_get(klass))
47
- end
48
- end
49
- end
50
-
51
- def self.name_to_classname(name)
52
- cleanname = name.gsub(/ /, "").sub(/\S/, &:upcase)
53
- "#{cleanname}Font"
54
- end
55
- end
56
- end
@@ -1,43 +0,0 @@
1
- module Fontist
2
- class Registry
3
- include Singleton
4
-
5
- def initialize
6
- @formulas ||= {}
7
- end
8
-
9
- def formulas
10
- parse_to_object(@formulas)
11
- end
12
-
13
- def self.formulas
14
- instance.formulas
15
- end
16
-
17
- def self.register(formula, key = nil)
18
- key ||= formula.instance.key || formula.to_s
19
- instance.register(formula, key)
20
- end
21
-
22
- def register(formula, key)
23
- @formulas[key] = build_formula_data(formula)
24
- end
25
-
26
- private
27
-
28
- def build_formula_data(formula)
29
- {
30
- installer: formula,
31
- fonts: formula.instance.fonts,
32
- license: formula.instance.license,
33
- homepage: formula.instance.homepage ,
34
- description: formula.instance.description,
35
- license_required: formula.instance.license_required,
36
- }
37
- end
38
-
39
- def parse_to_object(data)
40
- JSON.parse(data.to_json, object_class: OpenStruct)
41
- end
42
- end
43
- end