devopsdriver 0.1.39__tar.gz → 0.1.40__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. {devopsdriver-0.1.39 → devopsdriver-0.1.40}/PKG-INFO +3 -3
  2. {devopsdriver-0.1.39 → devopsdriver-0.1.40}/README.md +1 -1
  3. devopsdriver-0.1.40/devopsdriver/__init__.py +11 -0
  4. {devopsdriver-0.1.39 → devopsdriver-0.1.40}/devopsdriver/azdo/timestamp.py +54 -1
  5. {devopsdriver-0.1.39 → devopsdriver-0.1.40}/devopsdriver.egg-info/PKG-INFO +3 -3
  6. {devopsdriver-0.1.39 → devopsdriver-0.1.40}/pyproject.toml +1 -1
  7. {devopsdriver-0.1.39 → devopsdriver-0.1.40}/tests/test_azure_timestamp.py +61 -0
  8. devopsdriver-0.1.39/devopsdriver/__init__.py +0 -5
  9. {devopsdriver-0.1.39 → devopsdriver-0.1.40}/LICENSE +0 -0
  10. {devopsdriver-0.1.39 → devopsdriver-0.1.40}/devopsdriver/azdo/__init__.py +0 -0
  11. {devopsdriver-0.1.39 → devopsdriver-0.1.40}/devopsdriver/azdo/clients.py +0 -0
  12. {devopsdriver-0.1.39 → devopsdriver-0.1.40}/devopsdriver/azdo/workitem/__init__.py +0 -0
  13. {devopsdriver-0.1.39 → devopsdriver-0.1.40}/devopsdriver/azdo/workitem/client.py +0 -0
  14. {devopsdriver-0.1.39 → devopsdriver-0.1.40}/devopsdriver/azdo/workitem/wiql.py +0 -0
  15. {devopsdriver-0.1.39 → devopsdriver-0.1.40}/devopsdriver/azdo/workitem/workitem.py +0 -0
  16. {devopsdriver-0.1.39 → devopsdriver-0.1.40}/devopsdriver/manage_settings.py +0 -0
  17. {devopsdriver-0.1.39 → devopsdriver-0.1.40}/devopsdriver/sendmail.py +0 -0
  18. {devopsdriver-0.1.39 → devopsdriver-0.1.40}/devopsdriver/settings.py +0 -0
  19. {devopsdriver-0.1.39 → devopsdriver-0.1.40}/devopsdriver/template.py +0 -0
  20. {devopsdriver-0.1.39 → devopsdriver-0.1.40}/devopsdriver/templates/manage_settings.txt.mako +0 -0
  21. {devopsdriver-0.1.39 → devopsdriver-0.1.40}/devopsdriver.egg-info/SOURCES.txt +0 -0
  22. {devopsdriver-0.1.39 → devopsdriver-0.1.40}/devopsdriver.egg-info/dependency_links.txt +0 -0
  23. {devopsdriver-0.1.39 → devopsdriver-0.1.40}/devopsdriver.egg-info/entry_points.txt +0 -0
  24. {devopsdriver-0.1.39 → devopsdriver-0.1.40}/devopsdriver.egg-info/requires.txt +0 -0
  25. {devopsdriver-0.1.39 → devopsdriver-0.1.40}/devopsdriver.egg-info/top_level.txt +0 -0
  26. {devopsdriver-0.1.39 → devopsdriver-0.1.40}/setup.cfg +0 -0
  27. {devopsdriver-0.1.39 → devopsdriver-0.1.40}/tests/test_azure_clients.py +0 -0
  28. {devopsdriver-0.1.39 → devopsdriver-0.1.40}/tests/test_azure_workitem.py +0 -0
  29. {devopsdriver-0.1.39 → devopsdriver-0.1.40}/tests/test_azure_workitem_client.py +0 -0
  30. {devopsdriver-0.1.39 → devopsdriver-0.1.40}/tests/test_azure_workitem_wiql.py +0 -0
  31. {devopsdriver-0.1.39 → devopsdriver-0.1.40}/tests/test_manage_settings.py +0 -0
  32. {devopsdriver-0.1.39 → devopsdriver-0.1.40}/tests/test_sendmail.py +0 -0
  33. {devopsdriver-0.1.39 → devopsdriver-0.1.40}/tests/test_settings.py +0 -0
  34. {devopsdriver-0.1.39 → devopsdriver-0.1.40}/tests/test_template.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: devopsdriver
