Extensions

- Created scripts/extensions/README to describe samples.
- Created sample extension scripts of each type.
This commit is contained in:
Paul Beckingham 2011-04-18 00:51:34 -04:00
parent bac4610580
commit 60a5d271f4
10 changed files with 335 additions and 55 deletions

16
scripts/add-ons/README Normal file
View file

@ -0,0 +1,16 @@
External Scripts
----------------
Add-on scripts are executed vi an alias mechanism in taskwarrior. This has the
effect of this command:
task <script> <arguments>
resulting in the ultimate execution of:
<script> <arguments>
All external scripts are treated in the same manner, and have no access to the
taskwarrior internals.
---

View file

@ -1,8 +1,100 @@
There are several types of extension:
Extensions
----------
- Hook-based
- User Defined Attribute
- Command
- Format
- DOM
Extensions are Lua scripts that require installation and configuration, and when
invoked have access to taskwarrior internals through a Lua API.
There are several types of extension. Each type has different requirements, and
is called in different ways.
All extensions must be installed, which means they must implement the 'install'
function, which provides:
- Type One of: program, task, uda, command, format, dom
- Name Single word name
- Version Version string
- Description One to two line description
- Author Author's name
- Contact Author's contact
- License Distribution License
- Copyright Copyright notice
Program Hooks
-------------
These are scripts that are triggered by program-level events. The supported
program hooks are:
on-launch As soon as is convenient after program launch
on-exit As late as possible while still providing API
on-file-read Immediately before reading a data file
on-file-write Immediately after writing a data file
on-synch Immediately before a synch operation
on-merge Immediately before a merge operation
on-gc Immediately before a GC operation
When a program hook script is invoked, there is no context, so no arguments are
passed to the script.
Task Hooks
----------
These scripts are triggered by task-specific events. The supported task hooks
are:
on-task-add Immediately prior to committing an added task
on-task-modify Immediately prior to committing a modified task
on-task-complete Immediately prior to committing a completed task
on-task-delete Immediately prior to committing a deleted task
When a task hook script is invoked, the context is a specific task, and so the
task uuid is passed as the only argument.
User Defined Attribute
----------------------
It is possible to create a user-defined attribute with a UDA extension. These
extensions must provide:
- Data type (string, date, duration, integer, real, custom)
- Custom types must implement a compare function for sorting
- Default format rendering
- Allowed value checking
Command
-------
It is possible to implement a command using an extension. These extensions must
provide:
- BNF command syntax
- Declaration as read-only or write command, which allows taskwarrior to
allow this command when the database is read-only
- Declaration of whether the command displays ID values, which instructs
taskwarrior to run a GC beforehan
Format
------
A format extension is one that provides custom rendering for an attribute.
These extensions must provide:
- Must implement a format function.
DOM
---
DOM extensions provide a DOM address and can be called to respond to that name.
These extensions must provide:
- DOM name
- Evaluation function
---

View file

@ -0,0 +1,45 @@
-- Command Extension.
-- Implementing 'random'.
-- Arguments: None
-- Returns: An 8-element list of installation details. Only called once, on
-- installation of the extension.
function install ()
return 'command', -- Type
'random', -- Name
1.0, -- Version
'Displays a random pending task', -- Description
'Paul Beckingham', -- Author
'paul@beckingham.net', -- Contact
'GPLv2', -- License
'© 2011, Göteborg Bit Factory' -- Copyright
end
-- Arguments: None
-- Returns: Valid Taskwarrior BNF, minimally defining a production rule that
-- has the same name as the command itself
function syntax ()
return 'random ::= "random" ;'
end
-- Arguments: None
-- Returns: 1 --> command does not modify data
-- 0 --> command modifies data
function read_only ()
return 1
end
-- Arguments: None
-- Returns: 1 --> command displays task ID
-- 0 --> no ID dispalyed
function display_id ()
return 1
end
-- Arguments: None
-- Returns: 1, 'error' --> command failed
-- 0, nil --> success
function execute ()
return 1, 'Not implemented'
end

View file

@ -0,0 +1,24 @@
-- DOM Extension.
-- Implementing 'system.load.average'.
-- Arguments: None
-- Returns: An 8-element list of installation details. Only called once, on
-- installation of the extension.
function install ()
return 'dom', -- Type
'system.load.average', -- Name
1.0, -- Version
'Provides access to system load', -- Description
'Paul Beckingham', -- Author
'paul@beckingham.net', -- Contact
'GPLv2', -- License
'© 2011, Göteborg Bit Factory' -- Copyright
end
-- Arguments: The DOM reference to evaluate
-- Returns: The value from the DOM lookup
-- Note: 'name' may include '*' wildcards
function lookup (name)
return 1.23 -- Fake load average
end

View file

@ -0,0 +1,23 @@
-- Format Extension.
-- Implementing 'uuid.short'
-- Arguments: None
-- Returns: An 8-element list of installation details. Only called once, on
-- installation of the extension.
function install ()
return 'format', -- Type
'uuid.short', -- Name
1.0, -- Version
'Provides short formatted UUIDs', -- Description
'Paul Beckingham', -- Author
'paul@beckingham.net', -- Contact
'GPLv2', -- License
'© 2011, Göteborg Bit Factory' -- Copyright
end
-- Argument: Value to be formatted
-- Returns: Formatted value
function format (value)
return string.sub (value, 0, 8)
end

