diff --git a/changelogs/fragments/win_copy-empty-dir.yaml b/changelogs/fragments/win_copy-empty-dir.yaml new file mode 100644 index 00000000000..dbc242d315a --- /dev/null +++ b/changelogs/fragments/win_copy-empty-dir.yaml @@ -0,0 +1,2 @@ +bugfixes: +- win_copy - Fix copy of a dir that contains an empty directory - https://github.com/ansible/ansible/issues/50077 diff --git a/lib/ansible/modules/windows/win_copy.ps1 b/lib/ansible/modules/windows/win_copy.ps1 index 12cfbc9515f..50ae1c61aae 100644 --- a/lib/ansible/modules/windows/win_copy.ps1 +++ b/lib/ansible/modules/windows/win_copy.ps1 @@ -127,13 +127,13 @@ Function Copy-Folder($source, $dest) { Function Get-FileSize($path) { $file = Get-Item -Path $path -Force - $size = $null if ($file.PSIsContainer) { $dir_files_sum = Get-ChildItem $file.FullName -Recurse - if ($dir_files_sum -eq $null -or ($dir_files_sum.PSObject.Properties.name -contains 'length' -eq $false)) { + $size = (Get-ChildItem -Path $file.FullName -Recurse -Force | ` + Where-Object { $_.PSObject.Properties.Name -contains 'Length' } | ` + Measure-Object -Property Length -Sum).Sum + if ($null -eq $size) { $size = 0 - } else { - $size = ($dir_files_sum | Measure-Object -property length -sum).Sum } } else { $size = $file.Length diff --git a/test/integration/targets/win_copy/tasks/remote_tests.yml b/test/integration/targets/win_copy/tasks/remote_tests.yml index cdbf2c5dbae..0a8d41e26c2 100644 --- a/test/integration/targets/win_copy/tasks/remote_tests.yml +++ b/test/integration/targets/win_copy/tasks/remote_tests.yml @@ -412,3 +412,60 @@ - remote_copy_folder_content_to_folder_after_change_actual.matched == 2 - remote_copy_folder_content_to_folder_after_change_actual.files[0].checksum == 'b54ba7f5621240d403f06815f7246006ef8c7d43' - remote_copy_folder_content_to_folder_after_change_actual.files[1].checksum == 'c79a6506c1c948be0d456ab5104d5e753ab2f3e6' + +# https://github.com/ansible/ansible/issues/50077 +- name: create empty nested directory + win_file: + path: '{{ test_win_copy_path }}\source\empty-nested\nested-dir' + state: directory + +- name: copy empty nested directory (check mode) + win_copy: + src: '{{ test_win_copy_path }}\source\empty-nested' + dest: '{{ test_win_copy_path }}\target' + remote_src: True + check_mode: True + register: copy_empty_dir_check + +- name: get result of copy empty nested directory (check mode) + win_stat: + path: '{{ test_win_copy_path }}\target\empty-nested' + register: copy_empty_dir_actual_check + +- name: assert copy empty nested directory (check mode) + assert: + that: + - copy_empty_dir_check is changed + - copy_empty_dir_check.operation == "folder_copy" + - not copy_empty_dir_actual_check.stat.exists + +- name: copy empty nested directory + win_copy: + src: '{{ test_win_copy_path }}\source\empty-nested' + dest: '{{ test_win_copy_path }}\target' + remote_src: True + register: copy_empty_dir + +- name: get result of copy empty nested directory + win_stat: + path: '{{ test_win_copy_path }}\target\empty-nested\nested-dir' + register: copy_empty_dir_actual + +- name: assert copy empty nested directory + assert: + that: + - copy_empty_dir is changed + - copy_empty_dir.operation == "folder_copy" + - copy_empty_dir_actual.stat.exists + +- name: copy empty nested directory (idempotent) + win_copy: + src: '{{ test_win_copy_path }}\source\empty-nested' + dest: '{{ test_win_copy_path }}\target' + remote_src: True + register: copy_empty_dir_again + +- name: assert copy empty nested directory (idempotent) + assert: + that: + - not copy_empty_dir_again is changed