Skip to content

Commit a5ac69c

Browse files
committed
Add the support of hash content for e3.fs.get_filetree_state. ITPE-56
1 parent 8d119bf commit a5ac69c

File tree

2 files changed

+39
-3
lines changed

2 files changed

+39
-3
lines changed

src/e3/fs.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,16 +182,21 @@ def find(
182182
return result
183183

184184

185-
def get_filetree_state(path: str, ignore_hidden: bool = True) -> str:
185+
def get_filetree_state(
186+
path: str, ignore_hidden: bool = True, hash_content: bool = False
187+
) -> str:
186188
"""Compute a hash on a filetree to reflect its current state.
187189
188190
:param path: root path of the file tree to be checked
189191
:param ignore_hidden: if True (default) then files and directories
190192
tarting with a dot are ignored.
193+
:param hash_content: if True, include the content in the hash.
194+
191195
:return: a hash as a string
192196
193-
The function will not report changes in the hash if a file is modified
194-
and its attributes (size, modification time and mode) are not changed.
197+
By default, the function will not report changes in the hash if a file is
198+
modified and its attributes (size, modification time and mode) are not
199+
changed.
195200
This case is quite uncommon. By ignoring it we can compute efficiently a
196201
hash representing the state of the file tree without having to read the
197202
content of all files.
@@ -205,6 +210,10 @@ def compute_state(file_path: str) -> bytes:
205210
)
206211
return state.encode("utf-8")
207212

213+
def get_content(file_path: str) -> bytes:
214+
with open(file_path, "rb") as f:
215+
return f.read()
216+
208217
path = os.path.abspath(path)
209218
result = hashlib.sha1()
210219
if os.path.isdir(path):
@@ -225,8 +234,15 @@ def compute_state(file_path: str) -> bytes:
225234
full_path = os.path.join(root, path)
226235
result.update(compute_state(full_path))
227236

237+
if hash_content:
238+
result.update(get_content(full_path))
239+
228240
else:
229241
result.update(compute_state(path))
242+
243+
if hash_content:
244+
result.update(get_content(path))
245+
230246
return result.hexdigest()
231247

232248

tests/tests_e3/fs/main_test.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ def test_tree_state():
191191
time.sleep(2)
192192

193193
e3.os.fs.touch("toto")
194+
e3.os.fs.touch("toto2")
194195
state4 = e3.fs.get_filetree_state(current_dir)
195196
assert state4 != state3
196197
hidden = os.path.join(current_dir, ".h")
@@ -208,9 +209,28 @@ def test_tree_state():
208209
state6 = e3.fs.get_filetree_state("toto")
209210
assert isinstance(state6, str)
210211

212+
with open("toto", "wb") as f:
213+
f.write(b"hello world.")
214+
211215
# check that get_filetree_state accept unicode
212216
state7 = e3.fs.get_filetree_state("toto")
213217
assert isinstance(state7, str)
218+
assert state7 != state6
219+
220+
# check that get_filetree_state with hash_content is different that the
221+
# previous state
222+
state8 = e3.fs.get_filetree_state("toto", hash_content=True)
223+
assert isinstance(state8, str)
224+
assert state8 != state7
225+
226+
# check that get_filetree_state with hash_content is working with directory
227+
# and is different that the previous call without hash_content to true
228+
with open("toto2", "wb") as f:
229+
f.write(b"hello world 2.")
230+
231+
state9 = e3.fs.get_filetree_state(current_dir, hash_content=True)
232+
assert isinstance(state9, str)
233+
assert state9 != state4
214234

215235

216236
@pytest.mark.skipif(sys.platform == "win32", reason="test using symlink")

0 commit comments

Comments
 (0)