Thanks, I wasn't aware of the ordering within edit_line, so this information is helpful. I guess this order is as good as any given the permutation of delete_lines, insert_lines, replace_patterns could make different outcomes.
For some reason I felt that replace_patterns would be higher in the order, as a search or fuzzy search for existing text would correct issues first. Then if the correct pattern is found, its either deleted, or if not present, inserted. The discussion is academic, but still an interesting topic. Regards, Jim ----- Original Message ----- From: no-re...@cfengine.com To: help-cfengine@cfengine.org At: 5/23 17:47:44 Forum: Cfengine Help Subject: Re: question on replace_patterns and insert_lines Author: zzamboni Link to topic: https://cfengine.com/forum/read.php?3,22198,22205#msg-22205 Jim, The problem is that according to normal ordering, insert_lines runs *before* replace_patterns: http://www.cfengine.org/manuals/cf3-reference.html#Agent-normal-ordering So the line from insert_lines is inserted because the line does not yet exist in the file (it's still incorrect), and then replace_patterns corrects the erroneous line, and you end with two "correct" lines. The trick is to set a class after replace_patterns runs (regardless of the result of the replacement), and to make insert_lines conditional on that class. This forces the insert_lines to run only on the second pass (cfengine does up to three pases over the promises), which will result in the line being inserted *only* if, even after replace_patterns runs, the desired line does not yet exist in the file. I have coded this in a replace_or_add bundle that I have in my personal copy of the COPBL https://github.com/zzamboni/cfengine-copbl bundle edit_line replace_or_add(pattern,line) # Replace a pattern in a file with a single line. # If the pattern is not found, add the line to the file. # The pattern must match the whole line (it is automatically # anchored to the start and end of the line) to avoid # ambiguity. { replace_patterns: "^${pattern}$" replace_with => value("${line}"), classes => always("replace_done"); insert_lines: replace_done:: "${line}"; } body classes always(x) # Define a class no matter what the outcome of the promise is { promise_repaired => { "$(x)" }; promise_kept => { "$(x)" }; repair_failed => { "$(x)" }; repair_denied => { "$(x)" }; repair_timeout => { "$(x)" }; } _______________________________________________ Help-cfengine mailing list Help-cfengine@cfengine.org https://cfengine.org/mailman/listinfo/help-cfengine _______________________________________________ Help-cfengine mailing list Help-cfengine@cfengine.org https://cfengine.org/mailman/listinfo/help-cfengine