Skip to content

Commit

Permalink
feat(contrib): fix preview in vscode / project management (#6878)
Browse files Browse the repository at this point in the history
Signed-off-by: Thomas Bétrancourt <[email protected]>
  • Loading branch information
rclsilver authored Mar 13, 2024
1 parent 5715b3f commit d7abf0c
Show file tree
Hide file tree
Showing 32 changed files with 760 additions and 225 deletions.
37 changes: 34 additions & 3 deletions contrib/vscode-cds/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,26 @@
"main": "./out/extension.js",
"contributes": {
"commands": [
{
"command": "vscode-cds.clearCache",
"title": "Clear the cache",
"category": "CDS"
},
{
"command": "vscode-cds.setCurrentContext",
"title": "Change the CDS context"
"title": "Change the CDS context",
"category": "CDS"
},
{
"command": "vscode-cds.setCurrentProject",
"title": "Set the CDS context for the current repository",
"category": "CDS"
},
{
"command": "vscode-cds.previewWorkflow",
"title": "Preview the CDS workflow"
"title": "Preview the CDS workflow",
"category": "CDS",
"icon": "$(open-preview)"
}
],
"configuration": {
Expand All @@ -51,7 +64,25 @@
"markdownDescription": "Logging for CDS extension. The log is emitted to the output channel named as CDS."
}
}
}
},
"menus": {
"editor/title": [
{
"command": "vscode-cds.previewWorkflow",
"when": "isCDSWorkflowFile",
"alt": "vscode-cds.previewWorkflow",
"group": "navigation"
}
]
},
"keybindings": [
{
"command": "vscode-cds.previewWorkflow",
"key": "shift+ctrl+v",
"mac": "shift+cmd+v",
"when": "isCDSWorkflowFile"
}
]
},
"extensionDependencies": [
"redhat.vscode-yaml"
Expand Down
60 changes: 60 additions & 0 deletions contrib/vscode-cds/src/cds/file_utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import * as vscode from "vscode";
import * as uri from "vscode-uri";
import * as path from "path";


export function isCDSWorkflowFile(document: vscode.TextDocument) {
if (!isCDSFile(document)) {
return false;
}

if (getParentDirectory(document?.uri) !== 'workflows') {
return false;
}

return true;
}

export function isCDSWorkerModelFile(document: vscode.TextDocument) {
if (!isCDSFile(document)) {
return false;
}

if (getParentDirectory(document?.uri) !== 'worker-models') {
return false;
}

return true;
}

export function isCDSActionFile(document: vscode.TextDocument) {
if (!isCDSFile(document)) {
return false;
}

if (getParentDirectory(document?.uri) !== 'actions') {
return false;
}

return true;
}

function isCDSFile(document: vscode.TextDocument) {
if (document.languageId !== 'yaml') {
return false;
}

if (document.isUntitled) {
return false;
}

return getParentDirectory(getParentPath(document.uri)) === '.cds';
}

function getParentPath(filepath: uri.URI) {
return uri.Utils.dirname(uri.Utils.resolvePath(filepath));
}

function getParentDirectory(filepath: uri.URI): string {
return path.basename(getParentPath(filepath).path);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,15 @@ import { window, workspace } from "vscode";
import { Journal } from "../utils/journal";
import { isActiveEditorValid } from "../utils/editor";
import { Property } from "../utils/property";
import { Context } from "./models";
import { Context, Project } from "./models";
import { getGitLocalConfig, getGitRepositoryPath, setGitLocalConfig } from "../utils/git";
import { Cache } from "../utils/cache";

const defaultConfigFile = '~/.cdsrc';

const GIT_CONFIG_SECTION = "cds";
const GIT_CONFIG_PROJECT = "project";

export class CDS {
static getConfigFile(): string {
const cdsrc = Property.get('config') || defaultConfigFile;
Expand Down Expand Up @@ -39,6 +44,73 @@ export class CDS {
return foundContext[0];
}


static async getProjects(): Promise<Project[]> {
const context = await CDS.getCurrentContext();

if (context) {
const cachedProjects = Cache.get<Project[]>(`${context.context}.projects`);

if (cachedProjects) {
return cachedProjects;
}
}

const projectsJson = (await CDS.getInstance().runCtl("project", "list", "--format", "json"));
const projects = JSON.parse(projectsJson);

if (context) {
Cache.set(`${context.context}.projects`, projects, Cache.TTL_HOUR * 24);
}

return projects;
}

static async getCurrentProject(): Promise<Project | null> {
if (!window.activeTextEditor || window.activeTextEditor.document.uri.scheme !== 'file') {
return null;
}

try {
const repository = await getGitRepositoryPath(window.activeTextEditor.document.fileName);
const projectKey = await getGitLocalConfig(repository, GIT_CONFIG_SECTION, "project");

if (!projectKey) {
return null;
}

const foundProject = (await CDS.getProjects()).filter(p => p.key === projectKey)[0] ?? null;

if (!foundProject) {
return {
key: projectKey,
name: projectKey,
description: '',
favorite: 'false',
found: false,
};
}

return {
...foundProject,
found: true,
}
} catch (e) {
return null;
}
}

static async setCurrentProject(project: Project): Promise<void> {
if (!window.activeTextEditor || window.activeTextEditor.document.uri.scheme !== 'file') {
return;
}

if (project) {
const repository = await getGitRepositoryPath(window.activeTextEditor.document.fileName);
await setGitLocalConfig(repository, GIT_CONFIG_SECTION, GIT_CONFIG_PROJECT, project.key);
}
}

static async downloadSchemas(): Promise<void> {
await CDS.getInstance().runCtl("tools", "yaml-schema", "vscode");
}
Expand Down
4 changes: 4 additions & 0 deletions contrib/vscode-cds/src/cds/models/Context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface Context {
readonly context: string;
readonly host: string
}
7 changes: 7 additions & 0 deletions contrib/vscode-cds/src/cds/models/Project.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export interface Project {
readonly key: string;
readonly name: string;
readonly description: string
readonly favorite: 'true' | 'false';
readonly found: boolean;
}
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { Context } from './Context';
export { Project } from './Project';
14 changes: 14 additions & 0 deletions contrib/vscode-cds/src/commands/clear-cache.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Command } from ".";
import { Cache } from "../utils/cache";

export const ClearCacheCommandID = 'vscode-cds.clearCache';

export class ClearCacheCommand implements Command {
getID(): string {
return ClearCacheCommandID
}

async run(): Promise<void> {
Cache.clear();
}
}
15 changes: 15 additions & 0 deletions contrib/vscode-cds/src/commands/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import * as vscode from 'vscode';

export interface Command {
getID(): string
run(): Promise<void>
}

export function registerCommand(context: vscode.ExtensionContext, command: Command) {
context.subscriptions.push(vscode.commands.registerCommand(command.getID(), async () => {
await command.run();
}));
}

export { SetCurrentContextCommand as SetCurrentContext, SetCurrentContextCommandID } from './set-current-context';
export { SetCurrentProjectCommand as SetCurrentProject, SetCurrentProjectCommandID } from './set-current-project';
21 changes: 21 additions & 0 deletions contrib/vscode-cds/src/commands/preview-workflow.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import * as vscode from "vscode";

import { Command } from ".";
import { isCDSWorkflowFile } from "../cds/file_utils";
import { CDSPreview } from "../preview";

export const PreviewWorkflowCommandID = 'vscode-cds.previewWorkflow';

export class PreviewWorkflowCommand implements Command {
constructor(private instance: CDSPreview) { }

getID(): string {
return PreviewWorkflowCommandID
}

async run(): Promise<void> {
if (vscode.window.activeTextEditor?.document.uri && isCDSWorkflowFile(vscode.window.activeTextEditor.document)) {
this.instance.load(vscode.window.activeTextEditor?.document.uri);
}
}
}
24 changes: 23 additions & 1 deletion contrib/vscode-cds/src/commands/set-current-context.ts
Original file line number Diff line number Diff line change
@@ -1 +1,23 @@
export const setCurrentContextCommandID = 'vscode-cds.setCurrentContext';
import { Command } from ".";
import { selectContext } from "../forms/select-context";
import { CDS } from "../cds";
import { Journal } from "../utils/journal";
import { updateContext } from "../utils/context";

export const SetCurrentContextCommandID = 'vscode-cds.setCurrentContext';

export class SetCurrentContextCommand implements Command {
getID(): string {
return SetCurrentContextCommandID
}

async run(): Promise<void> {
const context = await selectContext();
try {
await CDS.setCurrentContext(context.context);
await updateContext();
} catch (e) {
Journal.logError(e as Error);
}
}
}
23 changes: 23 additions & 0 deletions contrib/vscode-cds/src/commands/set-current-project.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Command } from ".";
import { selectProject } from "../forms/select-project";
import { CDS } from "../cds";
import { Journal } from "../utils/journal";
import { setProject } from "../events/project";

export const SetCurrentProjectCommandID = 'vscode-cds.setCurrentProject';

export class SetCurrentProjectCommand implements Command {
getID(): string {
return SetCurrentProjectCommandID
}

async run(): Promise<void> {
const project = await selectProject();
try {
await CDS.setCurrentProject(project);
setProject(project);
} catch (e) {
Journal.logError(e as Error);
}
}
}
4 changes: 2 additions & 2 deletions contrib/vscode-cds/src/components/context-status.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import * as vscode from 'vscode';

import { setCurrentContextCommandID } from '../commands/set-current-context';
import { onContextChanged } from '../events/context';
import { SetCurrentContextCommandID } from '../commands';

let instance: vscode.StatusBarItem;

export function createContextStatusBarItem(context: vscode.ExtensionContext) {
instance = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 100);
instance.command = setCurrentContextCommandID;
instance.command = SetCurrentContextCommandID;
instance.tooltip = 'Current CDS context';
context.subscriptions.push(instance);

Expand Down
33 changes: 33 additions & 0 deletions contrib/vscode-cds/src/components/project-status.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import * as vscode from 'vscode';

import { SetCurrentProjectCommandID } from '../commands';
import { onProjectChanged } from '../events/project';
import { onGitRepositoryChanged } from '../events/git-repository';

let instance: vscode.StatusBarItem;

export function createProjectStatusBarItem(context: vscode.ExtensionContext) {
instance = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 100);
instance.command = SetCurrentProjectCommandID;
instance.tooltip = 'Current CDS project';
context.subscriptions.push(instance);

context.subscriptions.push(onGitRepositoryChanged(repository => {
if (repository) {
instance.show();
} else {
instance.hide();
}
}));

context.subscriptions.push(onProjectChanged(project => {
if (project) {
instance.text = `${project.name} (${project.key})`;
} else {
instance.text = 'Select a CDS project';
}

instance.color = (!!!project || project.found) ? '' : '#FF0000';
instance.show();
}));
}
2 changes: 1 addition & 1 deletion contrib/vscode-cds/src/events/context.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as vscode from 'vscode';
import { Context } from '../lib/cds/models';
import { Context } from '../cds/models';

const emitter = new vscode.EventEmitter<Context | null>();

Expand Down
Loading

0 comments on commit d7abf0c

Please sign in to comment.