pass all tests with wittens recommendation
This commit is contained in:
parent
6a1d1a2e59
commit
4b024daae0
3 changed files with 62 additions and 30 deletions
|
@ -1,18 +1,20 @@
|
|||
import json
|
||||
import logging
|
||||
import os
|
||||
import json
|
||||
|
||||
import borgmatic.borg.extract
|
||||
import borgmatic.borg.rlist
|
||||
import borgmatic.config.validate
|
||||
import borgmatic.hooks.command
|
||||
|
||||
from borgmatic.borg.state import DEFAULT_BORGMATIC_SOURCE_DIRECTORY
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_config_paths(bootstrap_arguments, global_arguments, local_borg_version):
|
||||
borgmatic_source_directory = bootstrap_arguments.borgmatic_source_directory or DEFAULT_BORGMATIC_SOURCE_DIRECTORY
|
||||
borgmatic_source_directory = (
|
||||
bootstrap_arguments.borgmatic_source_directory or DEFAULT_BORGMATIC_SOURCE_DIRECTORY
|
||||
)
|
||||
borgmatic_manifest_path = os.path.expanduser(
|
||||
os.path.join(borgmatic_source_directory, 'bootstrap', 'manifest.json')
|
||||
)
|
||||
|
@ -24,7 +26,7 @@ def get_config_paths(bootstrap_arguments, global_arguments, local_borg_version):
|
|||
bootstrap_arguments.archive,
|
||||
{},
|
||||
local_borg_version,
|
||||
global_arguments
|
||||
global_arguments,
|
||||
),
|
||||
[borgmatic_manifest_path],
|
||||
{},
|
||||
|
@ -38,14 +40,14 @@ def get_config_paths(bootstrap_arguments, global_arguments, local_borg_version):
|
|||
|
||||
return manifest_data['config_paths']
|
||||
|
||||
|
||||
|
||||
|
||||
def run_bootstrap(bootstrap_arguments, global_arguments, local_borg_version):
|
||||
'''
|
||||
Run the "bootstrap" action for the given repository.
|
||||
'''
|
||||
manifest_config_paths = get_config_paths(bootstrap_arguments, global_arguments, local_borg_version)
|
||||
manifest_config_paths = get_config_paths(
|
||||
bootstrap_arguments, global_arguments, local_borg_version
|
||||
)
|
||||
|
||||
for config_path in manifest_config_paths:
|
||||
logger.info('Bootstrapping config path %s', config_path)
|
||||
|
@ -58,7 +60,7 @@ def run_bootstrap(bootstrap_arguments, global_arguments, local_borg_version):
|
|||
bootstrap_arguments.archive,
|
||||
{},
|
||||
local_borg_version,
|
||||
global_arguments
|
||||
global_arguments,
|
||||
),
|
||||
[config_path],
|
||||
{},
|
||||
|
@ -70,7 +72,3 @@ def run_bootstrap(bootstrap_arguments, global_arguments, local_borg_version):
|
|||
strip_components=bootstrap_arguments.strip_components,
|
||||
progress=bootstrap_arguments.progress,
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import argparse
|
||||
import collections
|
||||
import itertools
|
||||
from argparse import Action, ArgumentParser
|
||||
|
||||
from borgmatic.config import collect
|
||||
|
@ -75,14 +76,20 @@ def parse_subparser_arguments(unparsed_arguments, subparsers):
|
|||
remaining_arguments.remove(item)
|
||||
|
||||
try:
|
||||
arguments[canonical_name] = None if canonical_name in subcommand_parsers_mapping else parsed
|
||||
arguments[canonical_name] = (
|
||||
None if canonical_name in subcommand_parsers_mapping else parsed
|
||||
)
|
||||
except UnboundLocalError:
|
||||
pass
|
||||
|
||||
|
||||
for argument in arguments:
|
||||
if not arguments[argument]:
|
||||
if not any(subcommand in arguments for subcommand in subcommand_parsers_mapping[argument]):
|
||||
raise ValueError(f"Missing subcommand for {argument}. Expected one of {subcommand_parsers_mapping[argument]}")
|
||||
if not any(
|
||||
subcommand in arguments for subcommand in subcommand_parsers_mapping[argument]
|
||||
):
|
||||
raise ValueError(
|
||||
f'Missing subcommand for {argument}. Expected one of {subcommand_parsers_mapping[argument]}'
|
||||
)
|
||||
|
||||
# If no actions are explicitly requested, assume defaults.
|
||||
if not arguments and '--help' not in unparsed_arguments and '-h' not in unparsed_arguments:
|
||||
|
@ -93,6 +100,10 @@ def parse_subparser_arguments(unparsed_arguments, subparsers):
|
|||
|
||||
remaining_arguments = list(unparsed_arguments)
|
||||
|
||||
# Now ask each subparser, one by one, to greedily consume arguments, from last to first. This
|
||||
# allows subparsers to consume arguments before their parent subparsers do.
|
||||
remaining_subparser_arguments = []
|
||||
|
||||
# Now ask each subparser, one by one, to greedily consume arguments, from last to first. This
|
||||
# allows subparsers to consume arguments before their parent subparsers do.
|
||||
for subparser_name, subparser in reversed(subparsers.items()):
|
||||
|
@ -100,9 +111,23 @@ def parse_subparser_arguments(unparsed_arguments, subparsers):
|
|||
continue
|
||||
|
||||
subparser = subparsers[subparser_name]
|
||||
unused_parsed, remaining_arguments = subparser.parse_known_args(
|
||||
[argument for argument in remaining_arguments if argument != subparser_name]
|
||||
unused_parsed, remaining = subparser.parse_known_args(
|
||||
[argument for argument in unparsed_arguments if argument != subparser_name]
|
||||
)
|
||||
remaining_subparser_arguments.append(remaining)
|
||||
|
||||
# Determine the remaining arguments that no subparsers have consumed.
|
||||
if remaining_subparser_arguments:
|
||||
remaining_arguments = [
|
||||
argument
|
||||
for argument in dict.fromkeys(
|
||||
itertools.chain.from_iterable(remaining_subparser_arguments)
|
||||
).keys()
|
||||
if all(
|
||||
argument in subparser_arguments
|
||||
for subparser_arguments in remaining_subparser_arguments
|
||||
)
|
||||
]
|
||||
|
||||
# Special case: If "borg" is present in the arguments, consume all arguments after (+1) the
|
||||
# "borg" action.
|
||||
|
@ -551,9 +576,7 @@ def make_parsers():
|
|||
)
|
||||
|
||||
config_group = config_parser.add_argument_group('config arguments')
|
||||
config_group.add_argument(
|
||||
'-h', '--help', action='help', help='Show this help message and exit'
|
||||
)
|
||||
config_group.add_argument('-h', '--help', action='help', help='Show this help message and exit')
|
||||
|
||||
config_subparsers = config_parser.add_subparsers(
|
||||
title='config subcommands',
|
||||
|
@ -568,7 +591,9 @@ def make_parsers():
|
|||
description='Extract just the config files that were used to create a borgmatic repository during the "create" operation',
|
||||
add_help=False,
|
||||
)
|
||||
config_bootstrap_group = config_bootstrap_parser.add_argument_group('config bootstrap arguments')
|
||||
config_bootstrap_group = config_bootstrap_parser.add_argument_group(
|
||||
'config bootstrap arguments'
|
||||
)
|
||||
config_bootstrap_group.add_argument(
|
||||
'--repository',
|
||||
help='Path of repository to extract config files from',
|
||||
|
@ -579,7 +604,9 @@ def make_parsers():
|
|||
help='Path that stores the config files used to create an archive, and additional source files used for temporary internal state like borgmatic database dumps. Defaults to ~/.borgmatic',
|
||||
)
|
||||
config_bootstrap_group.add_argument(
|
||||
'--archive', help='Name of archive to extract config files from, defaults to "latest"', default='latest'
|
||||
'--archive',
|
||||
help='Name of archive to extract config files from, defaults to "latest"',
|
||||
default='latest',
|
||||
)
|
||||
config_bootstrap_group.add_argument(
|
||||
'--destination',
|
||||
|
@ -947,7 +974,9 @@ def make_parsers():
|
|||
)
|
||||
borg_group.add_argument('-h', '--help', action='help', help='Show this help message and exit')
|
||||
|
||||
merged_subparsers = argparse._SubParsersAction(None, None, metavar=None, dest='merged', parser_class=None)
|
||||
merged_subparsers = argparse._SubParsersAction(
|
||||
None, None, metavar=None, dest='merged', parser_class=None
|
||||
)
|
||||
|
||||
for name, subparser in subparsers.choices.items():
|
||||
merged_subparsers._name_parser_map[name] = subparser
|
||||
|
@ -957,7 +986,7 @@ def make_parsers():
|
|||
merged_subparsers._name_parser_map[name] = subparser
|
||||
subparser._name_parser_map = merged_subparsers._name_parser_map
|
||||
|
||||
return top_level_parser, merged_subparsers
|
||||
return top_level_parser, merged_subparsers
|
||||
|
||||
|
||||
def parse_arguments(*unparsed_arguments):
|
||||
|
@ -967,12 +996,15 @@ def parse_arguments(*unparsed_arguments):
|
|||
'''
|
||||
top_level_parser, subparsers = make_parsers()
|
||||
|
||||
|
||||
arguments, remaining_arguments = parse_subparser_arguments(
|
||||
unparsed_arguments, subparsers.choices
|
||||
)
|
||||
|
||||
if 'bootstrap' in arguments.keys() and 'config' in arguments.keys() and len(arguments.keys()) > 2:
|
||||
if (
|
||||
'bootstrap' in arguments.keys()
|
||||
and 'config' in arguments.keys()
|
||||
and len(arguments.keys()) > 2
|
||||
):
|
||||
raise ValueError(
|
||||
'The bootstrap action cannot be combined with other actions. Please run it separately.'
|
||||
)
|
||||
|
|
|
@ -18,10 +18,10 @@ import borgmatic.actions.borg
|
|||
import borgmatic.actions.break_lock
|
||||
import borgmatic.actions.check
|
||||
import borgmatic.actions.compact
|
||||
import borgmatic.actions.config.bootstrap
|
||||
import borgmatic.actions.create
|
||||
import borgmatic.actions.export_tar
|
||||
import borgmatic.actions.extract
|
||||
import borgmatic.actions.config.bootstrap
|
||||
import borgmatic.actions.info
|
||||
import borgmatic.actions.list
|
||||
import borgmatic.actions.mount
|
||||
|
@ -622,12 +622,14 @@ def collect_configuration_run_summary_logs(configs, arguments):
|
|||
except ValueError as error:
|
||||
yield from log_error_records(str(error))
|
||||
return
|
||||
|
||||
|
||||
if 'bootstrap' in arguments:
|
||||
# no configuration file is needed for bootstrap
|
||||
local_borg_version = borg_version.local_borg_version({}, 'borg')
|
||||
try:
|
||||
borgmatic.actions.config.bootstrap.run_bootstrap(arguments['bootstrap'], arguments['global'], local_borg_version)
|
||||
borgmatic.actions.config.bootstrap.run_bootstrap(
|
||||
arguments['bootstrap'], arguments['global'], local_borg_version
|
||||
)
|
||||
yield logging.makeLogRecord(
|
||||
dict(
|
||||
levelno=logging.INFO,
|
||||
|
|
Loading…
Reference in a new issue