Issue 1:
ISSUE TYPE

Feature Idea

COMPONENT NAME

module lineinfile

ANSIBLE VERSION

2.3.0.0

---
- hosts: 127.0.0.1
tasks:
- name:
lineinfile:
dest: foo.txt
regexp: "msgid aaaa\nmsgstr bbbbb\n"
line: "msgid aaaa\nmsgstr bbbbb\n"

# echo > foo.txt
# ansible-playbook aa.yaml
# ansible-playbook aa.yaml
# ansible-playbook aa.yaml
# cat foo.txt
msgid aaaa
msgstr bbbbb

msgid aaaa
msgstr bbbbb

msgid aaaa
msgstr bbbbb

Issue 2:
ISSUE TYPE

Bug Report

COMPONENT NAME

Role dependencies

ANSIBLE VERSION

ansible 2.2.0.0
config file = /home/kyle/.ansible.cfg
configured module search path = Default w/o overrides

CONFIGURATION

[defaults]
inventory = ~/.ansible/hosts
ansible_managed = Managed by ansible. All changes will be overwritten
ssh_args = -o ControlMaster=auto -o ControlPersist=60s StrictHostKeyChecking=no
ask_vault_pass = yes
retry_files_enabled = False

OS / ENVIRONMENT

Debian Stretch and Debian Sid managing Debian Stretch

SUMMARY

I have roles: example_1, example_2, dependency_1 and dependency_2. dependency_1 is set to be duplicated (allow_duplicates: yes) and dependency_2 also depends on dependency_1.

When a playbook host has the roles example_1 and example_2 the following is executed:

dependency_1 (for dependency_2)

dependency_2 (for example_1)

dependency_1 (for example_1)

example_1

dependency_1 (for dependency_2)

dependency_1 (for example_2)

example_2

Step 5 is redundant and shouldn't run, as dependency_2 is only run once and its dependencies should only be run once.

STEPS TO REPRODUCE

./site.yml
---
- hosts: example.com
remote_user: user
roles:
- example_1
- example_2

./roles/example_{1,2}/meta/main.yml
---
dependencies:
- role: dependency_2
- role: dependency_1

./roles/dependency_1/meta/main.yml
---
allow_duplicates: yes

./roles/dependency_2/meta/main.yml
---
dependencies:
- role: dependency_1

./roles/{example_1,example_2,dependency_1,dependency_2}/tasks/main.yml
---
- name: display role
debug:
msg: this is role {{ role_path }}

EXPECTED RESULTS

$ ansible-playbook site.yml

PLAY [example.com] ***************************************************

TASK [setup] *******************************************************************
ok: [example.com]

TASK [dependency_1 : display role] *********************************************
ok: [example.com] => {
"msg": "this is role /home/user/ansible/roles/dependency_1"
}

TASK [dependency_2 : display role] *********************************************
ok: [example.com] => {
"msg": "this is role /home/user/ansible/roles/dependency_2"
}

TASK [dependency_1 : display role] *********************************************
ok: [example.com] => {
"msg": "this is role /home/user/ansible/roles/dependency_1"
}

TASK [example_1 : display role] ************************************************
ok: [example.com] => {
"msg": "this is role /home/user/ansible/roles/example_1"
}

TASK [dependency_1 : display role] *********************************************
ok: [example.com] => {
"msg": "this is role /home/user/ansible/roles/dependency_1"
}

TASK [example_2 : display role] ************************************************
ok: [example.com] => {
"msg": "this is role /home/kyle/user/ansible/roles/example_2"
}

PLAY RECAP *********************************************************************
example.com : ok=8 changed=0 unreachable=0 failed=0

ACTUAL RESULTS

$ ansible-playbook site.yml

PLAY [example.com] ***************************************************

TASK [setup] *******************************************************************
ok: [example.com]

TASK [dependency_1 : display role] *********************************************
ok: [example.com] => {
"msg": "this is role /home/user/ansible/roles/dependency_1"
}

TASK [dependency_2 : display role] *********************************************
ok: [example.com] => {
"msg": "this is role /home/user/ansible/roles/dependency_2"
}

TASK [dependency_1 : display role] *********************************************
ok: [example.com] => {
"msg": "this is role /home/user/ansible/roles/dependency_1"
}

TASK [example_1 : display role] ************************************************
ok: [example.com] => {
"msg": "this is role /home/user/ansible/roles/example_1"
}

TASK [dependency_1 : display role] *********************************************
ok: [example.com] => {
"msg": "this is role /home/user/ansible/roles/dependency_1"
}

TASK [dependency_1 : display role] *********************************************
ok: [example.com] => {
"msg": "this is role /home/user/ansible/roles/dependency_1"
}

TASK [example_2 : display role] ************************************************
ok: [example.com] => {
"msg": "this is role /home/kyle/user/ansible/roles/example_2"
}

PLAY RECAP *********************************************************************
example.com : ok=8 changed=0 unreachable=0 failed=0