FileContext's _open() and _close() are called everytime their wrapper is called, which tasks the caller with keeping track of whether they were already called or not. Be a little easier on the caller, keep track in an open count, and call _open() only once for multiple calls to open(), and close() likewise. The caller still needs to make sure the number of open() and close() calls matches.
Rename command "distro" to "pkg" together with "info", its last remaining subcommand. "distro" is often used in the sense of "Linux distribution", which would be too narrow for the targets jw-pkg could theoretically support.
With the exception of the "info" subcommand, nearly all of distro's subcommands deal with package managing, so push them into their own command category.
--uri is unnecessarily generic in that it could mean the URI of anything. --target makes it clearer that operations are to be exectuted on that target.
Add keyword-argument description to Cmd.__init__(), and default it to help. Also, add a property .description returning it, and add it to add_parser() so that it shows up in the usage message.
Add a CopyContext class. At this point it mostly acts as a context manager for two FileContext instances, and copying data is the canonical case to use it, hence the name.
- Add optional in_pipe and out_pipe parameters to __init__()
- Add a add_proc_filter() method
Add possibilites to attach input / output pipes to a FileContext instance. Data will be passed through the input pipe between ._get() and .get(), and through the output pipe between .put() and _put().
Add an async open() method which should allow to do what __init__() couldn't, because it's not async, and to match the already existing .close(). It's called by __aenter__() __aexit__() if the FileContext is instantiated as context manager, or at will when the user finds it a good idea.
Cosmetics: The "packages" parameter to some DistroContext's methods has a confusing name in same contexts, notably when mixed with a list of Package instances, so rename it to "pkg_names".
Add an optional "filter: PackageFilter|None" parameter to .select(), and if it's not None, call a new version of ._select() with it.
._select() is not abstract anylonger. Its default implementation filters the results of ._select_by_name(), can be reimplemented by deriving classes for better performance, but doesn't have to.
Rename ._select() to _select_by_name() in Distro and its subclasses. Don't rename .select() itself, because it's going to be a broader interface supporting more select criteria than just package names.
Add global --pkg-filter argument, defaulting to JW_DEFAULT_PKG_FILTER. If it's specified, instantiate a PackageFilterString from it, and initialize App's Distro instance with it.
Add a default_pkg_filter parameter to Distro's constructor defaulting to None, and expose it via the .default_pkg_filter property. As of this commit, no code in jw-pkg does anything meaningful with it.
Commit a19679fec reverted the first attempt to make AsyncSSH reuse one connection during an instance lifetime. That failed because a lot of distribution-specific properties were filled in a new event loop thread started by AsyncRunner, and AsyncSSH didn't like that.
The last commit provided the needed properties as members of the Distro class. This commit is the second part of the solution: Keep one connection around as a class member and reuse it on every _run() invocation.
Commit a19679fec reverted the first attempt to make AsyncSSH reuse one connection during an instance lifetime. That failed because a lot of distribution-specific properties were filled in a new event loop thread started by AsyncRunner, and AsyncSSH didn't like that.
This commit is the first part of the solution: Move those properties from the App class to the Distro class, and load the Distro class in an async loader. As soon as it's instantiated, it can provide all its properties without cluttering the code with async keywords.
The name of the env parameter to ExecContext.run() and .sudo() is not descriptive enough for which environment is supposed to be modified and how, so rename and split it up as follows:
- .run(): env -> mod_env
- .sudo(): env -> mod_env_sudo and mod_env_cmd
The parameters have the following meaning:
- "mod_env*" means that the environment is modified, not replaced
- "mod_env" and "mod_env_cmd" modify the environment "cmd" runs in
- "mod_env_sudo" modifies the environment sudo runs in
Fix the fallout of the API change all over jw-pkg.
The "secrets" class of commands currently only works on the host it's invoked on. Use the current FileContext to allow using the existing commands on a target host.
All methods are async and call their protected counterpart, which is designed to be overridden. If possible, default implementations do something meaningful, if not, they just raise plain NotImplementedError.
Add the basic type StatResult. It is something akin to os.stat_result, but with user and group string members instead of st_uid and st_gid. The latter can't be expected to be stable across remote contexts.