- name: test with_first_found set_fact: "first_found={{ item }}" with_first_found: - "does_not_exist" - "foo1" - "{{ role_path + '/files/bar1' }}" # will only hit this if dwim search is broken - name: set expected set_fact: first_expected="{{ role_path + '/files/foo1' }}" - name: set unexpected set_fact: first_unexpected="{{ role_path + '/files/bar1' }}" - name: verify with_first_found results assert: that: - "first_found == first_expected" - "first_found != first_unexpected" - name: test q(first_found) with no files produces empty list set_fact: first_found_var: "{{ q('first_found', params, errors='ignore') }}" vars: params: files: "not_a_file.yaml" skip: True - name: verify q(first_found) result assert: that: - "first_found_var == []" - name: test lookup(first_found) with no files produces empty string set_fact: first_found_var: "{{ lookup('first_found', params, errors='ignore') }}" vars: params: files: "not_a_file.yaml" - name: verify lookup(first_found) result assert: that: - "first_found_var == ''" # NOTE: skip: True deprecated e17a2b502d6601be53c60d7ba1c627df419460c9, remove 2.12 - name: test first_found with no matches and skip=True does nothing set_fact: "this_not_set={{ item }}" vars: params: files: - not/a/file.yaml - another/non/file.yaml skip: True loop: "{{ q('first_found', params) }}" - name: verify skip assert: that: - "this_not_set is not defined" - name: test first_found with no matches and errors='ignore' skips in a loop set_fact: "this_not_set={{ item }}" vars: params: files: - not/a/file.yaml - another/non/file.yaml loop: "{{ query('first_found', params, errors='ignore') }}" - name: verify errors=ignore assert: that: - "this_not_set is not defined" - name: test legacy formats set_fact: hatethisformat={{item}} vars: params: files: not/a/file.yaml;hosts paths: not/a/path:/etc loop: "{{ q('first_found', params) }}" - name: verify /etc/hosts was found assert: that: - "hatethisformat == '/etc/hosts'" - name: test spaces in names include_vars: "{{ item }}" with_first_found: - files: - "{{ role_path + '/files/vars file spaces.yml' }}" - assert: that: - foo is defined # TODO: no 'terms' test - name: test first_found lookup with no terms set_fact: no_terms: "{{ query('first_found', files=['missing1', 'hosts', 'missing2'], paths=['/etc'], errors='ignore') }}" - assert: that: "no_terms|first == '/etc/hosts'" - name: handle templatable dictionary entries block: - name: Load variables specific for OS family assert: that: - "{{item|quote}} is file" - "{{item|basename == 'itworks.yml'}}" with_first_found: - files: - "{{ansible_id}}-{{ansible_lsb.major_release}}.yml" # invalid var, should be skipped - "{{ansible_lsb.id}}-{{ansible_lsb.major_release}}.yml" # does not exist, but should try - "{{ansible_distribution}}-{{ansible_distribution_major_version}}.yml" # does not exist, but should try - itworks.yml - ishouldnotbefound.yml # this exist, but should not be found paths: - "{{role_path}}/vars" - name: Load variables specific for OS family, but now as list of dicts, same options as above assert: that: - "{{item|quote}} is file" - "{{item|basename == 'itworks.yml'}}" with_first_found: - files: - "{{ansible_id}}-{{ansible_lsb.major_release}}.yml" paths: - "{{role_path}}/vars" - files: - "{{ansible_lsb.id}}-{{ansible_lsb.major_release}}.yml" paths: - "{{role_path}}/vars" - files: - "{{ansible_distribution}}-{{ansible_distribution_major_version}}.yml" paths: - "{{role_path}}/vars" - files: - itworks.yml paths: - "{{role_path}}/vars" - files: - ishouldnotbefound.yml paths: - "{{role_path}}/vars" - name: Make sure skip works in 'mixed' argument passing assert: that: - q('first_found', ['/nonexistant'], skip=True) == [] - name: Test relative paths in roles include_role: role: "{{ role_path }}/roles/a"