mirror of
https://github.com/l0ng-ai/openidea.git
synced 2026-11-14 16:07:52 +00:00
fix(run): open .NET Project configurations as the form with a project field (#2757)
The .NET Project type had no way back from a command line to its fields, and a new configuration starts without params, so the editor fell back to the plain Command/Arguments form: there was no .NET project field, and Debug failed with "Select a .NET project". dotnet run command lines the form can express now map back to its fields, for new configurations and ones typed as a command. Fixes #2733
This commit is contained in:
@@ -6,7 +6,7 @@ import { useProject } from "@/platform/project";
|
||||
import { dotnetBuildConfig, dotnetProjectType, dotnetTestType } from "./dotnetTypes";
|
||||
import { ConfigForm } from "./ConfigForm";
|
||||
import { validateConfig } from "./configs";
|
||||
import { newConfigOfType, registerBuiltinTypes, withParams } from "./types";
|
||||
import { formParams, newConfigOfType, registerBuiltinTypes, withParams } from "./types";
|
||||
|
||||
const resolveDotnet = vi.hoisted(() => vi.fn());
|
||||
vi.mock("@/platform/ipc", async (importOriginal) => {
|
||||
@@ -69,6 +69,36 @@ describe(".NET configurations", () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it("opens a new configuration, and a typed dotnet run command, as the form with its project field", () => {
|
||||
const fresh = newConfigOfType(dotnetProjectType, []);
|
||||
expect(formParams(fresh, dotnetProjectType)).toEqual({ project: "" });
|
||||
render(
|
||||
<ConfigForm
|
||||
config={fresh}
|
||||
all={[fresh]}
|
||||
type={dotnetProjectType}
|
||||
errors={{}}
|
||||
modifyRequest={0}
|
||||
onChange={vi.fn()}
|
||||
/>,
|
||||
);
|
||||
expect(screen.getByLabelText(".NET project")).toBeTruthy();
|
||||
// #2733: typed into the command fields of a configuration without params.
|
||||
const typed: RunConfig = {
|
||||
...fresh,
|
||||
params: {},
|
||||
command: "dotnet",
|
||||
args: ["run", "--project", "Worker.Service", "--no-launch-profile", "--", "--verbose"],
|
||||
};
|
||||
expect(formParams(typed, dotnetProjectType)).toEqual({
|
||||
project: "Worker.Service",
|
||||
programArgs: "--verbose",
|
||||
});
|
||||
// Options the form has no field for keep the command editor.
|
||||
expect(formParams({ ...typed, args: ["run", "--project", "A", "--no-build"] }, dotnetProjectType)).toBeNull();
|
||||
expect(formParams({ ...typed, args: ["build", "A"] }, dotnetProjectType)).toBeNull();
|
||||
});
|
||||
|
||||
it("builds edited project/framework from the open root instead of a profile cwd", () => {
|
||||
useProject.setState({ project: { root: "/repo" } as never });
|
||||
const c = withParams(
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { call, commands, type RunConfig } from "@/platform/ipc";
|
||||
import { useProject } from "@/platform/project";
|
||||
import type { RunConfigTypeContribution } from "@/workbench/contributions";
|
||||
import { parseArgs } from "./configs";
|
||||
import { formatArgs, parseArgs } from "./configs";
|
||||
import { commandName } from "./commandName";
|
||||
import { prepareDotnetTest } from "@/platform/dotnet";
|
||||
|
||||
function profile(p: Readonly<Record<string, string>>): {
|
||||
@@ -28,6 +29,38 @@ export function dotnetCommand(p: Readonly<Record<string, string>>, test = false)
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* The form fields of a `dotnet run` command line ([`dotnetCommand`] reversed), or `null` when it
|
||||
* uses anything the form can't show. Lets a new configuration, and one typed as a command, open
|
||||
* as the form with its project field.
|
||||
*/
|
||||
function dotnetRunParams(c: RunConfig): Record<string, string> | null {
|
||||
if (!/^dotnet(\.exe)?$/i.test(commandName(c.command))) return null;
|
||||
const [verb, ...rest] = c.args;
|
||||
if (verb !== "run") return null;
|
||||
const p: Record<string, string> = c.command === "dotnet" ? {} : { executable: c.command };
|
||||
const flags: Record<string, string> = {
|
||||
"--project": "project",
|
||||
"--framework": "framework",
|
||||
"--configuration": "configuration",
|
||||
"--launch-profile": "launchProfile",
|
||||
};
|
||||
for (let i = 0; i < rest.length; i++) {
|
||||
const arg = rest[i]!;
|
||||
if (arg === "--") {
|
||||
p.programArgs = formatArgs(rest.slice(i + 1));
|
||||
break;
|
||||
}
|
||||
if (arg === "--no-launch-profile") continue;
|
||||
const key = flags[arg];
|
||||
const value = rest[i + 1];
|
||||
if (!key || value === undefined) return null;
|
||||
p[key] = value;
|
||||
i++;
|
||||
}
|
||||
return { project: "", ...p };
|
||||
}
|
||||
|
||||
/** Build the current project/framework, independently of the run's profile working directory. */
|
||||
export function dotnetBuildConfig(config: RunConfig): RunConfig {
|
||||
const p = config.params ?? {};
|
||||
@@ -104,6 +137,7 @@ export const dotnetProjectType: RunConfigTypeContribution = {
|
||||
},
|
||||
],
|
||||
commandLine: (p) => dotnetCommand(p),
|
||||
paramsFrom: dotnetRunParams,
|
||||
async prepareLaunch(config) {
|
||||
const resolved = await call(commands.runDotnetResolve(config, false));
|
||||
const p = resolved.params ?? {};
|
||||
|
||||
Reference in New Issue
Block a user