Skip to content

Commit 04a59c2

Browse files
committed
Updated the PathType and StorePathAction classes to allow for asserting if a path contains an executable.
1 parent 0f1b616 commit 04a59c2

File tree

4 files changed

+54
-9
lines changed

4 files changed

+54
-9
lines changed

utils/build_swift/argparse/actions.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ def __init__(self, option_strings, **kwargs):
180180

181181
if 'choices' in kwargs:
182182
kwargs['nargs'] = Nargs.OPTIONAL
183-
if 'const' in kwargs:
183+
elif 'const' in kwargs:
184184
kwargs['nargs'] = Nargs.ZERO
185185

186186
super(StoreAction, self).__init__(
@@ -242,8 +242,11 @@ class StorePathAction(StoreAction):
242242
"""
243243

244244
def __init__(self, option_strings, **kwargs):
245+
assert_exists = kwargs.pop('exists', False)
246+
assert_executable = kwargs.pop('executable', False)
247+
245248
kwargs['nargs'] = Nargs.SINGLE
246-
kwargs['type'] = PathType()
249+
kwargs['type'] = PathType(assert_exists, assert_executable)
247250
kwargs.setdefault('metavar', 'PATH')
248251

249252
super(StorePathAction, self).__init__(

utils/build_swift/argparse/types.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,19 +62,30 @@ class PathType(object):
6262
by the path exists.
6363
"""
6464

65-
def __init__(self, assert_exists=False):
65+
def __init__(self, assert_exists=False, assert_executable=False):
66+
if assert_executable:
67+
assert_exists = True
68+
6669
self.assert_exists = assert_exists
70+
self.assert_executable = assert_executable
6771

6872
def __call__(self, path):
6973
path = os.path.expanduser(path)
7074
path = os.path.abspath(path)
7175
path = os.path.realpath(path)
7276

73-
if self.assert_exists:
74-
assert os.path.exists(path)
77+
if self.assert_exists and not os.path.exists(path):
78+
raise ArgumentTypeError('{} does not exists'.format(path))
79+
80+
if self.assert_executable and not PathType._is_executable(path):
81+
raise ArgumentTypeError('{} is not an executable'.format(path))
7582

7683
return path
7784

85+
@staticmethod
86+
def _is_executable(path):
87+
return os.path.isfile(path) and os.access(path, os.X_OK)
88+
7889

7990
class RegexType(object):
8091
"""Argument type used to validate an input string against a regular

utils/build_swift/tests/argparse/test_actions.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@
77
# See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
88

99

10+
import os
11+
1012
from ..utils import TestCase, redirect_stderr
11-
from ...argparse import (ArgumentParser, BoolType, Nargs, PathType, SUPPRESS,
12-
actions)
13+
from ...argparse import (ArgumentParser, ArgumentTypeError, BoolType, Nargs,
14+
PathType, SUPPRESS, actions)
1315

1416

1517
# -----------------------------------------------------------------------------
@@ -252,6 +254,22 @@ def test_default_attributes(self):
252254
self.assertEqual(action.nargs, Nargs.SINGLE)
253255
self.assertIsInstance(action.type, PathType)
254256

257+
def test_exists(self):
258+
pass
259+
260+
def test_executable(self):
261+
parser = ArgumentParser()
262+
parser.add_argument('--foo', action=actions.StorePathAction,
263+
executable=True)
264+
265+
bash_path = '/bin/bash'
266+
if os.path.exists(bash_path) and os.access(bash_path, os.X_OK):
267+
with self.assertNotRaises(ArgumentTypeError):
268+
parser.parse_args(['--foo', bash_path])
269+
270+
with self.assertRaises(SystemExit):
271+
parser.parse_args(['--foo', __file__])
272+
255273

256274
class TestToggleTrueAction(TestCase):
257275

utils/build_swift/tests/argparse/test_types.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,26 @@ def test_expands_path(self):
9090
def test_assert_exists(self):
9191
path_type = types.PathType(assert_exists=True)
9292

93-
with self.assertNotRaises(AssertionError):
93+
with self.assertNotRaises(ArgumentTypeError):
9494
path_type(__file__)
9595

96-
with self.assertRaises(AssertionError):
96+
with self.assertRaises(ArgumentTypeError):
9797
path_type('/nonsensisal/path/')
9898
path_type('~/not-a-real/path to a file')
9999

100+
def test_assert_executable(self):
101+
path_type = types.PathType(assert_executable=True)
102+
103+
self.assertTrue(path_type.assert_exists)
104+
105+
bash_path = '/bin/bash'
106+
if os.path.isfile(bash_path) and os.access(bash_path, os.X_OK):
107+
with self.assertNotRaises(ArgumentTypeError):
108+
path_type(bash_path)
109+
110+
with self.assertRaises(ArgumentTypeError):
111+
path_type(__file__)
112+
100113

101114
class TestRegexType(TestCase):
102115

0 commit comments

Comments
 (0)