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 19----- 20Usage 21----- 22The package module can be accessed through the ``pw package`` command. This 23has several subcommands. 24 25``pw package list`` 26 Lists all the packages installed followed by all the packages available. 27 28``pw package install <package-name>`` 29 Installs ``<package-name>``. Exactly how this works is package-dependent, 30 and packages can decide to do nothing because the package is current, do an 31 incremental update, or delete the current version and install anew. Use 32 ``--force`` to remove the package before installing. 33 34``pw package status <package-name>`` 35 Indicates whether ``<package-name>`` is installed. 36 37``pw package remove <package-name>`` 38 Removes ``<package-name>``. 39 40By default ``pw package`` operates on the directory referenced by 41``PW_PACKAGE_ROOT``. 42 43.. _module-pw_package-middleware-only-packages: 44 45Middleware-Only Packages 46~~~~~~~~~~~~~~~~~~~~~~~~ 47Pigweed itself includes a number of packages that simply clone git repositories. 48In general, these should not be used by projects using Pigweed. Pigweed uses 49these packages to avoid using submodules so downstream projects don't have 50multiple copies of a given repository in their source tree. Projects using 51Pigweed should use submodules instead of packages because submodules are 52supported by much more mature tooling: git. To install these packages anyway, 53use ``--force`` on the command line or ``force=True`` in Python code. 54 55----------- 56Configuring 57----------- 58 59Compatibility 60~~~~~~~~~~~~~ 61Python 3 62 63Adding a New Package 64~~~~~~~~~~~~~~~~~~~~ 65To add a new package create a class that subclasses ``Package`` from 66``pw_package/package_manager.py``. 67 68.. code-block:: python 69 70 class Package: 71 """Package to be installed. 72 73 Subclass this to implement installation of a specific package. 74 """ 75 def __init__(self, name): 76 self._name = name 77 78 @property 79 def name(self): 80 return self._name 81 82 def install(self, path: pathlib.Path) -> None: 83 """Install the package at path. 84 85 Install the package in path. Cannot assume this directory is empty—it 86 may need to be deleted or updated. 87 """ 88 89 def remove(self, path: pathlib.Path) -> None: 90 """Remove the package from path. 91 92 Removes the directory containing the package. For most packages this 93 should be sufficient to remove the package, and subclasses should not 94 need to override this package. 95 """ 96 if os.path.exists(path): 97 shutil.rmtree(path) 98 99 def status(self, path: pathlib.Path) -> bool: 100 """Returns if package is installed at path and current. 101 102 This method will be skipped if the directory does not exist. 103 """ 104 105There's also a helper class for retrieving specific revisions of Git 106repositories in ``pw_package/git_repo.py``. 107 108Then call ``pw_package.package_manager.register(PackageClass)`` to register 109the class with the package manager. 110 111Setting up a Project 112~~~~~~~~~~~~~~~~~~~~ 113To set up the package manager for a new project create a file like below and 114add it to the ``PW_PLUGINS`` file (see :ref:`module-pw_cli` for details). This 115file is based off of ``pw_package/pigweed_packages.py``. 116 117.. code-block:: python 118 119 from pw_package import package_manager 120 # These modules register themselves so must be imported despite appearing 121 # unused. 122 from pw_package.packages import nanopb 123 124 def main(argv=None) -> int: 125 return package_manager.run(**vars(package_manager.parse_args(argv))) 126 127Options 128~~~~~~~ 129Options for code formatting can be specified in the ``pigweed.json`` file 130(see also :ref:`SEED-0101 <seed-0101>`). This is currently limited to one 131option. 132 133* ``allow_middleware_only_packages``: Allow middleware-only packages to be 134 installed. See :ref:`module-pw_package-middleware-only-packages` for more. 135 136.. code-block:: 137 138 { 139 "pw": { 140 "pw_package": { 141 "allow_middleware_only_packages": true 142 } 143 } 144 } 145