Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions Packages/src/Editor/CliOnlyTools~/Launch/Skill/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ uloop launch [project-path] [options]
| `project-path` | string | Optional. Use only when the target Unity project is not in the current directory. |
| `-r, --restart` | flag | Kill running Unity and restart |
| `-q, --quit` | flag | Kill an existing Unity process for the project without launching |
| `-i, --ignore-compiler-errors` | flag | Continue opening Unity even when the project has compiler errors |
| `--editor-version <version>` | string | Use this Unity Editor version instead of ProjectVersion.txt |
| `-p, --platform <P>` | string | Build target (e.g., StandaloneOSX, Android, iOS) |
| `--max-depth <N>` | number | Search depth when project-path is omitted (default: 3, -1 for unlimited) |
Expand All @@ -43,9 +42,6 @@ uloop launch -r
# Launch with build target
uloop launch -p Android

# Launch even when the project has compiler errors
uloop launch -i

# Launch with a specific installed Editor version
uloop launch --editor-version 6000.0.0f1

Expand Down Expand Up @@ -76,6 +72,6 @@ The final JSON payload includes:

- If Unity is already running, focuses the existing window and verifies tool readiness
- If process scan is blocked (e.g. sandboxed `ps`), plain launch falls back to IPC probing; `--restart` and `--quit` still fail because they need the process id
- `-i, --ignore-compiler-errors` only affects new Unity processes; it has no effect when reusing an already-running Editor
- New Unity processes ignore project compiler errors during Editor startup by default when run by dispatcher 3.0.1-beta.8 or newer; run `uloop update` first if an older dispatcher is installed
- `--editor-version` only affects new Unity processes; use it with `--restart` to replace an already-running Editor
- The command waits until Unity finishes startup and the CLI can connect before returning
2 changes: 1 addition & 1 deletion cli/dispatcher-contract.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"schemaVersion": 1,
"dispatcherVersion": "3.0.1-beta.7",
"dispatcherVersion": "3.0.1-beta.8",
"dispatcherContractVersion": 1
}
2 changes: 0 additions & 2 deletions cli/internal/cli/completion_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@ var nativeCommandOptions = map[string][]string{
"--" + projectPathFlagName,
"--delete-recovery",
"--editor-version",
"--ignore-compiler-errors",
"--max-depth",
"--platform",
"--quit",
"--restart",
"-i",
},
installCommandName: {"--" + installDirFlagName},
updateCommandName: {"--" + updateToVersionFlagName},
Expand Down
7 changes: 6 additions & 1 deletion cli/internal/cli/completion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,11 +189,16 @@ func TestCompletionListOptionsUsesNativeLaunchOptions(t *testing.T) {

output := stdout.String()
listedOptions := strings.Split(strings.TrimSpace(output), "\n")
for _, option := range []string{"--project-path", "--restart", "--quit", "--delete-recovery", "--platform", "--max-depth", "-i", "--ignore-compiler-errors", "--editor-version"} {
for _, option := range []string{"--project-path", "--restart", "--quit", "--delete-recovery", "--platform", "--max-depth", "--editor-version"} {
if !slices.Contains(listedOptions, option) {
t.Fatalf("launch option %s was not listed: %s", option, output)
}
}
for _, option := range []string{"-i", "--ignore-compiler-errors"} {
if slices.Contains(listedOptions, option) {
t.Fatalf("removed launch option %s was listed: %s", option, output)
}
}
}

func TestCompletionListOptionsUsesNativeUpdateOptions(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion cli/internal/cli/dispatcher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ func TestRunDispatcherLaunchOptionsDoNotRequireProjectPin(t *testing.T) {
var stderr bytes.Buffer
code := RunDispatcher(
context.Background(),
[]string{"launch", "-i", "--editor-version", "6000.0.0f1", projectRoot, "--quit"},
[]string{"launch", "--editor-version", "6000.0.0f1", projectRoot, "--quit"},
&stdout,
&stderr)

Expand Down
7 changes: 6 additions & 1 deletion cli/internal/cli/help_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ func TestRunProjectLocalLaunchHelpShowsGlobalOptions(t *testing.T) {
for _, expected := range []string{
"Usage:",
"uloop launch [options] [project-path]",
"-i, --ignore-compiler-errors",
"Compiler errors are ignored by default during Unity startup.",
"--editor-version <version>",
"Global options:",
"--project-path <path>",
Expand All @@ -250,6 +250,11 @@ func TestRunProjectLocalLaunchHelpShowsGlobalOptions(t *testing.T) {
t.Fatalf("launch help missing %q:\n%s", expected, output)
}
}
for _, removed := range []string{"-i, --ignore-compiler-errors", "--ignore-compiler-errors"} {
if strings.Contains(output, removed) {
t.Fatalf("launch help still includes removed option %q:\n%s", removed, output)
}
}
}

// Tests that first-party tool help is available without Unity project resolution.
Expand Down
23 changes: 10 additions & 13 deletions cli/internal/cli/launch.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,13 @@ var (
var editorVersionPattern = regexp.MustCompile(`(?m)^m_EditorVersion:\s*(.+)$`)

type launchOptions struct {
projectPath string
restart bool
quit bool
deleteRecovery bool
ignoreCompilerErrors bool
editorVersion string
platform string
maxDepth int
projectPath string
restart bool
quit bool
deleteRecovery bool
editorVersion string
platform string
maxDepth int
}

func tryHandleLaunchRequest(
Expand Down Expand Up @@ -297,9 +296,7 @@ func buildUnityLaunchArgs(projectRoot string, options launchOptions) []string {
if options.platform != "" {
launchArgs = append(launchArgs, "-buildTarget", options.platform)
}
if options.ignoreCompilerErrors {
launchArgs = append(launchArgs, "-ignorecompilererrors")
}
launchArgs = append(launchArgs, "-ignorecompilererrors")
return launchArgs
}

Expand Down Expand Up @@ -478,12 +475,12 @@ func printLaunchHelp(stdout io.Writer) {
writeLine(stdout, " -r, --restart Kill an existing Unity process for the project before launching")
writeLine(stdout, " -q, --quit Kill an existing Unity process for the project without launching")
writeLine(stdout, " -d, --delete-recovery Delete Assets/_Recovery before launch")
writeLine(stdout, " -i, --ignore-compiler-errors")
writeLine(stdout, " Continue opening Unity even when the project has compiler errors")
writeLine(stdout, " --editor-version <version>")
writeLine(stdout, " Use this Unity Editor version instead of ProjectVersion.txt")
writeLine(stdout, " -p, --platform <name> Pass Unity -buildTarget when launching")
writeLine(stdout, " --max-depth <n> Accepted for compatibility when searching from the current directory")
writeLine(stdout, "")
writeLine(stdout, "Compiler errors are ignored by default during Unity startup.")
writeLine(stdout, "")
printGlobalOptionsHelp(stdout)
}
3 changes: 0 additions & 3 deletions cli/internal/cli/launch_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ func applyLaunchOption(options *launchOptions, args []string, index int) (int, e
case arg == "-d" || arg == "--delete-recovery":
options.deleteRecovery = true
return index, nil
case arg == "-i" || arg == "--ignore-compiler-errors":
options.ignoreCompilerErrors = true
return index, nil
case arg == "--editor-version" || strings.HasPrefix(arg, "--editor-version="):
return applyLaunchEditorVersionOption(options, args, index)
case isUnsupportedLaunchHubOption(arg):
Expand Down
49 changes: 34 additions & 15 deletions cli/internal/cli/launch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ func TestParseLaunchOptionsSupportsCoreFlags(t *testing.T) {
[]string{
"--restart",
"--delete-recovery",
"--ignore-compiler-errors",
"--editor-version", "6000.0.0f1",
"--platform", "Android",
"--max-depth", "-1",
Expand All @@ -40,9 +39,6 @@ func TestParseLaunchOptionsSupportsCoreFlags(t *testing.T) {
if !options.deleteRecovery {
t.Fatal("delete recovery flag was not parsed")
}
if !options.ignoreCompilerErrors {
t.Fatal("ignore compiler errors flag was not parsed")
}
if options.editorVersion != "6000.0.0f1" {
t.Fatalf("editor version mismatch: %s", options.editorVersion)
}
Expand All @@ -57,23 +53,29 @@ func TestParseLaunchOptionsSupportsCoreFlags(t *testing.T) {
}
}

func TestParseLaunchOptionsSupportsShortIgnoreCompilerErrorsFlag(t *testing.T) {
// Verifies -i is the short alias for --ignore-compiler-errors.
options, err := parseLaunchOptions([]string{"-i", "/tmp/project"}, "")
if err != nil {
t.Fatalf("parseLaunchOptions failed: %v", err)
}
func TestParseLaunchOptionsRejectsRemovedIgnoreCompilerErrorsFlags(t *testing.T) {
// Verifies removed compiler-error ignore flags no longer remain in the launch API.
for _, arg := range []string{"-i", "--ignore-compiler-errors"} {
_, err := parseLaunchOptions([]string{arg}, "")
if err == nil {
t.Fatalf("expected removed ignore compiler errors flag error for %s", arg)
}

if !options.ignoreCompilerErrors {
t.Fatal("short ignore compiler errors flag was not parsed")
var argErr *argumentError
if !errors.As(err, &argErr) {
t.Fatalf("expected argumentError for %s, got %T", arg, err)
}
if argErr.option != arg {
t.Fatalf("option mismatch for %s: %s", arg, argErr.option)
}
}
}

func TestBuildUnityLaunchArgsIncludesIgnoreCompilerErrors(t *testing.T) {
// Verifies launch maps --ignore-compiler-errors to Unity Editor's native startup argument.
func TestBuildUnityLaunchArgsIncludesIgnoreCompilerErrorsByDefault(t *testing.T) {
// Verifies every Unity launch ignores project compiler errors during Editor startup.
args := buildUnityLaunchArgs(
"/tmp/project",
launchOptions{platform: "Android", ignoreCompilerErrors: true},
launchOptions{platform: "Android"},
)
expectedArgs := []string{
"-projectPath",
Expand All @@ -88,6 +90,23 @@ func TestBuildUnityLaunchArgsIncludesIgnoreCompilerErrors(t *testing.T) {
}
}

func TestBuildUnityLaunchArgsIncludesIgnoreCompilerErrorsForRestart(t *testing.T) {
// Verifies restarted Unity launches use the same compiler-error ignore startup argument.
args := buildUnityLaunchArgs(
"/tmp/project",
launchOptions{restart: true},
)
expectedArgs := []string{
"-projectPath",
"/tmp/project",
"-ignorecompilererrors",
}

if !slices.Equal(args, expectedArgs) {
t.Fatalf("Unity launch args mismatch: got %#v want %#v", args, expectedArgs)
}
}

func TestParseLaunchOptionsSupportsEditorVersionEqualsValue(t *testing.T) {
// Verifies --editor-version=value matches Unity CLI's value form.
options, err := parseLaunchOptions([]string{"--editor-version=6000.0.1f1", "/tmp/project"}, "")
Expand Down
Loading