ansible-collections / community.general

Ansible Community General Collection
https://galaxy.ansible.com/ui/repo/published/community/general/
GNU General Public License v3.0
823 stars 1.52k forks source link

Add new filters to calculate the union, intersection, difference and symmetric difference of lists by preserving the items order #7984

Open cfiehe opened 8 months ago

cfiehe commented 8 months ago

Summary

The behavioral change in the builtin filters ansible.builtin.union, ansible.builtin.intersect, ansible.builtin.difference and ansible.builtin.symmetric_difference introduced in Ansible Core 2.16 forces many people including myself to migrate their code in order to stay compatible with the current release: https://github.com/ansible/ansible/issues/82554

Starting from Ansible Core 2.16, the builtin filters do no longer preserve the item order, so that the result is unpredictable. This is unwanted in some cases. It is possible to workaround the problem e.g. by replacing a | union(b) with (a + b) | unique, but especially in complex statements where the union filter is involved and where ordering is important, you must have an eye on the operator precedencies. The whole code rewriting process is error-prone and statements become ugly and hard to read. In those cases, it would be nice to have replacing filters for the ansible.builtin.union, ansible.builtin.intersect, ansible.builtin.difference and ansible.builtin.symmetric_difference which behave in the same way as they did before Ansible Core 2.16.

Issue Type

Feature Idea

Component Name

lists_union, lists_intersect, lists_difference, symmetric_difference

Additional Information

---
- name: Filter test
  hosts: all
  become: true
  gather_facts: false
  vars:
    list1: [1, 2, 5, 3, 4, 10]
    list2: [1, 2, 3, 4, 5, 11, 99]
    list3: [1, 2, 3, 4, 5, 10, 99, 101]
  tasks:
    - name: Example for community.general.lists_union
      ansible.builtin.debug:
        msg: "{{ list1 | community.general.lists_union(list2, list3) }}"
    # => [1, 2, 5, 3, 4, 10, 11, 99, 101]

    - name: Example for community.general.lists_intersect
      ansible.builtin.debug:
        msg: "{{ list1 | community.general.lists_intersect(list2, list3) }}"
    # => [1, 2, 5, 3, 4]

    - name: Example for community.general.lists_difference
      ansible.builtin.debug:
        msg: "{{ list1 | community.general.lists_difference(list2, list3) }}"
    # => []

Code of Conduct

ansibullbot commented 8 months ago

Files identified in the description:

If these files are incorrect, please update the component name section of the description or use the !component bot command.

click here for bot help

ansibullbot commented 8 months ago

cc @hryamzik @obourdon click here for bot help

felixfontein commented 8 months ago

!component -plugins/modules/interfaces_file.py

felixfontein commented 8 months ago

Sounds like a good idea to me! Do you want to work on this, or are you hoping that someone else will do this?

cfiehe commented 8 months ago

I have created a feature pull request for those filters. I hope, that the code will pass the review 😃.

ansibullbot commented 8 months ago

Files identified in the description: None

If these files are incorrect, please update the component name section of the description or use the !component bot command.

click here for bot help