Skip to content

Commit 73db64e

Browse files
Merge pull request #136 from getgauge/134_multiple_stepImplDir
#134 Add support for multiple step implementation directories
2 parents 84c792d + 31918a8 commit 73db64e

File tree

9 files changed

+70
-44
lines changed

9 files changed

+70
-44
lines changed

getgauge/impl_loader.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from getgauge.util import *
1212

1313
project_root = get_project_root()
14-
impl_dir = get_step_impl_dir()
14+
impl_dirs = get_step_impl_dirs()
1515
env_dir = os.path.join(project_root, 'env', 'default')
1616
requirements_file = os.path.join(project_root, 'requirements.txt')
1717
sys.path.append(project_root)
@@ -21,22 +21,23 @@
2121
SKEL = 'skel'
2222

2323

24-
def load_impls(step_impl_dir=impl_dir):
24+
def load_impls(step_impl_dirs=impl_dirs):
2525
os.chdir(project_root)
26-
if not os.path.isdir(step_impl_dir):
27-
logging.error('Cannot import step implementations. Error: {} does not exist.'.format(step_impl_dir))
28-
logging.error('Make sure `STEP_IMPL_DIR` env var is set to a valid directory path.')
29-
return
30-
_import_impl(step_impl_dir)
26+
for impl_dir in step_impl_dirs:
27+
if not os.path.isdir(impl_dir):
28+
logging.error('Cannot import step implementations. Error: {} does not exist.'.format(step_impl_dirs))
29+
logging.error('Make sure `STEP_IMPL_DIR` env var is set to a valid directory path.')
30+
return
31+
_import_impl(impl_dir)
3132

3233

3334
def copy_skel_files():
3435
try:
3536
logging.info('Initialising Gauge Python project')
3637
logging.info('create {}'.format(env_dir))
3738
os.makedirs(env_dir)
38-
logging.info('create {}'.format(impl_dir))
39-
shutil.copytree(os.path.join(SKEL, STEP_IMPL_DIR_NAME), impl_dir)
39+
logging.info('create {}'.format(impl_dirs[0]))
40+
shutil.copytree(os.path.join(SKEL, STEP_IMPL_DIR_NAMES[0]), impl_dirs[0])
4041
logging.info('create {}'.format(os.path.join(env_dir, PYTHON_PROPERTIES)))
4142
shutil.copy(os.path.join(SKEL, PYTHON_PROPERTIES), env_dir)
4243
open(requirements_file, 'w').write('getgauge==' + _get_version())
@@ -51,7 +52,7 @@ def _import_impl(step_impl_dir):
5152
if f.endswith('.py'):
5253
_import_file(file_path)
5354
elif path.isdir(file_path):
54-
load_impls(file_path)
55+
load_impls([file_path])
5556

5657

5758
def _import_file(file_path):

getgauge/lsp_server.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
ImplementationFileGlobPatternResponse, StepNamesResponse, \
77
ImplementationFileListResponse
88
from getgauge.registry import registry
9-
from getgauge.util import get_impl_files, get_step_impl_dir
9+
from getgauge.util import get_impl_files, get_step_impl_dirs
1010

1111

1212
class LspServerHandler(lsp_pb2_grpc.lspServiceServicer):
@@ -60,7 +60,8 @@ def GetStepName(self, request, context):
6060

6161
def GetGlobPatterns(self, request, context):
6262
res = ImplementationFileGlobPatternResponse()
63-
res.globPatterns.extend(["{}/**/*.py".format(get_step_impl_dir())])
63+
globPatterns = [["{}/**/*.py".format(d)] for d in get_step_impl_dirs()]
64+
res.globPatterns.extend([item for sublist in globPatterns for item in sublist])
6465
return res
6566

6667
def KillProcess(self, request, context):

