qpid-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From acon...@apache.org
Subject svn commit: r1649171 - in /qpid/dispatch/trunk: ./ doc/book/ doc/man/ python/qpid_dispatch/management/ python/qpid_dispatch_internal/management/ python/qpid_dispatch_internal/tools/ tools/
Date Sat, 03 Jan 2015 04:20:57 GMT
Author: aconway
Date: Sat Jan  3 04:20:56 2015
New Revision: 1649171

URL: http://svn.apache.org/r1649171
Log:
DISPATCH-26: Router documentation - man pages from markdown, included in book.

All documentation sources converted to markdown with pandoc extensions for
tables and definition lists. Documentation includes:

- doc/man: man pages for tools (qdrouterd, qdmanage, qdstat)
  - markdown source is combined with --help output for program options.
  - qdrouterd.conf man page, generated from qdrouter.json schema

- doc/book: qpid dispatch book, includes
  - markdown chapter source.
  - schema.md chapter generated from qdrouter.json schema
  - man pages

All markdown docs (source and generated) are installed in share/doc/qpid-dispatch.

If pandoc is available, generate proper man pages and install in share/man, and
Qpid Dispatch Book in HTML and PDF format, installed in share/doc/qpid-dispatch.

Added:
    qpid/dispatch/trunk/doc/book/schema_md.py
    qpid/dispatch/trunk/doc/man/help2md.py
    qpid/dispatch/trunk/doc/man/man.template.pd
    qpid/dispatch/trunk/doc/man/man2book.py
      - copied, changed from r1647662, qpid/dispatch/trunk/doc/man/help2man.py
    qpid/dispatch/trunk/doc/man/qdmanage.8.noopt.md.in
    qpid/dispatch/trunk/doc/man/qdrouterd.8.noopt.md.in
    qpid/dispatch/trunk/doc/man/qdstat.8.noopt.md.in
Removed:
    qpid/dispatch/trunk/doc/man/check_help2man.py
    qpid/dispatch/trunk/doc/man/help2man.py
    qpid/dispatch/trunk/doc/man/qdmanage.8.in
    qpid/dispatch/trunk/doc/man/qdmanage.h2m.in
    qpid/dispatch/trunk/doc/man/qdrouterd.8.in
    qpid/dispatch/trunk/doc/man/qdstat.8.in
    qpid/dispatch/trunk/doc/man/qdstat.h2m
    qpid/dispatch/trunk/doc/man/qdstat.h2m.in
Modified:
    qpid/dispatch/trunk/CMakeLists.txt
    qpid/dispatch/trunk/doc/book/CMakeLists.txt
    qpid/dispatch/trunk/doc/book/introduction.md
    qpid/dispatch/trunk/doc/man/CMakeLists.txt
    qpid/dispatch/trunk/doc/man/README
    qpid/dispatch/trunk/doc/man/qdrouterd_conf_man.py
    qpid/dispatch/trunk/python/qpid_dispatch/management/qdrouter.json
    qpid/dispatch/trunk/python/qpid_dispatch/management/qdrouter.json.readme.txt
    qpid/dispatch/trunk/python/qpid_dispatch_internal/management/schema.py
    qpid/dispatch/trunk/python/qpid_dispatch_internal/tools/command.py
    qpid/dispatch/trunk/run.py.in
    qpid/dispatch/trunk/tools/qdmanage

