diff --git a/cli/hcl_to_json.py b/cli/hcl_to_json.py index 7e9f7275..dde8cfa0 100644 --- a/cli/hcl_to_json.py +++ b/cli/hcl_to_json.py @@ -68,7 +68,7 @@ def main(): parser.add_argument( "--no-explicit-blocks", action="store_true", - help="Disable explicit block markers", + help="Disable explicit block markers. Note: round-trip through json_to_hcl is NOT supported with this option.", ) parser.add_argument( "--no-preserve-heredocs", @@ -85,6 +85,11 @@ def main(): action="store_true", help="Convert scientific notation to standard floats", ) + parser.add_argument( + "--strip-string-quotes", + action="store_true", + help="Strip surrounding double-quotes from serialized string values. Note: round-trip through json_to_hcl is NOT supported with this option.", + ) # JSON output formatting parser.add_argument( @@ -106,6 +111,7 @@ def main(): preserve_heredocs=not args.no_preserve_heredocs, force_operation_parentheses=args.force_parens, preserve_scientific_notation=not args.no_preserve_scientific, + strip_string_quotes=args.strip_string_quotes, ) json_indent = args.json_indent diff --git a/hcl2/deserializer.py b/hcl2/deserializer.py index 5043985a..5e282503 100644 --- a/hcl2/deserializer.py +++ b/hcl2/deserializer.py @@ -63,9 +63,15 @@ class DeserializerOptions: """Options controlling how Python dicts are deserialized into LarkElement trees.""" + # Convert heredoc values (< Any: """Serialize to a quoted string.""" - return ( - '"' - + "".join(part.serialize(options, context) for part in self.string_parts) - + '"' - ) + inner = "".join(part.serialize(options, context) for part in self.string_parts) + if options.strip_string_quotes: + return inner + return '"' + inner + '"' class HeredocTemplateRule(LarkRule): @@ -129,9 +128,13 @@ def serialize( heredoc = ( heredoc.replace("\\", "\\\\").replace('"', '\\"').replace("\n", "\\n") ) + if options.strip_string_quotes: + return heredoc return f'"{heredoc}"' result = heredoc.rstrip(self._trim_chars) + if options.strip_string_quotes: + return result return f'"{result}"' @@ -178,4 +181,7 @@ def serialize( lines = [line.replace("\\", "\\\\").replace('"', '\\"') for line in lines] sep = "\\n" if not options.preserve_heredocs else "\n" - return '"' + sep.join(lines) + '"' + inner = sep.join(lines) + if options.strip_string_quotes: + return inner + return '"' + inner + '"' diff --git a/hcl2/utils.py b/hcl2/utils.py index 7e349558..d701ae25 100644 --- a/hcl2/utils.py +++ b/hcl2/utils.py @@ -11,14 +11,31 @@ class SerializationOptions: """Options controlling how LarkElement trees are serialized to Python dicts.""" + # Include __comments__ and __inline_comments__ keys in the output. with_comments: bool = True + # Add __start_line__ and __end_line__ metadata to each block/attribute. with_meta: bool = False + # Serialize nested objects as inline HCL strings (e.g. "${{key = value}}") + # instead of Python dicts. wrap_objects: bool = False + # Serialize tuples as inline HCL strings (e.g. "${[1, 2, 3]}") + # instead of Python lists. wrap_tuples: bool = False + # Add __is_block__ markers to distinguish blocks from plain objects. + # Note: round-trip through from_dict/dumps is NOT supported WITHOUT this option. explicit_blocks: bool = True + # Keep heredoc syntax (<