|
4 | 4 | import os |
5 | 5 | import pathlib |
6 | 6 | from abc import ABC, abstractmethod |
7 | | -from typing import List, Optional, Sequence, Tuple |
| 7 | +from typing import Iterable, List, Optional, Sequence, Tuple |
8 | 8 |
|
9 | 9 | from halo import Halo |
10 | 10 | from patch_ng import fromfile |
@@ -318,23 +318,24 @@ def on_disk_version(self) -> Optional[Version]: |
318 | 318 | ) |
319 | 319 | return None |
320 | 320 |
|
321 | | - def _on_disk_hash(self) -> Optional[str]: |
| 321 | + def _on_disk_hash(self) -> Tuple[Iterable[FileInfo], Optional[str]]: |
322 | 322 | """Get the hash of the project on disk. |
323 | 323 |
|
324 | 324 | Returns: |
325 | 325 | Str: Could be None if no on disk version |
326 | 326 | """ |
327 | 327 | if not os.path.exists(self.__metadata.path): |
328 | | - return None |
| 328 | + return [], None |
329 | 329 |
|
330 | 330 | try: |
331 | | - return Metadata.from_file(self.__metadata.path).hash |
| 331 | + metadata = Metadata.from_file(self.__metadata.path) |
| 332 | + return metadata.files, metadata.hash |
332 | 333 | except TypeError: |
333 | 334 | logger.warning( |
334 | 335 | f"{pathlib.Path(self.__metadata.path).relative_to(os.getcwd()).as_posix()}" |
335 | 336 | " is an invalid metadata file, not checking local hash!" |
336 | 337 | ) |
337 | | - return None |
| 338 | + return [], None |
338 | 339 |
|
339 | 340 | def _check_for_newer_version(self) -> Optional[Version]: |
340 | 341 | """Check if a newer version is available on the given branch. |
@@ -374,11 +375,24 @@ def _are_there_local_changes(self) -> bool: |
374 | 375 | Bool: True if there are local changes, false if no were detected or no hash was found. |
375 | 376 | """ |
376 | 377 | logger.debug(f"Checking if there were local changes in {self.local_path}") |
377 | | - on_disk_hash = self._on_disk_hash() |
378 | 378 |
|
379 | | - return bool(on_disk_hash) and on_disk_hash != hash_directory( |
380 | | - self.local_path, skiplist=[self.__metadata.FILENAME] |
381 | | - ) |
| 379 | + file_info, on_disk_hash = self._on_disk_hash() |
| 380 | + |
| 381 | + if not file_info: |
| 382 | + return bool(on_disk_hash) and on_disk_hash != hash_directory( |
| 383 | + self.local_path, skiplist=[self.__metadata.FILENAME] |
| 384 | + ) |
| 385 | + |
| 386 | + for file in file_info: |
| 387 | + full_path = os.path.join(self.local_path, file.path) |
| 388 | + if hash_file_normalized(full_path).hexdigest() != file.hash: |
| 389 | + logger.debug(f"The hash of {full_path} changed!") |
| 390 | + return True |
| 391 | + if oct(os.stat(full_path).st_mode)[-3:] != file.permissions: |
| 392 | + logger.debug(f"The file permissions of {full_path} changed!") |
| 393 | + return True |
| 394 | + |
| 395 | + return False |
382 | 396 |
|
383 | 397 | @abstractmethod |
384 | 398 | def _fetch_impl(self, version: Version) -> Version: |
|
0 commit comments