Merge #5535 from justinmk/api_level

api: Nvim version + API level
This commit is contained in:
Justin M. Keyes 2016-10-28 14:53:09 +02:00 committed by GitHub
commit 5b514b5988
11 changed files with 105 additions and 7 deletions

View File

@ -59,12 +59,17 @@ set_property(CACHE CMAKE_BUILD_TYPE PROPERTY
STRINGS "Debug" "Dev" "Release" "MinSizeRel" "RelWithDebInfo") STRINGS "Debug" "Dev" "Release" "MinSizeRel" "RelWithDebInfo")
# If not in a git repo (e.g., a tarball) these tokens define the complete # 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_MAJOR 0)
set(NVIM_VERSION_MINOR 1) set(NVIM_VERSION_MINOR 1)
set(NVIM_VERSION_PATCH 6) set(NVIM_VERSION_PATCH 6)
set(NVIM_VERSION_PRERELEASE "-dev") # for package maintainers set(NVIM_VERSION_PRERELEASE "-dev") # for package maintainers
# 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) file(TO_CMAKE_PATH ${CMAKE_CURRENT_LIST_DIR}/.git FORCED_GIT_DIR)
include(GetGitRevisionDescription) include(GetGitRevisionDescription)
get_git_head_revision(GIT_REFSPEC NVIM_VERSION_COMMIT) get_git_head_revision(GIT_REFSPEC NVIM_VERSION_COMMIT)

View File

@ -7,6 +7,10 @@
#define NVIM_VERSION_PRERELEASE "@NVIM_VERSION_PRERELEASE@" #define NVIM_VERSION_PRERELEASE "@NVIM_VERSION_PRERELEASE@"
#cmakedefine NVIM_VERSION_MEDIUM "@NVIM_VERSION_MEDIUM@" #cmakedefine NVIM_VERSION_MEDIUM "@NVIM_VERSION_MEDIUM@"
#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_CFLAGS "@NVIM_VERSION_CFLAGS@"
#define NVIM_VERSION_BUILD_TYPE "@NVIM_VERSION_BUILD_TYPE@" #define NVIM_VERSION_BUILD_TYPE "@NVIM_VERSION_BUILD_TYPE@"

View File

@ -51,9 +51,10 @@ Tabpage -> enum value kObjectTypeTabpage
Nvim exposes metadata about the API as a Dictionary with the following keys: Nvim exposes metadata about the API as a Dictionary with the following keys:
functions calling signature of the API functions version Nvim version, API level/compatibility
types The custom handle types defined by Nvim functions API function signatures
error_types The possible kinds of errors an API function can exit with. 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 This metadata is mostly useful for external programs accessing the API via
RPC, see |rpc-api|. RPC, see |rpc-api|.

View File

@ -168,6 +168,8 @@ API metadata object ~
API clients exist to hide msgpack-rpc details. The 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|): contains information that makes this task easier (see also |rpc-types|):
- 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 - The "functions" key contains a list of metadata objects for individual
functions. functions.
- Each function metadata object has |rpc-types| information about the return - Each function metadata object has |rpc-types| information about the return

View File

@ -5,6 +5,7 @@
# Steps: # Steps:
# Create the "release" commit: # Create the "release" commit:
# - CMakeLists.txt: Unset NVIM_VERSION_PRERELEASE # - CMakeLists.txt: Unset NVIM_VERSION_PRERELEASE
# - CMakeLists.txt: Unset NVIM_API_PRERELEASE
# - Tag the commit. # - Tag the commit.
# Create the "version bump" commit: # Create the "version bump" commit:
# - CMakeLists.txt: Set NVIM_VERSION_PRERELEASE to "-dev" # - CMakeLists.txt: Set NVIM_VERSION_PRERELEASE to "-dev"
@ -46,6 +47,7 @@ __BUMP_MSG="version bump"
echo "Most recent tag: ${__LAST_TAG}" echo "Most recent tag: ${__LAST_TAG}"
echo "Release version: ${__VERSION}" echo "Release version: ${__VERSION}"
$__sed -i.bk 's/(NVIM_VERSION_PRERELEASE) "-dev"/\1 ""/' CMakeLists.txt $__sed -i.bk 's/(NVIM_VERSION_PRERELEASE) "-dev"/\1 ""/' CMakeLists.txt
$__sed -i.bk 's/(NVIM_API_PRERELEASE) true/\1 false/' CMakeLists.txt
echo "Building changelog since ${__LAST_TAG}..." echo "Building changelog since ${__LAST_TAG}..."
__CHANGELOG="$(./scripts/git-log-pretty-since.sh "$__LAST_TAG" 'vim-patch:\S')" __CHANGELOG="$(./scripts/git-log-pretty-since.sh "$__LAST_TAG" 'vim-patch:\S')"

View File

@ -18,6 +18,7 @@
#include "nvim/map.h" #include "nvim/map.h"
#include "nvim/option.h" #include "nvim/option.h"
#include "nvim/option_defs.h" #include "nvim/option_defs.h"
#include "nvim/version.h"
#include "nvim/eval/typval_encode.h" #include "nvim/eval/typval_encode.h"
#include "nvim/lib/kvec.h" #include "nvim/lib/kvec.h"
@ -763,6 +764,7 @@ Dictionary api_metadata(void)
static Dictionary metadata = ARRAY_DICT_INIT; static Dictionary metadata = ARRAY_DICT_INIT;
if (!metadata.size) { if (!metadata.size) {
PUT(metadata, "version", DICTIONARY_OBJ(version_dict()));
init_function_metadata(&metadata); init_function_metadata(&metadata);
init_error_type_metadata(&metadata); init_error_type_metadata(&metadata);
init_type_metadata(&metadata); init_type_metadata(&metadata);

View File

@ -7,6 +7,7 @@
#include <assert.h> #include <assert.h>
#include <limits.h> #include <limits.h>
#include "nvim/api/private/helpers.h"
#include "nvim/vim.h" #include "nvim/vim.h"
#include "nvim/ascii.h" #include "nvim/ascii.h"
#include "nvim/iconv.h" #include "nvim/iconv.h"
@ -2514,6 +2515,17 @@ bool has_vim_patch(int n)
return false; 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) void ex_version(exarg_T *eap)
{ {
// Ignore a ":version 9.99" command. // Ignore a ":version 9.99" command.

View File

@ -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)

View File

@ -106,7 +106,7 @@ describe('api functions', function()
it('have metadata accessible with api_info()', function() it('have metadata accessible with api_info()', function()
local api_keys = eval("sort(keys(api_info()))") local api_keys = eval("sort(keys(api_info()))")
eq({'error_types', 'functions', 'types'}, api_keys) eq({'error_types', 'functions', 'types', 'version'}, api_keys)
end) end)
it('are highlighted by vim.vim syntax file', function() it('are highlighted by vim.vim syntax file', function()
@ -144,5 +144,4 @@ describe('api functions', function()
]]) ]])
screen:detach() screen:detach()
end) end)
end) end)

View File

@ -460,7 +460,7 @@ describe('msgpackparse() function', function()
eval(cmd) eval(cmd)
eval(cmd) -- do it again (try to force segfault) eval(cmd) -- do it again (try to force segfault)
local api_info = eval(cmd) -- do it again local api_info = eval(cmd) -- do it again
eq({'error_types', 'functions', 'types'}, api_info) eq({'error_types', 'functions', 'types', 'version'}, api_info)
end) end)
it('fails when called with no arguments', function() it('fails when called with no arguments', function()

Binary file not shown.