`_
+
+Basic Concepts
+--------------
+
+Click is based on declaring commands through decorators. Internally, there
+is a non-decorator interface for advanced use cases, but it's discouraged
+for high-level usage.
+
+A function becomes a Click command line tool by decorating it through
+:func:`click.command`. At its simplest, just decorating a function
+with this decorator will make it into a callable script:
+
+.. click:example::
+
+ import click
+
+ @click.command()
+ def hello():
+ click.echo('Hello World!')
+
+What's happening is that the decorator converts the function into a
+:class:`Command` which then can be invoked::
+
+ if __name__ == '__main__':
+ hello()
+
+And what it looks like:
+
+.. click:run::
+
+ invoke(hello, args=[], prog_name='python hello.py')
+
+And the corresponding help page:
+
+.. click:run::
+
+ invoke(hello, args=['--help'], prog_name='python hello.py')
+
+Echoing
+-------
+
+Why does this example use :func:`echo` instead of the regular
+:func:`print` function? The answer to this question is that Click
+attempts to support both Python 2 and Python 3 the same way and to be very
+robust even when the environment is misconfigured. Click wants to be
+functional at least on a basic level even if everything is completely
+broken.
+
+What this means is that the :func:`echo` function applies some error
+correction in case the terminal is misconfigured instead of dying with an
+:exc:`UnicodeError`.
+
+As an added benefit, starting with Click 2.0, the echo function also
+has good support for ANSI colors. It will automatically strip ANSI codes
+if the output stream is a file and if colorama is supported, ANSI colors
+will also work on Windows. See :ref:`ansi-colors` for more information.
+
+If you don't need this, you can also use the `print()` construct /
+function.
+
+Nesting Commands
+----------------
+
+Commands can be attached to other commands of type :class:`Group`. This
+allows arbitrary nesting of scripts. As an example here is a script that
+implements two commands for managing databases:
+
+.. click:example::
+
+ @click.group()
+ def cli():
+ pass
+
+ @click.command()
+ def initdb():
+ click.echo('Initialized the database')
+
+ @click.command()
+ def dropdb():
+ click.echo('Dropped the database')
+
+ cli.add_command(initdb)
+ cli.add_command(dropdb)
+
+As you can see, the :func:`group` decorator works like the :func:`command`
+decorator, but creates a :class:`Group` object instead which can be given
+multiple subcommands that can be attached with :meth:`Group.add_command`.
+
+For simple scripts, it's also possible to automatically attach and create a
+command by using the :meth:`Group.command` decorator instead. The above
+script can instead be written like this:
+
+.. click:example::
+
+ @click.group()
+ def cli():
+ pass
+
+ @cli.command()
+ def initdb():
+ click.echo('Initialized the database')
+
+ @cli.command()
+ def dropdb():
+ click.echo('Dropped the database')
+
+Adding Parameters
+-----------------
+
+To add parameters, use the :func:`option` and :func:`argument` decorators:
+
+.. click:example::
+
+ @click.command()
+ @click.option('--count', default=1, help='number of greetings')
+ @click.argument('name')
+ def hello(count, name):
+ for x in range(count):
+ click.echo('Hello %s!' % name)
+
+What it looks like:
+
+.. click:run::
+
+ invoke(hello, args=['--help'], prog_name='python hello.py')
+
+.. _switching-to-setuptools:
+
+Switching to Setuptools
+-----------------------
+
+In the code you wrote so far there is a block at the end of the file which
+looks like this: ``if __name__ == '__main__':``. This is traditionally
+how a standalone Python file looks like. With Click you can continue
+doing that, but there are better ways through setuptools.
+
+There are two main (and many more) reasons for this:
+
+The first one is that setuptools automatically generates executable
+wrappers for Windows so your command line utilities work on Windows too.
+
+The second reason is that setuptools scripts work with virtualenv on Unix
+without the virtualenv having to be activated. This is a very useful
+concept which allows you to bundle your scripts with all requirements into
+a virtualenv.
+
+Click is perfectly equipped to work with that and in fact the rest of the
+documentation will assume that you are writing applications through
+setuptools.
+
+I strongly recommend to have a look at the :ref:`setuptools-integration`
+chapter before reading the rest as the examples assume that you will
+be using setuptools.
diff -Nru click-0.4.43+16.04.20160203/docs/setuptools.rst click-6.7/docs/setuptools.rst
--- click-0.4.43+16.04.20160203/docs/setuptools.rst 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/docs/setuptools.rst 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,139 @@
+.. _setuptools-integration:
+
+Setuptools Integration
+======================
+
+When writing command line utilities, it's recommended to write them as
+modules that are distributed with setuptools instead of using Unix
+shebangs.
+
+Why would you want to do that? There are a bunch of reasons:
+
+1. One of the problems with the traditional approach is that the first
+ module the Python interpreter loads has an incorrect name. This might
+ sound like a small issue but it has quite significant implications.
+
+ The first module is not called by its actual name, but the
+ interpreter renames it to ``__main__``. While that is a perfectly
+ valid name it means that if another piece of code wants to import from
+ that module it will trigger the import a second time under its real
+ name and all of a sudden your code is imported twice.
+
+2. Not on all platforms are things that easy to execute. On Linux and OS
+ X you can add a comment to the beginning of the file (``#!/usr/bin/env
+ python``) and your script works like an executable (assuming it has
+ the executable bit set). This however does not work on Windows.
+ While on Windows you can associate interpreters with file extensions
+ (like having everything ending in ``.py`` execute through the Python
+ interpreter) you will then run into issues if you want to use the
+ script in a virtualenv.
+
+ In fact running a script in a virtualenv is an issue with OS X and
+ Linux as well. With the traditional approach you need to have the
+ whole virtualenv activated so that the correct Python interpreter is
+ used. Not very user friendly.
+
+3. The main trick only works if the script is a Python module. If your
+ application grows too large and you want to start using a package you
+ will run into issues.
+
+Introduction
+------------
+
+To bundle your script with setuptools, all you need is the script in a
+Python package and a ``setup.py`` file.
+
+Imagine this directory structure::
+
+ yourscript.py
+ setup.py
+
+Contents of ``yourscript.py``:
+
+.. click:example::
+
+ import click
+
+ @click.command()
+ def cli():
+ """Example script."""
+ click.echo('Hello World!')
+
+Contents of ``setup.py``::
+
+ from setuptools import setup
+
+ setup(
+ name='yourscript',
+ version='0.1',
+ py_modules=['yourscript'],
+ install_requires=[
+ 'Click',
+ ],
+ entry_points='''
+ [console_scripts]
+ yourscript=yourscript:cli
+ ''',
+ )
+
+The magic is in the ``entry_points`` parameter. Below
+``console_scripts``, each line identifies one console script. The first
+part before the equals sign (``=``) is the name of the script that should
+be generated, the second part is the import path followed by a colon
+(``:``) with the Click command.
+
+That's it.
+
+Testing The Script
+------------------
+
+To test the script, you can make a new virtualenv and then install your
+package::
+
+ $ virtualenv venv
+ $ . venv/bin/activate
+ $ pip install --editable .
+
+Afterwards, your command should be available:
+
+.. click:run::
+
+ invoke(cli, prog_name='yourscript')
+
+Scripts in Packages
+-------------------
+
+If your script is growing and you want to switch over to your script being
+contained in a Python package the changes necessary are minimal. Let's
+assume your directory structure changed to this::
+
+ yourpackage/
+ __init__.py
+ main.py
+ utils.py
+ scripts/
+ __init__.py
+ yourscript.py
+
+In this case instead of using ``py_modules`` in your ``setup.py`` file you
+can use ``packages`` and the automatic package finding support of
+setuptools. In addition to that it's also recommended to include other
+package data.
+
+These would be the modified contents of ``setup.py``::
+
+ from setuptools import setup, find_packages
+
+ setup(
+ name='yourpackage',
+ version='0.1',
+ packages=find_packages(),
+ include_package_data=True,
+ install_requires=[
+ 'Click',
+ ],
+ entry_points='''
+ [console_scripts]
+ yourscript=yourpackage.scripts.yourscript:cli
+ ''',
+ )
Binary files /tmp/tmp5CGTrm/S7dHEMVmjm/click-0.4.43+16.04.20160203/docs/_static/click@2x.png and /tmp/tmp5CGTrm/FrCzimMInt/click-6.7/docs/_static/click@2x.png differ
Binary files /tmp/tmp5CGTrm/S7dHEMVmjm/click-0.4.43+16.04.20160203/docs/_static/click.png and /tmp/tmp5CGTrm/FrCzimMInt/click-6.7/docs/_static/click.png differ
Binary files /tmp/tmp5CGTrm/S7dHEMVmjm/click-0.4.43+16.04.20160203/docs/_static/click-small@2x.png and /tmp/tmp5CGTrm/FrCzimMInt/click-6.7/docs/_static/click-small@2x.png differ
Binary files /tmp/tmp5CGTrm/S7dHEMVmjm/click-0.4.43+16.04.20160203/docs/_static/click-small.png and /tmp/tmp5CGTrm/FrCzimMInt/click-6.7/docs/_static/click-small.png differ
diff -Nru click-0.4.43+16.04.20160203/docs/_templates/sidebarintro.html click-6.7/docs/_templates/sidebarintro.html
--- click-0.4.43+16.04.20160203/docs/_templates/sidebarintro.html 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/docs/_templates/sidebarintro.html 2017-01-06 22:32:37.000000000 +0000
@@ -0,0 +1,13 @@
+About
+
+ Click is a Python package for creating beautiful command line interfaces in a
+ composable way with as little amount of code as necessary. It’s the “Command
+ Line Interface Creation Kit”.
+
+Useful Links
+
diff -Nru click-0.4.43+16.04.20160203/docs/_templates/sidebarlogo.html click-6.7/docs/_templates/sidebarlogo.html
--- click-0.4.43+16.04.20160203/docs/_templates/sidebarlogo.html 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/docs/_templates/sidebarlogo.html 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,3 @@
+
+
+
diff -Nru click-0.4.43+16.04.20160203/docs/testing.rst click-6.7/docs/testing.rst
--- click-0.4.43+16.04.20160203/docs/testing.rst 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/docs/testing.rst 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,113 @@
+Testing Click Applications
+==========================
+
+.. currentmodule:: click.testing
+
+For basic testing, Click provides the :mod:`click.testing` module which
+provides test functionality that helps you invoke command line
+applications and check their behavior.
+
+These tools should really only be used for testing as they change
+the entire interpreter state for simplicity and are not in any way
+thread-safe!
+
+Basic Testing
+-------------
+
+The basic functionality for testing Click applications is the
+:class:`CliRunner` which can invoke commands as command line scripts. The
+:meth:`CliRunner.invoke` method runs the command line script in isolation
+and captures the output as both bytes and binary data.
+
+The return value is a :class:`Result` object, which has the captured output
+data, exit code, and optional exception attached.
+
+Example::
+
+ import click
+ from click.testing import CliRunner
+
+ def test_hello_world():
+ @click.command()
+ @click.argument('name')
+ def hello(name):
+ click.echo('Hello %s!' % name)
+
+ runner = CliRunner()
+ result = runner.invoke(hello, ['Peter'])
+ assert result.exit_code == 0
+ assert result.output == 'Hello Peter!\n'
+
+For subcommand testing, a subcommand name must be specified in the `args` parameter of :meth:`CliRunner.invoke` method.
+
+Example::
+
+ import click
+ from click.testing import CliRunner
+
+ def test_sync():
+ @click.group()
+ @click.option('--debug/--no-debug', default=False)
+ def cli(debug):
+ click.echo('Debug mode is %s' % ('on' if debug else 'off'))
+
+ @cli.command()
+ def sync():
+ click.echo('Syncing')
+
+ runner = CliRunner()
+ result = runner.invoke(cli, ['--debug', 'sync'])
+ assert result.exit_code == 0
+ assert 'Debug mode is on' in result.output
+ assert 'Syncing' in result.output
+
+File System Isolation
+---------------------
+
+For basic command line tools that want to operate with the file system, the
+:meth:`CliRunner.isolated_filesystem` method comes in useful which sets up
+an empty folder and changes the current working directory to.
+
+Example::
+
+ import click
+ from click.testing import CliRunner
+
+ def test_cat():
+ @click.command()
+ @click.argument('f', type=click.File())
+ def cat(f):
+ click.echo(f.read())
+
+ runner = CliRunner()
+ with runner.isolated_filesystem():
+ with open('hello.txt', 'w') as f:
+ f.write('Hello World!')
+
+ result = runner.invoke(cat, ['hello.txt'])
+ assert result.exit_code == 0
+ assert result.output == 'Hello World!\n'
+
+Input Streams
+-------------
+
+The test wrapper can also be used to provide input data for the input
+stream (stdin). This is very useful for testing prompts, for instance::
+
+ import click
+ from click.testing import CliRunner
+
+ def test_prompts():
+ @click.command()
+ @click.option('--foo', prompt=True)
+ def test(foo):
+ click.echo('foo=%s' % foo)
+
+ runner = CliRunner()
+ result = runner.invoke(test, input='wau wau\n')
+ assert not result.exception
+ assert result.output == 'Foo: wau wau\nfoo=wau wau\n'
+
+Note that prompts will be emulated so that they write the input data to
+the output stream as well. If hidden input is expected then this
+obviously does not happen.
diff -Nru click-0.4.43+16.04.20160203/docs/upgrading.rst click-6.7/docs/upgrading.rst
--- click-0.4.43+16.04.20160203/docs/upgrading.rst 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/docs/upgrading.rst 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,100 @@
+Upgrading To Newer Releases
+===========================
+
+Click attempts the highest level of backwards compatibility but sometimes
+this is not entirely possible. In case we need to break backwards
+compatibility this document gives you information about how to upgrade or
+handle backwards compatibility properly.
+
+.. _upgrade-to-3.2:
+
+Upgrading to 3.2
+----------------
+
+Click 3.2 had to perform two changes to multi commands which were
+triggered by a change between Click 2 and Click 3 that had bigger
+consequences than anticipated.
+
+Context Invokes
+```````````````
+
+Click 3.2 contains a fix for the :meth:`Context.invoke` function when used
+with other commands. The original intention of this function was to
+invoke the other command as as if it came from the command line when it
+was passed a context object instead of a function. This use was only
+documented in a single place in the documentation before and there was no
+proper explanation for the method in the API documentation.
+
+The core issue is that before 3.2 this call worked against intentions::
+
+ ctx.invoke(other_command, 'arg1', 'arg2')
+
+This was never intended to work as it does not allow Click to operate on
+the parameters. Given that this pattern was never documented and ill
+intended the decision was made to change this behavior in a bugfix release
+before it spreads by accident and developers depend on it.
+
+The correct invocation for the above command is the following::
+
+ ctx.invoke(other_command, name_of_arg1='arg1', name_of_arg2='arg2')
+
+This also allowed us to fix the issue that defaults were not handled
+properly by this function.
+
+Multicommand Chaining API
+`````````````````````````
+
+Click 3 introduced multicommand chaning. This required a change in how
+Click internally dispatches. Unfortunately this change was not correctly
+implemented and it appeared that it was possible to provide an API that
+can inform the super command about all the subcommands that will be
+invoked.
+
+This assumption however does not work with one of the API guarantees that
+have been given in the past. As such this functionality has been removed
+in 3.2 as it was already broken. Instead the accidentally broken
+functionality of the :attr:`Context.invoked_subcommand` attribute was
+restored.
+
+If you do require the know which exact commands will be invoked there are
+different ways to cope with this. The first one is to let the subcommands
+all return functions and then to invoke the functions in a
+:meth:`Context.resultcallback`.
+
+
+.. _upgrade-to-2.0:
+
+Upgrading to 2.0
+----------------
+
+Click 2.0 has one breaking change which is the signature for parameter
+callbacks. Before 2.0, the callback was invoked with ``(ctx, value)``
+whereas now it's ``(ctx, param, value)``. This change was necessary as it
+otherwise made reusing callbacks too complicated.
+
+To ease the transition Click will still accept old callbacks. Starting
+with Click 3.0 it will start to issue a warning to stderr to encourage you
+to upgrade.
+
+In case you want to support both Click 1.0 and Click 2.0, you can make a
+simple decorator that adjusts the signatures::
+
+ import click
+ from functools import update_wrapper
+
+ def compatcallback(f):
+ # Click 1.0 does not have a version string stored, so we need to
+ # use getattr here to be safe.
+ if getattr(click, '__version__', '0.0') >= '2.0':
+ return f
+ return update_wrapper(lambda ctx, value: f(ctx, None, value), f)
+
+With that helper you can then write something like this::
+
+ @compatcallback
+ def callback(ctx, param, value):
+ return value.upper()
+
+Note that because Click 1.0 did not pass a parameter, the `param` argument
+here would be `None`, so a compatibility callback could not use that
+argument.
diff -Nru click-0.4.43+16.04.20160203/docs/utils.rst click-6.7/docs/utils.rst
--- click-0.4.43+16.04.20160203/docs/utils.rst 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/docs/utils.rst 2017-01-06 22:32:37.000000000 +0000
@@ -0,0 +1,398 @@
+Utilities
+=========
+
+.. currentmodule:: click
+
+Besides the functionality that Click provides to interface with argument
+parsing and handling, it also provides a bunch of addon functionality that
+is useful for writing command line utilities.
+
+
+Printing to Stdout
+------------------
+
+The most obvious helper is the :func:`echo` function, which in many ways
+works like the Python ``print`` statement or function. The main difference is
+that it works the same in Python 2 and 3, it intelligently detects
+misconfigured output streams, and it will never fail (except in Python 3; for
+more information see :ref:`python3-limitations`).
+
+Example::
+
+ import click
+
+ click.echo('Hello World!')
+
+Most importantly, it can print both Unicode and binary data, unlike the
+built-in ``print`` function in Python 3, which cannot output any bytes. It
+will, however, emit a trailing newline by default, which needs to be
+suppressed by passing ``nl=False``::
+
+ click.echo(b'\xe2\x98\x83', nl=False)
+
+Last but not least :func:`echo` uses click's intelligent internal output
+streams to stdout and stderr which support unicode output on the Windows
+console. This means for as long as you are using `click.echo` you can
+output unicode character (there are some limitations on the default font
+with regards to which characters can be displayed). This functionality is
+new in Click 6.0.
+
+.. versionadded:: 6.0
+
+Click now emulates output streams on Windows to support unicode to the
+Windows console through separate APIs. For more information see
+`wincmd`_.
+
+.. versionadded:: 3.0
+
+Starting with Click 3.0 you can also easily print to standard error by
+passing ``err=True``::
+
+ click.echo('Hello World!', err=True)
+
+
+.. _ansi-colors:
+
+ANSI Colors
+-----------
+
+.. versionadded:: 2.0
+
+Starting with Click 2.0, the :func:`echo` function gained extra
+functionality to deal with ANSI colors and styles. Note that on Windows,
+this functionality is only available if `colorama`_ is installed. If it
+is installed, then ANSI codes are intelligently handled.
+
+Primarily this means that:
+
+- Click's :func:`echo` function will automatically strip ANSI color codes
+ if the stream is not connected to a terminal.
+- the :func:`echo` function will transparently connect to the terminal on
+ Windows and translate ANSI codes to terminal API calls. This means
+ that colors will work on Windows the same way they do on other
+ operating systems.
+
+Note for `colorama` support: Click will automatically detect when `colorama`
+is available and use it. Do *not* call ``colorama.init()``!
+
+To install `colorama`, run this command::
+
+ $ pip install colorama
+
+For styling a string, the :func:`style` function can be used::
+
+ import click
+
+ click.echo(click.style('Hello World!', fg='green'))
+ click.echo(click.style('Some more text', bg='blue', fg='white'))
+ click.echo(click.style('ATTENTION', blink=True, bold=True))
+
+The combination of :func:`echo` and :func:`style` is also available in
+a single function called :func:`secho`::
+
+ click.secho('Hello World!', fg='green')
+ click.secho('Some more text', bg='blue', fg='white')
+ click.secho('ATTENTION', blink=True, bold=True)
+
+
+.. _colorama: https://pypi.python.org/pypi/colorama
+
+Pager Support
+-------------
+
+In some situations, you might want to show long texts on the terminal and
+let a user scroll through it. This can be achieved by using the
+:func:`echo_via_pager` function which works similarly to the :func:`echo`
+function, but always writes to stdout and, if possible, through a pager.
+
+Example:
+
+.. click:example::
+
+ @click.command()
+ def less():
+ click.echo_via_pager('\n'.join('Line %d' % idx
+ for idx in range(200)))
+
+
+Screen Clearing
+---------------
+
+.. versionadded:: 2.0
+
+To clear the terminal screen, you can use the :func:`clear` function that
+is provided starting with Click 2.0. It does what the name suggests: it
+clears the entire visible screen in a platform-agnostic way:
+
+::
+
+ import click
+ click.clear()
+
+
+Getting Characters from Terminal
+--------------------------------
+
+.. versionadded:: 2.0
+
+Normally, when reading input from the terminal, you would read from
+standard input. However, this is buffered input and will not show up until
+the line has been terminated. In certain circumstances, you might not want
+to do that and instead read individual characters as they are being written.
+
+For this, Click provides the :func:`getchar` function which reads a single
+character from the terminal buffer and returns it as a Unicode character.
+
+Note that this function will always read from the terminal, even if stdin
+is instead a pipe.
+
+Example::
+
+ import click
+
+ click.echo('Continue? [yn] ', nl=False)
+ c = click.getchar()
+ click.echo()
+ if c == 'y':
+ click.echo('We will go on')
+ elif c == 'n':
+ click.echo('Abort!')
+ else:
+ click.echo('Invalid input :(')
+
+Note that this reads raw input, which means that things like arrow keys
+will show up in the platform's native escape format. The only characters
+translated are ``^C`` and ``^D`` which are converted into keyboard
+interrupts and end of file exceptions respectively. This is done because
+otherwise, it's too easy to forget about that and to create scripts that
+cannot be properly exited.
+
+
+Waiting for Key Press
+---------------------
+
+.. versionadded:: 2.0
+
+Sometimes, it's useful to pause until the user presses any key on the
+keyboard. This is especially useful on Windows where ``cmd.exe`` will
+close the window at the end of the command execution by default, instead
+of waiting.
+
+In click, this can be accomplished with the :func:`pause` function. This
+function will print a quick message to the terminal (which can be
+customized) and wait for the user to press a key. In addition to that,
+it will also become a NOP (no operation instruction) if the script is not
+run interactively.
+
+Example::
+
+ import click
+ click.pause()
+
+
+Launching Editors
+-----------------
+
+.. versionadded:: 2.0
+
+Click supports launching editors automatically through :func:`edit`. This
+is very useful for asking users for multi-line input. It will
+automatically open the user's defined editor or fall back to a sensible
+default. If the user closes the editor without saving, the return value
+will be `None` otherwise the entered text.
+
+Example usage::
+
+ import click
+
+ def get_commit_message():
+ MARKER = '# Everything below is ignored\n'
+ message = click.edit('\n\n' + MARKER)
+ if message is not None:
+ return message.split(MARKER, 1)[0].rstrip('\n')
+
+Alternatively, the function can also be used to launch editors for files by
+a specific filename. In this case, the return value is always `None`.
+
+Example usage::
+
+ import click
+ click.edit(filename='/etc/passwd')
+
+
+Launching Applications
+----------------------
+
+.. versionadded:: 2.0
+
+Click supports launching applications through :func:`launch`. This can be
+used to open the default application assocated with a URL or filetype.
+This can be used to launch web browsers or picture viewers, for instance.
+In addition to this, it can also launch the file manager and automatically
+select the provided file.
+
+Example usage::
+
+ click.launch('http://click.pocoo.org/')
+ click.launch('/my/downloaded/file.txt', locate=True)
+
+
+Printing Filenames
+------------------
+
+Because filenames might not be Unicode, formatting them can be a bit
+tricky. Generally, this is easier in Python 2 than on 3, as you can just
+write the bytes to stdout with the ``print`` function, but in Python 3, you
+will always need to operate in Unicode.
+
+The way this works with click is through the :func:`format_filename`
+function. It does a best-effort conversion of the filename to Unicode and
+will never fail. This makes it possible to use these filenames in the
+context of a full Unicode string.
+
+Example::
+
+ click.echo('Path: %s' % click.format_filename(b'foo.txt'))
+
+
+Standard Streams
+----------------
+
+For command line utilities, it's very important to get access to input and
+output streams reliably. Python generally provides access to these
+streams through ``sys.stdout`` and friends, but unfortunately, there are
+API differences between 2.x and 3.x, especially with regards to how these
+streams respond to Unicode and binary data.
+
+Because of this, click provides the :func:`get_binary_stream` and
+:func:`get_text_stream` functions, which produce consistent results with
+different Python versions and for a wide variety pf terminal configurations.
+
+The end result is that these functions will always return a functional
+stream object (except in very odd cases in Python 3; see
+:ref:`python3-limitations`).
+
+Example::
+
+ import click
+
+ stdin_text = click.get_text_stream('stdin')
+ stdout_binary = click.get_binary_stream('stdout')
+
+.. versionadded:: 6.0
+
+Click now emulates output streams on Windows to support unicode to the
+Windows console through separate APIs. For more information see
+`wincmd`_.
+
+
+Intelligent File Opening
+------------------------
+
+.. versionadded:: 3.0
+
+Starting with Click 3.0 the logic for opening files from the :class:`File`
+type is exposed through the :func:`open_file` function. It can
+intelligently open stdin/stdout as well as any other file.
+
+Example::
+
+ import click
+
+ stdout = click.open_file('-', 'w')
+ test_file = click.open_file('test.txt', 'w')
+
+If stdin or stdout are returned, the return value is wrapped in a special
+file where the context manager will prevent the closing of the file. This
+makes the handling of standard streams transparent and you can always use
+it like this::
+
+ with click.open_file(filename, 'w') as f:
+ f.write('Hello World!\n')
+
+
+Finding Application Folders
+---------------------------
+
+.. versionadded:: 2.0
+
+Very often, you want to open a configuration file that belongs to your
+application. However, different operating systems store these configuration
+files in different locations depending on their standards. Click provides
+a :func:`get_app_dir` function which returns the most appropriate location
+for per-user config files for your application depending on the OS.
+
+Example usage::
+
+ import os
+ import click
+ import ConfigParser
+
+ APP_NAME = 'My Application'
+
+ def read_config():
+ cfg = os.path.join(click.get_app_dir(APP_NAME), 'config.ini')
+ parser = ConfigParser.RawConfigParser()
+ parser.read([cfg])
+ rv = {}
+ for section in parser.sections():
+ for key, value in parser.items(section):
+ rv['%s.%s' % (section, key)] = value
+ return rv
+
+
+Showing Progress Bars
+---------------------
+
+.. versionadded:: 2.0
+
+Sometimes, you have command line scripts that need to process a lot of data,
+but you want to quickly show the user some progress about how long that
+will take. Click supports simple progress bar rendering for that through
+the :func:`progressbar` function.
+
+The basic usage is very simple: the idea is that you have an iterable that
+you want to operate on. For each item in the iterable it might take some
+time to do processing. So say you have a loop like this::
+
+ for user in all_the_users_to_process:
+ modify_the_user(user)
+
+To hook this up with an automatically updating progress bar, all you need
+to do is to change the code to this::
+
+ import click
+
+ with click.progressbar(all_the_users_to_process) as bar:
+ for user in bar:
+ modify_the_user(user)
+
+Click will then automatically print a progress bar to the terminal and
+calculate the remaining time for you. The calculation of remaining time
+requires that the iterable has a length. If it does not have a length
+but you know the length, you can explicitly provide it::
+
+ with click.progressbar(all_the_users_to_process,
+ length=number_of_users) as bar:
+ for user in bar:
+ modify_the_user(user)
+
+Another useful feature is to associate a label with the progress bar which
+will be shown preceding the progress bar::
+
+ with click.progressbar(all_the_users_to_process,
+ label='Modifying user accounts',
+ length=number_of_users) as bar:
+ for user in bar:
+ modify_the_user(user)
+
+Sometimes, one may need to iterate over an external iterator, and advance the
+progress bar irregularly. To do so, you need to specify the length (and no
+iterable), and use the update method on the context return value instead of
+iterating directly over it::
+
+ with click.progressbar(length=total_size,
+ label='Unzipping archive') as bar:
+ for archive in zip_file:
+ archive.extract()
+ bar.update(archive.size)
diff -Nru click-0.4.43+16.04.20160203/docs/why.rst click-6.7/docs/why.rst
--- click-0.4.43+16.04.20160203/docs/why.rst 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/docs/why.rst 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,152 @@
+Why Click?
+==========
+
+There are so many libraries out there for writing command line utilities;
+why does Click exist?
+
+This question is easy to answer: because there is not a single command
+line utility for Python out there which ticks the following boxes:
+
+* is lazily composable without restrictions
+* fully follows the Unix command line conventions
+* supports loading values from environment variables out of the box
+* supports for prompting of custom values
+* is fully nestable and composable
+* works the same in Python 2 and 3
+* supports file handling out of the box
+* comes with useful common helpers (getting terminal dimensions,
+ ANSI colors, fetching direct keyboard input, screen clearing,
+ finding config paths, launching apps and editors, etc.)
+
+There are many alternatives to Click and you can have a look at them if
+you enjoy them better. The obvious ones are ``optparse`` and ``argparse``
+from the standard library.
+
+Click is actually implemented as a wrapper around a mild fork of
+``optparse`` and does not implement any parsing itself. The reason it's
+not based on ``argparse`` is that ``argparse`` does not allow proper
+nesting of commands by design and has some deficiencies when it comes to
+POSIX compliant argument handling.
+
+Click is designed to be fun to work with and at the same time not stand in
+your way. It's not overly flexible either. Currently, for instance, it
+does not allow you to customize the help pages too much. This is intentional
+because Click is designed to allow you to nest command line utilities. The
+idea is that you can have a system that works together with another system by
+tacking two Click instances together and they will continue working as they
+should.
+
+Too much customizability would break this promise.
+
+Click was written to support the `Flask `_
+microframework ecosystem because no tool could provide it with the
+functionality it needed.
+
+To get an understanding of what Click is all about, I strongly recommend
+looking at the :ref:`complex-guide` chapter to see what it's useful for.
+
+Why not Argparse?
+-----------------
+
+Click is internally based on optparse instead of argparse. This however
+is an implementation detail that a user does not have to be concerned
+with. The reason however Click is not using argparse is that it has some
+problematic behaviors that make handling arbitrary command line interfaces
+hard:
+
+* argparse has built-in magic behavior to guess if something is an
+ argument or an option. This becomes a problem when dealing with
+ incomplete command lines as it's not possible to know without having a
+ full understanding of the command line how the parser is going to
+ behave. This goes against Click's ambitions of dispatching to
+ subparsers.
+* argparse currently does not support disabling of interspersed
+ arguments. Without this feature it's not possible to safely implement
+ Click's nested parsing nature.
+
+Why not Docopt etc.?
+--------------------
+
+Docopt and many tools like it are cool in how they work, but very few of
+these tools deal with nesting of commands and composability in a way like
+Click. To the best of the developer's knowledge, Click is the first
+Python library that aims to create a level of composability of applications
+that goes beyond what the system itself supports.
+
+Docopt, for instance, acts by parsing your help pages and then parsing
+according to those rules. The side effect of this is that docopt is quite
+rigid in how it handles the command line interface. The upside of docopt
+is that it gives you strong control over your help page; the downside is
+that due to this it cannot rewrap your output for the current terminal
+width and it makes translations hard. On top of that docopt is restricted
+to basic parsing. It does not handle argument dispatching and callback
+invocation or types. This means there is a lot of code that needs to be
+written in addition to the basic help page to handle the parsing results.
+
+Most of all, however, it makes composability hard. While docopt does
+support dispatching to subcommands, it for instance does not directly
+support any kind of automatic subcommand enumeration based on what's
+available or it does not enforce subcommands to work in a consistent way.
+
+This is fine, but it's different from how Click wants to work. Click aims
+to support fully composable command line user interfaces by doing the
+following:
+
+- Click does not just parse, it also dispatches to the appropriate code.
+- Click has a strong concept of an invocation context that allows
+ subcommands to respond to data from the parent command.
+- Click has strong information available for all parameters and commands
+ so that it can generate unified help pages for the full CLI and to
+ assist the user in converting the input data as necessary.
+- Click has a strong understanding of what types are and can give the user
+ consistent error messages if something goes wrong. A subcommand
+ written by a different developer will not suddenly die with a
+ different error messsage because it's manually handled.
+- Click has enough meta information available for its whole program
+ that it can evolve over time to improve the user experience without
+ forcing developers to adjust their programs. For instance, if Click
+ decides to change how help pages are formatted, all Click programs
+ will automatically benefit from this.
+
+The aim of Click is to make composable systems, whereas the aim of docopt
+is to build the most beautiful and hand-crafted command line interfaces.
+These two goals conflict with one another in subtle ways. Click
+actively prevents people from implementing certain patterns in order to
+achieve unified command line interfaces. You have very little input on
+reformatting your help pages for instance.
+
+
+Why Hardcoded Behaviors?
+------------------------
+
+The other question is why Click goes away from optparse and hardcodes
+certain behaviors instead of staying configurable. There are multiple
+reasons for this. The biggest one is that too much configurability makes
+it hard to achieve a consistent command line experience.
+
+The best example for this is optparse's ``callback`` functionality for
+accepting arbitrary number of arguments. Due to syntactical ambiguities
+on the command line, there is no way to implement fully variadic arguments.
+There are always tradeoffs that need to be made and in case of
+``argparse`` these tradeoffs have been critical enough, that a system like
+Click cannot even be implemented on top of it.
+
+In this particular case, Click attempts to stay with a handful of accepted
+paradigms for building command line interfaces that can be well documented
+and tested.
+
+
+Why No Auto Correction?
+-----------------------
+
+The question came up why Click does not auto correct parameters given that
+even optparse and argparse support automatic expansion of long arguments.
+The reason for this is that it's a liability for backwards compatibility.
+If people start relying on automatically modified parameters and someone
+adds a new parameter in the future, the script might stop working. These
+kinds of problems are hard to find so Click does not attempt to be magical
+about this.
+
+This sort of behavior however can be implemented on a higher level to
+support things such as explicit aliases. For more information see
+:ref:`aliases`.
diff -Nru click-0.4.43+16.04.20160203/docs/wincmd.rst click-6.7/docs/wincmd.rst
--- click-0.4.43+16.04.20160203/docs/wincmd.rst 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/docs/wincmd.rst 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,73 @@
+Windows Console Notes
+=====================
+
+.. versionadded:: 6.0
+
+Until Click 6.0 there are various bugs and limitations with using Click on
+a Windows console. Most notably the decoding of command line arguments
+was performed with the wrong encoding on Python 2 and on all versions of
+Python output of unicode characters was impossible. Starting with Click
+6.0 we now emulate output streams on Windows to support unicode to the
+Windows console through separate APIs and we perform different decoding of
+parameters.
+
+Here is a brief overview of how this works and what it means to you.
+
+Unicode Arguments
+-----------------
+
+Click internally is generally based on the concept that any argument can
+come in as either byte string or unicode string and conversion is
+performed to the type expected value as late as possible. This has some
+advantages as it allows us to accept the data in the most appropriate form
+for the operating system and Python version.
+
+For instance paths are left as bytes on Python 2 unless you explicitly
+tell it otherwise.
+
+This caused some problems on Windows where initially the wrong encoding
+was used and garbage ended up in your input data. We not only fixed the
+encoding part, but we also now extract unicode parameters from `sys.argv`.
+
+This means that on Python 2 under Windows, the arguments processed will
+*most likely* be of unicode nature and not bytes. This was something that
+previously did not really happen unless you explicitly passed in unicode
+parameters so your custom types need to be aware of this.
+
+There is also another limitation with this: if `sys.argv` was modified
+prior to invoking a click handler, we have to fall back to the regular
+byte input in which case not all unicode values are available but only a
+subset of the codepage used for parameters.
+
+Unicode Output and Input
+------------------------
+
+Unicode output and input on Windows is implemented through the concept of
+a dispatching text stream. What this means is that when click first needs
+a text output (or input) stream on windows it goes through a few checks to
+figure out of a windows console is connected or not. If no Windows
+console is present then the text output stream is returned as such and the
+encoding for that stream is set to ``utf-8`` like on all platforms.
+
+However if a console is connected the stream will instead be emulated and
+use the cmd.exe unicode APIs to output text information. In this case the
+stream will also use ``utf-16-le`` as internal encoding. However there is
+some hackery going on that the underlying raw IO buffer is still bypassing
+the unicode APIs and byte output through an indirection is still possible.
+
+This hackery is used on both Python 2 and Python 3 as neither version of
+Python has native support for cmd.exe with unicode characters. There are
+some limitations you need to be aware of:
+
+* this unicode support is limited to ``click.echo``, ``click.prompt`` as
+ well as ``click.get_text_stream``.
+* depending on if unicode values or byte strings are passed the control
+ flow goes completely different places internally which can have some
+ odd artifacts if data partially ends up being buffered. Click
+ attempts to protect against that by manually always flushing but if
+ you are mixing and matching different string types to ``stdout`` or
+ ``stderr`` you will need to manually flush.
+
+Another important thing to note is that the Windows console's default
+fonts do not support a lot of characters which means that you are mostly
+limited to international letters but no emojis or special characters.
diff -Nru click-0.4.43+16.04.20160203/examples/aliases/aliases.ini click-6.7/examples/aliases/aliases.ini
--- click-0.4.43+16.04.20160203/examples/aliases/aliases.ini 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/examples/aliases/aliases.ini 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,2 @@
+[aliases]
+ci=commit
diff -Nru click-0.4.43+16.04.20160203/examples/aliases/aliases.py click-6.7/examples/aliases/aliases.py
--- click-0.4.43+16.04.20160203/examples/aliases/aliases.py 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/examples/aliases/aliases.py 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,111 @@
+import os
+import click
+
+try:
+ import ConfigParser as configparser
+except ImportError:
+ import configparser
+
+
+class Config(object):
+ """The config in this example only holds aliases."""
+
+ def __init__(self):
+ self.path = os.getcwd()
+ self.aliases = {}
+
+ def read_config(self, filename):
+ parser = configparser.RawConfigParser()
+ parser.read([filename])
+ try:
+ self.aliases.update(parser.items('aliases'))
+ except configparser.NoSectionError:
+ pass
+
+
+pass_config = click.make_pass_decorator(Config, ensure=True)
+
+
+class AliasedGroup(click.Group):
+ """This subclass of a group supports looking up aliases in a config
+ file and with a bit of magic.
+ """
+
+ def get_command(self, ctx, cmd_name):
+ # Step one: bulitin commands as normal
+ rv = click.Group.get_command(self, ctx, cmd_name)
+ if rv is not None:
+ return rv
+
+ # Step two: find the config object and ensure it's there. This
+ # will create the config object is missing.
+ cfg = ctx.ensure_object(Config)
+
+ # Step three: lookup an explicit command aliase in the config
+ if cmd_name in cfg.aliases:
+ actual_cmd = cfg.aliases[cmd_name]
+ return click.Group.get_command(self, ctx, actual_cmd)
+
+ # Alternative option: if we did not find an explicit alias we
+ # allow automatic abbreviation of the command. "status" for
+ # instance will match "st". We only allow that however if
+ # there is only one command.
+ matches = [x for x in self.list_commands(ctx)
+ if x.lower().startswith(cmd_name.lower())]
+ if not matches:
+ return None
+ elif len(matches) == 1:
+ return click.Group.get_command(self, ctx, matches[0])
+ ctx.fail('Too many matches: %s' % ', '.join(sorted(matches)))
+
+
+def read_config(ctx, param, value):
+ """Callback that is used whenever --config is passed. We use this to
+ always load the correct config. This means that the config is loaded
+ even if the group itself never executes so our aliases stay always
+ available.
+ """
+ cfg = ctx.ensure_object(Config)
+ if value is None:
+ value = os.path.join(os.path.dirname(__file__), 'aliases.ini')
+ cfg.read_config(value)
+ return value
+
+
+@click.command(cls=AliasedGroup)
+@click.option('--config', type=click.Path(exists=True, dir_okay=False),
+ callback=read_config, expose_value=False,
+ help='The config file to use instead of the default.')
+def cli():
+ """An example application that supports aliases."""
+
+
+@cli.command()
+def push():
+ """Pushes changes."""
+ click.echo('Push')
+
+
+@cli.command()
+def pull():
+ """Pulls changes."""
+ click.echo('Pull')
+
+
+@cli.command()
+def clone():
+ """Clones a repository."""
+ click.echo('Clone')
+
+
+@cli.command()
+def commit():
+ """Commits pending changes."""
+ click.echo('Commit')
+
+
+@cli.command()
+@pass_config
+def status(config):
+ """Shows the status."""
+ click.echo('Status for %s' % config.path)
diff -Nru click-0.4.43+16.04.20160203/examples/aliases/README click-6.7/examples/aliases/README
--- click-0.4.43+16.04.20160203/examples/aliases/README 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/examples/aliases/README 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,17 @@
+$ aliases_
+
+ aliases is a fairly advanced example that shows how
+ to implement command aliases with Click. It uses a
+ subclass of the default group to customize how commands
+ are located.
+
+ It supports both aliases read from a config file as well
+ as automatic abbreviations.
+
+ The aliases from the config are read from the aliases.ini
+ file. Try `aliases st` and `aliases ci`!
+
+Usage:
+
+ $ pip install --editable .
+ $ aliases --help
diff -Nru click-0.4.43+16.04.20160203/examples/aliases/setup.py click-6.7/examples/aliases/setup.py
--- click-0.4.43+16.04.20160203/examples/aliases/setup.py 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/examples/aliases/setup.py 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,15 @@
+from setuptools import setup
+
+setup(
+ name='click-example-aliases',
+ version='1.0',
+ py_modules=['aliases'],
+ include_package_data=True,
+ install_requires=[
+ 'click',
+ ],
+ entry_points='''
+ [console_scripts]
+ aliases=aliases:cli
+ ''',
+)
diff -Nru click-0.4.43+16.04.20160203/examples/colors/colors.py click-6.7/examples/colors/colors.py
--- click-0.4.43+16.04.20160203/examples/colors/colors.py 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/examples/colors/colors.py 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,26 @@
+import click
+
+
+all_colors = 'black', 'red', 'green', 'yellow', 'blue', 'magenta', \
+ 'cyan', 'white'
+
+
+@click.command()
+def cli():
+ """This script prints some colors. If colorama is installed this will
+ also work on Windows. It will also automatically remove all ANSI
+ styles if data is piped into a file.
+
+ Give it a try!
+ """
+ for color in all_colors:
+ click.echo(click.style('I am colored %s' % color, fg=color))
+ for color in all_colors:
+ click.echo(click.style('I am colored %s and bold' % color,
+ fg=color, bold=True))
+ for color in all_colors:
+ click.echo(click.style('I am reverse colored %s' % color, fg=color,
+ reverse=True))
+
+ click.echo(click.style('I am blinking', blink=True))
+ click.echo(click.style('I am underlined', underline=True))
diff -Nru click-0.4.43+16.04.20160203/examples/colors/README click-6.7/examples/colors/README
--- click-0.4.43+16.04.20160203/examples/colors/README 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/examples/colors/README 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,11 @@
+$ colors_
+
+ colors is a simple example that shows how you can
+ colorize text.
+
+ For this to work on Windows, colorama is required.
+
+Usage:
+
+ $ pip install --editable .
+ $ colors
diff -Nru click-0.4.43+16.04.20160203/examples/colors/setup.py click-6.7/examples/colors/setup.py
--- click-0.4.43+16.04.20160203/examples/colors/setup.py 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/examples/colors/setup.py 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,17 @@
+from setuptools import setup
+
+setup(
+ name='click-example-colors',
+ version='1.0',
+ py_modules=['colors'],
+ include_package_data=True,
+ install_requires=[
+ 'click',
+ # Colorama is only required for Windows.
+ 'colorama',
+ ],
+ entry_points='''
+ [console_scripts]
+ colors=colors:cli
+ ''',
+)
diff -Nru click-0.4.43+16.04.20160203/examples/complex/complex/cli.py click-6.7/examples/complex/complex/cli.py
--- click-0.4.43+16.04.20160203/examples/complex/complex/cli.py 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/examples/complex/complex/cli.py 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,65 @@
+import os
+import sys
+import click
+
+
+CONTEXT_SETTINGS = dict(auto_envvar_prefix='COMPLEX')
+
+
+class Context(object):
+
+ def __init__(self):
+ self.verbose = False
+ self.home = os.getcwd()
+
+ def log(self, msg, *args):
+ """Logs a message to stderr."""
+ if args:
+ msg %= args
+ click.echo(msg, file=sys.stderr)
+
+ def vlog(self, msg, *args):
+ """Logs a message to stderr only if verbose is enabled."""
+ if self.verbose:
+ self.log(msg, *args)
+
+
+pass_context = click.make_pass_decorator(Context, ensure=True)
+cmd_folder = os.path.abspath(os.path.join(os.path.dirname(__file__),
+ 'commands'))
+
+
+class ComplexCLI(click.MultiCommand):
+
+ def list_commands(self, ctx):
+ rv = []
+ for filename in os.listdir(cmd_folder):
+ if filename.endswith('.py') and \
+ filename.startswith('cmd_'):
+ rv.append(filename[4:-3])
+ rv.sort()
+ return rv
+
+ def get_command(self, ctx, name):
+ try:
+ if sys.version_info[0] == 2:
+ name = name.encode('ascii', 'replace')
+ mod = __import__('complex.commands.cmd_' + name,
+ None, None, ['cli'])
+ except ImportError:
+ return
+ return mod.cli
+
+
+@click.command(cls=ComplexCLI, context_settings=CONTEXT_SETTINGS)
+@click.option('--home', type=click.Path(exists=True, file_okay=False,
+ resolve_path=True),
+ help='Changes the folder to operate on.')
+@click.option('-v', '--verbose', is_flag=True,
+ help='Enables verbose mode.')
+@pass_context
+def cli(ctx, verbose, home):
+ """A complex command line interface."""
+ ctx.verbose = verbose
+ if home is not None:
+ ctx.home = home
diff -Nru click-0.4.43+16.04.20160203/examples/complex/complex/commands/cmd_init.py click-6.7/examples/complex/complex/commands/cmd_init.py
--- click-0.4.43+16.04.20160203/examples/complex/complex/commands/cmd_init.py 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/examples/complex/complex/commands/cmd_init.py 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,13 @@
+import click
+from complex.cli import pass_context
+
+
+@click.command('init', short_help='Initializes a repo.')
+@click.argument('path', required=False, type=click.Path(resolve_path=True))
+@pass_context
+def cli(ctx, path):
+ """Initializes a repository."""
+ if path is None:
+ path = ctx.home
+ ctx.log('Initialized the repository in %s',
+ click.format_filename(path))
diff -Nru click-0.4.43+16.04.20160203/examples/complex/complex/commands/cmd_status.py click-6.7/examples/complex/complex/commands/cmd_status.py
--- click-0.4.43+16.04.20160203/examples/complex/complex/commands/cmd_status.py 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/examples/complex/complex/commands/cmd_status.py 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,10 @@
+import click
+from complex.cli import pass_context
+
+
+@click.command('status', short_help='Shows file changes.')
+@pass_context
+def cli(ctx):
+ """Shows file changes in the current working directory."""
+ ctx.log('Changed files: none')
+ ctx.vlog('bla bla bla, debug info')
diff -Nru click-0.4.43+16.04.20160203/examples/complex/README click-6.7/examples/complex/README
--- click-0.4.43+16.04.20160203/examples/complex/README 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/examples/complex/README 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,16 @@
+$ complex_
+
+ complex is an example of building very complex cli
+ applications that load subcommands dynamically from
+ a plugin folder and other things.
+
+ All the commands are implemented as plugins in the
+ `complex.commands` package. If a python module is
+ placed named "cmd_foo" it will show up as "foo"
+ command and the `cli` object within it will be
+ loaded as nested Click command.
+
+Usage:
+
+ $ pip install --editable .
+ $ complex --help
diff -Nru click-0.4.43+16.04.20160203/examples/complex/setup.py click-6.7/examples/complex/setup.py
--- click-0.4.43+16.04.20160203/examples/complex/setup.py 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/examples/complex/setup.py 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,15 @@
+from setuptools import setup
+
+setup(
+ name='click-example-complex',
+ version='1.0',
+ packages=['complex', 'complex.commands'],
+ include_package_data=True,
+ install_requires=[
+ 'click',
+ ],
+ entry_points='''
+ [console_scripts]
+ complex=complex.cli:cli
+ ''',
+)
Binary files /tmp/tmp5CGTrm/S7dHEMVmjm/click-0.4.43+16.04.20160203/examples/imagepipe/example01.jpg and /tmp/tmp5CGTrm/FrCzimMInt/click-6.7/examples/imagepipe/example01.jpg differ
Binary files /tmp/tmp5CGTrm/S7dHEMVmjm/click-0.4.43+16.04.20160203/examples/imagepipe/example02.jpg and /tmp/tmp5CGTrm/FrCzimMInt/click-6.7/examples/imagepipe/example02.jpg differ
diff -Nru click-0.4.43+16.04.20160203/examples/imagepipe/.gitignore click-6.7/examples/imagepipe/.gitignore
--- click-0.4.43+16.04.20160203/examples/imagepipe/.gitignore 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/examples/imagepipe/.gitignore 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1 @@
+processed-*
diff -Nru click-0.4.43+16.04.20160203/examples/imagepipe/imagepipe.py click-6.7/examples/imagepipe/imagepipe.py
--- click-0.4.43+16.04.20160203/examples/imagepipe/imagepipe.py 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/examples/imagepipe/imagepipe.py 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,266 @@
+import click
+from functools import update_wrapper
+from PIL import Image, ImageFilter, ImageEnhance
+
+
+@click.group(chain=True)
+def cli():
+ """This script processes a bunch of images through pillow in a unix
+ pipe. One commands feeds into the next.
+
+ Example:
+
+ \b
+ imagepipe open -i example01.jpg resize -w 128 display
+ imagepipe open -i example02.jpg blur save
+ """
+
+
+@cli.resultcallback()
+def process_commands(processors):
+ """This result callback is invoked with an iterable of all the chained
+ subcommands. As in this example each subcommand returns a function
+ we can chain them together to feed one into the other, similar to how
+ a pipe on unix works.
+ """
+ # Start with an empty iterable.
+ stream = ()
+
+ # Pipe it through all stream processors.
+ for processor in processors:
+ stream = processor(stream)
+
+ # Evaluate the stream and throw away the items.
+ for _ in stream:
+ pass
+
+
+def processor(f):
+ """Helper decorator to rewrite a function so that it returns another
+ function from it.
+ """
+ def new_func(*args, **kwargs):
+ def processor(stream):
+ return f(stream, *args, **kwargs)
+ return processor
+ return update_wrapper(new_func, f)
+
+
+def generator(f):
+ """Similar to the :func:`processor` but passes through old values
+ unchanged and does not pass through the values as parameter.
+ """
+ @processor
+ def new_func(stream, *args, **kwargs):
+ for item in stream:
+ yield item
+ for item in f(*args, **kwargs):
+ yield item
+ return update_wrapper(new_func, f)
+
+
+def copy_filename(new, old):
+ new.filename = old.filename
+ return new
+
+
+@cli.command('open')
+@click.option('-i', '--image', 'images', type=click.Path(),
+ multiple=True, help='The image file to open.')
+@generator
+def open_cmd(images):
+ """Loads one or multiple images for processing. The input parameter
+ can be specified multiple times to load more than one image.
+ """
+ for image in images:
+ try:
+ click.echo('Opening "%s"' % image)
+ if image == '-':
+ img = Image.open(click.get_binary_stdin())
+ img.filename = '-'
+ else:
+ img = Image.open(image)
+ yield img
+ except Exception as e:
+ click.echo('Could not open image "%s": %s' % (image, e), err=True)
+
+
+@cli.command('save')
+@click.option('--filename', default='processed-%04d.png', type=click.Path(),
+ help='The format for the filename.',
+ show_default=True)
+@processor
+def save_cmd(images, filename):
+ """Saves all processed images to a series of files."""
+ for idx, image in enumerate(images):
+ try:
+ fn = filename % (idx + 1)
+ click.echo('Saving "%s" as "%s"' % (image.filename, fn))
+ yield image.save(fn)
+ except Exception as e:
+ click.echo('Could not save image "%s": %s' %
+ (image.filename, e), err=True)
+
+
+@cli.command('display')
+@processor
+def display_cmd(images):
+ """Opens all images in an image viewer."""
+ for image in images:
+ click.echo('Displaying "%s"' % image.filename)
+ image.show()
+ yield image
+
+
+@cli.command('resize')
+@click.option('-w', '--width', type=int, help='The new width of the image.')
+@click.option('-h', '--height', type=int, help='The new height of the image.')
+@processor
+def resize_cmd(images, width, height):
+ """Resizes an image by fitting it into the box without changing
+ the aspect ratio.
+ """
+ for image in images:
+ w, h = (width or image.size[0], height or image.size[1])
+ click.echo('Resizing "%s" to %dx%d' % (image.filename, w, h))
+ image.thumbnail((w, h))
+ yield image
+
+
+@cli.command('crop')
+@click.option('-b', '--border', type=int, help='Crop the image from all '
+ 'sides by this amount.')
+@processor
+def crop_cmd(images, border):
+ """Crops an image from all edges."""
+ for image in images:
+ box = [0, 0, image.size[0], image.size[1]]
+
+ if border is not None:
+ for idx, val in enumerate(box):
+ box[idx] = max(0, val - border)
+ click.echo('Cropping "%s" by %dpx' % (image.filename, border))
+ yield copy_filename(image.crop(box), image)
+ else:
+ yield image
+
+
+def convert_rotation(ctx, param, value):
+ if value is None:
+ return
+ value = value.lower()
+ if value in ('90', 'r', 'right'):
+ return (Image.ROTATE_90, 90)
+ if value in ('180', '-180'):
+ return (Image.ROTATE_180, 180)
+ if value in ('-90', '270', 'l', 'left'):
+ return (Image.ROTATE_270, 270)
+ raise click.BadParameter('invalid rotation "%s"' % value)
+
+
+def convert_flip(ctx, param, value):
+ if value is None:
+ return
+ value = value.lower()
+ if value in ('lr', 'leftright'):
+ return (Image.FLIP_LEFT_RIGHT, 'left to right')
+ if value in ('tb', 'topbottom', 'upsidedown', 'ud'):
+ return (Image.FLIP_LEFT_RIGHT, 'top to bottom')
+ raise click.BadParameter('invalid flip "%s"' % value)
+
+
+@cli.command('transpose')
+@click.option('-r', '--rotate', callback=convert_rotation,
+ help='Rotates the image (in degrees)')
+@click.option('-f', '--flip', callback=convert_flip,
+ help='Flips the image [LR / TB]')
+@processor
+def transpose_cmd(images, rotate, flip):
+ """Transposes an image by either rotating or flipping it."""
+ for image in images:
+ if rotate is not None:
+ mode, degrees = rotate
+ click.echo('Rotate "%s" by %ddeg' % (image.filename, degrees))
+ image = copy_filename(image.transpose(mode), image)
+ if flip is not None:
+ mode, direction = flip
+ click.echo('Flip "%s" %s' % (image.filename, direction))
+ image = copy_filename(image.transpose(mode), image)
+ yield image
+
+
+@cli.command('blur')
+@click.option('-r', '--radius', default=2, show_default=True,
+ help='The blur radius.')
+@processor
+def blur_cmd(images, radius):
+ """Applies gaussian blur."""
+ blur = ImageFilter.GaussianBlur(radius)
+ for image in images:
+ click.echo('Blurring "%s" by %dpx' % (image.filename, radius))
+ yield copy_filename(image.filter(blur), image)
+
+
+@cli.command('smoothen')
+@click.option('-i', '--iterations', default=1, show_default=True,
+ help='How many iterations of the smoothen filter to run.')
+@processor
+def smoothen_cmd(images, iterations):
+ """Applies a smoothening filter."""
+ for image in images:
+ click.echo('Smoothening "%s" %d time%s' %
+ (image.filename, iterations, iterations != 1 and 's' or '',))
+ for x in xrange(iterations):
+ image = copy_filename(image.filter(ImageFilter.BLUR), image)
+ yield image
+
+
+@cli.command('emboss')
+@processor
+def emboss_cmd(images):
+ """Embosses an image."""
+ for image in images:
+ click.echo('Embossing "%s"' % image.filename)
+ yield copy_filename(image.filter(ImageFilter.EMBOSS), image)
+
+
+@cli.command('sharpen')
+@click.option('-f', '--factor', default=2.0,
+ help='Sharpens the image.', show_default=True)
+@processor
+def sharpen_cmd(images, factor):
+ """Sharpens an image."""
+ for image in images:
+ click.echo('Sharpen "%s" by %f' % (image.filename, factor))
+ enhancer = ImageEnhance.Sharpness(image)
+ yield copy_filename(enhancer.enhance(max(1.0, factor)), image)
+
+
+@cli.command('paste')
+@click.option('-l', '--left', default=0, help='Offset from left.')
+@click.option('-r', '--right', default=0, help='Offset from right.')
+@processor
+def paste_cmd(images, left, right):
+ """Pastes the second image on the first image and leaves the rest
+ unchanged.
+ """
+ imageiter = iter(images)
+ image = next(imageiter, None)
+ to_paste = next(imageiter, None)
+
+ if to_paste is None:
+ if image is not None:
+ yield image
+ return
+
+ click.echo('Paste "%s" on "%s"' %
+ (to_paste.filename, image.filename))
+ mask = None
+ if to_paste.mode == 'RGBA' or 'transparency' in to_paste.info:
+ mask = to_paste
+ image.paste(to_paste, (left, right), mask)
+ image.filename += '+' + to_paste.filename
+ yield image
+
+ for image in imageiter:
+ yield image
diff -Nru click-0.4.43+16.04.20160203/examples/imagepipe/README click-6.7/examples/imagepipe/README
--- click-0.4.43+16.04.20160203/examples/imagepipe/README 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/examples/imagepipe/README 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,13 @@
+$ imagepipe_
+
+ imagepipe is an example application that implements some
+ multi commands that chain image processing instructions
+ together.
+
+ This requires pillow.
+
+Usage:
+
+ $ pip install --editable .
+ $ imagepipe open -i example01.jpg resize -w 128 display
+ $ imagepipe open -i example02.jpg blur save
diff -Nru click-0.4.43+16.04.20160203/examples/imagepipe/setup.py click-6.7/examples/imagepipe/setup.py
--- click-0.4.43+16.04.20160203/examples/imagepipe/setup.py 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/examples/imagepipe/setup.py 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,16 @@
+from setuptools import setup
+
+setup(
+ name='click-example-imagepipe',
+ version='1.0',
+ py_modules=['imagepipe'],
+ include_package_data=True,
+ install_requires=[
+ 'click',
+ 'pillow',
+ ],
+ entry_points='''
+ [console_scripts]
+ imagepipe=imagepipe:cli
+ ''',
+)
diff -Nru click-0.4.43+16.04.20160203/examples/inout/inout.py click-6.7/examples/inout/inout.py
--- click-0.4.43+16.04.20160203/examples/inout/inout.py 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/examples/inout/inout.py 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,30 @@
+import click
+
+
+@click.command()
+@click.argument('input', type=click.File('rb'), nargs=-1)
+@click.argument('output', type=click.File('wb'))
+def cli(input, output):
+ """This script works similar to the Unix `cat` command but it writes
+ into a specific file (which could be the standard output as denoted by
+ the ``-`` sign).
+
+ \b
+ Copy stdin to stdout:
+ inout - -
+
+ \b
+ Copy foo.txt and bar.txt to stdout:
+ inout foo.txt bar.txt -
+
+ \b
+ Write stdin into the file foo.txt
+ inout - foo.txt
+ """
+ for f in input:
+ while True:
+ chunk = f.read(1024)
+ if not chunk:
+ break
+ output.write(chunk)
+ output.flush()
diff -Nru click-0.4.43+16.04.20160203/examples/inout/README click-6.7/examples/inout/README
--- click-0.4.43+16.04.20160203/examples/inout/README 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/examples/inout/README 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,10 @@
+$ inout_
+
+ inout is a simple example of an application that
+ can read from files and write to files but also
+ accept input from stdin or write to stdout.
+
+Usage:
+
+ $ pip install --editable .
+ $ inout input_file.txt output_file.txt
diff -Nru click-0.4.43+16.04.20160203/examples/inout/setup.py click-6.7/examples/inout/setup.py
--- click-0.4.43+16.04.20160203/examples/inout/setup.py 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/examples/inout/setup.py 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,15 @@
+from setuptools import setup
+
+setup(
+ name='click-example-inout',
+ version='0.1',
+ py_modules=['inout'],
+ include_package_data=True,
+ install_requires=[
+ 'click',
+ ],
+ entry_points='''
+ [console_scripts]
+ inout=inout:cli
+ ''',
+)
diff -Nru click-0.4.43+16.04.20160203/examples/naval/naval.py click-6.7/examples/naval/naval.py
--- click-0.4.43+16.04.20160203/examples/naval/naval.py 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/examples/naval/naval.py 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,70 @@
+import click
+
+
+@click.group()
+@click.version_option()
+def cli():
+ """Naval Fate.
+
+ This is the docopt example adopted to Click but with some actual
+ commands implemented and not just the empty parsing which really
+ is not all that interesting.
+ """
+
+
+@cli.group()
+def ship():
+ """Manages ships."""
+
+
+@ship.command('new')
+@click.argument('name')
+def ship_new(name):
+ """Creates a new ship."""
+ click.echo('Created ship %s' % name)
+
+
+@ship.command('move')
+@click.argument('ship')
+@click.argument('x', type=float)
+@click.argument('y', type=float)
+@click.option('--speed', metavar='KN', default=10,
+ help='Speed in knots.')
+def ship_move(ship, x, y, speed):
+ """Moves SHIP to the new location X,Y."""
+ click.echo('Moving ship %s to %s,%s with speed %s' % (ship, x, y, speed))
+
+
+@ship.command('shoot')
+@click.argument('ship')
+@click.argument('x', type=float)
+@click.argument('y', type=float)
+def ship_shoot(ship, x, y):
+ """Makes SHIP fire to X,Y."""
+ click.echo('Ship %s fires to %s,%s' % (ship, x, y))
+
+
+@cli.group('mine')
+def mine():
+ """Manages mines."""
+
+
+@mine.command('set')
+@click.argument('x', type=float)
+@click.argument('y', type=float)
+@click.option('ty', '--moored', flag_value='moored',
+ default=True,
+ help='Moored (anchored) mine. Default.')
+@click.option('ty', '--drifting', flag_value='drifting',
+ help='Drifting mine.')
+def mine_set(x, y, ty):
+ """Sets a mine at a specific coordinate."""
+ click.echo('Set %s mine at %s,%s' % (ty, x, y))
+
+
+@mine.command('remove')
+@click.argument('x', type=float)
+@click.argument('y', type=float)
+def mine_remove(x, y):
+ """Removes a mine at a specific coordinate."""
+ click.echo('Removed mine at %s,%s' % (x, y))
diff -Nru click-0.4.43+16.04.20160203/examples/naval/README click-6.7/examples/naval/README
--- click-0.4.43+16.04.20160203/examples/naval/README 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/examples/naval/README 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,14 @@
+$ naval_
+
+ naval is a simple example of an application that
+ is ported from the docopt example of the same name.
+
+ Unlike the original this one also runs some code and
+ prints messages and it's command line interface was
+ changed slightly to make more sense with established
+ POSIX semantics.
+
+Usage:
+
+ $ pip install --editable .
+ $ naval --help
diff -Nru click-0.4.43+16.04.20160203/examples/naval/setup.py click-6.7/examples/naval/setup.py
--- click-0.4.43+16.04.20160203/examples/naval/setup.py 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/examples/naval/setup.py 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,15 @@
+from setuptools import setup
+
+setup(
+ name='click-example-naval',
+ version='2.0',
+ py_modules=['naval'],
+ include_package_data=True,
+ install_requires=[
+ 'click',
+ ],
+ entry_points='''
+ [console_scripts]
+ naval=naval:cli
+ ''',
+)
diff -Nru click-0.4.43+16.04.20160203/examples/README click-6.7/examples/README
--- click-0.4.43+16.04.20160203/examples/README 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/examples/README 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,12 @@
+Click Examples
+
+ This folder contains various Click examples. Note that
+ all of these are not runnable by themselves but should be
+ installed into a virtualenv.
+
+ This is done this way so that scripts also properly work
+ on Windows and in virtualenvs without accidentally executing
+ through the wrong interpreter.
+
+ For more information about this see the documentation:
+ http://click.pocoo.org/setuptools/
diff -Nru click-0.4.43+16.04.20160203/examples/repo/README click-6.7/examples/repo/README
--- click-0.4.43+16.04.20160203/examples/repo/README 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/examples/repo/README 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,9 @@
+$ repo_
+
+ repo is a simple example of an application that looks
+ and works similar to hg or git.
+
+Usage:
+
+ $ pip install --editable .
+ $ repo --help
diff -Nru click-0.4.43+16.04.20160203/examples/repo/repo.py click-6.7/examples/repo/repo.py
--- click-0.4.43+16.04.20160203/examples/repo/repo.py 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/examples/repo/repo.py 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,151 @@
+import os
+import sys
+import posixpath
+
+import click
+
+
+class Repo(object):
+
+ def __init__(self, home):
+ self.home = home
+ self.config = {}
+ self.verbose = False
+
+ def set_config(self, key, value):
+ self.config[key] = value
+ if self.verbose:
+ click.echo(' config[%s] = %s' % (key, value), file=sys.stderr)
+
+ def __repr__(self):
+ return '' % self.home
+
+
+pass_repo = click.make_pass_decorator(Repo)
+
+
+@click.group()
+@click.option('--repo-home', envvar='REPO_HOME', default='.repo',
+ metavar='PATH', help='Changes the repository folder location.')
+@click.option('--config', nargs=2, multiple=True,
+ metavar='KEY VALUE', help='Overrides a config key/value pair.')
+@click.option('--verbose', '-v', is_flag=True,
+ help='Enables verbose mode.')
+@click.version_option('1.0')
+@click.pass_context
+def cli(ctx, repo_home, config, verbose):
+ """Repo is a command line tool that showcases how to build complex
+ command line interfaces with Click.
+
+ This tool is supposed to look like a distributed version control
+ system to show how something like this can be structured.
+ """
+ # Create a repo object and remember it as as the context object. From
+ # this point onwards other commands can refer to it by using the
+ # @pass_repo decorator.
+ ctx.obj = Repo(os.path.abspath(repo_home))
+ ctx.obj.verbose = verbose
+ for key, value in config:
+ ctx.obj.set_config(key, value)
+
+
+@cli.command()
+@click.argument('src')
+@click.argument('dest', required=False)
+@click.option('--shallow/--deep', default=False,
+ help='Makes a checkout shallow or deep. Deep by default.')
+@click.option('--rev', '-r', default='HEAD',
+ help='Clone a specific revision instead of HEAD.')
+@pass_repo
+def clone(repo, src, dest, shallow, rev):
+ """Clones a repository.
+
+ This will clone the repository at SRC into the folder DEST. If DEST
+ is not provided this will automatically use the last path component
+ of SRC and create that folder.
+ """
+ if dest is None:
+ dest = posixpath.split(src)[-1] or '.'
+ click.echo('Cloning repo %s to %s' % (src, os.path.abspath(dest)))
+ repo.home = dest
+ if shallow:
+ click.echo('Making shallow checkout')
+ click.echo('Checking out revision %s' % rev)
+
+
+@cli.command()
+@click.confirmation_option()
+@pass_repo
+def delete(repo):
+ """Deletes a repository.
+
+ This will throw away the current repository.
+ """
+ click.echo('Destroying repo %s' % repo.home)
+ click.echo('Deleted!')
+
+
+@cli.command()
+@click.option('--username', prompt=True,
+ help='The developer\'s shown username.')
+@click.option('--email', prompt='E-Mail',
+ help='The developer\'s email address')
+@click.password_option(help='The login password.')
+@pass_repo
+def setuser(repo, username, email, password):
+ """Sets the user credentials.
+
+ This will override the current user config.
+ """
+ repo.set_config('username', username)
+ repo.set_config('email', email)
+ repo.set_config('password', '*' * len(password))
+ click.echo('Changed credentials.')
+
+
+@cli.command()
+@click.option('--message', '-m', multiple=True,
+ help='The commit message. If provided multiple times each '
+ 'argument gets converted into a new line.')
+@click.argument('files', nargs=-1, type=click.Path())
+@pass_repo
+def commit(repo, files, message):
+ """Commits outstanding changes.
+
+ Commit changes to the given files into the repository. You will need to
+ "repo push" to push up your changes to other repositories.
+
+ If a list of files is omitted, all changes reported by "repo status"
+ will be committed.
+ """
+ if not message:
+ marker = '# Files to be committed:'
+ hint = ['', '', marker, '#']
+ for file in files:
+ hint.append('# U %s' % file)
+ message = click.edit('\n'.join(hint))
+ if message is None:
+ click.echo('Aborted!')
+ return
+ msg = message.split(marker)[0].rstrip()
+ if not msg:
+ click.echo('Aborted! Empty commit message')
+ return
+ else:
+ msg = '\n'.join(message)
+ click.echo('Files to be committed: %s' % (files,))
+ click.echo('Commit message:\n' + msg)
+
+
+@cli.command(short_help='Copies files.')
+@click.option('--force', is_flag=True,
+ help='forcibly copy over an existing managed file')
+@click.argument('src', nargs=-1, type=click.Path())
+@click.argument('dst', type=click.Path())
+@pass_repo
+def copy(repo, src, dst, force):
+ """Copies one or multiple files to a new location. This copies all
+ files from SRC to DST.
+ """
+ for fn in src:
+ click.echo('Copy from %s -> %s' % (fn, dst))
diff -Nru click-0.4.43+16.04.20160203/examples/repo/setup.py click-6.7/examples/repo/setup.py
--- click-0.4.43+16.04.20160203/examples/repo/setup.py 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/examples/repo/setup.py 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,15 @@
+from setuptools import setup
+
+setup(
+ name='click-example-repo',
+ version='0.1',
+ py_modules=['repo'],
+ include_package_data=True,
+ install_requires=[
+ 'click',
+ ],
+ entry_points='''
+ [console_scripts]
+ repo=repo:cli
+ ''',
+)
diff -Nru click-0.4.43+16.04.20160203/examples/termui/README click-6.7/examples/termui/README
--- click-0.4.43+16.04.20160203/examples/termui/README 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/examples/termui/README 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,9 @@
+$ termui_
+
+ termui showcases the different terminal UI helpers that
+ Click provides.
+
+Usage:
+
+ $ pip install --editable .
+ $ termui --help
diff -Nru click-0.4.43+16.04.20160203/examples/termui/setup.py click-6.7/examples/termui/setup.py
--- click-0.4.43+16.04.20160203/examples/termui/setup.py 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/examples/termui/setup.py 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,17 @@
+from setuptools import setup
+
+setup(
+ name='click-example-termui',
+ version='1.0',
+ py_modules=['termui'],
+ include_package_data=True,
+ install_requires=[
+ 'click',
+ # Colorama is only required for Windows.
+ 'colorama',
+ ],
+ entry_points='''
+ [console_scripts]
+ termui=termui:cli
+ ''',
+)
diff -Nru click-0.4.43+16.04.20160203/examples/termui/termui.py click-6.7/examples/termui/termui.py
--- click-0.4.43+16.04.20160203/examples/termui/termui.py 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/examples/termui/termui.py 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,156 @@
+# coding: utf-8
+import click
+import math
+import time
+import random
+
+try:
+ range_type = xrange
+except NameError:
+ range_type = range
+
+
+@click.group()
+def cli():
+ """This script showcases different terminal UI helpers in Click."""
+ pass
+
+
+@cli.command()
+def colordemo():
+ """Demonstrates ANSI color support."""
+ for color in 'red', 'green', 'blue':
+ click.echo(click.style('I am colored %s' % color, fg=color))
+ click.echo(click.style('I am background colored %s' % color, bg=color))
+
+
+@cli.command()
+def pager():
+ """Demonstrates using the pager."""
+ lines = []
+ for x in range_type(200):
+ lines.append('%s. Hello World!' % click.style(str(x), fg='green'))
+ click.echo_via_pager('\n'.join(lines))
+
+
+@cli.command()
+@click.option('--count', default=8000, type=click.IntRange(1, 100000),
+ help='The number of items to process.')
+def progress(count):
+ """Demonstrates the progress bar."""
+ items = range_type(count)
+
+ def process_slowly(item):
+ time.sleep(0.002 * random.random())
+
+ def filter(items):
+ for item in items:
+ if random.random() > 0.3:
+ yield item
+
+ with click.progressbar(items, label='Processing accounts',
+ fill_char=click.style('#', fg='green')) as bar:
+ for item in bar:
+ process_slowly(item)
+
+ def show_item(item):
+ if item is not None:
+ return 'Item #%d' % item
+
+ with click.progressbar(filter(items), label='Committing transaction',
+ fill_char=click.style('#', fg='yellow'),
+ item_show_func=show_item) as bar:
+ for item in bar:
+ process_slowly(item)
+
+ with click.progressbar(length=count, label='Counting',
+ bar_template='%(label)s %(bar)s | %(info)s',
+ fill_char=click.style(u'█', fg='cyan'),
+ empty_char=' ') as bar:
+ for item in bar:
+ process_slowly(item)
+
+ with click.progressbar(length=count, width=0, show_percent=False,
+ show_eta=False,
+ fill_char=click.style('#', fg='magenta')) as bar:
+ for item in bar:
+ process_slowly(item)
+
+ # 'Non-linear progress bar'
+ steps = [math.exp( x * 1. / 20) - 1 for x in range(20)]
+ count = int(sum(steps))
+ with click.progressbar(length=count, show_percent=False,
+ label='Slowing progress bar',
+ fill_char=click.style(u'█', fg='green')) as bar:
+ for item in steps:
+ time.sleep(item)
+ bar.update(item)
+
+
+@cli.command()
+@click.argument('url')
+def open(url):
+ """Opens a file or URL In the default application."""
+ click.launch(url)
+
+
+@cli.command()
+@click.argument('url')
+def locate(url):
+ """Opens a file or URL In the default application."""
+ click.launch(url, locate=True)
+
+
+@cli.command()
+def edit():
+ """Opens an editor with some text in it."""
+ MARKER = '# Everything below is ignored\n'
+ message = click.edit('\n\n' + MARKER)
+ if message is not None:
+ msg = message.split(MARKER, 1)[0].rstrip('\n')
+ if not msg:
+ click.echo('Empty message!')
+ else:
+ click.echo('Message:\n' + msg)
+ else:
+ click.echo('You did not enter anything!')
+
+
+@cli.command()
+def clear():
+ """Clears the entire screen."""
+ click.clear()
+
+
+@cli.command()
+def pause():
+ """Waits for the user to press a button."""
+ click.pause()
+
+
+@cli.command()
+def menu():
+ """Shows a simple menu."""
+ menu = 'main'
+ while 1:
+ if menu == 'main':
+ click.echo('Main menu:')
+ click.echo(' d: debug menu')
+ click.echo(' q: quit')
+ char = click.getchar()
+ if char == 'd':
+ menu = 'debug'
+ elif char == 'q':
+ menu = 'quit'
+ else:
+ click.echo('Invalid input')
+ elif menu == 'debug':
+ click.echo('Debug menu')
+ click.echo(' b: back')
+ char = click.getchar()
+ if char == 'b':
+ menu = 'main'
+ else:
+ click.echo('Invalid input')
+ elif menu == 'quit':
+ return
diff -Nru click-0.4.43+16.04.20160203/examples/validation/README click-6.7/examples/validation/README
--- click-0.4.43+16.04.20160203/examples/validation/README 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/examples/validation/README 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,12 @@
+$ validation_
+
+ validation is a simple example of an application that
+ performs custom validation of parameters in different
+ ways.
+
+ This example requires Click 2.0 or higher.
+
+Usage:
+
+ $ pip install --editable .
+ $ validation --help
diff -Nru click-0.4.43+16.04.20160203/examples/validation/setup.py click-6.7/examples/validation/setup.py
--- click-0.4.43+16.04.20160203/examples/validation/setup.py 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/examples/validation/setup.py 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,15 @@
+from setuptools import setup
+
+setup(
+ name='click-example-validation',
+ version='1.0',
+ py_modules=['validation'],
+ include_package_data=True,
+ install_requires=[
+ 'click',
+ ],
+ entry_points='''
+ [console_scripts]
+ validation=validation:cli
+ ''',
+)
diff -Nru click-0.4.43+16.04.20160203/examples/validation/validation.py click-6.7/examples/validation/validation.py
--- click-0.4.43+16.04.20160203/examples/validation/validation.py 1970-01-01 00:00:00.000000000 +0000
+++ click-6.7/examples/validation/validation.py 2016-11-21 13:28:45.000000000 +0000
@@ -0,0 +1,44 @@
+import click
+try:
+ from urllib import parser as urlparse
+except ImportError:
+ import urlparse
+
+
+def validate_count(ctx, param, value):
+ if value < 0 or value % 2 != 0:
+ raise click.BadParameter('Should be a positive, even integer.')
+ return value
+
+
+class URL(click.ParamType):
+ name = 'url'
+
+ def convert(self, value, param, ctx):
+ if not isinstance(value, tuple):
+ value = urlparse.urlparse(value)
+ if value.scheme not in ('http', 'https'):
+ self.fail('invalid URL scheme (%s). Only HTTP URLs are '
+ 'allowed' % value.scheme, param, ctx)
+ return value
+
+
+@click.command()
+@click.option('--count', default=2, callback=validate_count,
+ help='A positive even number.')
+@click.option('--foo', help='A mysterious parameter.')
+@click.option('--url', help='A URL', type=URL())
+@click.version_option()
+def cli(count, foo, url):
+ """Validation.
+
+ This example validates parameters in different ways. It does it
+ through callbacks, through a custom type as well as by validating
+ manually in the function.
+ """
+ if foo is not None and foo != 'wat':
+ raise click.BadParameter('If a value is provided it needs to be the '
+ 'value "wat".', param_hint=['--foo'])
+ click.echo('count: %s' % count)
+ click.echo('foo: %s' % foo)
+ click.echo('url: %s' % repr(url))
diff -Nru click-0.4.43+16.04.20160203/get-version click-6.7/get-version
--- click-0.4.43+16.04.20160203/get-version 2016-02-03 11:17:38.000000000 +0000
+++ click-6.7/get-version 1970-01-01 00:00:00.000000000 +0000
@@ -1,2 +0,0 @@
-#! /bin/sh
-perl -e '$_ = <>; chomp; s/.*\((.*)\).*/\1/; print; exit' $@
-endif
diff -Nru click-0.4.43+16.04.20160203/init/upstart/click-system-hooks.conf.in click-6.7/init/upstart/click-system-hooks.conf.in
--- click-0.4.43+16.04.20160203/init/upstart/click-system-hooks.conf.in 2016-02-03 11:17:38.000000000 +0000
+++ click-6.7/init/upstart/click-system-hooks.conf.in 1970-01-01 00:00:00.000000000 +0000
@@ -1,8 +0,0 @@
-description "Run Click system-level hooks"
-author "Colin Watson "
-
-start on filesystem
-
-task
-
-exec @bindir@/click hook run-system
diff -Nru click-0.4.43+16.04.20160203/init/upstart/click-user-hooks.conf.in click-6.7/init/upstart/click-user-hooks.conf.in
--- click-0.4.43+16.04.20160203/init/upstart/click-user-hooks.conf.in 2016-02-03 11:17:38.000000000 +0000
+++ click-6.7/init/upstart/click-user-hooks.conf.in 1970-01-01 00:00:00.000000000 +0000
@@ -1,8 +0,0 @@
-description "Run Click user-level hooks"
-author "Colin Watson "
-
-start on starting xsession-init and started dbus
-
-task
-
-exec @bindir@/click hook run-user
diff -Nru click-0.4.43+16.04.20160203/init/upstart/Makefile.am click-6.7/init/upstart/Makefile.am
--- click-0.4.43+16.04.20160203/init/upstart/Makefile.am 2016-02-03 11:17:38.000000000 +0000
+++ click-6.7/init/upstart/Makefile.am 1970-01-01 00:00:00.000000000 +0000
@@ -1,12 +0,0 @@
-EXTRA_DIST = click-system-hooks.conf.in click-user-hooks.conf.in
-
-CLEANFILES = click-system-hooks.conf click-user-hooks.conf
-
-systemdir = $(sysconfdir)/init
-sessionsdir = $(prefix)/share/upstart/sessions
-
-system_DATA = click-system-hooks.conf
-sessions_DATA = click-user-hooks.conf
-
-%.conf: %.conf.in
- sed -e "s,[@]bindir[@],$(bindir),g" $< > $@
diff -Nru click-0.4.43+16.04.20160203/lib/click/click-0.4.pc.in click-6.7/lib/click/click-0.4.pc.in
--- click-0.4.43+16.04.20160203/lib/click/click-0.4.pc.in 2016-02-03 11:17:38.000000000 +0000
+++ click-6.7/lib/click/click-0.4.pc.in 1970-01-01 00:00:00.000000000 +0000
@@ -1,28 +0,0 @@
-# Copyright (C) 2014 Canonical Ltd.
-#
-# This file is part of click.
-#
-# click is free software: you can redistribute it and/or modify it under the
-# terms of the GNU General Public License as published by the Free Software
-# Foundation; version 3 of the License.
-#
-# click is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along
-# with click. If not, see