Changeset - 902c313b4dfb
[Not reviewed]
0 2 0
Brett Smith - 4 years ago 2021-01-09 15:09:08
brettcsmith@brettcsmith.org
cliutil: New function can_run.
2 files changed with 30 insertions and 0 deletions:
0 comments (0 inline, 0 general)
conservancy_beancount/cliutil.py
Show inline comments
...
 
@@ -7,49 +7,51 @@ This program is free software: you can redistribute it and/or modify it.
 
Refer to the LICENSE.txt that came with the software for details.
 

	
 
This program is distributed in the hope that it will be useful,
 
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."""
 

	
 
import argparse
 
import datetime
 
import enum
 
import io
 
import logging
 
import operator
 
import os
 
import pkg_resources
 
import re
 
import signal
 
import subprocess
 
import sys
 
import traceback
 
import types
 

	
 
from pathlib import Path
 

	
 
import rt.exceptions as rt_error
 

	
 
from . import data
 
from . import filters
 
from . import rtutil
 

	
 
from typing import (
 
    cast,
 
    Any,
 
    BinaryIO,
 
    Callable,
 
    Container,
 
    IO,
 
    Iterable,
 
    NamedTuple,
 
    NoReturn,
 
    Optional,
 
    Sequence,
 
    TextIO,
 
    Type,
 
    Union,
 
)
 
from .beancount_types import (
 
    MetaKey,
 
)
 

	
 
OutputFile = Union[int, IO]
 

	
...
 
@@ -266,32 +268,48 @@ def add_rewrite_rules_argument(parser: argparse.ArgumentParser) -> argparse.Acti
 
        metavar='PATH',
 
        type=Path,
 
        help="""Use rewrite rules from the given YAML file. You can specify
 
this option multiple times to load multiple sets of rewrite rules in order.
 
""")
 

	
 
def add_version_argument(parser: argparse.ArgumentParser) -> argparse.Action:
 
    progname = parser.prog or sys.argv[0]
 
    return parser.add_argument(
 
        '--version', '--copyright', '--license',
 
        action=InfoAction,
 
        nargs=0,
 
        const=f"{progname} version {VERSION}\n{LICENSE}",
 
        help="Show program version and license information",
 
    )
 

	
 
def can_run(
 
        cmd: Sequence[str],
 
        stdout: Optional[int]=subprocess.DEVNULL,
 
        stderr: Optional[int]=None,
 
        ok_returncodes: Container[int]=frozenset([0]),
 
) -> bool:
 
    try:
 
        with subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=stdout, stderr=stderr) as proc:
 
            # Typing says this can be None, but I don't think that's true
 
            # given that we passed stdin=PIPE.
 
            proc.stdin.close()  # type:ignore[union-attr]
 
    except (OSError, subprocess.SubprocessError):
 
        return False
 
    else:
 
        return proc.returncode in ok_returncodes
 

	
 
def date_arg(arg: str) -> datetime.date:
 
    return datetime.datetime.strptime(arg, '%Y-%m-%d').date()
 

	
 
def diff_year(date: datetime.date, diff: int) -> datetime.date:
 
    new_year = date.year + diff
 
    try:
 
        return date.replace(year=new_year)
 
    except ValueError:
 
        # The original date is Feb 29, which doesn't exist in the new year.
 
        if diff < 0:
 
            return datetime.date(new_year, 2, 28)
 
        else:
 
            return datetime.date(new_year, 3, 1)
 

	
 
def year_or_date_arg(arg: str) -> Union[int, datetime.date]:
 
    """Get either a date or a year (int) from an argument string
tests/test_cliutil.py
Show inline comments
...
 
@@ -7,32 +7,34 @@
 

	
 
import argparse
 
import datetime
 
import errno
 
import io
 
import inspect
 
import logging
 
import os
 
import re
 
import sys
 
import traceback
 

	
 
import pytest
 

	
 
from pathlib import Path
 

	
 
from . import testutil
 

	
 
from conservancy_beancount import cliutil
 

	
 
FILE_NAMES = ['-foobar', '-foo.bin']
 
STREAM_PATHS = [None, Path('-')]
 

	
 
class MockTraceback:
 
    def __init__(self, stack=None, index=0):
 
        if stack is None:
 
            stack = inspect.stack(context=False)
 
        self._stack = stack
 
        self._index = index
 
        frame_record = self._stack[self._index]
 
        self.tb_frame = frame_record.frame
 
        self.tb_lineno = frame_record.lineno
 

	
 
    @property
...
 
@@ -214,16 +216,26 @@ def test_version_argument(argparser, capsys, arg):
 
    (datetime.date(2010, 2, 28), 0, datetime.date(2010, 2, 28)),
 
    (datetime.date(2010, 2, 28), 1, datetime.date(2011, 2, 28)),
 
    (datetime.date(2010, 2, 28), 2, datetime.date(2012, 2, 28)),
 
    (datetime.date(2010, 2, 28), -1, datetime.date(2009, 2, 28)),
 
    (datetime.date(2010, 2, 28), -2, datetime.date(2008, 2, 28)),
 
    (datetime.date(2012, 2, 29), 2, datetime.date(2014, 3, 1)),
 
    (datetime.date(2012, 2, 29), 4, datetime.date(2016, 2, 29)),
 
    (datetime.date(2012, 2, 29), -2, datetime.date(2010, 2, 28)),
 
    (datetime.date(2012, 2, 29), -4, datetime.date(2008, 2, 29)),
 
    (datetime.date(2010, 3, 1), 1, datetime.date(2011, 3, 1)),
 
    (datetime.date(2010, 3, 1), 2, datetime.date(2012, 3, 1)),
 
    (datetime.date(2010, 3, 1), -1, datetime.date(2009, 3, 1)),
 
    (datetime.date(2010, 3, 1), -2, datetime.date(2008, 3, 1)),
 
])
 
def test_diff_year(date, diff, expected):
 
    assert cliutil.diff_year(date, diff) == expected
 

	
 
@pytest.mark.parametrize('cmd,expected', [
 
    (['true'], True),
 
    (['true', '--version'], True),
 
    (['false'], False),
 
    (['false', '--version'], False),
 
    ([str(testutil.TESTS_DIR)], False),
 
])
 
def test_can_run(cmd, expected):
 
    assert cliutil.can_run(cmd) == expected
0 comments (0 inline, 0 general)