Skip to content

Commit f2e3d28

Browse files
committed
feat: Add task dependency viewer
1 parent c1c56ca commit f2e3d28

File tree

10 files changed

+287
-2
lines changed

10 files changed

+287
-2
lines changed

package.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,11 @@
436436
"title": "Mise: Show mise tracked configurations",
437437
"icon": "$(list-ordered)"
438438
},
439+
{
440+
"command": "mise.visualizeTasksDeps",
441+
"title": "Mise: Visualize Tasks Dependencies",
442+
"icon": "$(git-merge)"
443+
},
439444
{
440445
"command": "mise.setEnvVariable",
441446
"title": "Mise: Set Environment Variable",
@@ -462,6 +467,11 @@
462467
"when": "view == miseTasksView",
463468
"group": "navigation@2"
464469
},
470+
{
471+
"command": "mise.visualizeTasksDeps",
472+
"when": "view == miseTasksView",
473+
"group": "navigation@2"
474+
},
465475
{
466476
"command": "mise.listAllTools",
467477
"when": "view == miseToolsView",
@@ -653,6 +663,8 @@
653663
"@vscode/codicons": "^0.0.36",
654664
"async-cache-dedupe": "^2.2.0",
655665
"cheerio": "^1.0.0",
666+
"d3": "^7.9.0",
667+
"d3-graphviz": "^5.6.0",
656668
"react": "18.3.1",
657669
"react-dom": "18.3.1",
658670
"react-error-boundary": "^4.1.2",

pnpm-lock.yaml

Lines changed: 93 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/commands.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export const MISE_INSTALL_TOOL = "mise.installTool";
1111
export const MISE_LIST_ALL_TOOLS = "mise.listAllTools";
1212
export const MISE_SHOW_SETTINGS = "mise.showSettings";
1313
export const MISE_SHOW_TRACKED_CONFIG = "mise.showTrackedConfig";
14+
export const MISE_VISUALIZE_TASKS_DEPS = "mise.visualizeTasksDeps";
1415
export const MISE_OPEN_ENV_VAR_DEFINITION = "mise.openEnvVariableDefinition";
1516
export const MISE_OPEN_FILE = "mise.openFile";
1617
export const MISE_OPEN_LOGS = "mise.openLogs";

src/miseExtension.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
MISE_SELECT_WORKSPACE_FOLDER,
1616
MISE_SHOW_SETTINGS,
1717
MISE_SHOW_TRACKED_CONFIG,
18+
MISE_VISUALIZE_TASKS_DEPS,
1819
} from "./commands";
1920
import {
2021
CONFIGURATION_FLAGS,
@@ -346,6 +347,12 @@ export class MiseExtension {
346347
}),
347348
);
348349

350+
context.subscriptions.push(
351+
vscode.commands.registerCommand(MISE_VISUALIZE_TASKS_DEPS, async () => {
352+
WebViewPanel.createOrShow(context, this.miseService, "TASKS_DEPS");
353+
}),
354+
);
355+
349356
const allTomlFilesSelector = { scheme: "file", language: "toml" };
350357

351358
context.subscriptions.push(

src/miseService.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,14 @@ function ensureMiseCommand(
9595

9696
export class MiseService {
9797
private readonly context: vscode.ExtensionContext;
98+
private readonly eventEmitter: vscode.EventEmitter<void>;
9899
constructor(context: vscode.ExtensionContext) {
99100
this.context = context;
101+
this.eventEmitter = new vscode.EventEmitter();
102+
}
103+
104+
subscribeToReloadEvent(listener: () => void): vscode.Disposable {
105+
return this.eventEmitter.event(listener);
100106
}
101107

102108
private hasVerifiedMiseVersion = false;
@@ -143,6 +149,7 @@ export class MiseService {
143149

144150
async invalidateCache() {
145151
await Promise.all([this.dedupeCache.clear(), this.cache.clear()]);
152+
this.eventEmitter.fire();
146153
}
147154

148155
async initializeMisePath() {
@@ -1042,4 +1049,17 @@ export class MiseService {
10421049
logger.info(`New symlink created ${linkPath} -> ${binPath}`);
10431050
return configuredPath;
10441051
}
1052+
1053+
async getTaskDependencies(tasks: string[] | undefined) {
1054+
if (!this.getMiseBinaryPath()) {
1055+
return "";
1056+
}
1057+
1058+
const taskString = tasks ? tasks.map((task) => `"${task}"`).join(" ") : "";
1059+
1060+
const { stdout } = await this.cache.execCmd({
1061+
command: `tasks deps ${taskString} --dot`,
1062+
});
1063+
return stdout;
1064+
}
10451065
}

src/webviewPanel.ts

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,20 @@ import { MISE_EDIT_SETTING } from "./commands";
77
import type { MiseService } from "./miseService";
88
import { logger } from "./utils/logger";
99

10-
type PanelView = "TOOLS" | "SETTINGS" | "TRACKED_CONFIGS";
10+
type PanelView = "TOOLS" | "SETTINGS" | "TRACKED_CONFIGS" | "TASKS_DEPS";
11+
12+
function panelTitleForView(view: PanelView) {
13+
switch (view) {
14+
case "TOOLS":
15+
return "Tools";
16+
case "SETTINGS":
17+
return "Settings";
18+
case "TRACKED_CONFIGS":
19+
return "Tracked Configs";
20+
case "TASKS_DEPS":
21+
return "Tasks Dependencies";
22+
}
23+
}
1124

1225
export default class WebViewPanel {
1326
public static currentPanels: Record<string, WebViewPanel> = {};
@@ -54,7 +67,7 @@ export default class WebViewPanel {
5467

5568
this._panel = vscode.window.createWebviewPanel(
5669
WebViewPanel.viewType,
57-
`Mise: ${this.view === "TOOLS" ? "Tools" : this.view === "SETTINGS" ? "Settings" : "Tracked Configs"}`,
70+
`Mise: ${panelTitleForView(this.view)}`,
5871
column,
5972
{
6073
retainContextWhenHidden: false,
@@ -117,6 +130,16 @@ export default class WebViewPanel {
117130
this.miseService.getTrackedConfigFiles(),
118131
);
119132
}
133+
case "taskDeps": {
134+
return executeAction(message, () =>
135+
this.miseService.getTaskDependencies(message.variables.tasks),
136+
);
137+
}
138+
case "tasks": {
139+
return executeAction(message, () =>
140+
this.miseService.getTasks(),
141+
);
142+
}
120143
}
121144
break;
122145
case "mutation":
@@ -180,6 +203,14 @@ export default class WebViewPanel {
180203
"workbench.action.webview.reloadWebviewAction",
181204
);
182205
});
206+
207+
miseService.subscribeToReloadEvent(() => {
208+
this._panel.webview.postMessage({
209+
type: "invalidateQueries",
210+
requestId: "invalidateQueries",
211+
data: null,
212+
});
213+
});
183214
}
184215

185216
public dispose() {

0 commit comments

Comments
 (0)