init: Add an API level concept to `capi`.

The API level concept is something used by other projects such as
Android and iOS to allow deprecated features to be removed and the
bahavior to be altered without breaking compability with existing
code.

The same will apply to AwesomeWM. The current API level is "4" and
as long as config use this, no deprecation or bahavior change will
be exposed. If the user sets it to an higher value or we release
the next major version and new users start to use the, then current,
default config, they will use the new API level.

The the far future, if ever, we could fork the entire Lua libraries
to support legacy APIs. This would only require to keep the core
API support for those legacy calls. In the meantime, `gears.debug`
will use this to manage the deprecation and some conditional code
will be added as a last resort attempt to preserve behavior
compatibility while moving forward with breaking changes.
This commit is contained in:
Emmanuel Lepage Vallee 2020-02-02 18:57:26 -05:00
parent d2f8999595
commit ee80fe052f
9 changed files with 106 additions and 24 deletions

View File

@ -3,6 +3,7 @@
#define AWESOME_VERSION "@AWESOME_VERSION@"
#define AWESOME_RELEASE "@AWESOME_RELEASE@"
#define AWESOME_API_LEVEL @AWESOME_API_LEVEL@
#endif //_AWE_VERSION_INTERNAL_H_

View File

@ -580,6 +580,7 @@ main(int argc, char **argv)
globalconf.keygrabber = LUA_REFNIL;
globalconf.mousegrabber = LUA_REFNIL;
globalconf.exit_code = EXIT_SUCCESS;
globalconf.api_level = awesome_default_api_level();
buffer_init(&globalconf.startup_errors);
string_array_init(&searchpath);

View File

@ -271,6 +271,7 @@ else()
set(AWESOME_MAN_PATH ${CMAKE_INSTALL_PREFIX}/share/man CACHE PATH "awesome manpage directory")
endif()
# Hide to avoid confusion
mark_as_advanced(CMAKE_INSTALL_CMAKE_INSTALL_PREFIX)
@ -280,6 +281,7 @@ set(AWESOME_SYSCONFDIR ${XDG_CONFIG_DIR}/${PROJECT_AWE_NAME})
set(AWESOME_LUA_LIB_PATH ${AWESOME_DATA_PATH}/lib)
set(AWESOME_ICON_PATH ${AWESOME_DATA_PATH}/icons)
set(AWESOME_THEMES_PATH ${AWESOME_DATA_PATH}/themes)
set(AWESOME_API_LEVEL 4)
# }}}
if(GENERATE_DOC)

View File

@ -100,4 +100,11 @@ awesome_release_string(void)
return AWESOME_RELEASE;
}
int
awesome_default_api_level(void)
{
return AWESOME_API_LEVEL;
}
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80

View File

@ -25,6 +25,7 @@
void eprint_version(void) __attribute__ ((noreturn));
const char *awesome_version_string(void);
const char *awesome_release_string(void);
int awesome_default_api_level(void);
#endif

View File

@ -224,6 +224,8 @@ typedef struct
xcb_generic_event_t *pending_event;
/** The exit code that main() will return with */
int exit_code;
/** The Global API level */
int api_level;
} awesome_t;
extern awesome_t globalconf;

37
luaa.c
View File

