1.. _module-pw_package: 2 3========== 4pw_package 5========== 6The package module provides a mechanism to install additional tools used by 7Pigweed. Most Pigweed dependencies should be installed using 8:ref:`module-pw_env_setup`. Examples of reasons packages should be managed using 9this module instead are listed below. 10 11* The dependency is extremely large and not commonly used. 12* The dependency has a number of compatible versions and we want to allow 13 downstream projects to pick a version rather than being forced to use ours. 14* The dependency has license issues that make it complicated for Google to 15 include it directly as a submodule or distribute it as a CIPD package. 16* The dependency needs to be "installed" into the system in some manner beyond 17 just extraction and thus isn't a good match for distribution with CIPD. 18 19Pigweed itself includes a number of packages that simply clone git repositories. 20In general, these should not be used by projects using Pigweed. Pigweed uses 21these packages to avoid using submodules so downstream projects don't have 22multiple copies of a given repository in their source tree. Projects using 23Pigweed should use submodules instead of packages because submodules are 24supported by much more mature tooling: git. 25 26----- 27Usage 28----- 29The package module can be accessed through the ``pw package`` command. This 30has several subcommands. 31 32``pw package list`` 33 Lists all the packages installed followed by all the packages available. 34 35``pw package install <package-name>`` 36 Installs ``<package-name>``. Exactly how this works is package-dependent, 37 and packages can decide to do nothing because the package is current, do an 38 incremental update, or delete the current version and install anew. Use 39 ``--force`` to remove the package before installing. 40 41``pw package status <package-name>`` 42 Indicates whether ``<package-name>`` is installed. 43 44``pw package remove <package-name>`` 45 Removes ``<package-name>``. 46 47----------- 48Configuring 49----------- 50 51Compatibility 52~~~~~~~~~~~~~ 53Python 3 54 55Adding a New Package 56~~~~~~~~~~~~~~~~~~~~ 57To add a new package create a class that subclasses ``Package`` from 58``pw_package/package_manager.py``. 59 60.. code-block:: python 61 62 class Package: 63 """Package to be installed. 64 65 Subclass this to implement installation of a specific package. 66 """ 67 def __init__(self, name): 68 self._name = name 69 70 @property 71 def name(self): 72 return self._name 73 74 def install(self, path: pathlib.Path) -> None: 75 """Install the package at path. 76 77 Install the package in path. Cannot assume this directory is empty—it 78 may need to be deleted or updated. 79 """ 80 81 def remove(self, path: pathlib.Path) -> None: 82 """Remove the package from path. 83 84 Removes the directory containing the package. For most packages this 85 should be sufficient to remove the package, and subclasses should not 86 need to override this package. 87 """ 88 if os.path.exists(path): 89 shutil.rmtree(path) 90 91 def status(self, path: pathlib.Path) -> bool: 92 """Returns if package is installed at path and current. 93 94 This method will be skipped if the directory does not exist. 95 """ 96 97There's also a helper class for retrieving specific revisions of Git 98repositories in ``pw_package/git_repo.py``. 99 100Then call ``pw_package.package_manager.register(PackageClass)`` to register 101the class with the package manager. 102 103Setting up a Project 104~~~~~~~~~~~~~~~~~~~~ 105To set up the package manager for a new project create a file like below and 106add it to the ``PW_PLUGINS`` file (see :ref:`module-pw_cli` for details). This 107file is based off of ``pw_package/pigweed_packages.py``. 108 109.. code-block:: python 110 111 from pw_package import package_manager 112 # These modules register themselves so must be imported despite appearing 113 # unused. 114 from pw_package.packages import nanopb 115 116 def main(argv=None) -> int: 117 return package_manager.run(**vars(package_manager.parse_args(argv))) 118