Skip to content

Commit 31493e4

Browse files
committed
cli command add init
1 parent edc987b commit 31493e4

5 files changed

Lines changed: 95 additions & 14 deletions

File tree

docs/cli.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ You can run it with a valid Python 3 interpreter, provided all requirements are
1010
```
1111
$ python3 PrimeBackup.pyz
1212
usage: PrimeBackup.pyz [-h] [-d DB] [-c CONFIG] [--version] [--debug]
13-
{back,overview,export,extract,fuse,import,list,make,migrate_db,show}
13+
{back,overview,export,extract,fuse,import,init,list,make,migrate_db,show}
1414
...
1515
1616
Prime Backup v1.x.x CLI tools
@@ -29,7 +29,7 @@ options:
2929
--debug Enable debug logging (default: False)
3030
3131
Command:
32-
{back,overview,export,extract,fuse,import,list,make,migrate_db,show}
32+
{back,overview,export,extract,fuse,import,init,list,make,migrate_db,show}
3333
Available commands
3434
back Restore the server files to a backup
3535
overview Show overview information of the database
@@ -40,6 +40,7 @@ Command:
4040
needs to have a backup metadata file
4141
'.prime_backup.meta.json', or the --auto-meta option
4242
need to be supplied
43+
init Initialize a new database at the directory given by --db
4344
list List backups
4445
make Create a new backup
4546
migrate_db Migrate the database to the current version X

docs/cli.zh.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Prime Backup 的 `*.pyz` 文件除了是一个 MCDR 插件外,也是一个命
1010
```
1111
$ python3 PrimeBackup.pyz
1212
usage: PrimeBackup.pyz [-h] [-d DB] [-c CONFIG] [--version] [--debug]
13-
{back,overview,export,extract,fuse,import,list,make,migrate_db,show}
13+
{back,overview,export,extract,fuse,import,init,list,make,migrate_db,show}
1414
...
1515
1616
Prime Backup v1.x.x CLI tools
@@ -29,7 +29,7 @@ options:
2929
--debug Enable debug logging (default: False)
3030
3131
Command:
32-
{back,overview,export,extract,fuse,import,list,make,migrate_db,show}
32+
{back,overview,export,extract,fuse,import,init,list,make,migrate_db,show}
3333
Available commands
3434
back Restore the server files to a backup
3535
overview Show overview information of the database
@@ -40,6 +40,7 @@ Command:
4040
needs to have a backup metadata file
4141
'.prime_backup.meta.json', or the --auto-meta option
4242
need to be supplied
43+
init Initialize a new database at the directory given by --db
4344
list List backups
4445
make Create a new backup
4546
migrate_db Migrate the database to the current version X

prime_backup/cli/cli_entrypoint.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from prime_backup.cli.cmd.cmd_extract import ExtractCommandAdapter
1111
from prime_backup.cli.cmd.cmd_fuse import FuseCommandAdapter
1212
from prime_backup.cli.cmd.cmd_import import ImportCommandAdapter
13+
from prime_backup.cli.cmd.cmd_init import InitCommandAdapter
1314
from prime_backup.cli.cmd.cmd_list import ListCommandAdapter
1415
from prime_backup.cli.cmd.cmd_make import MakeCommandAdapter
1516
from prime_backup.cli.cmd.cmd_migrate_db import MigrateDbCommandAdapter
@@ -48,6 +49,7 @@ def __create_command_adapters(cls) -> Dict[str, CliCommandAdapterBase]:
4849
ExtractCommandAdapter(),
4950
FuseCommandAdapter(),
5051
ImportCommandAdapter(),
52+
InitCommandAdapter(),
5153
ListCommandAdapter(),
5254
MakeCommandAdapter(),
5355
MigrateDbCommandAdapter(),