@ -540,15 +540,42 @@ static int luaA_get_active_modifiers(lua_State *L)
}
/**
* The version of awesome.
* The AwesomeWM version.
* @tfield string version
*/
/**
* The release name of awesome.
* The AwesomeWM release name.
* @tfield string release
*/
/**
* The AwesomeWM API level.
*
* By default, this matches the major version (first component of the version).
*
* API levels are used to allow newer version of AwesomeWM to alter the behavior
* and subset deprecated APIs. Using an older API level than the current major
* version allows to use legacy `rc.lua` with little porting. However, they wont
* be able to use all the new features. Attempting to use a newer feature along
* with an older API level is not and will not be supported, even if it almost
* works. Keeping up to date with the newer API levels is highly recommended.
*
* Going the other direction, setting an higher API level allows to take
* advantage of experimental feature. It will also be much harsher when it comes
* to deprecation. Setting the API level value beyond `current+3` will treat
* using APIs currently pending deprecation as fatal errors. All new code
* submitted to the upstream AwesomeWM codebase is forbidden to use deprecated
* APIs. Testing your patches with mode and the default config is recommended
* before submitting a patch.
*
* You can use the `-l` command line option or `api-level` modeline key to set
* the API level for your `rc.lua`. This setting is global and read only,
* individual modules cannot set their own API level.
*
* @tfield string api_level
*/
/**
* The configuration file which has been loaded.
* @tfield string conffile
@ -616,6 +643,12 @@ luaA_awesome_index(lua_State *L)
return 1;
}
if(A_STREQ(buf, "api_level"))
{
lua_pushinteger(L, globalconf.api_level);
return 1;
}
if(A_STREQ(buf, "startup"))
{
lua_pushboolean(L, globalconf.loop == NULL);

View File

@ -24,12 +24,41 @@
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <getopt.h>
#define KEY_VALUE_BUF_MAX 64
#define READ_BUF_MAX 127
static void
set_api_level(char *value)
{
if (!value)
return;
char *ptr;
int ret = strtol(value, &ptr, 10);
/* There is no valid number at all */
if (value == ptr) {
fprintf(stderr, "Invalid API level %s\n", value);
return;
}
/* There is a number, but also letters, this is invalid */
if (ptr[0] != '\0' && ptr[0] != '.') {
fprintf(stderr, "Invalid API level %s\n", value);
return;
}
/* This API level doesn't exist, fallback to v4 */
if (ret < 4)
ret = 4;
globalconf.api_level = ret;
}
static void
push_arg(string_array_t *args, char *value, size_t *len)
{
@ -327,15 +356,16 @@ exit_help(int exit_code)
FILE *outfile = (exit_code == EXIT_SUCCESS) ? stdout : stderr;
fprintf(outfile,
"Usage: awesome [OPTION]\n\
-h, --help show help\n\
-v, --version show version\n\
-f, --force ignore modelines and apply the command line arguments\n\
-c, --config FILE configuration file to use\n\
--search DIR add a directory to the library search path\n\
-k, --check check configuration file syntax\n\
-a, --no-argb disable client transparency support\n\
-m, --screen on|off enable or disable automatic screen creation (default: on)\n\
-r, --replace replace an existing window manager\n");
-h, --help show help\n\
-v, --version show version\n\
-c, --config FILE configuration file to use\n\
-f, --force ignore modelines and apply the command line arguments\n\
--search DIR add a directory to the library search path\n\
-k, --check check configuration file syntax\n\
-a, --no-argb disable client transparency support\n\
-l --api-level LEVEL select a different API support level than the current version \n\
-m, --screen on|off enable or disable automatic screen creation (default: on)\n\
-r, --replace replace an existing window manager\n");
exit(exit_code);
}
@ -348,23 +378,24 @@ options_check_args(int argc, char **argv, int *init_flags, string_array_t *paths
static struct option long_options[] =
{
{ "help", NO_ARG, NULL, 'h' },
{ "version", NO_ARG, NULL, 'v' },
{ "config", ARG , NULL, 'c' },
{ "force" , NO_ARG, NULL, 'f' },
{ "check", NO_ARG, NULL, 'k' },
{ "search", ARG , NULL, 's' },
{ "no-argb", NO_ARG, NULL, 'a' },
{ "replace", NO_ARG, NULL, 'r' },
{ "screen" , ARG , NULL, 'm' },
{ "reap", ARG , NULL, '\1' },
{ NULL, NO_ARG, NULL, 0 }
{ "help" , NO_ARG, NULL, 'h' },
{ "version" , NO_ARG, NULL, 'v' },
{ "config" , ARG , NULL, 'c' },
{ "force" , NO_ARG, NULL, 'f' },
{ "check" , NO_ARG, NULL, 'k' },
{ "search" , ARG , NULL, 's' },
{ "no-argb" , NO_ARG, NULL, 'a' },
{ "replace" , NO_ARG, NULL, 'r' },
{ "screen" , ARG , NULL, 'm' },
{ "api-level" , ARG , NULL, 'l' },
{ "reap" , ARG , NULL, '\1' },
{ NULL , NO_ARG, NULL, 0 }
};
char *confpath = NULL;
int opt;
while((opt = getopt_long(argc, argv, "vhkc:arm:",
while((opt = getopt_long(argc, argv, "vhkc:arml:",
long_options, NULL)) != -1) {
switch(opt)
{
@ -405,6 +436,9 @@ options_check_args(int argc, char **argv, int *init_flags, string_array_t *paths
case 'r':
(*init_flags) |= INIT_FLAG_REPLACE_WM;
break;
case 'l':
set_api_level(optarg);
break;
case '\1':
/* Silently ignore --reap and its argument */
break;

View File

@ -83,7 +83,8 @@ function awesome.xrdb_get_value()
end
-- Always show deprecated messages
awesome.version = "v9999"
awesome.version = "v9999"
awesome.api_level = 9999
-- SVG are composited. Without it we need a root surface
awesome.composite_manager_running = true