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
16 changes: 8 additions & 8 deletions engine/UPSTREAM.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,25 +31,25 @@
**9,621**(对照 `f4c50506`)、**9,659**(对照 `be48afbe`),生产 3,852、
测试 5,758。

2026-11-12 的 ports、killer 与 groups 重写在此基础上继续下降:对照 `26dbcae` 为
**7,847** 行 / 535 段,分布在 100 个文件(生产 3,142、测试 4,705)。
2026-11-12 的 ports、killer、groups 与 cmd 重写在此基础上继续下降:对照
`26dbcae` 为 **6,307** 行 / 410 段,分布在 75 个文件(生产 2,305、测试 4,002)。

按包(对照 `26dbcae`,ports、killer 与 groups 重写后):
按包(对照 `26dbcae`,ports、killer、groups 与 cmd 重写后):

| 包 | 生产 | 测试 | 合计 |
| --- | ---: | ---: | ---: |
| `internal/daemon` | 2,073 | 3,457 | 5,530 |
| `internal/cmd` | 837 | 703 | 1,540 |
| `internal/cmd` | 0 | 0 | 0 |
| `internal/groups` | 0 | 0 | 0 |
| `internal/scanner` | 220 | 540 | 760 |
| `internal/ports` | 0 | 0 | 0 |
| `internal/killer` | 0 | 0 | 0 |
| `internal/store` | 12 | 5 | 17 |

`internal/claims`、`internal/display`、`internal/testenv`、`internal/groups`、
`internal/ports`、`internal/killer` 与 `internal/store/claims*.go` 已经归零;
`internal/docker` 只剩结构体字段与表驱动用例数据。`internal/store` 已整包重写:
生产代码从 1,076 行降到 199 行。
`internal/claims`、`internal/cmd`、`internal/display`、`internal/testenv`、
`internal/groups`、`internal/ports`、`internal/killer` 与
`internal/store/claims*.go` 已经归零;`internal/docker` 只剩结构体字段与表驱动
用例数据。`internal/store` 已整包重写:生产代码从 1,076 行降到 199 行。

```sh
git clone https://github.com/raskrebs/sonar /tmp/sonar
Expand Down
107 changes: 58 additions & 49 deletions engine/internal/cmd/completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,61 +3,70 @@ package cmd
import (
"fmt"
"strconv"
"strings"

"github.com/sheathedsharp/option-berth/engine/internal/docker"
"github.com/sheathedsharp/option-berth/engine/internal/groups"
"github.com/sheathedsharp/option-berth/engine/internal/ports"
"github.com/spf13/cobra"
)

var completionCmd = &cobra.Command{
Use: "completion [bash|zsh|fish]",
Short: "Generate shell completion scripts",
GroupID: commandGroupInfra,
Long: `Generate shell completion scripts for option-berth.

To load completions:

Bash:
$ source <(oberth completion bash)

# To load completions for each session, execute once:
# Linux:
$ oberth completion bash > /etc/bash_completion.d/option-berth
# macOS:
$ oberth completion bash > $(brew --prefix)/etc/bash_completion.d/option-berth

Zsh:
# If shell completion is not already enabled in your environment,
# you will need to enable it. You can execute the following once:
$ echo "autoload -U compinit; compinit" >> ~/.zshrc

# To load completions for each session, execute once:
$ oberth completion zsh > "${fpath[1]}/_oberth"
// completionLong is the command's long help, one entry per output line so the
// per-shell recipes stay readable as a list rather than a block of prose.
var completionLong = strings.Join([]string{
"Generate shell completion scripts for option-berth.",
"",
"To load completions:",
"",
"Bash:",
" $ source <(oberth completion bash)",
"",
" # To load completions for each session, execute once:",
" # Linux:",
" $ oberth completion bash > /etc/bash_completion.d/option-berth",
" # macOS:",
" $ oberth completion bash > $(brew --prefix)/etc/bash_completion.d/option-berth",
"",
"Zsh:",
" # If shell completion is not already enabled in your environment,",
" # you will need to enable it. You can execute the following once:",
" $ echo \"autoload -U compinit; compinit\" >> ~/.zshrc",
"",
" # To load completions for each session, execute once:",
" $ oberth completion zsh > \"${fpath[1]}/_oberth\"",
"",
" # You will need to start a new shell for this setup to take effect.",
"",
"Fish:",
" $ oberth completion fish | source",
"",
" # To load completions for each session, execute once:",
" $ oberth completion fish > ~/.config/fish/completions/oberth.fish",
}, "\n") + "\n"

# You will need to start a new shell for this setup to take effect.

Fish:
$ oberth completion fish | source

# To load completions for each session, execute once:
$ oberth completion fish > ~/.config/fish/completions/oberth.fish
`,
var completionCmd = &cobra.Command{
Use: "completion [bash|zsh|fish]",
Short: "Generate shell completion scripts",
GroupID: commandGroupInfra,
Long: completionLong,
DisableFlagsInUseLine: true,
ValidArgs: []string{"bash", "zsh", "fish"},
Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs),
RunE: func(cmd *cobra.Command, args []string) error {
switch args[0] {
case "bash":
return cmd.Root().GenBashCompletion(cmd.OutOrStdout())
case "zsh":
return cmd.Root().GenZshCompletion(cmd.OutOrStdout())
case "fish":
return cmd.Root().GenFishCompletion(cmd.OutOrStdout(), true)
default:
return fmt.Errorf("unsupported shell: %s", args[0])
}
},
RunE: runCompletionShell,
}

// runCompletionShell writes the completion script the named shell reads.
func runCompletionShell(cmd *cobra.Command, args []string) error {
root, out := cmd.Root(), cmd.OutOrStdout()
switch args[0] {
case "bash":
return root.GenBashCompletion(out)
case "zsh":
return root.GenZshCompletion(out)
case "fish":
return root.GenFishCompletion(out, true)
}
return fmt.Errorf("unsupported shell: %s", args[0])
}

func init() {
Expand All @@ -80,11 +89,11 @@ var scanCompletionPorts = func() ([]ports.ListeningPort, error) {
return pp, nil
}

// completePort provides shell completions for commands that take a <port> argument.
// It scans listening ports, enriches them with Docker and process info, and returns
// completions formatted as "port\tdescription".
func completePort(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if len(args) > 0 {
// completePort offers candidate <port> arguments for the commands that take
// one: a listener scan enriched with Docker and process detail, rendered as
// "port\tdescription".
func completePort(_ *cobra.Command, args []string, _ string) ([]string, cobra.ShellCompDirective) {
if len(args) != 0 {
return nil, cobra.ShellCompDirectiveNoFileComp
}

Expand Down
6 changes: 3 additions & 3 deletions engine/internal/cmd/configsupport.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,9 @@ func configPathForProject(gg []state.Group, name string) string {
//
// The daemon parses `oberth.yaml` itself, so one that predates `port: auto`
// answers with "cannot unmarshal !!str `auto` into int" — an error about the
// file, for a problem with the daemon. This says the true thing instead, and
// what to do about it. A daemon from before capabilities were announced at all
// is treated the same way, which is right: it is older still.
// file, for a problem with the daemon. This says what is actually true, and
// what to do about it. A daemon from before capabilities were announced at
// all is treated the same way, which is right: it is older still.
func requireConfigSupport(c *client.Client, cfg *groups.Config) error {
return requireConfigSupportFor(c, cfg, true)
}
Expand Down
27 changes: 19 additions & 8 deletions engine/internal/cmd/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cmd

import (
"os"
"strings"

"github.com/sheathedsharp/option-berth/engine/internal/daemon/rpc"
"github.com/spf13/cobra"
Expand All @@ -15,17 +16,27 @@ var daemonCmd = &cobra.Command{
GroupID: commandGroupInfra,
}

// daemonSchemaLong is the schema command's long help, one entry per output line.
var daemonSchemaLong = strings.Join([]string{
"Print the JSON Schema describing every daemon type and method.",
"It is generated from the Go types and is byte-identical to the copy",
"checked in at docs/schema/protocol.schema.json.",
}, "\n")

var daemonSchemaCmd = &cobra.Command{
Use: "schema",
Short: "Print the daemon protocol JSON Schema",
Long: "Print the JSON Schema describing every daemon type and method.\n" +
"It is generated from the Go types and is byte-identical to the copy\n" +
"checked in at docs/schema/protocol.schema.json.",
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
_, err := os.Stdout.Write(rpc.Marshal())
return err
},
Long: daemonSchemaLong,
Args: cobra.NoArgs,
RunE: runDaemonSchema,
}

// runDaemonSchema writes the generated schema to stdout, where it is the whole
// answer.
func runDaemonSchema(_ *cobra.Command, _ []string) error {
schema := rpc.Marshal()
_, err := os.Stdout.Write(schema)
return err
}

func init() {
Expand Down
Loading
Loading