mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-06-26 10:54:26 +02:00
Extension Mechanism Cleanup
- Cleaned up existing extension debris, in anticipation of the new mechanisms to be included in future releases. This includes install/uninstall and a full set of triggers.
This commit is contained in:
parent
a736568e68
commit
19cdf25a8f
26 changed files with 10 additions and 913 deletions
|
@ -57,15 +57,6 @@ if (GNUTLS_FOUND)
|
|||
set (TASK_LIBRARIES ${TASK_LIBRARIES} ${GNUTLS_LIBRARIES})
|
||||
endif (GNUTLS_FOUND)
|
||||
|
||||
message ("-- Looking for Lua51")
|
||||
find_package (Lua51)
|
||||
if (LUA51_FOUND)
|
||||
message ("-- Found Lua51: ${LUA_LIBRARIES}")
|
||||
set (HAVE_LIBLUA true)
|
||||
set (TASK_INCLUDE_DIRS ${TASK_INCLUDE_DIRS} ${LUA_INCLUDE_DIR})
|
||||
set (TASK_LIBRARIES ${TASK_LIBRARIES} ${LUA_LIBRARIES})
|
||||
endif (LUA51_FOUND)
|
||||
|
||||
#message ("-- Looking for pthread")
|
||||
#find_path (PTHREAD_INCLUDE_DIR pthread.h)
|
||||
#find_library (PTHREAD_LIBRARY NAMES pthread)
|
||||
|
|
10
INSTALL
10
INSTALL
|
@ -12,9 +12,6 @@ from source.
|
|||
|
||||
More information on cmake can be obtained at http://cmake.org
|
||||
|
||||
Optionally, you might want to have Lua installed, if you wish to write plugins
|
||||
and modify taskwarrior.
|
||||
|
||||
|
||||
Basic Installation
|
||||
------------------
|
||||
|
@ -125,11 +122,6 @@ Cygwin
|
|||
again, or reinstall Cygwin under your normal Windows login.
|
||||
|
||||
|
||||
Darwin
|
||||
If you're having trouble with Lua, check to see if the include files were
|
||||
installed. If you're using fink, this will require the lua51-dev package in
|
||||
addition to lua51.
|
||||
|
||||
Darwin, 32bit
|
||||
The taskwarrior packages will not work on a 32-bit OSX installation on Core
|
||||
Duo hardware. You will need to build Taskwarrior from source, and use this
|
||||
|
@ -147,7 +139,7 @@ Darwin, 32bit
|
|||
Troubleshooting
|
||||
---------------
|
||||
|
||||
If you've recently made changes to dependencies (by reinstalling Lua, for
|
||||
If you've recently made changes to dependencies (by reinstalling libuuid, for
|
||||
example) be sure to rerun 'cmake .' before trying to execute 'make' again.
|
||||
|
||||
CMake will run and locate all the necessary pieces for the build, and create
|
||||
|
|
|
@ -45,9 +45,6 @@ Override PACKAGE_LANGUAGE, then
|
|||
/* Found the GnuTLS library */
|
||||
#cmakedefine HAVE_LIBGNUTLS
|
||||
|
||||
/* Found the lua library */
|
||||
#cmakedefine HAVE_LIBLUA
|
||||
|
||||
/* Found the pthread library */
|
||||
#cmakedefine HAVE_LIBPTHREAD
|
||||
|
||||
|
|
|
@ -340,17 +340,6 @@ The day in question has to be boxed by a range, like this:
|
|||
Note that a single date, such as 3/29/2012 does not refer to a whole day, but
|
||||
to a single point in time, 3/20/2012 0:00:00.
|
||||
|
||||
.TP
|
||||
.B Q: Why Lua as an extension language?
|
||||
Lua has many positive attributes:
|
||||
|
||||
- Lua is written using tight, fast, standard C
|
||||
- Lua is a breeze to integrate into any product
|
||||
- The Lua source code is beautifully written
|
||||
- Lua is a small language
|
||||
|
||||
Guile, Scheme and Neko were also considered.
|
||||
|
||||
.TP
|
||||
.B Q: How can I help?
|
||||
There are lots of ways. Here are some:
|
||||
|
|
|
@ -64,25 +64,10 @@ Note: This is being written from the OSX 10.6 perspective, and may therefore
|
|||
|
||||
4.1 The test suite exists to prove that we do not break taskwarrior features
|
||||
from one release to the next. While this is not a perfect solution, it has
|
||||
saved us many times from releasing code that is inferior.
|
||||
|
||||
The first step is to modify the test suite Makefile to remove the Lua line.
|
||||
This is because we do not yet have dynamic detection of the Lua library for
|
||||
the unit tests.
|
||||
saved us many times from releasing code that is broken. Build the unit
|
||||
tests:
|
||||
|
||||
$ cd ~/task-package.git/src/tests
|
||||
$ vi Makefile
|
||||
|
||||
Any text editor will do, but look for this line (line 5):
|
||||
|
||||
LFLAGS = -L/usr/local/lib -llua
|
||||
|
||||
and change it to:
|
||||
|
||||
LFLAGS = -L/usr/local/lib
|
||||
|
||||
Now build the unit tests:
|
||||
|
||||
$ make -j 2
|
||||
...
|
||||
|
||||
|
@ -97,8 +82,8 @@ Note: This is being written from the OSX 10.6 perspective, and may therefore
|
|||
Runtime: 86
|
||||
|
||||
The output should look something like this, with 0 failed, and 0 skipped
|
||||
tests. If there are any failures or skips, stop and mailed the log file,
|
||||
named 'all.log' to Paul & Fredde.
|
||||
tests. If there are any failures or skips, stop and mail the log file,
|
||||
named 'all.log' to Paul and/or Fredde.
|
||||
|
||||
5. Assemble the parts
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
cmake_minimum_required (VERSION 2.8)
|
||||
install (DIRECTORY bash fish vim zsh extensions
|
||||
install (DIRECTORY bash fish vim zsh
|
||||
DESTINATION ${TASK_DOCDIR}/scripts)
|
||||
install (DIRECTORY add-ons
|
||||
DESTINATION ${TASK_DOCDIR}/scripts
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
-- 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
|
||||
'MIT', -- License
|
||||
'© 2012, Göteborg Bit Factory' -- Copyright
|
||||
end
|
||||
|
||||
-- Arguments: None
|
||||
-- Returns: Usage syntax, such as "task random"
|
||||
function usage ()
|
||||
return 'task random'
|
||||
end
|
||||
|
||||
-- Arguments: None
|
||||
-- Returns: 1 --> command does not modify data
|
||||
-- 0 --> command modifies data
|
||||
function read_only ()
|
||||
return true
|
||||
end
|
||||
|
||||
-- Arguments: None
|
||||
-- Returns: 1 --> command displays task ID
|
||||
-- 0 --> no ID displayed
|
||||
function display_id ()
|
||||
return true
|
||||
end
|
||||
|
||||
-- Arguments: None
|
||||
-- Returns: 1 --> command failed
|
||||
-- 0 --> success
|
||||
function execute (command_line)
|
||||
task_footnote_message ('Not implemented')
|
||||
return 1
|
||||
end
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
-- 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
|
||||
'MIT', -- License
|
||||
'© 2012, Göteborg Bit Factory' -- Copyright
|
||||
end
|
||||
|
||||
-- Arguments: The DOM reference to evaluate
|
||||
-- Returns: The value from the DOM lookup
|
||||
function lookup (name)
|
||||
if name == 'system.load.average'
|
||||
then
|
||||
return 1.23 -- Fake load average
|
||||
end
|
||||
end
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
-- 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
|
||||
'MIT', -- License
|
||||
'© 2012, Göteborg Bit Factory' -- Copyright
|
||||
end
|
||||
|
||||
-- Argument: Value to be formatted
|
||||
-- Returns: Formatted value
|
||||
function format (value)
|
||||
return string.sub (value, 0, 8)
|
||||
end
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
-- 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
|
||||
'MIT', -- License
|
||||
'© 2012, Göteborg Bit Factory' -- Copyright
|
||||
end
|
||||
|
||||
-- Arguments: None
|
||||
-- Returns: String identifying valid program hook
|
||||
function hook ()
|
||||
return 'on-exit'
|
||||
end
|
||||
|
||||
-- Arguments: None
|
||||
-- Returns: 0 --> success only
|
||||
function execute ()
|
||||
print ('Goodbye.')
|
||||
end
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
-- 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
|
||||
'MIT', -- License
|
||||
'© 2012, 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 --> failure
|
||||
-- 0 --> success
|
||||
function execute (uuid)
|
||||
-- Only provide encouragement if the verbosity settings allow it.
|
||||
verbosity = task_get ('rc.verbose')
|
||||
if string.find (verbosity, 'encourage') ~= nil
|
||||
then
|
||||
task_footnote_message ('Good work.')
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
-- 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
|
||||
'MIT', -- License
|
||||
'© 2012, Göteborg Bit Factory' -- Copyright
|
||||
end
|
||||
|
||||
-- Arguments: None
|
||||
-- Returns: Data type
|
||||
function type ()
|
||||
return 'custom'
|
||||
end
|
||||
|
||||
-- Arguments: None
|
||||
-- Returns: List of allowable values
|
||||
function allowed ()
|
||||
return 'H', 'M', 'L', ''
|
||||
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
|
||||
-- also the default behavior if the format function is not
|
||||
-- implemented.
|
||||
function format (value)
|
||||
return value
|
||||
end
|
||||
|
||||
-- Arguments: Value
|
||||
-- Returns: Urgency Term
|
||||
-- Note: Should reference rc.urgency.<field>.coefficient
|
||||
function urgency (uuid)
|
||||
coefficient = task_get ('rc.urgency.priority.coefficient')
|
||||
|
||||
-- TODO Urgency calculation here
|
||||
|
||||
return coefficient * 1.0
|
||||
end
|
||||
|
258
src/API.cpp
258
src/API.cpp
|
@ -1,258 +0,0 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Taskwarrior Lua API
|
||||
//
|
||||
// Copyright 2006-2012, Paul Beckingham, Federico Hernandez.
|
||||
// Copyright © 1994–2008 Lua.org, PUC-Rio.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
// http://www.opensource.org/licenses/mit-license.php
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define L10N // Localization complete.
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <Context.h>
|
||||
#include <API.h>
|
||||
#include <text.h>
|
||||
#include <i18n.h>
|
||||
|
||||
extern Context context;
|
||||
|
||||
#ifdef HAVE_LIBLUA
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static int api_task_header_message (lua_State* L)
|
||||
{
|
||||
std::string message = luaL_checkstring (L, 1);
|
||||
context.header (message);
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static int api_task_footnote_message (lua_State* L)
|
||||
{
|
||||
std::string message = luaL_checkstring (L, 1);
|
||||
context.footnote (message);
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static int api_task_debug_message (lua_State* L)
|
||||
{
|
||||
std::string message = luaL_checkstring (L, 1);
|
||||
context.debug (message);
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Causes the shell mode task to exit. Ordinarily this does not occur.
|
||||
static int api_task_exit (lua_State*)
|
||||
{
|
||||
// TODO Is this the correct exception? How does the shell handle this?
|
||||
std::cout << STRING_API_EXITING << std::endl;
|
||||
exit (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// DOM reads.
|
||||
static int api_task_get (lua_State* L)
|
||||
{
|
||||
std::string name = luaL_checkstring (L, 1);
|
||||
try
|
||||
{
|
||||
lua_pushstring (L, context.dom.get (name).c_str ());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// TODO Error!
|
||||
lua_pushstring (L, "");
|
||||
}
|
||||
|
||||
return 1; // 1 returned value.
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// DOM writes.
|
||||
static int api_task_set (lua_State* L)
|
||||
{
|
||||
std::string name = luaL_checkstring (L, 1);
|
||||
std::string value = luaL_checkstring (L, 2);
|
||||
|
||||
try
|
||||
{
|
||||
context.dom.set (name, value);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// TODO Error!
|
||||
lua_pushstring (L, "");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
API::API ()
|
||||
: _state (NULL)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
API::~API ()
|
||||
{
|
||||
if (_state)
|
||||
{
|
||||
lua_close (_state);
|
||||
_state = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void API::initialize ()
|
||||
{
|
||||
// Initialize Lua.
|
||||
_state = luaL_newstate ();
|
||||
luaL_openlibs (_state); // TODO Error handling
|
||||
|
||||
// Register all the API functions in Lua global space.
|
||||
lua_pushcfunction (_state, api_task_header_message); lua_setglobal (_state, "task_header_message");
|
||||
lua_pushcfunction (_state, api_task_footnote_message); lua_setglobal (_state, "task_footnote_message");
|
||||
lua_pushcfunction (_state, api_task_debug_message); lua_setglobal (_state, "task_debug_message");
|
||||
lua_pushcfunction (_state, api_task_exit); lua_setglobal (_state, "task_exit");
|
||||
lua_pushcfunction (_state, api_task_get); lua_setglobal (_state, "task_get");
|
||||
lua_pushcfunction (_state, api_task_set); lua_setglobal (_state, "task_set");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool API::callProgramHook (
|
||||
const std::string& file,
|
||||
const std::string& function)
|
||||
{
|
||||
loadFile (file);
|
||||
|
||||
// Get function.
|
||||
lua_getglobal (_state, function.c_str ());
|
||||
if (!lua_isfunction (_state, -1))
|
||||
{
|
||||
lua_pop (_state, 1);
|
||||
throw format (STRING_API_NOFUNC, function);
|
||||
}
|
||||
|
||||
// Make call.
|
||||
if (lua_pcall (_state, 0, 2, 0) != 0)
|
||||
throw format (STRING_API_ERROR_CALLING, function, lua_tostring (_state, -1));
|
||||
|
||||
// Call successful - get return values.
|
||||
if (!lua_isnumber (_state, -2))
|
||||
throw format (STRING_API_ERROR_FAIL, function);
|
||||
|
||||
if (!lua_isstring (_state, -1) && !lua_isnil (_state, -1))
|
||||
throw format (STRING_API_ERROR_NORET, function);
|
||||
|
||||
int rc = lua_tointeger (_state, -2);
|
||||
const char* message = lua_tostring (_state, -1);
|
||||
|
||||
if (rc == 0)
|
||||
{
|
||||
if (message)
|
||||
context.footnote (format (STRING_API_WARNING, message));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (message)
|
||||
throw std::string (message);
|
||||
}
|
||||
|
||||
lua_pop (_state, 1);
|
||||
return rc == 0 ? true : false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool API::callTaskHook (
|
||||
const std::string& file,
|
||||
const std::string& function,
|
||||
Task& task)
|
||||
{
|
||||
loadFile (file);
|
||||
|
||||
// Save the task for reference via the API.
|
||||
_current = task;
|
||||
|
||||
// Get function.
|
||||
lua_getglobal (_state, function.c_str ());
|
||||
if (!lua_isfunction (_state, -1))
|
||||
{
|
||||
lua_pop (_state, 1);
|
||||
throw format (STRING_API_NOFUNC, function);
|
||||
}
|
||||
|
||||
// Prepare args.
|
||||
lua_pushnumber (_state, _current.id);
|
||||
|
||||
// Make call.
|
||||
if (lua_pcall (_state, 1, 2, 0) != 0)
|
||||
throw format (STRING_API_ERROR_CALLING, function, lua_tostring (_state, -1));
|
||||
|
||||
// Call successful - get return values.
|
||||
if (!lua_isnumber (_state, -2))
|
||||
throw format (STRING_API_ERROR_FAIL, function);
|
||||
|
||||
if (!lua_isstring (_state, -1) && !lua_isnil (_state, -1))
|
||||
throw format (STRING_API_ERROR_NORET, function);
|
||||
|
||||
int rc = lua_tointeger (_state, -2);
|
||||
const char* message = lua_tostring (_state, -1);
|
||||
|
||||
if (rc == 0)
|
||||
{
|
||||
if (message)
|
||||
context.footnote (format (STRING_API_WARNING, message));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (message)
|
||||
throw std::string (message);
|
||||
}
|
||||
|
||||
lua_pop (_state, 1);
|
||||
return rc == 0 ? true : false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void API::loadFile (const std::string& file)
|
||||
{
|
||||
// If the file is not loaded.
|
||||
if (std::find (_loaded.begin (), _loaded.end (), file) == _loaded.end ())
|
||||
{
|
||||
// Load the file, if possible.
|
||||
if (luaL_loadfile (_state, file.c_str ()) || lua_pcall (_state, 0, 0, 0))
|
||||
throw format (STRING_API_ERROR, lua_tostring (_state, -1));
|
||||
|
||||
// Mark this as _loaded, so as to not bother again.
|
||||
_loaded.push_back (file);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif
|
||||
|
74
src/API.h
74
src/API.h
|
@ -1,74 +0,0 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Taskwarrior Lua API
|
||||
//
|
||||
// Copyright 2006-2012, Paul Beckingham, Federico Hernandez.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
// http://www.opensource.org/licenses/mit-license.php
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef INCLUDED_API
|
||||
#define INCLUDED_API
|
||||
#define L10N // Localization complete.
|
||||
|
||||
#include <cmake.h>
|
||||
#ifdef HAVE_LIBLUA
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <Task.h>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include <lua.h>
|
||||
#include <lualib.h>
|
||||
#include <lauxlib.h>
|
||||
}
|
||||
|
||||
class API
|
||||
{
|
||||
public:
|
||||
API ();
|
||||
API (const API&);
|
||||
API& operator= (const API&);
|
||||
~API ();
|
||||
|
||||
void initialize ();
|
||||
bool callProgramHook (const std::string&, const std::string&);
|
||||
bool callTaskHook (const std::string&, const std::string&, Task&);
|
||||
|
||||
private:
|
||||
void loadFile (const std::string&);
|
||||
|
||||
public:
|
||||
lua_State* _state;
|
||||
std::vector <std::string> _loaded;
|
||||
|
||||
// Context for the API.
|
||||
// std::vector <Task> all;
|
||||
Task _current;
|
||||
// std::string& name;
|
||||
// std::string& value;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
|
@ -6,7 +6,6 @@ include_directories (${CMAKE_SOURCE_DIR}
|
|||
${TASK_INCLUDE_DIRS})
|
||||
|
||||
set (task_SRCS A3.cpp A3.h
|
||||
API.cpp API.h
|
||||
Arg.cpp Arg.h
|
||||
Color.cpp Color.h
|
||||
Config.cpp Config.h
|
||||
|
|
|
@ -502,7 +502,7 @@ bool Context::verbose (const std::string& token)
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// This needs to be taken out and shot, as soon as Lua extensions will allow.
|
||||
// This needs to be taken out and shot, as soon as hooks will allow.
|
||||
void Context::shadow ()
|
||||
{
|
||||
std::string file_name = config.get ("shadow.file");
|
||||
|
|
17
src/DOM.cpp
17
src/DOM.cpp
|
@ -35,13 +35,6 @@
|
|||
#include <DOM.h>
|
||||
#include <cmake.h>
|
||||
|
||||
#ifdef HAVE_LIBLUA
|
||||
extern "C"
|
||||
{
|
||||
#include <lua.h>
|
||||
}
|
||||
#endif
|
||||
|
||||
extern Context context;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -64,7 +57,6 @@ const std::vector <std::string> DOM::get_references () const
|
|||
refs.push_back ("context.width");
|
||||
refs.push_back ("context.height");
|
||||
refs.push_back ("system.version");
|
||||
refs.push_back ("system.lua.version");
|
||||
refs.push_back ("system.os");
|
||||
|
||||
return refs;
|
||||
|
@ -82,7 +74,6 @@ const std::vector <std::string> DOM::get_references () const
|
|||
// TODO stats.<name> <-- context.stats
|
||||
//
|
||||
// system.version
|
||||
// system.lua.version
|
||||
// system.os
|
||||
const std::string DOM::get (const std::string& name)
|
||||
{
|
||||
|
@ -124,12 +115,6 @@ const std::string DOM::get (const std::string& name)
|
|||
if (name == "system.version")
|
||||
return /*_cache[name] =*/ VERSION;
|
||||
|
||||
#ifdef HAVE_LIBLUA
|
||||
// Lua version number.
|
||||
else if (name == "system.lua.version")
|
||||
return /*_cache[name] =*/ LUA_RELEASE;
|
||||
#endif
|
||||
|
||||
// OS type.
|
||||
else if (name == "system.os")
|
||||
#if defined (DARWIN)
|
||||
|
@ -259,8 +244,6 @@ const std::string DOM::get (const std::string& name, const Task& task)
|
|||
return this->get (name);
|
||||
}
|
||||
|
||||
// TODO Need a context-specific DOM::set. For Lua. Probably.
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void DOM::set (const std::string& name, const std::string& value)
|
||||
{
|
||||
|
|
|
@ -103,10 +103,6 @@ Hooks::~Hooks ()
|
|||
// that if it isn't called, a script will not be loaded.
|
||||
void Hooks::initialize ()
|
||||
{
|
||||
#ifdef HAVE_LIBLUA
|
||||
_api.initialize ();
|
||||
#endif
|
||||
|
||||
// Allow a master switch to turn the whole thing off.
|
||||
bool big_red_switch = context.config.getBoolean ("extensions");
|
||||
if (big_red_switch)
|
||||
|
@ -147,7 +143,7 @@ void Hooks::initialize ()
|
|||
(void) n.skip (',');
|
||||
}
|
||||
else
|
||||
throw std::string (format (STRING_LUA_BAD_HOOK_DEF, *it));
|
||||
; // Was: throw std::string (format ("Malformed hook definition '{1}'.", *it));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -160,55 +156,15 @@ void Hooks::initialize ()
|
|||
// Program hooks.
|
||||
bool Hooks::trigger (const std::string& event)
|
||||
{
|
||||
#ifdef HAVE_LIBLUA
|
||||
std::vector <Hook>::iterator it;
|
||||
for (it = _all.begin (); it != _all.end (); ++it)
|
||||
{
|
||||
if (it->_event == event)
|
||||
{
|
||||
Timer timer (std::string ("Hooks::trigger ") + event);
|
||||
|
||||
if (validProgramEvent (event))
|
||||
{
|
||||
context.debug (std::string ("Event ") + event + " triggered");
|
||||
if (! _api.callProgramHook (it->_file, it->_function))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
throw std::string (format (STRING_LUA_BAD_EVENT, event));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Task hooks.
|
||||
bool Hooks::trigger (const std::string& event, Task& task)
|
||||
{
|
||||
#ifdef HAVE_LIBLUA
|
||||
std::vector <Hook>::iterator it;
|
||||
for (it = _all.begin (); it != _all.end (); ++it)
|
||||
{
|
||||
if (it->_event == event)
|
||||
{
|
||||
Timer timer (std::string ("Hooks::trigger ") + event);
|
||||
|
||||
if (validTaskEvent (event))
|
||||
{
|
||||
context.debug (std::string ("Event ") + event + " triggered");
|
||||
if (! _api.callTaskHook (it->_file, it->_function, task))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
throw std::string (format (STRING_LUA_BAD_EVENT, event));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Hooks::validProgramEvent (const std::string& event)
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <API.h>
|
||||
#include <cmake.h>
|
||||
|
||||
// Hook class representing a single hook, which is just a three-way map.
|
||||
|
@ -68,9 +67,6 @@ private:
|
|||
bool validTaskEvent (const std::string&);
|
||||
|
||||
private:
|
||||
#ifdef HAVE_LIBLUA
|
||||
API _api;
|
||||
#endif
|
||||
std::vector <Hook> _all; // All current hooks.
|
||||
|
||||
std::vector <std::string> _validProgramEvents;
|
||||
|
|
|
@ -39,13 +39,6 @@
|
|||
#include <cmake.h>
|
||||
#include <commit.h>
|
||||
|
||||
#ifdef HAVE_LIBLUA
|
||||
extern "C"
|
||||
{
|
||||
#include <lua.h>
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBGNUTLS
|
||||
#include <gnutls/gnutls.h>
|
||||
#endif
|
||||
|
@ -139,14 +132,6 @@ int CmdDiagnostics::execute (std::string& output)
|
|||
out << bold.colorize (STRING_CMD_DIAG_LIBRARIES)
|
||||
<< "\n";
|
||||
|
||||
out << " Lua: "
|
||||
#ifdef HAVE_LIBLUA
|
||||
<< LUA_RELEASE
|
||||
#else
|
||||
<< "n/a"
|
||||
#endif
|
||||
<< "\n";
|
||||
|
||||
out << " libuuid: "
|
||||
#if defined (HAVE_UUID) and defined (HAVE_UUID_UNPARSE_LOWER)
|
||||
<< "libuuid + uuid_unparse_lower"
|
||||
|
|
|
@ -350,46 +350,6 @@ int CmdShow::execute (std::string& output)
|
|||
// TODO Check for referenced but missing string files.
|
||||
// TODO Check for referenced but missing tips files.
|
||||
|
||||
// Check for referenced but missing hook scripts.
|
||||
#ifdef HAVE_LIBLUA
|
||||
std::vector <std::string> missing_scripts;
|
||||
for (i = all.begin (); i != all.end (); ++i)
|
||||
{
|
||||
if (i->substr (0, 5) == "hook.")
|
||||
{
|
||||
std::string value = context.config.get (*i);
|
||||
Nibbler n (value);
|
||||
|
||||
// <path>:<function> [, ...]
|
||||
while (!n.depleted ())
|
||||
{
|
||||
std::string file;
|
||||
std::string function;
|
||||
if (n.getUntil (':', file) &&
|
||||
n.skip (':') &&
|
||||
n.getUntil (',', function))
|
||||
{
|
||||
Path script (file);
|
||||
if (!script.exists () || !script.readable ())
|
||||
missing_scripts.push_back (file);
|
||||
|
||||
(void) n.skip (',');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (missing_scripts.size ())
|
||||
{
|
||||
out << STRING_CMD_SHOW_HOOKS << "\n";
|
||||
|
||||
for (i = missing_scripts.begin (); i != missing_scripts.end (); ++i)
|
||||
out << " " << *i << "\n";
|
||||
|
||||
out << "\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
// Check for bad values in rc.calendar.details.
|
||||
std::string calendardetails = context.config.get ("calendar.details");
|
||||
if (calendardetails != "full" &&
|
||||
|
|
|
@ -94,10 +94,6 @@ int CmdVersion::execute (std::string& output)
|
|||
<< STRING_CMD_VERSION_UNKNOWN
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBLUA
|
||||
<< "-lua"
|
||||
#endif
|
||||
|
||||
#if PACKAGE_LANGUAGE != LANGUAGE_EN_US
|
||||
<< " "
|
||||
<< STRING_LOCALIZATION_DESC
|
||||
|
@ -106,10 +102,6 @@ int CmdVersion::execute (std::string& output)
|
|||
<< "\n"
|
||||
<< STRING_CMD_VERSION_COPY
|
||||
<< "\n"
|
||||
#ifdef HAVE_LIBLUA
|
||||
<< STRING_CMD_VERSION_COPY2
|
||||
<< "\n"
|
||||
#endif
|
||||
<< "\n"
|
||||
<< disclaimer.render ()
|
||||
<< "\n"
|
||||
|
|
14
src/en-US.h
14
src/en-US.h
|
@ -117,15 +117,6 @@
|
|||
#define STRING_A3_RANGE_INVERTED "Inverted range 'high-low' instead of 'low-high'"
|
||||
#define STRING_A3_UUID_AFTER_COMMA "Unrecognized UUID after comma."
|
||||
|
||||
// API
|
||||
#define STRING_API_EXITING "Exiting."
|
||||
#define STRING_API_NOFUNC "The Lua function '{1}' was not found."
|
||||
#define STRING_API_ERROR_CALLING "Error calling '{1}' - {2}."
|
||||
#define STRING_API_ERROR_FAIL "Error: '{1}' did not return a success indicator."
|
||||
#define STRING_API_ERROR_NORET "Error: '{1}' did not return a message or nil."
|
||||
#define STRING_API_WARNING "Warning: {1}"
|
||||
#define STRING_API_ERROR "Error: {1}"
|
||||
|
||||
// Color
|
||||
#define STRING_COLOR_UNRECOGNIZED "The color '{1}' is not recognized."
|
||||
|
||||
|
@ -209,7 +200,6 @@
|
|||
#define STRING_CMD_VERSION_BUILT "{1} {2} built for "
|
||||
#define STRING_CMD_VERSION_UNKNOWN "unknown"
|
||||
#define STRING_CMD_VERSION_COPY "Copyright (C) 2006 - 2012 P. Beckingham, F. Hernandez."
|
||||
#define STRING_CMD_VERSION_COPY2 "Portions of this software Copyright (C) 1994 – 2008 Lua.org, PUC-Rio."
|
||||
#define STRING_CMD_LOGO_USAGE "Displays the Taskwarrior logo"
|
||||
#define STRING_CMD_LOGO_COLOR_REQ "The logo command requires that color support is enabled."
|
||||
#define STRING_CMD_EXEC_USAGE "Executes external commands and scripts"
|
||||
|
@ -761,10 +751,6 @@
|
|||
// Legacy
|
||||
#define STRING_LEGACY_FEATURE "Note: the '{1}' feature is deprecated."
|
||||
|
||||
// Lua
|
||||
#define STRING_LUA_BAD_HOOK_DEF "Malformed hook definition '{1}'."
|
||||
#define STRING_LUA_BAD_EVENT "Unrecognized hook event '{1}'."
|
||||
|
||||
// Record
|
||||
#define STRING_RECORD_EMPTY "Empty record in input."
|
||||
#define STRING_RECORD_JUNK_AT_EOL "Unrecognized characters at end of line."
|
||||
|
|
|
@ -31,23 +31,12 @@
|
|||
#include <main.h>
|
||||
#include <test.h>
|
||||
|
||||
#ifdef HAVE_LIBLUA
|
||||
extern "C"
|
||||
{
|
||||
#include <lua.h>
|
||||
}
|
||||
#endif
|
||||
|
||||
Context context;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
#if defined(HAVE_LIBLUA)
|
||||
UnitTest t (7);
|
||||
#else
|
||||
UnitTest t (6);
|
||||
#endif
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -57,9 +46,6 @@ int main (int argc, char** argv)
|
|||
// TODO dom.get rc.name
|
||||
DOM dom;
|
||||
t.is (dom.get ("system.version"), VERSION, "DOM system.version -> VERSION");
|
||||
#ifdef HAVE_LIBLUA
|
||||
t.is (dom.get ("system.lua.version"), LUA_RELEASE, "DOM system.lua.version -> LUA_RELEASE");
|
||||
#endif
|
||||
t.ok (dom.get ("system.os") != "<unknown>", "DOM system.os -> != Unknown");
|
||||
t.is (dom.get ("context.program"), "task", "DOM context.program -> 'task'");
|
||||
t.is (dom.get ("context.args"), "task", "DOM context.args -> 'task'");
|
||||
|
|
|
@ -1,73 +0,0 @@
|
|||
#! /usr/bin/env perl
|
||||
################################################################################
|
||||
## taskwarrior - a command line task list manager.
|
||||
##
|
||||
## Copyright 2006-2012, Paul Beckingham, Federico Hernandez.
|
||||
##
|
||||
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
## of this software and associated documentation files (the "Software"), to deal
|
||||
## in the Software without restriction, including without limitation the rights
|
||||
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
## copies of the Software, and to permit persons to whom the Software is
|
||||
## furnished to do so, subject to the following conditions:
|
||||
##
|
||||
## The above copyright notice and this permission notice shall be included
|
||||
## in all copies or substantial portions of the Software.
|
||||
##
|
||||
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
## SOFTWARE.
|
||||
##
|
||||
## http://www.opensource.org/licenses/mit-license.php
|
||||
##
|
||||
################################################################################
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Test::More tests => 4;
|
||||
|
||||
# Create the rc file.
|
||||
if (open my $fh, '>', 'hook.rc')
|
||||
{
|
||||
print $fh "data.location=.\n",
|
||||
"extensions=on\n",
|
||||
"hook.on-exit=" . $ENV{'PWD'} . "/hook:test\n";
|
||||
close $fh;
|
||||
ok (-r 'hook.rc', 'Created hook.rc');
|
||||
}
|
||||
|
||||
if (open my $fh, '>', 'hook')
|
||||
{
|
||||
print $fh "function test () print ('marker') return 0, nil end\n";
|
||||
close $fh;
|
||||
ok (-r 'hook', 'Created hook');
|
||||
}
|
||||
|
||||
# Test the hook.
|
||||
my $output = qx{../src/task rc:hook.rc version 2>&1};
|
||||
if ($output =~ /PUC-Rio/)
|
||||
{
|
||||
# Test the hook.
|
||||
$output = qx{../src/task rc:hook.rc _version 2>&1};
|
||||
like ($output, qr/\w{7}\nmarker/ms, 'Found marker after output');
|
||||
}
|
||||
else
|
||||
{
|
||||
pass ('Found marker after output - skipping: no Lua support');
|
||||
}
|
||||
|
||||
# Cleanup.
|
||||
unlink qw(pending.data completed.data undo.data backlog.data hook hook.rc);
|
||||
ok (! -r 'pending.data' &&
|
||||
! -r 'completed.data' &&
|
||||
! -r 'undo.data' &&
|
||||
! -r 'backlog.data' &&
|
||||
! -r 'hook' &&
|
||||
! -r 'hook.rc', 'Cleanup');
|
||||
|
||||
exit 0;
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
#! /usr/bin/env perl
|
||||
################################################################################
|
||||
## taskwarrior - a command line task list manager.
|
||||
##
|
||||
## Copyright 2006-2012, Paul Beckingham, Federico Hernandez.
|
||||
##
|
||||
## Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
## of this software and associated documentation files (the "Software"), to deal
|
||||
## in the Software without restriction, including without limitation the rights
|
||||
## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
## copies of the Software, and to permit persons to whom the Software is
|
||||
## furnished to do so, subject to the following conditions:
|
||||
##
|
||||
## The above copyright notice and this permission notice shall be included
|
||||
## in all copies or substantial portions of the Software.
|
||||
##
|
||||
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
## SOFTWARE.
|
||||
##
|
||||
## http://www.opensource.org/licenses/mit-license.php
|
||||
##
|
||||
################################################################################
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Test::More tests => 4;
|
||||
|
||||
# Create the rc file.
|
||||
if (open my $fh, '>', 'hook.rc')
|
||||
{
|
||||
print $fh "data.location=.\n",
|
||||
"extensions=on\n",
|
||||
"hook.on-launch=" . $ENV{'PWD'} . "/hook:test\n";
|
||||
close $fh;
|
||||
ok (-r 'hook.rc', 'Created hook.rc');
|
||||
}
|
||||
|
||||
if (open my $fh, '>', 'hook')
|
||||
{
|
||||
print $fh "function test () print ('marker') return 0, nil end\n";
|
||||
close $fh;
|
||||
ok (-r 'hook', 'Created hook');
|
||||
}
|
||||
|
||||
my $output = qx{../src/task rc:hook.rc version 2>&1};
|
||||
if ($output =~ /PUC-Rio/)
|
||||
{
|
||||
# Test the hook.
|
||||
$output = qx{../src/task rc:hook.rc _version 2>&1};
|
||||
like ($output, qr/^marker.+\b\w{7}\b/ms, 'Found marker before output');
|
||||
}
|
||||
else
|
||||
{
|
||||
pass ('Found marker before output - skip: no Lua support');
|
||||
}
|
||||
|
||||
# Cleanup.
|
||||
unlink qw(pending.data completed.data undo.data backlog.data hook hook.rc);
|
||||
ok (! -r 'pending.data' &&
|
||||
! -r 'completed.data' &&
|
||||
! -r 'undo.data' &&
|
||||
! -r 'backlog.data' &&
|
||||
! -r 'hook' &&
|
||||
! -r 'hook.rc', 'Cleanup');
|
||||
|
||||
exit 0;
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue