pygitgo 1.5.0__tar.gz → 1.6.0__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 (44) hide show
  1. {pygitgo-1.5.0/src/pygitgo.egg-info → pygitgo-1.6.0}/PKG-INFO +16 -1
  2. {pygitgo-1.5.0 → pygitgo-1.6.0}/README.md +15 -0
  3. {pygitgo-1.5.0 → pygitgo-1.6.0}/pyproject.toml +1 -1
  4. {pygitgo-1.5.0 → pygitgo-1.6.0}/src/pygitgo/main.py +3 -1
  5. pygitgo-1.6.0/src/pygitgo/utils/update_checker.py +97 -0
  6. {pygitgo-1.5.0 → pygitgo-1.6.0/src/pygitgo.egg-info}/PKG-INFO +16 -1
  7. {pygitgo-1.5.0 → pygitgo-1.6.0}/src/pygitgo.egg-info/SOURCES.txt +2 -0
  8. pygitgo-1.6.0/tests/test_update_checker.py +143 -0
  9. {pygitgo-1.5.0 → pygitgo-1.6.0}/LICENSE +0 -0
  10. {pygitgo-1.5.0 → pygitgo-1.6.0}/setup.cfg +0 -0
  11. {pygitgo-1.5.0 → pygitgo-1.6.0}/src/pygitgo/__init__.py +0 -0
  12. {pygitgo-1.5.0 → pygitgo-1.6.0}/src/pygitgo/auth/__init__.py +0 -0
  13. {pygitgo-1.5.0 → pygitgo-1.6.0}/src/pygitgo/auth/account.py +0 -0
  14. {pygitgo-1.5.0 → pygitgo-1.6.0}/src/pygitgo/auth/manager.py +0 -0
  15. {pygitgo-1.5.0 → pygitgo-1.6.0}/src/pygitgo/auth/ssh_utils.py +0 -0
  16. {pygitgo-1.5.0 → pygitgo-1.6.0}/src/pygitgo/commands/__init__.py +0 -0
  17. {pygitgo-1.5.0 → pygitgo-1.6.0}/src/pygitgo/commands/git_operations.py +0 -0
  18. {pygitgo-1.5.0 → pygitgo-1.6.0}/src/pygitgo/commands/jump.py +0 -0
  19. {pygitgo-1.5.0 → pygitgo-1.6.0}/src/pygitgo/commands/pull.py +0 -0
  20. {pygitgo-1.5.0 → pygitgo-1.6.0}/src/pygitgo/commands/staging.py +0 -0
  21. {pygitgo-1.5.0 → pygitgo-1.6.0}/src/pygitgo/commands/state.py +0 -0
  22. {pygitgo-1.5.0 → pygitgo-1.6.0}/src/pygitgo/commands/undo.py +0 -0
  23. {pygitgo-1.5.0 → pygitgo-1.6.0}/src/pygitgo/exceptions.py +0 -0
  24. {pygitgo-1.5.0 → pygitgo-1.6.0}/src/pygitgo/utils/__init__.py +0 -0
  25. {pygitgo-1.5.0 → pygitgo-1.6.0}/src/pygitgo/utils/colors.py +0 -0
  26. {pygitgo-1.5.0 → pygitgo-1.6.0}/src/pygitgo/utils/config.py +0 -0
  27. {pygitgo-1.5.0 → pygitgo-1.6.0}/src/pygitgo/utils/executor.py +0 -0
  28. {pygitgo-1.5.0 → pygitgo-1.6.0}/src/pygitgo/utils/platform_utils.py +0 -0
  29. {pygitgo-1.5.0 → pygitgo-1.6.0}/src/pygitgo/utils/setup.py +0 -0
  30. {pygitgo-1.5.0 → pygitgo-1.6.0}/src/pygitgo.egg-info/dependency_links.txt +0 -0
  31. {pygitgo-1.5.0 → pygitgo-1.6.0}/src/pygitgo.egg-info/entry_points.txt +0 -0
  32. {pygitgo-1.5.0 → pygitgo-1.6.0}/src/pygitgo.egg-info/requires.txt +0 -0
  33. {pygitgo-1.5.0 → pygitgo-1.6.0}/src/pygitgo.egg-info/top_level.txt +0 -0
  34. {pygitgo-1.5.0 → pygitgo-1.6.0}/tests/test_config.py +0 -0
  35. {pygitgo-1.5.0 → pygitgo-1.6.0}/tests/test_git_operations.py +0 -0
  36. {pygitgo-1.5.0 → pygitgo-1.6.0}/tests/test_jump.py +0 -0
  37. {pygitgo-1.5.0 → pygitgo-1.6.0}/tests/test_main.py +0 -0
  38. {pygitgo-1.5.0 → pygitgo-1.6.0}/tests/test_platform.py +0 -0
  39. {pygitgo-1.5.0 → pygitgo-1.6.0}/tests/test_pull.py +0 -0
  40. {pygitgo-1.5.0 → pygitgo-1.6.0}/tests/test_setup.py +0 -0
  41. {pygitgo-1.5.0 → pygitgo-1.6.0}/tests/test_staging.py +0 -0
  42. {pygitgo-1.5.0 → pygitgo-1.6.0}/tests/test_state.py +0 -0
  43. {pygitgo-1.5.0 → pygitgo-1.6.0}/tests/test_undo.py +0 -0
  44. {pygitgo-1.5.0 → pygitgo-1.6.0}/tests/test_url_validator.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pygitgo
3
- Version: 1.5.0
3
+ Version: 1.6.0
4
4
  Summary: GitGo CLI - Your Fast Git Companion. Simplifies git push, link, stash, and user management.
5
5
  Author: Huerte
6
6
  License: GPL-3.0-or-later
@@ -31,6 +31,7 @@ Dynamic: license-file
31
31
  [![PyPI Downloads](https://img.shields.io/pypi/dm/pygitgo?color=blue)](https://pypi.org/project/pygitgo)
32
32
  [![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
33
33
  [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
34
+ [![Ko-fi](https://img.shields.io/badge/Support-Ko--fi-FF5E5B?logo=ko-fi&logoColor=white)](https://ko-fi.com/huerte)
34
35
  [![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20Linux%20%7C%20macOS%20%7C%20Termux-lightgrey)](https://github.com/Huerte/GitGo)
35
36
 
36
37
  **Stop typing the same five Git commands. Run one instead.**
@@ -81,6 +82,7 @@ GitGo provides a CLI environment designed for faster and simpler Git workflows.
81
82
  - **Smart Branch Hopping:** Safely traverse branches with `jump`. Auto-stashes messy code and prevents merge conflict disasters with a Try-And-Revert safety engine.
82
83
  - **State Management:** A human-readable interface over `git stash`. States are named and listed by index so you never have to remember cryptic stash references.
83
84
  - **Custom Defaults:** Save your preferred branch name and commit message locally so you never have to type them again.
85
+ - **Auto-Update Checker:** Silently checks for newer versions in the background and notifies you, without slowing down your commands.
84
86
  - **SSH Auto-Setup:** Generates an SSH key, adds it to `ssh-agent`, and opens your GitHub settings automatically.
85
87
  - **HTTPS to SSH Conversion:** Silently converts the remote to SSH before pushing if your SSH is configured.
86
88
  - **Termux Compatibility:** Works natively on Android natively handling common issues like dubious ownership errors.
@@ -281,6 +283,7 @@ gitgo -r # verify GitGo is ready
281
283
 
282
284
  - **SSH Auto-Setup:** `gitgo user login` generates an `ed25519` SSH key, adds it to `ssh-agent`, prints the public key, and opens `github.com/settings/ssh/new`.
283
285
  - **HTTPS to SSH Conversion:** If your remote is set to HTTPS, GitGo converts the remote to SSH before pushing if SSH is configured. No `git remote set-url` is required.
286
+ - **Auto-Update Checker:** Spawns a non-blocking background thread on startup to query PyPI for newer versions. Results are cached locally for 7 days to prevent unnecessary network requests.
284
287
  - **Termux Compatibility:** Detects Termux via environment variables, adjusts binary locations (`$PREFIX/bin`), uses `termux-open` for browser actions, and natively handles the `detected dubious ownership` Git error.
285
288
  - **State Management:** `gitgo state` wraps `git stash` with named saves, indexed listing, and confirmation prompts.
286
289
 
@@ -311,6 +314,18 @@ Contributions are welcome and appreciated!
311
314
 
312
315
  ---
313
316
 
317
+ ## Support
318
+
319
+ If GitGo saves you time, consider buying me a coffee. It helps keep the project going.
320
+
321
+ <div align="center">
322
+ <a href="https://ko-fi.com/huerte">
323
+ <img src="https://ko-fi.com/img/githubbutton_sm.svg" alt="Support on Ko-fi" />
324
+ </a>
325
+ </div>
326
+
327
+ ---
328
+
314
329
  ## License
315
330
 
316
331
  Distributed under the **GPLv3** License. See [`LICENSE`](LICENSE) for details.
@@ -7,6 +7,7 @@
7
7
  [![PyPI Downloads](https://img.shields.io/pypi/dm/pygitgo?color=blue)](https://pypi.org/project/pygitgo)
8
8
  [![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
9
9
  [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
10
+ [![Ko-fi](https://img.shields.io/badge/Support-Ko--fi-FF5E5B?logo=ko-fi&logoColor=white)](https://ko-fi.com/huerte)
10
11
  [![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20Linux%20%7C%20macOS%20%7C%20Termux-lightgrey)](https://github.com/Huerte/GitGo)
11
12
 
12
13
  **Stop typing the same five Git commands. Run one instead.**
@@ -57,6 +58,7 @@ GitGo provides a CLI environment designed for faster and simpler Git workflows.
57
58
  - **Smart Branch Hopping:** Safely traverse branches with `jump`. Auto-stashes messy code and prevents merge conflict disasters with a Try-And-Revert safety engine.
58
59
  - **State Management:** A human-readable interface over `git stash`. States are named and listed by index so you never have to remember cryptic stash references.
59
60
  - **Custom Defaults:** Save your preferred branch name and commit message locally so you never have to type them again.
61
+ - **Auto-Update Checker:** Silently checks for newer versions in the background and notifies you, without slowing down your commands.
60
62
  - **SSH Auto-Setup:** Generates an SSH key, adds it to `ssh-agent`, and opens your GitHub settings automatically.
61
63
  - **HTTPS to SSH Conversion:** Silently converts the remote to SSH before pushing if your SSH is configured.
62
64
  - **Termux Compatibility:** Works natively on Android natively handling common issues like dubious ownership errors.
@@ -257,6 +259,7 @@ gitgo -r # verify GitGo is ready
257
259
 
258
260
  - **SSH Auto-Setup:** `gitgo user login` generates an `ed25519` SSH key, adds it to `ssh-agent`, prints the public key, and opens `github.com/settings/ssh/new`.
259
261
  - **HTTPS to SSH Conversion:** If your remote is set to HTTPS, GitGo converts the remote to SSH before pushing if SSH is configured. No `git remote set-url` is required.
262
+ - **Auto-Update Checker:** Spawns a non-blocking background thread on startup to query PyPI for newer versions. Results are cached locally for 7 days to prevent unnecessary network requests.
260
263
  - **Termux Compatibility:** Detects Termux via environment variables, adjusts binary locations (`$PREFIX/bin`), uses `termux-open` for browser actions, and natively handles the `detected dubious ownership` Git error.
261
264
  - **State Management:** `gitgo state` wraps `git stash` with named saves, indexed listing, and confirmation prompts.
262
265
 
@@ -287,6 +290,18 @@ Contributions are welcome and appreciated!
287
290
 
288
291
  ---
289
292
 
293
+ ## Support
294
+
295
+ If GitGo saves you time, consider buying me a coffee. It helps keep the project going.
296
+
297
+ <div align="center">
298
+ <a href="https://ko-fi.com/huerte">
299
+ <img src="https://ko-fi.com/img/githubbutton_sm.svg" alt="Support on Ko-fi" />
300
+ </a>
301
+ </div>
302
+
303
+ ---
304
+
290
305
  ## License
291
306
 
292
307
  Distributed under the **GPLv3** License. See [`LICENSE`](LICENSE) for details.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pygitgo"
7
- version = "1.5.0"
7
+ version = "1.6.0"
8
8
  description = "GitGo CLI - Your Fast Git Companion. Simplifies git push, link, stash, and user management."
9
9
  readme = "README.md"
10
10
  license = {text = "GPL-3.0-or-later"}
@@ -6,6 +6,7 @@ from pygitgo.commands.staging import get_changed_files, display_file_picker, sel
6
6
  from pygitgo.utils.colors import info, success, warning, error
7
7
  from pygitgo.utils.config import get_config, config_operation
8
8
  from pygitgo.exceptions import GitCommandError, GitGoError
9
+ from pygitgo.utils.update_checker import check_for_updates_background
9
10
  from pygitgo.utils.setup import ensure_first_run_setup
10
11
  from pygitgo.commands.state import state_operations
11
12
  from pygitgo.commands.undo import undo_operations
@@ -225,7 +226,7 @@ def main():
225
226
  epilog="Use 'gitgo <command> -h' for help on a specific command."
226
227
  )
227
228
 
228
- parser.add_argument("-v", "-V", "--version", action="version", version=f"GitGo {get_version()}")
229
+ parser.add_argument("-v", "-V", "--version", action="version", version=f"GitGo {get_version()}\nSupport GitGo: https://ko-fi.com/huerte")
229
230
  parser.add_argument("-r", "--ready", action="store_true", help="Check tool readiness")
230
231
 
231
232
  subparsers = parser.add_subparsers(title="Commands", dest="command")
@@ -337,6 +338,7 @@ def main():
337
338
  sys.exit(0)
338
339
 
339
340
  ensure_first_run_setup()
341
+ check_for_updates_background(get_version())
340
342
 
341
343
  try:
342
344
  if args.command == "jump":
@@ -0,0 +1,97 @@
1
+ import json
2
+ import threading
3
+ import urllib.request
4
+ import urllib.error
5
+ from datetime import datetime, timedelta
6
+ from pathlib import Path
7
+
8
+ from pygitgo.utils.colors import info, warning
9
+
10
+
11
+ CACHE_DIR = Path.home() / ".gitgo"
12
+ CACHE_FILE = CACHE_DIR / "update_check.json"
13
+ PYPI_URL = "https://pypi.org/pypi/pygitgo/json"
14
+ CHECK_INTERVAL = timedelta(days=7)
15
+ REQUEST_TIMEOUT = 2
16
+
17
+
18
+ def read_cache():
19
+ if not CACHE_FILE.exists():
20
+ return {}
21
+ try:
22
+ with open(CACHE_FILE, "r") as f:
23
+ return json.load(f)
24
+ except (json.JSONDecodeError, IOError):
25
+ return {}
26
+
27
+
28
+ def write_cache(data):
29
+ try:
30
+ CACHE_DIR.mkdir(exist_ok=True)
31
+ with open(CACHE_FILE, "w") as f:
32
+ json.dump(data, f)
33
+ except IOError:
34
+ pass
35
+
36
+
37
+ def should_check():
38
+ cache = read_cache()
39
+ last_check = cache.get("last_check")
40
+
41
+ if not last_check:
42
+ return True
43
+
44
+ try:
45
+ last_check_time = datetime.fromisoformat(last_check)
46
+ return (datetime.now() - last_check_time) > CHECK_INTERVAL
47
+ except ValueError:
48
+ return True
49
+
50
+
51
+ def get_latest_version():
52
+ try:
53
+ with urllib.request.urlopen(PYPI_URL, timeout=REQUEST_TIMEOUT) as response:
54
+ data = json.loads(response.read().decode("utf-8"))
55
+ return data["info"]["version"]
56
+ except Exception:
57
+ return None
58
+
59
+
60
+ def parse_version(version_string):
61
+ parts = [int(x) for x in version_string.split(".")]
62
+ while len(parts) < 3:
63
+ parts.append(0)
64
+ return parts
65
+
66
+
67
+ def check_for_updates(current_version):
68
+ if not should_check():
69
+ return
70
+
71
+ cache = read_cache()
72
+ cache["last_check"] = datetime.now().isoformat()
73
+ write_cache(cache)
74
+
75
+ latest_version = get_latest_version()
76
+ if not latest_version or latest_version == current_version:
77
+ return
78
+
79
+ try:
80
+ current_parts = parse_version(current_version)
81
+ latest_parts = parse_version(latest_version)
82
+
83
+ if latest_parts > current_parts:
84
+ print()
85
+ warning(f"GitGo update available: {current_version} -> {latest_version}")
86
+ info("Run: pip install --upgrade pygitgo")
87
+ print()
88
+
89
+ cache["notified_version"] = latest_version
90
+ write_cache(cache)
91
+ except (ValueError, AttributeError):
92
+ pass
93
+
94
+
95
+ def check_for_updates_background(current_version):
96
+ thread = threading.Thread(target=check_for_updates, args=(current_version,), daemon=True)
97
+ thread.start()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pygitgo
3
- Version: 1.5.0
3
+ Version: 1.6.0
4
4
  Summary: GitGo CLI - Your Fast Git Companion. Simplifies git push, link, stash, and user management.
5
5
  Author: Huerte
6
6
  License: GPL-3.0-or-later
@@ -31,6 +31,7 @@ Dynamic: license-file
31
31
  [![PyPI Downloads](https://img.shields.io/pypi/dm/pygitgo?color=blue)](https://pypi.org/project/pygitgo)
32
32
  [![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
33
33
  [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
34
+ [![Ko-fi](https://img.shields.io/badge/Support-Ko--fi-FF5E5B?logo=ko-fi&logoColor=white)](https://ko-fi.com/huerte)
34
35
  [![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20Linux%20%7C%20macOS%20%7C%20Termux-lightgrey)](https://github.com/Huerte/GitGo)
35
36
 
36
37
  **Stop typing the same five Git commands. Run one instead.**
@@ -81,6 +82,7 @@ GitGo provides a CLI environment designed for faster and simpler Git workflows.
81
82
  - **Smart Branch Hopping:** Safely traverse branches with `jump`. Auto-stashes messy code and prevents merge conflict disasters with a Try-And-Revert safety engine.
82
83
  - **State Management:** A human-readable interface over `git stash`. States are named and listed by index so you never have to remember cryptic stash references.
83
84
  - **Custom Defaults:** Save your preferred branch name and commit message locally so you never have to type them again.
85
+ - **Auto-Update Checker:** Silently checks for newer versions in the background and notifies you, without slowing down your commands.
84
86
  - **SSH Auto-Setup:** Generates an SSH key, adds it to `ssh-agent`, and opens your GitHub settings automatically.
85
87
  - **HTTPS to SSH Conversion:** Silently converts the remote to SSH before pushing if your SSH is configured.
86
88
  - **Termux Compatibility:** Works natively on Android natively handling common issues like dubious ownership errors.
@@ -281,6 +283,7 @@ gitgo -r # verify GitGo is ready
281
283
 
282
284
  - **SSH Auto-Setup:** `gitgo user login` generates an `ed25519` SSH key, adds it to `ssh-agent`, prints the public key, and opens `github.com/settings/ssh/new`.
283
285
  - **HTTPS to SSH Conversion:** If your remote is set to HTTPS, GitGo converts the remote to SSH before pushing if SSH is configured. No `git remote set-url` is required.
286
+ - **Auto-Update Checker:** Spawns a non-blocking background thread on startup to query PyPI for newer versions. Results are cached locally for 7 days to prevent unnecessary network requests.
284
287
  - **Termux Compatibility:** Detects Termux via environment variables, adjusts binary locations (`$PREFIX/bin`), uses `termux-open` for browser actions, and natively handles the `detected dubious ownership` Git error.
285
288
  - **State Management:** `gitgo state` wraps `git stash` with named saves, indexed listing, and confirmation prompts.
286
289
 
@@ -311,6 +314,18 @@ Contributions are welcome and appreciated!
311
314
 
312
315
  ---
313
316
 
317
+ ## Support
318
+
319
+ If GitGo saves you time, consider buying me a coffee. It helps keep the project going.
320
+
321
+ <div align="center">
322
+ <a href="https://ko-fi.com/huerte">
323
+ <img src="https://ko-fi.com/img/githubbutton_sm.svg" alt="Support on Ko-fi" />
324
+ </a>
325
+ </div>
326
+
327
+ ---
328
+
314
329
  ## License
315
330
 
316
331
  Distributed under the **GPLv3** License. See [`LICENSE`](LICENSE) for details.
@@ -27,6 +27,7 @@ src/pygitgo/utils/config.py
27
27
  src/pygitgo/utils/executor.py
28
28
  src/pygitgo/utils/platform_utils.py
29
29
  src/pygitgo/utils/setup.py
30
+ src/pygitgo/utils/update_checker.py
30
31
  tests/test_config.py
31
32
  tests/test_git_operations.py
32
33
  tests/test_jump.py
@@ -37,4 +38,5 @@ tests/test_setup.py
37
38
  tests/test_staging.py
38
39
  tests/test_state.py
39
40
  tests/test_undo.py
41
+ tests/test_update_checker.py
40
42
  tests/test_url_validator.py
@@ -0,0 +1,143 @@
1
+ from pygitgo.utils.update_checker import (
2
+ read_cache, write_cache, should_check, get_latest_version,
3
+ parse_version, check_for_updates, check_for_updates_background,
4
+ CACHE_FILE
5
+ )
6
+ from datetime import datetime, timedelta
7
+ from unittest.mock import patch, MagicMock
8
+ import json
9
+
10
+
11
+ def test_read_cache_empty(tmp_path, mocker):
12
+ mocker.patch("pygitgo.utils.update_checker.CACHE_FILE", tmp_path / "missing.json")
13
+ assert read_cache() == {}
14
+
15
+
16
+ def test_read_cache_valid(tmp_path, mocker):
17
+ cache_file = tmp_path / "update_check.json"
18
+ cache_file.write_text(json.dumps({"last_check": "2026-01-01T00:00:00"}))
19
+ mocker.patch("pygitgo.utils.update_checker.CACHE_FILE", cache_file)
20
+ result = read_cache()
21
+ assert result["last_check"] == "2026-01-01T00:00:00"
22
+
23
+
24
+ def test_read_cache_corrupted(tmp_path, mocker):
25
+ cache_file = tmp_path / "update_check.json"
26
+ cache_file.write_text("not json")
27
+ mocker.patch("pygitgo.utils.update_checker.CACHE_FILE", cache_file)
28
+ assert read_cache() == {}
29
+
30
+
31
+ def test_write_cache(tmp_path, mocker):
32
+ cache_file = tmp_path / "update_check.json"
33
+ mocker.patch("pygitgo.utils.update_checker.CACHE_DIR", tmp_path)
34
+ mocker.patch("pygitgo.utils.update_checker.CACHE_FILE", cache_file)
35
+ write_cache({"last_check": "2026-01-01T00:00:00"})
36
+ result = json.loads(cache_file.read_text())
37
+ assert result["last_check"] == "2026-01-01T00:00:00"
38
+
39
+
40
+ def test_should_check_no_cache(mocker):
41
+ mocker.patch("pygitgo.utils.update_checker.read_cache", return_value={})
42
+ assert should_check() is True
43
+
44
+
45
+ def test_should_check_expired(mocker):
46
+ old_date = (datetime.now() - timedelta(days=8)).isoformat()
47
+ mocker.patch("pygitgo.utils.update_checker.read_cache", return_value={"last_check": old_date})
48
+ assert should_check() is True
49
+
50
+
51
+ def test_should_check_still_valid(mocker):
52
+ recent_date = (datetime.now() - timedelta(days=1)).isoformat()
53
+ mocker.patch("pygitgo.utils.update_checker.read_cache", return_value={"last_check": recent_date})
54
+ assert should_check() is False
55
+
56
+
57
+ def test_should_check_invalid_date(mocker):
58
+ mocker.patch("pygitgo.utils.update_checker.read_cache", return_value={"last_check": "not-a-date"})
59
+ assert should_check() is True
60
+
61
+
62
+ def test_parse_version_standard():
63
+ assert parse_version("1.5.0") == [1, 5, 0]
64
+
65
+
66
+ def test_parse_version_short():
67
+ assert parse_version("2.0") == [2, 0, 0]
68
+
69
+
70
+ def test_parse_version_comparison():
71
+ assert parse_version("1.6.0") > parse_version("1.5.0")
72
+ assert parse_version("2.0.0") > parse_version("1.9.9")
73
+ assert parse_version("1.5.0") == parse_version("1.5.0")
74
+
75
+
76
+ def test_get_latest_version_success(mocker):
77
+ fake_response = MagicMock()
78
+ fake_response.read.return_value = json.dumps({"info": {"version": "1.6.0"}}).encode("utf-8")
79
+ fake_response.__enter__ = lambda s: s
80
+ fake_response.__exit__ = MagicMock(return_value=False)
81
+ mocker.patch("pygitgo.utils.update_checker.urllib.request.urlopen", return_value=fake_response)
82
+ assert get_latest_version() == "1.6.0"
83
+
84
+
85
+ def test_get_latest_version_network_failure(mocker):
86
+ mocker.patch("pygitgo.utils.update_checker.urllib.request.urlopen", side_effect=Exception("timeout"))
87
+ assert get_latest_version() is None
88
+
89
+
90
+ def test_check_for_updates_skips_when_cached(mocker):
91
+ mocker.patch("pygitgo.utils.update_checker.should_check", return_value=False)
92
+ fake_get = mocker.patch("pygitgo.utils.update_checker.get_latest_version")
93
+ check_for_updates("1.5.0")
94
+ fake_get.assert_not_called()
95
+
96
+
97
+ def test_check_for_updates_no_update_available(mocker):
98
+ mocker.patch("pygitgo.utils.update_checker.should_check", return_value=True)
99
+ mocker.patch("pygitgo.utils.update_checker.read_cache", return_value={})
100
+ mocker.patch("pygitgo.utils.update_checker.write_cache")
101
+ mocker.patch("pygitgo.utils.update_checker.get_latest_version", return_value="1.5.0")
102
+ fake_warning = mocker.patch("pygitgo.utils.update_checker.warning")
103
+ check_for_updates("1.5.0")
104
+ fake_warning.assert_not_called()
105
+
106
+
107
+ def test_check_for_updates_newer_version_available(mocker):
108
+ mocker.patch("pygitgo.utils.update_checker.should_check", return_value=True)
109
+ mocker.patch("pygitgo.utils.update_checker.read_cache", return_value={})
110
+ mocker.patch("pygitgo.utils.update_checker.write_cache")
111
+ mocker.patch("pygitgo.utils.update_checker.get_latest_version", return_value="2.0.0")
112
+ fake_warning = mocker.patch("pygitgo.utils.update_checker.warning")
113
+ fake_info = mocker.patch("pygitgo.utils.update_checker.info")
114
+ check_for_updates("1.5.0")
115
+ fake_warning.assert_called_with("GitGo update available: 1.5.0 -> 2.0.0")
116
+ fake_info.assert_called_with("Run: pip install --upgrade pygitgo")
117
+
118
+
119
+ def test_check_for_updates_older_version_on_pypi(mocker):
120
+ mocker.patch("pygitgo.utils.update_checker.should_check", return_value=True)
121
+ mocker.patch("pygitgo.utils.update_checker.read_cache", return_value={})
122
+ mocker.patch("pygitgo.utils.update_checker.write_cache")
123
+ mocker.patch("pygitgo.utils.update_checker.get_latest_version", return_value="1.4.0")
124
+ fake_warning = mocker.patch("pygitgo.utils.update_checker.warning")
125
+ check_for_updates("1.5.0")
126
+ fake_warning.assert_not_called()
127
+
128
+
129
+ def test_check_for_updates_pypi_returns_none(mocker):
130
+ mocker.patch("pygitgo.utils.update_checker.should_check", return_value=True)
131
+ mocker.patch("pygitgo.utils.update_checker.read_cache", return_value={})
132
+ mocker.patch("pygitgo.utils.update_checker.write_cache")
133
+ mocker.patch("pygitgo.utils.update_checker.get_latest_version", return_value=None)
134
+ fake_warning = mocker.patch("pygitgo.utils.update_checker.warning")
135
+ check_for_updates("1.5.0")
136
+ fake_warning.assert_not_called()
137
+
138
+
139
+ def test_check_for_updates_background_starts_thread(mocker):
140
+ fake_thread = MagicMock()
141
+ mocker.patch("pygitgo.utils.update_checker.threading.Thread", return_value=fake_thread)
142
+ check_for_updates_background("1.5.0")
143
+ fake_thread.start.assert_called_once()
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes