diff options
Diffstat (limited to 'docs')
-rw-r--r-- | docs/_static/custom.css | 29 | ||||
-rw-r--r-- | docs/api/__init__.md | 9 | ||||
-rw-r--r-- | docs/api/destinations.md | 16 | ||||
-rw-r--r-- | docs/api/records.md | 51 | ||||
-rw-r--r-- | docs/api/scripts.md | 19 | ||||
-rw-r--r-- | docs/api/sources.md | 10 | ||||
-rw-r--r-- | docs/api/utils.md | 10 | ||||
-rw-r--r-- | docs/changelog.md | 68 | ||||
-rw-r--r-- | docs/cli/installer.md | 9 | ||||
-rw-r--r-- | docs/concepts.md | 38 | ||||
-rw-r--r-- | docs/conf.py | 58 | ||||
-rw-r--r-- | docs/development/design.md | 22 | ||||
-rw-r--r-- | docs/development/index.md | 27 | ||||
-rw-r--r-- | docs/development/workflow.md | 116 | ||||
-rw-r--r-- | docs/index.md | 71 | ||||
-rw-r--r-- | docs/license.md | 7 | ||||
-rw-r--r-- | docs/requirements.txt | 4 |
17 files changed, 564 insertions, 0 deletions
diff --git a/docs/_static/custom.css b/docs/_static/custom.css new file mode 100644 index 0000000..a3dd063 --- /dev/null +++ b/docs/_static/custom.css @@ -0,0 +1,29 @@ +/*** GENERAL ***/ + +/* Make inline code blocks nicer to look at */ +code.literal { + border-radius: 0.3em; + padding: 0em 0.3em; +} + +div.highlight pre { + border-radius: 0.2em; + padding: 0.75em; + margin: 0 -0.5em; +} + +/*** API REFERENCE ***/ + +/* Space things out properly */ +dl > dd:last-child { + margin-bottom: 10px; +} + +/* Add a tiny dash of color to names of things */ +dt > .property { + color: #a02000; +} +.sig-name, +.sig-prename { + color: #0066bb; +} diff --git a/docs/api/__init__.md b/docs/api/__init__.md new file mode 100644 index 0000000..8a74ad3 --- /dev/null +++ b/docs/api/__init__.md @@ -0,0 +1,9 @@ +```{caution} +This API is not finalised, and may change in a patch version. +``` + +# `installer` + +```{eval-rst} +.. autofunction:: installer.install +``` diff --git a/docs/api/destinations.md b/docs/api/destinations.md new file mode 100644 index 0000000..780392d --- /dev/null +++ b/docs/api/destinations.md @@ -0,0 +1,16 @@ +```{caution} +This API is not finalised, and may change in a patch version. +``` + +# `installer.destinations` + +```{eval-rst} +.. automodule:: installer.destinations + +.. autoclass:: installer.destinations.WheelDestination + :members: + +.. autoclass:: installer.destinations.SchemeDictionaryDestination() + :members: + :special-members: __init__ +``` diff --git a/docs/api/records.md b/docs/api/records.md new file mode 100644 index 0000000..b0201fd --- /dev/null +++ b/docs/api/records.md @@ -0,0 +1,51 @@ +```{caution} +This API is not finalised, and may change in a patch version. +``` + +# `installer.records` + +```{eval-rst} +.. automodule:: installer.records +``` + +## Example + +```{doctest} pycon +>>> from installer.records import parse_record_file, RecordEntry +>>> lines = [ +... "file.py,sha256=AVTFPZpEKzuHr7OvQZmhaU3LvwKz06AJw8mT\\_pNh2yI,3144", +... "distribution-1.0.dist-info/RECORD,,", +... ] +>>> records = parse_record_file(lines) +>>> li = list(records) +>>> len(li) +2 +>>> record_tuple = li[0] +>>> record_tuple +('file.py', 'sha256=AVTFPZpEKzuHr7OvQZmhaU3LvwKz06AJw8mT\\_pNh2yI', '3144') +>>> record = RecordEntry.from_elements(*record_tuple) +>>> record +RecordEntry(path='file.py', hash_=Hash(name='sha256', value='AVTFPZpEKzuHr7OvQZmhaU3LvwKz06AJw8mT\\_pNh2yI'), size=3144) +>>> record.path +'file.py' +>>> record.hash_ +Hash(name='sha256', value='AVTFPZpEKzuHr7OvQZmhaU3LvwKz06AJw8mT\\_pNh2yI') +>>> record.size +3144 +>>> record.validate(b"...") +False +``` + +## Reference + +```{eval-rst} +.. autofunction:: installer.records.parse_record_file + +.. autoclass:: installer.records.RecordEntry() + :special-members: __init__ + :members: + +.. autoclass:: installer.records.Hash() + :special-members: __init__ + :members: +``` diff --git a/docs/api/scripts.md b/docs/api/scripts.md new file mode 100644 index 0000000..470d13e --- /dev/null +++ b/docs/api/scripts.md @@ -0,0 +1,19 @@ +```{caution} +This API is not finalised, and may change in a patch version. +``` + +# `installer.scripts` + +Provides the ability to generate executable launcher scripts, that are based on +[`simple_launcher`]. A description of how these scripts work is available in +simple_launcher's README. + +[`simple_launcher`]: https://bitbucket.org/vinay.sajip/simple_launcher/ + +```{eval-rst} +.. autoclass:: installer.scripts.InvalidScript() + +.. autoclass:: installer.scripts.Script() + :special-members: __init__ + :members: +``` diff --git a/docs/api/sources.md b/docs/api/sources.md new file mode 100644 index 0000000..7ee8306 --- /dev/null +++ b/docs/api/sources.md @@ -0,0 +1,10 @@ +```{caution} +This API is not finalised, and may change in a patch version. +``` + +# `installer.sources` + +```{eval-rst} +.. automodule:: installer.sources + :members: +``` diff --git a/docs/api/utils.md b/docs/api/utils.md new file mode 100644 index 0000000..53a4c10 --- /dev/null +++ b/docs/api/utils.md @@ -0,0 +1,10 @@ +```{caution} +This API is not finalised, and may change in a patch version. +``` + +# `installer.utils` + +```{eval-rst} +.. automodule:: installer.utils + :members: +``` diff --git a/docs/changelog.md b/docs/changelog.md new file mode 100644 index 0000000..2f9c494 --- /dev/null +++ b/docs/changelog.md @@ -0,0 +1,68 @@ +# Changelog + +## v0.6.0 (Dec 7, 2022) + +- Add support for Python 3.11 (#154) +- Encode hashes in `RECORD` files correctly (#141) +- Add `py.typed` marker file (#138) +- Implement `--prefix` option (#103) +- Fix the unbound `is_executable` (#115) +- Construct `RECORD` file using `csv.writer` (#118) +- Move away from `import installer.xyz` style imports (#110) +- Improve existing documentation content (typos, formatting) (#109) + +## v0.5.1 (Mar 11, 2022) + +- Change all names in `installer.__main__` to be underscore prefixed. +- Update project URL after move to the `pypa` organisation. +- Rewrite imports to be compatible with `vendoring`. + +## v0.5.0 (Feb 16, 2022) + +- Add a CLI, to install a wheel into the currently-running Python. +- Convert Windows paths to `/` separated when writing `RECORD`. +- Drop support for Python 3.6 and lower. +- Preserve the executable bit from wheels being installed. +- Write records in `RECORD` with relative paths. +- Improve API documentation. + +## v0.4.0 (Oct 13, 2021) + +- Pass schemes into {any}`WheelDestination.finalize_installation`. + +## v0.3.0 (Oct 11, 2021) + +- Add support for ARM 64 executables on Windows. +- Improve handling of wheels that contain entries for directories. + +## v0.2.3 (Jul 29, 2021) + +- Fix entry point handling in {any}`installer.install`. + +## v0.2.2 (May 15, 2021) + +- Teach {any}`SchemeDictionaryDestination` to create subfolders. + +## v0.2.1 (May 15, 2021) + +- Change {any}`parse_record_file` to yield the elements as a tuple, instead of + {any}`RecordEntry` objects. +- Implement {any}`WheelFile`, completing the end-to-end wheel installation + pipeline. +- Generate {any}`RecordEntry` for `RECORD` file in the {any}`installer.install`, + instead of requiring every `WheelDestination` implementation to do the exact + same thing. + +## v0.2.0 (May 3, 2021) + +- Initial release. + +--- + +Thank you to [Dan Ryan] and [Tzu-ping Chung] for the project name on PyPI. The +PyPI releases before 0.2.0 come from <https://github.com/sarugaku/installer> and +have been [yanked]. + +[dan ryan]: https://github.com/techalchemy +[tzu-ping chung]: https://github.com/uranusjr +[yanked]: https://www.python.org/dev/peps/pep-0592/#abstract diff --git a/docs/cli/installer.md b/docs/cli/installer.md new file mode 100644 index 0000000..d0a54e2 --- /dev/null +++ b/docs/cli/installer.md @@ -0,0 +1,9 @@ +# `python -m installer` + +This interface allows you to install a specific wheel into a Python interpreter. + +```{argparse} +:module: installer.__main__ +:func: _get_main_parser +:prog: python -m installer +``` diff --git a/docs/concepts.md b/docs/concepts.md new file mode 100644 index 0000000..e4b926e --- /dev/null +++ b/docs/concepts.md @@ -0,0 +1,38 @@ +# Concepts + +This library has two main abstractions: + +- {any}`WheelSource`: Serves as source of information about a wheel file. +- {any}`WheelDestination`: Handles all file writing and post-installation + processing. + +## WheelSource + +These objects represent a wheel file, abstracting away how the actual file is +stored or accessed. + +This allows the core install logic to be used with in-memory wheel files, or +unzipped-on-disk wheel, or with {any}`zipfile.ZipFile` objects from an on-disk +wheel, or something else entirely. + +This protocol/abstraction is designed to be implementable without a direct +dependency on this library. This allows for other libraries in the Python +packaging ecosystem to provide implementations of the protocol, allowing for +more code reuse opportunities. + +One of the benefits of this fully described interface is the possibility to +decouple the implementation of additional validation on wheels (such as +validating the RECORD entries in a wheel match the actual contents of the wheel, +or enforcing signing requirements) based on what the specific usecase demands. + +## WheelDestination + +These objects are responsible for handling the writing-to-filesystem +interactions, determining RECORD file entries and post-install actions (like +generating .pyc files). While this is a lot of responsibility, this was +explicitly provided to make it possible for custom `WheelDestination` +implementations to be more powerful and flexible. + +Most of these tasks can either be delegated to utilities provided in this +library (eg: script generation), or to the Python standard libary (eg: +generating `.pyc` files). diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..22bbe11 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,58 @@ +"""A sphinx documentation configuration file. +""" + +# -- Project information --------------------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +project = "installer" + +copyright = "2020, Pradyun Gedam" +author = "Pradyun Gedam" + +# -- General configuration ------------------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.doctest", + "sphinx.ext.intersphinx", + "sphinx.ext.todo", + "myst_parser", + "sphinxarg.ext", +] + +# -- Options for HTML output ----------------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = "furo" +html_title = project + +# -- Options for Autodoc -------------------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#configuration + +autodoc_member_order = "bysource" +autodoc_preserve_defaults = True + +# Keep the type hints outside the function signature, moving them to the +# descriptions of the relevant function/methods. +autodoc_typehints = "description" + +# Don't show the class signature with the class name. +autodoc_class_signature = "separated" + +# -- Options for intersphinx ---------------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/extensions/intersphinx.html#configuration + +intersphinx_mapping = { + "python": ("https://docs.python.org/3", None), + "pypug": ("https://packaging.python.org", None), +} + +# -- Options for Markdown files -------------------------------------------------------- +# https://myst-parser.readthedocs.io/en/latest/sphinx/reference.html + +myst_enable_extensions = [ + "colon_fence", + "deflist", +] +myst_heading_anchors = 3 diff --git a/docs/development/design.md b/docs/development/design.md new file mode 100644 index 0000000..cb67cc3 --- /dev/null +++ b/docs/development/design.md @@ -0,0 +1,22 @@ +# Design and Scope + +## What this is for + +This project is born out of [this discussion][1]. Effectively, the volunteers +who maintain the Python packaging toolchain identified a need for a library in +the ecology that handles the details of "wheel -> installed package". This is +that library. + +There's also a need for “a fast tool to populate a package into an environment” +and this library can be used to build that. This package itself might also +"grow" a CLI, to provide just that functionality. + +[1]: https://discuss.python.org/t/3869/ + +## What is provided + +- Abstractions for installation of a wheel distribution. +- Utilities for writing concrete implementations of these abstractions. +- Concrete implementations of these abstraction, for the most common usecase. +- Utilities for handling wheel RECORD files. +- Utilities for generating Python script launchers. diff --git a/docs/development/index.md b/docs/development/index.md new file mode 100644 index 0000000..22d1611 --- /dev/null +++ b/docs/development/index.md @@ -0,0 +1,27 @@ +# Development + +Thank you for your interest in installer! ✨ + +installer is a volunteer maintained open source project, and we welcome +contributions of all forms. This section of installer's documentation serves as +a resource to help you to contribute to the project. + +```{toctree} +:hidden: + +workflow +design +``` + +<!-- prettier-ignore-start --> +[Code of Conduct] +: Applies within all community spaces. If you are not familiar with our Code of Conduct, take a minute to read it before starting with your first contribution. + +[Workflow](./workflow) +: Describes how to work on this project. Start here if you're a new contributor. + +[Design and Scope](./design) +: Describes what this project is for, and how that informs the design decisions made. +<!-- prettier-ignore-end --> + +[code of conduct]: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md diff --git a/docs/development/workflow.md b/docs/development/workflow.md new file mode 100644 index 0000000..0c4f9e7 --- /dev/null +++ b/docs/development/workflow.md @@ -0,0 +1,116 @@ +# Workflow + +This page describes the tooling used during development of this project. It also +serves as a reference for the various commands that you would use when working +on this project. + +## Overview + +This project uses the [GitHub Flow] for collaboration. The codebase is Python. + +- [flit] is used for automating development tasks. +- [nox] is used for automating development tasks. +- [pre-commit] is used for running the linters. +- [sphinx] is used for generating this documentation. +- [pytest] is used for running the automated tests. + +## Repository Layout + +The repository layout is pretty standard for a modern pure-Python project. + +- `CODE_OF_CONDUCT.md` +- `LICENSE` +- `README.md` +- `.nox/` -- Generated by [nox]. +- `dist/` -- Generated as part of the release process. +- `docs/` -- Sources for the documentation. +- `src/` + - `installer/` -- Actual source code for the package +- `tests/` -- Automated tests for the package. +- `noxfile.py` -- for [nox]. +- `pyproject.toml` -- for packaging and tooling configuration. + +## Initial Setup + +To work on this project, you need to have git 2.17+ and Python 3.7+. + +- Clone this project using git: + + ```sh + git clone https://github.com/pradyunsg/installer.git + cd installer + ``` + +- Install the project's main development dependencies: + + ```sh + pip install nox + ``` + +You're all set for working on this project. + +## Commands + +### Code Linting + +```sh +nox -s lint +``` + +Run the linters, as configured with [pre-commit]. + +### Testing + +```sh +nox -s test +``` + +Run the tests against all supported Python versions, if an interpreter for that +version is available locally. + +```sh +nox -s test-3.9 +``` + +Run the tests against Python 3.9. It is also possible to specify other supported +Python versions (like `3.7` or `pypy3`). + +### Documentation + +```sh +nox -s docs +``` + +Generate the documentation for installer into the `build/docs` folder. This +(mostly) does the same thing as `nox -s docs-live`, except it invokes +`sphinx-build` instead of [sphinx-autobuild]. + +```sh +nox -s docs-live +``` + +Serve this project's documentation locally, using [sphinx-autobuild]. This will +open the generated documentation page in your browser. + +The server also watches for changes made to the documentation (`docs/`), which +will trigger a rebuild. Once the build is completed, server will automagically +reload any open pages using livereload. + +## Release process + +- Update the changelog. +- Update the version number in `__init__.py`. +- Commit these changes. +- Create a signed git tag. +- Run `flit publish`. +- Update the version number in `__init__.py`. +- Commit these changes. +- Push tag and commits. + +[github flow]: https://guides.github.com/introduction/flow/ +[flit]: https://flit.readthedocs.io/en/stable/ +[nox]: https://nox.readthedocs.io/en/stable/ +[pytest]: https://docs.pytest.org/en/stable/ +[sphinx]: https://www.sphinx-doc.org/en/master/ +[sphinx-autobuild]: https://github.com/executablebooks/sphinx-autobuild +[pre-commit]: https://pre-commit.com/ diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..7846513 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,71 @@ +--- +hide-toc: true +--- + +# Welcome to installer's documentation + +```{include} ../README.md +:start-after: <!-- start readme-pitch --> +:end-before: <!-- end readme-pitch --> +``` + +```{toctree} +:hidden: + +concepts +``` + +```{toctree} +:caption: API reference +:hidden: +:glob: + +api/* +``` + +```{toctree} +:caption: CLI reference +:hidden: +:glob: + +cli/* +``` + +```{toctree} +:caption: Project +:hidden: + +development/index +changelog +license +GitHub <https://github.com/pradyunsg/installer> +PyPI <https://pypi.org/project/installer> +``` + +## Basic Usage + +```python +import sys +import sysconfig + +from installer import install +from installer.destinations import SchemeDictionaryDestination +from installer.sources import WheelFile + +# Handler for installation directories and writing into them. +destination = SchemeDictionaryDestination( + sysconfig.get_paths(), + interpreter=sys.executable, + script_kind="posix", +) + +with WheelFile.open("sampleproject-1.3.1-py2.py3-none-any.whl") as source: + install( + source=source, + destination=destination, + # Additional metadata that is generated by the installation tool. + additional_metadata={ + "INSTALLER": b"amazing-installer 0.1.0", + }, + ) +``` diff --git a/docs/license.md b/docs/license.md new file mode 100644 index 0000000..7ec60a8 --- /dev/null +++ b/docs/license.md @@ -0,0 +1,7 @@ +# License + +This project's source code and documentation is under the following license: + +```{include} ../LICENSE + +``` diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000..c20ceec --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,4 @@ +sphinx +furo +myst-parser +sphinx-argparse |