Skip to content

Commit

Permalink
Improve warnings about new install method
Browse files Browse the repository at this point in the history
Display informative message when users forget to install the `extra` needed for the vendor-specific profile they're trying to run
(issue #4292)
  • Loading branch information
felipesanches committed Oct 12, 2023
1 parent 2bf3c83 commit 18b1d37
Show file tree
Hide file tree
Showing 11 changed files with 129 additions and 48 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ A more detailed list of changes is available in the corresponding milestones for
### Release notes
- This release adds support for marking checks as **experimental**, which will make them not affect the process exit code and so will allow such checks to result in a FAIL without breaking continuous integration builds. This will give time for users to report problems on the implementation of new checks. If after some time nobody complains, then those new checks will more safely be made effective by removing their `experimental` tag.

- **Bugfix:** Display informative message when users forget to install the `extra` needed for the vendor-specific profile they're trying to run (issue #4292)

### New checks
#### Addded to the Google Fonts Profile
- **EXPERIMENTAL - [com.google.fonts/check/metadata/empty_designer]:** Any font published on Google Fonts must credit one or several authors, foundry and/or individuals. (issue #3961)
Expand Down
3 changes: 3 additions & 0 deletions Lib/fontbakery/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@


def run_profile_check(profilename):
from fontbakery.utils import set_profile_name

set_profile_name(profilename)
module = import_module(f"fontbakery.profiles.{profilename}")
sys.exit(check_profile_main(module.profile))

Expand Down
2 changes: 1 addition & 1 deletion Lib/fontbakery/profiles/fontval.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
try:
import lxml.etree
except ImportError:
exit_with_install_instructions("fontval")
exit_with_install_instructions()

profile_imports = [".shared_conditions"]
profile = profile_factory(
Expand Down
79 changes: 57 additions & 22 deletions Lib/fontbakery/profiles/googlefonts.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,13 +254,14 @@
)
def com_google_fonts_check_canonical_filename(ttFont):
"""Checking file is named canonically."""

try:
from axisregistry import build_filename

current_filename = os.path.basename(ttFont.reader.file.name)
expected_filename = build_filename(ttFont)
except ImportError:
exit_with_install_instructions("googlefonts")
exit_with_install_instructions()

current_filename = os.path.basename(ttFont.reader.file.name)
expected_filename = build_filename(ttFont)

if current_filename != expected_filename:
yield FAIL, Message(
Expand Down Expand Up @@ -375,11 +376,14 @@ def com_google_fonts_check_description_urls(description_html):

@condition
def description_html(description):
try:
from lxml import etree
except ImportError:
exit_with_install_instructions()

if not description:
return

from lxml import etree

html = "<html>" + description + "</html>"
try:
return etree.fromstring(html)
Expand Down Expand Up @@ -444,8 +448,12 @@ def com_google_fonts_check_description_git_url(description_html):
)
def com_google_fonts_check_description_valid_html(descfile, description):
"""Is this a proper HTML snippet?"""
passed = True
try:
from lxml import html
except ImportError:
exit_with_install_instructions()

passed = True
if "<html>" in description or "</html>" in description:
yield FAIL, Message(
"html-tag",
Expand All @@ -455,8 +463,6 @@ def com_google_fonts_check_description_valid_html(descfile, description):
f" font family specimen webpage.",
)

from lxml import html

try:
html.fromstring("<html>" + description + "</html>")
except Exception as e:
Expand Down Expand Up @@ -535,8 +541,11 @@ def com_google_fonts_check_description_eof_linebreak(description):
)
def com_google_fonts_check_metadata_parses(family_directory):
"""Check METADATA.pb parse correctly."""
from google.protobuf import text_format
from fontbakery.utils import get_FamilyProto_Message
try:
from google.protobuf import text_format
from fontbakery.utils import get_FamilyProto_Message
except ImportError:
exit_with_install_instructions()

try:
pb_file = os.path.join(family_directory, "METADATA.pb")
Expand Down Expand Up @@ -1072,8 +1081,11 @@ def com_google_fonts_check_glyph_coverage(
ttFont, font_codepoints, family_metadata, config
):
"""Check Google Fonts glyph coverage."""
from glyphsets import GFGlyphData as glyph_data
import unicodedata2
try:
from glyphsets import GFGlyphData as glyph_data
import unicodedata2
except ImportError:
exit_with_install_instructions()

def missing_encoded_glyphs(glyphs):
encoded_glyphs = [g["unicode"] for g in glyphs if g["unicode"]]
Expand Down Expand Up @@ -1139,8 +1151,11 @@ def com_google_fonts_check_metadata_unsupported_subsets(
family_metadata, ttFont, font_codepoints
):
"""Check for METADATA subsets with zero support."""
from glyphsets import codepoints
from glyphsets.subsets import SUBSETS
try:
from glyphsets import codepoints
from glyphsets.subsets import SUBSETS
except ImportError:
exit_with_install_instructions()

codepoints.set_encoding_path(codepoints.nam_dir)

Expand Down Expand Up @@ -1191,13 +1206,17 @@ def com_google_fonts_check_metadata_unreachable_subsetting(
family_directory, font, ttFont, font_codepoints, config
):
"""Check for codepoints not covered by METADATA subsets."""
from glyphsets import codepoints
try:
import unicodedata2
from glyphsets import codepoints
except ImportError:
exit_with_install_instructions()

from fontbakery.utils import pretty_print_list
from fontbakery.profiles.googlefonts_conditions import (
metadata_file,
family_metadata,
)
import unicodedata2

codepoints.set_encoding_path(codepoints.nam_dir)

Expand Down Expand Up @@ -3625,7 +3644,10 @@ def glyphs_surface_area(ttFont):

@condition
def uharfbuzz_blob(font):
import uharfbuzz as hb
try:
import uharfbuzz as hb
except ImportError:
exit_with_install_instructions()

return hb.Blob.from_file_path(font)

Expand All @@ -3647,8 +3669,12 @@ def uharfbuzz_blob(font):
)
def com_google_fonts_check_slant_direction(ttFont, uharfbuzz_blob):
"""Checking direction of slnt axis angles"""
try:
import uharfbuzz as hb
except ImportError:
exit_with_install_instructions()

