diff options
author | kennyballou <kballou@onyx.boisestate.edu> | 2013-10-03 20:15:49 -0600 |
---|---|---|
committer | kennyballou <kballou@onyx.boisestate.edu> | 2013-10-03 20:15:49 -0600 |
commit | 9f37b86453e70502f943abc1dc6532a590dac9f7 (patch) | |
tree | 4087df829156742f52f46a59fb1b86ba0321102d | |
parent | eb280ea3bd908d9f33a881f2b46cd17671975848 (diff) | |
parent | 9fee0807a3ffbdd85df612caab99f060a5f4d006 (diff) | |
download | xnt-9f37b86453e70502f943abc1dc6532a590dac9f7.tar.gz xnt-9f37b86453e70502f943abc1dc6532a590dac9f7.tar.xz |
Merge branch 'add_target_run_check' into develop
-rw-r--r-- | docs/source/buildfile.rst | 49 | ||||
-rw-r--r-- | xnt/__init__.py | 25 |
2 files changed, 66 insertions, 8 deletions
diff --git a/docs/source/buildfile.rst b/docs/source/buildfile.rst index 8200fff..2786a32 100644 --- a/docs/source/buildfile.rst +++ b/docs/source/buildfile.rst @@ -73,6 +73,55 @@ call ``mkdir`` of the ``xnt`` (internally of the ``xnt.tasks``) module. This function, if not obvious by the name, creates a directory named 'build' (see :doc:`taskreference`). +Target Decorator +================ + +The ``target`` decorator is just a standard Python decorating function with a +few exceptions. Namely, a new default behaviour is being introduced: a target +will _not_ execute more than once in a single invocation of ``xnt``. However, +if you so require a target to execute more than once, the option is provided. +For example:: + + import xnt + + @xnt.target + def init(): + #executes initalization + + @xnt.target + def build(): + init() # depends on init + # compiles project + + @xnt.target + def package(): + init() # explicitly depends on init + build() # depends on build + # packages project together + +The ``target`` decorators new default behaviour will not run the ``init`` +target more than once if the ``package`` target was invoked. However, let's say +we introduce another target, ``clean`` for example, and define it as:: + + @xnt.target(always_run=True) + def clean(): + # clean project state + +To further illustrate this new optional argument, let us define another +target, ``test`` that will call ``clean`` twice:: + + @xnt.target + def test(): + clean() + package() + # Run tests + clean() + +When we run our ``test`` target, we notice we want to start from a fresh, clean +state and we want to finish on a fresh, clean state. With the new default, this +wouldn't be possible, but with this new optional argument, ``always_run`` it +still is. + Return Values ============= diff --git a/xnt/__init__.py b/xnt/__init__.py index 61de895..507041f 100644 --- a/xnt/__init__.py +++ b/xnt/__init__.py @@ -55,15 +55,24 @@ from xnt.tasks import setup from xnt.tasks import which from xnt.tasks import in_path -def target(target_fn): +def target(*args, **kwargs): """Decorator function for marking a method in build file as a "target" method, or a method meant to be invoked from Xnt """ - def wrap(): - """Inner wrapper function for decorator""" - print(target_fn.__name__ + ":") - return target_fn() - wrap.decorator = "target" - wrap.__doc__ = target_fn.__doc__ - return wrap + def w_target(target_fn): + """target wrapping function""" + has_run = [False,] + def wrap(): + """Inner wrapper function for decorator""" + if not has_run[0] or kwargs.get('always_run', False): + has_run[0] = True + print(target_fn.__name__ + ":") + return target_fn() + return None + wrap.decorator = "target" + wrap.__doc__ = target_fn.__doc__ + return wrap + if len(args) == 1 and callable(args[0]): + return w_target(args[0]) + return w_target |