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