66# option. This file may not be copied, modified, or distributed
77# except according to those terms.
88
9+ import copy
910from typing import List , Optional
1011
1112import ramble .util .colors as rucolor
@@ -27,6 +28,213 @@ def _title_color(title: str, n_indent: int = 0):
2728 return out_str
2829
2930
31+ class Variable :
32+ """Class representing a variable definition"""
33+
34+ def __init__ (
35+ self ,
36+ name : str ,
37+ default = None ,
38+ description : str = None ,
39+ values = None ,
40+ expandable : bool = True ,
41+ track_used : bool = True ,
42+ when = None ,
43+ ** kwargs ,
44+ ):
45+ """Constructor for a new variable
46+
47+ Args:
48+ name (str): Name of variable
49+ default: Default value of variable
50+ description (str): Description of variable
51+ values: List of suggested values for variable
52+ expandable (bool): True if variable can be expanded, False otherwise
53+ track_used (bool): True if variable should be considered used,
54+ False to ignore it for vectorizing experiments
55+ when (list | None): List of when conditions to apply to directive
56+ """
57+ self .name = name
58+ self .default = default
59+ self .description = description
60+ self .values = values .copy () if isinstance (values , list ) else [values ]
61+ self .expandable = expandable
62+ self .track_used = track_used
63+ self .when = when .copy () if when else []
64+
65+ def __str__ (self ):
66+ if not hasattr (self , "_str_indent" ):
67+ self ._str_indent = 0
68+ return self .as_str (n_indent = self ._str_indent )
69+
70+ def as_str (self , n_indent : int = 0 , verbose : bool = False ):
71+ """String representation of this variable
72+
73+ Args:
74+ n_indent (int): Number of spaces to indent string lines with
75+
76+ Returns:
77+ (str): Representation of this variable
78+ """
79+ indentation = " " * n_indent
80+
81+ if verbose :
82+ print_attrs = ["Description" , "Default" , "Values" ]
83+
84+ out_str = _title_color (f"{ indentation } { self .name } :\n " , n_indent )
85+ for print_attr in print_attrs :
86+ name = print_attr
87+ if print_attr == "Values" :
88+ name = "Suggested Values"
89+ attr_name = print_attr .lower ()
90+
91+ attr_val = getattr (self , attr_name , None )
92+ if attr_val :
93+ out_str += (
94+ f"{ indentation } { _title_color (name , n_indent = n_indent + 4 )} : "
95+ f'{ str (attr_val ).replace ("@" , "@@" )} \n '
96+ )
97+ else :
98+ out_str = f"{ indentation } { self .name } "
99+
100+ return out_str
101+
102+ def copy (self ):
103+ return copy .deepcopy (self )
104+
105+
106+ class VariableModification :
107+ """Class representing a variable modification"""
108+
109+ def __init__ (
110+ self ,
111+ name : str ,
112+ modification : str ,
113+ method : str = "set" ,
114+ separator : str = " " ,
115+ when = None ,
116+ ** kwargs ,
117+ ):
118+ """Constructor for a new variable modification
119+
120+ Args:
121+ name (str): The variable to modify
122+ modification (str): The value to modify 'name' with
123+ method (str): How the modification should be applied
124+ mode (str): Single mode to group this modification into
125+ modes (str): List of modes to group this modification into
126+ separator (str): Optional separator to use when modifying with 'append' or
127+ 'prepend' methods.
128+ when (list | None): List of when conditions this modification should apply in
129+
130+ Supported values are 'append', 'prepend', and 'set':
131+ 'append' will add the modification to the end of 'name'
132+ 'prepend' will add the modification to the beginning of 'name'
133+ 'set' (Default) will overwrite 'name' with the modification
134+ """
135+ self .name = name
136+ self .modification = modification
137+ self .method = method
138+ self .separator = separator
139+ self .when = when .copy () if when else []
140+
141+ def __str__ (self ):
142+ if not hasattr (self , "_str_indent" ):
143+ self ._str_indent = 0
144+ return self .as_str (n_indent = self ._str_indent )
145+
146+ def as_str (self , n_indent : int = 0 , verbose : bool = False ):
147+ """String representation of this variable
148+
149+ Args:
150+ n_indent (int): Number of spaces to indent string lines with
151+
152+ Returns:
153+ (str): Representation of this variable
154+ """
155+ indentation = " " * n_indent
156+
157+ print_attrs = ["Modification" , "Method" , "Separator" , "When" ]
158+
159+ out_str = _title_color (f"{ indentation } { self .name } :\n " , n_indent )
160+ for print_attr in print_attrs :
161+ name = print_attr
162+ attr_name = print_attr .lower ()
163+
164+ attr_val = getattr (self , attr_name , None )
165+ if attr_val :
166+ if print_attr == "Separator" :
167+ attr_val = f"'{ attr_val } '"
168+ out_str += (
169+ f"{ indentation } { _title_color (name , n_indent = n_indent + 4 )} : "
170+ f'{ str (attr_val ).replace ("@" , "@@" )} \n '
171+ )
172+ return out_str
173+
174+ def copy (self ):
175+ return copy .deepcopy (self )
176+
177+
178+ class EnvironmentVariable :
179+ """Class representing an environment variable"""
180+
181+ def __init__ (
182+ self ,
183+ name : str ,
184+ value = None ,
185+ description : str = None ,
186+ when = None ,
187+ ** kwargs ,
188+ ):
189+ """EnvironmentVariable constructor
190+
191+ Args:
192+ name (str): Name of environment variable
193+ value: Value to set environment variable to
194+ description (str): Description of the environment variable
195+ when (list | None): List of when conditions to apply to directive
196+ """
197+ self .name = name
198+ self .value = value
199+ self .description = description
200+ self .when = when .copy () if when else []
201+
202+ def __str__ (self ):
203+ if not hasattr (self , "_str_indent" ):
204+ self ._str_indent = 0
205+ return self .as_str (n_indent = self ._str_indent )
206+
207+ def as_str (self , n_indent : int = 0 , verbose : bool = False ):
208+ """String representation of environment variable
209+
210+ Args:
211+ n_indent (int): Number of spaces to indent string representation by
212+
213+ Returns:
214+ (str): String representing this environment variable
215+ """
216+ indentation = " " * n_indent
217+
218+ if verbose :
219+ print_attrs = ["Description" , "Value" ]
220+ out_str = _title_color (f"{ indentation } { self .name } :\n " , n_indent )
221+ for name in print_attrs :
222+ attr_name = name .lower ()
223+ attr_val = getattr (self , attr_name , None )
224+ if attr_val :
225+ out_str += (
226+ f"{ indentation } { _title_color (name , n_indent = n_indent + 4 )} : "
227+ f'{ str (attr_val ).replace ("@" , "@@" )} \n '
228+ )
229+ else :
230+ out_str = f"{ indentation } { self .name } "
231+
232+ return out_str
233+
234+ def copy (self ):
235+ return copy .deepcopy (self )
236+
237+
30238class EnvironmentVariableModifications :
31239 """Class representing modifications of an environment variable"""
32240
@@ -123,6 +331,9 @@ def as_str(self, n_indent: int = 0, verbose: bool = False):
123331
124332 return out_str
125333
334+ def copy (self ):
335+ return copy .deepcopy (self )
336+
126337 def add_modification (
127338 self ,
128339 modification : str ,
0 commit comments