Argument parsing and package requests
This commit is contained in:
parent
66b3d72689
commit
607905241e
|
@ -0,0 +1,182 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
from datetime import datetime, timezone
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Optional
|
||||||
|
import argparse
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import pwd
|
||||||
|
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.INFO,
|
||||||
|
format='%(levelname)s: %(message)s',
|
||||||
|
)
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_username():
|
||||||
|
return pwd.getpwuid(os.getuid()).pw_name
|
||||||
|
|
||||||
|
|
||||||
|
# The recfile descriptor for package requests.
|
||||||
|
# Used if Breadpack generates the file from scratch.
|
||||||
|
REQUEST_DESCRIPTOR = """
|
||||||
|
%rec: PackageRequest
|
||||||
|
%type: Date date
|
||||||
|
%type: Processed bool
|
||||||
|
%type: User line
|
||||||
|
%type: Package line
|
||||||
|
%mandatory: Package
|
||||||
|
%allowed: Date User Processed Package Comment
|
||||||
|
%sort: Processed Date
|
||||||
|
%doc: Package requests made via breadpack
|
||||||
|
""".strip()
|
||||||
|
|
||||||
|
|
||||||
|
def request_subcommand(
|
||||||
|
requestsfile: Path,
|
||||||
|
package_name: str,
|
||||||
|
comment: Optional[str] = None,
|
||||||
|
**kwargs):
|
||||||
|
if not requestsfile.exists():
|
||||||
|
logger.warning(f'Creating file {requestsfile}')
|
||||||
|
with requestsfile.open('w') as f:
|
||||||
|
f.write(REQUEST_DESCRIPTOR)
|
||||||
|
|
||||||
|
data = {
|
||||||
|
'Date': datetime.now(timezone.utc).isoformat(),
|
||||||
|
'User': _get_username(),
|
||||||
|
'Processed': 'no',
|
||||||
|
'Package': package_name,
|
||||||
|
}
|
||||||
|
if comment:
|
||||||
|
data['Comment'] = comment
|
||||||
|
|
||||||
|
with requestsfile.open('a') as f:
|
||||||
|
f.write('\n\n' + '\n'.join([f'{k}: {v}' for k, v in data.items()]))
|
||||||
|
|
||||||
|
logger.info(f'Your request for {package_name!r} has been sent!')
|
||||||
|
|
||||||
|
|
||||||
|
def list_subcommand(json: bool = False, upgradable: bool = False, **kwargs):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
|
def lint_subcommand(file, **kwargs):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
|
def check_subcommand(json: bool = False, save: bool = True, **kwargs):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
|
def lock_subcommand(**kwargs):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description='Breadpunk.club meta-package manager'
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--file',
|
||||||
|
type=Path,
|
||||||
|
help='Path to the breadpack.json file.',
|
||||||
|
default=Path('/bread/breadpack.json'),
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--lockfile',
|
||||||
|
type=Path,
|
||||||
|
help='Path to the breadpack-lock.json file.',
|
||||||
|
default=Path('/bread/breadpack-lock.json'),
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--requestsfile',
|
||||||
|
type=Path,
|
||||||
|
help='Path to the breadpack-requests.rec file.',
|
||||||
|
default=Path('/bread/breadpack-requests.rec'),
|
||||||
|
)
|
||||||
|
|
||||||
|
def nocommand(**kwargs):
|
||||||
|
parser.error('A subcommand is required.')
|
||||||
|
|
||||||
|
parser.set_defaults(func=nocommand)
|
||||||
|
subparsers = parser.add_subparsers(
|
||||||
|
title='subcommands',
|
||||||
|
)
|
||||||
|
|
||||||
|
request_parser = subparsers.add_parser(
|
||||||
|
'request',
|
||||||
|
help='Request for a new package to be installed.',
|
||||||
|
)
|
||||||
|
request_parser.add_argument(
|
||||||
|
'package_name',
|
||||||
|
help='Name of the requested package.',
|
||||||
|
)
|
||||||
|
request_parser.add_argument(
|
||||||
|
'-c', '--comment',
|
||||||
|
help='Optional comment to add notes '
|
||||||
|
'for the admin processing your request.',
|
||||||
|
default=None,
|
||||||
|
)
|
||||||
|
request_parser.set_defaults(func=request_subcommand)
|
||||||
|
|
||||||
|
list_parser = subparsers.add_parser(
|
||||||
|
'list',
|
||||||
|
help='List installed packages.',
|
||||||
|
)
|
||||||
|
list_parser.add_argument(
|
||||||
|
'--json',
|
||||||
|
help='Use JSON output.',
|
||||||
|
action='store_true',
|
||||||
|
default=False,
|
||||||
|
)
|
||||||
|
list_parser.add_argument(
|
||||||
|
'--upgradable',
|
||||||
|
help='Only list packages with available updates.',
|
||||||
|
action='store_true',
|
||||||
|
default=False,
|
||||||
|
)
|
||||||
|
list_parser.set_defaults(func=list_subcommand)
|
||||||
|
|
||||||
|
lint_parser = subparsers.add_parser(
|
||||||
|
'lint',
|
||||||
|
help='Check the syntax of the packages file and lockfile.',
|
||||||
|
)
|
||||||
|
lint_parser.set_defaults(func=lint_subcommand)
|
||||||
|
|
||||||
|
lock_parser = subparsers.add_parser(
|
||||||
|
'lock',
|
||||||
|
help='Regenerate the lockfile from scratch.',
|
||||||
|
)
|
||||||
|
lock_parser.set_defaults(func=lock_subcommand)
|
||||||
|
|
||||||
|
check_parser = subparsers.add_parser(
|
||||||
|
'check',
|
||||||
|
help='Check for available updates.',
|
||||||
|
)
|
||||||
|
check_parser.add_argument(
|
||||||
|
'--json',
|
||||||
|
help='Use JSON output.',
|
||||||
|
action='store_true',
|
||||||
|
default=False,
|
||||||
|
)
|
||||||
|
check_parser.add_argument(
|
||||||
|
'--save',
|
||||||
|
help='Update the lockfile. This is the default.',
|
||||||
|
action='store_true',
|
||||||
|
default=True,
|
||||||
|
)
|
||||||
|
check_parser.add_argument(
|
||||||
|
'--no-save',
|
||||||
|
help='Do not update the lockfile.',
|
||||||
|
action='store_false',
|
||||||
|
dest='save',
|
||||||
|
)
|
||||||
|
|
||||||
|
args = vars(parser.parse_args())
|
||||||
|
args.pop('func', nocommand)(**args)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
Reference in New Issue