From 11430122161111a3e7fcdb24ff1e35333cb0cc6a Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Mon, 30 Jan 2017 20:21:16 +0200 Subject: [PATCH] Improve Package Manager when check for updates // Resolve #892 --- platformio/__init__.py | 2 +- platformio/managers/lib.py | 5 +- platformio/managers/package.py | 23 ++++-- platformio/vcsclient.py | 15 +++- tests/commands/test_lib.py | 18 +++- tests/commands/test_platform.py | 141 +++++++++++++------------------- tests/test_maintenance.py | 7 +- 7 files changed, 111 insertions(+), 100 deletions(-) diff --git a/platformio/__init__.py b/platformio/__init__.py index 87c5830d..b62446a4 100644 --- a/platformio/__init__.py +++ b/platformio/__init__.py @@ -14,7 +14,7 @@ import sys -VERSION = (3, 3, "0a8") +VERSION = (3, 3, "0a9") __version__ = ".".join([str(s) for s in VERSION]) __title__ = "platformio" diff --git a/platformio/managers/lib.py b/platformio/managers/lib.py index 92e57a11..ee7b9019 100644 --- a/platformio/managers/lib.py +++ b/platformio/managers/lib.py @@ -212,10 +212,11 @@ class LibraryManager(BasePkgManager): item = v return item - def get_latest_repo_version(self, name, requirements): + def get_latest_repo_version(self, name, requirements, silent=False): item = self.max_satisfying_repo_version( util.get_api_result( - "/lib/info/%d" % self.get_pkg_id_by_name(name, requirements), + "/lib/info/%d" % self.get_pkg_id_by_name( + name, requirements, silent=silent), cache_valid="1d")['versions'], requirements) return item['name'] if item else None diff --git a/platformio/managers/package.py b/platformio/managers/package.py index 10b0cd18..7b5768af 100644 --- a/platformio/managers/package.py +++ b/platformio/managers/package.py @@ -103,7 +103,11 @@ class PkgRepoMixin(object): item = v return item - def get_latest_repo_version(self, name, requirements): + def get_latest_repo_version( # pylint: disable=unused-argument + self, + name, + requirements, + silent=False): version = None for versions in PackageRepoIterator(name, self.repositories): pkgdata = self.max_satisfying_repo_version(versions, requirements) @@ -193,14 +197,16 @@ class PkgInstallerMixin(object): else: pkg_dir = dirname(pkg_dir) + is_vcs_pkg = False if isfile(path) and path.endswith(self.VCS_MANIFEST_NAME): + is_vcs_pkg = True pkg_dir = dirname(dirname(path)) # return from cache if self.package_dir in PkgInstallerMixin._INSTALLED_CACHE: for manifest in PkgInstallerMixin._INSTALLED_CACHE[self. package_dir]: - if manifest['__pkg_dir'] == pkg_dir: + if not is_vcs_pkg and manifest['__pkg_dir'] == pkg_dir: return manifest manifest = {} @@ -491,8 +497,14 @@ class BasePkgManager(PkgRepoMixin, PkgInstallerMixin): package_dir = self.get_package_dir(name, requirements, url) if not package_dir: return None - manifest = self.load_manifest(package_dir) - if self.get_vcs_manifest_path(package_dir): + is_vcs_pkg = False + manifest_path = self.get_vcs_manifest_path(package_dir) + if manifest_path: + is_vcs_pkg = True + manifest = self.load_manifest(manifest_path) + else: + manifest = self.load_manifest(package_dir) + if is_vcs_pkg: vcs = VCSClientFactory.newClient( package_dir, manifest['url'], silent=True) if not vcs.can_be_updated: @@ -500,7 +512,8 @@ class BasePkgManager(PkgRepoMixin, PkgInstallerMixin): latest = vcs.get_latest_revision() else: try: - latest = self.get_latest_repo_version(name, requirements) + latest = self.get_latest_repo_version( + name, requirements, silent=True) except (exception.PlatformioException, ValueError): return None if not latest: diff --git a/platformio/vcsclient.py b/platformio/vcsclient.py index a5bba681..59710802 100644 --- a/platformio/vcsclient.py +++ b/platformio/vcsclient.py @@ -116,6 +116,14 @@ class GitClient(VCSClientBase): output = output.replace("*", "") # fix active branch return [b.strip() for b in output.split("\n")] + def get_current_branch(self): + output = self.get_cmd_output(["branch"]) + for line in output.split("\n"): + line = line.strip() + if line.startswith("*"): + return line[1:].strip() + return None + def get_tags(self): output = self.get_cmd_output(["tag", "-l"]) return [t.strip() for t in output.split("\n")] @@ -151,11 +159,12 @@ class GitClient(VCSClientBase): def get_latest_revision(self): if not self.can_be_updated: return self.get_latest_revision() + branch = self.get_current_branch() result = self.get_cmd_output(["ls-remote"]) for line in result.split("\n"): - line = line.strip() - if "HEAD" in line: - return line.split("HEAD", 1)[0].strip()[:7] + ref_pos = line.strip().find("refs/heads/" + branch) + if ref_pos > 0: + return line[:ref_pos].strip()[:7] return None diff --git a/tests/commands/test_lib.py b/tests/commands/test_lib.py index 47217262..c956049c 100644 --- a/tests/commands/test_lib.py +++ b/tests/commands/test_lib.py @@ -100,10 +100,21 @@ def test_global_lib_list(clirunner, validate_cliresult, isolated_pio_home): assert set(items1) == set(items2) +def test_global_lib_update_check(clirunner, validate_cliresult, + isolated_pio_home): + result = clirunner.invoke( + cmd_lib, ["-g", "update", "--only-check", "--json-output"]) + validate_cliresult(result) + output = json.loads(result.output) + assert set(["PJON", "RadioHead"]) == set([l['name'] for l in output]) + + def test_global_lib_update(clirunner, validate_cliresult, isolated_pio_home): result = clirunner.invoke(cmd_lib, ["-g", "update"]) validate_cliresult(result) - assert all([s in result.output for s in ("[Up-to-date]", "[VCS]")]) + assert "[Up-to-date]" in result.output + assert re.search(r"Updating PJON\s+@ 1fb26fd\s+\[[a-z\d]{7}\]", + result.output) def test_global_lib_uninstall(clirunner, validate_cliresult, @@ -124,9 +135,8 @@ def test_global_lib_uninstall(clirunner, validate_cliresult, def test_lib_show(clirunner, validate_cliresult, isolated_pio_home): result = clirunner.invoke(cmd_lib, ["show", "64"]) validate_cliresult(result) - assert all([ - s in result.output for s in ("ArduinoJson", "Arduino", "Atmel AVR") - ]) + assert all( + [s in result.output for s in ("ArduinoJson", "Arduino", "Atmel AVR")]) result = clirunner.invoke(cmd_lib, ["show", "OneWire"]) validate_cliresult(result) assert "OneWire" in result.output diff --git a/tests/commands/test_platform.py b/tests/commands/test_platform.py index 57706370..e6c34011 100644 --- a/tests/commands/test_platform.py +++ b/tests/commands/test_platform.py @@ -13,30 +13,12 @@ # limitations under the License. import json -import os -from os.path import join -from platformio import exception, util +from platformio import exception from platformio.commands import platform as cli_platform -def test_list_json_output(clirunner, validate_cliresult): - result = clirunner.invoke(cli_platform.platform_list, ["--json-output"]) - validate_cliresult(result) - list_result = json.loads(result.output) - assert isinstance(list_result, list) - assert len(list_result) - platforms = [item['name'] for item in list_result] - assert "titiva" in platforms - - -def test_list_raw_output(clirunner, validate_cliresult): - result = clirunner.invoke(cli_platform.platform_list) - validate_cliresult(result) - assert "teensy" in result.output - - -def test_search_json_output(clirunner, validate_cliresult): +def test_search_json_output(clirunner, validate_cliresult, isolated_pio_home): result = clirunner.invoke(cli_platform.platform_search, ["arduino", "--json-output"]) validate_cliresult(result) @@ -47,82 +29,75 @@ def test_search_json_output(clirunner, validate_cliresult): assert "atmelsam" in platforms -def test_search_raw_output(clirunner, validate_cliresult): +def test_search_raw_output(clirunner, validate_cliresult, isolated_pio_home): result = clirunner.invoke(cli_platform.platform_search, ["arduino"]) validate_cliresult(result) assert "teensy" in result.output -def test_install_uknown_from_registry(clirunner, validate_cliresult): - result = clirunner.invoke(cli_platform.platform_install, - ["uknown-platform"]) - assert result.exit_code == -1 - assert isinstance(result.exception, exception.UnknownPackage) - - -def test_install_from_vcs(clirunner, validate_cliresult): - result = clirunner.invoke(cli_platform.platform_install, [ - "https://github.com/platformio/" - "platform-espressif8266.git#feature/stage" - ]) - validate_cliresult(result) - assert "espressif8266_stage" in result.output - - -def test_install_uknown_version(clirunner, validate_cliresult): +def test_install_unknown_version(clirunner, validate_cliresult, + isolated_pio_home): result = clirunner.invoke(cli_platform.platform_install, ["atmelavr@99.99.99"]) assert result.exit_code == -1 assert isinstance(result.exception, exception.UndefinedPackageVersion) -def test_complex(clirunner, validate_cliresult): - with clirunner.isolated_filesystem(): - os.environ["PLATFORMIO_HOME_DIR"] = os.getcwd() - try: - result = clirunner.invoke( - cli_platform.platform_install, - ["teensy", "--with-package", "framework-arduinoteensy"]) - validate_cliresult(result) - assert all([ - s in result.output - for s in ("teensy", "Downloading", "Unpacking") - ]) +def test_install_unknown_from_registry(clirunner, validate_cliresult, + isolated_pio_home): + result = clirunner.invoke(cli_platform.platform_install, + ["unknown-platform"]) + assert result.exit_code == -1 + assert isinstance(result.exception, exception.UnknownPackage) - # show platform information - result = clirunner.invoke(cli_platform.platform_show, ["teensy"]) - validate_cliresult(result) - assert "teensy" in result.output - # list platforms - result = clirunner.invoke(cli_platform.platform_list, - ["--json-output"]) - validate_cliresult(result) - list_result = json.loads(result.output) - assert isinstance(list_result, list) - assert len(list_result) == 1 - assert list_result[0]["name"] == "teensy" - assert list_result[0]["packages"] == ["framework-arduinoteensy"] +def test_install_known_version(clirunner, validate_cliresult, + isolated_pio_home): + result = clirunner.invoke(cli_platform.platform_install, + ["atmelavr@1.1.0", "--skip-default-package"]) + validate_cliresult(result) + assert "atmelavr @ 1.1.0" in result.output - # try to install again - result = clirunner.invoke(cli_platform.platform_install, - ["teensy"]) - validate_cliresult(result) - assert "is already installed" in result.output - # try to update - for _ in range(2): - result = clirunner.invoke(cli_platform.platform_update) - validate_cliresult(result) - assert "teensy" in result.output - assert "Up-to-date" in result.output - assert "Out-of-date" not in result.output +def test_install_from_vcs(clirunner, validate_cliresult, isolated_pio_home): + result = clirunner.invoke(cli_platform.platform_install, [ + "https://github.com/platformio/" + "platform-espressif8266.git#feature/stage", "--skip-default-package" + ]) + validate_cliresult(result) + assert "espressif8266_stage" in result.output - # try to uninstall - result = clirunner.invoke(cli_platform.platform_uninstall, - ["teensy"]) - validate_cliresult(result) - for folder in ("platforms", "packages"): - assert len(os.listdir(join(util.get_home_dir(), folder))) == 0 - finally: - del os.environ["PLATFORMIO_HOME_DIR"] + +def test_list_json_output(clirunner, validate_cliresult, isolated_pio_home): + result = clirunner.invoke(cli_platform.platform_list, ["--json-output"]) + validate_cliresult(result) + list_result = json.loads(result.output) + assert isinstance(list_result, list) + assert len(list_result) + platforms = [item['name'] for item in list_result] + assert set(["atmelavr", "espressif8266_stage"]) == set(platforms) + + +def test_list_raw_output(clirunner, validate_cliresult, isolated_pio_home): + result = clirunner.invoke(cli_platform.platform_list) + validate_cliresult(result) + assert all( + [s in result.output for s in ("atmelavr", "espressif8266_stage")]) + + +def test_update_check(clirunner, validate_cliresult, isolated_pio_home): + result = clirunner.invoke(cli_platform.platform_update, + ["--only-check", "--json-output"]) + validate_cliresult(result) + output = json.loads(result.output) + assert len(output) == 1 + assert output[0]['name'] == "atmelavr" + + +def test_uninstall(clirunner, validate_cliresult, isolated_pio_home): + result = clirunner.invoke(cli_platform.platform_uninstall, + ["atmelavr", "espressif8266_stage"]) + validate_cliresult(result) + assert len( + [d.basename + for d in isolated_pio_home.join("platforms").listdir()]) == 0 diff --git a/tests/test_maintenance.py b/tests/test_maintenance.py index d0dd0fd5..ba4e2796 100644 --- a/tests/test_maintenance.py +++ b/tests/test_maintenance.py @@ -13,6 +13,7 @@ # limitations under the License. import json +import re from time import time from platformio import app, maintenance @@ -135,7 +136,8 @@ def test_check_and_update_libraries(clirunner, validate_cliresult, assert ("There are the new updates for libraries (ArduinoJson)" in result.output) assert "Please wait while updating libraries" in result.output - assert "[Out-of-date]" in result.output + assert re.search(r"Updating ArduinoJson\s+@ 5.6.7\s+\[[\d\.]+\]", + result.output) # check updated version result = clirunner.invoke(cli_pio, ["lib", "-g", "list", "--json-output"]) @@ -188,7 +190,8 @@ def test_check_and_update_platforms(clirunner, validate_cliresult, validate_cliresult(result) assert "There are the new updates for platforms (native)" in result.output assert "Please wait while updating platforms" in result.output - assert "[Out-of-date]" in result.output + assert re.search(r"Updating native\s+@ 0.0.0\s+\[[\d\.]+\]", + result.output) # check updated version result = clirunner.invoke(cli_pio, ["platform", "list", "--json-output"])