homely.system¶
homely.system.execute()¶
execute()
runs an external program in a subprocess in much the same way as
python’s subprocess module does, but the API is better suited towards the sorts
of things you will probably do in a HOMELY.py
script. When possible, the
program’s output is filtered through homely’s logging functions so that the
output is more readable amongst the other output from homely.
Note: if your python version doesn’t have asyncio
, output from the command will not be printed until the program has exited.
execute(cmd, stdout=None, stderr=None, expectexit=0, **kwargs)
stdout
There are four possible values for
stdout
:stdout=None
- Stdout from the subprocess will be filtered through homely’s logging functions so that the output is more readable in the context of everything else that’s printed to screen by homely. The subprocess will not have access to a TTY for user input. This is the default.
stdout=False
- Stdout from the subprocess will be discarded.
stdout=True
- Stdout from the subprocess will be included in the return value.
stdout="TTY"
The subprocess’s stdout will be connected directly to the homely process’s TTY to allow the user to interact with the subprocess. An exception will be raised if
execute()
was invoked in a context where there is no TTY available. (You can use homely.ui.allowinteractive() to determine ifstdout="TTY"
will be successful or not.)If you have used
stdout="TTY"
, then you must omit thestderr
argument, or usestderr=None
.
stderr
There are four possible values for
stderr
:stderr=None
Stderr from the subprocess will be filtered through homely’s logging functions so that the output is more readable in the context of everything else that’s printed to screen by homely.
NOTE: If you used
stdout="TTY"
then you must omitstderr
or usestderr=None
, and the subprocess’s stderr stream will be connected to the parent process’ TTY.stderr=False
- Same as for
stdout=False
- the subprocess’ stderr will be discarded. stderr=True
- Same as for
stdout=True
- the subprocess’ stderr will be included in the return value. stderr="STDOUT"
- The subprocess’ stderr stream will be merged with its stdout stream.
expectexit=0
- If the subprocess’ exit code is not equal to
expectexit
, an exception will be raised. You can also use a sequence (expectexit=[0, 1, ...]
) if there are multiple exit codes that signify success. **kwargs
kwargs
are passed directly into subprocess.Popen(), or loop.subprocess_exec() when asyncio is used to spawn the subprocess.
The return value will be a tuple of (exitcode
, stdout
, stderr
).
The stdout
and stderr
components will contain the entire contents of the process’s stdout/stderr streams, but only when you use use stdout=True
or stderr=True
, respectively.
Examples¶
Universal ctags is a great tool, but not available by default in homebrew. This example installs it by running the necessary brew commands:
from homely.system import execute
# install universal-ctags with homebrew
if haveexecutable('brew'):
execute(['brew', 'tap', 'universal-ctags/universal-ctags'])
execute(['brew', 'install', '--HEAD', 'universal-ctags'])
When homebrew isn’t installed, we can run the necessary shell commands to compile from source:
import os
from homely.system import execute, haveexecutable
from homely.files import mkdir, symlink
# install universal-ctags from source
if not haveexecutable('brew'):
url = 'https://github.com/universal-ctags/ctags'
checkout = '{}/src/universal-ctags.git'.format(os.environ['HOME']')
branch = 'master'
mkdir('~/src')
if not os.path.exists(checkout):
# clone the repo if we don't have a copy yet
execute(['git', 'clone', 'url', checkout])
execute(['git', 'checkout', 'master'], cwd=checkout)
else:
# pull the branch we want if we already have a clone
execute(['git', 'checkout', branch], cwd=checkout)
execute(['git', 'pull'], cwd=checkout)
# update to latest master branch
execute(['./autogen.sh'], cwd=checkout)
execute(['./configure'], cwd=checkout)
execute(['make'], cwd=checkout)
# create a symlink to the compiled binary and put it in ~/bin
mkdir('~/bin')
symlink('{}/ctags'.format(checkout), '~/bin/ctags')
Automatic Cleanup¶
Automatic Cleanup is not available for this feature.
homely.system.haveexecutable()¶
haveexecutable()
will return True
or False
depending on whether or not a particular executable is available in your $PATH
.
haveexecutable(name)
name
- The name of the executable you want to check for.
Examples¶
This code will clone a copy of the crecord mercurial extension in ~/src/crecord
, but only when the mercurial executable (hg
) is present:
import os
from homely.system import haveexecutable, execute
if haveexecutable('hg'):
src = os.environ["HOME"] + '/src'
mkdir(src)
localpath = src + '/crecord'
url = 'https://bitbucket.org/edgimar/crecord'
if os.path.exists(localpath):
execute(['hg', 'pull'], cwd=localpath)
else:
execute(['hg', 'clone', url, localpath])