Modified: qpid/dispatch/trunk/CMakeLists.txt
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/CMakeLists.txt?rev=1649171&r1=1649170&r2=1649171&view=diff
==============================================================================
--- qpid/dispatch/trunk/CMakeLists.txt (original)
+++ qpid/dispatch/trunk/CMakeLists.txt Sat Jan  3 04:20:56 2015
@@ -142,4 +142,4 @@ execute_process(COMMAND ${RUN} --sh OUTP
 add_subdirectory(tests)
 add_subdirectory(python)
 add_subdirectory(router)
-add_subdirectory(doc) # doc last, may run executables via help2man
+add_subdirectory(doc) # doc last, runs executables for --help output.

Modified: qpid/dispatch/trunk/doc/book/CMakeLists.txt
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/doc/book/CMakeLists.txt?rev=1649171&r1=1649170&r2=1649171&view=diff
==============================================================================
--- qpid/dispatch/trunk/doc/book/CMakeLists.txt (original)
+++ qpid/dispatch/trunk/doc/book/CMakeLists.txt Sat Jan  3 04:20:56 2015
@@ -22,20 +22,35 @@
 
 find_program(PANDOC pandoc)
 
+set(src ${CMAKE_CURRENT_SOURCE_DIR})
+set(bin ${CMAKE_CURRENT_BINARY_DIR})
+
+# Generate the schema chapter of the book.
+set(schema, "${CMAKE_SOURCE_DIR}/python/qpid_router/management/qdrouterd.json")
+add_custom_command(
+  OUTPUT schema.md
+  COMMAND ${RUN} -s ${src}/schema_md.py > schema.md
+  DEPENDS ${src}/schema_md.py ${schema}
+  )
+
+set(BOOK ${src}/introduction.md ${src}/using.md ${src}/addressing.md ${src}/amqp-mapping.md ${bin}/schema.md ${CMAKE_BINARY_DIR}/doc/man/manpages.md)
+
+# Install markdown documentation in the doc directory.
+install(FILES ${BOOK} DESTINATION ${QD_DOC_INSTALL_DIR})
+
 if (PANDOC)
-  set(src ${CMAKE_CURRENT_SOURCE_DIR})
-  set(BOOK ${src}/introduction.md ${src}/using.md ${src}/addressing.md ${src}/amqp-mapping.md)
-  set(CMD pandoc -s -S --toc -f markdown)
+  set(CMD pandoc -s -S --toc -f markdown -V "title=Qpid Dispatch Router Book")
   set(BASE ${CMAKE_CURRENT_BINARY_DIR}/qpid-dispatch-book)
   set(HTML ${BASE}.html)
   set(PDF ${BASE}.pdf)
 
-  add_custom_command (
-      OUTPUT qpid-dispatch-book.html qpid-dispatch-book.pdf
-      COMMAND ${CMD} -f markdown -o ${HTML} ${BOOK}
-      COMMAND ${CMD} -f markdown -o ${PDF} ${BOOK}
-      DEPENDS ${program} ${BOOK}
-      )
+  # Generate HTML and PDF books
+  add_custom_command(
+    OUTPUT qpid-dispatch-book.html qpid-dispatch-book.pdf
+    COMMAND ${CMD} -f markdown -o ${HTML} ${BOOK}
+    COMMAND ${CMD} -f markdown -o ${PDF} ${BOOK}
+    DEPENDS man ${program} ${BOOK}
+    )
   add_custom_target(book ALL DEPENDS ${HTML} ${BOOK})
 
   install(FILES ${HTML} ${PDF} DESTINATION ${QD_DOC_INSTALL_DIR})

Modified: qpid/dispatch/trunk/doc/book/introduction.md
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/doc/book/introduction.md?rev=1649171&r1=1649170&r2=1649171&view=diff
==============================================================================
--- qpid/dispatch/trunk/doc/book/introduction.md (original)
+++ qpid/dispatch/trunk/doc/book/introduction.md Sat Jan  3 04:20:56 2015
@@ -17,7 +17,7 @@ specific language governing permissions
 under the License.
 -->
 
-# Dispatch Router
+# Introduction
 
 ## Overview
 

Added: qpid/dispatch/trunk/doc/book/schema_md.py
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/doc/book/schema_md.py?rev=1649171&view=auto
==============================================================================
--- qpid/dispatch/trunk/doc/book/schema_md.py (added)
+++ qpid/dispatch/trunk/doc/book/schema_md.py Sat Jan  3 04:20:56 2015
@@ -0,0 +1,116 @@
+##
+## Licensed to the Apache Software Foundation (ASF) under one
+## or more contributor license agreements.  See the NOTICE file
+## distributed with this work for additional information
+## regarding copyright ownership.  The ASF licenses this file
+## to you under the Apache License, Version 2.0 (the
+## "License"); you may not use this file except in compliance
+## with the License.  You may obtain a copy of the License at
+##
+##   http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing,
+## software distributed under the License is distributed on an
+## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+## KIND, either express or implied.  See the License for the
+## specific language governing permissions and limitations
+## under the License
+##
+
+"""
+Generate the schema.md makrdown documentation for management schema.
+"""
+
+import sys, re
+from pkgutil import get_data
+from qpid_dispatch_internal.management.qdrouter import QdSchema
+
+class SchemaWriter(object):
+    """Write the schema as a markdown document"""
+
+    def __init__(self, out):
+        self.out = out
+        self.schema = QdSchema()
+
+
+    def write(self, value):
+        self.out.write(value)
+
+    def warn(self, message):
+        print >>sys.stderr, message
+
+    def attribute(self, attr, thing):
+        default = attr.default
+        if isinstance(default, basestring) and default.startswith('$'):
+            default = None  # Don't show defaults that are references, confusing.
+        self.write('\n`%s` '%(attr.name))
+        self.write('(%s)\n'%(', '.join(
+            filter(None, [str(attr.atype),
+                          attr.required and "required",
+                          attr.unique and "unique",
+                          default and "default=%s"%default]))))
+        if attr.description:
+            self.write(":   %s\n"%attr.description)
+        else:
+            self.warn("Warning: No description for %s in %s" % (attr, thing.short_name))
+
+    def preface(self, thing):
+        self.write('\n### `%s`\n' % thing.short_name)
+        if thing.description:
+            self.write('\n%s\n' % thing.description)
+        else:
+            self.warn("Warning no description for %s" % thing)
+
+    def attributes(self, thing):
+        for attr in thing.my_attributes:
+            self.attribute(attr, thing)
+
+    def annotation(self, annotation):
+        self.preface(annotation)
+        used_by = ["`%s`" % e.short_name
+                   for e in self.schema.filter(lambda e: annotation in e.annotations)]
+        if used_by:
+            self.write('\nUsed by %s.\n'%(', '.join(used_by)))
+        self.attributes(annotation)
+
+    def summary(self, thing):
+        return "`%s` (%s)" % (thing.short_name, ", ".join("`%s`" % a for a in thing.attributes))
+
+    def entity_type(self, entity_type):
+        self.preface(entity_type)
+        if entity_type.base:
+            self.write('\nExtends: %s.\n' % self.summary(entity_type.base))
+        if entity_type.annotations:
+            self.write('\nAnnotations: %s.\n' % (
+                ', '.join([self.summary(a) for a in entity_type.annotations])))
+        self.attributes(entity_type)
+
+    def entity_types(self, base_name):
+        base = self.schema.entity_type(base_name)
+        self.entity_type(base)
+        for entity_type in self.schema.filter(lambda t: t.extends(base)):
+            self.entity_type(entity_type)
+
+    def run(self):
+        self.write(get_data('qpid_dispatch.management', 'qdrouter.json.readme.txt')) # Preface
+        self.write("The rest of this section provides the schema documentation in readable format.\n")
+
+        self.write("\n## Annotations\n")
+        for annotation in self.schema.annotations.itervalues():
+            self.annotation(annotation)
+
+        self.write("\n## Base Entity Type\n")
+        self.entity_type(self.schema.entity_type("entity"))
+
+        self.write("\n## Configuration Entities\n")
+        self.entity_types("configurationEntity")
+
+        self.write("\n## Operational Entities\n")
+        self.entity_types("operationalEntity")
+
+def main():
+    """Generate schema markdown documentation from L{QdSchema}"""
+    SchemaWriter(sys.stdout).run()
+
+if __name__ == '__main__':
+    main()

Modified: qpid/dispatch/trunk/doc/man/CMakeLists.txt
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/doc/man/CMakeLists.txt?rev=1649171&r1=1649170&r2=1649171&view=diff
==============================================================================
--- qpid/dispatch/trunk/doc/man/CMakeLists.txt (original)
+++ qpid/dispatch/trunk/doc/man/CMakeLists.txt Sat Jan  3 04:20:56 2015
@@ -17,57 +17,88 @@
 ## under the License.
 ##
 
+#
+# Generate man pages with pandoc.
+# Documentation source is in markdown, generate man pages.
+#
+
+find_program(PANDOC pandoc)
+
 set(src ${CMAKE_CURRENT_SOURCE_DIR})
 set(bin ${CMAKE_CURRENT_BINARY_DIR})
 set(tools ${CMAKE_SOURCE_DIR}/tools)
 
-find_program(HELP2MAN help2man)
-
-if(HELP2MAN)
-
-  macro(help2man manpage h2mfile program)
-    configure_file(${src}/${h2mfile}.in ${bin}/${h2mfile})
-    string(REGEX MATCH "[0-9]*$" section ${manpage})
+# Configure man page sources and combine with --help options output from programs.
+# Install markdown version of man pages in share/doc.
+macro(help2md program section path)
+  set(infile "${src}/${program}.${section}.noopt.md.in")
+  set(manpage "${bin}/${program}.${section}")
+  configure_file(${infile} "${manpage}.noopt.md")
+  add_custom_command (
+    OUTPUT ${manpage}.md
+    COMMAND ${RUN} -s "${src}/help2md.py" "${manpage}.noopt.md" "${manpage}.md" "${path}/${program}" --help
+    DEPENDS ${path}/${program} ${manpage}.noopt.md ${src}/help2md.py ${infile}
+    )
+  set(MANPAGES_MD ${MANPAGES_MD} ${manpage}.md)
+endmacro()
+
+# If pandoc is avaliable generate and install proper man files.
+macro(manpage program section)
+  set(manpage "${bin}/${program}.${section}")
+  string(TIMESTAMP date "%Y-%m-%d")
+  if(PANDOC)
+    if(${section} EQUAL 8)
+      set(header "System Manager's Manual")
+    elseif(${section} EQUAL 5)
+      set(header "File Formats Manual")
+    else()
+      set(header "")
+    endif()
     add_custom_command (
       OUTPUT ${manpage}
-      COMMAND ${RUN} -s ${src}/help2man.py ${HELP2MAN} -s ${section} -i ${bin}/${h2mfile} -N -o ${bin}/${manpage} ${program}
-      DEPENDS ${program} ${bin}/${h2mfile}
+      COMMAND ${PANDOC} --template ${src}/man.template.pd -s -V date="${date}" -V title="${program}" -V section="${section}" -V version="${QPID_DISPATCH_VERSION}" -V header="${header}" -f markdown -t man -o ${manpage} "${manpage}.md"
+      DEPENDS "${manpage}.md" "${src}/man.template.pd"
       )
-  endmacro()
-
-else(HELP2MAN)
-
-  message(WARNING "help2man is not avaliable, cannot update man pages")
-  macro(help2man manpage h2mfile program)
-    # Copy a pre-generated version of the man page.
-    configure_file(${src}/${manpage}.in ${bin}/${manpage})
-  endmacro()
-
-endif(HELP2MAN)
-
-configure_file(qdrouterd.8.in ${bin}/qdrouterd.8)
-help2man(qdstat.8 qdstat.h2m ${tools}/qdstat)
-help2man(qdmanage.8 qdmanage.h2m ${tools}/qdmanage)
+    set(MANPAGES ${MANPAGES} ${manpage})
+    install(FILES ${manpage} DESTINATION "${MAN_INSTALL_DIR}/man${section}")
+  else(PANDOC)
+    message(WARNING "pandoc is not avaliable, cannot generate ${manpage}")
+  endif(PANDOC)
+endmacro()
+
+# Shortcut to run both help2md and manpage
+macro(help2man program section path)
+  help2md(${program} ${section} ${path})
+  manpage(${program} ${section})
+endmacro()
+
+# Man pages for executables.
+help2man(qdrouterd 8 ${CMAKE_BINARY_DIR}/router)
+help2man(qdstat 8 ${tools})
+help2man(qdmanage 8 ${tools})
 
 # Generate a man page from the qdrouter.json schema.
-set (QDROUTER_CONF_MAN qdrouterd.conf.5)
+set(schema, "${CMAKE_SOURCE_DIR}/python/qpid_router/management/qdrouterd.json")
+set(qdrouterd_conf_man "${bin}/qdrouterd.conf.5")
+add_custom_command(
+  OUTPUT ${qdrouterd_conf_man}.md
+  COMMAND ${RUN} -s ${src}/qdrouterd_conf_man.py ${qdrouterd_conf_man}.md
+  DEPENDS ${src}/qdrouterd_conf_man.py ${schema}
+  )
+set(MANPAGES_MD ${MANPAGES_MD} ${qdrouterd_conf_man}.md)
+manpage(qdrouterd.conf 5)
+
+# Generate the man page section of the book
+
+add_custom_command(
+  OUTPUT manpages.md
+  COMMAND ${RUN} -s ${src}/man2book.py ${MANPAGES_MD} > manpages.md
+  DEPENDS ${src}/man2book.py ${MANPAGES_MD}
+  )
 
-file (GLOB_RECURSE QDROUTER_CONF_MAN_DEPENDS
-  ${src}/qdrouterd_conf_man.py
-  ${CMAKE_SOURCE_DIR}/python/qpid_router_internal/management/*.py
-  ${CMAKE_SOURCE_DIR}/python/qpid_router/management/qdrouterd.json)
-
-add_custom_command (OUTPUT ${QDROUTER_CONF_MAN}
-    COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_BINARY_DIR}/tests/run.py -s ${src}/qdrouterd_conf_man.py ${QDROUTER_CONF_MAN}
-    DEPENDS ${QDROUTER_CONF_MAN_DEPENDS})
+# Install all the markdown files
+install(FILES ${MANPAGES_MD} DESTINATION ${QD_DOC_INSTALL_DIR})
 
 # Target to build the generated files
-add_custom_target(man ALL DEPENDS ${QDROUTER_CONF_MAN} ${bin}/qdmanage.8 ${bin}/qdstat.8)
-# Manual target to check if the generated files differ from the checked-in files
-add_custom_target(check-man COMMAND ${RUN} -s ${src}/check_help2man.py ${src} ${bin} qdmanage.8 qdstat.8)
-
-# Install man pages
-install(FILES ${bin}/qdrouterd.8 DESTINATION ${MAN_INSTALL_DIR}/man8)
-install(FILES ${bin}/${QDROUTER_CONF_MAN} DESTINATION ${MAN_INSTALL_DIR}/man5)
-install(FILES ${bin}/qdstat.8 DESTINATION ${MAN_INSTALL_DIR}/man8)
-install(FILES ${bin}/qdmanage.8 DESTINATION ${MAN_INSTALL_DIR}/man8)
+add_custom_target(man ALL DEPENDS ${MANPAGES_MD} ${MANPAGES} manpages.md)
+

Modified: qpid/dispatch/trunk/doc/man/README
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/doc/man/README?rev=1649171&r1=1649170&r2=1649171&view=diff
==============================================================================
--- qpid/dispatch/trunk/doc/man/README (original)
+++ qpid/dispatch/trunk/doc/man/README Sat Jan  3 04:20:56 2015
@@ -1,43 +1,37 @@
-;;
-;; Licensed to the Apache Software Foundation (ASF) under one
-;; or more contributor license agreements.  See the NOTICE file
-;; distributed with this work for additional information
-;; regarding copyright ownership.  The ASF licenses this file
-;; to you under the Apache License, Version 2.0 (the
-;; "License"); you may not use this file except in compliance
-;; with the License.  You may obtain a copy of the License at
-;; 
-;;   http://www.apache.org/licenses/LICENSE-2.0
-;; 
-;; Unless required by applicable law or agreed to in writing,
-;; software distributed under the License is distributed on an
-;; "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-;; KIND, either express or implied.  See the License for the
-;; specific language governing permissions and limitations
-;; under the License.
-;;
+<!-*-markdown-*-
 
-# How man pages are generated.
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+nspecific language governing permissions and limitations
+under the License.
 
-Command line tools --help option provides a very brief usage and list of options.
+-->
 
-Man pages should be more detailed, but we do not want to repeat the information
-from --help as it will easily become out of date.
+# How man pages are generated.
 
-To solve this we generate man pages using the  help2man utility.
-For each tool there should be a tool.htm with extra details for the man page.
-help2man will combine this with the --help otuput of the tool to create the full man page.
+Man pages are generated from markdown sources.
 
-See the help2man macro in CMakeLists.txt and the help2man documentation for more details.
+Command line tools --help option provides a very brief usage and list of
+options.  Man pages should be more detailed, but we do not want to repeat the
+option information from --help as it will easily become out of date.
 
-For building distributions when help2man is not available, the generated man page for
-each tool is checked in as "tool.8.in".
+A small python script helt2md.py combines the manpage markdown source named
+*.noopt.md with the output of "program --help" into a single markdown file.
 
-Run "make check-man" to check if generated man pages are up to date with the
-checked-in versions.
+The final man page is generated from the markdown by pandoc.
 
-To update the man page you MUST use help2man, do not edit the checked in file
-as your edits will be lost.
 
 # A really quick guide to nroff and man-page macros
 

Added: qpid/dispatch/trunk/doc/man/help2md.py
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/doc/man/help2md.py?rev=1649171&view=auto
==============================================================================
--- qpid/dispatch/trunk/doc/man/help2md.py (added)
+++ qpid/dispatch/trunk/doc/man/help2md.py Sat Jan  3 04:20:56 2015
@@ -0,0 +1,66 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License
+#
+
+"""
+Generate markdown man pages by combining a markdown document with the
+the --help output of the program.
+
+Extract the options section of help output and convert to markdown format for
+inclusion in a man page. Replace the # Options section of the source document
+or append it at the end if there is no # Options section.
+"""
+
+import re, sys
+from subprocess import check_output, STDOUT
+from os import path
+
+def help2md(help_out):
+    VALUE = r"(?:[\w-]+|<[^>]+>)"
+    DEFAULT = r"(?: +\([^)]+\))?"
+    OPTION = r"-[\w-]+(?:[ =]%s)?%s" % (VALUE, DEFAULT) # -opt[(=| )value][(default)]
+    OPTIONS = r"%s(?:, *%s)*" % (OPTION, OPTION)        # opt[,opt...]
+    HELP = r"(?:[ \t]+\w.*$)|(?:(?:\n[ \t]+[^-\s].*$)+)" # same line or following lines indented.
+    OPT_HELP = r"^\s+(%s)(%s)" % (OPTIONS, HELP)
+    SUBHEAD = r"^((?: +\w+)*):$"
+
+    options = re.search("^Options:$", help_out, re.IGNORECASE | re.MULTILINE)
+    if (options): help_out = help_out[options.end():]
+    result = ""
+
+    result += "# Options\n\n"
+    for item in re.finditer(r"%s|%s" % (OPT_HELP, SUBHEAD), help_out, re.IGNORECASE | re.MULTILINE):
+        if item.group(3):
+            result += "## %s\n\n" % item.group(3).strip() # Sub-heading
+        else:
+            result += "%s\n:   %s\n\n" % (item.group(1), re.sub("\s+", " ", item.group(2)).strip())
+    return result
+
+usage = "Usage: %s manpage_in.md manpage_out.md program [help-args...]"
+
+def main(argv):
+    if len(argv) < 4: raise ValueError("Wrong number of arguments: "+usage)
+    source, target, program = argv[1], argv[2], argv[3:]
+    source_md = open(source).read()
+    options_md = help2md(check_output(program, stderr=STDOUT))
+    combine_md = re.sub(r"\n# Options.*?(?=(\n# |$))", options_md, source_md, flags=re.IGNORECASE | re.DOTALL)
+    upcase_md = re.sub(r"^#+ .*$", lambda m: m.group(0).upper(), combine_md, flags=re.MULTILINE)
+    open(target, "w").write(upcase_md)
+
+if __name__ == "__main__":
+    main(sys.argv)

Added: qpid/dispatch/trunk/doc/man/man.template.pd
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/doc/man/man.template.pd?rev=1649171&view=auto
==============================================================================
--- qpid/dispatch/trunk/doc/man/man.template.pd (added)
+++ qpid/dispatch/trunk/doc/man/man.template.pd Sat Jan  3 04:20:56 2015
@@ -0,0 +1,9 @@
+$if(has-tables)$
+.\"t
+$endif$
+.TH "$title$" "$section$" "$date$" "Qpid Dispatch $version$" "$header$"
+$body$
+.SH AUTHOR
+Apache Qpid <http://qpid.apache.org/>
+.SH COPYRIGHT
+Copyright 2013 The Apache Software Foundation

Copied: qpid/dispatch/trunk/doc/man/man2book.py (from r1647662, qpid/dispatch/trunk/doc/man/help2man.py)
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/doc/man/man2book.py?p2=qpid/dispatch/trunk/doc/man/man2book.py&p1=qpid/dispatch/trunk/doc/man/help2man.py&r1=1647662&r2=1649171&rev=1649171&view=diff
==============================================================================
--- qpid/dispatch/trunk/doc/man/help2man.py (original)
+++ qpid/dispatch/trunk/doc/man/man2book.py Sat Jan  3 04:20:56 2015
@@ -17,8 +17,16 @@
 # under the License
 #
 
-import sys, os
+"""
+Collect markdown man pages in a directory and generate chapters for the book.
+"""
 
-# Set COLUMNS env var to avoid line breaks in help output.
-os.environ['COLUMNS'] = '10000'
-os.execv(sys.argv[1], sys.argv[1:])
+import sys, re, string
+from os import path
+
+man_files = sys.argv[1:]
+assert man_files
+for f in man_files:
+    print "# Manual page %s" % path.splitext(path.basename(f))[0]
+    print re.sub("^#+ .*", lambda m: "#"+string.capwords(m.group(0)),
+                 open(f).read(), flags=re.MULTILINE)

Added: qpid/dispatch/trunk/doc/man/qdmanage.8.noopt.md.in
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/doc/man/qdmanage.8.noopt.md.in?rev=1649171&view=auto
==============================================================================
--- qpid/dispatch/trunk/doc/man/qdmanage.8.noopt.md.in (added)
+++ qpid/dispatch/trunk/doc/man/qdmanage.8.noopt.md.in Sat Jan  3 04:20:56 2015
@@ -0,0 +1,92 @@
+# Name
+
+qdmanage - A management tool for Dispatch routers.
+
+# Synopsis
+
+qdmanage *operation* [*options...*] [*arguments...*]
+
+# Description
+
+An AMQP management client for use with qdrouterd. Sends AMQP management
+operations requests and prints the response in JSON format.  This is a generic AMQP
+management tool and can be used with any standard AMQP managed endpoint, not just
+with qdrouter.
+
+# Operations
+
+`query` [*ATTR*...]
+:   Prints the named attributes of all entities. With no arguments prints all attributes.
+    The --type option restricts the result to entities extending the type.
+
+`create` [*ATTR=VALUE*...]
+:   Create a new entity with the specified attributes.
+    With the --stdin option, read attributes from stdin. This can be a JSON
+    map of attributes to create a single entity, or a JSON list of maps to create multiple entitiees.
+
+`read`
+:   Print the attributes of an entity specified by the --name or --identity options.
+    With the --stdin option, create entities based on data from stdin. This can be a JSON
+    map of attributes to create a single entity, or a JSON list of maps to create multiple entitiees.
+
+`update` [*ATTR=VALUE*...]
+:   Update the attributes of an existing entity.
+    With the --stdin option, read attributes from stdin. This can be a JSON
+    map of attributes to update a single entity, or a JSON list of maps to update multiple entitiees.
+    If an ATTR name is listed with no =VALUE, that attribute will be deleted from the entity.
+
+`delete`
+:    Delete an entity specified by the --name or --identity options.
+
+`get-types` [*TYPE*]
+:    List entity types with their base types. With no arguments list all types.
+
+`get-operations` [*TYPE*]
+:    List entity types with their operations. With no arguments list all types.
+
+`get-attributes` [*TYPE*]
+:    List entity types with their attributes.  With no arguments list all types.
+
+`get-annotations` [*TYPE*]
+:    List entity types with their annotations.  With no arguments list all types.
+
+`get-mgmt-nodes`
+:    List all other known management nodes connected to this one.
+
+# Options
+
+Run `qdmanage --help` to see options.
+
+# Files
+
+*${QPID_DISPATCH_CONFDIR}/qdrouter.json*
+:    Management schema for qdrouterd.
+*${QPID_DISPATCH_CONFDIR}/qdrouter.json.readme.txt*
+:    Explanation of the management schema.
+
+# Examples
+
+Show the logging configuration
+
+    qdmanage query --type=log
+
+Change the default log level to debug
+
+    qdmanage udpdate name=log/DEFAULT level=debug
+
+Change the MESSAGE log level to trace and direct MESSAGE logs to the file "test.log"
+
+    qdmanage udpdate name=log/MESSAGE level=trace output=test.log
+
+Set the MESSAGE log level back to the default (delete the log/MESSAGE level attribute)
+
+    qdmanage udpdate name=log/MESSAGE level
+
+# See also
+
+*qdrouterd*(8), *qdstat*(8), *qdrouterd.conf*(5)
+
+[http://qpid.apache.org/components/dispatch-router](http://qpid.apache.org/components/dispatch-router)
+
+
+

Added: qpid/dispatch/trunk/doc/man/qdrouterd.8.noopt.md.in
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/doc/man/qdrouterd.8.noopt.md.in?rev=1649171&view=auto
==============================================================================
--- qpid/dispatch/trunk/doc/man/qdrouterd.8.noopt.md.in (added)
+++ qpid/dispatch/trunk/doc/man/qdrouterd.8.noopt.md.in Sat Jan  3 04:20:56 2015
@@ -0,0 +1,45 @@
+<!-- -*- markdown -*-
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+  http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License
+-->
+
+# Name
+
+qdrouterd - AMQP message router.
+
+# Synopsis
+
+qdrouterd [*options*]
+
+# Description
+
+The Qpid Dispatch router (qdrouterd) is a network daemon that directs
+AMQP 1.0 messages between endpoints, such as messaging clients and
+servers.
+
+# Options
+
+Run `qdrouterd --help` to see options.
+
+# Files
+
+${QPID_DISPATCH_CONFDIR}/qdrouterd.conf
+:   Configuration flie.
+
+# See Also
+*qdrouterd.conf*(5), *qdstat*(8), *qdstat.conf*(5),
+
+[http://qpid.apache.org/components/dispatch-router](http://qpid.apache.org/components/dispatch-router)
+

Modified: qpid/dispatch/trunk/doc/man/qdrouterd_conf_man.py
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/doc/man/qdrouterd_conf_man.py?rev=1649171&r1=1649170&r2=1649171&view=diff
==============================================================================
--- qpid/dispatch/trunk/doc/man/qdrouterd_conf_man.py (original)
+++ qpid/dispatch/trunk/doc/man/qdrouterd_conf_man.py Sat Jan  3 04:20:56 2015
@@ -18,60 +18,33 @@
 ##
 
 """
-Generate the qdrouterd.conf man page from the qdrouterd management schema.
+Generate the qdrouterd.conf.md man page from the qdrouterd management schema.
 """
 
 import sys
 from qpid_dispatch_internal.management.qdrouter import QdSchema
 
-def make_man_page(filename):
-    """Generate a man page for the configuration file from L{QdSchema} descriptions"""
-    with open(filename, 'w') as f:
+PREFACE = r"""
+# Name
 
-        f.write(
-r""".\" -*- nroff -*-
-.\"
-.\" Licensed to the Apache Software Foundation (ASF) under one
-.\" or more contributor license agreements.  See the NOTICE file
-.\" distributed with this work for additional information
-.\" regarding copyright ownership.  The ASF licenses this file
-.\" to you under the Apache License, Version 2.0 (the
-.\" "License"); you may not use this file except in compliance
-.\" with the License.  You may obtain a copy of the License at
-.\"
-.\"   http://www.apache.org/licenses/LICENSE-2.0
-.\"
-.\" Unless required by applicable law or agreed to in writing,
-.\" software distributed under the License is distributed on an
-.\" "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-.\" KIND, either express or implied.  See the License for the
-.\" specific language governing permissions and limitations
-.\" under the License
-.\"
-.TH QDROUTERD.CONF 5
-.SH NAME
-qdrouterd.conf \- Configuration file for the Qpid Dispatch router
-.SH DESCRIPTION
+qdrouterd.conf - Configuration file for the Qpid Dispatch router
+
+# Description
 
 The configuration file is made up of sections with this syntax:
 
-.nf
-SECTION-NAME {
-    ATTRIBUTE-NAME: ATTRIBUTE-VALUE
-    ATTRIBUTE-NAME: ATTRIBUTE-VALUE
-    ...
-}
-.fi
+    SECTION-NAME {
+        ATTRIBUTE-NAME: ATTRIBUTE-VALUE
+        ATTRIBUTE-NAME: ATTRIBUTE-VALUE
+        ...
+    }
 
 There are two types of sections:
 
-Entity sections correspond to management entities. They can be queried and
-configured via management tools. By default each section is assigned a
-management name and identity of <section-name>-<n>. For example
-"listener-2". You can provide explicit name and identity attributes in any
-section.
+*Configuration sections* correspond to configuration entities. They can be queried and
+configured via management tools as well as via the configuration file.
 
-Annotation sections define a group of attribute values that can be included in
+*Annotation sections* define a group of attribute values that can be included in
 one or more entity sections.
 
 For example you can define an "ssl-profile" annotation section with SSL credentials
@@ -79,22 +52,27 @@ that can be included in multiple "listen
 how the 'ssl-profile' attribute of 'listener' sections references the 'name'
 attribute of 'ssl-profile' sections.
 
-.nf
-ssl-profile {
-    name: ssl-profile-one
-    cert-db: ca-certificate-1.pem
-    cert-file: server-certificate-1.pem
-    key-file: server-private-key.pem
-}
-
-listener {
-    ssl-profile: ssl-profile-one
-    addr: 0.0.0.0
-    port: 20102
-    sasl-mechanisms: ANONYMOUS
-}
-.fi
-""")
+    ssl-profile {
+        name: ssl-profile-one
+        cert-db: ca-certificate-1.pem
+        cert-file: server-certificate-1.pem
+        key-file: server-private-key.pem
+    }
+
+    listener {
+        ssl-profile: ssl-profile-one
+        addr: 0.0.0.0
+        port: 20102
+        sasl-mechanisms: ANONYMOUS
+    }
+"""
+
+def make_man_page(filename):
+    """Generate a man page for the configuration file from L{QdSchema} descriptions"""
+
+    with open(filename, 'w') as f:
+        f.write(PREFACE)
+
         schema = QdSchema()
 
         def write_attribute(attr, attrs):
@@ -107,14 +85,14 @@ listener {
             if isinstance(default, basestring) and default.startswith('$'):
                 default = None  # Don't show defaults that are references, confusing.
 
-            f.write('.IP %s\n'%(attr.name))
-            f.write('(%s)\n\n'%(', '.join(
+            f.write('\n%s '%(attr.name))
+            f.write('(%s)\n'%(', '.join(
                 filter(None, [str(attr.atype),
                               attr.required and "required",
                               attr.unique and "unique",
                               default and "default=%s"%default]))))
             if attr.description:
-                f.write("%s\n"%attr.description)
+                f.write(":   %s\n"%attr.description)
             else:
                 print "Warning no description for", attr, "in", attrs
 
@@ -127,22 +105,23 @@ listener {
                 write_attribute(attr, attrs)
             f.write('\n\n')
 
-        f.write(".SH ANNOTATION SECTIONS\n\n")
+        f.write("\n\n# Annotation Sections\n\n")
         for annotation in schema.annotations.itervalues():
-            used_by = [e.name for e in schema.entity_types.itervalues()
+            used_by = [e.short_name for e in schema.entity_types.itervalues()
                        if annotation in e.annotations]
-            f.write('.SS "%s"\n'%annotation.short_name)
+            f.write('\n\n## %s\n'%annotation.short_name)
             write_attributes(annotation)
-            f.write('.IP "Annotationd by %s."\n'%(', '.join(used_by)))
+            if used_by: f.write('Used by %s.\n'%(', '.join(used_by)))
 
-        f.write(".SH ENTITY SECTIONS\n\n")
+        f.write("\n\n# Configuration Sections\n\n")
         config = schema.entity_type("configurationEntity")
         for entity_type in schema.entity_types.itervalues():
             if config in entity_type.all_bases:
-                f.write('.SS "%s"\n'% entity_type.short_name)
+                f.write('\n## %s\n'% entity_type.short_name)
                 write_attributes(entity_type)
-                f.write('.IP "Annotations %s."\n'%(', '.join(
-                    [a.short_name for a in entity_type.annotations])))
+                if entity_type.annotations:
+                    f.write('Annotations %s.\n'%(', '.join(
+                        [a.short_name for a in entity_type.annotations])))
 
 
 if __name__ == '__main__':

Added: qpid/dispatch/trunk/doc/man/qdstat.8.noopt.md.in
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/doc/man/qdstat.8.noopt.md.in?rev=1649171&view=auto
==============================================================================
--- qpid/dispatch/trunk/doc/man/qdstat.8.noopt.md.in (added)
+++ qpid/dispatch/trunk/doc/man/qdstat.8.noopt.md.in Sat Jan  3 04:20:56 2015
@@ -0,0 +1,40 @@
+<!--*- markdown -*-
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+  http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License
+-->
+
+# Name
+
+qdstat - A tool to inspect Dispatch router networks
+
+# Synopsis
+
+qdrouterd [*options*]
+
+# Description
+
+*qdstat* shows status information about networks of Dispatch routers.
+It can display connections, network nodes and links, and router stats
+such as memory use.
+
+# Options
+
+Run `qdstat --help` to see options.
+
+# See also
+
+*qdrouterd* (8), *qdmanage* (8), *qdrouterd.conf* (5)
+
+[http://qpid.apache.org/components/dispatch-router](http://qpid.apache.org/components/dispatch-router)

Modified: qpid/dispatch/trunk/python/qpid_dispatch/management/qdrouter.json
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/python/qpid_dispatch/management/qdrouter.json?rev=1649171&r1=1649170&r2=1649171&view=diff
==============================================================================
--- qpid/dispatch/trunk/python/qpid_dispatch/management/qdrouter.json (original)
+++ qpid/dispatch/trunk/python/qpid_dispatch/management/qdrouter.json Sat Jan  3 04:20:56 2015
@@ -1,5 +1,5 @@
 {
-    "description":  "Schema for the Qpid Dispatch Router management model. See qdrouter.txt.",
+    "description":  "Schema for the Qpid Dispatch Router management model. See qdrouter.json.readme.txt.",
 
     "prefix": "org.apache.qpid.dispatch",
 

Modified: qpid/dispatch/trunk/python/qpid_dispatch/management/qdrouter.json.readme.txt
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/python/qpid_dispatch/management/qdrouter.json.readme.txt?rev=1649171&r1=1649170&r2=1649171&view=diff
==============================================================================
--- qpid/dispatch/trunk/python/qpid_dispatch/management/qdrouter.json.readme.txt (original)
+++ qpid/dispatch/trunk/python/qpid_dispatch/management/qdrouter.json.readme.txt Sat Jan  3 04:20:56 2015
@@ -1,27 +1,26 @@
-Informal desctription of the qdrouter.json schema.
-==================================================
+# The qdrouter management schema
 
-qdrouterd.json defines annotations and entity types of the Qpid Dispatch Router management model.
-The model is based on the AMQP management specification.
+The schema `qdrouterd.json` is a JSON format file that defines annotations and
+entity types of the Qpid Dispatch Router management model.  The model is based
+on the AMQP management specification.
 
 The schema is a JSON map with the following keys:
 
-- "description": documentation string
-- "prefix": attribute and annotation names in the schema are short form with no prefix. Names must be prepended with this prefix when they are exposed to outside AMQP management clients or agents.
-
-- "annotations": map of annotation names to definitions.
-- "entityTypes": map of entity type names to definitions.
+- "description": documentation string for the schema
+- "prefix": Prefix prepended to schema names when they are exposed to AMQP management clients.
+- "annotations": map of annotation names to definitions (see below)
+- "entityTypes": map of entity type names to definitions (see below)
 
 Annotation and entity type definition maps have the following keys:
 
 - "description": documentation string.
 - "operations": list of allowed operation names.
-- "attributes": map of attribute names to attribute definitions.
+- "attributes": map of attribute names to attribute definitions (see below)
 
 Entity type definitions also have these fields:
 
-- "extends": Name of base type, the new type includes all operations and attributes from the base type.
-- "annotations": List of annotation names. The new type includes all operations and attributes from all the annotations.
+- "extends": Name of base type. The new type includes operations and attributes from the base type.
+- "annotations": List of annotation names. The new type includes operations and attributes from all the annotations.
 
 Attribute definition maps have the following fields:
 
@@ -29,29 +28,26 @@ Attribute definition maps have the follo
   - "String": a unicode string value.
   - "Integer": an integer value.
   - "Boolean": a true/false value.
-  - [...]: a list of strings means an enumeration. Values must be one of the strings or an integer integer index into the list, starting from 0.
+  - [...]: A list of strings is an enumeration. Values must be one of the strings or an integer integer index into the list, starting from 0.
+- "default": a default can be a literal value or a reference to another attribute in the form `$attributeName`.
 
-- "default": a default value can be a literal value or a reference to another attribute in the form $attributeName.
+There is the following hierarchy among entity types:
 
+`entity`: The base of all entity types.
+- `configurationEntity`: base for all types that hold *configuration information*.
 
-There is the following hierarchy among entity types:
+  Configuration information is supplied in advance and expresse *intent*. For
+  example "I want the router to listen on port N". All the entities that can be
+  used in the configuration file extend `configurationEntity`.
+
+- `operationalEntity`: base for all types that hold *operational information*.
+
+  Operational information reflects the actual current state of the router.  For
+  example, "how many addresses are presently active?" All the entities queried
+  by the `qdstat` tool extend `operationalEntity`.
+
+The two types are often related. For example `listener` and `connector` extend
+`configurationEntity`, they express the intent to make or receive
+connections. `connection` extends `operationalEntity`, it holds information
+the actual connection status.
 
-"entity": the base of all entity types.
-- "configurationEntity": base for all types that hold configuration information.
-- "operationalEntity": base for all types that hold operational information.
-
-"Configuration" information is supplied in advance and expresse intent. For
-example "I want the router to listen on port N", or, "I want the router to
-connect to this address" All the entities that can be used in the configuration
-file are now "configurationEntity".
-
-"Operational" information reflects the actual state of the router at a given
-moment in time.  For example, "how many addresses are presently active on the
-router?" All the entities queried by qdstat are now "operationalEntity".
-
-The two types are often related, for example "I want an on-demand connection to
-this address" and "is there presently a live outgoing connection to this
-address?"  As a matter of good practice we separate the two kinds of
-entities. For example "listener" and "connector" are configuration entities
-expressing the intent to make or receive connectoins. The "connection" entity
-holds live operational information about an actual connection.

Modified: qpid/dispatch/trunk/python/qpid_dispatch_internal/management/schema.py
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/python/qpid_dispatch_internal/management/schema.py?rev=1649171&r1=1649170&r2=1649171&view=diff
==============================================================================
--- qpid/dispatch/trunk/python/qpid_dispatch_internal/management/schema.py (original)
+++ qpid/dispatch/trunk/python/qpid_dispatch_internal/management/schema.py Sat Jan  3 04:20:56 2015
@@ -1,4 +1,4 @@
-#
+##
 ## Licensed to the Apache Software Foundation (ASF) under one
 ## or more contributor license agreements.  See the NOTICE file
 ## distributed with this work for additional information
@@ -189,14 +189,16 @@ class AttributeType(object):
     @ivar unique: True if the attribute value is unique.
     @ivar description: Description of the attribute type.
     @ivar annotation: Annotation section or None
+    @ivar defined_in: Annotation or EntityType in which this attribute is defined.
     """
 
-    def __init__(self, name, type=None, default=None, required=False, unique=False,
+    def __init__(self, name, type=None, defined_in=None, default=None, required=False, unique=False,
                  value=None, annotation=None, description=""):
         """
         See L{AttributeType} instance variables.
         """
         self.name = name
+        self.defined_in = defined_in
         self.atype = get_type(type)
         self.required = required
         self.default = default
@@ -255,7 +257,7 @@ class AttributeType(object):
         ])
 
     def __str__(self):
-        return "%s(%s)"%(self.__class__.__name__, self.name)
+        return self.name
 
 
 class RedefinedError(ValueError): pass
@@ -279,7 +281,12 @@ class AttrsAndOps(object):
         for k, v in attributes.iteritems():
             if k in self.attributes:
                 raise ValidationError("Duplicate attribute in '%s': '%s'"%(self.name, k))
-            self.attributes[k] = AttributeType(k, **v)
+            self.attributes[k] = AttributeType(k, defined_in=self, **v)
+
+    @property
+    def my_attributes(self):
+        """Return only attribute types defined in this annotation or entity type"""
+        return [a for a in self.attributes.itervalues() if a.defined_in == self]
 
     def dump(self):
         """Json friendly representation"""
@@ -574,11 +581,17 @@ class Schema(object):
         """Convert a list of attribute maps into a list of L{SchemaEntity}"""
         return [self.entity(m) for m in attribute_maps]
 
+    def filter(self, predicate):
+        """Return an iterator over entity types that satisfy predicate."""
+        return (t for t in self.entity_types.itervalues() if predicate(t))
+
     def by_type(self, type):
         """Return an iterator over entity types that extend or are type.
         If type is None return all entities."""
-        return (t for t in self.entity_types.itervalues() if not type or t.is_a(type))
-
+        if not type:
+            return self.entity_types.itervalues()
+        else:
+            return self.filter(lambda t: t.is_a(type))
 
 class SchemaEntity(EntityBase):
     """A map of attributes associated with an L{EntityType}"""

Modified: qpid/dispatch/trunk/python/qpid_dispatch_internal/tools/command.py
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/python/qpid_dispatch_internal/tools/command.py?rev=1649171&r1=1649170&r2=1649171&view=diff
==============================================================================
--- qpid/dispatch/trunk/python/qpid_dispatch_internal/tools/command.py (original)
+++ qpid/dispatch/trunk/python/qpid_dispatch_internal/tools/command.py Sat Jan  3 04:20:56 2015
@@ -24,6 +24,7 @@ Utilities for command-line programs.
 import os, sys, json, optparse
 from collections import Sequence, Mapping
 from qpid_dispatch_site import VERSION
+from textwrap import fill
 
 class UsageError(Exception):
     """
@@ -103,5 +104,7 @@ class OptionParser(optparse.OptionParser
         def version_cb(*args):
             print VERSION
             exit(0)
-        self.add_option("--version", help="Print version and exit", action="callback", callback=version_cb)
+
+        self.add_option("--version", help="Print version and exit.",
+                        action="callback", callback=version_cb)
 

Modified: qpid/dispatch/trunk/run.py.in
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/run.py.in?rev=1649171&r1=1649170&r2=1649171&view=diff
==============================================================================
--- qpid/dispatch/trunk/run.py.in (original)
+++ qpid/dispatch/trunk/run.py.in Sat Jan  3 04:20:56 2015
@@ -53,6 +53,12 @@ sys.path = dedup([
     "${CMAKE_SOURCE_DIR}/tests"
 ] + sys.path)
 
+def getpath(env):
+    path = os.environ.get(env)
+    if path:
+        return path.split(os.pathsep)
+    return []
+
 env_vars = {
     'PYTHONPATH': os.pathsep.join(sys.path),
     'PATH': os.pathsep.join(dedup(["${CMAKE_BINARY_DIR}",
@@ -61,7 +67,9 @@ env_vars = {
                                    os.path.join("${CMAKE_SOURCE_DIR}", 'tools'),
                                    os.path.join("${CMAKE_BINARY_DIR}", 'tools'),
                                    os.path.join("${CMAKE_SOURCE_DIR}", 'bin')] +
-                                  os.environ['PATH'].split(os.pathsep))),
+                                  getpath('PATH'))),
+    'MANPATH' : os.pathsep.join([os.path.join("${CMAKE_BINARY_DIR}",'doc','man')] +
+                                getpath('MANPATH')),
     'SOURCE_DIR': "${CMAKE_SOURCE_DIR}",
     'BUILD_DIR': "${CMAKE_BINARY_DIR}",
     'QPID_DISPATCH_HOME': "${CMAKE_SOURCE_DIR}",

Modified: qpid/dispatch/trunk/tools/qdmanage
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/tools/qdmanage?rev=1649171&r1=1649170&r2=1649171&view=diff
==============================================================================
--- qpid/dispatch/trunk/tools/qdmanage (original)
+++ qpid/dispatch/trunk/tools/qdmanage Sat Jan  3 04:20:56 2015
@@ -40,12 +40,10 @@ class QdManage():
                            'get-types', 'get-operations', 'get-attributes', 'get-annotations',
                            'get-mgmt-nodes']
 
-        usage = "%prog <operation> [options...] [arguments...]\n\nOperations:"
-        for o in self.operations:
-            method = o.replace('-', '_')
-            usage += "\n  %s" % getattr(self.__class__, method).__doc__
+        usage = "%prog <operation> [options...] [arguments...]"
+        description = "Operations: "+", ".join(self.operations)
 
-        op = OptionParser(usage, option_class=Option)
+        op = OptionParser(usage=usage, option_class=Option, description=description)
         op.add_option('--type', help='Type of entity to operate on.')
         op.add_option('--name', help='Name of entity to operate on.')
         op.add_option('--identity', help='Identity of entity to operate on.', metavar="ID")
@@ -96,60 +94,60 @@ class QdManage():
             self.print_json(func(self.opts.attributes).attributes)
 
     def query(self):
-        """query [ATTR...]        - Print attributes of entities."""
+        """query [ATTR...]          Print attributes of entities."""
         if self.args:  self.opts.attribute_names = self.args
         result = self.call_node('query', 'type', 'attribute_names')
         self.print_json(result.get_dicts(clean=True))
 
     def create(self):
-        """create [ATTR=VALUE...] - Create a new entity."""
+        """create [ATTR=VALUE...]   Create a new entity."""
         if self.args:
             self.opts.attributes = dict(attr_split(arg) for arg in self.args)
         self.call_bulk(lambda attrs: self.call_node('create', 'type', 'name', attributes=attrs))
 
     def read(self):
-        """read                   - Print attributes of selected entity."""
+        """read                     Print attributes of selected entity."""
         check_args(self.args, 0)
         self.print_json(self.call_node('read', 'type', 'name', 'identity').attributes)
 
     def update(self):
-        """update [ATTR=VALUE...] - Update an entity."""
+        """update [ATTR=VALUE...]   Update an entity."""
         if self.args:
             self.opts.attributes = dict(attr_split(arg) for arg in self.args)
         self.call_bulk(
             lambda attrs: self.call_node('update', 'type', 'name', 'identity', attributes=attrs))
 
     def delete(self):
-        """delete                 - Delete an entity"""
+        """delete                   Delete an entity"""
         check_args(self.args, 0)
         self.call_node('delete', 'type', 'name', 'identity')
 
     def get_types(self):
-        """get-types [TYPE]       - List entity types with their base types."""
+        """get-types [TYPE]         List entity types with their base types."""
         check_args(self.args, 1)
         if self.args: self.opts.type = self.args[0]
         self.print_json(self.call_node('get_types', 'type'))
 
     def get_annotations(self):
-        """get-annotations [TYPE] - List entity types with the annotations they implement."""
+        """get-annotations [TYPE]   List entity types with the annotations they implement."""
         check_args(self.args, 1)
         if self.args: self.opts.type = self.args[0]
         self.print_json(self.call_node('get_annotations', 'type'))
 
     def get_attributes(self):
-        """get-attributes [TYPE]  - List entity types with their attributes."""
+        """get-attributes [TYPE]    List entity types with their attributes."""
         check_args(self.args, 1)
         if self.args: self.opts.type = self.args[0]
         self.print_json(self.call_node('get_attributes', 'type'))
 
     def get_operations(self):
-        """get-operations [TYPE]  - List entity types with their operations."""
+        """get-operations [TYPE]    List entity types with their operations."""
         check_args(self.args, 1)
         if self.args: self.opts.type = self.args[0]
         self.print_json(self.call_node('get_operations', 'type'))
 
     def get_mgmt_nodes(self):
-        """get-mgmt-nodes         - List of other known management nodes"""
+        """get-mgmt-nodes           List of other known management nodes"""
         check_args(self.args, 0)
         self.print_json(self.call_node('get_mgmt_nodes'))
 



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


Mime
View raw message