Skip to content

Commit

Permalink
Rework -f argfile mechanism to avoid argparse required checks. #11
Browse files Browse the repository at this point in the history
  • Loading branch information
amykyta3 committed Jan 19, 2023
1 parent d7fa0b1 commit 748c857
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 20 deletions.
43 changes: 41 additions & 2 deletions src/peakrdl/main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import argparse
import sys
from typing import TYPE_CHECKING, List, Dict
import os
import shlex
from typing import TYPE_CHECKING, List, Dict, Optional, Set

from systemrdl import RDLCompileError

Expand Down Expand Up @@ -48,6 +50,42 @@ def __call__ (self, parser, namespace, values, option_string = None): # type: ig
sys.exit(0)


def get_file_args(path: str) -> List[str]:
if not os.path.exists(path):
print(f"error: file not found: {path}", file=sys.stderr)
sys.exit(1)

with open(path, "r", encoding='utf-8') as f:
return shlex.split(f.read(), comments=True)


def expand_file_args(argv: List[str], _pathlist: Optional[Set[str]] = None) -> List[str]:
if _pathlist is None:
_pathlist = set()

new_argv = []
argv_iter = iter(argv)
for arg in argv_iter:
if arg == "-f":
try:
path = next(argv_iter)
except StopIteration:
print("error: argument -f: expected FILE", file=sys.stderr)
sys.exit(1)

if path in _pathlist:
print(f"error: circular reference in -f files: '{path}' was already opened", file=sys.stderr)
sys.exit(1)
_pathlist.add(path)
file_args = get_file_args(path)
file_args = expand_file_args(file_args, _pathlist)
_pathlist.remove(path)
new_argv.extend(file_args)
else:
new_argv.append(arg)
return new_argv


def main() -> None:
# Collect all subcommands
subcommands = [
Expand Down Expand Up @@ -83,7 +121,8 @@ def main() -> None:
subcommand._init_subparser(subgroup)

# Execute!
options = parser.parse_args()
argv = expand_file_args(sys.argv[1:])
options = parser.parse_args(argv)
if not hasattr(options, 'subcommand'):
parser.print_usage()
print(f"{parser.prog}: error the following arguments are required: <subcommand>")
Expand Down
21 changes: 3 additions & 18 deletions src/peakrdl/subcommand.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,6 @@
from systemrdl.node import AddrmapNode
from systemrdl.udp import UDPDefinition


class LoadArgsFromFile(argparse.Action):
def __call__ (self, parser, namespace, values, option_string = None): # type: ignore
argfile = values

if not os.path.exists(argfile):
print(f"file not found: {argfile}", file=sys.stderr)
sys.exit(1)

with open(argfile, "r", encoding='utf-8') as f:
parser.parse_args(
shlex.split(f.read(), comments=True),
namespace
)


class Subcommand:
"""
Base command line interface subcommand class
Expand Down Expand Up @@ -57,10 +41,11 @@ def _init_subparser(self, subgroup: 'argparse._SubParsersAction') -> None:
self.add_arguments(subparser)
subparser.set_defaults(subcommand=self)

# Add
subparser.add_argument(
'-f',
metavar="FILENAME",
action=LoadArgsFromFile,
metavar="FILE",
dest="argfile",
help="Specify a file containing more command line arguments"
)

Expand Down

0 comments on commit 748c857

Please sign in to comment.