diff --git a/fleet/v1/objects/unit.py b/fleet/v1/objects/unit.py index 114c742..a7a0edb 100644 --- a/fleet/v1/objects/unit.py +++ b/fleet/v1/objects/unit.py @@ -146,7 +146,7 @@ def _set_options_from_file(self, file_handle): """ # TODO: Find a library to handle this unit file parsing - # Can't use configparser, it doesn't handle multiple entries for the same key in the same sectoin + # Can't use configparser, it doesn't handle multiple entries for the same key in the same section # This is terribly naive # build our output here @@ -161,6 +161,7 @@ def _set_options_from_file(self, file_handle): line_number += 1 # clear any extra white space + orig_line = line line = line.strip() # ignore comments, and blank lines @@ -183,8 +184,25 @@ def _set_options_from_file(self, file_handle): )) # Attempt to parse a line inside a section - # Lines should look like: name=value + # Lines should look like: name=value \ + # continuation + continuation = False try: + # if the previous value ends with \ then we are a continuation + # so remove the \, and set the flag so we'll append to this below + if options[-1]['value'].endswith('\\'): + options[-1]['value'] = options[-1]['value'][:-1] + continuation = True + except IndexError: + pass + + try: + # if we are a continuation, then just append our value to the previous line + if continuation: + options[-1]['value'] += orig_line + continue + + # else we are a normal line, so spit and get our name / value name, value = line.split('=', 1) options.append({ 'section': section, @@ -194,7 +212,7 @@ def _set_options_from_file(self, file_handle): except ValueError: raise ValueError( 'Unable to parse unit file; ' - 'Malformed line in section {0}: {1} (line: {2}'.format( + 'Malformed line in section {0}: {1} (line: {2})'.format( section, line, line_number diff --git a/fleet/v1/tests/test_unit.py b/fleet/v1/tests/test_unit.py index b7f2f9f..fb1bdab 100644 --- a/fleet/v1/tests/test_unit.py +++ b/fleet/v1/tests/test_unit.py @@ -101,6 +101,21 @@ def test2(): self.assertRaises(ValueError, test) self.assertRaises(ValueError, test2) + def test_from_string_continuation_good(self): + """When parsing unit files, line continuation with a trailing backslash works""" + unit = Unit(from_string="[Section]\nThisLine=The start of \\\nsomething very\\\n long and boring\n") + + # test options (this should match the string above) + test_options = [ + { + 'section': 'Section', + 'name': 'ThisLine', + 'value': 'The start of something very long and boring' + } + ] + + assert unit.options == test_options + def test_options_no_desired_state(self): """Setting options explicitly works""" test_options = [{'section': 'Service', 'name': 'ExecStart', 'value': '/usr/bin/sleep 1d'}]