make git-show-pushable-master-branches misses projects which should better be pulled in as dependencies. It searches $(BUILLD_PROJECTS) for repositories with pushable commits, that variable leaves some out, and DEP_PROJECTS has them. It make use of the renovated pkg-requires command.
This move should be extended to other uses of BUILD_PROJECTS as well, after giving it some test runs. And the legacy and redundant command prereq should be removed.
print() should be used to output information requested by a certain command, but not for logging the process to achieve it. log() should be used for the latter. The current code has the distinction not down clearly, fix that.
By default, argcomplete uses argcomplete.FilesCompleter as default for every argument. This mixes accessible files into the list of possible completions. For most of jw-pkg's commands, that's unwanted, so turn it off by defining a NoopCompleter class which does nothing, and by set every arguments's default completer to a NoopCompleter instance. If desired, completing files can be restored for an argument by
Every module derived from lib.Cmd implements its own parser.add_argument() logic. As a consequence, all Cmd derived modules need to be loaded to have the full argument tree available. This is avoided during normal program startup because it takes some time. It's not necessary during normal program execution, nor for showing help messages. It is, however, needed for argcomplete to do its thing, so fully parse the command line if the program runs in argcomplete mode, as determined by checking if _ARGCOMPLETE is present in the environment.
lib.ExecContext.log_delim() logs a header not designed for enclosing command output, and, hence, no footer should be output. This commit suppresses it.
print() should be used to output information requested by a certain command, but not for logging the process to achieve it. log() should be used for the latter. The current code has the distinction not down clearly, fix that.
Log to stderr and add some ASCII-art around the output. Also, add a --porcelain option to allow more stable output parsing. Subsequently, use that option in make targets parsing the output, notably make diff and make git-show-xxx.
Request a remote PTY from AsyncSSH, and wire the local terminal's stdin up with it if interactive == True. This gives a real interactive session if local stdin belongs to a terminal. Also, thanks to AsyncSSH understanding that, forward terminal size changes to the remote end.
Add a SSHClient implementation using AsyncSSH. This is the first and currently only class derived from SSHClient which implements SSHClient.Cap.LogOutput, designed to consume and log command output as it streams in. It felt like the lower hanging fruit not to do that with Paramiko: Paramiko doesn't provide a native async API, so it would need to spawn additional worker threads. I think.
Add an optional caps ("capabilities") argument to the constructor of SSHClient. It is meant to be used by derived classes in order to declare that they don't want the base class to handle a default behaviour for a certain capability, but that they want to implement it themselves instead.
Also, give the _run_ssh() callbacks the necessary info as parameters, so that the derived classes have the means to do so.
Python's platform.system() outputs 'Linux', and to use it is tempting. Sadly, that's wrong, because it reflects the host's idea of the target system, not the execution context's, so replace it with straight 'linux' if the distro is known, or, failing that, the output of uname -s.
Even with --interactive=[true|auto], there's no point in trying to read /etc/os-release interactively, so don't do that. Most notably, this commit keeps the property method from spilling /etc/os-release's content over the terminal.
This commit introduces two new types, Input and InputMode. They replace the more error-prone special strings cmd_input could be used with. InputMode is an Enum, and Input can be either IntputMode, a string or None.
Whether or not the CallContext.interactive property should be True or False, and hence, a call should be processed interactively, depends on multiple factors, constituting matrix of options with multiple preferences.
--interactive is the application default and can be true, false,
or auto
- A call can be explicitly invoked as interactive, non-interactive
or auto via the cmd_input parameter to ExecContext.run()
This commit adds more "mode:" options to make the latter more explicit. It takes preference over the global --interactive parameter: Global --interactive is only given a chance to decide if cmd_input is None (default) or mode:opt-interactive.
This commit also fixes a bug: --interactive is ignored because the interactive argument passed to ExecContext's constructor is ignored later on in calls to the wrapped _run() and _sudo() methods.
Since commit 02697af5, ExecContext.run() returns bytes for stdout and stderr and fixes that in calling code. The thing it did not fix was the code calling run_cmd(), which also made return bytes. This commit catches up on that.
Distro's sudo() and run() wrappers are not flagged async. It still works, because throughout jw-pkg all callers expect a coroutine return value, but flagging them as async makes the return value obvious.
Move the code of SSHClientInternal and SSCClientCmd into lib.ec.ssh, as "Paramiko" and "Exec", respectively. This makes the class layout a little more modular, and along the way fixes a bug where SSHClientInternal could be instantiated but was unusable (if the Paramiko is not installed).
ExecContext's .sudo() omits many of run()'s parameters, and this commit adds them. To avoid redundancy around repeating and massaging the long parameter list of both functions and their return values, it also adds some deeper changes:
- Make run(), _run(), sudo() and _sudo() always return instances of
Result. Before it was allowed to return a triplet of stdout,
stderr, and exit status.
- Have ExecContext stay out of the business of decoding the result
entirely. Result provides a convenience method .decode()
operating on stdout and stderr and leaves the decision to the
caller.
This entails miniscule adaptations in calling code, namely in
App.os_release, util.get_profile_env() and CmdListRepos._run().
- Wrap the _run() and _sudo() callbacks in a context manager object
of type CallContext to avoid code duplication.
- Consistently name the first argument to run(), _run(), sudo() and
_sudo() "cmd", not "args". The latter suggests that the caller is
omitting the executable, which is not the case.