Repository: ansible/ansible-lint

Issue:
includes not searched for in appropriate directories
I have role with a handler that includes a file:

```
- name: Demo
  include: uninstall.yml
  when: condition.matched
```

"uninstall.yml" is in <role>/tasks and this is what ansible seems to expect.

However, ansible-lint throws a stacktrace:

> Traceback (most recent call last):
>   File "/usr/bin/ansible-lint", line 116, in <module>
>     sys.exit(main(sys.argv[1:]))
>   File "/usr/bin/ansible-lint", line 103, in main
>     matches = runner.run()
>   File "/usr/lib/python2.6/site-packages/ansiblelint/**init**.py", line 211, in run
>     skip_list=set(self.skip_list)))
>   File "/usr/lib/python2.6/site-packages/ansiblelint/**init**.py", line 115, in run
>     with open(playbookfile['path'], 'Ur') as f:
> IOError: [Errno 2] No such file or directory: u'/home/<omitted>/roles/demo/handlers/uninstall.yml'

includes not searched for in appropriate directories
I have role with a handler that includes a file:

```
- name: Demo
  include: uninstall.yml
  when: condition.matched
```

"uninstall.yml" is in <role>/tasks and this is what ansible seems to expect.

However, ansible-lint throws a stacktrace:

> Traceback (most recent call last):
>   File "/usr/bin/ansible-lint", line 116, in <module>
>     sys.exit(main(sys.argv[1:]))
>   File "/usr/bin/ansible-lint", line 103, in main
>     matches = runner.run()
>   File "/usr/lib/python2.6/site-packages/ansiblelint/**init**.py", line 211, in run
>     skip_list=set(self.skip_list)))
>   File "/usr/lib/python2.6/site-packages/ansiblelint/**init**.py", line 115, in run
>     with open(playbookfile['path'], 'Ur') as f:
> IOError: [Errno 2] No such file or directory: u'/home/<omitted>/roles/demo/handlers/uninstall.yml'



Discussion:
Can you confirm `ansible-lint --version` and `ansible --version`

Ok, looks like including files in tasks from handlers is a new feature of ansible (a test playbook I wrote for this fails under 1.9 but not under 2.0). I typically use the Ansible libraries to look for includes in the right place but obviously I'm not quite modelling reality.

Can you confirm `ansible-lint --version` and `ansible --version`

Ok, looks like including files in tasks from handlers is a new feature of ansible (a test playbook I wrote for this fails under 1.9 but not under 2.0). I typically use the Ansible libraries to look for includes in the right place but obviously I'm not quite modelling reality.


Resolving patch:
diff --git a/lib/ansiblelint/utils.py b/lib/ansiblelint/utils.py
--- a/lib/ansiblelint/utils.py
+++ b/lib/ansiblelint/utils.py
@@ -154,7 +154,13 @@ def play_children(basedir, item, parent_type):
 
 
 def _include_children(basedir, k, v, parent_type):
-    return [{'path': path_dwim(basedir, v), 'type': parent_type}]
+    # handle include: filename.yml tags=blah
+    (command, args, kwargs) = tokenize("{0}: {1}".format(k,v))
+
+    result = path_dwim(basedir, args[0])
+    if not os.path.exists(result) and not basedir.endswith('tasks'):
+        result = path_dwim(os.path.join(basedir, '..', 'tasks'), v)
+    return [{'path': result, 'type': parent_type}]
 
 
 def _taskshandlers_children(basedir, k, v, parent_type):
@@ -271,7 +277,8 @@ def task_to_str(task):
     if name:
         return name
     action = task.get("action")
-    args = " ".join(["k=v" for (k, v) in action.items() if k != "module_arguments"] +
+    args = " ".join(["{0}={1}".format(k,v) for (k, v) in action.items()
+                    if k not in ["module", "module_arguments"]] +
                     action.get("module_arguments"))
     return "{0} {1}".format(action["module"], args)
 
diff --git a/lib/ansiblelint/version.py b/lib/ansiblelint/version.py
--- a/lib/ansiblelint/version.py
+++ b/lib/ansiblelint/version.py
@@ -1 +1 @@
-__version__ = '2.4.0'
+__version__ = '2.4.1'


Test patch: