| .. _module-pw_package: |
| |
| ========== |
| pw_package |
| ========== |
| The package module provides a mechanism to install additional tools used by |
| Pigweed. Most Pigweed dependencies should be installed using |
| :ref:`module-pw_env_setup`. Examples of reasons packages should be managed using |
| this module instead are listed below. |
| |
| * The dependency is extremely large and not commonly used. |
| * The dependency has a number of compatible versions and we want to allow |
| downstream projects to pick a version rather than being forced to use ours. |
| * The dependency has license issues that make it complicated for Google to |
| include it directly as a submodule or distribute it as a CIPD package. |
| * The dependency needs to be "installed" into the system in some manner beyond |
| just extraction and thus isn't a good match for distribution with CIPD. |
| |
| ----- |
| Usage |
| ----- |
| The package module can be accessed through the ``pw package`` command. This |
| has several subcommands. |
| |
| ``pw package list`` |
| Lists all the packages installed followed by all the packages available. |
| |
| ``pw package install <package-name>`` |
| Installs ``<package-name>``. Exactly how this works is package-dependent, |
| and packages can decide to do nothing because the package is current, do an |
| incremental update, or delete the current version and install anew. Use |
| ``--force`` to remove the package before installing. |
| |
| ``pw package status <package-name>`` |
| Indicates whether ``<packagxe-name>`` is installed. |
| |
| ``pw package remove <package-name>`` |
| Removes ``<package-name>``. |
| |
| ----------- |
| Configuring |
| ----------- |
| |
| Compatibility |
| ~~~~~~~~~~~~~ |
| Python 3 |
| |
| Adding a New Package |
| ~~~~~~~~~~~~~~~~~~~~ |
| To add a new package create a class that subclasses ``Package`` from |
| ``pw_package/package_manager.py``. |
| |
| .. code-block:: python |
| |
| class Package: |
| """Package to be installed. |
| |
| Subclass this to implement installation of a specific package. |
| """ |
| def __init__(self, name): |
| self._name = name |
| |
| @property |
| def name(self): |
| return self._name |
| |
| def install(self, path: pathlib.Path) -> None: |
| """Install the package at path. |
| |
| Install the package in path. Cannot assume this directory is empty—it |
| may need to be deleted or updated. |
| """ |
| |
| def remove(self, path: pathlib.Path) -> None: |
| """Remove the package from path. |
| |
| Removes the directory containing the package. For most packages this |
| should be sufficient to remove the package, and subclasses should not |
| need to override this package. |
| """ |
| if os.path.exists(path): |
| shutil.rmtree(path) |
| |
| def status(self, path: pathlib.Path) -> bool: |
| """Returns if package is installed at path and current. |
| |
| This method will be skipped if the directory does not exist. |
| """ |
| |
| There's also a helper class for retrieving specific revisions of Git |
| repositories in ``pw_package/git_repo.py``. |
| |
| Then call ``pw_package.package_manager.register(PackageClass)`` to register |
| the class with the package manager. |
| |
| Setting up a Project |
| ~~~~~~~~~~~~~~~~~~~~ |
| To set up the package manager for a new project create a file like below and |
| add it to the ``PW_PLUGINS`` file (see :ref:`module-pw_cli` for details). This |
| file is based off of ``pw_package/pigweed_packages.py``. |
| |
| .. code-block:: python |
| |
| from pw_package import package_manager |
| # These modules register themselves so must be imported despite appearing |
| # unused. |
| from pw_package.packages import nanopb |
| |
| def main(argv=None) -> int: |
| return package_manager.run(**vars(package_manager.parse_args(argv))) |