WIP Replace subprocess calls with a generic run function #109
|
@ -117,8 +117,7 @@ def check_archives(
|
||||||
# The check command spews to stdout/stderr even without the verbose flag. Suppress it.
|
# The check command spews to stdout/stderr even without the verbose flag. Suppress it.
|
||||||
stdout = None if verbosity_flags else open(os.devnull, 'w')
|
stdout = None if verbosity_flags else open(os.devnull, 'w')
|
||||||
|
|
||||||
logger.debug(' '.join(full_command))
|
run(full_command, stdout=stdout, stderr=subprocess.STDOUT)
|
||||||
subprocess.check_call(full_command, stdout=stdout, stderr=subprocess.STDOUT)
|
|
||||||
|
|
||||||
if 'extract' in checks:
|
if 'extract' in checks:
|
||||||
extract.extract_last_archive_dry_run(repository, lock_wait, local_path, remote_path)
|
extract.extract_last_archive_dry_run(repository, lock_wait, local_path, remote_path)
|
||||||
|
|
|
@ -2,9 +2,9 @@ import glob
|
||||||
import itertools
|
import itertools
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import subprocess
|
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
|
from borgmatic.run import run
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -154,5 +154,4 @@ def create_archive(
|
||||||
+ (('--json',) if json else ())
|
+ (('--json',) if json else ())
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.debug(' '.join(full_command))
|
return run(full_command, capture_output = json)
|
||||||
|
|||||||
subprocess.check_call(full_command)
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import logging
|
import logging
|
||||||
import sys
|
import sys
|
||||||
import subprocess
|
|
||||||
|
|
||||||
|
from borgmatic.run import run
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ def extract_last_archive_dry_run(repository, lock_wait=None, local_path='borg',
|
||||||
+ verbosity_flags
|
+ verbosity_flags
|
||||||
)
|
)
|
||||||
|
|
||||||
list_output = subprocess.check_output(full_list_command).decode(sys.stdout.encoding)
|
list_output = run(full_list_command, capture_output = True)
|
||||||
|
|
||||||
last_archive_name = list_output.strip().split('\n')[-1]
|
last_archive_name = list_output.strip().split('\n')[-1]
|
||||||
if not last_archive_name:
|
if not last_archive_name:
|
||||||
|
@ -48,5 +48,4 @@ def extract_last_archive_dry_run(repository, lock_wait=None, local_path='borg',
|
||||||
+ list_flag
|
+ list_flag
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.debug(' '.join(full_extract_command))
|
run(full_extract_command)
|
||||||
subprocess.check_call(full_extract_command)
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import logging
|
import logging
|
||||||
import subprocess
|
|
||||||
|
|
||||||
|
from borgmatic.run import run
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -23,7 +23,4 @@ def display_archives_info(
|
||||||
+ (('--json',) if json else ())
|
+ (('--json',) if json else ())
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.debug(' '.join(full_command))
|
return run(full_command, capture_output = json)
|
||||||
|
|
||||||
output = subprocess.check_output(full_command)
|
|
||||||
return output.decode() if output is not None else None
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import logging
|
import logging
|
||||||
import subprocess
|
|
||||||
|
|
||||||
|
from borgmatic.run import run
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -20,7 +20,5 @@ def list_archives(repository, storage_config, local_path='borg', remote_path=Non
|
||||||
+ (('--debug', '--show-rc') if logger.isEnabledFor(logging.DEBUG) else ())
|
+ (('--debug', '--show-rc') if logger.isEnabledFor(logging.DEBUG) else ())
|
||||||
+ (('--json',) if json else ())
|
+ (('--json',) if json else ())
|
||||||
)
|
)
|
||||||
logger.debug(' '.join(full_command))
|
|
||||||
|
|
||||||
output = subprocess.check_output(full_command)
|
run(full_command, capture_output = json)
|
||||||
witten
commented
Needs to Needs to `return` the result of the `run()` invocation?
|
|||||||
return output.decode() if output is not None else None
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import logging
|
import logging
|
||||||
import subprocess
|
|
||||||
|
|
||||||
|
from borgmatic.run import run
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -53,5 +53,4 @@ def prune_archives(
|
||||||
+ (('--dry-run',) if dry_run else ())
|
+ (('--dry-run',) if dry_run else ())
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.debug(' '.join(full_command))
|
run(full_command)
|
||||||
subprocess.check_call(full_command)
|
|
||||||
|
|
|
@ -205,7 +205,7 @@ def _run_commands_on_repository(
|
||||||
)
|
)
|
||||||
if args.create:
|
if args.create:
|
||||||
logger.info('{}: Creating archive{}'.format(repository, dry_run_label))
|
logger.info('{}: Creating archive{}'.format(repository, dry_run_label))
|
||||||
borg_create.create_archive(
|
output = borg_create.create_archive(
|
||||||
args.dry_run,
|
args.dry_run,
|
||||||
repository,
|
repository,
|
||||||
location,
|
location,
|
||||||
|
@ -213,6 +213,8 @@ def _run_commands_on_repository(
|
||||||
local_path=local_path,
|
local_path=local_path,
|
||||||
remote_path=remote_path,
|
remote_path=remote_path,
|
||||||
)
|
)
|
||||||
|
if args.json:
|
||||||
|
json_results.append(json.loads(output))
|
||||||
witten
commented
Would it make sense to do Would it make sense to do `if output:` instead of `if args.json` here? That way, you don't have the `args.json`-checking logic in two places (1. in `create_archive()` and, 2. here). Similar elsewhere in this function. Do no feel super strongly.
|
|||||||
if args.check and checks.repository_enabled_for_checks(repository, consistency):
|
if args.check and checks.repository_enabled_for_checks(repository, consistency):
|
||||||
logger.info('{}: Running consistency checks'.format(repository))
|
logger.info('{}: Running consistency checks'.format(repository))
|
||||||
borg_check.check_archives(
|
borg_check.check_archives(
|
||||||
|
@ -225,8 +227,6 @@ def _run_commands_on_repository(
|
||||||
)
|
)
|
||||||
if args.json:
|
if args.json:
|
||||||
json_results.append(json.loads(output))
|
json_results.append(json.loads(output))
|
||||||
else:
|
|
||||||
sys.stdout.write(output)
|
|
||||||
if args.info:
|
if args.info:
|
||||||
logger.info('{}: Displaying summary info for archives'.format(repository))
|
logger.info('{}: Displaying summary info for archives'.format(repository))
|
||||||
output = borg_info.display_archives_info(
|
output = borg_info.display_archives_info(
|
||||||
|
@ -234,8 +234,6 @@ def _run_commands_on_repository(
|
||||||
)
|
)
|
||||||
if args.json:
|
if args.json:
|
||||||
json_results.append(json.loads(output))
|
json_results.append(json.loads(output))
|
||||||
else:
|
|
||||||
sys.stdout.write(output)
|
|
||||||
|
|
||||||
|
|
||||||
def main(): # pragma: no cover
|
def main(): # pragma: no cover
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
import logging
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def run(args, capture_output = False, **kwargs):
|
||||||
witten
commented
Would be nice to have a doc string for this function, even though it's pretty self-explanitory. Also, given that this function is only used within Would be nice to have a doc string for this function, even though it's pretty self-explanitory.
Also, given that this function is only used within `borgmatic/borg/`, this file might belong in that directory. (Do not feel strongly.)
|
|||||||
|
logger.debug('Executing: ' + ' '.join(args))
|
||||||
witten
commented
Might be a little more idiomatic to do something like: Might be a little more idiomatic to do something like: `logger.debug('Executing: {}'.format(...))`
|
|||||||
|
|
||||||
|
if capture_output:
|
||||||
|
return subprocess.check_output(args, **kwargs).decode()
|
||||||
|
|
||||||
|
subprocess.check_call(args, **kwargs)
|
||||||
witten
commented
This function could use some very basic test coverage. Basically: The capture output case, and the no capture output case. That'd require a little bit of mocking. This function could use some very basic test coverage. Basically: The capture output case, and the no capture output case. That'd require a little bit of mocking.
|
Note that when you run the Black code formatter on this (part of running borgmatic's tox), it will complain about the format on lines like this one. You can always run
tox -e black
though to have it auto-reformat them for you.