#NEWLINE# @ operation #NEWLINE# def line( state , host , name , line , present = True , replace = None , flags = None ) : #NEWLINE# #INDENT# "\n    Ensure lines in files using grep to locate and sed to replace.\n\n    + name: target remote file to edit\n    + line: string or regex matching the target line\n    + present: whether the line should be in the file\n    + replace: text to replace entire matching lines when ``present=True``\n    + flags: list of flags to pass to sed when replacing/deleting\n\n    Note on regex matching:\n        unless line matches a line (starts with ^, ends $), pyinfra will wrap it such that\n        it does, like: ``^.*LINE*.$``. This means we don't swap parts of lines out. To use\n        more involved examples, see ``files.replace``.\n    " #NEWLINE# match_line = line #NEWLINE# if ( not match_line . startswith ( '^' ) ) : #NEWLINE# #INDENT# match_line = '^.*{0}' . format ( match_line ) #NEWLINE# #UNINDENT# if ( not match_line . endswith ( '$' ) ) : #NEWLINE# #INDENT# match_line = '{0}.*$' . format ( match_line ) #NEWLINE# #UNINDENT# present_lines = host . fact . find_in_file ( name , match_line ) #NEWLINE# commands = [ ] #NEWLINE# if replace : #NEWLINE# #INDENT# line = replace #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# replace = '' #NEWLINE# #UNINDENT# echo_command = 'echo "{0}" >> {1}' . format ( line , name ) #NEWLINE# sed_replace_command = sed_replace ( state , name , match_line , replace , flags = flags ) #NEWLINE# if ( ( not present_lines ) and present ) : #NEWLINE# #INDENT# if ( present_lines is None ) : #NEWLINE# #INDENT# commands . append ( '\n                # If the file now exists\n                if [ -f "{target}" ]; then\n                    # Grep for the line, sed if matches\n                    (grep "{match_line}" "{target}" && {sed_replace_command}) ||                     # Else echo\n                    {echo_command}\n\n                # No file, just echo\n                else\n                    {echo_command}\n                fi\n            ' . format ( target = name , match_line = match_line , echo_command = echo_command , sed_replace_command = sed_replace_command ) ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# commands . append ( echo_command ) #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# if ( present_lines and ( not present ) ) : #NEWLINE# #INDENT# commands . append ( sed_replace ( state , name , match_line , '' , flags = flags ) ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( present_lines and present ) : #NEWLINE# #INDENT# if ( replace and any ( ( ( line != replace ) for line in present_lines ) ) ) : #NEWLINE# #INDENT# commands . append ( sed_replace_command ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# return commands