flutter-dev 0.1.12__tar.gz → 0.1.13__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.
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/CHANGELOG.md +11 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/PKG-INFO +6 -4
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/README.md +5 -3
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/fdev.py +5 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/managers/package.py +74 -10
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/pyproject.toml +1 -1
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/tests/test_fdev_cli.py +20 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/tests/test_package_commands.py +125 -9
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/.env.example +0 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/LICENSE +0 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/MANIFEST.in +0 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/common_utils.py +0 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/core/__init__.py +0 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/core/ai_config.py +0 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/core/constants.py +0 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/core/state.py +0 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/create_page.py +0 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/flutter_dev.egg-info/SOURCES.txt +0 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/gemini_api.py +0 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/git_diff_output_editor.py +0 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/install_legacy.py +0 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/managers/__init__.py +0 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/managers/ai.py +0 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/managers/app.py +0 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/managers/brew.py +0 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/managers/build.py +0 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/managers/datetime.py +0 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/managers/device.py +0 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/managers/doctor.py +0 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/managers/git.py +0 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/managers/git_account.py +0 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/managers/localization.py +0 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/managers/merge.py +0 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/managers/mirror.py +0 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/managers/project.py +0 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/managers/web_deploy.py +0 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/requirements.txt +0 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/setup.cfg +0 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/setup.py +0 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/switch_ai.py +0 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/tests/test_ai_config.py +0 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/tests/test_app_commands.py +0 -0
- {flutter_dev-0.1.12 → flutter_dev-0.1.13}/tests/test_localization.py +0 -0
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project are documented in this file.
|
|
4
4
|
|
|
5
|
+
## 0.1.13 - 2026-07-22
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added `fdev -v` and `fdev --version` for showing the installed package version.
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- Changed `fdev upgrade` to check PyPI before invoking pip, skip installation when already current, suppress routine pip dependency output, and report verified before→after versions after a successful upgrade.
|
|
14
|
+
- Kept the terminal-restart reminder after an actual successful version change.
|
|
15
|
+
|
|
5
16
|
## 0.1.12 - 2026-07-22
|
|
6
17
|
|
|
7
18
|
### Changed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flutter-dev
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.13
|
|
4
4
|
Summary: A cross-platform CLI toolkit for Flutter development workflows.
|
|
5
5
|
Author: Royal Court BD
|
|
6
6
|
License-Expression: MIT
|
|
@@ -42,7 +42,7 @@ The package is published on PyPI as `flutter-dev` and installs console commands
|
|
|
42
42
|
python -m pip install flutter-dev
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
Current package metadata declares version `0.1.
|
|
45
|
+
Current package metadata declares version `0.1.13`, Python `>=3.8`, MIT license, and support for macOS, Linux, and Windows.
|
|
46
46
|
|
|
47
47
|
## Key Features
|
|
48
48
|
|
|
@@ -241,9 +241,10 @@ Switching GitHub accounts runs `gh auth switch` and `gh auth setup-git`, but it
|
|
|
241
241
|
| --- | --- |
|
|
242
242
|
| `fdev` | Shows command help. |
|
|
243
243
|
| `fdev help` | Shows command help. |
|
|
244
|
+
| `fdev -v` / `fdev --version` | Shows the version installed in the active fdev Python environment. |
|
|
244
245
|
| `fdev doctor` | Checks platform, Python, Flutter/Dart/Git, Python packages, Android/iOS tools, optional CLIs, `.env`, Flutter project detection, and global `fdev` availability. |
|
|
245
246
|
| `fdev init` | Creates or repairs the persistent AI `.env` with safe provider defaults and empty API keys. |
|
|
246
|
-
| `fdev upgrade` |
|
|
247
|
+
| `fdev upgrade` | Checks the latest PyPI version first. If already current, skips pip and prints one up-to-date notice; otherwise upgrades quietly and reports the previous and installed versions. |
|
|
247
248
|
| `fdev delete` | Detects the OS, asks for confirmation, then uninstalls the active Python environment's `flutter-dev` package. Use `fdev delete --yes` to skip confirmation. |
|
|
248
249
|
| `fdev ai` | Shows the current AI provider and opens an interactive provider switch prompt. |
|
|
249
250
|
| `fdev ai <provider>` | Switches `DEFAULT_AI_SERVICE` to `groq`, `mistral`, `sambanova`, or `openrouter`. |
|
|
@@ -451,11 +452,12 @@ where fdev
|
|
|
451
452
|
Use the built-in package management commands from the Python environment where `fdev` is installed:
|
|
452
453
|
|
|
453
454
|
```bash
|
|
455
|
+
fdev -v
|
|
454
456
|
fdev upgrade
|
|
455
457
|
fdev delete
|
|
456
458
|
```
|
|
457
459
|
|
|
458
|
-
|
|
460
|
+
The upgrade and delete commands print the detected OS and exact Python executable. Upgrade checks PyPI first and avoids running pip when the installed version is current. When pip is needed, both commands use the active executable with `-m pip`, not a hardcoded `python`, `python3`, `pip`, or `pip3`. On Windows, `fdev delete` and a required `fdev upgrade` schedule the same `sys.executable -m pip ...` operation in a delayed command process so the currently running console launcher can exit first.
|
|
459
461
|
|
|
460
462
|
### Flutter Project Not Detected
|
|
461
463
|
|
|
@@ -8,7 +8,7 @@ The package is published on PyPI as `flutter-dev` and installs console commands
|
|
|
8
8
|
python -m pip install flutter-dev
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
Current package metadata declares version `0.1.
|
|
11
|
+
Current package metadata declares version `0.1.13`, Python `>=3.8`, MIT license, and support for macOS, Linux, and Windows.
|
|
12
12
|
|
|
13
13
|
## Key Features
|
|
14
14
|
|
|
@@ -207,9 +207,10 @@ Switching GitHub accounts runs `gh auth switch` and `gh auth setup-git`, but it
|
|
|
207
207
|
| --- | --- |
|
|
208
208
|
| `fdev` | Shows command help. |
|
|
209
209
|
| `fdev help` | Shows command help. |
|
|
210
|
+
| `fdev -v` / `fdev --version` | Shows the version installed in the active fdev Python environment. |
|
|
210
211
|
| `fdev doctor` | Checks platform, Python, Flutter/Dart/Git, Python packages, Android/iOS tools, optional CLIs, `.env`, Flutter project detection, and global `fdev` availability. |
|
|
211
212
|
| `fdev init` | Creates or repairs the persistent AI `.env` with safe provider defaults and empty API keys. |
|
|
212
|
-
| `fdev upgrade` |
|
|
213
|
+
| `fdev upgrade` | Checks the latest PyPI version first. If already current, skips pip and prints one up-to-date notice; otherwise upgrades quietly and reports the previous and installed versions. |
|
|
213
214
|
| `fdev delete` | Detects the OS, asks for confirmation, then uninstalls the active Python environment's `flutter-dev` package. Use `fdev delete --yes` to skip confirmation. |
|
|
214
215
|
| `fdev ai` | Shows the current AI provider and opens an interactive provider switch prompt. |
|
|
215
216
|
| `fdev ai <provider>` | Switches `DEFAULT_AI_SERVICE` to `groq`, `mistral`, `sambanova`, or `openrouter`. |
|
|
@@ -417,11 +418,12 @@ where fdev
|
|
|
417
418
|
Use the built-in package management commands from the Python environment where `fdev` is installed:
|
|
418
419
|
|
|
419
420
|
```bash
|
|
421
|
+
fdev -v
|
|
420
422
|
fdev upgrade
|
|
421
423
|
fdev delete
|
|
422
424
|
```
|
|
423
425
|
|
|
424
|
-
|
|
426
|
+
The upgrade and delete commands print the detected OS and exact Python executable. Upgrade checks PyPI first and avoids running pip when the installed version is current. When pip is needed, both commands use the active executable with `-m pip`, not a hardcoded `python`, `python3`, `pip`, or `pip3`. On Windows, `fdev delete` and a required `fdev upgrade` schedule the same `sys.executable -m pip ...` operation in a delayed command process so the currently running console launcher can exit first.
|
|
425
427
|
|
|
426
428
|
### Flutter Project Not Detected
|
|
427
429
|
|
|
@@ -73,6 +73,7 @@ from managers.git_account import (
|
|
|
73
73
|
)
|
|
74
74
|
from managers.package import (
|
|
75
75
|
delete_fdev_command,
|
|
76
|
+
show_fdev_version,
|
|
76
77
|
upgrade_fdev_command,
|
|
77
78
|
)
|
|
78
79
|
|
|
@@ -124,6 +125,7 @@ def show_usage(exit_code=1):
|
|
|
124
125
|
print(" brew Interactive Homebrew package manager")
|
|
125
126
|
print(" upgrade Upgrade fdev from PyPI")
|
|
126
127
|
print(" delete Uninstall fdev from this computer")
|
|
128
|
+
print(" -v, --version Show the installed fdev version")
|
|
127
129
|
print(" help Show this help")
|
|
128
130
|
print(" merge Merge files from paths.txt into single output file")
|
|
129
131
|
print(" ai Show current AI service or switch to another")
|
|
@@ -167,6 +169,9 @@ def main():
|
|
|
167
169
|
|
|
168
170
|
command = sys.argv[1].lower()
|
|
169
171
|
|
|
172
|
+
if command in ("-v", "--version"):
|
|
173
|
+
return show_fdev_version()
|
|
174
|
+
|
|
170
175
|
if command in ("apk", "apk-split", "aab", "ipa", "release-run", "install"):
|
|
171
176
|
os.makedirs("build/app/outputs/flutter-apk", exist_ok=True)
|
|
172
177
|
os.makedirs("build/app/outputs/bundle/release", exist_ok=True)
|
|
@@ -9,9 +9,12 @@ import platform
|
|
|
9
9
|
import subprocess
|
|
10
10
|
import sys
|
|
11
11
|
|
|
12
|
+
import requests
|
|
13
|
+
|
|
12
14
|
from common_utils import BLUE, GREEN, RED, YELLOW, NC
|
|
13
15
|
|
|
14
16
|
PACKAGE_NAME = "flutter-dev"
|
|
17
|
+
PYPI_JSON_URL = f"https://pypi.org/pypi/{PACKAGE_NAME}/json"
|
|
15
18
|
|
|
16
19
|
|
|
17
20
|
def get_os_info():
|
|
@@ -59,6 +62,32 @@ def _print_installed_package_info(version, package_location):
|
|
|
59
62
|
print(f"{BLUE}Package location: {GREEN}{package_location}{NC}")
|
|
60
63
|
|
|
61
64
|
|
|
65
|
+
def show_fdev_version():
|
|
66
|
+
"""Print the version installed in the Python environment running fdev."""
|
|
67
|
+
version, _ = _get_installed_package_info()
|
|
68
|
+
if version == "not installed":
|
|
69
|
+
print(f"{RED}Could not determine the installed fdev version.{NC}")
|
|
70
|
+
return 1
|
|
71
|
+
|
|
72
|
+
print(f"fdev {version}")
|
|
73
|
+
return 0
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def _get_latest_pypi_version():
|
|
77
|
+
"""Return the latest published PyPI version, or None when unavailable."""
|
|
78
|
+
try:
|
|
79
|
+
response = requests.get(
|
|
80
|
+
PYPI_JSON_URL,
|
|
81
|
+
headers={"Accept": "application/json"},
|
|
82
|
+
timeout=10,
|
|
83
|
+
)
|
|
84
|
+
response.raise_for_status()
|
|
85
|
+
version = response.json()["info"]["version"]
|
|
86
|
+
return version.strip() if isinstance(version, str) and version.strip() else None
|
|
87
|
+
except (requests.RequestException, KeyError, TypeError, ValueError):
|
|
88
|
+
return None
|
|
89
|
+
|
|
90
|
+
|
|
62
91
|
def _build_pip_command(pip_args):
|
|
63
92
|
return [sys.executable, "-m", "pip", *pip_args]
|
|
64
93
|
|
|
@@ -68,6 +97,23 @@ def _run_pip_direct(pip_args):
|
|
|
68
97
|
return result.returncode
|
|
69
98
|
|
|
70
99
|
|
|
100
|
+
def _run_pip_quiet(pip_args):
|
|
101
|
+
"""Run pip without streaming routine dependency output to the terminal."""
|
|
102
|
+
result = subprocess.run(
|
|
103
|
+
_build_pip_command(pip_args),
|
|
104
|
+
capture_output=True,
|
|
105
|
+
text=True,
|
|
106
|
+
encoding="utf-8",
|
|
107
|
+
errors="replace",
|
|
108
|
+
)
|
|
109
|
+
if result.returncode != 0:
|
|
110
|
+
if result.stdout:
|
|
111
|
+
print(f"{GREEN}Output:\n{result.stdout.strip()}{NC}")
|
|
112
|
+
if result.stderr:
|
|
113
|
+
print(f"{RED}Error Output:\n{result.stderr.strip()}{NC}")
|
|
114
|
+
return result.returncode
|
|
115
|
+
|
|
116
|
+
|
|
71
117
|
def _build_windows_detached_command(pip_args):
|
|
72
118
|
pip_command = subprocess.list2cmdline(_build_pip_command(pip_args))
|
|
73
119
|
delayed_command = f"timeout /t 2 /nobreak > nul & {pip_command}"
|
|
@@ -158,12 +204,24 @@ def upgrade_fdev_command(argv=None):
|
|
|
158
204
|
|
|
159
205
|
pip_args = ["install", "--upgrade", PACKAGE_NAME]
|
|
160
206
|
print(f"{BLUE}Upgrade source: {GREEN}PyPI{NC}")
|
|
161
|
-
|
|
207
|
+
latest_version = _get_latest_pypi_version()
|
|
208
|
+
|
|
209
|
+
if latest_version == current_version:
|
|
210
|
+
print(f"{GREEN}✓ Already up to date: {current_version}{NC}")
|
|
211
|
+
return 0
|
|
212
|
+
|
|
213
|
+
if latest_version:
|
|
214
|
+
print(
|
|
215
|
+
f"{YELLOW}Upgrading {PACKAGE_NAME}: "
|
|
216
|
+
f"{current_version} → {latest_version}...{NC}"
|
|
217
|
+
)
|
|
218
|
+
else:
|
|
219
|
+
print(f"{YELLOW}Could not verify the latest PyPI version; checking with pip...{NC}")
|
|
162
220
|
|
|
163
221
|
if os_key == "windows":
|
|
164
222
|
return _run_windows_detached(pip_args, "Upgrade")
|
|
165
223
|
|
|
166
|
-
result =
|
|
224
|
+
result = _run_pip_quiet(pip_args)
|
|
167
225
|
if result == 0:
|
|
168
226
|
installed_version, installed_location = _get_installed_package_info()
|
|
169
227
|
if current_version != installed_version:
|
|
@@ -171,14 +229,20 @@ def upgrade_fdev_command(argv=None):
|
|
|
171
229
|
f"{GREEN}✓ {PACKAGE_NAME} upgraded successfully: "
|
|
172
230
|
f"{current_version} → {installed_version}.{NC}"
|
|
173
231
|
)
|
|
174
|
-
|
|
232
|
+
if installed_location != package_location:
|
|
233
|
+
print(f"{BLUE}Installed at: {GREEN}{installed_location}{NC}")
|
|
234
|
+
print(f"{BLUE}Restart your terminal if the fdev command still uses the old version.{NC}")
|
|
235
|
+
return 0
|
|
236
|
+
|
|
237
|
+
if latest_version and latest_version != installed_version:
|
|
175
238
|
print(
|
|
176
|
-
f"{
|
|
177
|
-
f"Installed
|
|
239
|
+
f"{RED}✗ Upgrade did not change the installed version. "
|
|
240
|
+
f"Installed: {installed_version}; PyPI: {latest_version}.{NC}"
|
|
178
241
|
)
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
print(f"{
|
|
182
|
-
|
|
183
|
-
|
|
242
|
+
return 1
|
|
243
|
+
|
|
244
|
+
print(f"{GREEN}✓ Already up to date: {installed_version}{NC}")
|
|
245
|
+
return 0
|
|
246
|
+
|
|
247
|
+
print(f"{RED}✗ Failed to upgrade {PACKAGE_NAME}.{NC}")
|
|
184
248
|
return result
|
|
@@ -26,6 +26,26 @@ class FdevCliTests(unittest.TestCase):
|
|
|
26
26
|
self.assertEqual(result, 0)
|
|
27
27
|
show_usage.assert_called_once_with(exit_code=0)
|
|
28
28
|
|
|
29
|
+
def test_short_version_flag_prints_installed_version(self):
|
|
30
|
+
with (
|
|
31
|
+
patch.object(sys, "argv", ["fdev", "-v"]),
|
|
32
|
+
patch.object(fdev, "show_fdev_version", return_value=0) as show_version,
|
|
33
|
+
):
|
|
34
|
+
result = fdev.main()
|
|
35
|
+
|
|
36
|
+
self.assertEqual(result, 0)
|
|
37
|
+
show_version.assert_called_once_with()
|
|
38
|
+
|
|
39
|
+
def test_long_version_flag_prints_installed_version(self):
|
|
40
|
+
with (
|
|
41
|
+
patch.object(sys, "argv", ["fdev", "--version"]),
|
|
42
|
+
patch.object(fdev, "show_fdev_version", return_value=0) as show_version,
|
|
43
|
+
):
|
|
44
|
+
result = fdev.main()
|
|
45
|
+
|
|
46
|
+
self.assertEqual(result, 0)
|
|
47
|
+
show_version.assert_called_once_with()
|
|
48
|
+
|
|
29
49
|
def test_unknown_command_prints_usage_and_exits_with_error(self):
|
|
30
50
|
with (
|
|
31
51
|
patch.object(sys, "argv", ["fdev", "unknown"]),
|
|
@@ -2,7 +2,7 @@ import io
|
|
|
2
2
|
import subprocess
|
|
3
3
|
import unittest
|
|
4
4
|
from contextlib import redirect_stdout
|
|
5
|
-
from unittest.mock import patch
|
|
5
|
+
from unittest.mock import Mock, patch
|
|
6
6
|
|
|
7
7
|
from managers import package
|
|
8
8
|
|
|
@@ -38,23 +38,96 @@ class PackageCommandTests(unittest.TestCase):
|
|
|
38
38
|
run.assert_not_called()
|
|
39
39
|
|
|
40
40
|
def test_upgrade_runs_pip_upgrade_in_current_python_environment(self):
|
|
41
|
+
with (
|
|
42
|
+
patch.object(package.platform, "system", return_value="Linux"),
|
|
43
|
+
patch.object(package.sys, "executable", "/venv/bin/python"),
|
|
44
|
+
patch.object(package, "_get_latest_pypi_version", return_value="0.1.13"),
|
|
45
|
+
patch.object(
|
|
46
|
+
package,
|
|
47
|
+
"_get_installed_package_info",
|
|
48
|
+
side_effect=[
|
|
49
|
+
("0.1.12", "/venv/lib/python/site-packages"),
|
|
50
|
+
("0.1.13", "/venv/lib/python/site-packages"),
|
|
51
|
+
],
|
|
52
|
+
),
|
|
53
|
+
patch.object(package, "_run_pip_quiet", return_value=0) as run,
|
|
54
|
+
):
|
|
55
|
+
result = package.upgrade_fdev_command([])
|
|
56
|
+
|
|
57
|
+
self.assertEqual(result, 0)
|
|
58
|
+
run.assert_called_once_with(["install", "--upgrade", "flutter-dev"])
|
|
59
|
+
|
|
60
|
+
def test_upgrade_skips_pip_when_already_up_to_date(self):
|
|
61
|
+
output = io.StringIO()
|
|
62
|
+
|
|
63
|
+
with (
|
|
64
|
+
patch.object(package.platform, "system", return_value="Linux"),
|
|
65
|
+
patch.object(
|
|
66
|
+
package,
|
|
67
|
+
"_get_installed_package_info",
|
|
68
|
+
return_value=("0.1.12", "/venv/lib/python/site-packages"),
|
|
69
|
+
),
|
|
70
|
+
patch.object(package, "_get_latest_pypi_version", return_value="0.1.12"),
|
|
71
|
+
patch.object(package, "_run_pip_quiet") as run,
|
|
72
|
+
redirect_stdout(output),
|
|
73
|
+
):
|
|
74
|
+
result = package.upgrade_fdev_command([])
|
|
75
|
+
|
|
76
|
+
self.assertEqual(result, 0)
|
|
77
|
+
run.assert_not_called()
|
|
78
|
+
self.assertIn("✓ Already up to date: 0.1.12", output.getvalue())
|
|
79
|
+
|
|
80
|
+
def test_quiet_pip_hides_routine_success_output(self):
|
|
41
81
|
completed = subprocess.CompletedProcess(
|
|
42
82
|
["/venv/bin/python", "-m", "pip", "install", "--upgrade", "flutter-dev"],
|
|
43
83
|
0,
|
|
84
|
+
stdout="Requirement already satisfied: flutter-dev (0.1.12)\n",
|
|
85
|
+
stderr="",
|
|
44
86
|
)
|
|
87
|
+
output = io.StringIO()
|
|
45
88
|
|
|
46
89
|
with (
|
|
47
|
-
patch.object(package.platform, "system", return_value="Linux"),
|
|
48
90
|
patch.object(package.sys, "executable", "/venv/bin/python"),
|
|
49
91
|
patch.object(package.subprocess, "run", return_value=completed) as run,
|
|
92
|
+
redirect_stdout(output),
|
|
50
93
|
):
|
|
51
|
-
result = package.
|
|
94
|
+
result = package._run_pip_quiet(["install", "--upgrade", "flutter-dev"])
|
|
52
95
|
|
|
53
96
|
self.assertEqual(result, 0)
|
|
97
|
+
self.assertEqual(output.getvalue(), "")
|
|
54
98
|
run.assert_called_once_with(
|
|
55
|
-
["/venv/bin/python", "-m", "pip", "install", "--upgrade", "flutter-dev"]
|
|
99
|
+
["/venv/bin/python", "-m", "pip", "install", "--upgrade", "flutter-dev"],
|
|
100
|
+
capture_output=True,
|
|
101
|
+
text=True,
|
|
102
|
+
encoding="utf-8",
|
|
103
|
+
errors="replace",
|
|
56
104
|
)
|
|
57
105
|
|
|
106
|
+
def test_latest_pypi_version_uses_package_json_metadata(self):
|
|
107
|
+
response = Mock()
|
|
108
|
+
response.json.return_value = {"info": {"version": "0.1.13"}}
|
|
109
|
+
|
|
110
|
+
with patch.object(package.requests, "get", return_value=response) as get:
|
|
111
|
+
version = package._get_latest_pypi_version()
|
|
112
|
+
|
|
113
|
+
self.assertEqual(version, "0.1.13")
|
|
114
|
+
response.raise_for_status.assert_called_once_with()
|
|
115
|
+
get.assert_called_once_with(
|
|
116
|
+
package.PYPI_JSON_URL,
|
|
117
|
+
headers={"Accept": "application/json"},
|
|
118
|
+
timeout=10,
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
def test_latest_pypi_version_returns_none_when_lookup_fails(self):
|
|
122
|
+
with patch.object(
|
|
123
|
+
package.requests,
|
|
124
|
+
"get",
|
|
125
|
+
side_effect=package.requests.RequestException("offline"),
|
|
126
|
+
):
|
|
127
|
+
version = package._get_latest_pypi_version()
|
|
128
|
+
|
|
129
|
+
self.assertIsNone(version)
|
|
130
|
+
|
|
58
131
|
def test_windows_delete_schedules_detached_uninstall(self):
|
|
59
132
|
with (
|
|
60
133
|
patch.object(package.platform, "system", return_value="Windows"),
|
|
@@ -100,16 +173,17 @@ class PackageCommandTests(unittest.TestCase):
|
|
|
100
173
|
)
|
|
101
174
|
|
|
102
175
|
def test_upgrade_prints_target_python_environment(self):
|
|
103
|
-
completed = subprocess.CompletedProcess(
|
|
104
|
-
["/home/user/project/.venv/bin/python", "-m", "pip", "install", "--upgrade", "flutter-dev"],
|
|
105
|
-
0,
|
|
106
|
-
)
|
|
107
176
|
output = io.StringIO()
|
|
108
177
|
|
|
109
178
|
with (
|
|
110
179
|
patch.object(package.platform, "system", return_value="Linux"),
|
|
111
180
|
patch.object(package.sys, "executable", "/home/user/project/.venv/bin/python"),
|
|
112
|
-
patch.object(
|
|
181
|
+
patch.object(
|
|
182
|
+
package,
|
|
183
|
+
"_get_installed_package_info",
|
|
184
|
+
return_value=("0.1.12", "/home/user/project/.venv/lib/python/site-packages"),
|
|
185
|
+
),
|
|
186
|
+
patch.object(package, "_get_latest_pypi_version", return_value="0.1.12"),
|
|
113
187
|
redirect_stdout(output),
|
|
114
188
|
):
|
|
115
189
|
result = package.upgrade_fdev_command([])
|
|
@@ -118,6 +192,48 @@ class PackageCommandTests(unittest.TestCase):
|
|
|
118
192
|
self.assertIn("Python environment:", output.getvalue())
|
|
119
193
|
self.assertIn("/home/user/project/.venv/bin/python", output.getvalue())
|
|
120
194
|
|
|
195
|
+
def test_successful_upgrade_prints_before_and_after_versions(self):
|
|
196
|
+
output = io.StringIO()
|
|
197
|
+
|
|
198
|
+
with (
|
|
199
|
+
patch.object(package.platform, "system", return_value="Linux"),
|
|
200
|
+
patch.object(
|
|
201
|
+
package,
|
|
202
|
+
"_get_installed_package_info",
|
|
203
|
+
side_effect=[
|
|
204
|
+
("0.1.12", "/venv/lib/python/site-packages"),
|
|
205
|
+
("0.1.13", "/venv/lib/python/site-packages"),
|
|
206
|
+
],
|
|
207
|
+
),
|
|
208
|
+
patch.object(package, "_get_latest_pypi_version", return_value="0.1.13"),
|
|
209
|
+
patch.object(package, "_run_pip_quiet", return_value=0),
|
|
210
|
+
redirect_stdout(output),
|
|
211
|
+
):
|
|
212
|
+
result = package.upgrade_fdev_command([])
|
|
213
|
+
|
|
214
|
+
self.assertEqual(result, 0)
|
|
215
|
+
self.assertIn("0.1.12 → 0.1.13", output.getvalue())
|
|
216
|
+
self.assertIn(
|
|
217
|
+
"Restart your terminal if the fdev command still uses the old version.",
|
|
218
|
+
output.getvalue(),
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
def test_show_fdev_version_prints_installed_version(self):
|
|
222
|
+
output = io.StringIO()
|
|
223
|
+
|
|
224
|
+
with (
|
|
225
|
+
patch.object(
|
|
226
|
+
package,
|
|
227
|
+
"_get_installed_package_info",
|
|
228
|
+
return_value=("0.1.13", "/venv/lib/python/site-packages"),
|
|
229
|
+
),
|
|
230
|
+
redirect_stdout(output),
|
|
231
|
+
):
|
|
232
|
+
result = package.show_fdev_version()
|
|
233
|
+
|
|
234
|
+
self.assertEqual(result, 0)
|
|
235
|
+
self.assertEqual(output.getvalue().strip(), "fdev 0.1.13")
|
|
236
|
+
|
|
121
237
|
def test_command_help_returns_zero(self):
|
|
122
238
|
with self.assertRaises(SystemExit) as raised:
|
|
123
239
|
package.delete_fdev_command(["--help"])
|
|
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
|
|
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
|
|
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
|