From c8c10d5955e794bf68ec12c2cba501b06ff6e625 Mon Sep 17 00:00:00 2001 From: jaimergp Date: Mon, 25 Nov 2024 11:18:14 +0100 Subject: [PATCH 1/8] Use $schema and $id in the right way --- menuinst/_schema.py | 47 +- menuinst/data/menuinst-1.default.json | 68 ++ menuinst/data/menuinst-1.schema.json | 734 ++++++++++++++++++ tests/data/jsons/entitlements.json | 3 +- tests/data/jsons/example-3.invalid.json | 3 +- tests/data/jsons/file_types.json | 3 +- .../jsons/file_types_no_event_handler.json | 3 +- tests/data/jsons/menu-name.json | 3 +- tests/data/jsons/no-platforms.json | 3 +- tests/data/jsons/osx_symlinks.json | 3 +- tests/data/jsons/precommands.json | 3 +- tests/data/jsons/sys-prefix.json | 3 +- tests/data/jsons/url_protocols.json | 3 +- tests/data/jsons/windows-terminal.json | 3 +- tests/data/jsons/working-dir.json | 3 +- 15 files changed, 841 insertions(+), 44 deletions(-) create mode 100644 menuinst/data/menuinst-1.default.json create mode 100644 menuinst/data/menuinst-1.schema.json diff --git a/menuinst/_schema.py b/menuinst/_schema.py index 560de6b3..2f746ec3 100644 --- a/menuinst/_schema.py +++ b/menuinst/_schema.py @@ -20,6 +20,9 @@ log = getLogger(__name__) +SCHEMA_DIALECT = "http://json-schema.org/draft-07/schema#" +SCHEMA_VERSION = "1" +SCHEMA_URL = f"https://schemas.conda.org/menuinst-{SCHEMA_VERSION}.schema.json" class BaseModel(_BaseModel): @@ -398,14 +401,21 @@ class MenuItem(BaseModel): class MenuInstSchema(BaseModel): "Metadata required to create menu items across operating systems with ``menuinst``." - id_: Literal["https://schemas.conda.io/menuinst-1.schema.json"] = Field( - ..., - description="Version of the menuinst schema.", + class Config(BaseModel.Config): + schema_extra = { + "$schema": SCHEMA_DIALECT, + "$id": SCHEMA_URL, + } + + id_: constr(min_length=1) = Field( + SCHEMA_URL, + description="DEPRECATED. Use ``$schema``.", alias="$id", + deprecated=True, ) - schema_: Literal["https://json-schema.org/draft-07/schema"] = Field( - ..., - description="Standard of the JSON schema we adhere to.", + schema_: constr(min_length=1) = Field( + SCHEMA_URL, + description="Version of the menuinst schema.", alias="$schema", ) menu_name: constr(min_length=1) = ... @@ -415,14 +425,15 @@ class MenuInstSchema(BaseModel): def dump_schema_to_json(write=True): + schema = MenuInstSchema.schema() if write: here = Path(__file__).parent - schema = MenuInstSchema.schema_json(indent=2) - print(schema) - with open(here / "data" / "menuinst.schema.json", "w") as f: - f.write(schema) + schema_str = json.dumps(schema, indent=2) + print(schema_str) + with open(here / "data" / f"menuinst-{SCHEMA_VERSION}.schema.json", "w") as f: + f.write(schema_str) f.write("\n") - return MenuInstSchema.schema() + return schema def dump_default_to_json(write=True): @@ -435,21 +446,17 @@ def dump_default_to_json(write=True): "osx": MacOS().dict(), "linux": Linux().dict(), } - default = MenuInstSchema( - menu_name="REQUIRED", - menu_items=[default_item], - **{ - "$id": "https://schemas.conda.io/menuinst-1.schema.json", - "$schema": "https://json-schema.org/draft-07/schema", - }, - ).dict() + default = MenuInstSchema(menu_name="REQUIRED", menu_items=[default_item]).dict() + default["$schema"] = SCHEMA_URL + default.pop("id_", None) + default.pop("schema_", None) for platform_value in default["menu_items"][0]["platforms"].values(): for key in list(platform_value.keys()): if key in MenuItem.__fields__: platform_value.pop(key) if write: pprint(default) - with open(here / "data" / "menuinst.default.json", "w") as f: + with open(here / "data" / f"menuinst-{SCHEMA_VERSION}.default.json", "w") as f: json.dump(default, f, indent=2) f.write("\n") return default diff --git a/menuinst/data/menuinst-1.default.json b/menuinst/data/menuinst-1.default.json new file mode 100644 index 00000000..0f0efd32 --- /dev/null +++ b/menuinst/data/menuinst-1.default.json @@ -0,0 +1,68 @@ +{ + "menu_name": "REQUIRED", + "menu_items": [ + { + "name": "REQUIRED", + "description": "REQUIRED", + "command": [ + "REQUIRED" + ], + "icon": null, + "precommand": null, + "precreate": null, + "working_dir": null, + "activate": true, + "terminal": false, + "platforms": { + "linux": { + "Categories": null, + "DBusActivatable": null, + "GenericName": null, + "Hidden": null, + "Implements": null, + "Keywords": null, + "MimeType": null, + "NoDisplay": null, + "NotShowIn": null, + "OnlyShowIn": null, + "PrefersNonDefaultGPU": null, + "SingleMainWindow": null, + "StartupNotify": null, + "StartupWMClass": null, + "TryExec": null, + "glob_patterns": null + }, + "osx": { + "CFBundleDisplayName": null, + "CFBundleIdentifier": null, + "CFBundleName": null, + "CFBundleSpokenName": null, + "CFBundleVersion": null, + "CFBundleURLTypes": null, + "CFBundleDocumentTypes": null, + "LSApplicationCategoryType": null, + "LSBackgroundOnly": null, + "LSEnvironment": null, + "LSMinimumSystemVersion": null, + "LSMultipleInstancesProhibited": null, + "LSRequiresNativeExecution": null, + "NSSupportsAutomaticGraphicsSwitching": null, + "UTExportedTypeDeclarations": null, + "UTImportedTypeDeclarations": null, + "entitlements": null, + "link_in_bundle": null, + "event_handler": null + }, + "win": { + "desktop": true, + "quicklaunch": false, + "terminal_profile": null, + "url_protocols": null, + "file_extensions": null, + "app_user_model_id": null + } + } + } + ], + "$schema": "https://schemas.conda.org/menuinst-1.schema.json" +} diff --git a/menuinst/data/menuinst-1.schema.json b/menuinst/data/menuinst-1.schema.json new file mode 100644 index 00000000..d3131330 --- /dev/null +++ b/menuinst/data/menuinst-1.schema.json @@ -0,0 +1,734 @@ +{ + "title": "MenuInstSchema", + "description": "Metadata required to create menu items across operating systems with ``menuinst``.", + "type": "object", + "properties": { + "$id": { + "title": "$Id", + "description": "DEPRECATED. Use ``$schema``.", + "default": "https://schemas.conda.org/menuinst-1.schema.json", + "deprecated": true, + "minLength": 1, + "type": "string" + }, + "$schema": { + "title": "$Schema", + "description": "Version of the menuinst schema.", + "default": "https://schemas.conda.org/menuinst-1.schema.json", + "minLength": 1, + "type": "string" + }, + "menu_name": { + "title": "Menu Name", + "minLength": 1, + "type": "string" + }, + "menu_items": { + "title": "Menu Items", + "minItems": 1, + "type": "array", + "items": { + "$ref": "#/definitions/MenuItem" + } + } + }, + "required": [ + "menu_name", + "menu_items" + ], + "additionalProperties": false, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://schemas.conda.org/menuinst-1.schema.json", + "definitions": { + "MenuItemNameDict": { + "title": "MenuItemNameDict", + "description": "Variable menu item name.\nUse this dictionary if the menu item name depends on installation parameters\nsuch as the target environment.", + "type": "object", + "properties": { + "target_environment_is_base": { + "title": "Target Environment Is Base", + "minLength": 1, + "type": "string" + }, + "target_environment_is_not_base": { + "title": "Target Environment Is Not Base", + "minLength": 1, + "type": "string" + } + }, + "additionalProperties": false + }, + "Linux": { + "title": "Linux", + "description": "Linux-specific instructions.\n\nCheck the `Desktop entry specification\n`__\nfor more details.", + "type": "object", + "properties": { + "name": { + "title": "Name", + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "$ref": "#/definitions/MenuItemNameDict" + } + ] + }, + "description": { + "title": "Description", + "type": "string" + }, + "icon": { + "title": "Icon", + "minLength": 1, + "type": "string" + }, + "command": { + "title": "Command", + "minItems": 1, + "type": "array", + "items": { + "type": "string" + } + }, + "working_dir": { + "title": "Working Dir", + "minLength": 1, + "type": "string" + }, + "precommand": { + "title": "Precommand", + "minLength": 1, + "type": "string" + }, + "precreate": { + "title": "Precreate", + "minLength": 1, + "type": "string" + }, + "activate": { + "title": "Activate", + "type": "boolean" + }, + "terminal": { + "title": "Terminal", + "type": "boolean" + }, + "Categories": { + "title": "Categories", + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "string", + "pattern": "^.+;$" + } + ] + }, + "DBusActivatable": { + "title": "Dbusactivatable", + "type": "boolean" + }, + "GenericName": { + "title": "Genericname", + "type": "string" + }, + "Hidden": { + "title": "Hidden", + "type": "boolean" + }, + "Implements": { + "title": "Implements", + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "string", + "pattern": "^.+;$" + } + ] + }, + "Keywords": { + "title": "Keywords", + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "string", + "pattern": "^.+;$" + } + ] + }, + "MimeType": { + "title": "Mimetype", + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "string", + "pattern": "^.+;$" + } + ] + }, + "NoDisplay": { + "title": "Nodisplay", + "type": "boolean" + }, + "NotShowIn": { + "title": "Notshowin", + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "string", + "pattern": "^.+;$" + } + ] + }, + "OnlyShowIn": { + "title": "Onlyshowin", + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "string", + "pattern": "^.+;$" + } + ] + }, + "PrefersNonDefaultGPU": { + "title": "Prefersnondefaultgpu", + "type": "boolean" + }, + "SingleMainWindow": { + "title": "Singlemainwindow", + "type": "boolean" + }, + "StartupNotify": { + "title": "Startupnotify", + "type": "boolean" + }, + "StartupWMClass": { + "title": "Startupwmclass", + "type": "string" + }, + "TryExec": { + "title": "Tryexec", + "type": "string" + }, + "glob_patterns": { + "title": "Glob Patterns", + "type": "object", + "additionalProperties": { + "type": "string", + "pattern": ".*\\*.*" + } + } + }, + "additionalProperties": false + }, + "CFBundleURLTypesModel": { + "title": "CFBundleURLTypesModel", + "description": "Describes a URL scheme associated with the app.", + "type": "object", + "properties": { + "CFBundleTypeRole": { + "title": "Cfbundletyperole", + "enum": [ + "Editor", + "Viewer", + "Shell", + "None" + ], + "type": "string" + }, + "CFBundleURLSchemes": { + "title": "Cfbundleurlschemes", + "type": "array", + "items": { + "type": "string" + } + }, + "CFBundleURLName": { + "title": "Cfbundleurlname", + "type": "string" + }, + "CFBundleURLIconFile": { + "title": "Cfbundleurliconfile", + "type": "string" + } + }, + "required": [ + "CFBundleURLSchemes" + ], + "additionalProperties": false + }, + "CFBundleDocumentTypesModel": { + "title": "CFBundleDocumentTypesModel", + "description": "Describes a document type associated with the app.", + "type": "object", + "properties": { + "CFBundleTypeIconFile": { + "title": "Cfbundletypeiconfile", + "type": "string" + }, + "CFBundleTypeName": { + "title": "Cfbundletypename", + "type": "string" + }, + "CFBundleTypeRole": { + "title": "Cfbundletyperole", + "enum": [ + "Editor", + "Viewer", + "Shell", + "None" + ], + "type": "string" + }, + "LSItemContentTypes": { + "title": "Lsitemcontenttypes", + "type": "array", + "items": { + "type": "string" + } + }, + "LSHandlerRank": { + "title": "Lshandlerrank", + "enum": [ + "Owner", + "Default", + "Alternate" + ], + "type": "string" + } + }, + "required": [ + "CFBundleTypeName", + "LSItemContentTypes", + "LSHandlerRank" + ], + "additionalProperties": false + }, + "UTTypeDeclarationModel": { + "title": "UTTypeDeclarationModel", + "type": "object", + "properties": { + "UTTypeConformsTo": { + "title": "Uttypeconformsto", + "type": "array", + "items": { + "type": "string" + } + }, + "UTTypeDescription": { + "title": "Uttypedescription", + "type": "string" + }, + "UTTypeIconFile": { + "title": "Uttypeiconfile", + "type": "string" + }, + "UTTypeIdentifier": { + "title": "Uttypeidentifier", + "type": "string" + }, + "UTTypeReferenceURL": { + "title": "Uttypereferenceurl", + "type": "string" + }, + "UTTypeTagSpecification": { + "title": "Uttypetagspecification", + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "required": [ + "UTTypeConformsTo", + "UTTypeIdentifier", + "UTTypeTagSpecification" + ], + "additionalProperties": false + }, + "MacOS": { + "title": "MacOS", + "description": "Mac-specific instructions. Check these URLs for more info:\n\n- ``CF*`` keys: see `Core Foundation Keys `__\n- ``LS*`` keys: see `Launch Services Keys `__\n- ``entitlements``: see `Entitlements documentation `__", + "type": "object", + "properties": { + "name": { + "title": "Name", + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "$ref": "#/definitions/MenuItemNameDict" + } + ] + }, + "description": { + "title": "Description", + "type": "string" + }, + "icon": { + "title": "Icon", + "minLength": 1, + "type": "string" + }, + "command": { + "title": "Command", + "minItems": 1, + "type": "array", + "items": { + "type": "string" + } + }, + "working_dir": { + "title": "Working Dir", + "minLength": 1, + "type": "string" + }, + "precommand": { + "title": "Precommand", + "minLength": 1, + "type": "string" + }, + "precreate": { + "title": "Precreate", + "minLength": 1, + "type": "string" + }, + "activate": { + "title": "Activate", + "type": "boolean" + }, + "terminal": { + "title": "Terminal", + "type": "boolean" + }, + "CFBundleDisplayName": { + "title": "Cfbundledisplayname", + "type": "string" + }, + "CFBundleIdentifier": { + "title": "Cfbundleidentifier", + "pattern": "^[A-z0-9\\-\\.]+$", + "type": "string" + }, + "CFBundleName": { + "title": "Cfbundlename", + "maxLength": 16, + "type": "string" + }, + "CFBundleSpokenName": { + "title": "Cfbundlespokenname", + "type": "string" + }, + "CFBundleVersion": { + "title": "Cfbundleversion", + "pattern": "^\\S+$", + "type": "string" + }, + "CFBundleURLTypes": { + "title": "Cfbundleurltypes", + "type": "array", + "items": { + "$ref": "#/definitions/CFBundleURLTypesModel" + } + }, + "CFBundleDocumentTypes": { + "title": "Cfbundledocumenttypes", + "type": "array", + "items": { + "$ref": "#/definitions/CFBundleDocumentTypesModel" + } + }, + "LSApplicationCategoryType": { + "title": "Lsapplicationcategorytype", + "pattern": "^public\\.app-category\\.\\S+$", + "type": "string" + }, + "LSBackgroundOnly": { + "title": "Lsbackgroundonly", + "type": "boolean" + }, + "LSEnvironment": { + "title": "Lsenvironment", + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "LSMinimumSystemVersion": { + "title": "Lsminimumsystemversion", + "pattern": "^\\d+\\.\\d+\\.\\d+$", + "type": "string" + }, + "LSMultipleInstancesProhibited": { + "title": "Lsmultipleinstancesprohibited", + "type": "boolean" + }, + "LSRequiresNativeExecution": { + "title": "Lsrequiresnativeexecution", + "type": "boolean" + }, + "NSSupportsAutomaticGraphicsSwitching": { + "title": "Nssupportsautomaticgraphicsswitching", + "type": "boolean" + }, + "UTExportedTypeDeclarations": { + "title": "Utexportedtypedeclarations", + "type": "array", + "items": { + "$ref": "#/definitions/UTTypeDeclarationModel" + } + }, + "UTImportedTypeDeclarations": { + "title": "Utimportedtypedeclarations", + "type": "array", + "items": { + "$ref": "#/definitions/UTTypeDeclarationModel" + } + }, + "entitlements": { + "title": "Entitlements", + "type": "array", + "items": { + "type": "string", + "pattern": "[a-z0-9\\.\\-]+" + } + }, + "link_in_bundle": { + "title": "Link In Bundle", + "type": "object", + "additionalProperties": { + "type": "string", + "pattern": "^(?!\\/)(?!\\.\\./).*" + } + }, + "event_handler": { + "title": "Event Handler", + "minLength": 1, + "type": "string" + } + }, + "additionalProperties": false + }, + "Windows": { + "title": "Windows", + "description": "Windows-specific instructions. You can override global keys here if needed", + "type": "object", + "properties": { + "name": { + "title": "Name", + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "$ref": "#/definitions/MenuItemNameDict" + } + ] + }, + "description": { + "title": "Description", + "type": "string" + }, + "icon": { + "title": "Icon", + "minLength": 1, + "type": "string" + }, + "command": { + "title": "Command", + "minItems": 1, + "type": "array", + "items": { + "type": "string" + } + }, + "working_dir": { + "title": "Working Dir", + "minLength": 1, + "type": "string" + }, + "precommand": { + "title": "Precommand", + "minLength": 1, + "type": "string" + }, + "precreate": { + "title": "Precreate", + "minLength": 1, + "type": "string" + }, + "activate": { + "title": "Activate", + "type": "boolean" + }, + "terminal": { + "title": "Terminal", + "type": "boolean" + }, + "desktop": { + "title": "Desktop", + "default": true, + "type": "boolean" + }, + "quicklaunch": { + "title": "Quicklaunch", + "default": false, + "type": "boolean" + }, + "terminal_profile": { + "title": "Terminal Profile", + "minLength": 1, + "type": "string" + }, + "url_protocols": { + "title": "Url Protocols", + "type": "array", + "items": { + "type": "string", + "pattern": "\\S+" + } + }, + "file_extensions": { + "title": "File Extensions", + "type": "array", + "items": { + "type": "string", + "pattern": "\\.\\S*" + } + }, + "app_user_model_id": { + "title": "App User Model Id", + "maxLength": 128, + "pattern": "\\S+\\.\\S+", + "type": "string" + } + }, + "additionalProperties": false + }, + "Platforms": { + "title": "Platforms", + "description": "Platform specific options.\n\nNote each of these fields supports the same keys as the top-level :class:`MenuItem`\n(sans ``platforms`` itself), in case overrides are needed.", + "type": "object", + "properties": { + "linux": { + "$ref": "#/definitions/Linux" + }, + "osx": { + "$ref": "#/definitions/MacOS" + }, + "win": { + "$ref": "#/definitions/Windows" + } + }, + "additionalProperties": false + }, + "MenuItem": { + "title": "MenuItem", + "description": "Instructions to create a menu item across operating systems.", + "type": "object", + "properties": { + "name": { + "title": "Name", + "anyOf": [ + { + "type": "string", + "minLength": 1 + }, + { + "$ref": "#/definitions/MenuItemNameDict" + } + ] + }, + "description": { + "title": "Description", + "type": "string" + }, + "command": { + "title": "Command", + "minItems": 1, + "type": "array", + "items": { + "type": "string" + } + }, + "icon": { + "title": "Icon", + "minLength": 1, + "type": "string" + }, + "precommand": { + "title": "Precommand", + "minLength": 1, + "type": "string" + }, + "precreate": { + "title": "Precreate", + "minLength": 1, + "type": "string" + }, + "working_dir": { + "title": "Working Dir", + "minLength": 1, + "type": "string" + }, + "activate": { + "title": "Activate", + "default": true, + "type": "boolean" + }, + "terminal": { + "title": "Terminal", + "default": false, + "type": "boolean" + }, + "platforms": { + "$ref": "#/definitions/Platforms" + } + }, + "required": [ + "name", + "description", + "command", + "platforms" + ], + "additionalProperties": false + } + } +} diff --git a/tests/data/jsons/entitlements.json b/tests/data/jsons/entitlements.json index 3edc7d1b..c2cf8b82 100644 --- a/tests/data/jsons/entitlements.json +++ b/tests/data/jsons/entitlements.json @@ -1,6 +1,5 @@ { - "$schema": "https://json-schema.org/draft-07/schema", - "$id": "https://schemas.conda.io/menuinst-1.schema.json", + "$schema": "https://raw.githubusercontent.com/conda/menuinst/refs/heads/main/menuinst/data/menuinst.schema.json", "menu_name": "Example with entitlements", "menu_items": [ { diff --git a/tests/data/jsons/example-3.invalid.json b/tests/data/jsons/example-3.invalid.json index 394734d0..06d00f47 100644 --- a/tests/data/jsons/example-3.invalid.json +++ b/tests/data/jsons/example-3.invalid.json @@ -1,6 +1,5 @@ { - "$schema": "https://json-schema.org/draft-07/schema", - "$id": "https://schemas.conda.io/menuinst-1.schema.json", + "$schema": "https://raw.githubusercontent.com/conda/menuinst/refs/heads/main/menuinst/data/menuinst.schema.json", "menu_name": "Example 2", "menu_items": [ { diff --git a/tests/data/jsons/file_types.json b/tests/data/jsons/file_types.json index 4fac2127..20cd66fa 100644 --- a/tests/data/jsons/file_types.json +++ b/tests/data/jsons/file_types.json @@ -1,6 +1,5 @@ { - "$schema": "https://json-schema.org/draft-07/schema", - "$id": "https://schemas.conda.io/menuinst-1.schema.json", + "$schema": "https://raw.githubusercontent.com/conda/menuinst/refs/heads/main/menuinst/data/menuinst.schema.json", "menu_name": "Example with file type association", "menu_items": [ { diff --git a/tests/data/jsons/file_types_no_event_handler.json b/tests/data/jsons/file_types_no_event_handler.json index 37d63bf4..70217cdc 100644 --- a/tests/data/jsons/file_types_no_event_handler.json +++ b/tests/data/jsons/file_types_no_event_handler.json @@ -1,6 +1,5 @@ { - "$schema": "https://json-schema.org/draft-07/schema", - "$id": "https://schemas.conda.io/menuinst-1.schema.json", + "$schema": "https://raw.githubusercontent.com/conda/menuinst/refs/heads/main/menuinst/data/menuinst.schema.json", "menu_name": "Example with file type association and no event handler (macOS only)", "menu_items": [ { diff --git a/tests/data/jsons/menu-name.json b/tests/data/jsons/menu-name.json index 0d8e09dd..b8671e1e 100644 --- a/tests/data/jsons/menu-name.json +++ b/tests/data/jsons/menu-name.json @@ -1,6 +1,5 @@ { - "$schema": "https://json-schema.org/draft-07/schema", - "$id": "https://schemas.conda.io/menuinst-1.schema.json", + "$schema": "https://raw.githubusercontent.com/conda/menuinst/refs/heads/main/menuinst/data/menuinst.schema.json", "menu_name": "Package", "menu_items": [ { diff --git a/tests/data/jsons/no-platforms.json b/tests/data/jsons/no-platforms.json index 03e1fbee..f4ff1c0a 100644 --- a/tests/data/jsons/no-platforms.json +++ b/tests/data/jsons/no-platforms.json @@ -1,6 +1,5 @@ { - "$schema": "https://json-schema.org/draft-07/schema", - "$id": "https://schemas.conda.io/menuinst-1.schema.json", + "$schema": "https://raw.githubusercontent.com/conda/menuinst/refs/heads/main/menuinst/data/menuinst.schema.json", "menu_name": "NoPlatforms", "menu_items": [ { diff --git a/tests/data/jsons/osx_symlinks.json b/tests/data/jsons/osx_symlinks.json index a8514356..6ca6e775 100644 --- a/tests/data/jsons/osx_symlinks.json +++ b/tests/data/jsons/osx_symlinks.json @@ -1,6 +1,5 @@ { - "$schema": "https://json-schema.org/draft-07/schema", - "$id": "https://schemas.conda.io/menuinst-1.schema.json", + "$schema": "https://raw.githubusercontent.com/conda/menuinst/refs/heads/main/menuinst/data/menuinst.schema.json", "menu_name": "Example with macOS symlinks", "menu_items": [ { diff --git a/tests/data/jsons/precommands.json b/tests/data/jsons/precommands.json index 9b2a6f05..344c050c 100644 --- a/tests/data/jsons/precommands.json +++ b/tests/data/jsons/precommands.json @@ -1,6 +1,5 @@ { - "$schema": "https://json-schema.org/draft-07/schema", - "$id": "https://schemas.conda.io/menuinst-1.schema.json", + "$schema": "https://raw.githubusercontent.com/conda/menuinst/refs/heads/main/menuinst/data/menuinst.schema.json", "menu_name": "Example with precommands", "menu_items": [ { diff --git a/tests/data/jsons/sys-prefix.json b/tests/data/jsons/sys-prefix.json index f44c1bf0..43b51f8e 100644 --- a/tests/data/jsons/sys-prefix.json +++ b/tests/data/jsons/sys-prefix.json @@ -1,6 +1,5 @@ { - "$schema": "https://json-schema.org/draft-07/schema", - "$id": "https://schemas.conda.io/menuinst-1.schema.json", + "$schema": "https://raw.githubusercontent.com/conda/menuinst/refs/heads/main/menuinst/data/menuinst.schema.json", "menu_name": "Sys.Prefix {{ DISTRIBUTION_NAME }}", "menu_items": [ { diff --git a/tests/data/jsons/url_protocols.json b/tests/data/jsons/url_protocols.json index 704f99e8..912c0534 100644 --- a/tests/data/jsons/url_protocols.json +++ b/tests/data/jsons/url_protocols.json @@ -1,6 +1,5 @@ { - "$schema": "https://json-schema.org/draft-07/schema", - "$id": "https://schemas.conda.io/menuinst-1.schema.json", + "$schema": "https://raw.githubusercontent.com/conda/menuinst/refs/heads/main/menuinst/data/menuinst.schema.json", "menu_name": "Example with file custom URL association", "menu_items": [ { diff --git a/tests/data/jsons/windows-terminal.json b/tests/data/jsons/windows-terminal.json index 3491da16..d0ae31fd 100644 --- a/tests/data/jsons/windows-terminal.json +++ b/tests/data/jsons/windows-terminal.json @@ -1,6 +1,5 @@ { - "$schema": "https://json-schema.org/draft-07/schema", - "$id": "https://schemas.conda.io/menuinst-1.schema.json", + "$schema": "https://raw.githubusercontent.com/conda/menuinst/refs/heads/main/menuinst/data/menuinst.schema.json", "menu_name": "Package", "menu_items": [ { diff --git a/tests/data/jsons/working-dir.json b/tests/data/jsons/working-dir.json index 6d68b21c..c68e0591 100644 --- a/tests/data/jsons/working-dir.json +++ b/tests/data/jsons/working-dir.json @@ -1,6 +1,5 @@ { - "$schema": "https://json-schema.org/draft-07/schema", - "$id": "https://schemas.conda.io/menuinst-1.schema.json", + "$schema": "https://raw.githubusercontent.com/conda/menuinst/refs/heads/main/menuinst/data/menuinst.schema.json", "menu_name": "Sys.Prefix {{ DISTRIBUTION_NAME }}", "menu_items": [ { From 89b80e6cbe5986a610d4fdfb050e1332398e259d Mon Sep 17 00:00:00 2001 From: jaimergp Date: Mon, 25 Nov 2024 11:22:24 +0100 Subject: [PATCH 2/8] update tests --- menuinst/utils.py | 4 ++-- tests/test_data.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/menuinst/utils.py b/menuinst/utils.py index 653df112..c9556ce8 100644 --- a/menuinst/utils.py +++ b/menuinst/utils.py @@ -196,7 +196,7 @@ def quote_string(cls, s: str) -> str: return quoted -def unlink(path: os.PathLike, missing_ok: bool = False): +def unlink(path: str | os.PathLike, missing_ok: bool = False): try: os.unlink(path) except FileNotFoundError as exc: @@ -204,7 +204,7 @@ def unlink(path: os.PathLike, missing_ok: bool = False): raise exc -def data_path(path: os.PathLike) -> Path: +def data_path(path: str | os.PathLike) -> Path: here = Path(__file__).parent return here / "data" / path diff --git a/tests/test_data.py b/tests/test_data.py index ba8095d9..e9793830 100644 --- a/tests/test_data.py +++ b/tests/test_data.py @@ -2,19 +2,19 @@ import json -from menuinst._schema import dump_default_to_json, dump_schema_to_json +from menuinst._schema import dump_default_to_json, dump_schema_to_json, SCHEMA_VERSION from menuinst.utils import data_path def test_schema_is_up_to_date(): - with open(data_path("menuinst.schema.json")) as f: + with open(data_path(f"menuinst-{SCHEMA_VERSION}.schema.json")) as f: in_file = json.load(f) in_code = dump_schema_to_json(write=False) assert in_file == in_code def test_defaults_are_up_to_date(): - with open(data_path("menuinst.default.json")) as f: + with open(data_path(f"menuinst-{SCHEMA_VERSION}.default.json")) as f: in_file = json.load(f) in_code = dump_default_to_json(write=False) assert in_file == in_code From 1b70c62ddf0bf843bbeeecc41df017c2bfeb6b5d Mon Sep 17 00:00:00 2001 From: jaimergp Date: Mon, 25 Nov 2024 11:29:02 +0100 Subject: [PATCH 3/8] add news --- news/283-schema-id | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 news/283-schema-id diff --git a/news/283-schema-id b/news/283-schema-id new file mode 100644 index 00000000..002b47b8 --- /dev/null +++ b/news/283-schema-id @@ -0,0 +1,20 @@ +### Enhancements + +* Bump schema version to `1`. (#282 via #283) + +### Bug fixes + +* Use `$schema` to indicate which schema will validate the menuinst shortcut. + This means that menuinst shortcuts must now include a `$schema` key pointing to a URL containing the relevant menuinst JSON schema version. (#282 via #283) + +### Deprecations + +* `$id` key is no longer required in the schema, and is now deprecated. (#282 via #283) + +### Docs + +* + +### Other + +* From 6e4bb1e5b0dd8f189717f1cb1252dd4f5ee03d49 Mon Sep 17 00:00:00 2001 From: jaimergp Date: Mon, 25 Nov 2024 11:29:45 +0100 Subject: [PATCH 4/8] future annotations --- menuinst/utils.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/menuinst/utils.py b/menuinst/utils.py index c9556ce8..b89b1e49 100644 --- a/menuinst/utils.py +++ b/menuinst/utils.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import os import re import shlex From aa1126389dca6f463ba6705cff3d0c695bb6dc8c Mon Sep 17 00:00:00 2001 From: jaimergp Date: Mon, 25 Nov 2024 12:10:31 +0100 Subject: [PATCH 5/8] pre-commit --- tests/test_data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_data.py b/tests/test_data.py index e9793830..55628bc4 100644 --- a/tests/test_data.py +++ b/tests/test_data.py @@ -2,7 +2,7 @@ import json -from menuinst._schema import dump_default_to_json, dump_schema_to_json, SCHEMA_VERSION +from menuinst._schema import SCHEMA_VERSION, dump_default_to_json, dump_schema_to_json from menuinst.utils import data_path From 6d846e4071e83f3421dac0cc65f0f411bab84fb2 Mon Sep 17 00:00:00 2001 From: jaimergp Date: Fri, 13 Dec 2024 19:57:49 +0100 Subject: [PATCH 6/8] Regenerate schema --- menuinst/data/menuinst-1.schema.json | 265 +++++++++++++++++++++++++-- 1 file changed, 248 insertions(+), 17 deletions(-) diff --git a/menuinst/data/menuinst-1.schema.json b/menuinst/data/menuinst-1.schema.json index d3131330..7e7e8f09 100644 --- a/menuinst/data/menuinst-1.schema.json +++ b/menuinst/data/menuinst-1.schema.json @@ -1,6 +1,6 @@ { "title": "MenuInstSchema", - "description": "Metadata required to create menu items across operating systems with ``menuinst``.", + "description": "Metadata required to create menu items across operating systems with `menuinst`.", "type": "object", "properties": { "$id": { @@ -8,6 +8,7 @@ "description": "DEPRECATED. Use ``$schema``.", "default": "https://schemas.conda.org/menuinst-1.schema.json", "deprecated": true, + "markdownDescription": "DEPRECATED. Use ``$schema``.", "minLength": 1, "type": "string" }, @@ -15,16 +16,21 @@ "title": "$Schema", "description": "Version of the menuinst schema.", "default": "https://schemas.conda.org/menuinst-1.schema.json", + "markdownDescription": "Version of the menuinst schema.", "minLength": 1, "type": "string" }, "menu_name": { "title": "Menu Name", + "description": "Name for the category containing the items specified in `menu_items`.", + "markdownDescription": "Name for the category containing the items specified in `menu_items`.", "minLength": 1, "type": "string" }, "menu_items": { "title": "Menu Items", + "description": "List of menu entries to create across main desktop systems.", + "markdownDescription": "List of menu entries to create across main desktop systems.", "minItems": 1, "type": "array", "items": { @@ -42,29 +48,36 @@ "definitions": { "MenuItemNameDict": { "title": "MenuItemNameDict", - "description": "Variable menu item name.\nUse this dictionary if the menu item name depends on installation parameters\nsuch as the target environment.", + "description": "Variable menu item name. Use this dictionary if the menu item name depends on installation parameters such as the target environment.", "type": "object", "properties": { "target_environment_is_base": { "title": "Target Environment Is Base", + "description": "Name when target environment is the base environment.", + "markdownDescription": "Name when target environment is the base environment.", "minLength": 1, "type": "string" }, "target_environment_is_not_base": { "title": "Target Environment Is Not Base", + "description": "Name when target environment is not the base environment.", + "markdownDescription": "Name when target environment is not the base environment.", "minLength": 1, "type": "string" } }, - "additionalProperties": false + "additionalProperties": false, + "markdownDescription": "Variable menu item name. Use this dictionary if the menu item name depends on installation parameters such as the target environment." }, "Linux": { "title": "Linux", - "description": "Linux-specific instructions.\n\nCheck the `Desktop entry specification\n`__\nfor more details.", + "description": "Linux-specific instructions.\n\nCheck the [Desktop entry specification]( https://specifications.freedesktop.org/desktop-entry-spec/latest/recognized-keys.html) for more details.", "type": "object", "properties": { "name": { "title": "Name", + "description": "The name of the menu item. Can be a dictionary if the name depends on installation parameters. See `MenuItemNameDict` for details.", + "markdownDescription": "The name of the menu item. Can be a dictionary if the name depends on installation parameters. See `MenuItemNameDict` for details.", "anyOf": [ { "type": "string", @@ -77,15 +90,21 @@ }, "description": { "title": "Description", + "description": "A longer description of the menu item. Shown on popup messages.", + "markdownDescription": "A longer description of the menu item. Shown on popup messages.", "type": "string" }, "icon": { "title": "Icon", + "description": "Path to the file representing or containing the icon.", + "markdownDescription": "Path to the file representing or containing the icon.", "minLength": 1, "type": "string" }, "command": { "title": "Command", + "description": "Command to run with the menu item, expressed as a list of strings where each string is an argument.", + "markdownDescription": "Command to run with the menu item, expressed as a list of strings where each string is an argument.", "minItems": 1, "type": "array", "items": { @@ -94,29 +113,41 @@ }, "working_dir": { "title": "Working Dir", + "description": "Working directory for the running process. Defaults to user directory on each platform.", + "markdownDescription": "Working directory for the running process. Defaults to user directory on each platform.", "minLength": 1, "type": "string" }, "precommand": { "title": "Precommand", + "description": "(Simple, preferrably single-line) logic to run before the command is run. Runs before the environment is activated, if that applies.", + "markdownDescription": "(Simple, preferrably single-line) logic to run before the command is run. Runs before the environment is activated, if that applies.", "minLength": 1, "type": "string" }, "precreate": { "title": "Precreate", + "description": "(Simple, preferrably single-line) logic to run before the shortcut is created.", + "markdownDescription": "(Simple, preferrably single-line) logic to run before the shortcut is created.", "minLength": 1, "type": "string" }, "activate": { "title": "Activate", + "description": "Whether to activate the target environment before running `command`.", + "markdownDescription": "Whether to activate the target environment before running `command`.", "type": "boolean" }, "terminal": { "title": "Terminal", + "description": "Whether run the program in a terminal/console or not. On Windows, it only has an effect if `activate` is true. On MacOS, the application will ignore command-line arguments.", + "markdownDescription": "Whether run the program in a terminal/console or not. On Windows, it only has an effect if `activate` is true. On MacOS, the application will ignore command-line arguments.", "type": "boolean" }, "Categories": { "title": "Categories", + "description": "Categories in which the entry should be shown in a menu. See 'Registered categories' in the [Menu Spec]( http://www.freedesktop.org/Standards/menu-spec).", + "markdownDescription": "Categories in which the entry should be shown in a menu. See 'Registered categories' in the [Menu Spec]( http://www.freedesktop.org/Standards/menu-spec).", "anyOf": [ { "type": "array", @@ -132,18 +163,26 @@ }, "DBusActivatable": { "title": "Dbusactivatable", + "description": "A boolean value specifying if D-Bus activation is supported for this application.", + "markdownDescription": "A boolean value specifying if D-Bus activation is supported for this application.", "type": "boolean" }, "GenericName": { "title": "Genericname", + "description": "Generic name of the application; e.g. if the name is 'conda', this would be 'Package Manager'.", + "markdownDescription": "Generic name of the application; e.g. if the name is 'conda', this would be 'Package Manager'.", "type": "string" }, "Hidden": { "title": "Hidden", + "description": "Disable shortcut, signaling a missing resource.", + "markdownDescription": "Disable shortcut, signaling a missing resource.", "type": "boolean" }, "Implements": { "title": "Implements", + "description": "List of supported interfaces. See 'Interfaces' in [Desktop Entry Spec]( https://specifications.freedesktop.org/desktop-entry-spec/latest/interfaces.html).", + "markdownDescription": "List of supported interfaces. See 'Interfaces' in [Desktop Entry Spec]( https://specifications.freedesktop.org/desktop-entry-spec/latest/interfaces.html).", "anyOf": [ { "type": "array", @@ -159,6 +198,8 @@ }, "Keywords": { "title": "Keywords", + "description": "Additional terms to describe this shortcut to aid in searching.", + "markdownDescription": "Additional terms to describe this shortcut to aid in searching.", "anyOf": [ { "type": "array", @@ -174,6 +215,8 @@ }, "MimeType": { "title": "Mimetype", + "description": "The MIME type(s) supported by this application. Note this includes file types and URL protocols. For URL protocols, use `x-scheme-handler/your-protocol-here`. For example, if you want to register `menuinst:`, you would include `x-scheme-handler/menuinst`.", + "markdownDescription": "The MIME type(s) supported by this application. Note this includes file types and URL protocols. For URL protocols, use `x-scheme-handler/your-protocol-here`. For example, if you want to register `menuinst:`, you would include `x-scheme-handler/menuinst`.", "anyOf": [ { "type": "array", @@ -189,10 +232,14 @@ }, "NoDisplay": { "title": "Nodisplay", + "description": "Do not show this item in the menu. Useful to associate MIME types and other registrations, without having an actual clickable item. Not to be confused with 'Hidden'.", + "markdownDescription": "Do not show this item in the menu. Useful to associate MIME types and other registrations, without having an actual clickable item. Not to be confused with 'Hidden'.", "type": "boolean" }, "NotShowIn": { "title": "Notshowin", + "description": "Desktop environments that should NOT display this item. It'll check against `$XDG_CURRENT_DESKTOP`.", + "markdownDescription": "Desktop environments that should NOT display this item. It'll check against `$XDG_CURRENT_DESKTOP`.", "anyOf": [ { "type": "array", @@ -208,6 +255,8 @@ }, "OnlyShowIn": { "title": "Onlyshowin", + "description": "Desktop environments that should display this item. It'll check against `$XDG_CURRENT_DESKTOP`.", + "markdownDescription": "Desktop environments that should display this item. It'll check against `$XDG_CURRENT_DESKTOP`.", "anyOf": [ { "type": "array", @@ -223,26 +272,38 @@ }, "PrefersNonDefaultGPU": { "title": "Prefersnondefaultgpu", + "description": "Hint that the app prefers to be run on a more powerful discrete GPU if available.", + "markdownDescription": "Hint that the app prefers to be run on a more powerful discrete GPU if available.", "type": "boolean" }, "SingleMainWindow": { "title": "Singlemainwindow", + "description": "Do not show the 'New Window' option in the app's context menu.", + "markdownDescription": "Do not show the 'New Window' option in the app's context menu.", "type": "boolean" }, "StartupNotify": { "title": "Startupnotify", + "description": "Advanced. See [Startup Notification spec]( https://www.freedesktop.org/wiki/Specifications/startup-notification-spec/).", + "markdownDescription": "Advanced. See [Startup Notification spec]( https://www.freedesktop.org/wiki/Specifications/startup-notification-spec/).", "type": "boolean" }, "StartupWMClass": { "title": "Startupwmclass", + "description": "Advanced. See [Startup Notification spec]( https://www.freedesktop.org/wiki/Specifications/startup-notification-spec/).", + "markdownDescription": "Advanced. See [Startup Notification spec]( https://www.freedesktop.org/wiki/Specifications/startup-notification-spec/).", "type": "string" }, "TryExec": { "title": "Tryexec", + "description": "Filename or absolute path to an executable file on disk used to determine if the program is actually installed and can be run. If the test fails, the shortcut might be ignored / hidden.", + "markdownDescription": "Filename or absolute path to an executable file on disk used to determine if the program is actually installed and can be run. If the test fails, the shortcut might be ignored / hidden.", "type": "string" }, "glob_patterns": { "title": "Glob Patterns", + "description": "Map of custom MIME types to their corresponding glob patterns (e.g. `*.txt`). Only needed if you define custom MIME types in `MimeType`.", + "markdownDescription": "Map of custom MIME types to their corresponding glob patterns (e.g. `*.txt`). Only needed if you define custom MIME types in `MimeType`.", "type": "object", "additionalProperties": { "type": "string", @@ -250,7 +311,8 @@ } } }, - "additionalProperties": false + "additionalProperties": false, + "markdownDescription": "Linux-specific instructions.\n\nCheck the [Desktop entry specification]( https://specifications.freedesktop.org/desktop-entry-spec/latest/recognized-keys.html) for more details." }, "CFBundleURLTypesModel": { "title": "CFBundleURLTypesModel", @@ -259,6 +321,8 @@ "properties": { "CFBundleTypeRole": { "title": "Cfbundletyperole", + "description": "This key specifies the app's role with respect to the URL.", + "markdownDescription": "This key specifies the app's role with respect to the URL.", "enum": [ "Editor", "Viewer", @@ -269,6 +333,8 @@ }, "CFBundleURLSchemes": { "title": "Cfbundleurlschemes", + "description": "URL schemes / protocols handled by this type (e.g. 'mailto').", + "markdownDescription": "URL schemes / protocols handled by this type (e.g. 'mailto').", "type": "array", "items": { "type": "string" @@ -276,17 +342,22 @@ }, "CFBundleURLName": { "title": "Cfbundleurlname", + "description": "Abstract name for this URL type. Uniqueness recommended.", + "markdownDescription": "Abstract name for this URL type. Uniqueness recommended.", "type": "string" }, "CFBundleURLIconFile": { "title": "Cfbundleurliconfile", + "description": "Name of the icon image file (minus the .icns extension).", + "markdownDescription": "Name of the icon image file (minus the .icns extension).", "type": "string" } }, "required": [ "CFBundleURLSchemes" ], - "additionalProperties": false + "additionalProperties": false, + "markdownDescription": "Describes a URL scheme associated with the app." }, "CFBundleDocumentTypesModel": { "title": "CFBundleDocumentTypesModel", @@ -295,14 +366,20 @@ "properties": { "CFBundleTypeIconFile": { "title": "Cfbundletypeiconfile", + "description": "Name of the icon image file (minus the .icns extension).", + "markdownDescription": "Name of the icon image file (minus the .icns extension).", "type": "string" }, "CFBundleTypeName": { "title": "Cfbundletypename", + "description": "Abstract name for this document type. Uniqueness recommended.", + "markdownDescription": "Abstract name for this document type. Uniqueness recommended.", "type": "string" }, "CFBundleTypeRole": { "title": "Cfbundletyperole", + "description": "This key specifies the app's role with respect to the type.", + "markdownDescription": "This key specifies the app's role with respect to the type.", "enum": [ "Editor", "Viewer", @@ -313,6 +390,8 @@ }, "LSItemContentTypes": { "title": "Lsitemcontenttypes", + "description": "List of UTI strings defining a supported file type; e.g. for PNG files, use 'public.png'. See [UTI Reference]( https://developer.apple.com/library/archive/documentation/Miscellaneous/Reference/UTIRef/Articles/System-DeclaredUniformTypeIdentifiers.html) for more info about the system-defined UTIs. Custom UTIs can be defined via 'UTExportedTypeDeclarations'. UTIs defined by other apps (not the system) need to be imported via 'UTImportedTypeDeclarations'.\n\nSee [Fun with UTIs](https://www.cocoanetics.com/2012/09/fun-with-uti/) for more info.", + "markdownDescription": "List of UTI strings defining a supported file type; e.g. for PNG files, use 'public.png'. See [UTI Reference]( https://developer.apple.com/library/archive/documentation/Miscellaneous/Reference/UTIRef/Articles/System-DeclaredUniformTypeIdentifiers.html) for more info about the system-defined UTIs. Custom UTIs can be defined via 'UTExportedTypeDeclarations'. UTIs defined by other apps (not the system) need to be imported via 'UTImportedTypeDeclarations'.\n\nSee [Fun with UTIs](https://www.cocoanetics.com/2012/09/fun-with-uti/) for more info.", "type": "array", "items": { "type": "string" @@ -320,6 +399,8 @@ }, "LSHandlerRank": { "title": "Lshandlerrank", + "description": "Determines how Launch Services ranks this app among the apps that declare themselves editors or viewers of files of this type.", + "markdownDescription": "Determines how Launch Services ranks this app among the apps that declare themselves editors or viewers of files of this type.", "enum": [ "Owner", "Default", @@ -333,7 +414,8 @@ "LSItemContentTypes", "LSHandlerRank" ], - "additionalProperties": false + "additionalProperties": false, + "markdownDescription": "Describes a document type associated with the app." }, "UTTypeDeclarationModel": { "title": "UTTypeDeclarationModel", @@ -341,6 +423,8 @@ "properties": { "UTTypeConformsTo": { "title": "Uttypeconformsto", + "description": "The Uniform Type Identifier types that this type conforms to.", + "markdownDescription": "The Uniform Type Identifier types that this type conforms to.", "type": "array", "items": { "type": "string" @@ -348,22 +432,32 @@ }, "UTTypeDescription": { "title": "Uttypedescription", + "description": "A description for this type.", + "markdownDescription": "A description for this type.", "type": "string" }, "UTTypeIconFile": { "title": "Uttypeiconfile", + "description": "The bundle icon resource to associate with this type.", + "markdownDescription": "The bundle icon resource to associate with this type.", "type": "string" }, "UTTypeIdentifier": { "title": "Uttypeidentifier", + "description": "The Uniform Type Identifier to assign to this type.", + "markdownDescription": "The Uniform Type Identifier to assign to this type.", "type": "string" }, "UTTypeReferenceURL": { "title": "Uttypereferenceurl", + "description": "The webpage for a reference document that describes this type.", + "markdownDescription": "The webpage for a reference document that describes this type.", "type": "string" }, "UTTypeTagSpecification": { "title": "Uttypetagspecification", + "description": "A dictionary defining one or more equivalent type identifiers.", + "markdownDescription": "A dictionary defining one or more equivalent type identifiers.", "type": "object", "additionalProperties": { "type": "array", @@ -382,11 +476,13 @@ }, "MacOS": { "title": "MacOS", - "description": "Mac-specific instructions. Check these URLs for more info:\n\n- ``CF*`` keys: see `Core Foundation Keys `__\n- ``LS*`` keys: see `Launch Services Keys `__\n- ``entitlements``: see `Entitlements documentation `__", + "description": "Mac-specific instructions. Check these URLs for more info:\n\n- `CF*` keys: see [Core Foundation Keys](https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html) - `LS*` keys: see [Launch Services Keys](https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/LaunchServicesKeys.html) - `entitlements`: see [Entitlements documentation](https://developer.apple.com/documentation/bundleresources/entitlements)", "type": "object", "properties": { "name": { "title": "Name", + "description": "The name of the menu item. Can be a dictionary if the name depends on installation parameters. See `MenuItemNameDict` for details.", + "markdownDescription": "The name of the menu item. Can be a dictionary if the name depends on installation parameters. See `MenuItemNameDict` for details.", "anyOf": [ { "type": "string", @@ -399,15 +495,21 @@ }, "description": { "title": "Description", + "description": "A longer description of the menu item. Shown on popup messages.", + "markdownDescription": "A longer description of the menu item. Shown on popup messages.", "type": "string" }, "icon": { "title": "Icon", + "description": "Path to the file representing or containing the icon.", + "markdownDescription": "Path to the file representing or containing the icon.", "minLength": 1, "type": "string" }, "command": { "title": "Command", + "description": "Command to run with the menu item, expressed as a list of strings where each string is an argument.", + "markdownDescription": "Command to run with the menu item, expressed as a list of strings where each string is an argument.", "minItems": 1, "type": "array", "items": { @@ -416,52 +518,74 @@ }, "working_dir": { "title": "Working Dir", + "description": "Working directory for the running process. Defaults to user directory on each platform.", + "markdownDescription": "Working directory for the running process. Defaults to user directory on each platform.", "minLength": 1, "type": "string" }, "precommand": { "title": "Precommand", + "description": "(Simple, preferrably single-line) logic to run before the command is run. Runs before the environment is activated, if that applies.", + "markdownDescription": "(Simple, preferrably single-line) logic to run before the command is run. Runs before the environment is activated, if that applies.", "minLength": 1, "type": "string" }, "precreate": { "title": "Precreate", + "description": "(Simple, preferrably single-line) logic to run before the shortcut is created.", + "markdownDescription": "(Simple, preferrably single-line) logic to run before the shortcut is created.", "minLength": 1, "type": "string" }, "activate": { "title": "Activate", + "description": "Whether to activate the target environment before running `command`.", + "markdownDescription": "Whether to activate the target environment before running `command`.", "type": "boolean" }, "terminal": { "title": "Terminal", + "description": "Whether run the program in a terminal/console or not. On Windows, it only has an effect if `activate` is true. On MacOS, the application will ignore command-line arguments.", + "markdownDescription": "Whether run the program in a terminal/console or not. On Windows, it only has an effect if `activate` is true. On MacOS, the application will ignore command-line arguments.", "type": "boolean" }, "CFBundleDisplayName": { "title": "Cfbundledisplayname", + "description": "Display name of the bundle, visible to users and used by Siri. If not provided, 'menuinst' will use the 'name' field.", + "markdownDescription": "Display name of the bundle, visible to users and used by Siri. If not provided, 'menuinst' will use the 'name' field.", "type": "string" }, "CFBundleIdentifier": { "title": "Cfbundleidentifier", + "description": "Unique identifier for the shortcut. Typically uses a reverse-DNS format. If not provided, 'menuinst' will generate one from the 'name' field.", + "markdownDescription": "Unique identifier for the shortcut. Typically uses a reverse-DNS format. If not provided, 'menuinst' will generate one from the 'name' field.", "pattern": "^[A-z0-9\\-\\.]+$", "type": "string" }, "CFBundleName": { "title": "Cfbundlename", + "description": "Short name of the bundle. May be used if `CFBundleDisplayName` is absent. If not provided, 'menuinst' will generate one from the 'name' field.", + "markdownDescription": "Short name of the bundle. May be used if `CFBundleDisplayName` is absent. If not provided, 'menuinst' will generate one from the 'name' field.", "maxLength": 16, "type": "string" }, "CFBundleSpokenName": { "title": "Cfbundlespokenname", + "description": "Suitable replacement for text-to-speech operations on the app. For example, 'my app one two three' instead of 'MyApp123'.", + "markdownDescription": "Suitable replacement for text-to-speech operations on the app. For example, 'my app one two three' instead of 'MyApp123'.", "type": "string" }, "CFBundleVersion": { "title": "Cfbundleversion", + "description": "Build version number for the bundle. In the context of 'menuinst' this can be used to signal a new version of the menu item for the same application version.", + "markdownDescription": "Build version number for the bundle. In the context of 'menuinst' this can be used to signal a new version of the menu item for the same application version.", "pattern": "^\\S+$", "type": "string" }, "CFBundleURLTypes": { "title": "Cfbundleurltypes", + "description": "URL types supported by this app. Requires setting `event_handler` too. Note this feature requires macOS 10.14.4 or above.", + "markdownDescription": "URL types supported by this app. Requires setting `event_handler` too. Note this feature requires macOS 10.14.4 or above.", "type": "array", "items": { "$ref": "#/definitions/CFBundleURLTypesModel" @@ -469,6 +593,8 @@ }, "CFBundleDocumentTypes": { "title": "Cfbundledocumenttypes", + "description": "Document types supported by this app. Requires setting `event_handler` too. Requires macOS 10.14.4 or above.", + "markdownDescription": "Document types supported by this app. Requires setting `event_handler` too. Requires macOS 10.14.4 or above.", "type": "array", "items": { "$ref": "#/definitions/CFBundleDocumentTypesModel" @@ -476,15 +602,21 @@ }, "LSApplicationCategoryType": { "title": "Lsapplicationcategorytype", + "description": "The App Store uses this string to determine the appropriate categorization.", + "markdownDescription": "The App Store uses this string to determine the appropriate categorization.", "pattern": "^public\\.app-category\\.\\S+$", "type": "string" }, "LSBackgroundOnly": { "title": "Lsbackgroundonly", + "description": "Specifies whether this app runs only in the background.", + "markdownDescription": "Specifies whether this app runs only in the background.", "type": "boolean" }, "LSEnvironment": { "title": "Lsenvironment", + "description": "List of key-value pairs used to define environment variables.", + "markdownDescription": "List of key-value pairs used to define environment variables.", "type": "object", "additionalProperties": { "type": "string" @@ -492,23 +624,33 @@ }, "LSMinimumSystemVersion": { "title": "Lsminimumsystemversion", + "description": "Minimum version of macOS required for this app to run, as `x.y.z`. For example, for macOS v10.4 and later, use `10.4.0`.", + "markdownDescription": "Minimum version of macOS required for this app to run, as `x.y.z`. For example, for macOS v10.4 and later, use `10.4.0`.", "pattern": "^\\d+\\.\\d+\\.\\d+$", "type": "string" }, "LSMultipleInstancesProhibited": { "title": "Lsmultipleinstancesprohibited", + "description": "Whether an app is prohibited from running simultaneously in multiple user sessions.", + "markdownDescription": "Whether an app is prohibited from running simultaneously in multiple user sessions.", "type": "boolean" }, "LSRequiresNativeExecution": { "title": "Lsrequiresnativeexecution", + "description": "If true, prevent a universal binary from being run under Rosetta emulation on an Intel-based Mac.", + "markdownDescription": "If true, prevent a universal binary from being run under Rosetta emulation on an Intel-based Mac.", "type": "boolean" }, "NSSupportsAutomaticGraphicsSwitching": { "title": "Nssupportsautomaticgraphicsswitching", + "description": "If true, allows an OpenGL app to utilize the integrated GPU.", + "markdownDescription": "If true, allows an OpenGL app to utilize the integrated GPU.", "type": "boolean" }, "UTExportedTypeDeclarations": { "title": "Utexportedtypedeclarations", + "description": "The uniform type identifiers owned and exported by the app.", + "markdownDescription": "The uniform type identifiers owned and exported by the app.", "type": "array", "items": { "$ref": "#/definitions/UTTypeDeclarationModel" @@ -516,6 +658,8 @@ }, "UTImportedTypeDeclarations": { "title": "Utimportedtypedeclarations", + "description": "The uniform type identifiers inherently supported, but not owned, by the app.", + "markdownDescription": "The uniform type identifiers inherently supported, but not owned, by the app.", "type": "array", "items": { "$ref": "#/definitions/UTTypeDeclarationModel" @@ -523,6 +667,8 @@ }, "entitlements": { "title": "Entitlements", + "description": "List of permissions to request for the launched application. See [the entitlements docs]( https://developer.apple.com/documentation/bundleresources/entitlements) for a full list of possible values.", + "markdownDescription": "List of permissions to request for the launched application. See [the entitlements docs]( https://developer.apple.com/documentation/bundleresources/entitlements) for a full list of possible values.", "type": "array", "items": { "type": "string", @@ -531,6 +677,8 @@ }, "link_in_bundle": { "title": "Link In Bundle", + "description": "Paths that should be symlinked into the shortcut app bundle. It takes a mapping of source to destination paths. Destination paths must be relative. Placeholder `{{ MENU_ITEM_LOCATION }}` can be useful.", + "markdownDescription": "Paths that should be symlinked into the shortcut app bundle. It takes a mapping of source to destination paths. Destination paths must be relative. Placeholder `{{ MENU_ITEM_LOCATION }}` can be useful.", "type": "object", "additionalProperties": { "type": "string", @@ -539,11 +687,14 @@ }, "event_handler": { "title": "Event Handler", + "description": "Required shell script logic to handle opened URL payloads. Note this feature requires macOS 10.14.4 or above.", + "markdownDescription": "Required shell script logic to handle opened URL payloads. Note this feature requires macOS 10.14.4 or above.", "minLength": 1, "type": "string" } }, - "additionalProperties": false + "additionalProperties": false, + "markdownDescription": "Mac-specific instructions. Check these URLs for more info:\n\n- `CF*` keys: see [Core Foundation Keys](https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html) - `LS*` keys: see [Launch Services Keys](https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/LaunchServicesKeys.html) - `entitlements`: see [Entitlements documentation](https://developer.apple.com/documentation/bundleresources/entitlements)" }, "Windows": { "title": "Windows", @@ -552,6 +703,8 @@ "properties": { "name": { "title": "Name", + "description": "The name of the menu item. Can be a dictionary if the name depends on installation parameters. See `MenuItemNameDict` for details.", + "markdownDescription": "The name of the menu item. Can be a dictionary if the name depends on installation parameters. See `MenuItemNameDict` for details.", "anyOf": [ { "type": "string", @@ -564,15 +717,21 @@ }, "description": { "title": "Description", + "description": "A longer description of the menu item. Shown on popup messages.", + "markdownDescription": "A longer description of the menu item. Shown on popup messages.", "type": "string" }, "icon": { "title": "Icon", + "description": "Path to the file representing or containing the icon.", + "markdownDescription": "Path to the file representing or containing the icon.", "minLength": 1, "type": "string" }, "command": { "title": "Command", + "description": "Command to run with the menu item, expressed as a list of strings where each string is an argument.", + "markdownDescription": "Command to run with the menu item, expressed as a list of strings where each string is an argument.", "minItems": 1, "type": "array", "items": { @@ -581,44 +740,63 @@ }, "working_dir": { "title": "Working Dir", + "description": "Working directory for the running process. Defaults to user directory on each platform.", + "markdownDescription": "Working directory for the running process. Defaults to user directory on each platform.", "minLength": 1, "type": "string" }, "precommand": { "title": "Precommand", + "description": "(Simple, preferrably single-line) logic to run before the command is run. Runs before the environment is activated, if that applies.", + "markdownDescription": "(Simple, preferrably single-line) logic to run before the command is run. Runs before the environment is activated, if that applies.", "minLength": 1, "type": "string" }, "precreate": { "title": "Precreate", + "description": "(Simple, preferrably single-line) logic to run before the shortcut is created.", + "markdownDescription": "(Simple, preferrably single-line) logic to run before the shortcut is created.", "minLength": 1, "type": "string" }, "activate": { "title": "Activate", + "description": "Whether to activate the target environment before running `command`.", + "markdownDescription": "Whether to activate the target environment before running `command`.", "type": "boolean" }, "terminal": { "title": "Terminal", + "description": "Whether run the program in a terminal/console or not. On Windows, it only has an effect if `activate` is true. On MacOS, the application will ignore command-line arguments.", + "markdownDescription": "Whether run the program in a terminal/console or not. On Windows, it only has an effect if `activate` is true. On MacOS, the application will ignore command-line arguments.", "type": "boolean" }, "desktop": { "title": "Desktop", + "description": "Whether to create a desktop icon in addition to the Start Menu item.", "default": true, + "markdownDescription": "Whether to create a desktop icon in addition to the Start Menu item.", "type": "boolean" }, "quicklaunch": { "title": "Quicklaunch", + "description": "DEPRECATED. Whether to create a quick launch icon in addition to the Start Menu item.", "default": false, + "deprecated": true, + "markdownDescription": "DEPRECATED. Whether to create a quick launch icon in addition to the Start Menu item.", "type": "boolean" }, "terminal_profile": { "title": "Terminal Profile", + "description": "Name of the Windows Terminal profile to create. This name must be unique across multiple installations because menuinst will overwrite Terminal profiles with the same name.", + "markdownDescription": "Name of the Windows Terminal profile to create. This name must be unique across multiple installations because menuinst will overwrite Terminal profiles with the same name.", "minLength": 1, "type": "string" }, "url_protocols": { "title": "Url Protocols", + "description": "URL protocols that will be associated with this program.", + "markdownDescription": "URL protocols that will be associated with this program.", "type": "array", "items": { "type": "string", @@ -627,6 +805,8 @@ }, "file_extensions": { "title": "File Extensions", + "description": "File extensions that will be associated with this program.", + "markdownDescription": "File extensions that will be associated with this program.", "type": "array", "items": { "type": "string", @@ -635,29 +815,54 @@ }, "app_user_model_id": { "title": "App User Model Id", + "description": "Identifier used in Windows 7 and above to associate processes, files and windows with a particular application. If your shortcut produces duplicated icons, you need to define this field. If not set, it will default to `Menuinst.`.\n\nSee [AppUserModelID docs]( https://learn.microsoft.com/en-us/windows/win32/shell/appids#how-to-form-an-application-defined-appusermodelid) for more information on the required string format.", + "markdownDescription": "Identifier used in Windows 7 and above to associate processes, files and windows with a particular application. If your shortcut produces duplicated icons, you need to define this field. If not set, it will default to `Menuinst.`.\n\nSee [AppUserModelID docs]( https://learn.microsoft.com/en-us/windows/win32/shell/appids#how-to-form-an-application-defined-appusermodelid) for more information on the required string format.", "maxLength": 128, "pattern": "\\S+\\.\\S+", "type": "string" } }, - "additionalProperties": false + "additionalProperties": false, + "markdownDescription": "Windows-specific instructions. You can override global keys here if needed" }, "Platforms": { "title": "Platforms", - "description": "Platform specific options.\n\nNote each of these fields supports the same keys as the top-level :class:`MenuItem`\n(sans ``platforms`` itself), in case overrides are needed.", + "description": "Platform specific options.\n\nNote each of these fields supports the same keys as the top-level `MenuItem` (sans `platforms` itself), in case overrides are needed.", "type": "object", "properties": { "linux": { - "$ref": "#/definitions/Linux" + "title": "Linux", + "description": "Options for Linux. See `Linux` model for details.", + "markdownDescription": "Options for Linux. See `Linux` model for details.", + "allOf": [ + { + "$ref": "#/definitions/Linux" + } + ] }, "osx": { - "$ref": "#/definitions/MacOS" + "title": "Osx", + "description": "Options for macOS. See `MacOS` model for details.", + "markdownDescription": "Options for macOS. See `MacOS` model for details.", + "allOf": [ + { + "$ref": "#/definitions/MacOS" + } + ] }, "win": { - "$ref": "#/definitions/Windows" + "title": "Win", + "description": "Options for Windows. See `Windows` model for details.", + "markdownDescription": "Options for Windows. See `Windows` model for details.", + "allOf": [ + { + "$ref": "#/definitions/Windows" + } + ] } }, - "additionalProperties": false + "additionalProperties": false, + "markdownDescription": "Platform specific options.\n\nNote each of these fields supports the same keys as the top-level `MenuItem` (sans `platforms` itself), in case overrides are needed." }, "MenuItem": { "title": "MenuItem", @@ -666,6 +871,8 @@ "properties": { "name": { "title": "Name", + "description": "The name of the menu item. Can be a dictionary if the name depends on installation parameters. See `MenuItemNameDict` for details.", + "markdownDescription": "The name of the menu item. Can be a dictionary if the name depends on installation parameters. See `MenuItemNameDict` for details.", "anyOf": [ { "type": "string", @@ -678,10 +885,14 @@ }, "description": { "title": "Description", + "description": "A longer description of the menu item. Shown on popup messages.", + "markdownDescription": "A longer description of the menu item. Shown on popup messages.", "type": "string" }, "command": { "title": "Command", + "description": "Command to run with the menu item, expressed as a list of strings where each string is an argument.", + "markdownDescription": "Command to run with the menu item, expressed as a list of strings where each string is an argument.", "minItems": 1, "type": "array", "items": { @@ -690,36 +901,55 @@ }, "icon": { "title": "Icon", + "description": "Path to the file representing or containing the icon.", + "markdownDescription": "Path to the file representing or containing the icon.", "minLength": 1, "type": "string" }, "precommand": { "title": "Precommand", + "description": "(Simple, preferrably single-line) logic to run before the command is run. Runs before the environment is activated, if that applies.", + "markdownDescription": "(Simple, preferrably single-line) logic to run before the command is run. Runs before the environment is activated, if that applies.", "minLength": 1, "type": "string" }, "precreate": { "title": "Precreate", + "description": "(Simple, preferrably single-line) logic to run before the shortcut is created.", + "markdownDescription": "(Simple, preferrably single-line) logic to run before the shortcut is created.", "minLength": 1, "type": "string" }, "working_dir": { "title": "Working Dir", + "description": "Working directory for the running process. Defaults to user directory on each platform.", + "markdownDescription": "Working directory for the running process. Defaults to user directory on each platform.", "minLength": 1, "type": "string" }, "activate": { "title": "Activate", + "description": "Whether to activate the target environment before running `command`.", "default": true, + "markdownDescription": "Whether to activate the target environment before running `command`.", "type": "boolean" }, "terminal": { "title": "Terminal", + "description": "Whether run the program in a terminal/console or not. On Windows, it only has an effect if `activate` is true. On MacOS, the application will ignore command-line arguments.", "default": false, + "markdownDescription": "Whether run the program in a terminal/console or not. On Windows, it only has an effect if `activate` is true. On MacOS, the application will ignore command-line arguments.", "type": "boolean" }, "platforms": { - "$ref": "#/definitions/Platforms" + "title": "Platforms", + "description": "Platform-specific options. Presence of a platform field enables menu items in that platform.", + "markdownDescription": "Platform-specific options. Presence of a platform field enables menu items in that platform.", + "allOf": [ + { + "$ref": "#/definitions/Platforms" + } + ] } }, "required": [ @@ -728,7 +958,8 @@ "command", "platforms" ], - "additionalProperties": false + "additionalProperties": false, + "markdownDescription": "Instructions to create a menu item across operating systems." } } } From 5200cfcafda359b08c0a146527b5e06f0e140ec3 Mon Sep 17 00:00:00 2001 From: jaimergp Date: Fri, 13 Dec 2024 21:07:22 +0100 Subject: [PATCH 7/8] Update menuinst-1.schema.json Co-authored-by: Marco Esters --- menuinst/data/menuinst-1.schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/menuinst/data/menuinst-1.schema.json b/menuinst/data/menuinst-1.schema.json index 7e7e8f09..4f07091e 100644 --- a/menuinst/data/menuinst-1.schema.json +++ b/menuinst/data/menuinst-1.schema.json @@ -8,7 +8,7 @@ "description": "DEPRECATED. Use ``$schema``.", "default": "https://schemas.conda.org/menuinst-1.schema.json", "deprecated": true, - "markdownDescription": "DEPRECATED. Use ``$schema``.", + "markdownDescription": "DEPRECATED. Use `$schema`.", "minLength": 1, "type": "string" }, From 6102317c18ebf0420b2a72a9733c7a552cfe2ca7 Mon Sep 17 00:00:00 2001 From: jaimergp Date: Fri, 13 Dec 2024 21:08:45 +0100 Subject: [PATCH 8/8] regenerate again --- menuinst/data/menuinst-1.schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/menuinst/data/menuinst-1.schema.json b/menuinst/data/menuinst-1.schema.json index 4f07091e..7e7e8f09 100644 --- a/menuinst/data/menuinst-1.schema.json +++ b/menuinst/data/menuinst-1.schema.json @@ -8,7 +8,7 @@ "description": "DEPRECATED. Use ``$schema``.", "default": "https://schemas.conda.org/menuinst-1.schema.json", "deprecated": true, - "markdownDescription": "DEPRECATED. Use `$schema`.", + "markdownDescription": "DEPRECATED. Use ``$schema``.", "minLength": 1, "type": "string" },