Files
cibuildwheel/cibuildwheel/environment.py
T

86 lines
2.8 KiB
Python
Raw Normal View History

from typing import Dict, List, Mapping, Optional
2019-11-12 23:51:27 +00:00
2021-01-06 13:50:58 -05:00
import bashlex
2017-09-01 13:24:12 +01:00
from . import bashlex_eval
class EnvironmentParseError(Exception):
pass
def split_env_items(env_string: str) -> List[str]:
2017-09-01 13:24:12 +01:00
'''Splits space-separated variable assignments into a list of individual assignments.
>>> split_env_items('VAR=abc')
['VAR=abc']
>>> split_env_items('VAR="a string" THING=3')
['VAR="a string"', 'THING=3']
>>> split_env_items('VAR="a string" THING=\\'single "quotes"\\'')
['VAR="a string"', 'THING=\\'single "quotes"\\'']
>>> split_env_items('VAR="dont \\\\"forget\\\\" about backslashes"')
['VAR="dont \\\\"forget\\\\" about backslashes"']
2017-09-06 18:27:06 +01:00
>>> split_env_items('PATH="$PATH;/opt/cibw_test_path"')
['PATH="$PATH;/opt/cibw_test_path"']
>>> split_env_items('PATH2="something with spaces"')
['PATH2="something with spaces"']
2017-09-01 13:24:12 +01:00
'''
2017-09-06 18:35:42 +01:00
if not env_string:
return []
2017-09-06 18:27:06 +01:00
command_node = bashlex.parsesingle(env_string)
result = []
for word_node in command_node.parts:
part_string = env_string[word_node.pos[0]:word_node.pos[1]]
result.append(part_string)
return result
2017-09-01 13:24:12 +01:00
2020-02-03 20:42:55 +01:00
class EnvironmentAssignment:
def __init__(self, assignment: str):
2017-09-01 13:24:12 +01:00
name, equals, value = assignment.partition('=')
if not equals:
raise EnvironmentParseError(assignment)
self.name = name
self.value = value
def evaluated_value(self, environment: Dict[str, str], executor: Optional[bashlex_eval.EnvironmentExecutor] = None) -> str:
2017-09-01 13:24:12 +01:00
'''Returns the value of this assignment, as evaluated in the environment'''
return bashlex_eval.evaluate(self.value, environment=environment, executor=executor)
2017-09-01 13:24:12 +01:00
def as_shell_assignment(self) -> str:
2020-05-09 10:34:59 +02:00
return f'export {self.name}={self.value}'
2017-09-01 13:24:12 +01:00
def __repr__(self) -> str:
2020-05-09 10:34:59 +02:00
return f'{self.name}={self.value}'
2017-09-01 13:33:29 +01:00
2017-09-01 13:24:12 +01:00
2020-02-03 20:42:55 +01:00
class ParsedEnvironment:
def __init__(self, assignments: List[EnvironmentAssignment]):
2017-09-01 13:24:12 +01:00
self.assignments = assignments
def as_dictionary(self,
prev_environment: Mapping[str, str],
executor: Optional[bashlex_eval.EnvironmentExecutor] = None) -> Dict[str, str]:
2020-05-15 13:46:59 +02:00
environment = dict(**prev_environment)
2017-09-01 13:24:12 +01:00
for assignment in self.assignments:
value = assignment.evaluated_value(environment=environment, executor=executor)
2017-09-01 13:24:12 +01:00
environment[assignment.name] = value
return environment
def as_shell_commands(self) -> List[str]:
2017-09-01 13:24:12 +01:00
return [a.as_shell_assignment() for a in self.assignments]
2017-09-01 13:33:29 +01:00
def __repr__(self) -> str:
2020-05-09 10:34:59 +02:00
return f'ParsedEnvironment({[repr(a) for a in self.assignments]!r})'
def parse_environment(env_string: str) -> ParsedEnvironment:
env_items = split_env_items(env_string)
assignments = [EnvironmentAssignment(item) for item in env_items]
return ParsedEnvironment(assignments=assignments)