mirror of
https://github.com/l0ng-ai/openidea.git
synced 2026-11-06 16:08:05 +00:00
Opening a folder of independent Gradle builds selected only the first build. Link Gradle Projects… (pick a build's settings or build file) and Unlink on a build's root let an ordinary project window manage several independent builds without changing their scripts. The build model holds a list of Gradle builds; each keeps its own wrapper, working directory, environment, task routing and sync cache, keyed by the owning build directory. The links persist in the project's Gradle settings (linkedProjects); unlinking leaves files and saved run configurations alone. Existing includeBuild support is unchanged, and an explicitly linked build takes precedence over a composite that also includes it. Workspace windows keep Link/Unlink disabled. Co-authored-by: gudcks0305 <84506708+gudcks0305@users.noreply.github.com>
89 lines
3.1 KiB
TypeScript
89 lines
3.1 KiB
TypeScript
/** Read-only build context shared by file and folder presentation consumers. */
|
|
import { useEffect } from "react";
|
|
import { create } from "zustand";
|
|
import { call, commands, isTauri, onIdeEvent, type BuildModel } from "./ipc";
|
|
import { useProject } from "./project";
|
|
|
|
export interface BuildPresentation {
|
|
modules: ReadonlyMap<string, "maven" | "gradle">;
|
|
spring: boolean;
|
|
}
|
|
const EMPTY: BuildPresentation = { modules: new Map(), spring: false };
|
|
export const useBuildPresentation = create<BuildPresentation>(() => EMPTY);
|
|
|
|
export function buildPresentation(model: BuildModel): BuildPresentation {
|
|
const modules = new Map<string, "maven" | "gradle">();
|
|
for (const p of model.maven?.projects ?? []) modules.set(p.dir, "maven");
|
|
for (const p of (model.gradle ?? []).flatMap((g) => g.projects)) modules.set(p.dir, "gradle");
|
|
const spring =
|
|
(model.maven?.projects ?? []).some(
|
|
(p) =>
|
|
p.dependencies.some((d) => d.groupId.startsWith("org.springframework")) ||
|
|
p.plugins.some((p) => p.groupId.startsWith("org.springframework")),
|
|
) || (model.gradle ?? []).some((g) => g.projects.some((p) => p.tasks.some((t) => t.name === "bootRun")));
|
|
return { modules, spring };
|
|
}
|
|
|
|
/** A Maven / Gradle module folder below the project root: IDEA shows its name in bold. */
|
|
export function isModuleFolder(rel: string, root: boolean, modules: BuildPresentation["modules"]): boolean {
|
|
return !root && rel !== "" && modules.has(rel);
|
|
}
|
|
|
|
export function moduleFolderIcon(rel: string, root: boolean, modules: BuildPresentation["modules"]): string | null {
|
|
const tool = modules.get(rel);
|
|
return tool ? `${tool}-${root ? "project" : "module"}` : null;
|
|
}
|
|
|
|
let users = 0;
|
|
let generation = 0;
|
|
let dispose: (() => void) | undefined;
|
|
async function load() {
|
|
const gen = ++generation;
|
|
if (!useProject.getState().project || !isTauri()) {
|
|
useBuildPresentation.setState(EMPTY);
|
|
return;
|
|
}
|
|
try {
|
|
const model = await call(commands.buildModel());
|
|
if (generation === gen) useBuildPresentation.setState(buildPresentation(model));
|
|
} catch {
|
|
/* Presentation keeps its filename fallback. */
|
|
}
|
|
}
|
|
|
|
export function useProjectPresentation(): BuildPresentation {
|
|
useEffect(() => {
|
|
if (users++ === 0) {
|
|
void load();
|
|
const project = useProject.subscribe((s, prev) => {
|
|
if (s.project === prev.project) return;
|
|
useBuildPresentation.setState(EMPTY);
|
|
void load();
|
|
});
|
|
const roots = onIdeEvent("projectRootsChanged", () => void load());
|
|
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
const files = onIdeEvent("fsChanged", (e) => {
|
|
if (
|
|
![...e.created, ...e.modified, ...e.removed].some((p) =>
|
|
/(?:^|\/)(pom\.xml|(?:build|settings)\.gradle(?:\.kts)?)$/.test(p),
|
|
)
|
|
)
|
|
return;
|
|
clearTimeout(timer);
|
|
timer = setTimeout(() => void load(), 100);
|
|
});
|
|
dispose = () => {
|
|
project();
|
|
roots();
|
|
files();
|
|
clearTimeout(timer);
|
|
generation++;
|
|
};
|
|
}
|
|
return () => {
|
|
if (--users === 0) dispose?.();
|
|
};
|
|
}, []);
|
|
return useBuildPresentation();
|
|
}
|