bee_python 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +202 -0
- data/build/README +23 -0
- data/egg/egg/build.yml +70 -0
- data/egg/egg/ez_setup.py +280 -0
- data/egg/egg/script.py +12 -0
- data/egg/egg/setup.erb +11 -0
- data/egg/egg/suite.py +37 -0
- data/egg/egg/test.py +31 -0
- data/egg/egg.yml +69 -0
- data/egg/http/build.erb +53 -0
- data/egg/http/server.py +34 -0
- data/egg/http.yml +50 -0
- data/egg/mysql/mysql.py +43 -0
- data/egg/mysql.yml +44 -0
- data/egg/project/build.erb +77 -0
- data/egg/project/script.py +42 -0
- data/egg/project/test.py +31 -0
- data/egg/project.yml +59 -0
- data/egg/script/build.erb +35 -0
- data/egg/script/script.py +42 -0
- data/egg/script.yml +50 -0
- data/egg/soap/build.erb +52 -0
- data/egg/soap/client.py +18 -0
- data/egg/soap/server.py +30 -0
- data/egg/soap.yml +58 -0
- data/egg/source/source.py +42 -0
- data/egg/source.yml +47 -0
- data/egg/test/test.py +28 -0
- data/egg/test.yml +44 -0
- data/egg/xmlrpc/build.erb +52 -0
- data/egg/xmlrpc/client.py +22 -0
- data/egg/xmlrpc/server.py +24 -0
- data/egg/xmlrpc.yml +51 -0
- data/lib/bee_task_python.rb +390 -0
- data/test/build.yml +16 -0
- data/test/tc_bee_task_python.rb +27 -0
- data/test/test_build.rb +26 -0
- data/test/test_build_listener.rb +62 -0
- data/test/ts_bee_python.rb +26 -0
- data/tools/common/__init__.py +5 -0
- data/tools/common/common/__init__.py +140 -0
- data/tools/common/common/__pkginfo__.py +43 -0
- data/tools/common/common/adbh.py +35 -0
- data/tools/common/common/cache.py +114 -0
- data/tools/common/common/changelog.py +234 -0
- data/tools/common/common/clcommands.py +181 -0
- data/tools/common/common/cli.py +212 -0
- data/tools/common/common/compat.py +328 -0
- data/tools/common/common/configuration.py +1087 -0
- data/tools/common/common/contexts.py +58 -0
- data/tools/common/common/corbautils.py +117 -0
- data/tools/common/common/daemon.py +171 -0
- data/tools/common/common/date.py +279 -0
- data/tools/common/common/db.py +49 -0
- data/tools/common/common/dbf.py +229 -0
- data/tools/common/common/debugger.py +208 -0
- data/tools/common/common/decorators.py +190 -0
- data/tools/common/common/deprecation.py +118 -0
- data/tools/common/common/fileutils.py +409 -0
- data/tools/common/common/graph.py +259 -0
- data/tools/common/common/html.py +142 -0
- data/tools/common/common/interface.py +76 -0
- data/tools/common/common/logging_ext.py +166 -0
- data/tools/common/common/modutils.py +670 -0
- data/tools/common/common/optik_ext.py +383 -0
- data/tools/common/common/optparser.py +92 -0
- data/tools/common/common/pdf_ext.py +111 -0
- data/tools/common/common/proc.py +276 -0
- data/tools/common/common/pyro_ext.py +146 -0
- data/tools/common/common/pytest.py +754 -0
- data/tools/common/common/shellutils.py +383 -0
- data/tools/common/common/sphinx_ext.py +87 -0
- data/tools/common/common/sphinxutils.py +122 -0
- data/tools/common/common/sqlgen.py +31 -0
- data/tools/common/common/table.py +930 -0
- data/tools/common/common/tasksqueue.py +97 -0
- data/tools/common/common/test/__init__.py +1 -0
- data/tools/common/common/test/data/ChangeLog +184 -0
- data/tools/common/common/test/data/MyPyPa-0.1.0-py2.5.egg +0 -0
- data/tools/common/common/test/data/__init__.py +1 -0
- data/tools/common/common/test/data/content_differ_dir/NOTHING +0 -0
- data/tools/common/common/test/data/content_differ_dir/README +1 -0
- data/tools/common/common/test/data/content_differ_dir/subdir/coin +1 -0
- data/tools/common/common/test/data/content_differ_dir/subdir/toto.txt +53 -0
- data/tools/common/common/test/data/file_differ_dir/NOTHING +0 -0
- data/tools/common/common/test/data/file_differ_dir/README +1 -0
- data/tools/common/common/test/data/file_differ_dir/subdir/toto.txt +53 -0
- data/tools/common/common/test/data/file_differ_dir/subdirtwo/Hello +0 -0
- data/tools/common/common/test/data/find_test/__init__.py +0 -0
- data/tools/common/common/test/data/find_test/foo.txt +0 -0
- data/tools/common/common/test/data/find_test/module.py +0 -0
- data/tools/common/common/test/data/find_test/module2.py +0 -0
- data/tools/common/common/test/data/find_test/newlines.txt +0 -0
- data/tools/common/common/test/data/find_test/noendingnewline.py +0 -0
- data/tools/common/common/test/data/find_test/nonregr.py +0 -0
- data/tools/common/common/test/data/find_test/normal_file.txt +0 -0
- data/tools/common/common/test/data/find_test/spam.txt +0 -0
- data/tools/common/common/test/data/find_test/sub/doc.txt +0 -0
- data/tools/common/common/test/data/find_test/sub/momo.py +0 -0
- data/tools/common/common/test/data/find_test/test.ini +0 -0
- data/tools/common/common/test/data/find_test/test1.msg +0 -0
- data/tools/common/common/test/data/find_test/test2.msg +0 -0
- data/tools/common/common/test/data/find_test/write_protected_file.txt +0 -0
- data/tools/common/common/test/data/foo.txt +9 -0
- data/tools/common/common/test/data/module.py +88 -0
- data/tools/common/common/test/data/module2.py +77 -0
- data/tools/common/common/test/data/newlines.txt +3 -0
- data/tools/common/common/test/data/noendingnewline.py +36 -0
- data/tools/common/common/test/data/nonregr.py +14 -0
- data/tools/common/common/test/data/normal_file.txt +0 -0
- data/tools/common/common/test/data/reference_dir/NOTHING +0 -0
- data/tools/common/common/test/data/reference_dir/README +1 -0
- data/tools/common/common/test/data/reference_dir/subdir/coin +1 -0
- data/tools/common/common/test/data/reference_dir/subdir/toto.txt +53 -0
- data/tools/common/common/test/data/same_dir/NOTHING +0 -0
- data/tools/common/common/test/data/same_dir/README +1 -0
- data/tools/common/common/test/data/same_dir/subdir/coin +1 -0
- data/tools/common/common/test/data/same_dir/subdir/toto.txt +53 -0
- data/tools/common/common/test/data/spam.txt +9 -0
- data/tools/common/common/test/data/sub/doc.txt +1 -0
- data/tools/common/common/test/data/sub/momo.py +1 -0
- data/tools/common/common/test/data/subdir_differ_dir/NOTHING +0 -0
- data/tools/common/common/test/data/subdir_differ_dir/README +1 -0
- data/tools/common/common/test/data/subdir_differ_dir/subdir/coin +1 -0
- data/tools/common/common/test/data/subdir_differ_dir/subdir/toto.txt +53 -0
- data/tools/common/common/test/data/test.ini +20 -0
- data/tools/common/common/test/data/test1.msg +30 -0
- data/tools/common/common/test/data/test2.msg +42 -0
- data/tools/common/common/test/data/write_protected_file.txt +0 -0
- data/tools/common/common/test/foomod.py +17 -0
- data/tools/common/common/test/unittest_cache.py +129 -0
- data/tools/common/common/test/unittest_changelog.py +37 -0
- data/tools/common/common/test/unittest_compat.py +239 -0
- data/tools/common/common/test/unittest_configuration.py +348 -0
- data/tools/common/common/test/unittest_date.py +154 -0
- data/tools/common/common/test/unittest_decorators.py +62 -0
- data/tools/common/common/test/unittest_deprecation.py +76 -0
- data/tools/common/common/test/unittest_fileutils.py +133 -0
- data/tools/common/common/test/unittest_graph.py +50 -0
- data/tools/common/common/test/unittest_html.py +76 -0
- data/tools/common/common/test/unittest_interface.py +87 -0
- data/tools/common/common/test/unittest_modutils.py +244 -0
- data/tools/common/common/test/unittest_pytest.py +50 -0
- data/tools/common/common/test/unittest_shellutils.py +248 -0
- data/tools/common/common/test/unittest_table.py +448 -0
- data/tools/common/common/test/unittest_taskqueue.py +71 -0
- data/tools/common/common/test/unittest_testlib.py +956 -0
- data/tools/common/common/test/unittest_textutils.py +247 -0
- data/tools/common/common/test/unittest_tree.py +248 -0
- data/tools/common/common/test/unittest_umessage.py +55 -0
- data/tools/common/common/test/unittest_ureports_html.py +64 -0
- data/tools/common/common/test/unittest_ureports_text.py +105 -0
- data/tools/common/common/test/unittest_xmlutils.py +75 -0
- data/tools/common/common/test/utils.py +87 -0
- data/tools/common/common/testlib.py +1927 -0
- data/tools/common/common/textutils.py +476 -0
- data/tools/common/common/tree.py +372 -0
- data/tools/common/common/umessage.py +161 -0
- data/tools/common/common/ureports/__init__.py +174 -0
- data/tools/common/common/ureports/docbook_writer.py +139 -0
- data/tools/common/common/ureports/html_writer.py +131 -0
- data/tools/common/common/ureports/nodes.py +201 -0
- data/tools/common/common/ureports/text_writer.py +140 -0
- data/tools/common/common/vcgutils.py +216 -0
- data/tools/common/common/visitor.py +107 -0
- data/tools/common/common/xmlrpcutils.py +136 -0
- data/tools/common/common/xmlutils.py +61 -0
- data/tools/compile/compile.py +16 -0
- data/tools/coverage/coverage.py +602 -0
- data/tools/epydoc/__init__.py +227 -0
- data/tools/epydoc/__init__.pyc +0 -0
- data/tools/epydoc/apidoc.py +2203 -0
- data/tools/epydoc/apidoc.pyc +0 -0
- data/tools/epydoc/checker.py +349 -0
- data/tools/epydoc/checker.pyc +0 -0
- data/tools/epydoc/cli.py +1470 -0
- data/tools/epydoc/cli.pyc +0 -0
- data/tools/epydoc/compat.py +250 -0
- data/tools/epydoc/compat.pyc +0 -0
- data/tools/epydoc/docbuilder.py +1358 -0
- data/tools/epydoc/docbuilder.pyc +0 -0
- data/tools/epydoc/docintrospecter.py +1056 -0
- data/tools/epydoc/docintrospecter.pyc +0 -0
- data/tools/epydoc/docparser.py +2113 -0
- data/tools/epydoc/docparser.pyc +0 -0
- data/tools/epydoc/docstringparser.py +1111 -0
- data/tools/epydoc/docstringparser.pyc +0 -0
- data/tools/epydoc/docwriter/__init__.py +12 -0
- data/tools/epydoc/docwriter/__init__.pyc +0 -0
- data/tools/epydoc/docwriter/dotgraph.py +1351 -0
- data/tools/epydoc/docwriter/dotgraph.pyc +0 -0
- data/tools/epydoc/docwriter/html.py +3491 -0
- data/tools/epydoc/docwriter/html.pyc +0 -0
- data/tools/epydoc/docwriter/html_colorize.py +909 -0
- data/tools/epydoc/docwriter/html_colorize.pyc +0 -0
- data/tools/epydoc/docwriter/html_css.py +550 -0
- data/tools/epydoc/docwriter/html_css.pyc +0 -0
- data/tools/epydoc/docwriter/html_help.py +190 -0
- data/tools/epydoc/docwriter/html_help.pyc +0 -0
- data/tools/epydoc/docwriter/latex.py +1187 -0
- data/tools/epydoc/docwriter/latex.pyc +0 -0
- data/tools/epydoc/docwriter/plaintext.py +276 -0
- data/tools/epydoc/docwriter/plaintext.pyc +0 -0
- data/tools/epydoc/docwriter/xlink.py +505 -0
- data/tools/epydoc/docwriter/xlink.pyc +0 -0
- data/tools/epydoc/gui.py +1148 -0
- data/tools/epydoc/gui.pyc +0 -0
- data/tools/epydoc/log.py +204 -0
- data/tools/epydoc/log.pyc +0 -0
- data/tools/epydoc/markup/__init__.py +623 -0
- data/tools/epydoc/markup/__init__.pyc +0 -0
- data/tools/epydoc/markup/doctest.py +311 -0
- data/tools/epydoc/markup/doctest.pyc +0 -0
- data/tools/epydoc/markup/epytext.py +2116 -0
- data/tools/epydoc/markup/epytext.pyc +0 -0
- data/tools/epydoc/markup/javadoc.py +250 -0
- data/tools/epydoc/markup/javadoc.pyc +0 -0
- data/tools/epydoc/markup/plaintext.py +78 -0
- data/tools/epydoc/markup/plaintext.pyc +0 -0
- data/tools/epydoc/markup/pyval_repr.py +532 -0
- data/tools/epydoc/markup/pyval_repr.pyc +0 -0
- data/tools/epydoc/markup/restructuredtext.py +906 -0
- data/tools/epydoc/markup/restructuredtext.pyc +0 -0
- data/tools/epydoc/test/__init__.py +97 -0
- data/tools/epydoc/test/__init__.pyc +0 -0
- data/tools/epydoc/test/util.py +226 -0
- data/tools/epydoc/test/util.pyc +0 -0
- data/tools/epydoc/util.py +289 -0
- data/tools/epydoc/util.pyc +0 -0
- data/tools/logilab/logilab/__init__.py +5 -0
- data/tools/logilab/logilab/astng/__init__.py +82 -0
- data/tools/logilab/logilab/astng/__pkginfo__.py +76 -0
- data/tools/logilab/logilab/astng/_exceptions.py +64 -0
- data/tools/logilab/logilab/astng/_nodes_ast.py +667 -0
- data/tools/logilab/logilab/astng/_nodes_compiler.py +758 -0
- data/tools/logilab/logilab/astng/bases.py +608 -0
- data/tools/logilab/logilab/astng/builder.py +239 -0
- data/tools/logilab/logilab/astng/inference.py +426 -0
- data/tools/logilab/logilab/astng/inspector.py +289 -0
- data/tools/logilab/logilab/astng/manager.py +421 -0
- data/tools/logilab/logilab/astng/mixins.py +165 -0
- data/tools/logilab/logilab/astng/node_classes.py +848 -0
- data/tools/logilab/logilab/astng/nodes.py +85 -0
- data/tools/logilab/logilab/astng/nodes_as_string.py +389 -0
- data/tools/logilab/logilab/astng/patchcomptransformer.py +159 -0
- data/tools/logilab/logilab/astng/protocols.py +333 -0
- data/tools/logilab/logilab/astng/raw_building.py +212 -0
- data/tools/logilab/logilab/astng/rebuilder.py +307 -0
- data/tools/logilab/logilab/astng/scoped_nodes.py +951 -0
- data/tools/logilab/logilab/astng/test/__init__.py +19 -0
- data/tools/logilab/logilab/astng/test/data/MyPyPa-0.1.0-py2.5.egg +0 -0
- data/tools/logilab/logilab/astng/test/data/MyPyPa-0.1.0-py2.5.zip +0 -0
- data/tools/logilab/logilab/astng/test/data/SSL1/Connection1.py +33 -0
- data/tools/logilab/logilab/astng/test/data/SSL1/__init__.py +20 -0
- data/tools/logilab/logilab/astng/test/data/__init__.py +20 -0
- data/tools/logilab/logilab/astng/test/data/all.py +29 -0
- data/tools/logilab/logilab/astng/test/data/appl/__init__.py +23 -0
- data/tools/logilab/logilab/astng/test/data/appl/myConnection.py +30 -0
- data/tools/logilab/logilab/astng/test/data/format.py +34 -0
- data/tools/logilab/logilab/astng/test/data/module.py +90 -0
- data/tools/logilab/logilab/astng/test/data/module2.py +112 -0
- data/tools/logilab/logilab/astng/test/data/noendingnewline.py +57 -0
- data/tools/logilab/logilab/astng/test/data/nonregr.py +76 -0
- data/tools/logilab/logilab/astng/test/data/notall.py +28 -0
- data/tools/logilab/logilab/astng/test/data2/__init__.py +20 -0
- data/tools/logilab/logilab/astng/test/data2/clientmodule_test.py +51 -0
- data/tools/logilab/logilab/astng/test/data2/suppliermodule_test.py +32 -0
- data/tools/logilab/logilab/astng/test/regrtest.py +135 -0
- data/tools/logilab/logilab/astng/test/regrtest_data/absimport.py +22 -0
- data/tools/logilab/logilab/astng/test/regrtest_data/descriptor_crash.py +31 -0
- data/tools/logilab/logilab/astng/test/regrtest_data/import_package_subpackage_module.py +68 -0
- data/tools/logilab/logilab/astng/test/regrtest_data/package/__init__.py +24 -0
- data/tools/logilab/logilab/astng/test/regrtest_data/package/subpackage/__init__.py +20 -0
- data/tools/logilab/logilab/astng/test/regrtest_data/package/subpackage/module.py +20 -0
- data/tools/logilab/logilab/astng/test/unittest_builder.py +684 -0
- data/tools/logilab/logilab/astng/test/unittest_inference.py +1112 -0
- data/tools/logilab/logilab/astng/test/unittest_inspector.py +105 -0
- data/tools/logilab/logilab/astng/test/unittest_lookup.py +302 -0
- data/tools/logilab/logilab/astng/test/unittest_manager.py +98 -0
- data/tools/logilab/logilab/astng/test/unittest_nodes.py +302 -0
- data/tools/logilab/logilab/astng/test/unittest_scoped_nodes.py +501 -0
- data/tools/logilab/logilab/astng/test/unittest_utils.py +104 -0
- data/tools/logilab/logilab/astng/utils.py +342 -0
- data/tools/logilab/logilab/common/__init__.py +140 -0
- data/tools/logilab/logilab/common/__pkginfo__.py +43 -0
- data/tools/logilab/logilab/common/adbh.py +35 -0
- data/tools/logilab/logilab/common/cache.py +114 -0
- data/tools/logilab/logilab/common/changelog.py +234 -0
- data/tools/logilab/logilab/common/clcommands.py +181 -0
- data/tools/logilab/logilab/common/cli.py +212 -0
- data/tools/logilab/logilab/common/compat.py +328 -0
- data/tools/logilab/logilab/common/configuration.py +1087 -0
- data/tools/logilab/logilab/common/contexts.py +58 -0
- data/tools/logilab/logilab/common/corbautils.py +117 -0
- data/tools/logilab/logilab/common/daemon.py +171 -0
- data/tools/logilab/logilab/common/date.py +279 -0
- data/tools/logilab/logilab/common/db.py +49 -0
- data/tools/logilab/logilab/common/dbf.py +229 -0
- data/tools/logilab/logilab/common/debugger.py +208 -0
- data/tools/logilab/logilab/common/decorators.py +190 -0
- data/tools/logilab/logilab/common/deprecation.py +118 -0
- data/tools/logilab/logilab/common/fileutils.py +409 -0
- data/tools/logilab/logilab/common/graph.py +259 -0
- data/tools/logilab/logilab/common/html.py +142 -0
- data/tools/logilab/logilab/common/interface.py +76 -0
- data/tools/logilab/logilab/common/logging_ext.py +166 -0
- data/tools/logilab/logilab/common/modutils.py +670 -0
- data/tools/logilab/logilab/common/optik_ext.py +383 -0
- data/tools/logilab/logilab/common/optparser.py +92 -0
- data/tools/logilab/logilab/common/pdf_ext.py +111 -0
- data/tools/logilab/logilab/common/proc.py +276 -0
- data/tools/logilab/logilab/common/pyro_ext.py +146 -0
- data/tools/logilab/logilab/common/pytest.py +754 -0
- data/tools/logilab/logilab/common/shellutils.py +383 -0
- data/tools/logilab/logilab/common/sphinx_ext.py +87 -0
- data/tools/logilab/logilab/common/sphinxutils.py +122 -0
- data/tools/logilab/logilab/common/sqlgen.py +31 -0
- data/tools/logilab/logilab/common/table.py +930 -0
- data/tools/logilab/logilab/common/tasksqueue.py +97 -0
- data/tools/logilab/logilab/common/test/__init__.py +1 -0
- data/tools/logilab/logilab/common/test/data/ChangeLog +184 -0
- data/tools/logilab/logilab/common/test/data/MyPyPa-0.1.0-py2.5.egg +0 -0
- data/tools/logilab/logilab/common/test/data/__init__.py +1 -0
- data/tools/logilab/logilab/common/test/data/content_differ_dir/NOTHING +0 -0
- data/tools/logilab/logilab/common/test/data/content_differ_dir/README +1 -0
- data/tools/logilab/logilab/common/test/data/content_differ_dir/subdir/coin +1 -0
- data/tools/logilab/logilab/common/test/data/content_differ_dir/subdir/toto.txt +53 -0
- data/tools/logilab/logilab/common/test/data/file_differ_dir/NOTHING +0 -0
- data/tools/logilab/logilab/common/test/data/file_differ_dir/README +1 -0
- data/tools/logilab/logilab/common/test/data/file_differ_dir/subdir/toto.txt +53 -0
- data/tools/logilab/logilab/common/test/data/file_differ_dir/subdirtwo/Hello +0 -0
- data/tools/logilab/logilab/common/test/data/find_test/__init__.py +0 -0
- data/tools/logilab/logilab/common/test/data/find_test/foo.txt +0 -0
- data/tools/logilab/logilab/common/test/data/find_test/module.py +0 -0
- data/tools/logilab/logilab/common/test/data/find_test/module2.py +0 -0
- data/tools/logilab/logilab/common/test/data/find_test/newlines.txt +0 -0
- data/tools/logilab/logilab/common/test/data/find_test/noendingnewline.py +0 -0
- data/tools/logilab/logilab/common/test/data/find_test/nonregr.py +0 -0
- data/tools/logilab/logilab/common/test/data/find_test/normal_file.txt +0 -0
- data/tools/logilab/logilab/common/test/data/find_test/spam.txt +0 -0
- data/tools/logilab/logilab/common/test/data/find_test/sub/doc.txt +0 -0
- data/tools/logilab/logilab/common/test/data/find_test/sub/momo.py +0 -0
- data/tools/logilab/logilab/common/test/data/find_test/test.ini +0 -0
- data/tools/logilab/logilab/common/test/data/find_test/test1.msg +0 -0
- data/tools/logilab/logilab/common/test/data/find_test/test2.msg +0 -0
- data/tools/logilab/logilab/common/test/data/find_test/write_protected_file.txt +0 -0
- data/tools/logilab/logilab/common/test/data/foo.txt +9 -0
- data/tools/logilab/logilab/common/test/data/module.py +88 -0
- data/tools/logilab/logilab/common/test/data/module2.py +77 -0
- data/tools/logilab/logilab/common/test/data/newlines.txt +3 -0
- data/tools/logilab/logilab/common/test/data/noendingnewline.py +36 -0
- data/tools/logilab/logilab/common/test/data/nonregr.py +14 -0
- data/tools/logilab/logilab/common/test/data/normal_file.txt +0 -0
- data/tools/logilab/logilab/common/test/data/reference_dir/NOTHING +0 -0
- data/tools/logilab/logilab/common/test/data/reference_dir/README +1 -0
- data/tools/logilab/logilab/common/test/data/reference_dir/subdir/coin +1 -0
- data/tools/logilab/logilab/common/test/data/reference_dir/subdir/toto.txt +53 -0
- data/tools/logilab/logilab/common/test/data/same_dir/NOTHING +0 -0
- data/tools/logilab/logilab/common/test/data/same_dir/README +1 -0
- data/tools/logilab/logilab/common/test/data/same_dir/subdir/coin +1 -0
- data/tools/logilab/logilab/common/test/data/same_dir/subdir/toto.txt +53 -0
- data/tools/logilab/logilab/common/test/data/spam.txt +9 -0
- data/tools/logilab/logilab/common/test/data/sub/doc.txt +1 -0
- data/tools/logilab/logilab/common/test/data/sub/momo.py +1 -0
- data/tools/logilab/logilab/common/test/data/subdir_differ_dir/NOTHING +0 -0
- data/tools/logilab/logilab/common/test/data/subdir_differ_dir/README +1 -0
- data/tools/logilab/logilab/common/test/data/subdir_differ_dir/subdir/coin +1 -0
- data/tools/logilab/logilab/common/test/data/subdir_differ_dir/subdir/toto.txt +53 -0
- data/tools/logilab/logilab/common/test/data/test.ini +20 -0
- data/tools/logilab/logilab/common/test/data/test1.msg +30 -0
- data/tools/logilab/logilab/common/test/data/test2.msg +42 -0
- data/tools/logilab/logilab/common/test/data/write_protected_file.txt +0 -0
- data/tools/logilab/logilab/common/test/foomod.py +17 -0
- data/tools/logilab/logilab/common/test/unittest_cache.py +129 -0
- data/tools/logilab/logilab/common/test/unittest_changelog.py +37 -0
- data/tools/logilab/logilab/common/test/unittest_compat.py +239 -0
- data/tools/logilab/logilab/common/test/unittest_configuration.py +348 -0
- data/tools/logilab/logilab/common/test/unittest_date.py +154 -0
- data/tools/logilab/logilab/common/test/unittest_decorators.py +62 -0
- data/tools/logilab/logilab/common/test/unittest_deprecation.py +76 -0
- data/tools/logilab/logilab/common/test/unittest_fileutils.py +133 -0
- data/tools/logilab/logilab/common/test/unittest_graph.py +50 -0
- data/tools/logilab/logilab/common/test/unittest_html.py +76 -0
- data/tools/logilab/logilab/common/test/unittest_interface.py +87 -0
- data/tools/logilab/logilab/common/test/unittest_modutils.py +244 -0
- data/tools/logilab/logilab/common/test/unittest_pytest.py +50 -0
- data/tools/logilab/logilab/common/test/unittest_shellutils.py +248 -0
- data/tools/logilab/logilab/common/test/unittest_table.py +448 -0
- data/tools/logilab/logilab/common/test/unittest_taskqueue.py +71 -0
- data/tools/logilab/logilab/common/test/unittest_testlib.py +956 -0
- data/tools/logilab/logilab/common/test/unittest_textutils.py +247 -0
- data/tools/logilab/logilab/common/test/unittest_tree.py +248 -0
- data/tools/logilab/logilab/common/test/unittest_umessage.py +55 -0
- data/tools/logilab/logilab/common/test/unittest_ureports_html.py +64 -0
- data/tools/logilab/logilab/common/test/unittest_ureports_text.py +105 -0
- data/tools/logilab/logilab/common/test/unittest_xmlutils.py +75 -0
- data/tools/logilab/logilab/common/test/utils.py +87 -0
- data/tools/logilab/logilab/common/testlib.py +1927 -0
- data/tools/logilab/logilab/common/textutils.py +476 -0
- data/tools/logilab/logilab/common/tree.py +372 -0
- data/tools/logilab/logilab/common/umessage.py +161 -0
- data/tools/logilab/logilab/common/ureports/__init__.py +174 -0
- data/tools/logilab/logilab/common/ureports/docbook_writer.py +139 -0
- data/tools/logilab/logilab/common/ureports/html_writer.py +131 -0
- data/tools/logilab/logilab/common/ureports/nodes.py +201 -0
- data/tools/logilab/logilab/common/ureports/text_writer.py +140 -0
- data/tools/logilab/logilab/common/vcgutils.py +216 -0
- data/tools/logilab/logilab/common/visitor.py +107 -0
- data/tools/logilab/logilab/common/xmlrpcutils.py +136 -0
- data/tools/logilab/logilab/common/xmlutils.py +61 -0
- data/tools/pychecker/COPYRIGHT +31 -0
- data/tools/pychecker/ChangeLog +349 -0
- data/tools/pychecker/CodeChecks.py +1969 -0
- data/tools/pychecker/CodeChecks.pyc +0 -0
- data/tools/pychecker/CodeChecks.pyo +0 -0
- data/tools/pychecker/Config.py +475 -0
- data/tools/pychecker/Config.pyc +0 -0
- data/tools/pychecker/Config.pyo +0 -0
- data/tools/pychecker/KNOWN_BUGS +100 -0
- data/tools/pychecker/MAINTAINERS +81 -0
- data/tools/pychecker/NEWS +406 -0
- data/tools/pychecker/OP.py +131 -0
- data/tools/pychecker/OP.pyc +0 -0
- data/tools/pychecker/OP.pyo +0 -0
- data/tools/pychecker/OptionTypes.py +117 -0
- data/tools/pychecker/OptionTypes.pyc +0 -0
- data/tools/pychecker/OptionTypes.pyo +0 -0
- data/tools/pychecker/README +152 -0
- data/tools/pychecker/Stack.py +115 -0
- data/tools/pychecker/Stack.pyc +0 -0
- data/tools/pychecker/Stack.pyo +0 -0
- data/tools/pychecker/TODO +101 -0
- data/tools/pychecker/VERSION +1 -0
- data/tools/pychecker/Warning.py +50 -0
- data/tools/pychecker/Warning.pyc +0 -0
- data/tools/pychecker/Warning.pyo +0 -0
- data/tools/pychecker/__init__.py +17 -0
- data/tools/pychecker/__init__.pyc +0 -0
- data/tools/pychecker/__init__.pyo +0 -0
- data/tools/pychecker/checker.py +961 -0
- data/tools/pychecker/checker.pyc +0 -0
- data/tools/pychecker/checker.pyo +0 -0
- data/tools/pychecker/function.py +159 -0
- data/tools/pychecker/function.pyc +0 -0
- data/tools/pychecker/function.pyo +0 -0
- data/tools/pychecker/msgs.py +175 -0
- data/tools/pychecker/msgs.pyc +0 -0
- data/tools/pychecker/msgs.pyo +0 -0
- data/tools/pychecker/options.py +275 -0
- data/tools/pychecker/options.pyc +0 -0
- data/tools/pychecker/options.pyo +0 -0
- data/tools/pychecker/pcmodules.py +19 -0
- data/tools/pychecker/pcmodules.pyc +0 -0
- data/tools/pychecker/pcmodules.pyo +0 -0
- data/tools/pychecker/printer.py +47 -0
- data/tools/pychecker/printer.pyc +0 -0
- data/tools/pychecker/printer.pyo +0 -0
- data/tools/pychecker/python.py +427 -0
- data/tools/pychecker/python.pyc +0 -0
- data/tools/pychecker/python.pyo +0 -0
- data/tools/pychecker/utils.py +102 -0
- data/tools/pychecker/utils.pyc +0 -0
- data/tools/pychecker/utils.pyo +0 -0
- data/tools/pychecker/warn.py +778 -0
- data/tools/pychecker/warn.pyc +0 -0
- data/tools/pychecker/warn.pyo +0 -0
- data/tools/pylint2/pylint/__init__.py +16 -0
- data/tools/pylint2/pylint/__pkginfo__.py +67 -0
- data/tools/pylint2/pylint/checkers/__init__.py +155 -0
- data/tools/pylint2/pylint/checkers/base.py +749 -0
- data/tools/pylint2/pylint/checkers/classes.py +527 -0
- data/tools/pylint2/pylint/checkers/design_analysis.py +344 -0
- data/tools/pylint2/pylint/checkers/exceptions.py +183 -0
- data/tools/pylint2/pylint/checkers/format.py +367 -0
- data/tools/pylint2/pylint/checkers/imports.py +379 -0
- data/tools/pylint2/pylint/checkers/logging.py +98 -0
- data/tools/pylint2/pylint/checkers/misc.py +128 -0
- data/tools/pylint2/pylint/checkers/newstyle.py +107 -0
- data/tools/pylint2/pylint/checkers/raw_metrics.py +125 -0
- data/tools/pylint2/pylint/checkers/similar.py +333 -0
- data/tools/pylint2/pylint/checkers/string_format.py +239 -0
- data/tools/pylint2/pylint/checkers/typecheck.py +364 -0
- data/tools/pylint2/pylint/checkers/utils.py +208 -0
- data/tools/pylint2/pylint/checkers/variables.py +498 -0
- data/tools/pylint2/pylint/config.py +149 -0
- data/tools/pylint2/pylint/epylint.py +149 -0
- data/tools/pylint2/pylint/gui.py +433 -0
- data/tools/pylint2/pylint/interfaces.py +98 -0
- data/tools/pylint2/pylint/lint.py +914 -0
- data/tools/pylint2/pylint/pyreverse/__init__.py +5 -0
- data/tools/pylint2/pylint/pyreverse/diadefslib.py +229 -0
- data/tools/pylint2/pylint/pyreverse/diagrams.py +247 -0
- data/tools/pylint2/pylint/pyreverse/main.py +123 -0
- data/tools/pylint2/pylint/pyreverse/utils.py +131 -0
- data/tools/pylint2/pylint/pyreverse/writer.py +196 -0
- data/tools/pylint2/pylint/reporters/__init__.py +67 -0
- data/tools/pylint2/pylint/reporters/guireporter.py +36 -0
- data/tools/pylint2/pylint/reporters/html.py +69 -0
- data/tools/pylint2/pylint/reporters/text.py +156 -0
- data/tools/pylint2/pylint/utils.py +518 -0
- data/tools/pylint2/pylint.py +16 -0
- data/tools/test/suite.py +35 -0
- metadata +566 -0
@@ -0,0 +1,234 @@
|
|
1
|
+
# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
|
2
|
+
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
|
3
|
+
#
|
4
|
+
# This file is part of logilab-common.
|
5
|
+
#
|
6
|
+
# logilab-common is free software: you can redistribute it and/or modify it under
|
7
|
+
# the terms of the GNU Lesser General Public License as published by the Free
|
8
|
+
# Software Foundation, either version 2.1 of the License, or (at your option) any
|
9
|
+
# later version.
|
10
|
+
#
|
11
|
+
# logilab-common is distributed in the hope that it will be useful, but WITHOUT
|
12
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
13
|
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
14
|
+
# details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Lesser General Public License along
|
17
|
+
# with logilab-common. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
"""Manipulation of upstream change log files.
|
19
|
+
|
20
|
+
The upstream change log files format handled is simpler than the one
|
21
|
+
often used such as those generated by the default Emacs changelog mode.
|
22
|
+
|
23
|
+
Sample ChangeLog format::
|
24
|
+
|
25
|
+
Change log for project Yoo
|
26
|
+
==========================
|
27
|
+
|
28
|
+
--
|
29
|
+
* add a new functionality
|
30
|
+
|
31
|
+
2002-02-01 -- 0.1.1
|
32
|
+
* fix bug #435454
|
33
|
+
* fix bug #434356
|
34
|
+
|
35
|
+
2002-01-01 -- 0.1
|
36
|
+
* initial release
|
37
|
+
|
38
|
+
|
39
|
+
There is 3 entries in this change log, one for each released version and one
|
40
|
+
for the next version (i.e. the current entry).
|
41
|
+
Each entry contains a set of messages corresponding to changes done in this
|
42
|
+
release.
|
43
|
+
All the non empty lines before the first entry are considered as the change
|
44
|
+
log title.
|
45
|
+
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
"""
|
50
|
+
__docformat__ = "restructuredtext en"
|
51
|
+
|
52
|
+
import sys
|
53
|
+
from stat import S_IWRITE
|
54
|
+
|
55
|
+
BULLET = '*'
|
56
|
+
SUBBULLET = '-'
|
57
|
+
INDENT = ' ' * 4
|
58
|
+
|
59
|
+
class NoEntry(Exception):
|
60
|
+
"""raised when we are unable to find an entry"""
|
61
|
+
|
62
|
+
class EntryNotFound(Exception):
|
63
|
+
"""raised when we are unable to find a given entry"""
|
64
|
+
|
65
|
+
class Version(tuple):
|
66
|
+
"""simple class to handle soft version number has a tuple while
|
67
|
+
correctly printing it as X.Y.Z
|
68
|
+
"""
|
69
|
+
def __new__(klass, versionstr):
|
70
|
+
if isinstance(versionstr, basestring):
|
71
|
+
versionstr = versionstr.strip(' :')
|
72
|
+
try:
|
73
|
+
parsed = [int(i) for i in versionstr.split('.')]
|
74
|
+
except ValueError, ex:
|
75
|
+
raise ValueError("invalid literal for version '%s' (%s)"%(versionstr,ex))
|
76
|
+
else:
|
77
|
+
parsed = versionstr
|
78
|
+
return tuple.__new__(klass, parsed)
|
79
|
+
|
80
|
+
def __str__(self):
|
81
|
+
return '.'.join([str(i) for i in self])
|
82
|
+
|
83
|
+
# upstream change log #########################################################
|
84
|
+
|
85
|
+
class ChangeLogEntry(object):
|
86
|
+
"""a change log entry, i.e. a set of messages associated to a version and
|
87
|
+
its release date
|
88
|
+
"""
|
89
|
+
version_class = Version
|
90
|
+
|
91
|
+
def __init__(self, date=None, version=None, **kwargs):
|
92
|
+
self.__dict__.update(kwargs)
|
93
|
+
if version:
|
94
|
+
self.version = self.version_class(version)
|
95
|
+
else:
|
96
|
+
self.version = None
|
97
|
+
self.date = date
|
98
|
+
self.messages = []
|
99
|
+
|
100
|
+
def add_message(self, msg):
|
101
|
+
"""add a new message"""
|
102
|
+
self.messages.append(([msg],[]))
|
103
|
+
|
104
|
+
def complete_latest_message(self, msg_suite):
|
105
|
+
"""complete the latest added message
|
106
|
+
"""
|
107
|
+
if not self.messages:
|
108
|
+
raise ValueError('unable to complete last message as there is no previous message)')
|
109
|
+
if self.messages[-1][1]: # sub messages
|
110
|
+
self.messages[-1][1][-1].append(msg_suite)
|
111
|
+
else: # message
|
112
|
+
self.messages[-1][0].append(msg_suite)
|
113
|
+
|
114
|
+
def add_sub_message(self, sub_msg, key=None):
|
115
|
+
if not self.messages:
|
116
|
+
raise ValueError('unable to complete last message as there is no previous message)')
|
117
|
+
if key is None:
|
118
|
+
self.messages[-1][1].append([sub_msg])
|
119
|
+
else:
|
120
|
+
raise NotImplementedError("sub message to specific key are not implemented yet")
|
121
|
+
|
122
|
+
def write(self, stream=sys.stdout):
|
123
|
+
"""write the entry to file """
|
124
|
+
stream.write('%s -- %s\n' % (self.date or '', self.version or ''))
|
125
|
+
for msg, sub_msgs in self.messages:
|
126
|
+
stream.write('%s%s %s\n' % (INDENT, BULLET, msg[0]))
|
127
|
+
stream.write(''.join(msg[1:]))
|
128
|
+
if sub_msgs:
|
129
|
+
stream.write('\n')
|
130
|
+
for sub_msg in sub_msgs:
|
131
|
+
stream.write('%s%s %s\n' % (INDENT * 2, SUBBULLET, sub_msg[0]))
|
132
|
+
stream.write(''.join(sub_msg[1:]))
|
133
|
+
stream.write('\n')
|
134
|
+
|
135
|
+
stream.write('\n\n')
|
136
|
+
|
137
|
+
class ChangeLog(object):
|
138
|
+
"""object representation of a whole ChangeLog file"""
|
139
|
+
|
140
|
+
entry_class = ChangeLogEntry
|
141
|
+
|
142
|
+
def __init__(self, changelog_file, title=''):
|
143
|
+
self.file = changelog_file
|
144
|
+
self.title = title
|
145
|
+
self.additional_content = ''
|
146
|
+
self.entries = []
|
147
|
+
self.load()
|
148
|
+
|
149
|
+
def __repr__(self):
|
150
|
+
return '<ChangeLog %s at %s (%s entries)>' % (self.file, id(self),
|
151
|
+
len(self.entries))
|
152
|
+
|
153
|
+
def add_entry(self, entry):
|
154
|
+
"""add a new entry to the change log"""
|
155
|
+
self.entries.append(entry)
|
156
|
+
|
157
|
+
def get_entry(self, version='', create=None):
|
158
|
+
""" return a given changelog entry
|
159
|
+
if version is omitted, return the current entry
|
160
|
+
"""
|
161
|
+
if not self.entries:
|
162
|
+
if version or not create:
|
163
|
+
raise NoEntry()
|
164
|
+
self.entries.append(self.entry_class())
|
165
|
+
if not version:
|
166
|
+
if self.entries[0].version and create is not None:
|
167
|
+
self.entries.insert(0, self.entry_class())
|
168
|
+
return self.entries[0]
|
169
|
+
version = self.version_class(version)
|
170
|
+
for entry in self.entries:
|
171
|
+
if entry.version == version:
|
172
|
+
return entry
|
173
|
+
raise EntryNotFound()
|
174
|
+
|
175
|
+
def add(self, msg, create=None):
|
176
|
+
"""add a new message to the latest opened entry"""
|
177
|
+
entry = self.get_entry(create=create)
|
178
|
+
entry.add_message(msg)
|
179
|
+
|
180
|
+
def load(self):
|
181
|
+
""" read a logilab's ChangeLog from file """
|
182
|
+
try:
|
183
|
+
stream = open(self.file)
|
184
|
+
except IOError:
|
185
|
+
return
|
186
|
+
last = None
|
187
|
+
expect_sub = False
|
188
|
+
for line in stream.readlines():
|
189
|
+
sline = line.strip()
|
190
|
+
words = sline.split()
|
191
|
+
# if new entry
|
192
|
+
if len(words) == 1 and words[0] == '--':
|
193
|
+
expect_sub = False
|
194
|
+
last = self.entry_class()
|
195
|
+
self.add_entry(last)
|
196
|
+
# if old entry
|
197
|
+
elif len(words) == 3 and words[1] == '--':
|
198
|
+
expect_sub = False
|
199
|
+
last = self.entry_class(words[0], words[2])
|
200
|
+
self.add_entry(last)
|
201
|
+
# if title
|
202
|
+
elif sline and last is None:
|
203
|
+
self.title = '%s%s' % (self.title, line)
|
204
|
+
# if new entry
|
205
|
+
elif sline and sline[0] == BULLET:
|
206
|
+
expect_sub = False
|
207
|
+
last.add_message(sline[1:].strip())
|
208
|
+
# if new sub_entry
|
209
|
+
elif expect_sub and sline and sline[0] == SUBBULLET:
|
210
|
+
last.add_sub_message(sline[1:].strip())
|
211
|
+
# if new line for current entry
|
212
|
+
elif sline and last.messages:
|
213
|
+
last.complete_latest_message(line)
|
214
|
+
else:
|
215
|
+
expect_sub = True
|
216
|
+
self.additional_content += line
|
217
|
+
stream.close()
|
218
|
+
|
219
|
+
def format_title(self):
|
220
|
+
return '%s\n\n' % self.title.strip()
|
221
|
+
|
222
|
+
def save(self):
|
223
|
+
"""write back change log"""
|
224
|
+
# filetutils isn't importable in appengine, so import locally
|
225
|
+
from logilab.common.fileutils import ensure_fs_mode
|
226
|
+
ensure_fs_mode(self.file, S_IWRITE)
|
227
|
+
self.write(open(self.file, 'w'))
|
228
|
+
|
229
|
+
def write(self, stream=sys.stdout):
|
230
|
+
"""write changelog to stream"""
|
231
|
+
stream.write(self.format_title())
|
232
|
+
for entry in self.entries:
|
233
|
+
entry.write(stream)
|
234
|
+
|
@@ -0,0 +1,181 @@
|
|
1
|
+
# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
|
2
|
+
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
|
3
|
+
#
|
4
|
+
# This file is part of logilab-common.
|
5
|
+
#
|
6
|
+
# logilab-common is free software: you can redistribute it and/or modify it under
|
7
|
+
# the terms of the GNU Lesser General Public License as published by the Free
|
8
|
+
# Software Foundation, either version 2.1 of the License, or (at your option) any
|
9
|
+
# later version.
|
10
|
+
#
|
11
|
+
# logilab-common is distributed in the hope that it will be useful, but WITHOUT
|
12
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
13
|
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
14
|
+
# details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Lesser General Public License along
|
17
|
+
# with logilab-common. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
"""Helper functions to support command line tools providing more than
|
19
|
+
one command.
|
20
|
+
|
21
|
+
e.g called as "tool command [options] args..." where <options> and <args> are
|
22
|
+
command'specific
|
23
|
+
|
24
|
+
|
25
|
+
|
26
|
+
|
27
|
+
"""
|
28
|
+
__docformat__ = "restructuredtext en"
|
29
|
+
|
30
|
+
# XXX : merge with optparser ?
|
31
|
+
import sys
|
32
|
+
from os.path import basename
|
33
|
+
|
34
|
+
from logilab.common.configuration import Configuration
|
35
|
+
|
36
|
+
|
37
|
+
DEFAULT_COPYRIGHT = '''\
|
38
|
+
Copyright (c) 2004-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
|
39
|
+
http://www.logilab.fr/ -- mailto:contact@logilab.fr'''
|
40
|
+
|
41
|
+
|
42
|
+
DEFAULT_DOC = '''\
|
43
|
+
Type "%prog <command> --help" for more information about a specific
|
44
|
+
command. Available commands are :\n'''
|
45
|
+
|
46
|
+
class BadCommandUsage(Exception):
|
47
|
+
"""Raised when an unknown command is used or when a command is not
|
48
|
+
correctly used.
|
49
|
+
"""
|
50
|
+
|
51
|
+
|
52
|
+
class Command(Configuration):
|
53
|
+
"""Base class for command line commands."""
|
54
|
+
arguments = ''
|
55
|
+
name = ''
|
56
|
+
# hidden from help ?
|
57
|
+
hidden = False
|
58
|
+
# max/min args, None meaning unspecified
|
59
|
+
min_args = None
|
60
|
+
max_args = None
|
61
|
+
def __init__(self, __doc__=None, version=None):
|
62
|
+
if __doc__:
|
63
|
+
usage = __doc__ % (self.name, self.arguments,
|
64
|
+
self.__doc__.replace(' ', ''))
|
65
|
+
else:
|
66
|
+
usage = self.__doc__.replace(' ', '')
|
67
|
+
Configuration.__init__(self, usage=usage, version=version)
|
68
|
+
|
69
|
+
def check_args(self, args):
|
70
|
+
"""check command's arguments are provided"""
|
71
|
+
if self.min_args is not None and len(args) < self.min_args:
|
72
|
+
raise BadCommandUsage('missing argument')
|
73
|
+
if self.max_args is not None and len(args) > self.max_args:
|
74
|
+
raise BadCommandUsage('too many arguments')
|
75
|
+
|
76
|
+
def run(self, args):
|
77
|
+
"""run the command with its specific arguments"""
|
78
|
+
raise NotImplementedError()
|
79
|
+
|
80
|
+
|
81
|
+
def pop_arg(args_list, expected_size_after=0, msg="Missing argument"):
|
82
|
+
"""helper function to get and check command line arguments"""
|
83
|
+
try:
|
84
|
+
value = args_list.pop(0)
|
85
|
+
except IndexError:
|
86
|
+
raise BadCommandUsage(msg)
|
87
|
+
if expected_size_after is not None and len(args_list) > expected_size_after:
|
88
|
+
raise BadCommandUsage('too many arguments')
|
89
|
+
return value
|
90
|
+
|
91
|
+
|
92
|
+
_COMMANDS = {}
|
93
|
+
|
94
|
+
def register_commands(commands):
|
95
|
+
"""register existing commands"""
|
96
|
+
for command_klass in commands:
|
97
|
+
_COMMANDS[command_klass.name] = command_klass
|
98
|
+
|
99
|
+
|
100
|
+
def main_usage(status=0, doc=DEFAULT_DOC, copyright=DEFAULT_COPYRIGHT):
|
101
|
+
"""display usage for the main program (i.e. when no command supplied)
|
102
|
+
and exit
|
103
|
+
"""
|
104
|
+
commands = _COMMANDS.keys()
|
105
|
+
commands.sort()
|
106
|
+
if doc != DEFAULT_DOC:
|
107
|
+
try:
|
108
|
+
doc = doc % ('<command>', '<command arguments>',
|
109
|
+
'''\
|
110
|
+
Type "%prog <command> --help" for more information about a specific
|
111
|
+
command. Available commands are :\n''')
|
112
|
+
except TypeError:
|
113
|
+
print 'could not find the "command", "arguments" and "default" slots'
|
114
|
+
doc = doc.replace('%prog', basename(sys.argv[0]))
|
115
|
+
print 'usage:', doc
|
116
|
+
max_len = max([len(cmd) for cmd in commands]) # list comprehension for py 2.3 support
|
117
|
+
padding = ' '*max_len
|
118
|
+
for command in commands:
|
119
|
+
cmd = _COMMANDS[command]
|
120
|
+
if not cmd.hidden:
|
121
|
+
title = cmd.__doc__.split('.')[0]
|
122
|
+
print ' ', (command+padding)[:max_len], title
|
123
|
+
if copyright:
|
124
|
+
print '\n', copyright
|
125
|
+
sys.exit(status)
|
126
|
+
|
127
|
+
|
128
|
+
def cmd_run(cmdname, *args):
|
129
|
+
try:
|
130
|
+
command = _COMMANDS[cmdname](__doc__='%%prog %s %s\n\n%s')
|
131
|
+
except KeyError:
|
132
|
+
raise BadCommandUsage('no %s command' % cmdname)
|
133
|
+
args = command.load_command_line_configuration(args)
|
134
|
+
command.check_args(args)
|
135
|
+
try:
|
136
|
+
command.run(args)
|
137
|
+
except KeyboardInterrupt:
|
138
|
+
print 'interrupted'
|
139
|
+
except BadCommandUsage, err:
|
140
|
+
print 'ERROR: ', err
|
141
|
+
print command.help()
|
142
|
+
|
143
|
+
|
144
|
+
def main_run(args, doc=DEFAULT_DOC, copyright=DEFAULT_COPYRIGHT):
|
145
|
+
"""command line tool"""
|
146
|
+
try:
|
147
|
+
arg = args.pop(0)
|
148
|
+
except IndexError:
|
149
|
+
main_usage(status=1, doc=doc, copyright=copyright)
|
150
|
+
if arg in ('-h', '--help'):
|
151
|
+
main_usage(doc=doc, copyright=copyright)
|
152
|
+
try:
|
153
|
+
cmd_run(arg, *args)
|
154
|
+
except BadCommandUsage, err:
|
155
|
+
print 'ERROR: ', err
|
156
|
+
main_usage(1, doc=doc, copyright=copyright)
|
157
|
+
|
158
|
+
|
159
|
+
class ListCommandsCommand(Command):
|
160
|
+
"""list available commands, useful for bash completion."""
|
161
|
+
name = 'listcommands'
|
162
|
+
arguments = '[command]'
|
163
|
+
hidden = True
|
164
|
+
|
165
|
+
def run(self, args):
|
166
|
+
"""run the command with its specific arguments"""
|
167
|
+
if args:
|
168
|
+
command = pop_arg(args)
|
169
|
+
cmd = _COMMANDS[command]
|
170
|
+
for optname, optdict in cmd.options:
|
171
|
+
print '--help'
|
172
|
+
print '--' + optname
|
173
|
+
else:
|
174
|
+
commands = _COMMANDS.keys()
|
175
|
+
commands.sort()
|
176
|
+
for command in commands:
|
177
|
+
cmd = _COMMANDS[command]
|
178
|
+
if not cmd.hidden:
|
179
|
+
print command
|
180
|
+
|
181
|
+
register_commands([ListCommandsCommand])
|
@@ -0,0 +1,212 @@
|
|
1
|
+
# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
|
2
|
+
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
|
3
|
+
#
|
4
|
+
# This file is part of logilab-common.
|
5
|
+
#
|
6
|
+
# logilab-common is free software: you can redistribute it and/or modify it under
|
7
|
+
# the terms of the GNU Lesser General Public License as published by the Free
|
8
|
+
# Software Foundation, either version 2.1 of the License, or (at your option) any
|
9
|
+
# later version.
|
10
|
+
#
|
11
|
+
# logilab-common is distributed in the hope that it will be useful, but WITHOUT
|
12
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
13
|
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
14
|
+
# details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Lesser General Public License along
|
17
|
+
# with logilab-common. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
"""Command line interface helper classes.
|
19
|
+
|
20
|
+
It provides some default commands, a help system, a default readline
|
21
|
+
configuration with completion and persistent history.
|
22
|
+
|
23
|
+
Example::
|
24
|
+
|
25
|
+
class BookShell(CLIHelper):
|
26
|
+
|
27
|
+
def __init__(self):
|
28
|
+
# quit and help are builtins
|
29
|
+
# CMD_MAP keys are commands, values are topics
|
30
|
+
self.CMD_MAP['pionce'] = _("Sommeil")
|
31
|
+
self.CMD_MAP['ronfle'] = _("Sommeil")
|
32
|
+
CLIHelper.__init__(self)
|
33
|
+
|
34
|
+
help_do_pionce = ("pionce", "pionce duree", _("met ton corps en veille"))
|
35
|
+
def do_pionce(self):
|
36
|
+
print 'nap is good'
|
37
|
+
|
38
|
+
help_do_ronfle = ("ronfle", "ronfle volume", _("met les autres en veille"))
|
39
|
+
def do_ronfle(self):
|
40
|
+
print 'fuuuuuuuuuuuu rhhhhhrhrhrrh'
|
41
|
+
|
42
|
+
cl = BookShell()
|
43
|
+
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
"""
|
48
|
+
__docformat__ = "restructuredtext en"
|
49
|
+
|
50
|
+
import __builtin__
|
51
|
+
if not hasattr(__builtin__, '_'):
|
52
|
+
__builtin__._ = str
|
53
|
+
|
54
|
+
|
55
|
+
def init_readline(complete_method, histfile=None):
|
56
|
+
"""Init the readline library if available."""
|
57
|
+
try:
|
58
|
+
import readline
|
59
|
+
readline.parse_and_bind("tab: complete")
|
60
|
+
readline.set_completer(complete_method)
|
61
|
+
string = readline.get_completer_delims().replace(':', '')
|
62
|
+
readline.set_completer_delims(string)
|
63
|
+
if histfile is not None:
|
64
|
+
try:
|
65
|
+
readline.read_history_file(histfile)
|
66
|
+
except IOError:
|
67
|
+
pass
|
68
|
+
import atexit
|
69
|
+
atexit.register(readline.write_history_file, histfile)
|
70
|
+
except:
|
71
|
+
print 'readline is not available :-('
|
72
|
+
|
73
|
+
|
74
|
+
class Completer :
|
75
|
+
"""Readline completer."""
|
76
|
+
|
77
|
+
def __init__(self, commands):
|
78
|
+
self.list = commands
|
79
|
+
|
80
|
+
def complete(self, text, state):
|
81
|
+
"""Hook called by readline when <tab> is pressed."""
|
82
|
+
n = len(text)
|
83
|
+
matches = []
|
84
|
+
for cmd in self.list :
|
85
|
+
if cmd[:n] == text :
|
86
|
+
matches.append(cmd)
|
87
|
+
try:
|
88
|
+
return matches[state]
|
89
|
+
except IndexError:
|
90
|
+
return None
|
91
|
+
|
92
|
+
|
93
|
+
class CLIHelper:
|
94
|
+
"""An abstract command line interface client which recognize commands
|
95
|
+
and provide an help system.
|
96
|
+
"""
|
97
|
+
|
98
|
+
CMD_MAP = {'help' : _("Others"),
|
99
|
+
'quit' : _("Others"),
|
100
|
+
}
|
101
|
+
CMD_PREFIX = ''
|
102
|
+
|
103
|
+
def __init__(self, histfile=None) :
|
104
|
+
self._topics = {}
|
105
|
+
self.commands = None
|
106
|
+
self._completer = Completer(self._register_commands())
|
107
|
+
init_readline(self._completer.complete, histfile)
|
108
|
+
|
109
|
+
def run(self):
|
110
|
+
"""loop on user input, exit on EOF"""
|
111
|
+
while 1:
|
112
|
+
try:
|
113
|
+
line = raw_input('>>> ')
|
114
|
+
except EOFError:
|
115
|
+
print
|
116
|
+
break
|
117
|
+
s_line = line.strip()
|
118
|
+
if not s_line:
|
119
|
+
continue
|
120
|
+
args = s_line.split()
|
121
|
+
if args[0] in self.commands:
|
122
|
+
try:
|
123
|
+
cmd = 'do_%s' % self.commands[args[0]]
|
124
|
+
getattr(self, cmd)(*args[1:])
|
125
|
+
except EOFError:
|
126
|
+
break
|
127
|
+
except:
|
128
|
+
import traceback
|
129
|
+
traceback.print_exc()
|
130
|
+
else:
|
131
|
+
try:
|
132
|
+
self.handle_line(s_line)
|
133
|
+
except:
|
134
|
+
import traceback
|
135
|
+
traceback.print_exc()
|
136
|
+
|
137
|
+
def handle_line(self, stripped_line):
|
138
|
+
"""Method to overload in the concrete class (should handle
|
139
|
+
lines which are not commands).
|
140
|
+
"""
|
141
|
+
raise NotImplementedError()
|
142
|
+
|
143
|
+
|
144
|
+
# private methods #########################################################
|
145
|
+
|
146
|
+
def _register_commands(self):
|
147
|
+
""" register available commands method and return the list of
|
148
|
+
commands name
|
149
|
+
"""
|
150
|
+
self.commands = {}
|
151
|
+
self._command_help = {}
|
152
|
+
commands = [attr[3:] for attr in dir(self) if attr[:3] == 'do_']
|
153
|
+
for command in commands:
|
154
|
+
topic = self.CMD_MAP[command]
|
155
|
+
help_method = getattr(self, 'help_do_%s' % command)
|
156
|
+
self._topics.setdefault(topic, []).append(help_method)
|
157
|
+
self.commands[self.CMD_PREFIX + command] = command
|
158
|
+
self._command_help[command] = help_method
|
159
|
+
return self.commands.keys()
|
160
|
+
|
161
|
+
def _print_help(self, cmd, syntax, explanation):
|
162
|
+
print _('Command %s') % cmd
|
163
|
+
print _('Syntax: %s') % syntax
|
164
|
+
print '\t', explanation
|
165
|
+
print
|
166
|
+
|
167
|
+
|
168
|
+
# predefined commands #####################################################
|
169
|
+
|
170
|
+
def do_help(self, command=None) :
|
171
|
+
"""base input of the help system"""
|
172
|
+
if command in self._command_help:
|
173
|
+
self._print_help(*self._command_help[command])
|
174
|
+
elif command is None or command not in self._topics:
|
175
|
+
print _("Use help <topic> or help <command>.")
|
176
|
+
print _("Available topics are:")
|
177
|
+
topics = self._topics.keys()
|
178
|
+
topics.sort()
|
179
|
+
for topic in topics:
|
180
|
+
print '\t', topic
|
181
|
+
print
|
182
|
+
print _("Available commands are:")
|
183
|
+
commands = self.commands.keys()
|
184
|
+
commands.sort()
|
185
|
+
for command in commands:
|
186
|
+
print '\t', command[len(self.CMD_PREFIX):]
|
187
|
+
|
188
|
+
else:
|
189
|
+
print _('Available commands about %s:') % command
|
190
|
+
print
|
191
|
+
for command_help_method in self._topics[command]:
|
192
|
+
try:
|
193
|
+
if callable(command_help_method):
|
194
|
+
self._print_help(*command_help_method())
|
195
|
+
else:
|
196
|
+
self._print_help(*command_help_method)
|
197
|
+
except:
|
198
|
+
import traceback
|
199
|
+
traceback.print_exc()
|
200
|
+
print 'ERROR in help method %s'% (
|
201
|
+
command_help_method.func_name)
|
202
|
+
|
203
|
+
help_do_help = ("help", "help [topic|command]",
|
204
|
+
_("print help message for the given topic/command or \
|
205
|
+
available topics when no argument"))
|
206
|
+
|
207
|
+
def do_quit(self):
|
208
|
+
"""quit the CLI"""
|
209
|
+
raise EOFError()
|
210
|
+
|
211
|
+
def help_do_quit(self):
|
212
|
+
return ("quit", "quit", _("quit the application"))
|