diff --git a/lib/files.cf b/lib/files.cf index c61af73ce8..6fb6cdff47 100644 --- a/lib/files.cf +++ b/lib/files.cf @@ -435,6 +435,8 @@ bundle edit_line set_variable_values_ini(tab, sectionName) # Be careful if the index string contains funny chars "cindex[$(index)]" string => canonify("$(index)"); + "_escaped_key[$(index)]" string => escape("$(index)"); + "_escaped_section[$(sectionName)]" string => escape("$(sectionName)"); classes: "edit_$(cindex[$(index)])" not => strcmp("$($(tab)[$(sectionName)][$(index)])","dontchange"), @@ -442,27 +444,45 @@ bundle edit_line set_variable_values_ini(tab, sectionName) field_edits: + # This is emitting an /error/ when no commented out managed key line is + # found within the selected region. The missing keys is completely + # expected in the case of promising a new file or section. How can this be + # guarded against executing? The only thought I have is ... + # if => regcmp( "some regex I dunno how to craft", readfile( $(edit.filename) ) + + # # If the line is there, but commented out, first uncomment it + # "#+\s*$(index)\s*=.*" + # select_region => INI_section(escape("$(sectionName)")), + # edit_field => col("\s*=\s*","1","$(index)","set"), + # if => and(canonify("_section_$(sectionName)_present_reached"), + # "edit_$(cindex[$(index)])"); # If the line is there, but commented out, first uncomment it - "#+\s*$(index)\s*=.*" - select_region => INI_section(escape("$(sectionName)")), - edit_field => col("\s*=\s*","1","$(index)","set"), - if => "edit_$(cindex[$(index)])"; + "#+\s*$(_escaped_key[$(index)])\s*=.*" + if => and( + #canonify("_section_$(sectionName)_present_reached"), # I don't think this helps because the class is based on the promise running on a buffer of the file, we are only checking the file as it exists before the promise finished + #"edit_$(cindex[$(index)])", # is it useful? why would you do not change? this bundle only asserts keys provided in dataset, providing a key with value donotchange is tantemount to not providing the key + # regcmp matches if the promised file contains [$(sectionName)] with a commented out $(index) + regcmp( concat("\[$(_escaped_section[$(sectionName)])\]", + "[^#\[]*#\s*$(_escaped_key[$(index)])\s*=.*"), + readfile( $(edit.filename) ))), + select_region => INI_section( "$(_escaped_section[$(sectionName)])" ), + edit_field => col("\s*=\s*","1","$(index)","set"); # match a line starting like the key something "\s*$(index)\s*=.*" edit_field => col("\s*=\s*","2","$($(tab)[$(sectionName)][$(index)])","set"), select_region => INI_section(escape("$(sectionName)")), - classes => results("bundle", "set_variable_values_ini_not_$(cindex[$(index)])"), - if => "edit_$(cindex[$(index)])"; - + if => and(canonify("_section_$(sectionName)_present_reached"), + "edit_$(cindex[$(index)])"); insert_lines: "[$(sectionName)]" location => start, - comment => "Insert lines"; + comment => "Insert lines", + classes => results( "bundle", "_section_$(sectionName)_present" ); "$(index)=$($(tab)[$(sectionName)][$(index)])" select_region => INI_section(escape("$(sectionName)")), - if => "!(set_variable_values_ini_not_$(cindex[$(index)])_kept|set_variable_values_ini_not_$(cindex[$(index)])_repaired).edit_$(cindex[$(index)])"; + if => "edit_$(cindex[$(index)])"; } @@ -790,6 +810,7 @@ bundle edit_line set_line_based(v, sep, bp, kp, cp) # If the line is there with the wrong value, replace with # the correct value + # "^\s*(ucredit\s*=\s*(?!1$).*|ucredit)$" "^\s*($(i)$(bp)(?!$(ev[$(i)])$).*|$(i))$" comment => "Correct the value '$(i)'", replace_with => value("$(i)$(sep)$($(v)[$(i)])"), diff --git a/tests/acceptance/lib/files/set_variable_values_ini_no_error_when_keys_in_section_not_present.cf b/tests/acceptance/lib/files/set_variable_values_ini_no_error_when_keys_in_section_not_present.cf new file mode 100644 index 0000000000..ad5261a6da --- /dev/null +++ b/tests/acceptance/lib/files/set_variable_values_ini_no_error_when_keys_in_section_not_present.cf @@ -0,0 +1,35 @@ +####################################################### +# +# Test bundle set_config_values_ini +# +####################################################### + +body common control +{ + inputs => { '../../default.cf.sub' }; + bundlesequence => { default("$(this.promise_filename)") }; + version => "1.0"; +} + +####################################################### + + +bundle agent test +{ + meta: + "description" -> { "CFE-3866" } + string => "Test that set_variable_values_ini does not error when promised key is not present"; + +} + +####################################################### + +bundle agent check +{ + + methods: + + "Pass/FAIL" + usebundle => dcs_passif_output(".*$(this.promise_filename).sub Pass.*", ".*error.*", "$(sys.cf_agent) -Kf $(this.promise_filename).sub --define AUTO,DEBUG,EXTRA", $(this.promise_filename)); + +} diff --git a/tests/acceptance/lib/files/set_variable_values_ini_no_error_when_keys_in_section_not_present.cf.sub b/tests/acceptance/lib/files/set_variable_values_ini_no_error_when_keys_in_section_not_present.cf.sub new file mode 100644 index 0000000000..dfa9235ad5 --- /dev/null +++ b/tests/acceptance/lib/files/set_variable_values_ini_no_error_when_keys_in_section_not_present.cf.sub @@ -0,0 +1,69 @@ +####################################################### +# +# Test bundle set_config_values_ini +# +####################################################### + +body common control +{ + inputs => { '../../default.cf.sub' }; + bundlesequence => { default("$(this.promise_filename)") }; + version => "1.0"; +} + +####################################################### + +bundle agent init +{ + files: + + "$(G.testfile).actual" + copy_from => local_cp("$(this.promise_filename).start"); + + + "$(G.testfile).expected" + copy_from => local_cp("$(this.promise_filename).finish"); + +} + +####################################################### + +bundle agent test +{ + meta: + "description" -> { "CFE-3866" } + string => "Test that set_variable_values_ini does not error when promised key is not present"; + + vars: + "config[section 1][present_at_start]" string => "1"; + "config[section 1][absent_at_start]" string => "1"; + "sections" slist => getindices( config ); + + files: + + "$(G.testfile).actual" + edit_line => set_variable_values_ini("test.config", "$(sections)"); + +} + +####################################################### + +bundle agent check +{ + + methods: + + "check" + usebundle => dcs_if_diff( "$(G.testfile).actual", "$(G.testfile).expected", + "pass", "_fail"); + + # Fail the test if any of the files fail. + "fail" + usebundle => dcs_fail( $(this.promise_filename) ), + if => "_fail"; + + pass:: + "pass" + usebundle => dcs_pass( $(this.promise_filename) ); + +} diff --git a/tests/acceptance/lib/files/set_variable_values_ini_no_error_when_keys_in_section_not_present.cf.sub.finish b/tests/acceptance/lib/files/set_variable_values_ini_no_error_when_keys_in_section_not_present.cf.sub.finish new file mode 100644 index 0000000000..49c619c8ff --- /dev/null +++ b/tests/acceptance/lib/files/set_variable_values_ini_no_error_when_keys_in_section_not_present.cf.sub.finish @@ -0,0 +1,5 @@ +[section 1] +present_at_start=1 +absent_at_start=1 +[section 2] +present_at_start=two diff --git a/tests/acceptance/lib/files/set_variable_values_ini_no_error_when_keys_in_section_not_present.cf.sub.start b/tests/acceptance/lib/files/set_variable_values_ini_no_error_when_keys_in_section_not_present.cf.sub.start new file mode 100644 index 0000000000..f2fd73a17c --- /dev/null +++ b/tests/acceptance/lib/files/set_variable_values_ini_no_error_when_keys_in_section_not_present.cf.sub.start @@ -0,0 +1,4 @@ +[section 1] +present_at_start=1 +[section 2] +present_at_start=two