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

Ignore broken symlinks in mkdocs serve. #639

Closed
paulproteus opened this issue Jun 18, 2015 · 7 comments
Closed

Ignore broken symlinks in mkdocs serve. #639

paulproteus opened this issue Jun 18, 2015 · 7 comments
Labels

Comments

@paulproteus
Copy link

What I am experiencing:

  • When I am editing index.md in Emacs, Emacs creates files like:
➜  docs git:(master) ✗ ls -al .#*  
lrwxrwxrwx 1 paulproteus paulproteus 36 Jun 17 17:24 .#index.md -> paulproteus@charkha.27783:1434311808
  • These files are Emacs' way of using symlinks to track which computer+process was Emacs-ing the file, so that in case of a crash, Emacs can figure out how to restore its state.

What I expect:

  • When I edit somethingelse.md and press save, I expect the mkdocs livereload to reload the browser.

What I see instead:

INFO    -  Building documentation... 
ERROR   -  file not found: /home/paulproteus/projects/sandstorm/docs/.#index.md 
ERROR   -  Error building page .#index.md 
[E 150617 17:22:21 ioloop:612] Exception in callback (3, <function null_wrapper at 0x7fc883190500>)
    Traceback (most recent call last):
      File "/home/paulproteus/.local/lib/python2.7/site-packages/tornado/ioloop.py", line 866, in start
        handler_func(fd_obj, events)
      File "/home/paulproteus/.local/lib/python2.7/site-packages/tornado/stack_context.py", line 275, in null_wrapper
        return fn(*args, **kwargs)
      File "/usr/lib/python2.7/dist-packages/pyinotify.py", line 1604, in handle_read
        self.process_events()
      File "/usr/lib/python2.7/dist-packages/pyinotify.py", line 1321, in process_events
        self._default_proc_fun(revent)
      File "/home/paulproteus/.local/lib/python2.7/site-packages/livereload/watcher.py", line 152, in inotify_event
        self.callback()
      File "/home/paulproteus/.local/lib/python2.7/site-packages/livereload/handlers.py", line 65, in poll_tasks
        filepath, delay = cls.watcher.examine()
      File "/home/paulproteus/.local/lib/python2.7/site-packages/livereload/watcher.py", line 72, in examine
        func and func()
      File "/usr/lib/python2.7/dist-packages/mkdocs/serve.py", line 74, in builder
        build(config, live_server=True)
      File "/usr/lib/python2.7/dist-packages/mkdocs/build.py", line 299, in build
        build_pages(config)
      File "/usr/lib/python2.7/dist-packages/mkdocs/build.py", line 259, in build_pages
        dump_json)
      File "/usr/lib/python2.7/dist-packages/mkdocs/build.py", line 171, in _build_page
        input_content = io.open(input_path, 'r', encoding='utf-8').read()
    IOError: [Errno 2] No such file or directory: '/home/paulproteus/projects/sandstorm/docs/.#index.md'

What I propose:

  • If a "No such file or directory" error occurs, but the problem is a broken symlink, the mkdocs build should continue as if the file does not exist. Note that this arguably is a special-case to handle Emacs' own weirdness; a different way to do it would be to look at the list of git ignored files.
  • Perhaps in general, mkdocs should issue a warning (not an error) on broken symlinks, gracefully ignoring them.

I'm open to a bunch of ideas. I wanted to file this in the hopes of sparking a discussion where the maintainers of mkdocs could express their opinion about the best way forward.

Thanks so much! Also hi! I'm twitter.com/asheeshlaroia and was chatting with a mkdocs developer earlier today. Seems like a great project! I learned about it via http://ericholscher.com/blog/2014/feb/27/how-i-judge-documentation-quality/ !

@d0ugal d0ugal added the Bug label Jun 18, 2015
@d0ugal
Copy link
Member

d0ugal commented Jun 18, 2015

Interesting, I think we will want to add an extra check in the file discovery to check is the file is a symlink and then check that the target is valid. If it isn't we can ignore it. We can probably do this with a combination of os.path.islink and os.readlink.

@d0ugal d0ugal changed the title Feature request: For livereload, ignore broken symlinks Ignore broken symlinks in mkdocs serve. Jun 27, 2015
@d0ugal d0ugal added this to the 0.15.0 milestone Jun 27, 2015
d0ugal added a commit to d0ugal/mkdocs that referenced this issue Jun 27, 2015
d0ugal added a commit that referenced this issue Jun 28, 2015
@paulproteus
Copy link
Author

paulproteus commented Jun 29, 2015 via email

@d0ugal
Copy link
Member

d0ugal commented Jun 29, 2015

Happy to help :)

@ky4n
Copy link

ky4n commented Feb 17, 2016

First I'd like to point out that I like this project quite much and currently implement mkdocs for our internal repository.

Unfortunately I've stumbled on an issue caused by the way this bugfix handles symbolic links. It looks like symbolic links with relative path are not processed properly.

Sample tree (lets assume path /srv/git/repo:

docs
├── foobar.md -> foobar/README.md
├── foobaz.md -> ../cookbooks/foobaz/README.md
├── Test.md
├── index.md
└── foobaz
    ├── index.md
    └── README.md

Neither docs/foobar.md nor docs/foobaz.md will be built/served (assuming no pages listed in the config file). walk_docs_dir from config/config_options.py is having some issues with parsing the symlinks.

It looks like this happens because the CWD is different from dirpath. In my example it's dirpath: /srv/git/repo and cwd was /srv/git/repo/docs, which makes mkdocs ignore those 2 files despite they being valid symlinks.

Diff for config/config_options.py:

@@ -352,7 +349,8 @@
                 # Some editors (namely Emacs) will create temporary symlinks
                 # for internal magic. We can just ignore these files.
                 if os.path.islink(fullpath):
-                    if not os.path.exists(os.readlink(fullpath)):
+                    fp = os.path.join(dirpath, os.readlink(fullpath))
+                    if not os.path.exists(fp):
                         continue

                 relpath = os.path.normpath(os.path.relpath(fullpath, docs_dir))

This could be probably written a bit nicer so I'm just pasting the diff here.

PS. I'm using mkdocs installed via pip if that matters (ver 0.15.2)

@waylan
Copy link
Member

waylan commented Feb 17, 2016

@ky4n this sounds like a legitimate issue with a reasonable solution. Unfortunately, you risk it getting forgotten as you commented on a closed issue. It would have been better to create a new issue which links to this one for context. Actually, as you have a provided fix, a pull request would be the quickest way to have the fix applied.

@d0ugal d0ugal reopened this Feb 17, 2016
d0ugal added a commit to d0ugal/mkdocs that referenced this issue Feb 17, 2016
@d0ugal d0ugal removed this from the 0.15.0 milestone Feb 18, 2016
d0ugal added a commit to d0ugal/mkdocs that referenced this issue Feb 18, 2016
@d0ugal
Copy link
Member

d0ugal commented Feb 18, 2016

@ky4n
Copy link

ky4n commented Feb 23, 2016

@d0ugal Thank you, works like a charm.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants