Merged PR 4493: CppToJson Schema Deserialization Code

Most of this code is boilerplate code that creates an environment that can be used to generate code that deserializes the output of CppToJson.py.

The important files are:
- CppyToJson.SimpleSchema
- GeneratedCode/CppToJson_PythonJsonSerialization.py
- SchemaBuildEnvironment/Build.py
- SchemaBuildEnvironment/Readme.rst
This commit is contained in:
David Brownell 2019-06-05 17:05:51 +00:00
Родитель 31ca95c271
Коммит 909f1dfa75
18 изменённых файлов: 1733 добавлений и 2 удалений

6
.gitignore поставляемый
Просмотреть файл

@ -2,7 +2,7 @@ __pycache__
*.pyc
*.pyo
Generated/*
**/Generated/*
Activate.cmd
Activate.*.cmd
@ -14,4 +14,6 @@ Activate.*.sh
.coverage
coverage.xml
.vscode/*
**/.vscode/*
Libraries/Python/DataPipelines/v1\.0/DataPipelines/GeneratedCode/Compiler\.ConditionalInvocationQueryMixin\.data

Просмотреть файл

@ -0,0 +1,9 @@
<Functions *>:
<func_name string>
<raw_return_type string>
<simple_return_type string>
<var_names string *>
<raw_var_types string *>
<simple_var_types string *>

Просмотреть файл

@ -0,0 +1,560 @@
# --------------------------------------------------------------------------------
# |
# | WARNING:
# | This file was generated; any local changes will be overwritten during
# | future invocations of the generator!
# |
# | Generated by: <SimpleSchemaGenerator>/Plugins/Impl/PythonSerializationImpl.py
# | Generated on: 2019-06-05 09:55:01.478584
# |
# --------------------------------------------------------------------------------
import copy
import sys
from collections import OrderedDict
import six
import CommonEnvironment
from CommonEnvironment.TypeInfo import Arity
from CommonEnvironment.TypeInfo.AnyOfTypeInfo import AnyOfTypeInfo
from CommonEnvironment.TypeInfo.ClassTypeInfo import ClassTypeInfo
from CommonEnvironment.TypeInfo.DictTypeInfo import DictTypeInfo
from CommonEnvironment.TypeInfo.GenericTypeInfo import GenericTypeInfo
from CommonEnvironment.TypeInfo.ListTypeInfo import ListTypeInfo
from CommonEnvironment.TypeInfo.FundamentalTypes.Serialization.PythonCodeVisitor import PythonCodeVisitor
# <Unused import> pylint: disable = W0611
# <Unused import> pylint: disable = W0614
from CommonEnvironment.TypeInfo.FundamentalTypes.All import * # <Wildcard import> pylint: disable = W0401
# <Standard import should be placed before...> pylint: disable = C0411
# ----------------------------------------------------------------------
import json
from CommonEnvironment import FileSystem
from CommonEnvironment.TypeInfo.FundamentalTypes.Serialization.JsonSerialization import JsonSerialization
# ----------------------------------------------------------------------
class JsonEncoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, Object):
d = copy.deepcopy(o.__dict__)
for k in list(six.iterkeys(d)):
if k.startswith("_"):
del d[k]
return d
return getattr(o, "__dict__", o)
# ----------------------------------------------------------------------
# <Method name "..." doesn't conform to PascalCase naming style> pylint: disable = C0103
# <Line too long> pylint: disable = C0301
# <Too many lines in module> pylint: disable = C0302
# <Wrong hanging indentation> pylint: disable = C0330
# <Too few public methods> pylint: disable = R0903
# <Too many public methods> pylint: disable = R0904
# <Too many branches> pylint: disable = R0912
# <Too many statements> pylint: disable = R0915
# ----------------------------------------------------------------------
class SerializationException(Exception):
def __init__(self, ex_or_string):
if isinstance(ex_or_string, six.string_types):
super(SerializationException, self).__init__(ex_or_string)
else:
super(SerializationException, self).__init__(str(ex_or_string))
self.__dict__ = copy.deepcopy(ex_or_string.__dict__)
class UniqueKeySerializationException(SerializationException): pass
class SerializeException(SerializationException): pass
class DeserializeException(SerializationException): pass
class DoesNotExist(object): pass
# ----------------------------------------------------------------------
# |
# | Utility Methods
# |
# ----------------------------------------------------------------------
def Deserialize(
root,
process_additional_data=False,
always_include_optional=False,
):
return Deserialize_Functions(
root,
is_root=False,
process_additional_data=process_additional_data,
always_include_optional=always_include_optional,
)
# ----------------------------------------------------------------------
def Deserialize_Functions(
items,
process_additional_data=False,
always_include_optional=False,
is_root=False,
):
"""Deserializes 'Functions' from a JSON object to a python object"""
if isinstance(items, six.string_types):
if FileSystem.IsFilename(items):
with open(items) as f:
items = json.load(f)
else:
items = json.loads(items)
if not isinstance(items, list):
if isinstance(items, dict) and "Functions" in items:
items = items["Functions"]
elif not isinstance(items, dict) and hasattr(items, "Functions"):
items = getattr(items, "Functions")
elif is_root:
items = DoesNotExist
try:
try:
items = Deserializer().Functions(
items,
process_additional_data=process_additional_data,
always_include_optional=always_include_optional,
)
if items is DoesNotExist:
items = []
except:
_DecorateActiveException("Functions")
except SerializationException:
raise
except Exception as ex:
raise DeserializeException(ex)
return items
# ----------------------------------------------------------------------
# |
# | Type Infos
# |
# ----------------------------------------------------------------------
Functions_TypeInfo = ClassTypeInfo(OrderedDict([ ( "func_name", StringTypeInfo(min_length=1) ), ( "raw_return_type", StringTypeInfo(min_length=1) ), ( "simple_return_type", StringTypeInfo(min_length=1) ), ( "var_names", StringTypeInfo(min_length=1, arity=Arity.FromString('*')) ), ( "raw_var_types", StringTypeInfo(min_length=1, arity=Arity.FromString('*')) ), ( "simple_var_types", StringTypeInfo(min_length=1, arity=Arity.FromString('*')) ) ]), require_exact_match=True, arity=Arity.FromString('*'))
_Functions_TypeInfo_Contents = OrderedDict([("func_name", GenericTypeInfo()), ("raw_return_type", GenericTypeInfo()), ("simple_return_type", GenericTypeInfo()), ("var_names", GenericTypeInfo(arity=Arity.FromString('*'))), ("raw_var_types", GenericTypeInfo(arity=Arity.FromString('*'))), ("simple_var_types", GenericTypeInfo(arity=Arity.FromString('*')))])
_Functions_TypeInfo = AnyOfTypeInfo([ClassTypeInfo(_Functions_TypeInfo_Contents, require_exact_match=False), DictTypeInfo(_Functions_TypeInfo_Contents, require_exact_match=False)], arity=Arity.FromString('*'))
_Functions_func_name_TypeInfo = StringTypeInfo(min_length=1)
_Functions_raw_return_type_TypeInfo = StringTypeInfo(min_length=1)
_Functions_simple_return_type_TypeInfo = StringTypeInfo(min_length=1)
_Functions_var_names_TypeInfo = StringTypeInfo(min_length=1, arity=Arity.FromString('*'))
_Functions_raw_var_types_TypeInfo = StringTypeInfo(min_length=1, arity=Arity.FromString('*'))
_Functions_simple_var_types_TypeInfo = StringTypeInfo(min_length=1, arity=Arity.FromString('*'))
# ----------------------------------------------------------------------
# |
# | Deserializer
# |
# ----------------------------------------------------------------------
class Deserializer(object):
# ----------------------------------------------------------------------
@classmethod
def Functions(cls, items, always_include_optional, process_additional_data):
if items in [DoesNotExist, None, []]:
_Functions_TypeInfo.ValidateArity(None)
return DoesNotExist
results = []
for this_index, this_item in enumerate(items or []):
try:
results.append(cls._Functions_Item(this_item, always_include_optional, process_additional_data))
except:
_DecorateActiveException("Index {}".format(this_index))
_Functions_TypeInfo.ValidateArity(results)
return results
# ----------------------------------------------------------------------
@classmethod
def Functions_func_name(cls, item):
if item in [DoesNotExist, None]:
_Functions_func_name_TypeInfo.ValidateArity(None)
return DoesNotExist
result = cls._Functions_func_name_Item(item)
_Functions_func_name_TypeInfo.ValidateArity(result)
return result
# ----------------------------------------------------------------------
@classmethod
def Functions_raw_return_type(cls, item):
if item in [DoesNotExist, None]:
_Functions_raw_return_type_TypeInfo.ValidateArity(None)
return DoesNotExist
result = cls._Functions_raw_return_type_Item(item)
_Functions_raw_return_type_TypeInfo.ValidateArity(result)
return result
# ----------------------------------------------------------------------
@classmethod
def Functions_simple_return_type(cls, item):
if item in [DoesNotExist, None]:
_Functions_simple_return_type_TypeInfo.ValidateArity(None)
return DoesNotExist
result = cls._Functions_simple_return_type_Item(item)
_Functions_simple_return_type_TypeInfo.ValidateArity(result)
return result
# ----------------------------------------------------------------------
@classmethod
def Functions_var_names(cls, items):
if items in [DoesNotExist, None, []]:
_Functions_var_names_TypeInfo.ValidateArity(None)
return DoesNotExist
results = []
for this_index, this_item in enumerate(items or []):
try:
results.append(cls._Functions_var_names_Item(this_item))
except:
_DecorateActiveException("Index {}".format(this_index))
_Functions_var_names_TypeInfo.ValidateArity(results)
return results
# ----------------------------------------------------------------------
@classmethod
def Functions_raw_var_types(cls, items):
if items in [DoesNotExist, None, []]:
_Functions_raw_var_types_TypeInfo.ValidateArity(None)
return DoesNotExist
results = []
for this_index, this_item in enumerate(items or []):
try:
results.append(cls._Functions_raw_var_types_Item(this_item))
except:
_DecorateActiveException("Index {}".format(this_index))
_Functions_raw_var_types_TypeInfo.ValidateArity(results)
return results
# ----------------------------------------------------------------------
@classmethod
def Functions_simple_var_types(cls, items):
if items in [DoesNotExist, None, []]:
_Functions_simple_var_types_TypeInfo.ValidateArity(None)
return DoesNotExist
results = []
for this_index, this_item in enumerate(items or []):
try:
results.append(cls._Functions_simple_var_types_Item(this_item))
except:
_DecorateActiveException("Index {}".format(this_index))
_Functions_simple_var_types_TypeInfo.ValidateArity(results)
return results
# ----------------------------------------------------------------------
# ----------------------------------------------------------------------
# ----------------------------------------------------------------------
@classmethod
def _Functions_Item(cls, item, always_include_optional, process_additional_data):
result = _CreatePythonObject(
attributes=None,
)
# func_name
try:
setattr(result, "func_name", cls.Functions_func_name(
cls._GetPythonAttribute(
item,
"func_name",
is_optional=False,
),
)
)
except:
_DecorateActiveException("func_name")
# raw_return_type
try:
setattr(result, "raw_return_type", cls.Functions_raw_return_type(
cls._GetPythonAttribute(
item,
"raw_return_type",
is_optional=False,
),
)
)
except:
_DecorateActiveException("raw_return_type")
# simple_return_type
try:
setattr(result, "simple_return_type", cls.Functions_simple_return_type(
cls._GetPythonAttribute(
item,
"simple_return_type",
is_optional=False,
),
)
)
except:
_DecorateActiveException("simple_return_type")
# var_names
try:
cls._ApplyOptionalChildren(item, "var_names", result, cls.Functions_var_names, always_include_optional)
except:
_DecorateActiveException("var_names")
# raw_var_types
try:
cls._ApplyOptionalChildren(item, "raw_var_types", result, cls.Functions_raw_var_types, always_include_optional)
except:
_DecorateActiveException("raw_var_types")
# simple_var_types
try:
cls._ApplyOptionalChildren(item, "simple_var_types", result, cls.Functions_simple_var_types, always_include_optional)
except:
_DecorateActiveException("simple_var_types")
# Additional data
if process_additional_data:
cls._ApplyAdditionalData(
item,
result,
exclude_names={"func_name", "raw_return_type", "simple_return_type", "var_names", "raw_var_types", "simple_var_types"},
)
_Functions_TypeInfo.ValidateItem(
result,
recurse=False,
require_exact_match=not process_additional_data,
)
return result
# ----------------------------------------------------------------------
@classmethod
def _Functions_func_name_Item(cls, item):
return JsonSerialization.DeserializeItem(_Functions_func_name_TypeInfo, item, **{})
# ----------------------------------------------------------------------
@classmethod
def _Functions_raw_return_type_Item(cls, item):
return JsonSerialization.DeserializeItem(_Functions_raw_return_type_TypeInfo, item, **{})
# ----------------------------------------------------------------------
@classmethod
def _Functions_simple_return_type_Item(cls, item):
return JsonSerialization.DeserializeItem(_Functions_simple_return_type_TypeInfo, item, **{})
# ----------------------------------------------------------------------
@classmethod
def _Functions_var_names_Item(cls, item):
return JsonSerialization.DeserializeItem(_Functions_var_names_TypeInfo, item, **{})
# ----------------------------------------------------------------------
@classmethod
def _Functions_raw_var_types_Item(cls, item):
return JsonSerialization.DeserializeItem(_Functions_raw_var_types_TypeInfo, item, **{})
# ----------------------------------------------------------------------
@classmethod
def _Functions_simple_var_types_Item(cls, item):
return JsonSerialization.DeserializeItem(_Functions_simple_var_types_TypeInfo, item, **{})
# ----------------------------------------------------------------------
# ----------------------------------------------------------------------
# ----------------------------------------------------------------------
@classmethod
def _ApplyOptionalChildren(cls, items, attribute_name, dest, apply_func, always_include_optional):
value = cls._GetPythonAttribute(
items,
attribute_name,
is_optional=True,
)
if value is not DoesNotExist:
value = apply_func(value)
if value is not DoesNotExist:
setattr(dest, attribute_name, value)
return
if always_include_optional:
setattr(dest, attribute_name, [])
# ----------------------------------------------------------------------
@classmethod
def _ApplyAdditionalData(
cls,
source,
dest,
exclude_names,
):
for name, child in [(k, v) for k, v in six.iteritems(source if isinstance(source, dict) else source.__dict__) if not k.startswith("_") and k not in exclude_names]:
try:
if isinstance(child, list):
children = []
for index, item in enumerate(child):
item_name = "Index {}".format(index)
try:
children.append(cls._CreateAdditionalDataItem(item_name, item))
except:
_DecorateActiveException(item_name)
setattr(dest, name, children)
else:
setattr(dest, name, cls._CreateAdditionalDataItem(name, child))
except:
_DecorateActiveException(name)
# ----------------------------------------------------------------------
@classmethod
def _CreateAdditionalDataItem(cls, name, source):
# The following types should be returned directly without additional conversion
if isinstance(source, (int, float, str, bool)):
return source
assert not isinstance(source, list), source
if not isinstance(source, dict):
source = source.__dict__
source_attribute_names = source.get("_attribute_names", set())
attributes = OrderedDict()
items = OrderedDict()
for k, v in six.iteritems(source):
if k.startswith("_"):
continue
if k in source_attribute_names:
attributes[k] = v
else:
items[k] = v
if len(items) == 1 and next(six.iterkeys(items)) == source.get("_text_attribute_name", None):
return _CreatePythonObject(
attributes=attributes,
**{"simple_value": source[source["_text_attribute_name"]], "_text_attribute_name": "simple_value"},
)
result = _CreatePythonObject(
attributes=attributes,
)
for k, v in six.iteritems(items):
try:
if isinstance(v, list):
new_items = []
for index, child in enumerate(v):
try:
new_items.append(cls._CreateAdditionalDataItem("item", child))
except:
_DecorateActiveException("Index {}".format(index))
setattr(result, k, new_items)
else:
new_item = cls._CreateAdditionalDataItem(k, v)
setattr(result, k, new_item)
except:
_DecorateActiveException(k)
return result
# ----------------------------------------------------------------------
@staticmethod
def _GetPythonAttribute(
item,
attribute_name,
is_optional=False,
):
if not isinstance(item, dict):
item = item.__dict__
value = item.get(attribute_name, DoesNotExist)
if value is DoesNotExist and not is_optional:
raise SerializeException("No items were found")
return value
# ----------------------------------------------------------------------
class Object(object):
def __init__(self):
self._attribute_names = set()
def __repr__(self):
return CommonEnvironment.ObjectReprImpl(self)
# ----------------------------------------------------------------------
def _CreatePythonObject(
attributes=None,
**kwargs
):
attributes = attributes or {}
result = Object()
for d in [attributes, kwargs]:
for k, v in six.iteritems(d):
setattr(result, k, v)
for k in six.iterkeys(attributes):
result._attribute_names.add(k)
return result
# ----------------------------------------------------------------------
# ----------------------------------------------------------------------
# ----------------------------------------------------------------------
def _DecorateActiveException(frame_desc):
exception = sys.exc_info()[1]
if not hasattr(exception, "stack"):
setattr(exception, "stack", [])
exception.stack.insert(0, frame_desc)
# <The raise statement is not inside an except clause> pylint: disable = E0704
raise

Просмотреть файл

@ -0,0 +1 @@
The python code in this directory was generated by ../SchemaBuildEnvironment/Build.py.

Просмотреть файл

@ -0,0 +1,334 @@
# ----------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License
# ----------------------------------------------------------------------
"""Unit tests for CppToJson_PythonJsonSerialization.py"""
import os
import sys
import unittest
import CommonEnvironment
from DataPipelines.GeneratedCode.CppToJson_PythonJsonSerialization import *
# ----------------------------------------------------------------------
_script_fullpath = CommonEnvironment.ThisFullpath()
_script_dir, _script_name = os.path.split(_script_fullpath)
# ----------------------------------------------------------------------
# ----------------------------------------------------------------------
class TestSuite(unittest.TestCase):
# ----------------------------------------------------------------------
def test_Empty(self):
self.assertEqual(Deserialize([]), [])
# ----------------------------------------------------------------------
def test_NoArgs(self):
result = Deserialize(
[
{
"func_name": "Name",
"raw_return_type": "int1",
"simple_return_type": "int2",
},
],
)
self.assertEqual(len(result), 1)
self.assertEqual(result[0].func_name, "Name")
self.assertEqual(result[0].raw_return_type, "int1")
self.assertEqual(result[0].simple_return_type, "int2")
self.assertTrue(not hasattr(result[0], "var_names"))
self.assertTrue(not hasattr(result[0], "raw_var_types"))
self.assertTrue(not hasattr(result[0], "simple_var_types"))
# ----------------------------------------------------------------------
def test_WithArgs(self):
result = Deserialize(
[
{
"func_name": "Name",
"raw_return_type": "int1",
"simple_return_type": "int2",
"var_names": ["a", "b",],
"raw_var_types": ["c", "d",],
"simple_var_types": ["e", "f",],
},
],
)
self.assertEqual(len(result), 1)
self.assertEqual(result[0].func_name, "Name")
self.assertEqual(result[0].raw_return_type, "int1")
self.assertEqual(result[0].simple_return_type, "int2")
self.assertEqual(result[0].var_names, ["a", "b",])
self.assertEqual(result[0].raw_var_types, ["c", "d",])
self.assertEqual(result[0].simple_var_types, ["e", "f",])
# ----------------------------------------------------------------------
def test_Multiple(self):
result = Deserialize(
[
{
"func_name": "Name1",
"raw_return_type": "int1",
"simple_return_type": "int2",
},
{
"func_name": "Name2",
"raw_return_type": "int3",
"simple_return_type": "int4",
},
],
)
self.assertEqual(len(result), 2)
self.assertEqual(result[0].func_name, "Name1")
self.assertEqual(result[0].raw_return_type, "int1")
self.assertEqual(result[0].simple_return_type, "int2")
self.assertTrue(not hasattr(result[0], "var_names"))
self.assertTrue(not hasattr(result[0], "raw_var_types"))
self.assertTrue(not hasattr(result[0], "simple_var_types"))
self.assertEqual(result[1].func_name, "Name2")
self.assertEqual(result[1].raw_return_type, "int3")
self.assertEqual(result[1].simple_return_type, "int4")
self.assertTrue(not hasattr(result[1], "var_names"))
self.assertTrue(not hasattr(result[1], "raw_var_types"))
self.assertTrue(not hasattr(result[1], "simple_var_types"))
# ----------------------------------------------------------------------
def test_InvalidName(self):
self.assertRaisesRegex(
Exception,
"An item was expected",
lambda: Deserialize(
[
{
"func_name": None,
"raw_return_type": "int1",
"simple_return_type": "int2",
},
],
),
)
self.assertRaisesRegex(
Exception,
"'' is not a valid 'String' string - Value must have more than 1 character",
lambda: Deserialize(
[
{
"func_name": "",
"raw_return_type": "int1",
"simple_return_type": "int2",
},
],
),
)
# ----------------------------------------------------------------------
def test_InvalidRawReturnType(self):
self.assertRaisesRegex(
Exception,
"An item was expected",
lambda: Deserialize(
[
{
"func_name": "Name",
"raw_return_type": None,
"simple_return_type": "int2",
},
],
),
)
self.assertRaisesRegex(
Exception,
"'' is not a valid 'String' string - Value must have more than 1 character",
lambda: Deserialize(
[
{
"func_name": "Name",
"raw_return_type": "",
"simple_return_type": "int2",
},
],
),
)
# ----------------------------------------------------------------------
def test_InvalidSimpleReturnType(self):
self.assertRaisesRegex(
Exception,
"An item was expected",
lambda: Deserialize(
[
{
"func_name": "Name",
"raw_return_type": "int1",
"simple_return_type": None,
},
],
),
)
self.assertRaisesRegex(
Exception,
"'' is not a valid 'String' string - Value must have more than 1 character",
lambda: Deserialize(
[
{
"func_name": "Name",
"raw_return_type": "int1",
"simple_return_type": "",
},
],
),
)
# ----------------------------------------------------------------------
def test_InvalidVarName(self):
self.assertRaisesRegex(
Exception,
"expected string or bytes-like object", # TODO
lambda: Deserialize(
[
{
"func_name": "Name",
"raw_return_type": "int1",
"simple_return_type": "int2",
"var_names": [None, "b",],
"raw_var_types": ["c", "d",],
"simple_var_types": ["e", "f",],
},
],
),
)
self.assertRaisesRegex(
Exception,
"'' is not a valid 'String' string - Value must have more than 1 character",
lambda: Deserialize(
[
{
"func_name": "Name",
"raw_return_type": "int1",
"simple_return_type": "int2",
"var_names": ["", "b",],
"raw_var_types": ["c", "d",],
"simple_var_types": ["e", "f",],
},
],
),
)
# ----------------------------------------------------------------------
def test_InvalidRawVarType(self):
self.assertRaisesRegex(
Exception,
"expected string or bytes-like object", # TODO
lambda: Deserialize(
[
{
"func_name": "Name",
"raw_return_type": "int1",
"simple_return_type": "int2",
"var_names": ["a", "b",],
"raw_var_types": ["c", None,],
"simple_var_types": ["e", "f",],
},
],
),
)
self.assertRaisesRegex(
Exception,
"'' is not a valid 'String' string - Value must have more than 1 character",
lambda: Deserialize(
[
{
"func_name": "Name",
"raw_return_type": "int1",
"simple_return_type": "int2",
"var_names": ["a", "b",],
"raw_var_types": ["c", "",],
"simple_var_types": ["e", "f",],
},
],
),
)
# ----------------------------------------------------------------------
def test_InvalidSimpleVarType(self):
self.assertRaisesRegex(
Exception,
"expected string or bytes-like object", # TODO
lambda: Deserialize(
[
{
"func_name": "Name",
"raw_return_type": "int1",
"simple_return_type": "int2",
"var_names": ["a", "b",],
"raw_var_types": ["c", "d",],
"simple_var_types": ["e", None, "g",],
},
],
),
)
self.assertRaisesRegex(
Exception,
"'' is not a valid 'String' string - Value must have more than 1 character",
lambda: Deserialize(
[
{
"func_name": "Name",
"raw_return_type": "int1",
"simple_return_type": "int2",
"var_names": ["", "b",],
"raw_var_types": ["c", "d",],
"simple_var_types": ["e", "", "g",],
},
],
),
)
# ----------------------------------------------------------------------
def test_ProcessAdditionalData(self):
input = [
{
"func_name": "Name",
"raw_return_type": "int1",
"simple_return_type": "int2",
"another_value": {"hello": "world",},
"another_value2": "a string",
"optional_list": [1, 2, 3],
},
]
result = Deserialize(input)
self.assertEqual(len(result), 1)
self.assertTrue(not hasattr(result[0], "another_value"))
result = Deserialize(
input,
process_additional_data=True,
)
self.assertEqual(len(result), 1)
self.assertEqual(result[0].another_value.hello, "world")
self.assertEqual(result[0].another_value2, "a string")
self.assertEqual(result[0].optional_list, [1, 2, 3,])
# ----------------------------------------------------------------------
# ----------------------------------------------------------------------
# ----------------------------------------------------------------------
if __name__ == "__main__":
try:
sys.exit(unittest.main(verbosity=2))
except KeyboardInterrupt:
pass

Просмотреть файл

Просмотреть файл

@ -0,0 +1,98 @@
# ----------------------------------------------------------------------
# |
# | Activate_custom.py
# |
# | David Brownell <db@DavidBrownell.com>
# | 2018-05-07 08:59:57
# |
# ----------------------------------------------------------------------
# |
# | Copyright David Brownell 2018-19.
# | Distributed under the Boost Software License, Version 1.0.
# | (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# |
# ----------------------------------------------------------------------
"""Performs repository-specific activation activities."""
import os
import sys
sys.path.insert(0, os.getenv("DEVELOPMENT_ENVIRONMENT_FUNDAMENTAL"))
from RepositoryBootstrap.SetupAndActivate import CommonEnvironment, CurrentShell
del sys.path[0]
# ----------------------------------------------------------------------
_script_fullpath = CommonEnvironment.ThisFullpath()
_script_dir, _script_name = os.path.split(_script_fullpath)
# ----------------------------------------------------------------------
# <Class '<name>' has no '<attr>' member> pylint: disable = E1101
# <Unrearchable code> pylint: disable = W0101
# <Unused argument> pylint: disable = W0613
# ----------------------------------------------------------------------
def GetCustomActions(
output_stream,
configuration,
version_specs,
generated_dir,
debug,
verbose,
fast,
repositories,
is_mixin_repo,
):
"""
Returns an action or list of actions that should be invoked as part of the activation process.
Actions are generic command line statements defined in
<Common_Environment>/Libraries/Python/CommonEnvironment/v1.0/CommonEnvironment/Shell/Commands/__init__.py
that are converted into statements appropriate for the current scripting language (in most
cases, this is Bash on Linux systems and Batch or PowerShell on Windows systems.
"""
return []
# ----------------------------------------------------------------------
def GetCustomScriptExtractors():
"""
Returns information that can be used to enumerate, extract, and generate documentation
for scripts stored in the Scripts directory in this repository and all repositories
that depend upon it.
****************************************************
Note that it is very rare to have the need to implement
this method. In most cases, it is safe to delete it.
****************************************************
There concepts are used with custom script extractors:
- DirGenerator: Method to enumerate sub-directories when searching for scripts in a
repository's Scripts directory.
def Func(directory, version_sepcs) -> [ (subdir, should_recurse), ... ]
[ subdir, ... ]
(subdir, should_recurse)
subdir
- CreateCommands: Method that creates the shell commands to invoke a script.
def Func(script_filename) -> [ command, ...]
command
None # Indicates not supported
- CreateDocumentation: Method that extracts documentation from a script.
def Func(script_filename) -> documentation string
- ScriptNameDecorator: Returns a new name for the script.
def Func(script_filename) -> name string
See <Common_Environment>/Activate_custom.py for an example of how script extractors
are used to process Python and PowerShell scripts.
"""
return

Просмотреть файл

@ -0,0 +1,86 @@
# ----------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License
# ----------------------------------------------------------------------
"""Builds generated code"""
import os
import sys
import CommonEnvironment
from CommonEnvironment import BuildImpl
from CommonEnvironment import CommandLine
from CommonEnvironment import FileSystem
from CommonEnvironment import Process
from CommonEnvironment.Shell.All import CurrentShell
from CommonEnvironment.StreamDecorator import StreamDecorator
# ----------------------------------------------------------------------
_script_fullpath = CommonEnvironment.ThisFullpath()
_script_dir, _script_name = os.path.split(_script_fullpath)
# ----------------------------------------------------------------------
# ----------------------------------------------------------------------
@CommandLine.EntryPoint
@CommandLine.Constraints(
output_stream=None,
)
def Build(
force=False,
output_stream=sys.stdout,
verbose=False,
):
return Process.Execute(
'"{script}" Generate PythonJson CppToJson "{output_dir}" "/input={input}" /plugin_arg=no_serialization:true{force}{verbose}'.format(
script=CurrentShell.CreateScriptName("SimpleSchemaGenerator"),
output_dir=os.path.join(_script_dir, "..", "GeneratedCode"),
input=os.path.join(_script_dir, "..", "CppToJson.SimpleSchema"),
force=" /force" if force else "",
verbose=" /verbose" if verbose else "",
),
output_stream,
)
# ----------------------------------------------------------------------
@CommandLine.EntryPoint
@CommandLine.Constraints(
output_stream=None,
)
def Clean(
output_stream=sys.stdout,
):
output_dir = os.path.join(_script_dir, "..", "GeneratedCode")
if not os.path.isdir(output_dir):
output_stream.write("'{}' does not exist.\n".format(output_dir))
else:
filenames = [
"Compiler.ConditionalInvocationQueryMixin.data",
"CppToJson_PythonJsonSerialization.py",
]
output_stream.write("Removing content in '{}'...".format(output_dir))
with StreamDecorator(output_stream).DoneManager():
for filename in filenames:
filename = os.path.join(output_dir, filename)
FileSystem.RemoveFile(filename)
return 0
# ----------------------------------------------------------------------
# ----------------------------------------------------------------------
# ----------------------------------------------------------------------
if __name__ == "__main__":
try:
sys.exit(
BuildImpl.Main(
BuildImpl.Configuration(
"SchemaCodeGenerator",
requires_output_dir=False,
),
),
)
except KeyboardInterrupt:
pass

Просмотреть файл

Просмотреть файл

@ -0,0 +1,5 @@
This is a environment suitable for building code in `../GeneratedCode`.
To get started, run:
`bootstrap.<cmd|sh> <Common Code Dir>`

Просмотреть файл

@ -0,0 +1,38 @@
@REM ----------------------------------------------------------------------
@REM |
@REM | Setup.cmd
@REM |
@REM | David Brownell <db@DavidBrownell.com>
@REM | 2018-04-20 11:21:37
@REM |
@REM ----------------------------------------------------------------------
@REM |
@REM | Copyright David Brownell 2018-19.
@REM | Distributed under the Boost Software License, Version 1.0.
@REM | (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@REM |
@REM ----------------------------------------------------------------------
@echo off
@REM ----------------------------------------------------------------------
@REM |
@REM | Run as:
@REM | Setup.cmd [/debug] [/verbose] [/configuration_EQ_<config_name>]*
@REM |
@REM ----------------------------------------------------------------------
if "%DEVELOPMENT_ENVIRONMENT_FUNDAMENTAL%"=="" (
echo.
echo ERROR: Please run Activate.cmd within a repository before running this script. It may be necessary to Setup and Activate the Common_Environment repository before setting up this one.
echo.
goto end
)
pushd "%~dp0"
call %DEVELOPMENT_ENVIRONMENT_FUNDAMENTAL%\RepositoryBootstrap\Impl\Setup.cmd %*
set _SETUP_ERROR=%ERRORLEVEL%
popd
if %_SETUP_ERROR% NEQ 0 (exit /B %_SETUP_ERROR%)
:end

Просмотреть файл

@ -0,0 +1,38 @@
#!/bin/bash
# ----------------------------------------------------------------------
# |
# | Setup.sh
# |
# | David Brownell <db@DavidBrownell.com>
# | 2018-05-09 10:37:21
# |
# ----------------------------------------------------------------------
# |
# | Copyright David Brownell 2018-19.
# | Distributed under the Boost Software License, Version 1.0.
# | (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# |
# ----------------------------------------------------------------------
set -e # Exit on error
set +v # Disable output
# ----------------------------------------------------------------------
# |
# | Run as:
# | ./Setup.sh [/debug] [/verbose] [/configuration=<config_name>]*
# |
# ----------------------------------------------------------------------
# Note that sudo is necessary because the process will create symbolic links
if [[ "${DEVELOPMENT_ENVIRONMENT_FUNDAMENTAL}" = "" ]]
then
echo
echo "ERROR: Please run Activate.sh within a repository before running this script. It may be necessary to Setup and Activate the Common_Environment repository before setting up this one."
echo
exit -1
fi
pushd "$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" > /dev/null
source $DEVELOPMENT_ENVIRONMENT_FUNDAMENTAL/RepositoryBootstrap/Impl/Setup.sh "$@"
popd > /dev/null

Просмотреть файл

@ -0,0 +1,121 @@
# ----------------------------------------------------------------------
# |
# | Setup_custom.py
# |
# | David Brownell <db@DavidBrownell.com>
# | 2018-05-03 22:12:13
# |
# ----------------------------------------------------------------------
# |
# | Copyright David Brownell 2018-19.
# | Distributed under the Boost Software License, Version 1.0.
# | (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# |
# ----------------------------------------------------------------------
"""Performs repository-specific setup activities."""
# ----------------------------------------------------------------------
# |
# | To setup an environment, run:
# |
# | Setup(.cmd|.ps1|.sh) [/debug] [/verbose] [/configuration=<config_name>]*
# |
# ----------------------------------------------------------------------
import os
import sys
from collections import OrderedDict
import CommonEnvironment
# ----------------------------------------------------------------------
_script_fullpath = CommonEnvironment.ThisFullpath()
_script_dir, _script_name = os.path.split(_script_fullpath)
# ----------------------------------------------------------------------
# <Missing function docstring> pylint: disable = C0111
# <Line too long> pylint: disable = C0301
# <Wrong hanging indentation> pylint: disable = C0330
# <Class '<name>' has no '<attr>' member> pylint: disable = E1103
# <Unreachable code> pylint: disable = W0101
# <Wildcard import> pylint: disable = W0401
# <Unused argument> pylint: disable = W0613
fundamental_repo = os.getenv("DEVELOPMENT_ENVIRONMENT_FUNDAMENTAL")
assert os.path.isdir(fundamental_repo), fundamental_repo
sys.path.insert(0, fundamental_repo)
from RepositoryBootstrap import * # <Unused import> pylint: disable = W0614
from RepositoryBootstrap.SetupAndActivate import CurrentShell # <Unused import> pylint: disable = W0614
from RepositoryBootstrap.SetupAndActivate.Configuration import * # <Unused import> pylint: disable = W0614
del sys.path[0]
# ----------------------------------------------------------------------
# There are two types of repositories: Standard and Mixin. Only one standard
# repository may be activated within an environment at a time while any number
# of mixin repositories can be activated within a standard repository environment.
# Standard repositories may be dependent on other repositories (thereby inheriting
# their functionality), support multiple configurations, and specify version
# information for tools and libraries in themselves or its dependencies.
#
# Mixin repositories are designed to augment other repositories. They cannot
# have configurations or dependencies and may not be activated on their own.
#
# These difference are summarized in this table:
#
# Standard Mixin
# -------- -----
# Can be activated in isolation X
# Supports configurations X
# Supports VersionSpecs X
# Can be dependent upon other repositories X
# Can be activated within any other Standard X
# repository
#
# Consider a script that wraps common Git commands. This functionality is useful
# across a number of different repositories, yet doesn't have functionality that
# is useful on its own; it provides functionality that augments other repositories.
# This functionality should be included within a repository that is classified
# as a mixin repository.
#
# To classify a repository as a Mixin repository, decorate the GetDependencies method
# with the MixinRepository decorator.
#
# @MixinRepository # <-- Uncomment this line to classify this repository as a mixin repository
def GetDependencies():
"""
Returns information about the dependencies required by this repository.
The return value should be an OrderedDict if the repository supports multiple configurations
(aka is configurable) or a single Configuration if not.
"""
return Configuration(
"Standard Configuration",
[
Dependency(
"5C7E1B3369B74BC098141FAD290288DA",
"Common_SimpleSchemaGenerator",
None,
"https://github.com/davidbrownell/Common_SimpleSchemaGenerator.git",
),
],
)
# ----------------------------------------------------------------------
def GetCustomActions(debug, verbose, explicit_configurations):
"""
Returns an action or list of actions that should be invoked as part of the setup process.
Actions are generic command line statements defined in
<Common_Environment>/Libraries/Python/CommonEnvironment/v1.0/CommonEnvironment/Shell/Commands/__init__.py
that are converted into statements appropriate for the current scripting language (in most
cases, this is Bash on Linux systems and Batch or PowerShell on Windows systems.
"""
return []

Просмотреть файл

@ -0,0 +1,8 @@
This file is used to uniquely identify this repository for the purposes of dependency management.
Other repositories that depend on this one will search for this file upon initial setup and
generate information that can be used when activating development environments.
**** PLEASE DO NOT MODIFY, REMOVE, OR RENAME THIS FILE, AS DOING SO WILL LIKELY BREAK OTHER REPOSITORIES! ****
Friendly Name: SchemaBuildEnvironment
Id: DE0092F9E4AF4A44B1FA219707C3AF42

Просмотреть файл

@ -0,0 +1,111 @@
@REM ----------------------------------------------------------------------
@REM |
@REM | bootstrap.cmd
@REM |
@REM | David Brownell <db@DavidBrownell.com>
@REM | 2019-05-21 08:07:40
@REM |
@REM ----------------------------------------------------------------------
@REM |
@REM | Copyright David Brownell 2019
@REM | Distributed under the Boost Software License, Version 1.0. See
@REM | accompanying file LICENSE_1_0.txt or copy at
@REM | http://www.boost.org/LICENSE_1_0.txt.
@REM |
@REM ----------------------------------------------------------------------
@echo off
IF "%~1"=="" (
echo.
echo This script bootstraps common library enlistment and setup.
echo.
echo Usage:
echo %0 ^<common code dir^>
echo.
exit /B -1
)
set _COMMON_CODE_DIR=%~1
shift /1
if "%DEVELOPMENT_ENVIRONMENT_REPOSITORY_ACTIVATED_FLAG%" NEQ "" (
echo.
echo ERROR: Please run this from a standard ^(non-activated^) command prompt.
echo.
exit /B -1
)
REM Bootstrap enlistment and setup of Common_Environment, and then invoke
REM bootstrap_impl.py once python is available.
IF NOT EXIST "%_COMMON_CODE_DIR%\Common\Environment" (
git clone https://github.com/davidbrownell/Common_Environment_v3.git "%_COMMON_CODE_DIR%\Common\Environment"
if %ERRORLEVEL% NEQ 0 exit /B %ERRORLEVEL%
)
REM Note that the following loop has been crafted to work around batch's crazy
REM expansion rules. Modify at your own risk!
set _BOOTSTRAP_NAME=
set _BOOTSTRAP_CLA=
:GetRemainingArgs_Begin
if "%~1"=="" goto :GetRemainingArgs_End
set _ARG=%~1
if "%_ARG:~,9%"=="/name_EQ_" goto :GetRemainingArgs_Name
if "%_ARG:~,9%"=="-name_EQ_" goto :GetRemainingArgs_Name
REM If here, we are looking at an arg that should be passed to the script
set _BOOTSTRAP_CLA=%_BOOTSTRAP_CLA% "%_ARG%"
goto :GetRemainingArgs_Continue
:GetRemainingArgs_Name
REM If here, we are looking at a name argument
set _BOOTSTRAP_NAME=%_ARG:~9%
goto :GetRemainingArgs_Continue
:GetRemainingArgs_Continue
shift /1
goto :GetRemainingArgs_Begin
:GetRemainingArgs_End
set _BOOTSTRAP_NAME_ARG=
if "%_BOOTSTRAP_NAME%" NEQ "" (
set _BOOTSTRAP_NAME_ARG=/name_EQ_%_BOOTSTRAP_NAME%
)
call "%_COMMON_CODE_DIR%\Common\Environment\Setup.cmd" %_BOOTSTRAP_NAME_ARG% %_BOOTSTRAP_CLA%
if %ERRORLEVEL% NEQ 0 exit /B %ERRORLEVEL%
REM Write the environment activation and python execution statements to a temporary
REM file so this environment remains unactivated (by doing this, the current script
REM can be invoked multiple times from the same environment).
set _ACTIVATE_CMD=Activate.cmd
if "%_BOOTSTRAP_NAME%" NEQ "" (
set _ACTIVATE_CMD=Activate.%_BOOTSTRAP_NAME%.cmd
)
(
echo @echo off
echo call "%_COMMON_CODE_DIR%\Common\Environment\%_ACTIVATE_CMD%" python36
echo python "%~dp0bootstrap_impl.py" "%_COMMON_CODE_DIR%" %_BOOTSTRAP_CLA%
) >bootstrap_tmp.cmd
cmd /C bootstrap_tmp.cmd
set _ERRORLEVEL=%ERRORLEVEL%
del bootstrap_tmp.cmd
set _ACTIVATE_CMD=
set _ARG=
set _BOOTSTRAP_CLA=
set _BOOTSTRAP_NAME=
set _BOOTSTRAP_NAME_ARG=
set _COMMON_CODE_DIR=
if %_ERRORLEVEL% NEQ 0 exit /B %_ERRORLEVEL%

Просмотреть файл

@ -0,0 +1,103 @@
#!/bin/bash
# ----------------------------------------------------------------------
# |
# | bootstrap.sh
# |
# | David Brownell <db@DavidBrownell.com>
# | 2019-05-21 11:27:06
# |
# ----------------------------------------------------------------------
# |
# | Copyright David Brownell 2019
# | Distributed under the Boost Software License, Version 1.0. See
# | accompanying file LICENSE_1_0.txt or copy at
# | http://www.boost.org/LICENSE_1_0.txt.
# |
# ----------------------------------------------------------------------
set -e # Exit on error
set +v # Disable output
should_continue=1
if [[ ${should_continue} == 1 && "$1" == "" ]]
then
echo ""
echo "This script bootstraps common library enlistment and setup."
echo ""
echo " Usage:"
echo " $0 <common code dir>"
echo ""
should_continue=0
fi
if [[ ${should_continue} == 1 && ${DEVELOPMENT_ENVIRONMENT_REPOSITORY_ACTIVATED_FLAG} ]]
then
echo ""
echo "ERROR: Please run this from a standard (non-activated) command prompt."
echo ""
should_continue=0
fi
if [[ ${should_continue} == 1 ]]
then
# Bootstrap enlistment and setup of Common_Environment, and then invoke
# bootstrap_impl.py once python is available.
if [[ ! -e "$1/Common/Environment" ]]
then
git clone https://github.com/davidbrownell/Common_Environment_v3.git "$1/Common/Environment"
fi
name=""
ARGS=()
for var in "${@:2}"
do
if [[ $var == /name=* ]] || [[ $var == -name=* ]]
then
name=`echo $var | cut -d'=' -f 2`
else
ARGS+=("$var")
fi
done
if [[ ! -z "${name}" ]]
then
name_arg="/name=${name}"
else
name_arg=""
fi
"$1/Common/Environment/Setup.sh" ${name_arg} ${ARGS[@]}
# Write the environment activation and python execution statements to a temporary
# file so this environment remains unactivated (by doing this, the current script
# can be invoked multiple times from the same environment).
if [[ ! -z "${name}" ]]
then
activate_cmd="Activate.${name}.sh"
else
activate_cmd="Activate.sh"
fi
this_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cat >bootstrap_tmp.sh <<EOL
#!/bin/bash
. "$1/Common/Environment/${activate_cmd}" python36
python "${this_dir}/bootstrap_impl.py" "$1" ${ARGS[@]}
EOL
chmod +x bootstrap_tmp.sh
./bootstrap_tmp.sh
error_code=${error_code}
rm bootstrap_tmp.sh
if [[ ${error_code} -ne 0 ]]
then
should_continue=0
fi
fi

Просмотреть файл

@ -0,0 +1,217 @@
# ----------------------------------------------------------------------
# |
# | bootstrap_impl.py
# |
# | David Brownell <db@DavidBrownell.com>
# | 2019-05-21 08:23:15
# |
# ----------------------------------------------------------------------
# |
# | Copyright David Brownell 2019
# | Distributed under the Boost Software License, Version 1.0. See
# | accompanying file LICENSE_1_0.txt or copy at
# | http://www.boost.org/LICENSE_1_0.txt.
# |
# ----------------------------------------------------------------------
"""Performs repository bootstrap activities (Enlistment and setup)"""
import os
import shutil
import sys
import textwrap
from collections import OrderedDict
import inflect as inflect_mod
import six
import CommonEnvironment
from CommonEnvironment.CallOnExit import CallOnExit
from CommonEnvironment import CommandLine
from CommonEnvironment import FileSystem
from CommonEnvironment import Process
from CommonEnvironment.Shell.All import CurrentShell
from CommonEnvironment.StreamDecorator import StreamDecorator
from CommonEnvironment import StringHelpers
# ----------------------------------------------------------------------
_script_fullpath = CommonEnvironment.ThisFullpath()
_script_dir, _script_name = os.path.split(_script_fullpath)
# ----------------------------------------------------------------------
# Tuples in the form:
# ("<repo name>", "<clone command line>", "<setup command suffix>" or None)
_REPO_DATA = [
("Common_EnvironmentEx", 'git clone https://github.com/davidbrownell/Common_EnvironmentEx "{output_dir}"', None),
("Common_SimpleSchemaGenerator", 'git clone https://github.com/davidbrownell/Common_SimpleSchemaGenerator "{output_dir}"', None),
]
_ACTIVATION_REPO_CONFIGURATION = None
# ----------------------------------------------------------------------
inflect = inflect_mod.engine()
# ----------------------------------------------------------------------
@CommandLine.EntryPoint
@CommandLine.Constraints(
output_dir=CommandLine.DirectoryTypeInfo(),
output_stream=None,
)
def EntryPoint(
output_dir,
verbose=False,
output_stream=sys.stdout,
):
with StreamDecorator(output_stream).DoneManager(
line_prefix="",
prefix="\nResults: ",
suffix="\n",
) as dm:
repo_data = OrderedDict()
enlistment_repositories = []
dm.stream.write("Calculating enlistment repositories...")
with dm.stream.DoneManager(
done_suffix=lambda: "{} found for enlistment".format(inflect.no("repository", len(enlistment_repositories))),
suffix="\n",
) as this_dm:
for data in _REPO_DATA:
repo_name = data[0]
repo_output_dir = os.path.join(output_dir, repo_name.replace("_", os.path.sep))
if not os.path.isdir(repo_output_dir):
enlistment_repositories.append((repo_output_dir, data))
repo_data[repo_output_dir] = data
repo_data[_script_dir] = (_script_dir, None, None)
if enlistment_repositories:
dm.stream.write("Enlisting in {}...".format(inflect.no("repository", len(enlistment_repositories))))
with dm.stream.DoneManager(
suffix="\n",
) as enlist_dm:
for index, (output_dir, data) in enumerate(enlistment_repositories):
enlist_dm.stream.write("'{}' ({} of {})...".format(data[0], index + 1, len(enlistment_repositories)))
with enlist_dm.stream.DoneManager() as this_dm:
FileSystem.MakeDirs(os.path.dirname(output_dir))
temp_directory = output_dir + "_tmp"
sink = six.moves.StringIO()
this_dm.result = Process.Execute(
data[1].format(
output_dir=temp_directory,
),
StreamDecorator(
[
sink,
StreamDecorator(
this_dm.stream if verbose else None,
line_prefix="INFO: ",
),
],
),
)
if this_dm.result != 0:
if not verbose:
this_dm.stream.write(sink.getvalue())
return this_dm.result
shutil.move(temp_directory, output_dir)
dm.stream.write("Setting up {}...".format(inflect.no("repository", len(repo_data))))
with dm.stream.DoneManager(
suffix="\n",
) as setup_dm:
command_line_template = "Setup{} {{suffix}}".format(CurrentShell.ScriptExtension)
for index, (output_dir, data) in enumerate(six.iteritems(repo_data)):
setup_dm.stream.write("'{}' ({} of {})...".format(data[0], index + 1, len(repo_data)))
with setup_dm.stream.DoneManager() as this_dm:
prev_dir = os.getcwd()
os.chdir(output_dir)
with CallOnExit(lambda: os.chdir(prev_dir)):
command_line = command_line_template.format(
suffix=data[2] or "",
)
if CurrentShell.CategoryName == "Windows":
command_line = command_line.replace("=", "_EQ_")
elif CurrentShell.CategoryName == "Linux":
command_line = "./{}".format(command_line)
sink = six.moves.StringIO()
this_dm.result = Process.Execute(
command_line,
StreamDecorator(
[
sink,
StreamDecorator(
this_dm.stream if verbose else None,
line_prefix="INFO: ",
),
],
),
)
if this_dm.result != 0:
if not verbose:
this_dm.stream.write(sink.getvalue())
return this_dm.result
dm.stream.write(
StringHelpers.LeftJustify(
textwrap.dedent(
"""\
# ----------------------------------------------------------------------
# ----------------------------------------------------------------------
# ----------------------------------------------------------------------
The enlistment and setup of all repositories was successful. To begin
development activities, please run the following command. Note that
this command must be run every time you open a new terminal window.
{}{} {}
# ----------------------------------------------------------------------
# ----------------------------------------------------------------------
# ----------------------------------------------------------------------
""",
).format(
". " if CurrentShell.CategoryName == "Linux" else "",
os.path.join(
_script_dir,
"Activate{}{}".format(
".{}".format(os.getenv("DEVELOPMENT_ENVIRONMENT_ENVIRONMENT_NAME")) if os.getenv("DEVELOPMENT_ENVIRONMENT_ENVIRONMENT_NAME") != "DefaultEnv" else "",
CurrentShell.ScriptExtension,
),
),
_ACTIVATION_REPO_CONFIGURATION or "",
),
16,
skip_first_line=False,
),
)
return dm.result
# ----------------------------------------------------------------------
# ----------------------------------------------------------------------
# ----------------------------------------------------------------------
if __name__ == "__main__":
try:
sys.exit(CommandLine.Main())
except KeyboardInterrupt:
pass

Просмотреть файл