View file

@ -1,42 +0,0 @@
--------------------------------------------------------------------------------
-- taskwarrior - a command line task list manager.
--
-- Copyright 2006 - 2011, Paul Beckingham, Federico Hernandez.
-- All rights reserved.
--
-- This program 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; either version 2 of the License, or (at your option) any later
-- version.
--
-- This program 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
-- this program; if not, write to the
--
-- Free Software Foundation, Inc.,
-- 51 Franklin Street, Fifth Floor,
-- Boston, MA
-- 02110-1301
-- USA
--
--------------------------------------------------------------------------------
-- Extension to implement 'priority' as a user-defined attribute.
-- Required for all extensions.
function install ()
return 'Priority', -- Name
1.0, -- Version
'uda', -- Type
'Implements priority attribute', -- Description
'Paul Beckingham', -- Author
'paul@beckingham.net', -- Contact
'© 2011, Göteborg Bit Factory' -- Copyright
end
-- TODO Required for UDA extensions.

View file

@ -0,0 +1,31 @@
-- Program Hook Extension.
-- Implementing goodbye message.
-- Arguments: None
-- Returns: An 8-element list of installation details. Only called once, on
-- installation of the extension.
function install ()
return 'program', -- Type
'goodbye', -- Name
1.0, -- Version
'Simply says goodbye', -- Description
'Paul Beckingham', -- Author
'paul@beckingham.net', -- Contact
'GPLv2', -- License
'© 2011, Göteborg Bit Factory' -- Copyright
end
-- Arguments: None
-- Returns: String identifying valid program hook
function hook ()
return 'on-exit'
end
-- Arguments: None
-- Returns: 1, 'error' --> failure
-- 0, nil --> success
function goodbye ()
print ('Goodbye.')
return 0, nil
end

View file

@ -0,0 +1,36 @@
-- Task Hook Extension.
-- Implementing encouragement message.
-- Arguments: None
-- Returns: An 8-element list of installation details. Only called once, on
-- installation of the extension.
function install ()
return 'task', -- Type
'encourage', -- Name
1.0, -- Version
'Positive feedback', -- Description
'Paul Beckingham', -- Author
'paul@beckingham.net', -- Contact
'GPLv2', -- License
'© 2011, Göteborg Bit Factory' -- Copyright
end
-- Arguments: None
-- Returns: String identifying valid program hook
function hook ()
return 'on-task-complete'
end
-- Arguments: None
-- Returns: 1, 'error' --> failure
-- 0, nil --> success
function encourage ()
-- Only provide encouragement if the verbosity settings allow it.
verbosity = task_get ('rc.verbose')
if string.find (verbosity, 'encourage') ~= nil
then
print ('Good work.')
end
return 0, nil
end

View file

@ -0,0 +1,61 @@
-- User Defined Attribute Extension.
-- Implementing 'priority'.
-- Arguments: None
-- Returns: An 8-element list of installation details. Only called once, on
-- installation of the extension.
function install ()
return 'uda', -- Type
'priority', -- Name
1.0, -- Version
'Implements priority attribute', -- Description
'Paul Beckingham', -- Author
'paul@beckingham.net', -- Contact
'GPLv2', -- License
'© 2011, Göteborg Bit Factory' -- Copyright
end
-- Arguments: None
-- Returns: Data type
function type ()
return 'custom'
end
-- Arguments: proposed value
-- Returns: 1 --> allowed
-- 0 --> disallowed
function allowed (value)
if value == 'H' ||
value == 'M' ||
value == 'L' ||
value == '' then
return 1
end
return 0
end
-- Arguments: left and right values to compare
-- Returns: 1 --> left < right
-- 0 --> left >= right
function compare (left, right)
if left == 'M' && right == 'H' then
return 1
elseif left == 'L' && (right == 'H' || right == 'M') then
return 1
elseif left == '' then
return 1
end
return 0
end
-- Arguments: Raw data
-- Returns: Formatted data
-- Note: Shown here is a pass-through format, doing no formatting. This is
-- the default behavior if the format function is not implemented.
function format (value)
return value
end

View file

@ -53,7 +53,6 @@
#include <API.h>
extern Context context;
Task* the_task = NULL;
#ifdef HAVE_LIBLUA
@ -122,6 +121,7 @@ static int api_task_set (lua_State* L)
catch (...)
{
// TODO Error!
lua_pushstring (L, "");
}
}
@ -223,16 +223,10 @@ bool API::callTaskHook (
// Prepare args.
lua_pushnumber (L, current.id);
// Expose the task.
the_task = &current;
// Make call.
if (lua_pcall (L, 1, 2, 0) != 0)
throw std::string ("Error calling '") + function + "' - " + lua_tostring (L, -1) + ".";
// Hide the task.
the_task = NULL;
// Call successful - get return values.
if (!lua_isnumber (L, -2))
throw std::string ("Error: '") + function + "' did not return a success indicator.";