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
10 changes: 7 additions & 3 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,13 @@ jobs:
go-version: '1.26.1'
cache-dependency-path: Packages/src/GoCli~/go.sum

- name: Test native Go CLI
working-directory: Packages/src/GoCli~
run: go test ./...
- name: Install golangci-lint
run: |
go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.12.0
echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH"

- name: Check native Go CLI
run: scripts/check-go-cli.sh

- name: Build native Go CLI
run: scripts/build-go-cli.sh
Expand Down
10 changes: 7 additions & 3 deletions .github/workflows/native-cli-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,13 @@ jobs:
go-version: '1.26.1'
cache-dependency-path: Packages/src/GoCli~/go.sum

- name: Test native CLI
working-directory: Packages/src/GoCli~
run: go test ./...
- name: Install golangci-lint
run: |
go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.12.0
echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH"

- name: Check native CLI
run: scripts/check-go-cli.sh

- name: Build native CLI binaries
run: scripts/build-go-cli.sh
Expand Down
12 changes: 9 additions & 3 deletions .github/workflows/security-scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ on:
- 'Packages/src/**/*.cs'
- 'Assets/**/*.cs'
- 'Packages/src/GoCli~/**/*.go'
- 'Packages/src/GoCli~/.golangci.yml'
- 'Packages/src/GoCli~/go.mod'
- 'Packages/src/GoCli~/go.sum'
pull_request:
Expand All @@ -15,6 +16,7 @@ on:
- 'Packages/src/**/*.cs'
- 'Assets/**/*.cs'
- 'Packages/src/GoCli~/**/*.go'
- 'Packages/src/GoCli~/.golangci.yml'
- 'Packages/src/GoCli~/go.mod'
- 'Packages/src/GoCli~/go.sum'
workflow_dispatch:
Expand Down Expand Up @@ -113,6 +115,10 @@ jobs:
go-version: '1.26.1'
cache-dependency-path: Packages/src/GoCli~/go.sum

- name: Run Go tests
working-directory: Packages/src/GoCli~
run: go test ./...
- name: Install golangci-lint
run: |
go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.12.0
echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH"

- name: Check Go CLI
run: scripts/check-go-cli.sh
12 changes: 12 additions & 0 deletions Packages/src/GoCli~/.golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
version: "2"

linters:
default: standard

formatters:
enable:
- gofumpt
- goimports

run:
timeout: 5m
Binary file modified Packages/src/GoCli~/dist/darwin-amd64/uloop-core
Binary file not shown.
Binary file modified Packages/src/GoCli~/dist/darwin-amd64/uloop-dispatcher
Binary file not shown.
Binary file modified Packages/src/GoCli~/dist/darwin-arm64/uloop-core
Binary file not shown.
Binary file modified Packages/src/GoCli~/dist/darwin-arm64/uloop-dispatcher
Binary file not shown.
Binary file modified Packages/src/GoCli~/dist/windows-amd64/uloop-core.exe
Binary file not shown.
Binary file modified Packages/src/GoCli~/dist/windows-amd64/uloop-dispatcher.exe
Binary file not shown.
26 changes: 13 additions & 13 deletions Packages/src/GoCli~/internal/cli/completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func tryHandleCompletionRequest(args []string, cache toolsCache, stdout io.Write

if args[0] == listOptionsFlag {
if len(args) < 2 {
fmt.Fprintln(stderr, "--list-options requires a command name")
writeLine(stderr, "--list-options requires a command name")
return true, 1
}
printOptionsForCommand(args[1], cache, stdout)
Expand All @@ -64,7 +64,7 @@ func tryHandleCompletionRequest(args []string, cache toolsCache, stdout io.Write

request, err := parseCompletionRequest(args[1:])
if err != nil {
fmt.Fprintln(stderr, err.Error())
writeLine(stderr, err.Error())
return true, 1
}

Expand All @@ -73,32 +73,32 @@ func tryHandleCompletionRequest(args []string, cache toolsCache, stdout io.Write
shellName = detectShell()
}
if shellName == "" {
fmt.Fprintln(stderr, "Could not detect shell. Use --shell bash, --shell zsh, --shell powershell, or --shell pwsh.")
writeLine(stderr, "Could not detect shell. Use --shell bash, --shell zsh, --shell powershell, or --shell pwsh.")
return true, 1
}

script := getCompletionScript(shellName)
if !request.install {
fmt.Fprintln(stdout, script)
writeLine(stdout, script)
return true, 0
}

configPath, err := getShellConfigPath(shellName)
if err != nil {
fmt.Fprintln(stderr, err.Error())
writeLine(stderr, err.Error())
return true, 1
}
if err := installCompletionScript(configPath, shellName, script); err != nil {
fmt.Fprintln(stderr, err.Error())
writeLine(stderr, err.Error())
return true, 1
}

fmt.Fprintf(stdout, "Completion installed to %s\n", configPath)
writeFormat(stdout, "Completion installed to %s\n", configPath)
if isPowerShellShell(shellName) {
fmt.Fprintln(stdout, "Restart PowerShell to enable completion.")
writeLine(stdout, "Restart PowerShell to enable completion.")
return true, 0
}
fmt.Fprintf(stdout, "Run 'source %s' or restart your shell to enable completion.\n", configPath)
writeFormat(stdout, "Run 'source %s' or restart your shell to enable completion.\n", configPath)
return true, 0
}

Expand Down Expand Up @@ -172,7 +172,7 @@ func printCommandNames(cache toolsCache, stdout io.Writer) {
commands = append(commands, tool.Name)
}
sort.Strings(commands)
fmt.Fprintln(stdout, strings.Join(commands, "\n"))
writeLine(stdout, strings.Join(commands, "\n"))
}

func printOptionsForCommand(command string, cache toolsCache, stdout io.Writer) {
Expand All @@ -192,7 +192,7 @@ func printOptionsForCommand(command string, cache toolsCache, stdout io.Writer)
options = append(options, "--"+pascalToKebab(propertyName))
}
sort.Strings(options)
fmt.Fprintln(stdout, strings.Join(options, "\n"))
writeLine(stdout, strings.Join(options, "\n"))
}

func detectShell() string {
Expand Down Expand Up @@ -322,6 +322,6 @@ func isPowerShellShell(shellName string) bool {
}

func printCompletionHelp(stdout io.Writer) {
fmt.Fprintln(stdout, "Usage:")
fmt.Fprintln(stdout, " uloop completion [--shell bash|zsh|powershell|pwsh] [--install]")
writeLine(stdout, "Usage:")
writeLine(stdout, " uloop completion [--shell bash|zsh|powershell|pwsh] [--install]")
}
7 changes: 3 additions & 4 deletions Packages/src/GoCli~/internal/cli/fix.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package cli

import (
"fmt"
"io"
"os"
"path/filepath"
Expand All @@ -17,16 +16,16 @@ var staleLockFileNames = []string{
func runFix(projectRoot string, stdout io.Writer, stderr io.Writer) int {
cleaned, err := cleanupStaleLockFiles(projectRoot)
if err != nil {
fmt.Fprintln(stderr, err.Error())
writeLine(stderr, err.Error())
return 1
}

if cleaned == 0 {
fmt.Fprintln(stdout, "No lock files found.")
writeLine(stdout, "No lock files found.")
return 0
}

fmt.Fprintf(stdout, "\nCleaned up %d lock file(s).\n", cleaned)
writeFormat(stdout, "\nCleaned up %d lock file(s).\n", cleaned)
return 0
}

Expand Down
50 changes: 25 additions & 25 deletions Packages/src/GoCli~/internal/cli/launch.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func tryHandleLaunchRequest(

options, err := parseLaunchOptions(args[1:], globalProjectPath)
if err != nil {
fmt.Fprintln(stderr, err.Error())
writeLine(stderr, err.Error())
return true, 1
}

Expand Down Expand Up @@ -147,47 +147,47 @@ func isInvalidLaunchOptionValue(option string, value string) bool {
func runLaunch(ctx context.Context, options launchOptions, startPath string, stdout io.Writer, stderr io.Writer) int {
projectRoot, err := resolveLaunchProjectRoot(startPath, options)
if err != nil {
fmt.Fprintln(stderr, err.Error())
writeLine(stderr, err.Error())
return 1
}

if options.deleteRecovery {
if err := os.RemoveAll(filepath.Join(projectRoot, recoveryDirectoryPath)); err != nil {
fmt.Fprintln(stderr, err.Error())
writeLine(stderr, err.Error())
return 1
}
}

runningProcess, err := findRunningUnityProcess(ctx, projectRoot)
if err != nil {
fmt.Fprintln(stderr, err.Error())
writeLine(stderr, err.Error())
return 1
}

if runningProcess != nil {
if !options.restart && !options.quit {
_ = focusUnityProcess(ctx, runningProcess.pid)
fmt.Fprintf(stdout, "Unity is already running for %s (PID: %d)\n", projectRoot, runningProcess.pid)
writeFormat(stdout, "Unity is already running for %s (PID: %d)\n", projectRoot, runningProcess.pid)
return 0
}
if err := killUnityProcess(runningProcess.pid); err != nil {
fmt.Fprintln(stderr, err.Error())
writeLine(stderr, err.Error())
return 1
}
if options.quit {
fmt.Fprintf(stdout, "Unity process stopped (PID: %d)\n", runningProcess.pid)
writeFormat(stdout, "Unity process stopped (PID: %d)\n", runningProcess.pid)
return 0
}
}

if options.quit {
fmt.Fprintln(stdout, "No Unity process is running for this project.")
writeLine(stdout, "No Unity process is running for this project.")
return 0
}

unityPath, err := resolveUnityExecutablePath(projectRoot)
if err != nil {
fmt.Fprintln(stderr, err.Error())
writeLine(stderr, err.Error())
return 1
}

Expand All @@ -198,16 +198,16 @@ func runLaunch(ctx context.Context, options launchOptions, startPath string, std

command := exec.CommandContext(ctx, unityPath, launchArgs...)
if err := command.Start(); err != nil {
fmt.Fprintln(stderr, err.Error())
writeLine(stderr, err.Error())
return 1
}
fmt.Fprintf(stdout, "Unity launch started for %s (PID: %d)\n", projectRoot, command.Process.Pid)
writeFormat(stdout, "Unity launch started for %s (PID: %d)\n", projectRoot, command.Process.Pid)

if err := waitForLaunchReady(ctx, projectRoot); err != nil {
fmt.Fprintln(stderr, err.Error())
writeLine(stderr, err.Error())
return 1
}
fmt.Fprintln(stdout, "Unity is ready.")
writeLine(stdout, "Unity is ready.")
return 0
}

Expand Down Expand Up @@ -238,7 +238,7 @@ func resolveUnityExecutablePath(projectRoot string) (string, error) {
}
}
if len(candidates) == 0 {
return "", fmt.Errorf("Unity launch is not supported on %s", runtime.GOOS)
return "", fmt.Errorf("unity launch is not supported on %s", runtime.GOOS)
}
return candidates[0], nil
}
Expand Down Expand Up @@ -277,11 +277,11 @@ func readUnityEditorVersion(projectRoot string) (string, error) {
}
matches := editorVersionPattern.FindStringSubmatch(string(content))
if len(matches) != 2 {
return "", fmt.Errorf("Unity editor version not found in %s", projectVersionFilePath)
return "", fmt.Errorf("unity editor version not found in %s", projectVersionFilePath)
}
version := strings.TrimSpace(matches[1])
if version == "" {
return "", fmt.Errorf("Unity editor version is empty in %s", projectVersionFilePath)
return "", fmt.Errorf("unity editor version is empty in %s", projectVersionFilePath)
}
return version, nil
}
Expand Down Expand Up @@ -318,13 +318,13 @@ func waitForLaunchReady(ctx context.Context, projectRoot string) error {
}

func printLaunchHelp(stdout io.Writer) {
fmt.Fprintln(stdout, "Usage:")
fmt.Fprintln(stdout, " uloop launch [options] [project-path]")
fmt.Fprintln(stdout, "")
fmt.Fprintln(stdout, "Options:")
fmt.Fprintln(stdout, " -r, --restart Kill an existing Unity process for the project before launching")
fmt.Fprintln(stdout, " -q, --quit Kill an existing Unity process for the project without launching")
fmt.Fprintln(stdout, " -d, --delete-recovery Delete Assets/_Recovery before launch")
fmt.Fprintln(stdout, " -p, --platform <name> Pass Unity -buildTarget when launching")
fmt.Fprintln(stdout, " --max-depth <n> Accepted for compatibility when searching from the current directory")
writeLine(stdout, "Usage:")
writeLine(stdout, " uloop launch [options] [project-path]")
writeLine(stdout, "")
writeLine(stdout, "Options:")
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, " -p, --platform <name> Pass Unity -buildTarget when launching")
writeLine(stdout, " --max-depth <n> Accepted for compatibility when searching from the current directory")
}
16 changes: 16 additions & 0 deletions Packages/src/GoCli~/internal/cli/output.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package cli

import (
"fmt"
"io"
)

func writeLine(writer io.Writer, values ...any) {
// CLI status output failures are not recoverable after command outcome is decided.
_, _ = fmt.Fprintln(writer, values...)
}

func writeFormat(writer io.Writer, format string, values ...any) {
// CLI status output failures are not recoverable after command outcome is decided.
_, _ = fmt.Fprintf(writer, format, values...)
}
Loading