Proposal: Modernized JSON-based Manifest (module.json) for IPM #1035
Replies: 3 comments 1 reply
-
|
To ensure the new 1. Stage 1: JSON Class Object (via
2. Stage 2: Class Object Raw XML Stream (via
It provides
By using the Class Object as an intermediary, this architecture is format-agnostic. |
Beta Was this translation helpful? Give feedback.
-
|
When using the 1. The Parameter Value Constraint (Strings Only)we must represent numeric and boolean values as strings (e.g., The limitation exists because of how the When you define 2. The Resource Structure Constraint (Objects Only)
While slightly less concise, this provides a future-proof schema. It allows for easy expansion (adding {"$schema":"http://json-schema.org/draft-07/schema#","title":"IPM Module Manifest","type":"object","required":["name","version"],"properties":{"name":{"type":"string","description":"The unique name of the module"},"description":{"type":"string"},"version":{"type":"string","pattern":"^[0-9]+\\.[0-9]+\\.[0-9]+(-.*)?$"},"packaging":{"type":"string","default":"module"},"keywords":{"type":"array","items":{"type":"string"}},"dependencies":{"type":"object","additionalProperties":{"type":"string"},"description":"Map of module names to versions. Note: Versions must be strings."},"parameters":{"type":"object","additionalProperties":{"type":"string"},"description":"Key-Value pairs for variables. Values MUST be strings due to IRIS constraints."},"resources":{"type":"array","items":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"directory":{"type":"string"},"scope":{"type":"string"},"deploy":{"type":"boolean"}}}},"tests":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"package":{"type":"string"},"phase":{"type":"string"}}}},"fileCopies":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"target":{"type":"string"}}}},"invoke":{"type":"array","items":{"type":"object","required":["class","method"],"properties":{"class":{"type":"string"},"method":{"type":"string"},"phase":{"type":"string"},"when":{"type":"string"},"checkStatus":{"type":"boolean"},"args":{"type":"array","items":{"type":"string"}}}}},"afterInstallMessage":{"type":"string"}}}module.json {"name":"demo-module1","description":"creating json schema","keywords":["cos","testing","interoperaibility"],"version":"1.0.0","resources":[{"name":"Demo.PKG"},{"name":"REST.Dispatch.CLS"},{"name":"Myapp.MAC","directory":"newmac"}],"tests":[{"name":"/tests/unit_tests/","package":"Test.Unit","phase":"test"}],"fileCopies":[{"name":"lib/","target":"${libdir}my-lib/"}],"invoke":[{"class":"Demo.First","method":"Populate","args":["${count}","test string"]},{"class":"%EnsembleMgr","method":"EnableNamespace","when":"Before","checkStatus":true,"args":["${namespace}","${verbose}"]}],"dependencies":{"MDX2JSON":"1.0.2","objectscript-math":"1.0.2"},"parameters":{"count":"1","ipm":"${ipm}"},"packaging":"module","afterInstallMessage":"Module installed successfully! To start call USER>Do ##class(Package.Class).Run()"} |
Beta Was this translation helpful? Give feedback.
-
|
@AshokThangavel Thanks for taking an initial stab at this! For the most part, it looks great. Some initial thoughts:
|
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Following the conversation in module.json I am moving the proposal for a schema-backed JSON manifest here for deeper feedback.
I am moving the proposal for a schema-backed JSON manifest here. This design focuses on a "Fresh Start" approach to improve developer experience (DX) and ensure system stability within the InterSystems Package Manager ecosystem.
Proposed Workflow: Class-based Transpilation Layer
To handle this transition, I propose a design centered around a Class-based Transpilation Layer. This approach delivers the "fresh start" for the manifest structure while ensuring zero-breakage backward compatibility.
%IPM.Manifest.JSON.Module) that mirror roughly 80% of the property structure from the existing%IPM.Storage.Moduleand inherit from%JSON.Adaptor.module.xml. If absent, it will fall back tomodule.json.module.jsonremains the Physical SOT on disk for the developer. The mapped metadata becomes the Logical SOT persisted within the IPM database classes. This ensures all existing downstream tools—which expect specific metadata—continue to work without modification.1. Key Improvements
resources,tests,fileCopies, andwebApplications(formerly CSPApplications) for precise IDE IntelliSense and validation.ERROR #6315.2. Sample Manifest
{ "$schema": "./module.schema.json", "name": "demo-module1", "version": "1.0.0", "dependencies": { "MDX2JSON": "1.0.2", "objectscript-math": "1.0.2" }, "resources": ["Demo.PKG", { "name": "Myapp.MAC", "directory": "newmac" }], "tests": [ { "name": "/tests/unit_tests/", "package": "Test.Unit", "phase": "test" } ], "WebApplications": [ { "url": "/rest-test", "dispatchClass": "REST.Dispatch", "auth": { "password": true } } ] }3. Full JSON Schema (Draft-7)
{ "$schema": "http://json-schema.org/draft-07/schema#", "$id": "https://intersystems.com/ipm/module.schema.json", "title": "IPM Module Manifest", "type": "object", "required": [ "name", "version" ], "properties": { "name": { "type": "string", "description": "The unique name of the module" }, "version": { "type": "string", "description": "Semantic version (e.g., 1.0.0)" }, "description": { "type": "string" }, "keywords": { "type": "array", "items": { "type": "string" } }, "pythonWheel": { "type": "array", "items": { "type": "string" } }, "author": { "type": "object", "properties": { "person": { "type": "string" }, "organization": { "type": "string" }, "copyright": { "type": "integer" }, "license": { "type": "string" }, "notes": { "type": "string" } } }, "dependencies": { "type": "object", "description": "Map of module names to their versions. Version is REQUIRED.", "additionalProperties": { "type": "string", "minLength": 1, "pattern": "^[0-9*>=<].*$", "description": "Version string (e.g., '1.0.2', '>=2.0.0', or '*')" } }, "parameters": { "type": "object", "additionalProperties": { "type": [ "string", "number", "boolean" ] } }, "systemRequirements": { "type": "object", "properties": { "version": { "type": "string" }, "interoperability": { "type": "boolean" } } }, "resources": { "type": "array", "items": { "oneOf": [ { "type": "string", "description": "Full resource name (e.g. My.Class.CLS)" }, { "type": "object", "required": [ "name" ], "properties": { "name": { "type": "string" }, "directory": { "type": "string" } } } ] } }, "tests": { "type": "array", "items": { "type": "object", "required": [ "name", "package" ], "properties": { "name": { "type": "string" }, "package": { "type": "string" }, "phase": { "type": "string", "default": "test" } } } }, "fileCopies": { "type": "array", "items": { "type": "object", "required": [ "name", "target" ], "properties": { "name": { "type": "string" }, "target": { "type": "string" } } } }, "invoke": { "type": "array", "items": { "type": "object", "required": [ "class", "method" ], "properties": { "class": { "type": "string" }, "method": { "type": "string" }, "args": { "type": "array", "items": { "type": "string" } }, "phase": { "type": "string" }, "when": { "type": "string", "enum": [ "Before", "After" ] }, "checkStatus": { "type": "boolean" } } } }, "WebApplications": { "type": "array", "items": { "type": "object", "required": [ "url" ], "properties": { "url": { "type": "string" }, "dispatchClass": { "type": "string" }, "sourcePath": { "type": "string" }, "deployPath": { "type": "string" }, "auth": { "type": "object", "properties": { "password": { "type": "boolean" }, "unauthenticated": { "type": "boolean" } } } } } }, "systemSettings": { "type": "object", "additionalProperties": { "type": "string" } }, "afterInstallMessage": { "type": "string" } } }{ "name": "demo-module1", "version": "1.0.0", "description": "creating json schema", "keywords": [ "cos", "testing", "interoperaibility" ], "pythonWheel": [ "cryptography-46.0.2-cp311-abi3-manylinux_2_34_aarch64.whl" ], "author": { "person": "your name", "organization": "your organization", "copyright": 2020, "license": "MIT", "notes": "notes" }, "dependencies": { "MDX2JSON": "1.0.2", "objectscript-math": "1.0.2" }, "parameters": { "count": 1, "ipm": "${ipm}" }, "systemRequirements": { "version": ">2021.2", "interoperability": true }, "resources": [ "Demo.PKG", "REST.Dispatch.CLS", { "name": "Myapp.MAC", "directory": "newmac" } ], "tests": [ { "name": "/tests/unit_tests/", "package": "Test.Unit", "phase": "test" } ], "fileCopies": [ { "name": "lib/", "target": "${libdir}my-lib/" } ], "invoke": [ { "class": "Demo.First", "method": "Populate", "args": [ "${count}", "test string" ] }, { "class": "%EnsembleMgr", "method": "EnableNamespace", "phase": "Compile", "when": "Before", "checkStatus": true, "args": [ "${namespace}", "${verbose}" ] } ], "webApplications": [ { "url": "/hello", "sourcePath": "/src/csp", "deployPath": "${cspdir}rest-test", "serveFiles": true, "recurse": true, "matchRoles": ":${dbrole}", "auth": { "password": true, "unauthenticated": false } }, { "url": "/rest-test", "dispatchClass": "REST.Dispatch", "useCookies": "2", "recurse": true } ], "systemSettings": { "CSP.DefaultFileCharset": "UTF-8" }, "afterInstallMessage": "Module installed successfully! To start call USER>Do ##class(Package.Class).Run()" }Beta Was this translation helpful? Give feedback.
All reactions