Replace a list of directories, but only if they are empty

I have spend hours trying to solve this in a clear style, with no success.

I need to replace a few directories with a symbolic link to other
directories, but only when the first directories are empty. I have
managed to do that with a single directory combining registered
variables from "stat" and "find" modules, but I am not able to do it
when I have several directories and I try to do registered variables in
loops instead of separate tasks per directory.

This example removes directories and replaces them with symbolic links,
but it doesn't test for emptiness first, something I need because
ansible will happily delete a non-empty directory even with no
"force=yes" (sadly bitten by this earlier this morning):

"""
- name: Test directories
  stat: path=/var/spool/nullmailer/{{ item }}
  register: directories
  with_items:
    - queue
    - tmp

- name: Delete directories, if they are actual directories
  file: path=/var/spool/nullmailer/{{ item.item }} state=absent
  when: item.stat.isdir is defined and item.stat.isdir
  with_items: "{{ directories.results }}"

- name: Create symbolic links
  file: path=/var/spool/nullmailer/{{ item }}
        src=/home/nullmailer-spool/{{ item }}
        state=link
        mode=0700 owner=nullmail group=nullmail
  with_items:
    - queue
    - tmp
"""

Not tested, but you should be able test and create in one task.

- name: Create symbolic links
   file:
     path: /var/spool/nullmailer/{{ item.item }}
     src: /home/nullmailer-spool/{{ item.item }}
     state: link
     force: yes
   when: item.stat.isdir is defined and item.stat.isdir and item.stat.size == 0
   with_items: "{{ directories.results }}"

It doesn't work for two reasons:

1. item.stat.size meaning is nos portable between OS. In particular, an
empty directory in linux is 4096 bytes in size. On SmartOS, size seems
to be the number of files inside, so its value is "2" for an empty
directory ("." and ".." are always present).

2. Ansible doesn't allow to convert a directory to a symlink directly,
you seems to need to delete the directory first.

- name: Create symbolic links
  file:
    path: /var/spool/nullmailer/{{ item.item }}
    src: /home/nullmailer-spool/{{ item.item }}
    state: link
    force: yes
  when: item.stat.isdir is defined and item.stat.isdir and
item.stat.size == 0
  with_items: "{{ directories.results }}"

It doesn't work for two reasons:

1. item.stat.size meaning is nos portable between OS. In particular, an
empty directory in linux is 4096 bytes in size.

On the Linux distros I use, Debian, Centos, Redhat and Ubuntu, a empty directory is 0 in stat.

On SmartOS, size seems
to be the number of files inside, so its value is "2" for an empty
directory ("." and ".." are always present).

You can always add an exception on other OSes.
Or you would need to find something that work on all you OSes.

2. Ansible doesn't allow to convert a directory to a symlink directly,
you seems to need to delete the directory first.

With "force: yes" it will convert a empty directory, but not a non empty directory.

So you could drop "when:" and add a "ignore_errors: yes" instead but that doesn't look good in my opinion.