diff --git a/api/csolution-openapi.yml b/api/csolution-openapi.yml index 7fe2628..4d71dd7 100644 --- a/api/csolution-openapi.yml +++ b/api/csolution-openapi.yml @@ -1,7 +1,7 @@ openapi: 3.1.0 info: title: csolution rpc - version: 0.0.1 + version: 0.0.2 description: Specification of remote procedure call methods for CMSIS csolution integration license: name: Apache 2.0 @@ -43,6 +43,17 @@ paths: '200': description: OK content: {application/json: {schema: {$ref: '#/components/schemas/ApplyResponse'}}} + /rpc/Resolve: + post: + summary: Resolve trivial component dependencies + description: Resolve trivial component dependencies for the given context + tags: [/rpc] + requestBody: + content: {application/json: {schema: {$ref: '#/components/schemas/ResolveRequest'}}} + responses: + '200': + description: OK + content: {application/json: {schema: {$ref: '#/components/schemas/ResolveResponse'}}} /rpc/LoadPacks: post: summary: Load installed and local packs @@ -120,17 +131,6 @@ paths: '200': description: OK content: {application/json: {schema: {$ref: '#/components/schemas/SelectVariantResponse'}}} - /rpc/SelectVersion: - post: - summary: Select version - description: Select version - tags: [/rpc] - requestBody: - content: {application/json: {schema: {$ref: '#/components/schemas/SelectVersionRequest'}}} - responses: - '200': - description: OK - content: {application/json: {schema: {$ref: '#/components/schemas/SelectVersionResponse'}}} /rpc/SelectBundle: post: summary: Select bundle @@ -167,6 +167,17 @@ paths: components: schemas: + SuccessResult: + type: object + properties: + success: + type: boolean + description: true if requested operation has been performed successfully or selection has been modified + message: + type: string + description: optional error/warning/info message + required: + - success Common: type: object properties: @@ -197,15 +208,16 @@ components: items: type: string PacksInfo: - type: object - properties: - packs: - type: array - description: List of packs information - items: - $ref: '#/components/schemas/Pack' - required: - - packs + allOf: + - $ref: '#/components/schemas/SuccessResult' + - properties: + packs: + type: array + description: List of packs information + items: + $ref: '#/components/schemas/Pack' + required: + - packs Component: allOf: - $ref: '#/components/schemas/Common' @@ -221,14 +233,18 @@ components: description: Maximum of supported component instances required: - pack - CtItem: + Options: type: object properties: - name: + layer: type: string - description: Name of element - required: - - name + description: Absolute path to .clayer.yml file + explicitVersion: + type: string + description: 'Version requirement in SemVer syntax: https://open-cmsis-pack.github.io/cmsis-toolbox/YML-Input-Format/#name-conventions empty ' + explicitVendor: + type: boolean + description: Flag to prefix component ID with vendor when adding component to project or layer, false ComponentInstance: type: object properties: @@ -238,14 +254,30 @@ components: selectedCount: type: integer description: Number of selected instances + generator: + type: string + description: Associated generator name + fixed: + type: boolean + description: Component cannot be unselected + options: + $ref: '#/components/schemas/Options' resolvedComponent: $ref: '#/components/schemas/Component' - layer: - type: string - description: Layer required: - id - selectedCount + CtItem: + type: object + properties: + name: + type: string + description: Name of element + result: + type: string + description: 'Condition result: https://github.com/Open-CMSIS-Pack/devtools/blob/tools/projmgr/2.8.0/libs/rtemodel/include/RteItem.h#L78-L95' + required: + - name CtVariant: allOf: - $ref: '#/components/schemas/CtItem' @@ -275,13 +307,18 @@ components: selectedCount: type: integer description: Number of selected instances + generator: + type: string + description: Associated generator name + fixed: + type: boolean + description: Component cannot be unselected variants: type: array items: $ref: '#/components/schemas/CtVariant' - layer: - type: string - description: Layer + options: + $ref: '#/components/schemas/Options' required: - id - variants @@ -342,16 +379,16 @@ components: required: - bundles CtRoot: - type: object - description: Root of Component Tree - properties: - classes: - type: array - description: Array of Component Classes - items: - $ref: '#/components/schemas/CtClass' - required: - - classes + allOf: + - $ref: '#/components/schemas/SuccessResult' + - properties: + classes: + type: array + description: Array of Component Classes + items: + $ref: '#/components/schemas/CtClass' + required: + - classes Condition: type: object properties: @@ -388,41 +425,50 @@ components: - id - result Results: - type: object - properties: - validation: - type: array - items: - $ref: '#/components/schemas/Result' + allOf: + - $ref: '#/components/schemas/SuccessResult' + - properties: + result: + type: string + description: 'Condition result: https://github.com/Open-CMSIS-Pack/devtools/blob/tools/projmgr/2.8.0/libs/rtemodel/include/RteItem.h#L78-L95' + validation: + type: array + items: + $ref: '#/components/schemas/Result' + required: + - result UsedItems: - type: object - properties: - components: - type: array - items: - $ref: '#/components/schemas/ComponentInstance' - packs: - type: array - items: - $ref: '#/components/schemas/Pack' - required: - - components - - packs + allOf: + - $ref: '#/components/schemas/SuccessResult' + - properties: + components: + type: array + items: + $ref: '#/components/schemas/ComponentInstance' + packs: + type: array + items: + $ref: '#/components/schemas/Pack' + required: + - components + - packs + LogMessages: - type: object - properties: - info: - type: array - items: - type: string - errors: - type: array - items: - type: string - warnings: - type: array - items: - type: string + allOf: + - $ref: '#/components/schemas/SuccessResult' + - properties: + info: + type: array + items: + type: string + errors: + type: array + items: + type: string + warnings: + type: array + items: + type: string GetVersionRequest: allOf: @@ -431,12 +477,20 @@ components: method: type: string const: GetVersion + + GetVersionResult: + allOf: + - $ref: '#/components/schemas/SuccessResult' + - properties: + version: + type: string + description: Tool version GetVersionResponse: allOf: - $ref: '#/x-jsonrpc-envelope-response' - properties: result: - type: string + $ref: '#/components/schemas/GetVersionResult' ShutdownRequest: allOf: - $ref: '#/x-jsonrpc-envelope-request' @@ -449,7 +503,7 @@ components: - $ref: '#/x-jsonrpc-envelope-response' - properties: result: - type: boolean + $ref: '#/components/schemas/SuccessResult' ApplyRequest: allOf: - $ref: '#/x-jsonrpc-envelope-request-with-params' @@ -469,7 +523,27 @@ components: - $ref: '#/x-jsonrpc-envelope-response' - properties: result: - type: boolean + $ref: '#/components/schemas/SuccessResult' + ResolveRequest: + allOf: + - $ref: '#/x-jsonrpc-envelope-request-with-params' + - properties: + method: + type: string + const: Resolve + params: + type: object + properties: + context: + type: string + required: + - context + ResolveResponse: + allOf: + - $ref: '#/x-jsonrpc-envelope-response' + - properties: + result: + $ref: '#/components/schemas/SuccessResult' LoadPacksRequest: allOf: - $ref: '#/x-jsonrpc-envelope-request' @@ -482,7 +556,7 @@ components: - $ref: '#/x-jsonrpc-envelope-response' - properties: result: - type: boolean + $ref: '#/components/schemas/SuccessResult' LoadSolutionRequest: allOf: - $ref: '#/x-jsonrpc-envelope-request-with-params' @@ -502,7 +576,7 @@ components: - $ref: '#/x-jsonrpc-envelope-response' - properties: result: - type: boolean + $ref: '#/components/schemas/SuccessResult' GetPacksInfoRequest: allOf: - $ref: '#/x-jsonrpc-envelope-request-with-params' @@ -580,18 +654,23 @@ components: type: string id: type: string + description: component aggregate ID count: type: integer + description: number of instances to select, 0 to select unselect + options: + $ref: '#/components/schemas/Options' required: - context - id - count + - options SelectComponentResponse: allOf: - $ref: '#/x-jsonrpc-envelope-response' - properties: result: - type: boolean + $ref: '#/components/schemas/SuccessResult' SelectVariantRequest: allOf: - $ref: '#/x-jsonrpc-envelope-request-with-params' @@ -606,6 +685,7 @@ components: type: string id: type: string + description: component aggregate ID variant: type: string required: @@ -617,33 +697,7 @@ components: - $ref: '#/x-jsonrpc-envelope-response' - properties: result: - type: boolean - SelectVersionRequest: - allOf: - - $ref: '#/x-jsonrpc-envelope-request-with-params' - - properties: - method: - type: string - const: SelectVersion - params: - type: object - properties: - context: - type: string - id: - type: string - version: - type: string - required: - - context - - id - - version - SelectVersionResponse: - allOf: - - $ref: '#/x-jsonrpc-envelope-response' - - properties: - result: - type: boolean + $ref: '#/components/schemas/SuccessResult' SelectBundleRequest: allOf: - $ref: '#/x-jsonrpc-envelope-request-with-params' @@ -669,7 +723,7 @@ components: - $ref: '#/x-jsonrpc-envelope-response' - properties: result: - type: boolean + $ref: '#/components/schemas/SuccessResult' ValidateComponentsRequest: allOf: - $ref: '#/x-jsonrpc-envelope-request-with-params' diff --git a/bridge/.vscode/launch.json b/bridge/.vscode/launch.json index 0135bd5..5a457f6 100644 --- a/bridge/.vscode/launch.json +++ b/bridge/.vscode/launch.json @@ -16,7 +16,8 @@ "preLaunchTask": "tsc: build - tsconfig.json", "outFiles": [ "${workspaceFolder}/**/*.js" - ] + ], + "envFile": "${workspaceFolder}/.env" } ] } diff --git a/bridge/src/server.ts b/bridge/src/server.ts index 8c31f64..038525a 100644 --- a/bridge/src/server.ts +++ b/bridge/src/server.ts @@ -7,13 +7,35 @@ import { ChildProcess, spawn } from "node:child_process"; import express from 'express'; import cors from 'cors'; +import path from "node:path"; let child: ChildProcess|undefined; const app = express(); const port = 3000; function launch(): boolean { - child = spawn('csolution', ['rpc'], { cwd: './' }); + + + // Determine platform specifics + const isWindows = process.platform === 'win32'; + const binaryName = isWindows ? 'csolution.exe' : 'csolution'; + + let csolutionBinPath = undefined; + // Override with environment variable if available + if (process.env.CSOLUTION_PATH) { + console.log('Found CSOLUTION_PATH in environment:', process.env.CSOLUTION_PATH); + csolutionBinPath = process.env.CSOLUTION_PATH; + } + + // Resolve the final path to the executable + const csolutionBin = csolutionBinPath ? path.resolve(csolutionBinPath, binaryName) : binaryName; + console.log('Running csolution:', csolutionBin); + + const csolutionArgs = process.env.CSOLUTION_ARGS ?? ''; + const args = csolutionArgs.split(',').map(s => s.trim()); + child = spawn(csolutionBin, ['rpc', ...args], // append extra args from env + { cwd: './' } + ); child.on('error', (err) => { console.error(err.message); diff --git a/examples/vscode-extension-client/src/rpc-interface.ts b/examples/vscode-extension-client/src/rpc-interface.ts index 1f3faf4..7e6dc69 100644 --- a/examples/vscode-extension-client/src/rpc-interface.ts +++ b/examples/vscode-extension-client/src/rpc-interface.ts @@ -6,6 +6,10 @@ * json-rpc-codegen generated file: DO NOT EDIT! */ +export interface SuccessResult { + success: boolean, + message?: string, +} export interface Common { id: string, description?: string, @@ -16,7 +20,7 @@ export interface Pack extends Common { used?: boolean, references?: string[], } -export interface PacksInfo { +export interface PacksInfo extends SuccessResult { packs: Pack[], } export interface Component extends Common { @@ -24,14 +28,22 @@ export interface Component extends Common { implements?: string, maxInstances?: number, } -export interface CtItem { - name: string, +export interface Options { + layer?: string, + explicitVersion?: string, + explicitVendor?: boolean, } export interface ComponentInstance { id: string, selectedCount: number, + generator?: string, + fixed?: boolean, + options?: Options, resolvedComponent?: Component, - layer?: string, +} +export interface CtItem { + name: string, + result?: string, } export interface CtVariant extends CtItem { components: Component[], @@ -41,8 +53,10 @@ export interface CtAggregate extends CtItem { activeVariant?: string, activeVersion?: string, selectedCount?: number, + generator?: string, + fixed?: boolean, variants: CtVariant[], - layer?: string, + options?: Options, } export interface CtTreeItem extends CtItem { cgroups?: CtGroup[], @@ -63,7 +77,7 @@ export interface CtClass extends CtItem { activeBundle?: string, bundles: CtBundle[], } -export interface CtRoot { +export interface CtRoot extends SuccessResult { classes: CtClass[], } export interface Condition { @@ -76,21 +90,28 @@ export interface Result { aggregates?: string[], conditions?: Condition[], } -export interface Results { +export interface Results extends SuccessResult { + result: string, validation?: Result[], } -export interface UsedItems { +export interface UsedItems extends SuccessResult { components: ComponentInstance[], packs: Pack[], } -export interface LogMessages { +export interface LogMessages extends SuccessResult { info?: string[], errors?: string[], warnings?: string[], } +export interface GetVersionResult extends SuccessResult { + version?: string, +} export interface ApplyParams { context: string, } +export interface ResolveParams { + context: string, +} export interface LoadSolutionParams { solution: string, } @@ -108,17 +129,13 @@ export interface SelectComponentParams { context: string, id: string, count: number, + options: Options, } export interface SelectVariantParams { context: string, id: string, variant: string, } -export interface SelectVersionParams { - context: string, - id: string, - version: string, -} export interface SelectBundleParams { context: string, cclass: string, @@ -129,18 +146,18 @@ export interface ValidateComponentsParams { } export interface RpcInterface { - getVersion(): Promise; - shutdown(): Promise; - apply(args: ApplyParams): Promise; - loadPacks(): Promise; - loadSolution(args: LoadSolutionParams): Promise; + getVersion(): Promise; + shutdown(): Promise; + apply(args: ApplyParams): Promise; + resolve(args: ResolveParams): Promise; + loadPacks(): Promise; + loadSolution(args: LoadSolutionParams): Promise; getPacksInfo(args: GetPacksInfoParams): Promise; getUsedItems(args: GetUsedItemsParams): Promise; getComponentsTree(args: GetComponentsTreeParams): Promise; - selectComponent(args: SelectComponentParams): Promise; - selectVariant(args: SelectVariantParams): Promise; - selectVersion(args: SelectVersionParams): Promise; - selectBundle(args: SelectBundleParams): Promise; + selectComponent(args: SelectComponentParams): Promise; + selectVariant(args: SelectVariantParams): Promise; + selectBundle(args: SelectBundleParams): Promise; validateComponents(args: ValidateComponentsParams): Promise; getLogMessages(): Promise; } @@ -149,19 +166,22 @@ export abstract class RpcMethods implements RpcInterface { abstract get(remoteMethod: string, args?: TArgs): Promise; - public async getVersion(): Promise { + public async getVersion(): Promise { return this.get('GetVersion'); } - public async shutdown(): Promise { + public async shutdown(): Promise { return this.get('Shutdown'); } - public async apply(args: ApplyParams): Promise { + public async apply(args: ApplyParams): Promise { return this.get('Apply', args); } - public async loadPacks(): Promise { + public async resolve(args: ResolveParams): Promise { + return this.get('Resolve', args); + } + public async loadPacks(): Promise { return this.get('LoadPacks'); } - public async loadSolution(args: LoadSolutionParams): Promise { + public async loadSolution(args: LoadSolutionParams): Promise { return this.get('LoadSolution', args); } public async getPacksInfo(args: GetPacksInfoParams): Promise { @@ -173,16 +193,13 @@ export abstract class RpcMethods implements RpcInterface { public async getComponentsTree(args: GetComponentsTreeParams): Promise { return this.get('GetComponentsTree', args); } - public async selectComponent(args: SelectComponentParams): Promise { + public async selectComponent(args: SelectComponentParams): Promise { return this.get('SelectComponent', args); } - public async selectVariant(args: SelectVariantParams): Promise { + public async selectVariant(args: SelectVariantParams): Promise { return this.get('SelectVariant', args); } - public async selectVersion(args: SelectVersionParams): Promise { - return this.get('SelectVersion', args); - } - public async selectBundle(args: SelectBundleParams): Promise { + public async selectBundle(args: SelectBundleParams): Promise { return this.get('SelectBundle', args); } public async validateComponents(args: ValidateComponentsParams): Promise {