3
- Version: 0.1.39
3
+ Version: 0.1.40
4
4
  Summary: DevOps tools
5
5
  Author-email: Marc Page <marcallenpage@gmail.com>
6
6
  License: This is free and unencumbered software released into the public domain.
@@ -32,7 +32,7 @@ Project-URL: Homepage, https://github.com/marcpage/devops-driver
32
32
  Project-URL: Documentation, https://github.com/marcpage/devops-driver
33
33
  Project-URL: Repository, https://github.com/marcpage/devops-driver.git
34
34
  Project-URL: Issues, https://github.com/marcpage/devops-driver/issues
35
- Project-URL: Changelog, https://github.com/marcpage/devops-driver
35
+ Project-URL: Changelog, https://github.com/marcpage/devops-driver/releases
36
36
  Keywords: azure,devops,jira,confluence,email,pipelines,tools
37
37
  Classifier: Development Status :: 1 - Planning
38
38
  Classifier: Environment :: Console
@@ -60,7 +60,7 @@ Requires-Dist: coverage>=7.4.4; extra == "test"
60
60
  Provides-Extra: doc
61
61
 
62
62
  ![status sheild](https://img.shields.io/static/v1?label=status&message=beta&color=blue&style=plastic)
63
- [![status sheild](https://img.shields.io/static/v1?label=released&message=v0.1.39&color=active&style=plastic)](https://pypi.org/project/devopsdriver/0.1.39/)
63
+ [![status sheild](https://img.shields.io/static/v1?label=released&message=v0.1.40&color=active&style=plastic)](https://pypi.org/project/devopsdriver/0.1.40/)
64
64
  [![GitHub](https://img.shields.io/github/license/marcpage/devops-driver?style=plastic)](https://github.com/marcpage/devops-driver?tab=Unlicense-1-ov-file#readme)
65
65
  [![GitHub contributors](https://img.shields.io/github/contributors/marcpage/devops-driver?style=flat)](https://github.com/marcpage/devops-driver/graphs/contributors)
66
66
  [![PR's Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat)](http://makeapullrequest.com)
@@ -1,5 +1,5 @@
1
1
  ![status sheild](https://img.shields.io/static/v1?label=status&message=beta&color=blue&style=plastic)
2
- [![status sheild](https://img.shields.io/static/v1?label=released&message=v0.1.39&color=active&style=plastic)](https://pypi.org/project/devopsdriver/0.1.39/)
2
+ [![status sheild](https://img.shields.io/static/v1?label=released&message=v0.1.40&color=active&style=plastic)](https://pypi.org/project/devopsdriver/0.1.40/)
3
3
  [![GitHub](https://img.shields.io/github/license/marcpage/devops-driver?style=plastic)](https://github.com/marcpage/devops-driver?tab=Unlicense-1-ov-file#readme)
4
4
  [![GitHub contributors](https://img.shields.io/github/contributors/marcpage/devops-driver?style=flat)](https://github.com/marcpage/devops-driver/graphs/contributors)
5
5
  [![PR's Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat)](http://makeapullrequest.com)
@@ -0,0 +1,11 @@
1
+ """ DevOps tools """
2
+
3
+ from .settings import Settings
4
+ from .sendmail import send_email
5
+ from .template import Template
6
+ from .azdo.clients import Azure
7
+
8
+
9
+ __version__ = "0.1.40"
10
+ __author__ = "Marc Page"
11
+ __credits__ = ""
@@ -4,9 +4,11 @@
4
4
  """ Tools that help when working with Azure """
5
5
 
6
6
 
7
- from datetime import datetime, timezone
7
+ from datetime import datetime, timezone, timedelta
8
+ from functools import total_ordering
8
9
 
9
10
 
11
+ @total_ordering
10
12
  class Timestamp:
11
13
  """An Azure timestamp"""
12
14
 
@@ -37,6 +39,11 @@ class Timestamp:
37
39
  except ValueError:
38
40
  return False
39
41
 
42
+ @staticmethod
43
+ def now():
44
+ """Returns a timestamp representing now"""
45
+ return Timestamp(datetime.now(tz=timezone.utc))
46
+
40
47
  def __init__(self, value: datetime | str | float | int):
41
48
  if isinstance(value, datetime):
42
49
  self.value = value
@@ -50,6 +57,39 @@ class Timestamp:
50
57
  def __str__(self) -> str:
51
58
  return self.to_string()
52
59
 
60
+ def __lt__(self, other) -> bool:
61
+ match Timestamp.__comparison_type(other):
62
+ case 1:
63
+ return self.value < other.value
64
+ case 2:
65
+ return self.value < other
66
+ case _:
67
+ return NotImplemented
68
+
69
+ def __eq__(self, other) -> bool:
70
+ match Timestamp.__comparison_type(other):
71
+ case 1:
72
+ return self.value == other.value
73
+ case 2:
74
+ return self.value == other
75
+ case _:
76
+ return NotImplemented
77
+
78
+ def __sub__(self, other):
79
+ match Timestamp.__comparison_type(other):
80
+ case 1:
81
+ return self.value - other.value
82
+ case 2 | 3:
83
+ return self.value - other
84
+ case _:
85
+ return NotImplemented
86
+
87
+ def __add__(self, other):
88
+ if Timestamp.__comparison_type(other) != 3:
89
+ return NotImplemented
90
+
91
+ return Timestamp(self.value + other)
92
+
53
93
  def to_string(self) -> str:
54
94
  """Returns the Azure formatted timestamp
55
95
 
@@ -78,3 +118,16 @@ class Timestamp:
78
118
  return result.replace(
79
119
  microsecond=int(fractional_seconds * Timestamp.US_PER_SEC)
80
120
  ).replace(tzinfo=timezone.utc)
121
+
122
+ @staticmethod
123
+ def __comparison_type(other) -> int:
124
+ if isinstance(other, timedelta):
125
+ return 3
126
+
127
+ if isinstance(other, datetime):
128
+ return 2
129
+
130
+ if hasattr(other, "value") and isinstance(other.value, datetime):
131
+ return 1
132
+
133
+ return 0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: devopsdriver
3
- Version: 0.1.39
3
+ Version: 0.1.40
4
4
  Summary: DevOps tools
5
5
  Author-email: Marc Page <marcallenpage@gmail.com>
6
6
  License: This is free and unencumbered software released into the public domain.
@@ -32,7 +32,7 @@ Project-URL: Homepage, https://github.com/marcpage/devops-driver
32
32
  Project-URL: Documentation, https://github.com/marcpage/devops-driver
33
33
  Project-URL: Repository, https://github.com/marcpage/devops-driver.git
34
34
  Project-URL: Issues, https://github.com/marcpage/devops-driver/issues
35
- Project-URL: Changelog, https://github.com/marcpage/devops-driver
35
+ Project-URL: Changelog, https://github.com/marcpage/devops-driver/releases
36
36
  Keywords: azure,devops,jira,confluence,email,pipelines,tools
37
37
  Classifier: Development Status :: 1 - Planning
38
38
  Classifier: Environment :: Console
@@ -60,7 +60,7 @@ Requires-Dist: coverage>=7.4.4; extra == "test"
60
60
  Provides-Extra: doc
61
61
 
62
62
  ![status sheild](https://img.shields.io/static/v1?label=status&message=beta&color=blue&style=plastic)
63
- [![status sheild](https://img.shields.io/static/v1?label=released&message=v0.1.39&color=active&style=plastic)](https://pypi.org/project/devopsdriver/0.1.39/)
63
+ [![status sheild](https://img.shields.io/static/v1?label=released&message=v0.1.40&color=active&style=plastic)](https://pypi.org/project/devopsdriver/0.1.40/)
64
64
  [![GitHub](https://img.shields.io/github/license/marcpage/devops-driver?style=plastic)](https://github.com/marcpage/devops-driver?tab=Unlicense-1-ov-file#readme)
65
65
  [![GitHub contributors](https://img.shields.io/github/contributors/marcpage/devops-driver?style=flat)](https://github.com/marcpage/devops-driver/graphs/contributors)
66
66
  [![PR's Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat)](http://makeapullrequest.com)
@@ -50,7 +50,7 @@ Homepage = "https://github.com/marcpage/devops-driver"
50
50
  Documentation = "https://github.com/marcpage/devops-driver"
51
51
  Repository = "https://github.com/marcpage/devops-driver.git"
52
52
  Issues = "https://github.com/marcpage/devops-driver/issues"
53
- Changelog = "https://github.com/marcpage/devops-driver"
53
+ Changelog = "https://github.com/marcpage/devops-driver/releases"
54
54
 
55
55
  [tool.setuptools.dynamic]
56
56
  version = {attr = "devopsdriver.__version__"}
@@ -2,6 +2,7 @@
2
2
 
3
3
  """ Test Azure Timestamp """
4
4
 
5
+ from datetime import datetime, timezone, timedelta
5
6
  from devopsdriver.azdo import Timestamp
6
7
 
7
8
  TEST_TIMESTAMPS = [
@@ -243,5 +244,65 @@ def test_basic() -> None:
243
244
  ), f"{timestamp} != {Timestamp(value_under_test.value).to_timestamp()}"
244
245
 
245
246
 
247
+ def test_comparison() -> None:
248
+ """test comparison operators"""
249
+ time1 = datetime.now(tz=timezone.utc)
250
+ time2 = time1 + timedelta(days=7)
251
+ assert time2 > time1
252
+ assert Timestamp(time2) > time1
253
+ assert Timestamp(time2) > Timestamp(time1)
254
+ assert time1 < time2
255
+ assert Timestamp(time1) < time2
256
+ assert Timestamp(time1) < Timestamp(time2)
257
+ assert time1 <= time1
258
+ assert Timestamp(time1) <= time1
259
+ assert Timestamp(time1) <= Timestamp(time1)
260
+ assert time2 >= time2
261
+ assert Timestamp(time2) >= time2
262
+ assert Timestamp(time2) >= Timestamp(time2)
263
+ assert Timestamp(time1) == time1
264
+ assert Timestamp(time2) == Timestamp(time2)
265
+ assert Timestamp(time1) != time2
266
+ assert Timestamp(time2) != Timestamp(time1)
267
+ assert Timestamp(time1) != 5
268
+
269
+ try:
270
+ assert Timestamp(time2) < 5
271
+
272
+ except TypeError as error:
273
+ assert "Timestamp" in str(error) and "int" in str(error), error
274
+
275
+
276
+ def test_now() -> None:
277
+ """Test the now() method"""
278
+ now1 = Timestamp.now()
279
+ now2 = Timestamp.now() + timedelta(milliseconds=50)
280
+ assert now2 > now1
281
+ assert (now2.value - now1.value).total_seconds() < 1
282
+
283
+
284
+ def test_math() -> None:
285
+ """test addition and subtraction"""
286
+ now1 = Timestamp.now()
287
+ now2 = now1 + timedelta(days=7)
288
+ assert (now2 - now1).days == 7
289
+ assert now2 - timedelta(days=7) == now1
290
+
291
+ try:
292
+ assert now1 - 5 is False
293
+
294
+ except TypeError as error:
295
+ assert "Timestamp" in str(error) and "int" in str(error), error
296
+
297
+ try:
298
+ assert now2 + 5 is False
299
+
300
+ except TypeError as error:
301
+ assert "Timestamp" in str(error) and "int" in str(error), error
302
+
303
+
246
304
  if __name__ == "__main__":
305
+ test_math()
306
+ test_now()
307
+ test_comparison()
247
308
  test_basic()
@@ -1,5 +0,0 @@
1
- """ DevOps tools """
2
-
3
- __version__ = "0.1.39"
4
- __author__ = "Marc Page"
5
- __credits__ = ""
File without changes
File without changes