-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support setting the mapping fo build source path between container an…
…d host mechine * Set the path mapping with global config *.yml file * If mapping not set on global config file, try to read mapping form environment variable.
- Loading branch information
1 parent
43e2f77
commit 1951da7
Showing
6 changed files
with
164 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import json | ||
import logging | ||
import re | ||
from os import environ | ||
from pathlib import PurePosixPath | ||
|
||
logger = logging.getLogger(__name__) | ||
json_re = re.compile(r'^(?:["[{]|(?:-?[1-9]\d*(?:\.\d+)?|null|true|false)$)') | ||
|
||
|
||
def get_host_path(original, mapping): | ||
ret = original | ||
orig_path = PurePosixPath(original) | ||
for k, v in mapping.items(): | ||
try: | ||
logger.debug("Mapping:%s:%s", k, v) | ||
relative_path = orig_path.relative_to(k) | ||
ret = PurePosixPath(v).joinpath(relative_path) | ||
return str(ret) | ||
except ValueError: | ||
logger.warning("Error when composing new path!") | ||
pass | ||
return str(ret) | ||
|
||
|
||
def nest_dict(flat_dict, sep): | ||
ret = {} | ||
for key, value in flat_dict.items(): | ||
key_list = key.split(sep, 1) | ||
if len(key_list) == 2: | ||
root = key_list[0] | ||
if root not in ret: | ||
ret[root] = {} | ||
ret[root][key_list[1]] = value | ||
else: | ||
ret[key] = value | ||
return ret | ||
|
||
|
||
def load_from_env(env_prefix=None, sep=None, decode_json=True): | ||
if decode_json: | ||
decode = lambda s: json.loads(s) if json_re.match(s) is not None else s | ||
else: | ||
decode = lambda s: s | ||
env = {key[len(env_prefix):].lower(): decode(value) for key, value in environ.items() if key.startswith(env_prefix)} | ||
if sep is not None: | ||
env = nest_dict(env, sep) | ||
return env |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import os | ||
import unittest | ||
from json import loads | ||
|
||
from apluslms_roman.utils.path_mapping import json_re, load_from_env | ||
|
||
test_case_loadable = ( | ||
'true', | ||
'false', | ||
'null', | ||
'123', | ||
'-123', | ||
'3.14', | ||
'-3.14', | ||
'{"foo": "bar"}', | ||
'[1, 2, 3]', | ||
'"foo bar"' | ||
) | ||
|
||
test_case_not_loadable = ( | ||
"/foobar.py", | ||
"text", | ||
"yes", | ||
"0123123", | ||
) | ||
|
||
|
||
class TestJsonLoadable(unittest.TestCase): | ||
|
||
def test_loadable_not_raise(self): | ||
for case in test_case_loadable: | ||
with self.subTest(non_json=case): | ||
loads(case) | ||
|
||
def test_not_loadable_raise(self): | ||
for case in test_case_not_loadable: | ||
with self.subTest(non_json=case): | ||
with self.assertRaises(ValueError, msg="Testing:{}".format(case)): | ||
loads(case) | ||
|
||
|
||
class TestJsonRegex(unittest.TestCase): | ||
|
||
def test_loadable_match(self): | ||
for case in test_case_loadable: | ||
with self.subTest(non_json=case): | ||
self.assertTrue(json_re.match(case)is not None, msg="Testing:{}".format(case)) | ||
|
||
def test_not_loadable_not_match(self): | ||
for case in test_case_not_loadable: | ||
with self.subTest(non_json=case): | ||
self.assertFalse(json_re.match(case) is not None, msg="Testing:{}".format(case)) | ||
|
||
|
||
class TestLoadFromEnv(unittest.TestCase): | ||
|
||
def test_with_decode_json(self): | ||
os.environ['DOCKER_FOO_BAR'] = '123' | ||
self.assertEqual({'foo': {'bar': '123'}}, load_from_env('DOCKER_', '_', False)) | ||
|
||
def test_without_decode_json(self): | ||
os.environ['DOCKER_FOO_BAR'] = '123' | ||
self.assertEqual({'foo': {'bar': 123}}, load_from_env('DOCKER_', '_', True)) | ||
|
||
def test_without_separation_char(self): | ||
os.environ['DOCKER_FOO_BAR'] = '123' | ||
self.assertEqual({'foo_bar': 123}, load_from_env('DOCKER_')) |