New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Long-term maintainability goals #234
Comments
I'm starting to think this might not be necessary (thank gods). The entry point system (available through It seems like there is a reasonably simple solution: don't mess with executable code at all, just add a
|
As a concrete example, this (abridged) `pyproject.toml` with a mandatory dependency on `aiohttp`: dependencies = ["aiohttp~=3.8"] [project.entry-points."glasgow.applet"] audio-yamaha-opx = "glasgow.applet.audio.yamaha_opx:AudioYamahaOPxApplet" can now be transformed into the following one with an optional dependency on `aiohttp`: [project.optional-dependencies] http = ["aiohttp~=3.8"] [project.entry-points."glasgow.applet"] audio-yamaha-opx = "glasgow.applet.audio.yamaha_opx:AudioYamahaOPxApplet [http]" If `aiohttp` is not installed or its version is unsatisfying, the CLI shows a placeholder instead of the applet whose `--help` text explains how to install the missing packages. See GlasgowEmbedded#234.
As a concrete example, this (abridged) `pyproject.toml` with a mandatory dependency on `aiohttp`: dependencies = ["aiohttp~=3.8"] [project.entry-points."glasgow.applet"] audio-yamaha-opx = "glasgow.applet.audio.yamaha_opx:AudioYamahaOPxApplet" can now be transformed into the following one with an optional dependency on `aiohttp`: [project.optional-dependencies] http = ["aiohttp~=3.8"] [project.entry-points."glasgow.applet"] audio-yamaha-opx = "glasgow.applet.audio.yamaha_opx:AudioYamahaOPxApplet [http]" If `aiohttp` is not installed or its version is unsatisfying, the CLI shows a placeholder instead of the applet whose `--help` text explains how to install the missing packages. See GlasgowEmbedded#234.
As a concrete example, this (abridged) `pyproject.toml` with a mandatory dependency on `aiohttp`: dependencies = ["aiohttp~=3.8"] [project.entry-points."glasgow.applet"] audio-yamaha-opx = "glasgow.applet.audio.yamaha_opx:AudioYamahaOPxApplet" can now be transformed into the following one with an optional dependency on `aiohttp`: [project.optional-dependencies] http = ["aiohttp~=3.8"] [project.entry-points."glasgow.applet"] audio-yamaha-opx = "glasgow.applet.audio.yamaha_opx:AudioYamahaOPxApplet [http]" If `aiohttp` is not installed or its version is unsatisfying, the CLI shows a placeholder instead of the applet whose `--help` text explains how to install the missing packages. See GlasgowEmbedded#234.
As a concrete example, this (abridged) `pyproject.toml` with a mandatory dependency on `aiohttp`: dependencies = ["aiohttp~=3.8"] [project.entry-points."glasgow.applet"] audio-yamaha-opx = "glasgow.applet.audio.yamaha_opx:AudioYamahaOPxApplet" can now be transformed into the following one with an optional dependency on `aiohttp`: [project.optional-dependencies] http = ["aiohttp~=3.8"] [project.entry-points."glasgow.applet"] audio-yamaha-opx = "glasgow.applet.audio.yamaha_opx:AudioYamahaOPxApplet [http]" If `aiohttp` is not installed or its version is unsatisfying, the CLI shows a placeholder instead of the applet whose `--help` text explains how to install the missing packages. See GlasgowEmbedded#234.
As a concrete example, this (abridged) `pyproject.toml` with a mandatory dependency on `aiohttp`: dependencies = ["aiohttp~=3.8"] [project.entry-points."glasgow.applet"] audio-yamaha-opx = "glasgow.applet.audio.yamaha_opx:AudioYamahaOPxApplet" can now be transformed into the following one with an optional dependency on `aiohttp`: [project.optional-dependencies] http = ["aiohttp~=3.8"] [project.entry-points."glasgow.applet"] audio-yamaha-opx = "glasgow.applet.audio.yamaha_opx:AudioYamahaOPxApplet [http]" If `aiohttp` is not installed or its version is unsatisfying, the CLI shows a placeholder instead of the applet whose `--help` text explains how to install the missing packages. See #234.
The third goal is now complete! 🎉 |
Please DO NOT start working on tasks from this list on your own. These tasks are very complex, have far-reaching consequences, and require subtle API design. In most cases, I (@whitequark) have a fairly specific solution in mind, which I will eventually transfer to a dedicated issue for collaborating. Unless you discuss any work on these tasks beforehand, it is unlikely to be accepted.
1. Replace
argparse
with a new, almost certainly in-house argument parsing system.Although
argparse
has served us extremely well so far (it is quite impressive how well it supports Glasgow's sprawling, complicated CLI), there are many issues with it:add_pin_argument
is the worst offender),program-ice40-sram
);cli.TextHelpFormatter
is an abomination, Markdown or reST would be ideal),A particularly unpleasant consequence of the imperative interface and lack of an abstract model is that using shell completions (e.g.
argcomplete
requires importing every applet on every Tab press, which is unusably slow.Any solution would have to start off with an
argparse
API compatibility layer and allow gradual migration. (The new API could either useargparse
internally to perform actual argument parsing and help formatting during the migration, or it could present anargparse
-compatible interface.)2. Replace
logging
with a new, definitely in-house logging system.Although
logging
has served us pretty okay so far (complex applets, especially JTAG-related applets, do already have serious usability problems), there are many issues with it:{}
-style formats and is the sole remaining reason the codebase uses%
-style formats (workarounds are available but unpleasant),glasgow -F
, instead of straightforward-vvv
enabling tracing three interfaces deep),dump_bin
are not necessary in first place),Any solution would include a
logging
-compatible sink for external library code, as well as to allow gradual migration.3. Extend the Python import system to allow introducing external (PyPI) library dependencies from applet code.
Although the current situation where applets directly and unconditionally import libraries and the Glasgow package depends on the union of external dependencies of all in-tree applets has somewhat worked so far, there are many issues with it:
glasgow script
,audio-yamaha-opx
, something most people will never use).A possible solution is to transform imports of the form
from ..pypi.aiohttp import aiohttp
or evenfrom ..pypi.aiohttp.ge_3_7 import aiohttp
into code that:extra_requires
for the setuptools package, so that e.g.pip install glasgow[debug-arm-jtag]
installs whatever dependencies that applet may or may not have (this becomes even more useful if the new pip resolver starts to track extras statefully rather than statelessly as it is done now).It would be extremely cool (and also ensure we never struggle with dependency hell) if the external dependencies of every applet would exist in a sort of "in-process venv", but while this seems possible (barely) with PEP 302 import hooks and creative use of the pip cli, it looks like one of those things that would break in truly horrifying ways that negate whatever advantages they may have when they work.
4. Switch to declarative pin management based on nMigen platforms.
For historical reasons (namely, Migen platforms being very crude), Glasgow reimplements large chunks of nMigen platform code: connector-based indirection, triple construction, IO buffer insertion. There are many issues with it:
argparse
-based pin allocation scheme (that would work a lot better if represented as a constraint solving problem),XxxBus
modules that mostly rearrange the wires attached to the tristate triples that are constructed for every pin,Unfortunately, Glasgow has additional requirements well beyond what most FPGA boards require (and thus what nmigen-boards can handle):
platform.request
(with dynamically added resources) non-viable,Solving this will certainly require major nMigen changes (as well as migrating the entire codebase to nMigen in first place).
The text was updated successfully, but these errors were encountered: