Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
ansible
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenEdx
ansible
Commits
38d20427
Commit
38d20427
authored
Apr 30, 2015
by
Brian Coca
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
v2 ansible-doc can now list modules
parent
df881b7f
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
203 additions
and
15 deletions
+203
-15
v2/ansible/cli/doc.py
+99
-15
v2/ansible/utils/module_docs.py
+102
-0
v2/ansible/utils/module_docs_fragments
+2
-0
No files found.
v2/ansible/cli/doc.py
View file @
38d20427
...
...
@@ -16,14 +16,19 @@
# ansible-vault is a script that encrypts/decrypts YAML files. See
# http://docs.ansible.com/playbooks_vault.html for more details.
import
fcntl
import
os
import
re
import
struct
import
sys
import
termios
import
traceback
from
ansible
import
constants
as
C
from
ansible.errors
import
AnsibleError
,
AnsibleOptionsError
from
ansible.plugins
import
module_loader
from
ansible.cli
import
CLI
#
from ansible.utils import module_docs
from
ansible.utils
import
module_docs
class
DocCLI
(
CLI
):
""" Vault command line class """
...
...
@@ -41,13 +46,16 @@ class DocCLI(CLI):
LESS_OPTS
=
'FRSX'
# -F (quit-if-one-screen) -R (allow raw ansi control chars)
# -S (chop long lines) -X (disable termcap init and de-init)
def
__init__
(
self
,
args
,
display
=
None
):
super
(
DocCLI
,
self
)
.
__init__
(
args
,
display
)
self
.
module_list
=
[]
def
parse
(
self
):
self
.
parser
=
optparse
.
OptionParser
(
version
=
version
(
"
%
prog"
),
self
.
parser
=
CLI
.
base_parser
(
usage
=
'usage:
%
prog [options] [module...]'
,
description
=
'Show Ansible module documentation'
,
epilog
=
'Show Ansible module documentation'
,
)
self
.
parser
.
add_option
(
"-M"
,
"--module-path"
,
action
=
"store"
,
dest
=
"module_path"
,
default
=
C
.
DEFAULT_MODULE_PATH
,
...
...
@@ -56,8 +64,6 @@ class DocCLI(CLI):
help
=
'List available modules'
)
self
.
parser
.
add_option
(
"-s"
,
"--snippet"
,
action
=
"store_true"
,
default
=
False
,
dest
=
'show_snippet'
,
help
=
'Show playbook snippet for specified module(s)'
)
self
.
parser
.
add_option
(
'-v'
,
action
=
'version'
,
help
=
'Show version number and exit'
)
self
.
options
,
self
.
args
=
self
.
parser
.
parse_args
()
self
.
display
.
verbosity
=
self
.
options
.
verbosity
...
...
@@ -65,19 +71,97 @@ class DocCLI(CLI):
def
run
(
self
):
if
options
.
module_path
is
not
None
:
for
i
in
options
.
module_path
.
split
(
os
.
pathsep
):
utils
.
plugins
.
module_fin
der
.
add_directory
(
i
)
if
self
.
options
.
module_path
is
not
None
:
for
i
in
self
.
options
.
module_path
.
split
(
os
.
pathsep
):
module_loa
der
.
add_directory
(
i
)
if
options
.
list_dir
:
if
self
.
options
.
list_dir
:
# list modules
paths
=
utils
.
plugins
.
module_finder
.
_get_paths
()
module_list
=
[]
paths
=
module_loader
.
_get_paths
()
for
path
in
paths
:
find_modules
(
path
,
module_list
)
self
.
find_modules
(
path
)
pager
(
get_module_list_text
(
module_list
))
#self.pager(get_module_list_text(module_list))
print
self
.
get_module_list_text
()
return
0
if
len
(
args
)
==
0
:
if
len
(
self
.
args
)
==
0
:
raise
AnsibleOptionsError
(
"Incorrect options passed"
)
def
find_modules
(
self
,
path
):
if
os
.
path
.
isdir
(
path
):
for
module
in
os
.
listdir
(
path
):
if
module
.
startswith
(
'.'
):
continue
elif
os
.
path
.
isdir
(
module
):
self
.
find_modules
(
module
)
elif
any
(
module
.
endswith
(
x
)
for
x
in
self
.
BLACKLIST_EXTS
):
continue
elif
module
.
startswith
(
'__'
):
continue
elif
module
in
self
.
IGNORE_FILES
:
continue
elif
module
.
startswith
(
'_'
):
fullpath
=
'/'
.
join
([
path
,
module
])
if
os
.
path
.
islink
(
fullpath
):
# avoids aliases
continue
module
=
os
.
path
.
splitext
(
module
)[
0
]
# removes the extension
self
.
module_list
.
append
(
module
)
def
get_module_list_text
(
self
):
tty_size
=
0
if
os
.
isatty
(
0
):
tty_size
=
struct
.
unpack
(
'HHHH'
,
fcntl
.
ioctl
(
0
,
termios
.
TIOCGWINSZ
,
struct
.
pack
(
'HHHH'
,
0
,
0
,
0
,
0
)))[
1
]
columns
=
max
(
60
,
tty_size
)
displace
=
max
(
len
(
x
)
for
x
in
self
.
module_list
)
linelimit
=
columns
-
displace
-
5
text
=
[]
deprecated
=
[]
for
module
in
sorted
(
set
(
self
.
module_list
)):
if
module
in
module_docs
.
BLACKLIST_MODULES
:
continue
filename
=
module_loader
.
find_plugin
(
module
)
if
filename
is
None
:
continue
if
filename
.
endswith
(
".ps1"
):
continue
if
os
.
path
.
isdir
(
filename
):
continue
try
:
doc
,
plainexamples
,
returndocs
=
module_docs
.
get_docstring
(
filename
)
desc
=
self
.
tty_ify
(
doc
.
get
(
'short_description'
,
'?'
))
.
strip
()
if
len
(
desc
)
>
linelimit
:
desc
=
desc
[:
linelimit
]
+
'...'
if
module
.
startswith
(
'_'
):
# Handle deprecated
deprecated
.
append
(
"
%-*
s
%-*.*
s"
%
(
displace
,
module
[
1
:],
linelimit
,
len
(
desc
),
desc
))
else
:
text
.
append
(
"
%-*
s
%-*.*
s"
%
(
displace
,
module
,
linelimit
,
len
(
desc
),
desc
))
except
:
traceback
.
print_exc
()
sys
.
stderr
.
write
(
"ERROR: module
%
s has a documentation error formatting or is missing documentation
\n
"
%
module
)
if
len
(
deprecated
)
>
0
:
text
.
append
(
"
\n
DEPRECATED:"
)
text
.
extend
(
deprecated
)
return
"
\n
"
.
join
(
text
)
@classmethod
def
tty_ify
(
self
,
text
):
t
=
self
.
_ITALIC
.
sub
(
"`"
+
r"\1"
+
"'"
,
text
)
# I(word) => `word'
t
=
self
.
_BOLD
.
sub
(
"*"
+
r"\1"
+
"*"
,
t
)
# B(word) => *word*
t
=
self
.
_MODULE
.
sub
(
"["
+
r"\1"
+
"]"
,
t
)
# M(word) => [word]
t
=
self
.
_URL
.
sub
(
r"\1"
,
t
)
# U(word) => word
t
=
self
.
_CONST
.
sub
(
"`"
+
r"\1"
+
"'"
,
t
)
# C(word) => `word'
return
t
v2/ansible/utils/module_docs.py
0 → 100644
View file @
38d20427
#!/usr/bin/env python
# (c) 2012, Jan-Piet Mens <jpmens () gmail.com>
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
#
import
os
import
sys
import
ast
import
yaml
import
traceback
from
ansible.plugins
import
fragment_loader
# modules that are ok that they do not have documentation strings
BLACKLIST_MODULES
=
[
'async_wrapper'
,
'accelerate'
,
'async_status'
]
def
get_docstring
(
filename
,
verbose
=
False
):
"""
Search for assignment of the DOCUMENTATION and EXAMPLES variables
in the given file.
Parse DOCUMENTATION from YAML and return the YAML doc or None
together with EXAMPLES, as plain text.
DOCUMENTATION can be extended using documentation fragments
loaded by the PluginLoader from the module_docs_fragments
directory.
"""
doc
=
None
plainexamples
=
None
returndocs
=
None
try
:
# Thank you, Habbie, for this bit of code :-)
M
=
ast
.
parse
(
''
.
join
(
open
(
filename
)))
for
child
in
M
.
body
:
if
isinstance
(
child
,
ast
.
Assign
):
if
'DOCUMENTATION'
in
(
t
.
id
for
t
in
child
.
targets
):
doc
=
yaml
.
safe_load
(
child
.
value
.
s
)
fragment_slug
=
doc
.
get
(
'extends_documentation_fragment'
,
'doesnotexist'
)
.
lower
()
# Allow the module to specify a var other than DOCUMENTATION
# to pull the fragment from, using dot notation as a separator
if
'.'
in
fragment_slug
:
fragment_name
,
fragment_var
=
fragment_slug
.
split
(
'.'
,
1
)
fragment_var
=
fragment_var
.
upper
()
else
:
fragment_name
,
fragment_var
=
fragment_slug
,
'DOCUMENTATION'
if
fragment_slug
!=
'doesnotexist'
:
fragment_class
=
fragment_loader
.
get
(
fragment_name
)
assert
fragment_class
is
not
None
fragment_yaml
=
getattr
(
fragment_class
,
fragment_var
,
'{}'
)
fragment
=
yaml
.
safe_load
(
fragment_yaml
)
if
fragment
.
has_key
(
'notes'
):
notes
=
fragment
.
pop
(
'notes'
)
if
notes
:
if
not
doc
.
has_key
(
'notes'
):
doc
[
'notes'
]
=
[]
doc
[
'notes'
]
.
extend
(
notes
)
if
'options'
not
in
fragment
.
keys
():
raise
Exception
(
"missing options in fragment, possibly misformatted?"
)
for
key
,
value
in
fragment
.
items
():
if
not
doc
.
has_key
(
key
):
doc
[
key
]
=
value
else
:
doc
[
key
]
.
update
(
value
)
if
'EXAMPLES'
in
(
t
.
id
for
t
in
child
.
targets
):
plainexamples
=
child
.
value
.
s
[
1
:]
# Skip first empty line
if
'RETURN'
in
(
t
.
id
for
t
in
child
.
targets
):
returndocs
=
child
.
value
.
s
[
1
:]
except
:
traceback
.
print_exc
()
# temp
if
verbose
==
True
:
traceback
.
print_exc
()
print
"unable to parse
%
s"
%
filename
return
doc
,
plainexamples
,
returndocs
v2/ansible/utils/module_docs_fragments
0 → 120000
View file @
38d20427
../../../lib/ansible/utils/module_docs_fragments
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment