# # # patch "automate.cc" # from [d083b203936a4d0abcd55e2ae9e3479192db220c] # to [dd511cb884e0db7622d6a94df97793211df4e59e] # # patch "tests/automate_inventory_restricted/__driver__.lua" # from [20aa6fa7f1d4b21dfd609f7afffc60b9d4d379ef] # to [677b34e9d8464cf4670428d1f804f142d134d081] # ============================================================ --- automate.cc d083b203936a4d0abcd55e2ae9e3479192db220c +++ automate.cc dd511cb884e0db7622d6a94df97793211df4e59e @@ -629,6 +629,98 @@ inventory_rosters(roster_t const & old_r } } +// check if the include/exclude paths contains paths to renamed nodes +// if yes, add the corresponding old/new name of these nodes to the +// paths as well, so the tree walker code will correctly identify them later +// on or skips them if they should be excluded +static void +inventory_expand_paths(roster_t const & old_roster, + roster_t const & new_roster, + node_restriction const & mask, + vector & includes, + vector & excludes) +{ + // at first check the includes vector + vector new_includes; + for (int i=0, s=includes.size(); iself)) + { + file_path new_path; + new_roster.get_name(node->self, new_path); + if (fp != new_path && + find(includes.begin(), includes.end(), new_path) == includes.end()) + { + new_includes.push_back(new_path); + } + } + } + + if (new_roster.has_node(fp)) + { + node_t node = new_roster.get_node(fp); + if (old_roster.has_node(node->self)) + { + file_path old_path; + old_roster.get_name(node->self, old_path); + if (fp != old_path && + find(includes.begin(), includes.end(), old_path) == includes.end()) + { + new_includes.push_back(old_path); + } + } + } + } + + copy(new_includes.begin(), new_includes.end(), + inserter(includes, includes.end())); + + // and now the excludes vector + vector new_excludes; + for (int i=0, s=excludes.size(); iself)) + { + file_path new_path; + new_roster.get_name(node->self, new_path); + if (fp != new_path && + find(excludes.begin(), excludes.end(), new_path) == excludes.end()) + { + new_excludes.push_back(new_path); + } + } + } + + if (new_roster.has_node(fp)) + { + node_t node = new_roster.get_node(fp); + if (old_roster.has_node(node->self)) + { + file_path old_path; + old_roster.get_name(node->self, old_path); + if (fp != old_path && + find(excludes.begin(), excludes.end(), old_path) == excludes.end()) + { + new_excludes.push_back(old_path); + } + } + } + } + + copy(new_excludes.begin(), new_excludes.end(), + inserter(excludes, excludes.end())); +} + struct inventory_itemizer : public tree_walker { path_restriction const & mask; @@ -901,6 +993,10 @@ CMD_AUTOMATE(inventory, N_("[PATH]...") node_restriction nmask(includes, excludes, app.opts.depth, old_roster, new_roster, app); inventory_rosters(old_roster, new_roster, nmask, inventory); + // ensure that the include/exclude paths contain the corresponding paths + // for the old/new roster items if restricted to such + inventory_expand_paths(old_roster, new_roster, nmask, includes, excludes); + // skip the check of the workspace paths because some of them might // be missing and the user might want to query the recorded structure // of them anyways ============================================================ --- tests/automate_inventory_restricted/__driver__.lua 20aa6fa7f1d4b21dfd609f7afffc60b9d4d379ef +++ tests/automate_inventory_restricted/__driver__.lua 677b34e9d8464cf4670428d1f804f142d134d081 @@ -333,4 +333,99 @@ checkexp ("checked all", #parsed, index- checkexp ("checked all", #parsed, index-1) +---------- +-- reset the workspace for further tests + +check(mtn("revert", "."), 0, false, false) +remove("dir_a/file_0") + +---------- +-- rename a node and restrict on that renamed node + +check(mtn("mv", "dir_a", "dir_c"), 0, false, false) + +check(mtn("automate", "inventory", "dir_a"), 0, true, false) +source_restricted = readfile("stdout") + +check(mtn("automate", "inventory", "dir_c"), 0, true, false) +target_restricted = readfile("stdout") + +-- restricting to either path, old or new, should lead to the same output +check(source_restricted == target_restricted) + +-- now check this output +parsed = parse_basic_io(source_restricted) +index = 1 + +index = check_inventory (parsed, index, +{ path = "dir_a", + old_type = "directory", + new_path = "dir_c", + fs_type = "none", + status = {"rename_source"}}) + +index = check_inventory (parsed, index, +{ path = "dir_a/file_a", + old_type = "file", + new_path = "dir_c/file_a", + fs_type = "none", + status = {"rename_source"}}) + +index = check_inventory (parsed, index, +{ path = "dir_c", + new_type = "directory", + old_path = "dir_a", + fs_type = "directory", + status = {"rename_target", "known" }}) + +index = check_inventory (parsed, index, +{ path = "dir_c/file_a", + new_type = "file", + old_path = "dir_a/file_a", + fs_type = "file", + status = {"rename_target", "known" }}) + +checkexp ("checked all", #parsed, index-1) + +---------- +-- keep the above workspace situtation, but exclude the output of the file_a +-- node in all scenarios + +check(mtn("automate", "inventory", "dir_a", "--exclude", "dir_a/file_a"), 0, true, false) +rename("stdout", "source_source_excluded") + +check(mtn("automate", "inventory", "dir_a", "--exclude", "dir_c/file_a"), 0, true, false) +rename("stdout", "source_target_excluded") + +check(mtn("automate", "inventory", "dir_c", "--exclude", "dir_c/file_a"), 0, true, false) +rename("stdout", "target_target_excluded") + +check(mtn("automate", "inventory", "dir_c", "--exclude", "dir_a/file_a"), 0, true, false) +rename("stdout", "target_source_excluded") + +-- all of the above calls should return the same output +check(samefile("source_source_excluded", "source_target_excluded")) +check(samefile("target_target_excluded", "target_source_excluded")) +check(samefile("source_source_excluded", "target_target_excluded")) + +-- now check this output +parsed = parse_basic_io(readfile("source_source_excluded")) +index = 1 + +index = check_inventory (parsed, index, +{ path = "dir_a", + old_type = "directory", + new_path = "dir_c", + fs_type = "none", + status = {"rename_source"}}) + +index = check_inventory (parsed, index, +{ path = "dir_c", + new_type = "directory", + old_path = "dir_a", + fs_type = "directory", + status = {"rename_target", "known" }}) + +checkexp ("checked all", #parsed, index-1) + -- end of file