getgauge/processor.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from getgauge.refactor import refactor_step
1616
from getgauge.registry import registry, MessagesStore, ScreenshotsStore
1717
from getgauge.static_loader import reload_steps
18-
from getgauge.util import get_step_impl_dir, get_impl_files, read_file_contents, get_file_name
18+
from getgauge.util import get_step_impl_dirs, get_impl_files, read_file_contents, get_file_name
1919
from getgauge.validator import validate_step
2020

2121
ATTACH_DEBUGGER_EVENT = 'Runner Ready for Debugging'
@@ -82,7 +82,7 @@ def handle_detached():
8282
def _execute_before_suite_hook(request, response, _socket, clear=True):
8383
if clear:
8484
registry.clear()
85-
load_impls(get_step_impl_dir())
85+
load_impls(get_step_impl_dirs())
8686
if environ.get('DEBUGGING'):
8787
ptvsd.enable_attach(address=(
8888
'127.0.0.1', int(environ.get('DEBUG_PORT'))))
@@ -278,8 +278,8 @@ def stub_impl_response(codes, file_name, response):
278278

279279

280280
def _glob_pattern(_request, response, _socket):
281-
patterns = ["{}/**/*.py".format(get_step_impl_dir())]
282-
return response.implementationFileGlobPatternResponse.globPatterns.extend(patterns)
281+
patterns = [["{}/**/*.py".format(d)] for d in get_step_impl_dirs()]
282+
return response.implementationFileGlobPatternResponse.globPatterns.extend([item for sublist in patterns for item in sublist])
283283

284284

