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 Extensions are Lua scripts that require installation and configuration, and when
- User Defined Attribute invoked have access to taskwarrior internals through a Lua API.
- Command
- Format There are several types of extension. Each type has different requirements, and
- DOM 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> #include <API.h>
extern Context context; extern Context context;
Task* the_task = NULL;
#ifdef HAVE_LIBLUA #ifdef HAVE_LIBLUA
@ -122,6 +121,7 @@ static int api_task_set (lua_State* L)
catch (...) catch (...)
{ {
// TODO Error! // TODO Error!
lua_pushstring (L, "");
} }
} }
@ -223,16 +223,10 @@ bool API::callTaskHook (
// Prepare args. // Prepare args.
lua_pushnumber (L, current.id); lua_pushnumber (L, current.id);
// Expose the task.
the_task = &current;
// Make call. // Make call.
if (lua_pcall (L, 1, 2, 0) != 0) if (lua_pcall (L, 1, 2, 0) != 0)
throw std::string ("Error calling '") + function + "' - " + lua_tostring (L, -1) + "."; throw std::string ("Error calling '") + function + "' - " + lua_tostring (L, -1) + ".";
// Hide the task.
the_task = NULL;
// Call successful - get return values. // Call successful - get return values.
if (!lua_isnumber (L, -2)) if (!lua_isnumber (L, -2))
throw std::string ("Error: '") + function + "' did not return a success indicator."; throw std::string ("Error: '") + function + "' did not return a success indicator.";