mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-03-30 05:46:55 +00:00
API: add a schema for plugin config files
Also flip the dependence between json_schema_validator and kicommon, and create a shared JSON_SCHEMA_VALIDATOR so that we don't have to copy/paste the schema loading code as much
This commit is contained in:
parent
6be3401b92
commit
3f7e459d62
api
common
include
kicad/pcm
thirdparty/json_schema_validator
@ -132,3 +132,19 @@ if( APPLE )
|
||||
"@executable_path/../Frameworks" )
|
||||
set_target_properties( kiapi PROPERTIES BUILD_WITH_INSTALL_RPATH 1 )
|
||||
endif()
|
||||
|
||||
if( NOT (${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR} ) )
|
||||
file( GLOB SCHEMA_FILES ${CMAKE_CURRENT_SOURCE_DIR}/schemas/*.json )
|
||||
|
||||
add_custom_target( api_schema_build_copy ALL
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/schemas ${CMAKE_BINARY_DIR}/schemas
|
||||
DEPENDS ${SCHEMA_FILES}
|
||||
COMMENT "Copying API schema files into build directory"
|
||||
)
|
||||
endif()
|
||||
|
||||
INSTALL( DIRECTORY
|
||||
schemas
|
||||
DESTINATION ${KICAD_DATA}
|
||||
COMPONENT Runtime
|
||||
)
|
||||
|
108
api/schemas/api.v1.schema.json
Normal file
108
api/schemas/api.v1.schema.json
Normal file
@ -0,0 +1,108 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"$id": "https://go.kicad.org/api/schemas/v1",
|
||||
"title": "KiCad API Plugin Schema",
|
||||
"description": "KiCad IPC API Plugin and Action schema",
|
||||
"$ref": "#/definitions/Plugin",
|
||||
"definitions": {
|
||||
"Plugin": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"identifier": {
|
||||
"type": "string",
|
||||
"description": "Plugin identifier",
|
||||
"pattern": "^[a-zA-Z][-_a-zA-Z0-9.]{0,98}[a-zA-Z0-9]$"
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"maxLength": 200
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"maxLength": 500
|
||||
},
|
||||
"runtime": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"python",
|
||||
"exec"
|
||||
],
|
||||
"description": "How KiCad should launch the plugin"
|
||||
},
|
||||
"min_version": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
]
|
||||
},
|
||||
"actions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"identifier": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"show-button": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"scopes": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"pcb",
|
||||
"schematic",
|
||||
"footprint",
|
||||
"symbol",
|
||||
"project_manager"
|
||||
]
|
||||
}
|
||||
},
|
||||
"entrypoint": {
|
||||
"type": "string"
|
||||
},
|
||||
"icons-light": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"icons-dark": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"identifier",
|
||||
"name",
|
||||
"description",
|
||||
"show-button",
|
||||
"entrypoint"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"identifier",
|
||||
"name",
|
||||
"description",
|
||||
"runtime",
|
||||
"actions"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
@ -161,6 +161,7 @@ set( KICOMMON_SRCS
|
||||
gestfich.cpp
|
||||
increment.cpp
|
||||
json_conversions.cpp
|
||||
json_schema_validator.cpp
|
||||
kidialog.cpp
|
||||
kiid.cpp
|
||||
kiway.cpp
|
||||
@ -226,6 +227,7 @@ target_link_libraries( kicommon
|
||||
kimath
|
||||
kiplatform
|
||||
nlohmann_json
|
||||
nlohmann_json_schema_validator
|
||||
fmt::fmt
|
||||
CURL::libcurl
|
||||
picosha2
|
||||
@ -304,6 +306,7 @@ target_include_directories( kicommon
|
||||
$<TARGET_PROPERTY:expected,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
$<TARGET_PROPERTY:kiapi,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
$<TARGET_PROPERTY:picosha2,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
$<TARGET_PROPERTY:nlohmann_json_schema_validator,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
)
|
||||
|
||||
add_dependencies( kicommon pegtl version_header )
|
||||
|
@ -29,6 +29,28 @@
|
||||
#include <api/api_plugin_manager.h>
|
||||
#include <api/api_utils.h>
|
||||
#include <json_conversions.h>
|
||||
#include <json_schema_validator.h>
|
||||
|
||||
|
||||
class LOGGING_ERROR_HANDLER : public nlohmann::json_schema::error_handler
|
||||
{
|
||||
public:
|
||||
LOGGING_ERROR_HANDLER() : m_hasError( false ) {}
|
||||
|
||||
bool HasError() const { return m_hasError; }
|
||||
|
||||
void error( const nlohmann::json::json_pointer& ptr, const nlohmann::json& instance,
|
||||
const std::string& message ) override
|
||||
{
|
||||
m_hasError = true;
|
||||
wxLogTrace( traceApi,
|
||||
wxString::Format( wxS( "JSON error: at %s, value:\n%s\n%s" ),
|
||||
ptr.to_string(), instance.dump(), message ) );
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_hasError;
|
||||
};
|
||||
|
||||
|
||||
bool PLUGIN_RUNTIME::FromJson( const nlohmann::json& aJson )
|
||||
@ -54,7 +76,8 @@ bool PLUGIN_RUNTIME::FromJson( const nlohmann::json& aJson )
|
||||
|
||||
struct API_PLUGIN_CONFIG
|
||||
{
|
||||
API_PLUGIN_CONFIG( API_PLUGIN& aParent, const wxFileName& aConfigFile );
|
||||
API_PLUGIN_CONFIG( API_PLUGIN& aParent, const wxFileName& aConfigFile,
|
||||
const JSON_SCHEMA_VALIDATOR& aValidator );
|
||||
|
||||
bool valid;
|
||||
wxString identifier;
|
||||
@ -67,7 +90,8 @@ struct API_PLUGIN_CONFIG
|
||||
};
|
||||
|
||||
|
||||
API_PLUGIN_CONFIG::API_PLUGIN_CONFIG( API_PLUGIN& aParent, const wxFileName& aConfigFile ) :
|
||||
API_PLUGIN_CONFIG::API_PLUGIN_CONFIG( API_PLUGIN& aParent, const wxFileName& aConfigFile,
|
||||
const JSON_SCHEMA_VALIDATOR& aValidator ) :
|
||||
parent( aParent )
|
||||
{
|
||||
valid = false;
|
||||
@ -94,7 +118,11 @@ API_PLUGIN_CONFIG::API_PLUGIN_CONFIG( API_PLUGIN& aParent, const wxFileName& aCo
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO add schema and validate
|
||||
LOGGING_ERROR_HANDLER handler;
|
||||
aValidator.Validate( js, handler, nlohmann::json_uri( "#/definitions/Plugin" ) );
|
||||
|
||||
if( !handler.HasError() )
|
||||
wxLogTrace( traceApi, "Plugin: schema validation successful" );
|
||||
|
||||
// All of these are required; any exceptions here leave us with valid == false
|
||||
try
|
||||
@ -151,9 +179,9 @@ API_PLUGIN_CONFIG::API_PLUGIN_CONFIG( API_PLUGIN& aParent, const wxFileName& aCo
|
||||
}
|
||||
|
||||
|
||||
API_PLUGIN::API_PLUGIN( const wxFileName& aConfigFile ) :
|
||||
API_PLUGIN::API_PLUGIN( const wxFileName& aConfigFile, const JSON_SCHEMA_VALIDATOR& aValidator ) :
|
||||
m_configFile( aConfigFile ),
|
||||
m_config( std::make_unique<API_PLUGIN_CONFIG>( *this, aConfigFile ) )
|
||||
m_config( std::make_unique<API_PLUGIN_CONFIG>( *this, aConfigFile, aValidator ) )
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,8 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include <env_vars.h>
|
||||
#include <fmt/format.h>
|
||||
#include <wx/dir.h>
|
||||
@ -42,6 +44,13 @@ API_PLUGIN_MANAGER::API_PLUGIN_MANAGER( wxEvtHandler* aEvtHandler ) :
|
||||
wxEvtHandler(),
|
||||
m_parent( aEvtHandler )
|
||||
{
|
||||
// Read and store pcm schema
|
||||
wxFileName schemaFile( PATHS::GetStockDataPath( true ), wxS( "api.v1.schema.json" ) );
|
||||
schemaFile.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS );
|
||||
schemaFile.AppendDir( wxS( "schemas" ) );
|
||||
|
||||
m_schema_validator = std::make_unique<JSON_SCHEMA_VALIDATOR>( schemaFile );
|
||||
|
||||
Bind( EDA_EVT_PLUGIN_MANAGER_JOB_FINISHED, &API_PLUGIN_MANAGER::processNextJob, this );
|
||||
}
|
||||
|
||||
@ -90,7 +99,7 @@ void API_PLUGIN_MANAGER::ReloadPlugins()
|
||||
wxLogTrace( traceApi, wxString::Format( "Manager: loading plugin from %s",
|
||||
aFile.GetFullPath() ) );
|
||||
|
||||
auto plugin = std::make_unique<API_PLUGIN>( aFile );
|
||||
auto plugin = std::make_unique<API_PLUGIN>( aFile, *m_schema_validator );
|
||||
|
||||
if( plugin->IsOk() )
|
||||
{
|
||||
|
64
common/json_schema_validator.cpp
Normal file
64
common/json_schema_validator.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <fstream>
|
||||
#include <wx/filename.h>
|
||||
#include <wx/log.h>
|
||||
|
||||
#include <json_schema_validator.h>
|
||||
#include <locale_io.h>
|
||||
|
||||
|
||||
JSON_SCHEMA_VALIDATOR::JSON_SCHEMA_VALIDATOR( const wxFileName& aSchemaFile )
|
||||
{
|
||||
std::ifstream schema_stream( aSchemaFile.GetFullPath().fn_str() );
|
||||
nlohmann::json schema;
|
||||
|
||||
try
|
||||
{
|
||||
// For some obscure reason on MINGW, using UCRT option,
|
||||
// m_schema_validator.set_root_schema() hangs without switching to locale "C"
|
||||
#if defined(__MINGW32__) && defined(_UCRT)
|
||||
LOCALE_IO dummy;
|
||||
#endif
|
||||
|
||||
schema_stream >> schema;
|
||||
m_validator.set_root_schema( schema );
|
||||
}
|
||||
catch( std::exception& e )
|
||||
{
|
||||
if( !aSchemaFile.FileExists() )
|
||||
{
|
||||
wxLogError( wxString::Format( _( "schema file '%s' not found" ),
|
||||
aSchemaFile.GetFullPath() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogError( wxString::Format( _( "Error loading schema: %s" ), e.what() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nlohmann::json JSON_SCHEMA_VALIDATOR::Validate( const nlohmann::json& aJson,
|
||||
nlohmann::json_schema::error_handler& aErrorHandler,
|
||||
const nlohmann::json_uri& aInitialUri ) const
|
||||
{
|
||||
return m_validator.validate( aJson, aErrorHandler, aInitialUri );
|
||||
}
|
@ -34,6 +34,7 @@
|
||||
|
||||
struct API_PLUGIN_CONFIG;
|
||||
class API_PLUGIN;
|
||||
class JSON_SCHEMA_VALIDATOR;
|
||||
|
||||
|
||||
struct PLUGIN_DEPENDENCY
|
||||
@ -104,7 +105,7 @@ struct PLUGIN_ACTION
|
||||
class KICOMMON_API API_PLUGIN
|
||||
{
|
||||
public:
|
||||
API_PLUGIN( const wxFileName& aConfigFile );
|
||||
API_PLUGIN( const wxFileName& aConfigFile, const JSON_SCHEMA_VALIDATOR& aValidator );
|
||||
|
||||
~API_PLUGIN();
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <wx/event.h>
|
||||
|
||||
#include <api/api_plugin.h>
|
||||
#include <json_schema_validator.h>
|
||||
#include <kicommon.h>
|
||||
|
||||
/// Internal event used for handling async tasks
|
||||
@ -98,4 +99,6 @@ private:
|
||||
};
|
||||
|
||||
std::deque<JOB> m_jobs;
|
||||
|
||||
std::unique_ptr<JSON_SCHEMA_VALIDATOR> m_schema_validator;
|
||||
};
|
||||
|
43
include/json_schema_validator.h
Normal file
43
include/json_schema_validator.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef JSON_SCHEMA_VALIDATOR_H
|
||||
#define JSON_SCHEMA_VALIDATOR_H
|
||||
|
||||
#include <wx/filename.h>
|
||||
#include <kicommon.h>
|
||||
#include <json_common.h>
|
||||
#include <nlohmann/json-schema.hpp>
|
||||
|
||||
class KICOMMON_API JSON_SCHEMA_VALIDATOR
|
||||
{
|
||||
public:
|
||||
JSON_SCHEMA_VALIDATOR( const wxFileName& aSchemaFile );
|
||||
|
||||
~JSON_SCHEMA_VALIDATOR() = default;
|
||||
|
||||
nlohmann::json Validate( const nlohmann::json& aJson,
|
||||
nlohmann::json_schema::error_handler& aErrorHandler,
|
||||
const nlohmann::json_uri& aInitialUri = nlohmann::json_uri("#") ) const;
|
||||
|
||||
private:
|
||||
nlohmann::json_schema::json_validator m_validator;
|
||||
};
|
||||
|
||||
#endif //JSON_SCHEMA_VALIDATOR_H
|
@ -40,7 +40,6 @@ target_link_libraries( pcm
|
||||
${wxWidgets_LIBRARIES}
|
||||
common
|
||||
picosha2
|
||||
nlohmann_json_schema_validator
|
||||
)
|
||||
|
||||
# Copy the schema to the build directory when building outside the source tree
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "core/wx_stl_compat.h"
|
||||
#include <env_vars.h>
|
||||
#include <background_jobs_monitor.h>
|
||||
#include <json_schema_validator.h>
|
||||
#include "build_version.h"
|
||||
#include "paths.h"
|
||||
#include "pcm.h"
|
||||
@ -81,32 +82,7 @@ PLUGIN_CONTENT_MANAGER::PLUGIN_CONTENT_MANAGER(
|
||||
schema_file.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS );
|
||||
schema_file.AppendDir( wxS( "schemas" ) );
|
||||
|
||||
std::ifstream schema_stream( schema_file.GetFullPath().fn_str() );
|
||||
nlohmann::json schema;
|
||||
|
||||
try
|
||||
{
|
||||
// For some obscure reason on MINGW, using UCRT option,
|
||||
// m_schema_validator.set_root_schema() hangs without switching to locale "C"
|
||||
#if defined(__MINGW32__) && defined(_UCRT)
|
||||
LOCALE_IO dummy;
|
||||
#endif
|
||||
|
||||
schema_stream >> schema;
|
||||
m_schema_validator.set_root_schema( schema );
|
||||
}
|
||||
catch( std::exception& e )
|
||||
{
|
||||
if( !schema_file.FileExists() )
|
||||
{
|
||||
wxLogError( wxString::Format( _( "schema file '%s' not found" ),
|
||||
schema_file.GetFullPath() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogError( wxString::Format( _( "Error loading schema: %s" ), e.what() ) );
|
||||
}
|
||||
}
|
||||
m_schema_validator = std::make_unique<JSON_SCHEMA_VALIDATOR>( schema_file );
|
||||
|
||||
// Load currently installed packages
|
||||
wxFileName f( PATHS::GetUserSettingsPath(), wxT( "installed_packages.json" ) );
|
||||
@ -314,7 +290,7 @@ void PLUGIN_CONTENT_MANAGER::ValidateJson( const nlohmann::json& aJson,
|
||||
const nlohmann::json_uri& aUri ) const
|
||||
{
|
||||
THROWING_ERROR_HANDLER error_handler;
|
||||
m_schema_validator.validate( aJson, error_handler, aUri );
|
||||
m_schema_validator->Validate( aJson, error_handler, aUri );
|
||||
}
|
||||
|
||||
|
||||
|
@ -23,12 +23,12 @@
|
||||
|
||||
#include "core/wx_stl_compat.h"
|
||||
#include "pcm_data.h"
|
||||
#include <json_schema_validator.h>
|
||||
#include "widgets/wx_progress_reporters.h"
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <json_common.h>
|
||||
#include <nlohmann/json-schema.hpp>
|
||||
|
||||
#include <thread>
|
||||
#include <tuple>
|
||||
#include <unordered_map>
|
||||
@ -393,7 +393,7 @@ private:
|
||||
time_t getCurrentTimestamp() const;
|
||||
|
||||
wxWindow* m_dialog;
|
||||
nlohmann::json_schema::json_validator m_schema_validator;
|
||||
std::unique_ptr<JSON_SCHEMA_VALIDATOR> m_schema_validator;
|
||||
wxString m_3rdparty_path;
|
||||
wxString m_cache_path;
|
||||
std::unordered_map<wxString, PCM_REPOSITORY> m_repository_cache;
|
||||
|
@ -6,15 +6,14 @@ add_library( nlohmann_json_schema_validator STATIC
|
||||
string-format-check.cpp
|
||||
)
|
||||
|
||||
add_dependencies( nlohmann_json_schema_validator kicommon )
|
||||
|
||||
target_include_directories( nlohmann_json_schema_validator
|
||||
PUBLIC
|
||||
$<INSTALL_INTERFACE:include>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
)
|
||||
|
||||
target_include_directories( nlohmann_json_schema_validator INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} )
|
||||
|
||||
target_link_libraries( nlohmann_json_schema_validator
|
||||
PUBLIC nlohmann_json
|
||||
PRIVATE kicommon
|
||||
)
|
||||
|
@ -6,7 +6,6 @@
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
#include <json_common.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
namespace nlohmann
|
||||
|
@ -21,7 +21,6 @@
|
||||
# define JSON_SCHEMA_VALIDATOR_API
|
||||
#endif
|
||||
|
||||
#include <json_common.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#ifdef NLOHMANN_JSON_VERSION_MAJOR
|
||||
|
Loading…
Reference in New Issue
Block a user