Skip to content

Commit ebfeb28

Browse files
committed
refactor: restructure pipeline and session examples, update executor implementations, and improve server components
1 parent ad6d745 commit ebfeb28

File tree

24 files changed

+958
-973
lines changed

24 files changed

+958
-973
lines changed

cmd/runshell/cmd/exec.go

Lines changed: 9 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -30,61 +30,28 @@ var execCmd = &cobra.Command{
3030
var exec types.Executor
3131
var err error
3232
if execDockerImage != "" {
33-
exec, err = executor.NewDockerExecutor(types.DockerConfig{
33+
exec, err = executor.NewDockerExecutorBuilder(types.DockerConfig{
3434
Image: execDockerImage,
35-
}, nil)
35+
}, nil).Build()
3636
if err != nil {
3737
return fmt.Errorf("failed to create Docker executor: %w", err)
3838
}
3939
} else {
40-
exec = executor.NewLocalExecutor(types.LocalConfig{
40+
exec, err = executor.NewLocalExecutorBuilder(types.LocalConfig{
4141
AllowUnregisteredCommands: true,
42-
}, nil)
42+
}, nil).Build()
43+
if err != nil {
44+
return fmt.Errorf("failed to create local executor: %w", err)
45+
}
4346
}
4447

4548
// 创建管道执行器
4649
pipeExec := executor.NewPipelineExecutor(exec)
4750

48-
// 检查是否包含管道符
49-
cmdStr := strings.Join(args, " ")
50-
if strings.Contains(cmdStr, "|") {
51-
// 解析管道命令
52-
pipeline, err := pipeExec.ParsePipeline(cmdStr)
53-
if err != nil {
54-
return fmt.Errorf("failed to parse pipeline: %w", err)
55-
}
56-
57-
// 设置执行选项
58-
pipeline.Options = &types.ExecuteOptions{
59-
WorkDir: execWorkDir,
60-
Env: parseEnvVars(execEnvVars),
61-
Stdin: os.Stdin,
62-
Stdout: os.Stdout,
63-
Stderr: os.Stderr,
64-
}
65-
pipeline.Context = cmd.Context()
66-
67-
// 执行管道命令
68-
result, err := pipeExec.ExecutePipeline(pipeline)
69-
if err != nil {
70-
// 检查是否是 grep 命令没有匹配项的情况
71-
if strings.Contains(cmdStr, "grep") && result != nil && result.ExitCode == 1 {
72-
return nil
73-
}
74-
return fmt.Errorf("failed to execute pipeline: %w", err)
75-
}
76-
77-
if result.ExitCode != 0 {
78-
return fmt.Errorf("pipeline failed with exit code %d", result.ExitCode)
79-
}
80-
81-
return nil
82-
}
83-
8451
// 非管道命令的处理
8552
ctx := &types.ExecuteContext{
8653
Context: cmd.Context(),
87-
Command: types.Command{Command: args[0]},
54+
Command: types.Command{Command: args[0], Args: args[1:]},
8855
Options: &types.ExecuteOptions{
8956
WorkDir: execWorkDir,
9057
Env: parseEnvVars(execEnvVars),
@@ -95,7 +62,7 @@ var execCmd = &cobra.Command{
9562
Executor: exec,
9663
}
9764

98-
result, err := exec.Execute(ctx)
65+
result, err := pipeExec.Execute(ctx)
9966
if err != nil {
10067
return fmt.Errorf("failed to execute command: %w", err)
10168
}

cmd/runshell/cmd/exec_test.go

Lines changed: 0 additions & 140 deletions
This file was deleted.

cmd/runshell/cmd/server.go

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,14 @@ var serverCmd = &cobra.Command{
2525
Short: "Start the HTTP server",
2626
Long: `Start the HTTP server to handle command execution requests.`,
2727
RunE: func(cmd *cobra.Command, args []string) error {
28-
var err error
29-
// 创建执行器
30-
var exec types.Executor
28+
// 创建执行器构建器
29+
var execBuilder types.ExecutorBuilder
3130
if dockerImage != "" {
32-
exec, err = executor.NewDockerExecutor(types.DockerConfig{
31+
execBuilder = executor.NewDockerExecutorBuilder(types.DockerConfig{
3332
Image: dockerImage,
3433
}, nil)
35-
if err != nil {
36-
return fmt.Errorf("failed to create Docker executor: %w", err)
37-
}
3834
} else {
39-
exec = executor.NewLocalExecutor(types.LocalConfig{
35+
execBuilder = executor.NewLocalExecutorBuilder(types.LocalConfig{
4036
AllowUnregisteredCommands: true,
4137
}, nil)
4238
}
@@ -50,12 +46,19 @@ var serverCmd = &cobra.Command{
5046
return fmt.Errorf("failed to create auditor: %w", err)
5147
}
5248

53-
// 创建审计执行器
54-
exec = executor.NewAuditedExecutor(exec, auditor)
49+
// 创建审计执行器构建器
50+
origBuilder := execBuilder
51+
execBuilder = types.ExecutorBuilderFunc(func() (types.Executor, error) {
52+
exec, err := origBuilder.Build()
53+
if err != nil {
54+
return nil, err
55+
}
56+
return executor.NewAuditedExecutor(exec, auditor), nil
57+
})
5558
}
5659

5760
// 创建服务器
58-
srv := server.NewServer(exec, serverAddr)
61+
srv := server.NewServer(execBuilder, serverAddr)
5962

6063
// 启动服务器
6164
if err := srv.Start(); err != nil {
Lines changed: 25 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import (
2424
"context"
2525
"fmt"
2626
"log"
27-
"os"
2827

2928
"github.com/iamlongalong/runshell/pkg/executor"
3029
"github.com/iamlongalong/runshell/pkg/types"
@@ -47,26 +46,24 @@ import (
4746
//
4847
// runPipeline(pipeExec, "ls -la | grep go", nil)
4948
// runPipeline(pipeExec, "cat file.txt | grep pattern | wc -l", env)
50-
func runPipeline(pipeExec *executor.PipelineExecutor, cmdStr string, env map[string]string) error {
49+
func runPipeline(ctx context.Context, pipeExec *executor.PipelineExecutor, cmdStr string, env map[string]string) error {
5150
fmt.Printf("\nExecuting: %s\n", cmdStr)
5251

53-
pipeline, err := pipeExec.ParsePipeline(cmdStr)
54-
if err != nil {
55-
return fmt.Errorf("failed to parse pipeline: %v", err)
56-
}
57-
58-
pipeline.Context = context.Background()
59-
pipeline.Options = &types.ExecuteOptions{
60-
Stdout: os.Stdout,
61-
Stderr: os.Stderr,
62-
Env: env,
63-
}
64-
65-
result, err := pipeExec.ExecutePipeline(pipeline)
52+
result, err := pipeExec.Execute(&types.ExecuteContext{
53+
Context: ctx,
54+
Command: types.Command{
55+
Command: cmdStr,
56+
},
57+
Options: &types.ExecuteOptions{
58+
Env: env,
59+
},
60+
})
6661
if err != nil {
6762
return fmt.Errorf("failed to execute pipeline: %v", err)
6863
}
6964

65+
fmt.Printf("Pipeline Output:\n%s\n", result.Output)
66+
7067
fmt.Printf("Pipeline exit code: %d\n", result.ExitCode)
7168
return nil
7269
}
@@ -77,47 +74,44 @@ func main() {
7774
AllowUnregisteredCommands: true,
7875
}, &types.ExecuteOptions{})
7976

77+
ctx := context.Background()
78+
8079
// 创建管道执行器
8180
pipeExec := executor.NewPipelineExecutor(localExec)
8281

8382
// 示例 1: 简单的管道命令
84-
// 列出当前目录内容并过滤包含 "go" 的行
8583
fmt.Println("\n=== Example 1: Simple Pipeline ===")
86-
err := runPipeline(pipeExec, "ls -la | grep go", nil)
84+
err := runPipeline(ctx, pipeExec, "ls -la | grep go", nil)
8785
if err != nil {
8886
log.Printf("Example 1 failed: %v\n", err)
8987
}
9088

9189
// 示例 2: 多重管道命令
92-
// 统计当前目录中包含 "go" 的文件数量
9390
fmt.Println("\n=== Example 2: Multiple Pipes ===")
94-
err = runPipeline(pipeExec, "ls -la | grep go | wc -l", nil)
91+
err = runPipeline(ctx, pipeExec, "ls -la | grep go | wc -l", nil)
9592
if err != nil {
9693
log.Printf("Example 2 failed: %v\n", err)
9794
}
9895

9996
// 示例 3: 带环境变量的管道命令
100-
// 显示系统路径信息,并添加自定义路径
101-
fmt.Println("\n=== Example 3: Pipeline with Environment Variables ===")
102-
err = runPipeline(pipeExec, "env | grep PATH", map[string]string{
103-
"CUSTOM_PATH": "/custom/path",
97+
fmt.Println("\n=== Example 3: Environment Variables ===")
98+
err = runPipeline(ctx, pipeExec, "pwd | tr '[:lower:]' '[:upper:]'", map[string]string{
99+
"PWD": "/custom/path",
104100
})
105101
if err != nil {
106102
log.Printf("Example 3 failed: %v\n", err)
107103
}
108104

109-
// 示例 4: 复杂的管道命令
110-
// 查找并排序 Go 相关进程,显示前三个
111-
fmt.Println("\n=== Example 4: Complex Pipeline ===")
112-
err = runPipeline(pipeExec, "ps aux | grep go | sort -k2 | head -n 3", nil)
105+
// 示例 4: 文本处理
106+
fmt.Println("\n=== Example 4: Text Processing ===")
107+
err = runPipeline(ctx, pipeExec, "echo hello world | tr '[:lower:]' '[:upper:]'", nil)
113108
if err != nil {
114109
log.Printf("Example 4 failed: %v\n", err)
115110
}
116111

117-
// 示例 5: 文件处理管道命令
118-
// 分析 go.mod 文件中的依赖项
119-
fmt.Println("\n=== Example 5: File Processing Pipeline ===")
120-
err = runPipeline(pipeExec, "cat ../go.mod | grep require | sort | uniq -c", nil)
112+
// 示例 5: 多命令管道
113+
fmt.Println("\n=== Example 5: Multiple Commands ===")
114+
err = runPipeline(ctx, pipeExec, `echo 'hi\nhello\nworld' | grep o`, nil)
121115
if err != nil {
122116
log.Printf("Example 5 failed: %v\n", err)
123117
}

0 commit comments

Comments
 (0)