pax_global_header00006660000000000000000000000064127417737030014525gustar00rootroot0000000000000052 comment=3700191e230bc502e1f69a68d58bf7dd54982e62 cement-2.10.0/000077500000000000000000000000001274177370300130605ustar00rootroot00000000000000cement-2.10.0/.coveragerc000066400000000000000000000000001274177370300151670ustar00rootroot00000000000000cement-2.10.0/.gitignore000066400000000000000000000011141274177370300150450ustar00rootroot00000000000000*egg* env/ var/ log/ tmp/ dist __pycache__/ # Gitignores from https://github.com/github/gitignore # Vi *.swp *.swo # Vim .*.sw[a-z] *.un~ # OSX .DS_Store? Icon? # Thumbnails ._* # Files that might appear on external disk .Spotlight-V100 .Trashes # Python *.py[co] # Packages *.egg *.egg-info dist build eggs parts bin develop-eggs .installed.cfg # Installer logs pip-log.txt # Unit test / coverage reports .coverage htmlcov coverage_report .tox # TextMate *.tmproj *.tmproject tmtags test.log example.py extensions .env .vagrant myapp*.py # redis test artifacts dump.rdb cement-2.10.0/.pylintrc000066400000000000000000000162421274177370300147320ustar00rootroot00000000000000[MASTER] # Specify a configuration file. #rcfile= # Python code to execute, usually for sys.path manipulation such as # pygtk.require(). #init-hook= # Profiled execution. profile=no # Add files or directories to the blacklist. They should be base names, not # paths. ignore=CVS # Pickle collected data for later comparisons. persistent=yes # List of plugins (as comma separated values of python modules names) to load, # usually to register additional checkers. load-plugins= [MESSAGES CONTROL] # Enable the message, report, category or checker with the given id(s). You can # either give multiple identifier separated by comma (,) or put this option # multiple time. #enable= # Disable the message, report, category or checker with the given id(s). You # can either give multiple identifier separated by comma (,) or put this option # multiple time (only on the command line, not in the configuration file where # it should appear only once). disable=W0105,W0232,W0232,R0903,E0213,R0923,E0211 [REPORTS] # Set the output format. Available formats are text, parseable, colorized, msvs # (visual studio) and html output-format=colorized # Include message's id in output include-ids=yes # Put messages in a separate file for each module / package specified on the # command line instead of printing them on stdout. Reports (if any) will be # written in a file name "pylint_global.[txt|html]". files-output=no # Tells whether to display a full report or only the messages reports=yes # Python expression which should return a note less than 10 (10 is the highest # note). You have access to the variables errors warning, statement which # respectively contain the number of errors / warnings messages and the total # number of statements analyzed. This is used by the global evaluation report # (RP0004). evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) # Add a comment according to your evaluation note. This is used by the global # evaluation report (RP0004). comment=no [BASIC] # Required attributes for module, separated by a comma required-attributes= # List of builtins function names that should not be used, separated by a comma bad-functions=map,filter,apply,input # Regular expression which should only match correct module names module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ # Regular expression which should only match correct module level names const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$ # Regular expression which should only match correct class names class-rgx=[A-Z_][a-zA-Z0-9]+$ # Regular expression which should only match correct function names function-rgx=[a-z_][a-z0-9_]{2,30}$ # Regular expression which should only match correct method names method-rgx=[a-z_][a-z0-9_]{2,30}$ # Regular expression which should only match correct instance attribute names attr-rgx=[a-z_][a-z0-9_]{2,30}$ # Regular expression which should only match correct argument names argument-rgx=[a-z_][a-z0-9_]{2,30}$ # Regular expression which should only match correct variable names variable-rgx=[a-z_][a-z0-9_]{2,30}$ # Regular expression which should only match correct list comprehension / # generator expression variable names inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ # Good variable names which should always be accepted, separated by a comma good-names=i,j,k,ex,Run,_ # Bad variable names which should always be refused, separated by a comma bad-names=foo,bar,baz,toto,tutu,tata # Regular expression which should only match functions or classes name which do # not require a docstring no-docstring-rgx=__.*__ [FORMAT] # Maximum number of characters on a single line. max-line-length=80 # Maximum number of lines in a module max-module-lines=1000 # String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 # tab). indent-string=' ' [MISCELLANEOUS] # List of note tags to take in consideration, separated by a comma. notes=FIXME,XXX,TODO [SIMILARITIES] # Minimum lines number of a similarity. min-similarity-lines=4 # Ignore comments when computing similarities. ignore-comments=yes # Ignore docstrings when computing similarities. ignore-docstrings=yes [TYPECHECK] # Tells whether missing members accessed in mixin class should be ignored. A # mixin class is detected if its name ends with "mixin" (case insensitive). ignore-mixin-members=yes # List of classes names for which member attributes should not be checked # (useful for classes with attributes dynamically set). ignored-classes=SQLObject # When zope mode is activated, add a predefined set of Zope acquired attributes # to generated-members. zope=no # List of members which are set dynamically and missed by pylint inference # system, and so shouldn't trigger E0201 when accessed. Python regular # expressions are accepted. generated-members=REQUEST,acl_users,aq_parent [VARIABLES] # Tells whether we should check for unused import in __init__ files. init-import=no # A regular expression matching the beginning of the name of dummy variables # (i.e. not used). dummy-variables-rgx=_|dummy|klass # List of additional names supposed to be defined in builtins. Remember that # you should avoid to define new builtins when possible. additional-builtins= [CLASSES] # List of interface methods to ignore, separated by a comma. This is used for # instance to not check methods defines in Zope's Interface base class. ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by # List of method names used to declare (i.e. assign) instance attributes. defining-attr-methods=__init__,__new__,setUp # List of valid names for the first argument in a class method. valid-classmethod-first-arg=cls [DESIGN] # Maximum number of arguments for function / method max-args=5 # Argument names that match this expression will be ignored. Default to name # with leading underscore ignored-argument-names=_.* # Maximum number of locals for function / method body max-locals=15 # Maximum number of return / yield for function / method body max-returns=6 # Maximum number of branch for function / method body max-branchs=12 # Maximum number of statements in function / method body max-statements=50 # Maximum number of parents for a class (see R0901). max-parents=7 # Maximum number of attributes for a class (see R0902). max-attributes=7 # Minimum number of public methods for a class (see R0903). min-public-methods=2 # Maximum number of public methods for a class (see R0904). max-public-methods=20 [IMPORTS] # Deprecated modules which should not be used, separated by a comma deprecated-modules=regsub,string,TERMIOS,Bastion,rexec # Create a graph of every (i.e. internal and external) dependencies in the # given file (report RP0402 must not be disabled) import-graph= # Create a graph of external dependencies in the given file (report RP0402 must # not be disabled) ext-import-graph= # Create a graph of internal dependencies in the given file (report RP0402 must # not be disabled) int-import-graph= [EXCEPTIONS] # Exceptions that will emit a warning when being caught. Defaults to # "Exception" overgeneral-exceptions=Exception cement-2.10.0/.travis.yml000066400000000000000000000002311274177370300151650ustar00rootroot00000000000000language: python sudo: false script: ./scripts/travis.sh os: - linux python: - 2.6 - 2.7 - 3.3 - 3.4 - 3.5 services: - memcached - redis cement-2.10.0/CONTRIBUTORS000066400000000000000000000004741274177370300147450ustar00rootroot00000000000000Contributors ============ The following people have contributed to Cement, either by way of source code, documentation, or testing. * BJ Dierkes (derks) - Creator, Primary Maintainer * Kyle Rockman (rocktavious) * Tomasz Czyż (spinus) * Ildar Akhmetgaleev (akhilman) * Nicolas Brisac (zacbri) cement-2.10.0/ChangeLog000077500000000000000000000531321274177370300146410ustar00rootroot00000000000000.. _changelog: ChangeLog ============================================================================== All bugs/feature details can be found at: https://github.com/datafolklabs/cement/issues/XXXXX Where XXXXX is the 'Issue #' referenced below. Additionally, this change log is available online at: http://builtoncement.com/2.8/changes/ See the :ref:`upgrading` section for more information related to any incompatible changes, and how to update your application to fix them. Also check out the :ref:`whats_new` section for details on new features. 2.10.0 - Thu July 14, 2016 ------------------------------------------------------------------------------ Bugs: * :issue:`363` - CementTestCase does not delete temporary files/directories * :issue:`346` - AttributeError: 'module' object has no attribute 'SIGHUP' on Windows * :issue:`352` - ``CementApp.extend()`` breaks on ``CementApp.reload()`` * :issue:`366` - Output handler override options dissappear * :issue:`385` - JsonOutputHandler/YamlOutputHandler/MustacheOutputHandler Do not pass keyword args down to backend render functions * :issue:`393` - ``CementApp.Meta.hooks`` ignored for hooks defined by extensions Features: * :issue:`350` - Support for plugin directories * :issue:`370` - Handlebars templating support * :pr:`371` - Jinja2 templating support * :issue:`373` - Switch over to using Flake8 for PEP8 and style compliance * :pr:`375` - Redis cache handler support * :issue:`379` - Support for alternative config file extensions * :issue:`380` - Support for Cython/Compiled Plugins * :issue:`389` - ConfigObj support for Python 3 * :issue:`394` - Watchdog extension for cross-platform filesystem event monitoring * :issue:`395` - Ability to pass metadata keyword arguments to handlers via ``CementApp.Meta.meta_defaults``. Refactoring; * :issue:`386` - Partially deprecated use of ``imp`` in favor of ``importlib`` on Python >= 3.1 * :issue:`390` - ArgparseArgumentHandler should store unknown arguments Incompatible: * None Deprecation: * :issue:`365` - Deprecated ``LoggingLogHandler.warn()`` * :issue:`372` - Deprecated Explicit Python 3.2 Support * :issue:`376` - Deprecated ``cement.core.interface.list()`` 2.8.0 - Wed Feb 24, 2016 ------------------------------------------------------------------------------ Bugs: * :issue:`310` - Resolved issue where console/file logs had duplicate entries under certain circumstances. * :issue:`314` - Resolved inconsistent behavor in ``colorlog`` extension. * :issue:`316` - Running Nose tests with ``-s`` option causes traceback * :issue:`317` - Calling ``CementApp.run()`` should return results from ``Controller._dispatch()`` * :issue:`320` - Partials not rendering with Mustache templates * :issue:`325` - Wrap Utility Doesn't Support Unicode * :issue:`328` - Post Run Hook Not Executing * :issue:`331` - KeyError: 'USER' When Running Nose Tests * :issue:`338` - Support non-ascii encoding for email subject and body Features: * :issue:`205` - Added new ``ArgparseController`` and ``expose`` decorator in ``ext_argparse`` to eventually replace ``CementBaseController``. * :issue:`299` - Added Argcomplete Framework Extension * :issue:`322` - Added Tabulate Framework Extension (tabulatized output) * :issue:`336` - Added Support for ``CementApp.reload()`` (SIGHUP) * :issue:`337` - Added ``app.run_forever()`` alternative run method. * :issue:`342` - Added Alarm/Timeout Support * :issue:`343` - Memcached Extension/Pylibmc Now Supports Python 3 Refactoring: * :issue:`311` - Refactor Hooks/Handlers into CementApp * :issue:`319` - Use ``os.devnull`` instead of internal ``NullOut`` hack. Incompatible: * :issue:`311` - Hook ``signal`` now requires ``app`` argument. * :issue:`313` - Default ``Cement.Meta.exit_on_close`` to ``False``. Calls to ``sys.exit()`` should be explicit by the app developer, and not implied by the framework. * :issue:`332` - Output Handler Interface Must Support Keyword Arguments 2.6.0 - Thu May 14, 2015 ------------------------------------------------------------------------------ Bugs: * :issue:`294` - Added work-around for scenario where an app wants to support arbitrary positional argument with a value of ``default``. By default, this will attempt to explicitly call the ``default`` command rather than using ``default`` as the argument. This fix adds ``CementBaseController.Meta.default_func`` allowing the developer to override the name of the default function that is called if no matching sub-command is passed. Features: * :issue:`197` - Added support for colorized logging. * :issue:`281` - Added support for Python `with` statement. * :issue:`282` - Added support to define/register hooks and handlers via ``CementApp.Meta``. * :issue:`290` - Added ability to disable Cement framework logging via ``CementApp.Meta.framework_logging = False``. * :issue:`297` - Added **experimental** support for reloading configurations anytime config files and/or plugin config files are modified. Optional extension `ext_reload_config`. Incompatible: * :issue:`308` - No longer require explicit ``CementApp.Meta.base_controller`` if a controller with the label of ``base`` is registered. This is potentially backward in-compatible in that previously ``CementBaseController.Meta.label`` defaulted to ``base``. It now defaults to ``None``, which makes more sense but will break for any controllers that have not explicitly set a ``label`` of ``base``. 2.4.0 - Wed Sep 17, 2014 ------------------------------------------------------------------------------ Bugs: * :issue:`211` - LoggingLogHandler namespace causes issues (regression) * :issue:`235` - Duplicate Config Section when plugin already loaded * :issue:`246` - Plugin extension does not disable after already being enabled Features: * :issue:`119` - Added cement.utils.shell.Prompt to quickly gather user input in several different ways. * :issue:`182` - Added a mail interface with basic implementations of 'dummy' (just prints message to console) and 'smtp' * :issue:`229` - Ability to override handlers via command line options. Also related: :issue:`225`. * :issue:`248` - Added documentation for BASH Auto-Completion example. * :issue:`249` - Allow utils.shell.exec_cmd* to accept additional. parameters, passing all `args` and `kwargs` down to subprocess.Popen. Allows features such as changing the current working directory, and setting a timeout value, etc (everything that Popen supports). * :issue:`257` - CementBaseController._dispatch() should return result of controller function. * :issue:`259` - Add yaml and yaml_configobj config handlers. * :issue:`262` - Add json and json_configobj config handlers. * :issue:`267` - Add support for multiple `plugin_dirs` and `plugin_config_dirs` * :issue:`269` - Allow app.close() to accept an exit code, and exit with that code. * :issue:`270` - Add support for multiple template_dirs * :issue:`274` - Add cement.core.interface.list function * :issue:`275` - Added `examples/` directory with working examples based on Examples section of the documentation. Incompatible: * :issue:`227` - Standardize handler config section naming conventions. All handler config sections are now labeled after ``interface.handler`` (i.e. ``output.json``, or ``mail.sendgrid``, etc). * :issue:`229` - Handler override options deprecate the use of ``--json``, and ``--yaml`` output handler options. * :issue:`260` - Extensions/Plugins/Bootstrap modules must accept `app` argument in `load()` function. See Upgrading doc for more information. 2.2.0 - Wed Jan 29, 2014 ------------------------------------------------------------------------------ Bugs: * :issue:`211` - LoggingLogHandler namespace causes issues * :issue:`215` - Epilog not printed on --help Features: * :issue:`209` - Added app.debug property to allow developers to know if `--debug` was passed at command line of via the config * :issue:`219` - Merged ext.memcached into mainline * :issue:`222` - Merged ext.configobj into mainline * :issue:`223` - Merged ext.genshi into mainline * :issue:`224` - Merged ext.yaml into mainline Incompatible: * :issue:`202` - Deprecated namespace packaging for cement and cement.ext. Resolves issues with certain IDE's and other situations where the lack of a proper ``__init__.py`` causes issues. This change means that external extensions can no longer share the ``cement.ext`` module namespace, and must have it's own unique module path. Misc: * Official Git repo relocated to: http://github.com/datafolklabs/cement 2.1.4 - Tue Oct 29, 2013 ------------------------------------------------------------------------------ Bugs: * :issue:`191` - KeyError when using minimal logger with --debug * :issue:`199` - Moved post_argument_parsing hook down, after arguments_override_config logic happens. * :issue:`204` - utils.misc.wrap should handle None type * :issue:`208` - LoggingLogHandler does not honor Meta.config_section Features: * :issue:`190` - Merged daemon extension into core * :issue:`194` - Added pre_argument_parsing/post_argument_parsing hooks * :issue:`196` - Added utils.misc.wrap * :issue:`200` - Merged ext.mustache into mainline. * :issue:`203` - Added support for external template directory * :issue:`207` - Added support for alternative 'display' name for stacked controllers Incompatible: * :issue:`163` - LoggingLogHandler.Meta.clear_loggers was changed from a boolean option, to a list. Additionally, LoggingLogHandler.clear_loggers() now requires a `namespace` argument. ILog interface no longer defines `clear_loggers()` as a required function (though ILog interfaces are welcome to implement one if necessary). * :issue:`173` - Deprecated 'has_key()' from configparser extension * :issue:`201` - Add Deprecation Warning for CementApp.get_last_rendered() 2.1.2 - Thu Nov 1st, 2012 ------------------------------------------------------------------------------ This is a branch off of the 2.0.x stable code base. Maintenance releases for 2.0.x will happen under the stable/2.0.x git branch, while forward feature development will happen here under as 2.1.x under the git master branch. Bugs: * :issue:`162` - Unable to set log 'level' by config * :issue:`167` - Non-stacked controllers not listed in --help * :issue:`169` - Fixed tests.utils.shell_tests timeout issue * :issue:`171` - No handlers could be found for logger * :issue:`183` - os.environ['HOME'] does not exist on Windows Features: * :issue:`161` - Ability to override `usage` * :issue:`164` - Store previously rendered data as app._last_rendered, and retrievable by app.get_last_rendered(). * :issue:`165` - Allow utils.fs.backup() to support a suffix kwarg * :issue:`166` - Ability to set the 'app' for CementTestCase.make_app() * :issue:`170` - Added support for `nested` and `embedded` controllers. Misc: * :issue:`172` - 100% PEP8 Compliant * :issue:`160` - Refactor CementApp._resolve_handler() as handler.resolve() Deprecation Notices: * :issue:`173` - ConfigParserConfigHandler.has_key() is now deprecated, and will be removed in future versions. Please use `if key in app.config.keys(section)` instead. Incompatible Changes: * :issue:`141` - Removed shortcuts from CementBaseController (such as log, pargs, etc). Use `self.app.` instead. * :issue:`167` - Listed above, in order to fix this issue as well as restrict future issues we implemented a hard requirement that all base controllers have the label 'base'. This should not be a major change for anyone using Cement 2.0.x as it is a simple 1 line change in any one application. As all documentation encourages the use of the label 'base' it should not be a wide spread incompatibility. * :issue:`179` - CementBaseController `hidden`, `visible`, and `exposed` have been removed, and replaced by other private means of managing the dispatch of commands. * CementBaseController no longer implements a `default` command. * :issue:`177` - Renamed several cement.core.backend pieces including: `handlers` -> `__handlers__`, `hooks` -> `__hooks__`, `SAVED_STDOUT` -> `__saved_stdout__`, and `SAVED_STDERR` -> `__saved_stderr__`. * :issue:`178` - Moved `backend.defaults()` to `utils.misc.init_defaults()`, and `backend.minimal_logger()` to `utils.misc.minimal_logger()` 2.0.0 - Fri Aug 03, 2012 ------------------------------------------------------------------------------ This is the initial stable release of the 2.0.x branch. Future releases of this branch will include bug/security fixes and minor feature updates. Forward moving feature development will continue out of the 2.1.x branch. Bugs: * :issue:`143` - Incorrect doc regarding logging. The LoggingLogHandler now supports an optional 'namespace' argument allowing the developer to override the log prefix. * :issue:`150` - foundation.CementApp.Meta.argv now defaults to None, but is overridden in __init__() with sys.argv if no other argv is passed as meta. Features: * :issue:`138` - Added 'shell' argument to utils.shell.exec_cmd() and utils.shell.exec_cmd2(). * :issue:`140` - Included ~/.myapp/config in default config search * :issue:`144` - Added a note on Contributing, as well as a CONTRIBUTORS file. * :issue:`152` - Added 'argument_formatter' to ControllerBaseClass.Meta. * :issue:`153` - Added spawn_process() and spawn_thread() to utils.shell. Incompatible Changes: * :issue:`100` - Interfaces audit. * ILog.level() redefined as ILog.get_level() * IPlugin.loaded_plugins attribute redefined as IPlugin.get_loaded_plugins() * IPlugin.enable_plugins attribute redefined as IPlugin.get_enabled_plugins() * IPlugin.disabled_plugins attribute redefined as IPlugin.get_disabled_plugins() * :issue:`145` - The IArgument interface no longer specifies that the `parsed_args` be maintained by the handler implementation. This means that `app.args.parsed_args` is no longer available, however `app.pargs` functions just the same as it points to `app._parsed_args`. * :issue:`148` - The CementExtensionHandler.loaded_extensions property is now a callable at CementExtensionHandler.get_loaded_extensions(). * :issue:`151` - Removed all previously deprecated code including: * Removed CementApp.Meta.defaults, and CementBaseHandler.Meta.defaults. Now use `config_defaults` instead. * Removed cement.foundation.lay_cement(). Now use CementApp directly. * Removed cement.handler.enabled(). Now use `handler.registered()` instead. * :issue:`154` - Validate for handler config_defaults and config_section by default. Only incompatible if not previously sub-classing from handler.CementBaseHandler. * :issue:`157` - CementRuntimeError renamed as FrameworkError * :issue:`158` - CementSignalError renamed as CaughtSignal * :issue:`159` - CementInterfaceError renamed as InterfaceError Misc: * :issue:`155` - Removed unused CementArgumentError, and CementConfigError. These types of exceptions should be defined at the application level. 1.9.14 - Sun Jul 16, 2012 ------------------------------------------------------------------------------ Bugs: * :issue:`127` - Inherited positional arguments listed multiple times Feature Enhancements: * :issue:`131` - Controller aliases * :issue:`126` - Add a 'bootstrap' importer to CementApp * Added cement.utils.test.CementTestCase for improved testing. Incompatible Changes: * :issue:`129` - Simplify extensions/plugins/hooks/etc. * Hooks renamed from 'cement_xxx_hook' to just 'xxx'. For example, the 'cement_pre_setup_hook' is now simply 'pre_setup'. Additionally, the 'cement_on_close_hook' is now broken out into 'pre_close', and 'post_close'. * The cement.core.hooks.register decorator was replaced with a simple function of the same name. New usage is: register('hook_name', hook_func). * Plugins, extensions, and the application bootstrap now attempt to call a 'load()' function, meaning library code and loading code can live in the same file (i.e. hooks won't be registered just because you imported an extension to sub-class a handler, etc). * cement.utils.test_helper moved to cement.utils.test. * By default, command line arguments no longer override config settings. This is now configurable by the CementApp.Meta.arguments_override_config boolean. Related: :issue:`136`. 1.9.12 - Thu Jul 05, 2012 ------------------------------------------------------------------------------ Bugs: * Fixed version mis-hap in setup.py 1.9.10 - Wed Jul 04, 2012 ------------------------------------------------------------------------------ Feature Enhancements: * :issue:`118` - Added utils.fs.backup() to safely backup files/dirs. Misc: * :issue:`111` - Use relative imports (makes cement more portable as it can be included and distributed with 3rd party sources). * :issue:`120` - Use standard json rather than relying on jsonpickle Incompatible Changes: * core.util.abspath moved to utils.fs.abspath * core.util.is_true moved to utils.misc.is_true * Namespace reverted from 'cement2' back to 'cement'. * The following extensions have been removed from the cement source tree, and are now available externally (see: http://github.com/cement): daemon, memcached, configobj, yaml, genshi. 1.9.8 - Thu May 3, 2012 ------------------------------------------------------------------------------ Feature Enhancements: * :issue:`95` - Add a 'config_section' Meta default for all handlers. Required to parse config options for a handler. * :issue:`97` - Add a standard cache handler interface. * :issue:`105` - Add 'meta_override' and 'core_meta_override' list to CementApp().Meta. Also resolves :issue:`104`. * :issue:`108` - Add CementApp.extend() functionality. * :issue:`109` - Add cement.ext.memcached extension Incompatible Changes: * :issue:`103` - plugin_bootstrap_module renamed as plugin_bootstrap. * :issue:`106` - Deprecate Meta.defaults in favor of Meta.config_defaults * :issue:`107` - Make the app name the default config section, not [base] 1.9.6 - Wed Apr 18, 2012 ------------------------------------------------------------------------------ Bug Fixes: * :issue:`89` - Secondary controllers display under other controllers * :issue:`90` - Logging to file doesn't expand '~' * :issue:`91` - Logging to file doesn't create basedir Feature Enhancements: * :issue:`88` - Add cement.ext.genshi extension, provides Genshi Text Templating Launguage support. * :issue:`93` - Add epilog support for CementBaseController. Refactoring: * :issue:`87` - Refactor Meta handling Incompatible Changes: * :issue:`96` - Move 'setup()' functions to '_setup()' * Moved CementBaseController.dispatch() to _dispatch() * Moved CementBaseController.usage_text to _usage_text() * Moved CementBaseController.help_text to _help_text() * backend.defaults() no longer accepts an app name as an argument. * foundation.lay_cement() is deprecated. Use foundation.CementApp() directly. * No longer pass anything but 'app' object to handlers _setup() functions. * handler.enabled() is deprecated. Use handler.registered(). 1.9.4 - Wed Dec 21, 2011 ------------------------------------------------------------------------------ Bug Fixes: * :issue:`73` - Hooks broken in Python 3 * :issue:`81` - Controller defaults should be processed before base controller.setup() Feature Enhancements: * :issue:`65` - Added 'daemon' extension. Process is daemonized by passing the '--daemon' option. Handles switching the run user/group, as well as managing a pid file. * :issue:`72` - Added new framework hooks. * :issue:`76` - Added app.close() functionality including a cement_on_close_hook() allowing plugins/extensions/etc to be able to cleanup on application exit. * :issue:`77` - Added default signal handler for SIGINT/SIGTERM as well as the cement_signal_hook which is called when any catch_signals are encountered. * :issue:`78` - Added cement_pre_render_hook, and cement_post_render_hook allowing developers to control the data that is rendered to console. * :issue:`84` - Ability to run all tests from utils/run_tests.sh Incompatible Changes: * :issue:`72` - The framework hooks 'cement_add_args_hook' and 'cement_validate_config' were removed in favor of the new pre/post setup and run hooks. * :issue:`82` - Change 'meta' classes to Python-proper 'Meta', and interfaces to use 'IMeta'. Old functionality will be completely removed before Cement stable release. 1.9.2 - Wed Nov 02, 2011 ------------------------------------------------------------------------------ This is an initial beta release of Cement, and therefore no bugs or features are listed. Future releases will detail all changes. cement-2.10.0/LICENSE000077500000000000000000000030321274177370300140660ustar00rootroot00000000000000.. _license: License ======= Copyright (c) 2009-2016 Data Folk Labs, LLC All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Data Folk Labs, LLC. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. cement-2.10.0/README.md000066400000000000000000000057211274177370300143440ustar00rootroot00000000000000Cement Framework ================ Cement is an advanced CLI Application Framework for Python. Its goal is to introduce a standard, and feature-full platform for both simple and complex command line applications as well as support rapid development needs without sacrificing quality. Cement is flexible, and it's use cases span from the simplicity of a micro-framework to the complexity of a mega-framework. Whether it's a single file script, or a multi-tier application, Cement is the foundation you've been looking for. The first commit to Git was on Dec 4, 2009. Since then, the framework has seen several iterations in design, and has continued to grow and improve since it's inception. Cement is the most stable, and complete framework for command line and backend application development. [![Continuous Integration Status](https://travis-ci.org/datafolklabs/cement.svg)](https://travis-ci.org/datafolklabs/cement) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/datafolklabs/cement?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) Cement core features include (but are not limited to): * Core pieces of the framework are customizable via handlers/interfaces * Extension handler interface to easily extend framework functionality * Config handler supports parsing multiple config files into one config * Argument handler parses command line arguments and merges with config * Log handler supports console and file logging * Plugin handler provides an interface to easily extend your application * Hook support adds a bit of magic to apps and also ties into framework * Handler system connects implementation classes with Interfaces * Output handler interface renders return dictionaries to console * Cache handler interface adds caching support for improved performance * Controller handler supports sub-commands, and nested controllers * Zero external dependencies* (not including optional extensions) * 100% test coverage using `nose` and `coverage` * 100% PEP8 and style compliant using `flake8` * Extensive Sphinx documentation * Tested on Python 2.6, 2.7, 3.3, 3.4, and 3.5 *Note that argparse is required as an external dependency for Python < 2.7 and < 3.2. Additionally, some optional extensions that are shipped with the mainline Cement sources do require external dependencies. It is the responsibility of the application developer to include these dependencies along with their application, as Cement explicitly does not include them.* More Information ---------------- * DOCS: http://builtoncement.com/2.10/ * CODE: http://github.com/datafolklabs/cement/ * PYPI: http://pypi.python.org/pypi/cement/ * SITE: http://builtoncement.com/ * T-CI: https://travis-ci.org/datafolklabs/cement * HELP: cement@librelist.org - #cement - gitter.im/datafolklabs/cement License ------- The Cement CLI Application Framework is Open Source and is distributed under the BSD License (three clause). Please see the LICENSE file included with this software. cement-2.10.0/Vagrantfile000066400000000000000000000025571274177370300152560ustar00rootroot00000000000000Vagrant.configure("2") do |config| config.vm.define "ubuntu", primary: true do |this| this.vm.box = "ubuntu" this.vm.hostname = "ubuntu" this.vm.box_url = "https://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box" this.vm.provision "shell", inline: "/vagrant/scripts/vagrant/up.sh" end config.vm.define "ubuntu-12.04", autostart: false do |this| this.vm.box = "ubuntu-12.04" this.vm.hostname = "ubuntu-12.04" this.vm.box_url = "https://cloud-images.ubuntu.com/vagrant/precise/current/precise-server-cloudimg-amd64-vagrant-disk1.box" this.vm.provision "shell", inline: "/vagrant/scripts/vagrant/up.sh" end config.vm.define "ubuntu-14.04", autostart: false do |this| this.vm.box = "ubuntu-14.04" this.vm.hostname = "ubuntu-14.04" this.vm.box_url = "https://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box" this.vm.provision "shell", inline: "/vagrant/scripts/vagrant/up.sh" end config.vm.define "windows-server-2012-r2", autostart: false do |this| this.vm.box = "opentable/win-2012r2-standard-amd64-nocm" this.vm.hostname = "windows-server-2012-r2" this.vm.box_url = "opentable/win-2012r2-standard-amd64-nocm" end config.vm.provider "virtualbox" do |vb| vb.memory = 2048 vb.cpus = 2 vb.gui = true end end cement-2.10.0/cement/000077500000000000000000000000001274177370300143335ustar00rootroot00000000000000cement-2.10.0/cement/__init__.py000066400000000000000000000000001274177370300164320ustar00rootroot00000000000000cement-2.10.0/cement/core/000077500000000000000000000000001274177370300152635ustar00rootroot00000000000000cement-2.10.0/cement/core/__init__.py000066400000000000000000000000001274177370300173620ustar00rootroot00000000000000cement-2.10.0/cement/core/arg.py000066400000000000000000000074521274177370300164160ustar00rootroot00000000000000""" Cement core argument module. """ from ..core import interface from ..core.handler import CementBaseHandler from ..utils.misc import minimal_logger LOG = minimal_logger(__name__) # pylint: disable=w0613 def argument_validator(klass, obj): """Validates a handler implementation against the IArgument interface.""" members = [ '_setup', 'parse', 'add_argument', ] interface.validate(IArgument, obj, members) # pylint: disable=W0105,W0232,W0232,R0903,E0213,R0923 class IArgument(interface.Interface): """ This class defines the Argument Handler Interface. Classes that implement this handler must provide the methods and attributes defined below. Implementations do *not* subclass from interfaces. Example: .. code-block:: python from cement.core import interface, arg class MyArgumentHandler(arg.CementArgumentHandler): class Meta: interface = arg.IArgument label = 'my_argument_handler' """ class IMeta: """Interface meta-data options.""" label = 'argument' """The string identifier of the interface.""" validator = argument_validator """Interface validator function.""" # Must be provided by the implementation Meta = interface.Attribute('Handler Meta-data') def _setup(app_obj): """ The _setup function is called during application initialization and must 'setup' the handler object making it ready for the framework or the application to make further calls to it. :param app_obj: The application object :returns: ``None`` """ # pylint: disable=E0211 def add_argument(*args, **kw): """ Add arguments for parsing. This should be -o/--option or positional. Note that the interface defines the following parameters so that at the very least, external extensions can guarantee that they can properly add command line arguments when necessary. The implementation itself should, and will provide and support many more options than those listed here. That said, the implementation must support the following: :arg args: List of option arguments. Generally something like ['-h', '--help']. :keyword dest: The destination name (var). Default: arg[0]'s string. :keyword help: The help text for --help output (for that argument). :keyword action: Must support: ['store', 'store_true', 'store_false', 'store_const'] :keyword choices: A list of valid values that can be passed to an option whose action is ``store``. :keyword const: The value stored if action == 'store_const'. :keyword default: The default value. :returns: ``None`` """ def parse(arg_list): """ Parse the argument list (i.e. sys.argv). Can return any object as long as it's members contain those of the added arguments. For example, if adding a '-v/--version' option that stores to the dest of 'version', then the member must be callable as 'Object().version'. :param arg_list: A list of command line arguments. :returns: Callable object """ # pylint: disable=W0105 class CementArgumentHandler(CementBaseHandler): """Base class that all Argument Handlers should sub-class from.""" class Meta: """ Handler meta-data (can be passed as keyword arguments to the parent class). """ label = None """The string identifier of the handler implementation.""" interface = IArgument """The interface that this class implements.""" def __init__(self, *args, **kw): super(CementArgumentHandler, self).__init__(*args, **kw) cement-2.10.0/cement/core/backend.py000066400000000000000000000003111274177370300172170ustar00rootroot00000000000000"""Cement core backend module.""" VERSION = (2, 10, 0, 'final', 0) # pragma: nocover # global hooks/handlers (DEPRECATED) __handlers__ = {} # pragma: nocover __hooks__ = {} # pragma: nocover cement-2.10.0/cement/core/cache.py000066400000000000000000000066701274177370300167110ustar00rootroot00000000000000"""Cement core cache module.""" from ..core import interface, handler from ..utils.misc import minimal_logger LOG = minimal_logger(__name__) def cache_validator(klass, obj): """Validates a handler implementation against the ICache interface.""" members = [ '_setup', 'get', 'set', 'delete', 'purge', ] interface.validate(ICache, obj, members) class ICache(interface.Interface): """ This class defines the Cache Handler Interface. Classes that implement this handler must provide the methods and attributes defined below. Implementations do *not* subclass from interfaces. Usage: .. code-block:: python from cement.core import cache class MyCacheHandler(object): class Meta: interface = cache.ICache label = 'my_cache_handler' ... """ # pylint: disable=W0232, C0111, R0903 class IMeta: """Interface meta-data.""" label = 'cache' """The label (or type identifier) of the interface.""" validator = cache_validator """Interface validator function.""" # Must be provided by the implementation Meta = interface.Attribute('Handler meta-data') def _setup(app_obj): """ The _setup function is called during application initialization and must 'setup' the handler object making it ready for the framework or the application to make further calls to it. :param app_obj: The application object. :returns: ``None`` """ def get(key, fallback=None): """ Get the value for a key in the cache. If the key does not exist or the key/value in cache is expired, this functions must return 'fallback' (which in turn must default to None). :param key: The key of the value stored in cache :param fallback: Optional value that is returned if the cache is expired or the key does not exist. Default: None :returns: Unknown (whatever the value is in cache, or the `fallback`) """ def set(key, value, time=None): """ Set the key/value in the cache for a set amount of `time`. :param key: The key of the value to store in cache. :param value: The value of that key to store in cache. :param time: A one-off expire time. If no time is given, then a default value is used (determined by the implementation). :type time: ``int`` (seconds) or ``None`` :returns: ``None`` """ def delete(key): """ Deletes a key/value from the cache. :param key: The key in the cache to delete. :returns: True if the key is successfully deleted, False otherwise. :rtype: ``boolean`` """ # pylint: disable=E0211 def purge(): """ Clears all data from the cache. """ class CementCacheHandler(handler.CementBaseHandler): """ Base class that all Cache Handlers should sub-class from. """ class Meta: """ Handler meta-data (can be passed as keyword arguments to the parent class). """ label = None """String identifier of this handler implementation.""" interface = ICache """The interface that this handler class implements.""" def __init__(self, *args, **kw): super(CementCacheHandler, self).__init__(*args, **kw) cement-2.10.0/cement/core/config.py000066400000000000000000000151761274177370300171140ustar00rootroot00000000000000"""Cement core config module.""" import os from ..core import interface, handler from ..utils.fs import abspath from ..utils.misc import minimal_logger LOG = minimal_logger(__name__) def config_validator(klass, obj): """Validates a handler implementation against the IConfig interface.""" members = [ '_setup', 'keys', 'get_sections', 'get_section_dict', 'get', 'set', 'parse_file', 'merge', 'add_section', 'has_section', ] interface.validate(IConfig, obj, members) class IConfig(interface.Interface): """ This class defines the Config Handler Interface. Classes that implement this handler must provide the methods and attributes defined below. All implementations must provide sane 'default' functionality when instantiated with no arguments. Meaning, it can and should accept optional parameters that alter how it functions, but can not require any parameters. When the framework first initializes handlers it does not pass anything too them, though a handler can be instantiated first (with or without parameters) and then passed to 'CementApp()' already instantiated. Implementations do *not* subclass from interfaces. Usage: .. code-block:: python from cement.core import config class MyConfigHandler(config.CementConfigHandler): class Meta: interface = config.IConfig label = 'my_config_handler' ... """ # pylint: disable=W0232, C0111, R0903 class IMeta: """Interface meta-data.""" label = 'config' """The string identifier of the interface.""" validator = config_validator """The validator function.""" # Must be provided by the implementation Meta = interface.Attribute('Handler Meta-data') def _setup(app_obj): """ The _setup function is called during application initialization and must 'setup' the handler object making it ready for the framework or the application to make further calls to it. :param app_obj: The application object. :returns: None """ def parse_file(file_path): """ Parse config file settings from file_path. Returns True if the file existed, and was parsed successfully. Returns False otherwise. :param file_path: The path to the config file to parse. :returns: True if the file was parsed, False otherwise. :rtype: ``boolean`` """ def keys(section): """ Return a list of configuration keys from `section`. :param section: The config [section] to pull keys from. :returns: A list of keys in `section`. :rtype: ``list`` """ def get_sections(): """ Return a list of configuration sections. These are designated by a [block] label in a config file. :returns: A list of config sections. :rtype: ``list`` """ def get_section_dict(section): """ Return a dict of configuration parameters for [section]. :param section: The config [section] to generate a dict from (using that section keys). :returns: A dictionary of the config section. :rtype: ``dict`` """ def add_section(section): """ Add a new section if it doesn't exist. :param section: The [section] label to create. :returns: ``None`` """ def get(section, key): """ Return a configuration value based on [section][key]. The return value type is unknown. :param section: The [section] of the configuration to pull key value from. :param key: The configuration key to get the value from. :returns: The value of the `key` in `section`. :rtype: ``Unknown`` """ def set(section, key, value): """ Set a configuration value based at [section][key]. :param section: The [section] of the configuration to pull key value from. :param key: The configuration key to set the value at. :param value: The value to set. :returns: ``None`` """ def merge(dict_obj, override=True): """ Merges a dict object into the configuration. :param dict_obj: The dictionary to merge into the config :param override: Boolean. Whether to override existing values. Default: True :returns: ``None`` """ def has_section(section): """ Returns whether or not the section exists. :param section: The section to test for. :returns: ``boolean`` """ class CementConfigHandler(handler.CementBaseHandler): """ Base class that all Config Handlers should sub-class from. """ class Meta: """ Handler meta-data (can be passed as keyword arguments to the parent class). """ label = None """The string identifier of the implementation.""" interface = IConfig """The interface that this handler implements.""" def __init__(self, *args, **kw): super(CementConfigHandler, self).__init__(*args, **kw) def _parse_file(self, file_path): """ Parse a configuration file at `file_path` and store it. This function must be provided by the handler implementation (that is sub-classing this). :param file_path: The file system path to the configuration file. :returns: True if file was read properly, False otherwise :rtype: ``boolean`` """ raise NotImplementedError def parse_file(self, file_path): """ Ensure we are using the absolute/expanded path to `file_path`, and then call `_parse_file` to parse config file settings from it, overwriting existing config settings. If the file does not exist, returns False. Developers sub-classing from here should generally override `_parse_file` which handles just the parsing of the file and leaving this function to wrap any checks/logging/etc. :param file_path: The file system path to the configuration file. :returns: ``boolean`` """ file_path = abspath(file_path) if os.path.exists(file_path): LOG.debug("config file '%s' exists, loading settings..." % file_path) return self._parse_file(file_path) else: LOG.debug("config file '%s' does not exist, skipping..." % file_path) return False cement-2.10.0/cement/core/controller.py000066400000000000000000000436341274177370300200320ustar00rootroot00000000000000"""Cement core controller module.""" import re import textwrap import argparse from ..core import exc, interface, handler from ..utils.misc import minimal_logger LOG = minimal_logger(__name__) def controller_validator(klass, obj): """ Validates a handler implementation against the IController interface. """ members = [ '_setup', '_dispatch', ] meta = [ 'label', 'interface', 'config_section', 'config_defaults', 'stacked_on', 'stacked_type', ] interface.validate(IController, obj, members, meta=meta) # also check _meta.arguments values errmsg = "Controller arguments must be a list of tuples. I.e. " + \ "[ (['-f', '--foo'], dict(action='store')), ]" if obj._meta.arguments is not None: if type(obj._meta.arguments) is not list: raise exc.InterfaceError(errmsg) for item in obj._meta.arguments: if type(item) is not tuple: raise exc.InterfaceError(errmsg) if type(item[0]) is not list: raise exc.InterfaceError(errmsg) if type(item[1]) is not dict: raise exc.InterfaceError(errmsg) if not obj._meta.label == 'base' and obj._meta.stacked_on is None: errmsg = "Controller `%s` is not stacked anywhere!" % \ obj.__class__.__name__ raise exc.InterfaceError(errmsg) if not obj._meta.label == 'base' and \ obj._meta.stacked_type not in ['nested', 'embedded']: raise exc.InterfaceError( "Controller '%s' " % obj._meta.label + "has an unknown stacked type of '%s'." % obj._meta.stacked_type ) class IController(interface.Interface): """ This class defines the Controller Handler Interface. Classes that implement this handler must provide the methods and attributes defined below. Implementations do *not* subclass from interfaces. Usage: .. code-block:: python from cement.core import controller class MyBaseController(controller.CementBaseController): class Meta: interface = controller.IController ... """ # pylint: disable=W0232, C0111, R0903 class IMeta: """Interface meta-data.""" #: The string identifier of the interface. label = 'controller' #: The interface validator function. validator = controller_validator # Must be provided by the implementation Meta = interface.Attribute('Handler meta-data') def _setup(app_obj): """ The _setup function is after application initialization and after it is determined that this controller was requested via command line arguments. Meaning, a controllers _setup() function is only called right before it's _dispatch() function is called to execute a command. Must 'setup' the handler object making it ready for the framework or the application to make further calls to it. :param app_obj: The application object. :returns: ``None`` """ def _dispatch(self): """ Reads the application object's data to dispatch a command from this controller. For example, reading self.app.pargs to determine what command was passed, and then executing that command function. Note that Cement does *not* parse arguments when calling _dispatch() on a controller, as it expects the controller to handle parsing arguments (I.e. self.app.args.parse()). :returns: Returns the result of the executed controller function, or ``None`` if no controller function is called. """ class expose(object): """ Used to expose controller functions to be listed as commands, and to decorate the function with Meta data for the argument parser. :param help: Help text to display for that command. :type help: str :param hide: Whether the command should be visible. :type hide: boolean :param aliases: Aliases to this command. :param aliases_only: Whether to only display the aliases (not the label). This is useful for situations where you have obscure function names which you do not want displayed. Effecively, if there are aliases and `aliases_only` is True, then aliases[0] will appear as the actual command/function label. :type aliases: ``list`` Usage: .. code-block:: python from cement.core.controller import CementBaseController, expose class MyAppBaseController(CementBaseController): class Meta: label = 'base' @expose(hide=True, aliases=['run']) def default(self): print("In MyAppBaseController.default()") @expose() def my_command(self): print("In MyAppBaseController.my_command()") """ # pylint: disable=W0622 def __init__(self, help='', hide=False, aliases=[], aliases_only=False): self.hide = hide self.help = help self.aliases = aliases self.aliases_only = aliases_only def __call__(self, func): metadict = {} metadict['label'] = re.sub('_', '-', func.__name__) metadict['func_name'] = func.__name__ metadict['exposed'] = True metadict['hide'] = self.hide metadict['help'] = self.help or func.__doc__ metadict['aliases'] = self.aliases metadict['aliases_only'] = self.aliases_only metadict['controller'] = None # added by the controller func.__cement_meta__ = metadict return func # pylint: disable=R0921 class CementBaseController(handler.CementBaseHandler): """ This is an implementation of the `IControllerHandler <#cement.core.controller.IController>`_ interface, but as a base class that application controllers `should` subclass from. Registering it directly as a handler is useless. NOTE: This handler **requires** that the applications 'arg_handler' be argparse. If using an alternative argument handler you will need to write your own controller base class. NOTE: This the initial default implementation of CementBaseController. In the future it will be replaced by CementBaseController2, therefore using CementBaseController2 is recommended for new development. Usage: .. code-block:: python from cement.core.controller import CementBaseController class MyAppBaseController(CementBaseController): class Meta: label = 'base' description = 'MyApp is awesome' config_defaults = dict() arguments = [] epilog = "This is the text at the bottom of --help." # ... class MyStackedController(CementBaseController): class Meta: label = 'second_controller' aliases = ['sec', 'secondary'] stacked_on = 'base' stacked_type = 'embedded' # ... """ class Meta: """ Controller meta-data (can be passed as keyword arguments to the parent class). """ interface = IController """The interface this class implements.""" label = None """The string identifier for the controller.""" aliases = [] """ A list of aliases for the controller. Will be treated like command/function aliases for non-stacked controllers. For example: ``myapp --help`` is the same as ``myapp --help``. """ aliases_only = False """ When set to True, the controller label will not be displayed at command line, only the aliases will. Effectively, aliases[0] will appear as the label. This feature is useful for the situation Where you might want two controllers to have the same label when stacked on top of separate controllers. For example, 'myapp users list' and 'myapp servers list' where 'list' is a stacked controller, not a function. """ description = None """The description shown at the top of '--help'. Default: None""" config_section = None """ A config [section] to merge config_defaults into. Cement will default to controller.