from fontbakery.utils import axis, PointsPen
import uharfbuzz as hb

if not axis(ttFont, "slnt"):
yield PASS, "Font has no slnt axis"
Expand Down Expand Up @@ -3968,7 +3994,10 @@ def com_google_fonts_check_fontdata_namecheck(ttFont, familyname):
)
def com_google_fonts_check_fontv(ttFont):
"""Check for font-v versioning."""
from fontv.libfv import FontVersion
try:
from fontv.libfv import FontVersion
except ImportError:
exit_with_install_instructions()

fv = FontVersion(ttFont)
if fv.version and (fv.is_development or fv.is_release):
Expand Down Expand Up @@ -6853,7 +6882,10 @@ def can_shape(ttFont, text, parameters=None):
Returns true if the font can render a text string without any
.notdef characters.
"""
from vharfbuzz import Vharfbuzz
try:
from vharfbuzz import Vharfbuzz
except ImportError:
exit_with_install_instructions()

filename = ttFont.reader.file.name
vharfbuzz = Vharfbuzz(filename)
Expand Down Expand Up @@ -6981,7 +7013,10 @@ def com_google_fonts_check_repo_sample_image(readme_contents, readme_directory,
)
def com_google_fonts_check_metadata_can_render_samples(ttFont, family_metadata):
"""Check samples can be rendered."""
from gflanguages import LoadLanguages
try:
from gflanguages import LoadLanguages
except ImportError:
exit_with_install_instructions()

passed = True
languages = LoadLanguages()
Expand Down
8 changes: 6 additions & 2 deletions Lib/fontbakery/profiles/googlefonts_conditions.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ def family_metadata(metadata_file):
try:
from google.protobuf import text_format
except ImportError:
exit_with_install_instructions("googlefonts")
exit_with_install_instructions()

from fontbakery.utils import get_FamilyProto_Message

Expand All @@ -197,9 +197,13 @@ def family_metadata(metadata_file):
@condition
def registered_vendor_ids():
"""Get a list of vendor IDs from Microsoft's website."""
from bs4 import BeautifulSoup, NavigableString
from pkg_resources import resource_filename

try:
from bs4 import BeautifulSoup, NavigableString
except ImportError:
exit_with_install_instructions()

