Git Office Hours : le test pour Entr'ouvert
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

git_oh.py 2.6KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. #!/usr/bin/python3
  2. """ Entrouvert test """
  3. import datetime
  4. import shutil
  5. import tempfile
  6. import warnings
  7. from collections.abc import Sequence
  8. from typing import Generator
  9. import git
  10. from git.repo.base import Repo
  11. from git.objects.commit import Commit
  12. def in_office_hours(moment:datetime.datetime=datetime.datetime.now(),
  13. starthour:datetime.time=datetime.time(8,0,0),
  14. stophour:datetime.time=datetime.time(20,0,0),
  15. weekend:Sequence[int]=(5,6))->bool:
  16. """ Indicates if a moment is in office hours.
  17. Office hours are localized, comparisons are done without
  18. taking care of tzoffset : in fact, if a working day starts at
  19. 08:00, 07:59:59+0200 is off as 07:59:59+0000 is.
  20. Arguments :
  21. - moment : the moment to compare with office hours
  22. - starthour : standard day start hour
  23. - stophour : standard day stop hour
  24. - weekend : list of days off (0,1,....,6)
  25. """
  26. for dow in weekend:
  27. if dow < 0 or dow > 6:
  28. raise ValueError("Weekend days are integer in [0..6]")
  29. if starthour.tzinfo is not None or stophour.tzinfo is not None:
  30. warnings.warn("Start & stop hours should not indicate any \
  31. tzinfo : comparisons are done without taking tzoffset in considaration")
  32. if moment.weekday() in weekend:
  33. return False
  34. localtime = moment.time()
  35. return starthour <= localtime <= stophour
  36. def iter_commits(repo:Repo)->Generator[Commit, None, None]:
  37. """ Generator on all git commits in given repository.
  38. Recursively iterate on each commit in each branch/ref not yielding
  39. duplicates commits (based on commit hashes)
  40. Arguments :
  41. - repo : The repository instance to fetch commits from
  42. """
  43. encountered = set()
  44. for ref in repo.refs:
  45. for commit in repo.iter_commits(ref.name):
  46. if commit.binsha not in encountered:
  47. encountered.add(commit.binsha)
  48. yield commit
  49. class TempRemoteRepo(Repo):
  50. """ A temporary repository referencing a remote repository
  51. Allows to iterate on all commits without cloning the remote
  52. """
  53. def __init__(self, remote_url:str):
  54. """ Initialize a new empty repository referencing a remote repo
  55. Arguments :
  56. - remote_url : The url of the remote repo to reference
  57. """
  58. self.temppath = tempfile.mkdtemp(prefix="git_oh_")
  59. git.Repo.init(self.temppath)
  60. super().__init__(self.temppath)
  61. self.create_remote("origin", remote_url).fetch()
  62. def __del__(self):
  63. shutil.rmtree(self.temppath)
  64. super().__del__()
  65. def __iter__(self)->Generator[Commit, None, None]:
  66. return iter_commits(self)