diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2016-10-26 15:20:00 +0200 |
---|---|---|
committer | Justin M. Keyes <justinkz@gmail.com> | 2016-10-28 14:33:13 +0200 |
commit | c5f5f427c6f8d1b4136bf41171f8f0980561080e (patch) | |
tree | 3ee5625e251a64d270c1ef7f761a3725b1e84a44 | |
parent | f25797f86976cbccf697d6df953154c5e59656e6 (diff) | |
download | rneovim-c5f5f427c6f8d1b4136bf41171f8f0980561080e.tar.gz rneovim-c5f5f427c6f8d1b4136bf41171f8f0980561080e.tar.bz2 rneovim-c5f5f427c6f8d1b4136bf41171f8f0980561080e.zip |
api: api_info()['version']
API level is disconnected from NVIM version. The API metadata holds the
current API level, and the lowest backwards-compatible level supported
by this instance.
Release 0.1.6 is the first release that reports the Nvim version and API
level.
metadata['version'] = {
major: 0,
minor: 1,
patch: 6,
api_level: 1,
api_compatible: 0,
api_prerelease: false,
}
The API level may remain unchanged across Nvim releases if the API has
not changed.
When changing the API,
- set NVIM_API_PRERELEASE to true
- increment NVIM_API_LEVEL (at most once per Nvim version)
- adjust NVIM_API_LEVEL_COMPAT if backwards-compatibility was broken
api_level_0.mpack was generated from Nvim 0.1.5 with:
nvim --api-info
-rw-r--r-- | CMakeLists.txt | 9 | ||||
-rw-r--r-- | config/versiondef.h.in | 6 | ||||
-rw-r--r-- | runtime/doc/api.txt | 8 | ||||
-rw-r--r-- | runtime/doc/msgpack_rpc.txt | 5 | ||||
-rw-r--r-- | src/nvim/api/private/helpers.c | 15 | ||||
-rw-r--r-- | src/nvim/version.c | 12 | ||||
-rw-r--r-- | test/functional/api/compatibility_spec.lua | 65 | ||||
-rw-r--r-- | test/functional/api/version_spec.lua | 71 | ||||
-rw-r--r-- | test/functional/eval/api_functions_spec.lua | 2 | ||||
-rw-r--r-- | test/functional/eval/msgpack_functions_spec.lua | 2 | ||||
-rw-r--r-- | test/functional/fixtures/api_level_0.mpack (renamed from test/functional/fixtures/api-info/0.mpack) | bin | 7873 -> 7873 bytes |
11 files changed, 100 insertions, 95 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 3b139025d7..75c0bd0ecd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,16 +59,15 @@ set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Dev" "Release" "MinSizeRel" "RelWithDebInfo") # If not in a git repo (e.g., a tarball) these tokens define the complete -# version string, else it is combined with the result of `git describe`. +# version string, else they are combined with the result of `git describe`. set(NVIM_VERSION_MAJOR 0) set(NVIM_VERSION_MINOR 1) set(NVIM_VERSION_PATCH 6) set(NVIM_VERSION_PRERELEASE "-dev") # for package maintainers -# Neovim API version. When changing the API, bump CURRENT if -# PRERELEASE is false, and set PRERELEASE as true -set(NVIM_API_CURRENT 1) -set(NVIM_API_COMPATIBILITY 0) +# API level +set(NVIM_API_LEVEL 1) # Bump this after any API change. +set(NVIM_API_LEVEL_COMPAT 0) # Adjust this after a _breaking_ API change. set(NVIM_API_PRERELEASE true) file(TO_CMAKE_PATH ${CMAKE_CURRENT_LIST_DIR}/.git FORCED_GIT_DIR) diff --git a/config/versiondef.h.in b/config/versiondef.h.in index 465d90b674..b9565735b3 100644 --- a/config/versiondef.h.in +++ b/config/versiondef.h.in @@ -7,9 +7,9 @@ #define NVIM_VERSION_PRERELEASE "@NVIM_VERSION_PRERELEASE@" #cmakedefine NVIM_VERSION_MEDIUM "@NVIM_VERSION_MEDIUM@" -#define NVIM_API_CURRENT @NVIM_API_CURRENT@ -#define NVIM_API_COMPATIBILITY @NVIM_API_COMPATIBILITY@ -#cmakedefine NVIM_API_PRERELEASE +#define NVIM_API_LEVEL @NVIM_API_LEVEL@ +#define NVIM_API_LEVEL_COMPAT @NVIM_API_LEVEL_COMPAT@ +#define NVIM_API_PRERELEASE @NVIM_API_PRERELEASE@ #define NVIM_VERSION_CFLAGS "@NVIM_VERSION_CFLAGS@" #define NVIM_VERSION_BUILD_TYPE "@NVIM_VERSION_BUILD_TYPE@" diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt index dd48a0c2a5..976b852bdb 100644 --- a/runtime/doc/api.txt +++ b/runtime/doc/api.txt @@ -51,10 +51,10 @@ Tabpage -> enum value kObjectTypeTabpage Nvim exposes metadata about the API as a Dictionary with the following keys: -api_level API version compatibility information -functions calling signature of the API functions -types The custom handle types defined by Nvim -error_types The possible kinds of errors an API function can exit with. +version Nvim version, API level/compatibility +functions API function signatures +types Custom handle types defined by Nvim +error_types Possible error types returned by API functions This metadata is mostly useful for external programs accessing the API via RPC, see |rpc-api|. diff --git a/runtime/doc/msgpack_rpc.txt b/runtime/doc/msgpack_rpc.txt index bfd4100f15..757f5574d4 100644 --- a/runtime/doc/msgpack_rpc.txt +++ b/runtime/doc/msgpack_rpc.txt @@ -168,9 +168,8 @@ API metadata object ~ API clients exist to hide msgpack-rpc details. The API metadata object contains information that makes this task easier (see also |rpc-types|): - - The "api_level" key contais API compatibility information. The "current" - key holds the API version supported Neovim. The "compatibility" key holds - the oldest supported API version. + - The "version" key contains the Nvim version, API level, and API + backwards-compatibility level. - The "functions" key contains a list of metadata objects for individual functions. - Each function metadata object has |rpc-types| information about the return diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index 7fda2802c8..208c3b53c8 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -18,9 +18,9 @@ #include "nvim/map.h" #include "nvim/option.h" #include "nvim/option_defs.h" +#include "nvim/version.h" #include "nvim/eval/typval_encode.h" #include "nvim/lib/kvec.h" -#include "auto/versiondef.h" /// Helper structure for vim_to_object typedef struct { @@ -764,10 +764,10 @@ Dictionary api_metadata(void) static Dictionary metadata = ARRAY_DICT_INIT; if (!metadata.size) { + PUT(metadata, "version", DICTIONARY_OBJ(version_dict())); init_function_metadata(&metadata); init_error_type_metadata(&metadata); init_type_metadata(&metadata); - init_api_level_metadata(&metadata); } return copy_object(DICTIONARY_OBJ(metadata)).data.dictionary; @@ -827,17 +827,6 @@ static void init_type_metadata(Dictionary *metadata) PUT(*metadata, "types", DICTIONARY_OBJ(types)); } -static void init_api_level_metadata(Dictionary *metadata) -{ - Dictionary version = ARRAY_DICT_INIT; - PUT(version, "current", INTEGER_OBJ(NVIM_API_CURRENT)); - PUT(version, "compatibility", INTEGER_OBJ(NVIM_API_COMPATIBILITY)); -#ifdef NVIM_API_PRERELEASE - PUT(version, "prerelease", BOOLEAN_OBJ(true)); -#endif - - PUT(*metadata, "api_level", DICTIONARY_OBJ(version)); -} /// Creates a deep clone of an object Object copy_object(Object obj) diff --git a/src/nvim/version.c b/src/nvim/version.c index 498afa9656..7ab8c84569 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -7,6 +7,7 @@ #include <assert.h> #include <limits.h> +#include "nvim/api/private/helpers.h" #include "nvim/vim.h" #include "nvim/ascii.h" #include "nvim/iconv.h" @@ -2514,6 +2515,17 @@ bool has_vim_patch(int n) return false; } +Dictionary version_dict(void) { + Dictionary d = ARRAY_DICT_INIT; + PUT(d, "major", INTEGER_OBJ(NVIM_VERSION_MAJOR)); + PUT(d, "minor", INTEGER_OBJ(NVIM_VERSION_MINOR)); + PUT(d, "patch", INTEGER_OBJ(NVIM_VERSION_PATCH)); + PUT(d, "api_level", INTEGER_OBJ(NVIM_API_LEVEL)); + PUT(d, "api_compatible", INTEGER_OBJ(NVIM_API_LEVEL_COMPAT)); + PUT(d, "api_prerelease", BOOLEAN_OBJ(NVIM_API_PRERELEASE)); + return d; +} + void ex_version(exarg_T *eap) { // Ignore a ":version 9.99" command. diff --git a/test/functional/api/compatibility_spec.lua b/test/functional/api/compatibility_spec.lua deleted file mode 100644 index e0fc625b46..0000000000 --- a/test/functional/api/compatibility_spec.lua +++ /dev/null @@ -1,65 +0,0 @@ - -local helpers = require('test.functional.helpers')(after_each) -local lfs = require('lfs') -local mpack = require('mpack') -local clear, eq, neq = helpers.clear, helpers.eq, helpers.neq - -local read_mpack_file = function(fname) - local fd = io.open(fname, 'rb') - local data = fd:read('*a') - fd:close() - local unpack = mpack.Unpacker() - return unpack(data) -end - --- ignore metadata in API function spec -local remove_function_metadata = function(fspec) - fspec['can_fail'] = nil - fspec['async'] = nil - fspec['method'] = nil - fspec['since'] = nil - fspec['deprecated_since'] = nil - fspec['receives_channel_id'] = nil - for idx,_ in ipairs(fspec['parameters']) do - fspec['parameters'][idx][2] = '' - end -end - -clear() -local api_level = helpers.call('api_info')['api_level'] - -describe('api compatibility', function() - before_each(clear) - - it("version metadata is sane", function() - local info = helpers.call('api_info') - local current = info['api_level']['current'] - local compatibility = info['api_level']['compatibility'] - neq(current, nil) - neq(compatibility, nil) - assert(current >= compatibility) - end) - - for ver = api_level['compatibility'], api_level['current'] do - local path = 'test/functional/fixtures/api-info/' .. tostring(ver) .. '.mpack' - it('are backwards compatible with api level '..ver, function() - if lfs.attributes(path,"mode") ~= "file" then - pending("No fixture found, skipping test") - return - end - - local old_api = read_mpack_file(path) - local api = helpers.call('api_info') - - for _, fspec in ipairs(old_api['functions']) do - remove_function_metadata(fspec) - for _, fspec_new in ipairs(api['functions']) do - if fspec['name'] == fspec_new['name'] then - remove_function_metadata(fspec_new) - eq(fspec, fspec_new) - end - end - end - end) - end -end) diff --git a/test/functional/api/version_spec.lua b/test/functional/api/version_spec.lua new file mode 100644 index 0000000000..3efd00ddbe --- /dev/null +++ b/test/functional/api/version_spec.lua @@ -0,0 +1,71 @@ +local helpers = require('test.functional.helpers')(after_each) +local mpack = require('mpack') +local clear, funcs, eq = helpers.clear, helpers.funcs, helpers.eq + +local function read_mpack_file(fname) + local fd = io.open(fname, 'rb') + local data = fd:read('*a') + fd:close() + local unpack = mpack.Unpacker() + return unpack(data) +end + +-- Remove metadata that is not essential to backwards-compatibility. +local function remove_function_metadata(fspec) + fspec['can_fail'] = nil + fspec['async'] = nil + fspec['method'] = nil + fspec['since'] = nil + fspec['deprecated_since'] = nil + fspec['receives_channel_id'] = nil + for idx, _ in ipairs(fspec['parameters']) do + fspec['parameters'][idx][2] = '' -- Remove parameter name. + end + return fspec +end + +describe("api_info()['version']", function() + before_each(clear) + + it("returns API level", function() + local version = helpers.call('api_info')['version'] + local current = version['api_level'] + local compat = version['api_compatible'] + eq("number", type(current)) + eq("number", type(compat)) + assert(current >= compat) + end) + + it("returns Nvim version", function() + local version = helpers.call('api_info')['version'] + local major = version['major'] + local minor = version['minor'] + local patch = version['patch'] + eq("number", type(major)) + eq("number", type(minor)) + eq("number", type(patch)) + eq(1, funcs.has("nvim-"..major.."."..minor.."."..patch)) + eq(0, funcs.has("nvim-"..major.."."..minor.."."..(patch + 1))) + eq(0, funcs.has("nvim-"..major.."."..(minor + 1).."."..patch)) + eq(0, funcs.has("nvim-"..(major + 1).."."..minor.."."..patch)) + end) + + it("api_compatible level is valid", function() + local api = helpers.call('api_info') + local compat = api['version']['api_compatible'] + local path = 'test/functional/fixtures/api_level_' + ..tostring(compat)..'.mpack' + + -- Verify that the current API function signatures match those of the API + -- level for which we claim compatibility. + local old_api = read_mpack_file(path) + for _, fn_old in ipairs(old_api['functions']) do + for _, fn_new in ipairs(api['functions']) do + if fn_old['name'] == fn_new['name'] then + eq(remove_function_metadata(fn_old), + remove_function_metadata(fn_new)) + end + end + end + end) +end) diff --git a/test/functional/eval/api_functions_spec.lua b/test/functional/eval/api_functions_spec.lua index 5345c9782d..21dd228145 100644 --- a/test/functional/eval/api_functions_spec.lua +++ b/test/functional/eval/api_functions_spec.lua @@ -106,7 +106,7 @@ describe('api functions', function() it('have metadata accessible with api_info()', function() local api_keys = eval("sort(keys(api_info()))") - eq({'api_level', 'error_types', 'functions', 'types'}, api_keys) + eq({'error_types', 'functions', 'types', 'version'}, api_keys) end) it('are highlighted by vim.vim syntax file', function() diff --git a/test/functional/eval/msgpack_functions_spec.lua b/test/functional/eval/msgpack_functions_spec.lua index ae7e1b5609..f11c08de05 100644 --- a/test/functional/eval/msgpack_functions_spec.lua +++ b/test/functional/eval/msgpack_functions_spec.lua @@ -460,7 +460,7 @@ describe('msgpackparse() function', function() eval(cmd) eval(cmd) -- do it again (try to force segfault) local api_info = eval(cmd) -- do it again - eq({'api_level', 'error_types', 'functions', 'types'}, api_info) + eq({'error_types', 'functions', 'types', 'version'}, api_info) end) it('fails when called with no arguments', function() diff --git a/test/functional/fixtures/api-info/0.mpack b/test/functional/fixtures/api_level_0.mpack Binary files differindex 75b236a3c1..75b236a3c1 100644 --- a/test/functional/fixtures/api-info/0.mpack +++ b/test/functional/fixtures/api_level_0.mpack |