285285
processors = {Message.ExecutionStarting: _execute_before_suite_hook,

getgauge/static_loader.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ def reload_steps(file_path, content=None):
1616
load_steps(pf)
1717

1818

19-
def load_files(step_impl_dir):
20-
for dirpath, dirs, files in os.walk(step_impl_dir):
21-
py_files = (os.path.join(dirpath, f)
22-
for f in files if f.endswith('.py'))
23-
for file_path in py_files:
24-
pf = PythonFile.parse(file_path)
25-
if pf:
26-
load_steps(pf)
19+
def load_files(step_impl_dirs):
20+
for step_impl_dir in step_impl_dirs:
21+
for dirpath, _, files in os.walk(step_impl_dir):
22+
py_files = (os.path.join(dirpath, f) for f in files if f.endswith('.py'))
23+
for file_path in py_files:
24+
pf = PythonFile.parse(file_path)
25+
if pf:
26+
load_steps(pf)

getgauge/util.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
PROJECT_ROOT_ENV = 'GAUGE_PROJECT_ROOT'
44
STEP_IMPL_DIR_ENV = 'STEP_IMPL_DIR'
5-
STEP_IMPL_DIR_NAME = os.getenv(STEP_IMPL_DIR_ENV) or 'step_impl'
65

76

87
def get_project_root():
@@ -12,17 +11,19 @@ def get_project_root():
1211
return ""
1312

1413

15-
def get_step_impl_dir():
16-
return os.path.join(get_project_root(), STEP_IMPL_DIR_NAME)
14+
def get_step_impl_dirs():
15+
STEP_IMPL_DIR_NAMES = map(str.strip, os.getenv(STEP_IMPL_DIR_ENV).split(',')) if os.getenv(STEP_IMPL_DIR_ENV) else ['step_impl']
16+
return [os.path.join(get_project_root(), name) for name in STEP_IMPL_DIR_NAMES]
1717

1818

1919
def get_impl_files():
20-
step_impl_dir = get_step_impl_dir()
20+
step_impl_dirs = get_step_impl_dirs()
2121
file_list = []
22-
for root, _, files in os.walk(step_impl_dir):
23-
for file in files:
24-
if file.endswith('.py') and '__init__.py' != os.path.basename(file):
25-
file_list.append(os.path.join(root, file))
22+
for step_impl_dir in step_impl_dirs:
23+
for root, _, files in os.walk(step_impl_dir):
24+
for file in files:
25+
if file.endswith('.py') and '__init__.py' != os.path.basename(file):
26+
file_list.append(os.path.join(root, file))
2627
return file_list
2728

2829

@@ -37,7 +38,7 @@ def read_file_contents(file_name):
3738

3839
def get_file_name(prefix='', counter=0):
3940
name = 'step_implementation{}.py'.format(prefix)
40-
file_name = os.path.join(get_step_impl_dir(), name)
41+
file_name = os.path.join(get_step_impl_dirs()[0], name)
4142
if not os.path.exists(file_name):
4243
return file_name
4344
else:

start.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from getgauge.impl_loader import copy_skel_files
1212
from getgauge.messages import lsp_pb2_grpc
1313
from getgauge.static_loader import load_files
14-
from getgauge.util import get_step_impl_dir
14+
from getgauge.util import get_step_impl_dirs
1515

1616
PLUGIN_JSON = 'python.json'
1717
VERSION = 'version'
@@ -28,12 +28,12 @@ def main():
2828

2929

3030
def load_implementations():
31-
d = get_step_impl_dir()
32-
if path.exists(d):
33-
load_files(d)
34-
else:
35-
logging.error(
36-
'can not load implementations from {}. {} does not exist.'.format(d, d))
31+
d = get_step_impl_dirs()
32+
for impl_dir in d:
33+
if not path.exists(impl_dir):
34+
logging.error('can not load implementations from {}. {} does not exist.'.format(impl_dir, impl_dir))
35+
load_files(d)
36+
3737

3838

3939
def start():

tests/test_lsp_server.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from getgauge.messages.messages_pb2 import *
1010
from getgauge.messages.spec_pb2 import ProtoStepValue
1111
from getgauge.registry import registry
12-
from getgauge.util import get_step_impl_dir
12+
from getgauge.util import get_step_impl_dirs
1313
from getgauge.parser import PythonFile
1414

1515

@@ -35,7 +35,7 @@ def test_LspServerHandler_glob_pattern(self):
3535
def test_LspServerHandler_file_list(self):
3636
handler = LspServerHandler(None)
3737
req = ImplementationFileListRequest()
38-
self.fs.create_file(os.path.join(get_step_impl_dir(), 'foo.py'))
38+
self.fs.create_file(os.path.join(get_step_impl_dirs()[0], 'foo.py'))
3939

4040
res = handler.GetImplementationFiles(req, None)
4141

@@ -118,8 +118,8 @@ def foo(vowels):
118118
print(vowels)
119119
''')
120120
self.fs.create_file(os.path.join(
121-
get_step_impl_dir(), 'foo.py'), contents=content)
122-
loader.load_files(get_step_impl_dir())
121+
get_step_impl_dirs()[0], 'foo.py'), contents=content)
122+
loader.load_files(get_step_impl_dirs())
123123

124124
request = RefactorRequest()
125125
request.saveChanges = False

tests/test_utils.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from unittest import main, TestCase
2+
from getgauge.util import get_step_impl_dirs
3+
import os
4+
5+
6+
class UtilTests(TestCase):
7+
8+
def test_get_step_impl_gives_default_if_no_env_Set(self):
9+
dirs = get_step_impl_dirs()
10+
expected = ['step_impl']
11+
self.assertEquals(dirs,expected)
12+
13+
def test_get_step_impl_returns_array_of_impl_dirs(self):
14+
os.environ["STEP_IMPL_DIR"] = "step_impl, step_impl1"
15+
dirs = get_step_impl_dirs()
16+
expected = ['step_impl','step_impl1']
17+
self.assertEquals(dirs,expected)
18+
19+
if __name__ == '__main__':
20+
main()

tests/test_validate.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,6 @@ def test_is_valid(self):
1616

1717
def test_format_params(self):
1818
self.assertEqual("a, b, arg3", _format_params(["a", "b", "2"]))
19+
20+
if __name__ == '__main__':
21+
unittest.main()

0 commit comments

Comments
 (0)