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

[macOS] Emit FileModifiedEvent on permission change #815

Merged
merged 3 commits into from Jul 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion changelog.rst
Expand Up @@ -9,7 +9,8 @@ Changelog
2021-xx-x • `full history <https://github.com/gorakhargosh/watchdog/compare/v2.1.3...master>`__

- [watchmedo] Fix usage of ``os.setsid()`` and ``os.killpg()`` Unix-only functions. (`#809 <https://github.com/gorakhargosh/watchdog/pull/809>`_)
- Thanks to our beloved contributors: @replabrobin, @BoboTiG
- [mac] Fix missing ``FileModifiedEvent`` on permission or ownership changes of a file. (`#809 <https://github.com/gorakhargosh/watchdog/pull/814>`_)
- Thanks to our beloved contributors: @replabrobin, @BoboTiG, @SamSchott

2.1.3
~~~~~
Expand Down
11 changes: 8 additions & 3 deletions src/watchdog/observers/fsevents.py
Expand Up @@ -156,6 +156,11 @@ def _is_historic_created_event(self, event):

return in_history or before_start

@staticmethod
def _is_meta_mod(event):
"""Returns True if the event indicates a change in metadata."""
return event.is_inode_meta_mod or event.is_xattr_mod or event.is_owner_change

def queue_events(self, timeout, events):

if logger.getEffectiveLevel() <= logging.DEBUG:
Expand Down Expand Up @@ -209,7 +214,7 @@ def queue_events(self, timeout, events):

self._fs_view.add(event.inode)

if event.is_modified or event.is_inode_meta_mod or event.is_xattr_mod:
if event.is_modified or self._is_meta_mod(event):
self._queue_modified_event(event, src_path, src_dirname)

self._queue_deleted_event(event, src_path, src_dirname)
Expand All @@ -222,7 +227,7 @@ def queue_events(self, timeout, events):

self._fs_view.add(event.inode)

if event.is_modified or event.is_inode_meta_mod or event.is_xattr_mod:
if event.is_modified or self._is_meta_mod(event):
self._queue_modified_event(event, src_path, src_dirname)

if event.is_renamed:
Expand All @@ -247,7 +252,7 @@ def queue_events(self, timeout, events):

events.remove(dst_event)

if dst_event.is_modified or dst_event.is_inode_meta_mod or dst_event.is_xattr_mod:
if dst_event.is_modified or self._is_meta_mod(dst_event):
self._queue_modified_event(dst_event, dst_path, dst_dirname)

if dst_event.is_removed:
Expand Down
16 changes: 16 additions & 0 deletions tests/test_emitter.py
Expand Up @@ -15,6 +15,7 @@
# limitations under the License.

import os
import stat
import time
import pytest
import logging
Expand Down Expand Up @@ -195,6 +196,21 @@ def test_modify():
assert isinstance(event, FileClosedEvent)


@pytest.mark.flaky(max_runs=5, min_passes=1, rerun_filter=rerun_filter)
def test_chmod():
mkfile(p('a'))
start_watching()

# Note: We use S_IREAD here because chmod on Windows only
# allows setting the read-only flag.
os.chmod(p('a'), stat.S_IREAD)

expect_event(FileModifiedEvent(p('a')))

# Reset permissions to allow cleanup.
os.chmod(p('a'), stat.S_IWRITE)


@pytest.mark.flaky(max_runs=5, min_passes=1, rerun_filter=rerun_filter)
def test_move():
mkdir(p('dir1'))
Expand Down