# Copyright (c) 2014-present PlatformIO # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # pylint: disable=unused-argument import os from platformio import fs from platformio.package.commands.install import package_install_cmd from platformio.package.commands.uninstall import package_uninstall_cmd from platformio.package.exception import UnknownPackageError from platformio.package.manager.library import LibraryPackageManager from platformio.package.manager.platform import PlatformPackageManager from platformio.package.manager.tool import ToolPackageManager from platformio.project.config import ProjectConfig PROJECT_CONFIG_TPL = """ [env] platform = platformio/atmelavr@^3.4.0 lib_deps = milesburton/DallasTemperature@^3.9.1 [env:baremetal] board = uno [env:devkit] framework = arduino board = attiny88 """ def pkgs_to_names(pkgs): return [pkg.metadata.name for pkg in pkgs] def test_global_packages( clirunner, validate_cliresult, func_isolated_pio_core, tmp_path ): # libraries result = clirunner.invoke( package_install_cmd, [ "--global", "-l", "marvinroger/Homie@^3.0.1", ], ) validate_cliresult(result) assert pkgs_to_names(LibraryPackageManager().get_installed()) == [ "ArduinoJson", "AsyncMqttClient", "AsyncTCP", "Bounce2", "ESP Async WebServer", "ESPAsyncTCP", "Homie", ] # uninstall all deps result = clirunner.invoke( package_uninstall_cmd, [ "--global", "-l", "Homie", ], ) validate_cliresult(result) assert not pkgs_to_names(LibraryPackageManager().get_installed()) # skip dependencies validate_cliresult( clirunner.invoke( package_install_cmd, [ "--global", "-l", "marvinroger/Homie@^3.0.1", ], ) ) result = clirunner.invoke( package_uninstall_cmd, ["--global", "-l", "marvinroger/Homie@^3.0.1", "--skip-dependencies"], ) validate_cliresult(result) assert pkgs_to_names(LibraryPackageManager().get_installed()) == [ "ArduinoJson", "AsyncMqttClient", "AsyncTCP", "Bounce2", "ESP Async WebServer", "ESPAsyncTCP", ] # remove specific dependency result = clirunner.invoke( package_uninstall_cmd, [ "--global", "-l", "ESP Async WebServer", ], ) validate_cliresult(result) assert pkgs_to_names(LibraryPackageManager().get_installed()) == [ "ArduinoJson", "AsyncMqttClient", "Bounce2", ] # custom storage storage_dir = tmp_path / "custom_lib_storage" storage_dir.mkdir() result = clirunner.invoke( package_install_cmd, [ "--global", "--storage-dir", str(storage_dir), "-l", "marvinroger/Homie@^3.0.1", "--skip-dependencies", ], ) validate_cliresult(result) assert pkgs_to_names(LibraryPackageManager(storage_dir).get_installed()) == [ "Homie" ] result = clirunner.invoke( package_uninstall_cmd, [ "--global", "--storage-dir", str(storage_dir), "-l", "marvinroger/Homie@^3.0.1", ], ) validate_cliresult(result) assert not pkgs_to_names(LibraryPackageManager(storage_dir).get_installed()) # tools result = clirunner.invoke( package_install_cmd, ["--global", "-t", "platformio/framework-arduino-avr-attiny@^1.5.2"], ) validate_cliresult(result) assert pkgs_to_names(ToolPackageManager().get_installed()) == [ "framework-arduino-avr-attiny" ] result = clirunner.invoke( package_uninstall_cmd, ["--global", "-t", "framework-arduino-avr-attiny"], ) validate_cliresult(result) assert not pkgs_to_names(ToolPackageManager().get_installed()) # platforms result = clirunner.invoke( package_install_cmd, ["--global", "-p", "platformio/atmelavr@^3.4.0"], ) validate_cliresult(result) assert pkgs_to_names(PlatformPackageManager().get_installed()) == ["atmelavr"] assert pkgs_to_names(ToolPackageManager().get_installed()) == ["toolchain-atmelavr"] result = clirunner.invoke( package_uninstall_cmd, ["--global", "-p", "platformio/atmelavr@^3.4.0"], ) validate_cliresult(result) assert not pkgs_to_names(PlatformPackageManager().get_installed()) assert not pkgs_to_names(ToolPackageManager().get_installed()) def test_project(clirunner, validate_cliresult, isolated_pio_core, tmp_path): project_dir = tmp_path / "project" project_dir.mkdir() (project_dir / "platformio.ini").write_text(PROJECT_CONFIG_TPL) result = clirunner.invoke( package_install_cmd, ["-d", str(project_dir)], ) validate_cliresult(result) with fs.cd(str(project_dir)): config = ProjectConfig() lm = LibraryPackageManager( os.path.join(config.get("platformio", "libdeps_dir"), "devkit") ) assert pkgs_to_names(lm.get_installed()) == ["DallasTemperature", "OneWire"] assert pkgs_to_names(ToolPackageManager().get_installed()) == [ "framework-arduino-avr-attiny", "toolchain-atmelavr", ] assert config.get("env:devkit", "lib_deps") == [ "milesburton/DallasTemperature@^3.9.1" ] # try again result = clirunner.invoke( package_install_cmd, ["-d", str(project_dir)], ) validate_cliresult(result) assert "Already up-to-date" in result.output # uninstall result = clirunner.invoke( package_uninstall_cmd, ["-d", str(project_dir)], ) validate_cliresult(result) with fs.cd(str(project_dir)): config = ProjectConfig() lm = LibraryPackageManager( os.path.join(config.get("platformio", "libdeps_dir"), "devkit") ) assert not pkgs_to_names(lm.get_installed()) assert not pkgs_to_names(ToolPackageManager().get_installed()) assert config.get("env:devkit", "lib_deps") == [ "milesburton/DallasTemperature@^3.9.1" ] def test_custom_project_libraries( clirunner, validate_cliresult, func_isolated_pio_core, tmp_path ): project_dir = tmp_path / "project" project_dir.mkdir() (project_dir / "platformio.ini").write_text(PROJECT_CONFIG_TPL) spec = "bblanchon/ArduinoJson@^6.19.2" result = clirunner.invoke( package_install_cmd, ["-d", str(project_dir), "-e", "devkit", "-l", spec], ) validate_cliresult(result) assert "Already up-to-date" not in result.output with fs.cd(str(project_dir)): # check folders config = ProjectConfig() lm = LibraryPackageManager( os.path.join(config.get("platformio", "libdeps_dir"), "devkit") ) assert pkgs_to_names(lm.get_installed()) == ["ArduinoJson"] # do not expect any platforms/tools assert not os.path.exists(config.get("platformio", "platforms_dir")) assert not os.path.exists(config.get("platformio", "packages_dir")) # check saved deps assert config.get("env:devkit", "lib_deps") == [ "bblanchon/ArduinoJson@^6.19.2", ] # uninstall result = clirunner.invoke( package_uninstall_cmd, ["-e", "devkit", "-l", spec], ) validate_cliresult(result) config = ProjectConfig() lm = LibraryPackageManager( os.path.join(config.get("platformio", "libdeps_dir"), "devkit") ) assert not pkgs_to_names(lm.get_installed()) # do not expect any platforms/tools assert not os.path.exists(config.get("platformio", "platforms_dir")) assert not os.path.exists(config.get("platformio", "packages_dir")) # check saved deps assert config.get("env:devkit", "lib_deps") == [ "milesburton/DallasTemperature@^3.9.1" ] # install library without saving to config result = clirunner.invoke( package_install_cmd, ["-e", "devkit", "-l", spec, "--no-save"], ) validate_cliresult(result) config = ProjectConfig() lm = LibraryPackageManager( os.path.join(config.get("platformio", "libdeps_dir"), "devkit") ) assert pkgs_to_names(lm.get_installed()) == ["ArduinoJson"] assert config.get("env:devkit", "lib_deps") == [ "milesburton/DallasTemperature@^3.9.1", ] result = clirunner.invoke( package_uninstall_cmd, ["-e", "devkit", "-l", spec, "--no-save"], ) validate_cliresult(result) config = ProjectConfig() assert config.get("env:devkit", "lib_deps") == [ "milesburton/DallasTemperature@^3.9.1", ] # unknown libraries result = clirunner.invoke( package_uninstall_cmd, ["-l", "platformio/unknown_library"] ) assert isinstance(result.exception, UnknownPackageError) def test_custom_project_tools( clirunner, validate_cliresult, func_isolated_pio_core, tmp_path ): project_dir = tmp_path / "project" project_dir.mkdir() (project_dir / "platformio.ini").write_text(PROJECT_CONFIG_TPL) spec = "platformio/tool-openocd" result = clirunner.invoke( package_install_cmd, ["-d", str(project_dir), "-e", "devkit", "-t", spec], ) validate_cliresult(result) with fs.cd(str(project_dir)): config = ProjectConfig() assert pkgs_to_names(ToolPackageManager().get_installed()) == ["tool-openocd"] assert not LibraryPackageManager( os.path.join(config.get("platformio", "libdeps_dir"), "devkit") ).get_installed() # do not expect any platforms assert not os.path.exists(config.get("platformio", "platforms_dir")) # check saved deps assert config.get("env:devkit", "platform_packages") == [ "platformio/tool-openocd@^2.1100.211028", ] # uninstall result = clirunner.invoke( package_uninstall_cmd, ["-e", "devkit", "-t", spec], ) validate_cliresult(result) assert not pkgs_to_names(ToolPackageManager().get_installed()) # check saved deps assert not ProjectConfig().get("env:devkit", "platform_packages") # install tool without saving to config result = clirunner.invoke( package_install_cmd, ["-e", "devkit", "-t", "platformio/tool-esptoolpy@1.20310.0"], ) validate_cliresult(result) assert pkgs_to_names(ToolPackageManager().get_installed()) == [ "tool-esptoolpy", ] assert ProjectConfig().get("env:devkit", "platform_packages") == [ "platformio/tool-esptoolpy@1.20310.0", ] # uninstall result = clirunner.invoke( package_uninstall_cmd, ["-e", "devkit", "-t", "platformio/tool-esptoolpy@^1", "--no-save"], ) validate_cliresult(result) assert not pkgs_to_names(ToolPackageManager().get_installed()) assert ProjectConfig().get("env:devkit", "platform_packages") == [ "platformio/tool-esptoolpy@1.20310.0", ] # unknown tool result = clirunner.invoke( package_uninstall_cmd, ["-t", "platformio/unknown_tool"] ) assert isinstance(result.exception, UnknownPackageError) def test_custom_project_platforms( clirunner, validate_cliresult, func_isolated_pio_core, tmp_path ): project_dir = tmp_path / "project" project_dir.mkdir() (project_dir / "platformio.ini").write_text(PROJECT_CONFIG_TPL) spec = "platformio/atmelavr@^3.4.0" result = clirunner.invoke( package_install_cmd, ["-d", str(project_dir), "-e", "devkit", "-p", spec], ) validate_cliresult(result) with fs.cd(str(project_dir)): config = ProjectConfig() assert pkgs_to_names(PlatformPackageManager().get_installed()) == ["atmelavr"] assert not LibraryPackageManager( os.path.join(config.get("platformio", "libdeps_dir"), "devkit") ).get_installed() assert pkgs_to_names(ToolPackageManager().get_installed()) == [ "framework-arduino-avr-attiny", "toolchain-atmelavr", ] # uninstall result = clirunner.invoke( package_uninstall_cmd, ["-e", "devkit", "-p", spec], ) validate_cliresult(result) assert not pkgs_to_names(PlatformPackageManager().get_installed()) assert not pkgs_to_names(ToolPackageManager().get_installed()) # unknown platform result = clirunner.invoke(package_uninstall_cmd, ["-p", "unknown_platform"]) assert isinstance(result.exception, UnknownPackageError)