Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Social plugin throws error during build when running docker on Windows #5508

Closed
4 tasks done
joshooaj opened this issue May 11, 2023 · 2 comments
Closed
4 tasks done
Labels
bug Issue reports a bug 🏆 perfect Issue is of outstanding quality resolved Issue is resolved, yet unreleased if open

Comments

@joshooaj
Copy link
Contributor

Context

No response

Bug description

When calling mkdocs build using mkdocs-material-insiders with the social and privacy plugins in a docker container on Windows, I see the error below. I think I tracked it down to the use of os.replace(..) on line 709 of squidfunk/mkdocs-material-insiders:src/plugins/social/plugin.py.

I'm running Windows 11 with docker desktop, and using a docker image built from the unaltered insiders repo. What appears to be happening is that os.replace(..) is attempting to create a symbolic link from '/tmp/tmpcw97qgbh/Roboto-ThinItalic.ttf' to '/docs/.cache/plugin/social/fonts/Roboto/Thin Italic.ttf', and since this is a docker container, the '/docs/' folder is mapped to my host OS and os.replace(..) does not appear to allow you to move files/folders "between drives".

If I replace os.replace(file, os.path.join(path, family, f"{name}.ttf")) with shutil.move(file, os.path.join(path, family, f"{name}.ttf")) the issue goes away and the build succeeds.

site_name: My Docs
site_url: https://example.local

theme:
  name: material

plugins:
  - social
  - privacy
ERROR    -  Error building page 'index.md': [Errno 18] Cross-device link: '/tmp/tmpcw97qgbh/Roboto-ThinItalic.ttf' -> '.cache/plugin/social/fonts/Roboto/Thin Italic.ttf'
Traceback (most recent call last):
  File "/usr/local/bin/mkdocs", line 8, in <module>
    sys.exit(cli())
             ^^^^^
  File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1130, in __call__
    return self.main(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1055, in main
    rv = self.invoke(ctx)
         ^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1657, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/click/core.py", line 760, in invoke
    return __callback(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/mkdocs/__main__.py", line 250, in build_command
    build.build(cfg, dirty=not clean)
  File "/usr/local/lib/python3.11/site-packages/mkdocs/commands/build.py", line 329, in build
    _build_page(file.page, config, doc_files, nav, env, dirty)
  File "/usr/local/lib/python3.11/site-packages/mkdocs/commands/build.py", line 234, in _build_page
    output = config.plugins.run_event('post_page', output, page=page, config=config)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/mkdocs/plugins.py", line 520, in run_event
    result = method(item, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/material/plugins/social/plugin.py", line 151, in on_post_page
    raise future.exception()
  File "/usr/local/lib/python3.11/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/material/plugins/social/plugin.py", line 284, in _generate
    self.card_layer_jobs[h].result(),
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/concurrent/futures/_base.py", line 456, in result
    return self.__get_result()
           ^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/concurrent/futures/_base.py", line 401, in __get_result
    raise self._exception
  File "/usr/local/lib/python3.11/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/material/plugins/social/plugin.py", line 318, in _render
    image = self._render_typography(layer, image)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/material/plugins/social/plugin.py", line 402, in _render_typography
    path = self._resolve_font(family, styles)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/material/plugins/social/plugin.py", line 647, in _resolve_font
    self._fetch_font_from_google_fonts(family)
  File "/usr/local/lib/python3.11/site-packages/material/plugins/social/plugin.py", line 709, in _fetch_font_from_google_fonts
    os.replace(file, os.path.join(path, family, f"{name}.ttf"))
OSError: [Errno 18] Cross-device link: '/tmp/tmpcw97qgbh/Roboto-ThinItalic.ttf' -> '.cache/plugin/social/fonts/Roboto/Thin Italic.ttf'

Related links

Reproduction

example.zip

Steps to reproduce

  1. Build a container image from the mkdocs-material-insiders repo.
  2. Create a new mkdocs site with a minimal mkdocs.yml.
  3. Add the social and privacy plugins to mkdocs.yml.
  4. Build the site using the container. For example: docker run -v "$PWD:/docs" mkdocs-material-insiders build`.

Browser

No response

Before submitting

@squidfunk squidfunk added the bug Issue reports a bug label May 12, 2023
@squidfunk
Copy link
Owner

squidfunk commented May 12, 2023

Thanks for the excellent bug report and reproduction, and taking the time to investigate and provide a solution. You're right, we should switch to shutil.move, as it's higher-level than os.replace and accounts for moving files between different drives, the exact use case reported here. Fixed in d328ee60f. The privacy plugin should've nothing to do with the problem, since it doesn't use the os.replace functionality.

This bug report is awarded the 🏆 perfect badge.

@squidfunk squidfunk added resolved Issue is resolved, yet unreleased if open 🏆 perfect Issue is of outstanding quality labels May 12, 2023
@squidfunk
Copy link
Owner

Released as part of 9.1.12+insiders-4.33.2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue reports a bug 🏆 perfect Issue is of outstanding quality resolved Issue is resolved, yet unreleased if open
Projects
None yet
Development

No branches or pull requests

2 participants