prime_backup/cli/cmd/__init__.py

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,30 +39,42 @@ def init_environment(self, db_path: Path, *, migrate: bool = False, config_path:
3939
if root_path.is_file() and root_path.name == db_constants.DB_FILE_NAME:
4040
root_path = root_path.parent
4141

42+
config = self.load_config(root_path, config_path)
43+
set_config_instance(config)
44+
45+
if not (dbf := root_path / db_constants.DB_FILE_NAME).is_file():
46+
self.logger.error('Database file {!r} does not exist'.format(dbf.as_posix()))
47+
ErrorReturnCodes.invalid_argument.sys_exit()
48+
self.init_db(root_path, create=False, migrate=migrate)
49+
50+
@classmethod
51+
def load_config(cls, root_path: Path, config_path: Optional[Path]) -> Config:
4252
if config_path is None:
4353
auto_config_path = root_path.parent / 'config' / 'prime_backup' / 'config.json'
4454
if auto_config_path.is_file():
45-
config = self.__load_config(auto_config_path)
46-
self.logger.info('Config file auto-detected and loaded from {!r}'.format(auto_config_path.as_posix()))
55+
config = cls.__load_config(auto_config_path)
56+
logger.get().info('Config file auto-detected and loaded from {!r}'.format(auto_config_path.as_posix()))
4757
else:
4858
config = Config.get_default()
49-
self.logger.info('Config file not provided; auto-detected path {!r} does not exist, using default config'.format(auto_config_path.as_posix()))
59+
logger.get().info('Config file not provided; auto-detected path {!r} does not exist, using default config'.format(auto_config_path.as_posix()))
5060
else:
51-
config = self.__load_config(config_path)
52-
self.logger.info('Config file loaded from {!r}'.format(config_path.as_posix()))
53-
54-
set_config_instance(config)
61+
config = cls.__load_config(config_path)
62+
logger.get().info('Config file loaded from {!r}'.format(config_path.as_posix()))
63+
return config
5564

56-
if not (dbf := root_path / db_constants.DB_FILE_NAME).is_file():
57-
self.logger.error('Database file {!r} does not exist'.format(dbf.as_posix()))
65+
def init_db(self, root_path: Path, *, create: bool, migrate: bool):
66+
if root_path.is_file():
67+
self.logger.error('Storage root {!r} is a file'.format(root_path.as_posix()))
5868
ErrorReturnCodes.invalid_argument.sys_exit()
69+
70+
config = Config.get()
5971
config.storage_root = str(root_path.as_posix())
6072

6173
self.logger.info('Storage root set to {!r}'.format(config.storage_root))
6274
try:
6375
if DbAccess.is_initialized():
6476
DbAccess.shutdown()
65-
DbAccess.init(create=False, migrate=migrate)
77+
DbAccess.init(create=create, migrate=migrate)
6678
except BadDbVersion as e:
6779
self.logger.info('Load database failed, you need to ensure the database is accessible with MCDR plugin: {}'.format(e))
6880
ErrorReturnCodes.action_failed.sys_exit()

prime_backup/cli/cmd/cmd_init.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import argparse
2+
import dataclasses
3+
from pathlib import Path
4+
5+
from typing_extensions import override
6+
7+
from prime_backup.action.get_db_overview_action import GetDbOverviewAction
8+
from prime_backup.cli.cmd import CliCommandHandlerBase, CommonCommandArgs, CliCommandAdapterBase
9+
from prime_backup.cli.return_codes import ErrorReturnCodes
10+
from prime_backup.config.config import set_config_instance
11+
from prime_backup.db import db_constants
12+
from prime_backup.db.access import DbAccess
13+
14+
15+
@dataclasses.dataclass(frozen=True)
16+
class InitCommandArgs(CommonCommandArgs):
17+
pass
18+
19+
20+
class InitCommandHandler(CliCommandHandlerBase):
21+
def __init__(self, args: InitCommandArgs):
22+
super().__init__()
23+
self.args = args
24+
25+
def handle(self):
26+
root_path = self.args.db_path
27+
if root_path.name == db_constants.DB_FILE_NAME and not root_path.is_dir():
28+
self.logger.error('The init command expects --db to be the database parent directory, not the database file path {!r}'.format(root_path.as_posix()))
29+
ErrorReturnCodes.invalid_argument.sys_exit()
30+
31+
db_file_path = root_path / db_constants.DB_FILE_NAME
32+
if db_file_path.exists():
33+
self.logger.error('Database file {!r} already exists'.format(db_file_path.as_posix()))
34+
ErrorReturnCodes.invalid_argument.sys_exit()
35+
36+
config = self.load_config(root_path, self.args.config_path)
37+
set_config_instance(config)
38+
self.init_db(root_path, create=True, migrate=False)
39+
40+
result = GetDbOverviewAction().run()
41+
self.logger.info('Database initialized at {!r}, current DB version: {}'.format(DbAccess.get_db_file_path().as_posix(), result.db_version))
42+
43+
44+
class InitCommandAdapter(CliCommandAdapterBase):
45+
@property
46+
@override
47+
def command(self) -> str:
48+
return 'init'
49+
50+
@property
51+
@override
52+
def description(self) -> str:
53+
return 'Initialize a new database at the directory given by --db'
54+
55+
@override
56+
def build_parser(self, parser: argparse.ArgumentParser):
57+
pass
58+
59+
@override
60+
def run(self, args: argparse.Namespace):
61+
handler = InitCommandHandler(InitCommandArgs(
62+
db_path=Path(args.db),
63+
config_path=Path(args.config) if args.config is not None else None,
64+
))
65+
handler.handle()

0 commit comments

Comments
 (0)