1.. _loading-collections:
2
3===================
4Loading collections
5===================
6
7The core of Invoke's execution model involves one or more Collection objects.
8While these may be created programmatically, in typical use Invoke will create
9them for you from Python modules it finds or is told to use.
10
11
12.. _collection-discovery:
13
14Task module discovery
15=====================
16
17With no other configuration, simply calling ``invoke`` will look for a single
18Python module or package named ``tasks``, and will treat it as the root
19namespace. ``tasks`` (or any other name given via :ref:`loading configuration
20options <configuring-loading>`) is searched for in the following ways:
21
22* First, if a valid tasks module by that name already exists on Python's
23  `sys.path <http://docs.python.org/release/2.7/library/sys.html#sys.path>`_,
24  no more searching is done -- that module is selected.
25* Failing that, search towards the root of the local filesystem, starting with
26  the user's current working directory (`os.getcwd
27  <http://docs.python.org/release/2.7/library/os.html#os.getcwd>`_) and try
28  importing again with each directory temporarily added to ``sys.path``.
29
30    * Due to how Python's import machinery works, this approach will always
31      favor a package directory (``tasks/`` containing an ``__init__.py``) over
32      a module file (``tasks.py``) in the same location.
33    * If a candidate is found and successfully imported, its parent directory
34      will **stay** on ``sys.path`` during the rest of the Python session --
35      this allows task code to make convenient assumptions concerning sibling
36      modules' importability.
37
38Candidate modules/packages are introspected to make sure they can actually be
39used as valid task collections. Any that fail are discarded, the ``sys.path``
40munging done to import them is reverted, and the search continues.
41
42
43.. _configuring-loading:
44
45Configuring the loading process
46===============================
47
48You can configure the above behavior, requesting that Invoke alter the
49collection name searched for and/or the path where filesystem-level loading
50starts looking.
51
52For example, you may already have a project-level ``tasks.py`` that you can't
53easily rename; or you may want to host a number of tasks collections stored
54outside the project root and make it easy to switch between them; or any number
55of reasons.
56
57Both the sought collection name and the search root can be specified via
58:ref:`configuration file options <config-files>` or as :doc:`runtime CLI flags
59</invoke>`:
60
61- **Change the collection name**: Set the ``tasks.collection_name``
62  configuration option, or use :option:`--collection`. It should be a Python
63  module name and not a file name (so ``mytasks``, not ``mytasks.py`` or
64  ``mytasks/``.)
65- **Change the root search path**: Configure ``tasks.search_root`` or use
66  :option:`--search-root`. This value may be any valid directory path.
67