registered_vendor_ids = {}
CACHED = resource_filename(
"fontbakery", "data/fontbakery-microsoft-vendorlist.cache"
Expand Down
2 changes: 1 addition & 1 deletion Lib/fontbakery/profiles/iso15008.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
try:
import uharfbuzz as hb
except ImportError:
exit_with_install_instructions("iso15008")
exit_with_install_instructions()

profile = profile_factory(default_section=Section("Suitability for In-Car Display"))

Expand Down
23 changes: 18 additions & 5 deletions Lib/fontbakery/profiles/shaping.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ def run_a_set_of_shaping_tests(
filename = Path(ttFont.reader.file.name)
vharfbuzz = Vharfbuzz(filename)
except ImportError:
exit_with_install_instructions("shaping")
exit_with_install_instructions()

shaping_file_found = False
ran_a_test = False
Expand Down Expand Up @@ -408,7 +408,10 @@ def com_google_fonts_check_shaping_collides(config, ttFont):


def setup_glyph_collides(ttFont, configuration):
from collidoscope import Collidoscope
try:
from collidoscope import Collidoscope
except ImportError:
exit_with_install_instructions()

filename = Path(ttFont.reader.file.name)
collidoscope_configuration = configuration.get("collidoscope")
Expand All @@ -430,7 +433,10 @@ def setup_glyph_collides(ttFont, configuration):
def run_collides_glyph_test(
filename, vharfbuzz, test, configuration, failed_shaping_tests, extra_data
):
from stringbrewer import StringBrewer
try:
from stringbrewer import StringBrewer
except ImportError:
exit_with_install_instructions()

col = extra_data["collidoscope"]
is_stringbrewer = (
Expand Down Expand Up @@ -481,7 +487,10 @@ def collides_glyph_test_results(vharfbuzz, shaping_file, failed_shaping_tests):


def is_complex_shaper_font(ttFont):
from ufo2ft.constants import INDIC_SCRIPTS, USE_SCRIPTS
try:
from ufo2ft.constants import INDIC_SCRIPTS, USE_SCRIPTS
except ImportError:
exit_with_install_instructions()

for table in ["GSUB", "GPOS"]:
if table not in ttFont:
Expand Down Expand Up @@ -603,10 +612,14 @@ def find_mark_base(lookup, attachments):
def com_google_fonts_check_soft_dotted(ttFont):
"""Ensure soft_dotted characters lose their dot when combined with marks that
replace the dot."""
try:
from vharfbuzz import Vharfbuzz
except ImportError:
exit_with_install_instructions()

import itertools
from beziers.path import BezierPath
from fontTools import unicodedata
from vharfbuzz import Vharfbuzz

cmap = ttFont["cmap"].getBestCmap()

Expand Down
12 changes: 10 additions & 2 deletions Lib/fontbakery/profiles/typenetwork.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@
from fontbakery.profiles.universal import UNIVERSAL_PROFILE_CHECKS
from fontbakery.section import Section
from fontbakery.status import PASS, FAIL, WARN, SKIP, INFO
from fontbakery.utils import add_check_overrides, bullet_list, pretty_print_list
from fontbakery.utils import (
add_check_overrides,
bullet_list,
exit_with_install_instructions,
pretty_print_list,
)
from fontbakery.constants import (
NameID,
PlatformID,
Expand Down Expand Up @@ -354,7 +359,10 @@
)
def com_typenetwork_glyph_coverage(ttFont, font_codepoints, config):
"""Check Type Network minimum glyph coverage."""
import unicodedata2
try:
import unicodedata2
except ImportError:
exit_with_install_instructions()

TN_latin_set = {
0x0020: (" ", "SPACE"),
Expand Down
18 changes: 12 additions & 6 deletions Lib/fontbakery/profiles/ufo_sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@

@condition
def ufo_font(ufo):
from fontTools.ufoLib.errors import UFOLibError

try:
from fontTools.ufoLib.errors import UFOLibError
import defcon
except ImportError:
exit_with_install_instructions()

try:
return defcon.Font(ufo)
except ImportError:
exit_with_install_instructions("ufo-sources")
except UFOLibError:
return None

Expand All @@ -45,10 +45,13 @@ def designSpace(designspace):
'an object to read, write and edit
interpolation systems for typefaces'.
"""
if designspace:
try:
from fontTools.designspaceLib import DesignSpaceDocument
import defcon
except ImportError:
exit_with_install_instructions()

if designspace:
DS = DesignSpaceDocument.fromfile(designspace)
DS.loadSourceFonts(defcon.Font)
return DS
Expand All @@ -60,9 +63,12 @@ def designspace_sources(designSpace):
Given a DesignSpaceDocument object,
return a set of UFO font sources.
"""
if designSpace:
try:
import defcon
except ImportError:
exit_with_install_instructions()

if designSpace:
return designSpace.loadSourceFonts(defcon.Font)


Expand Down
Loading

0 comments on commit 18b1d37

Please sign in to comment.