Skip to content

Commit a26539c

Browse files
committed
Copy sdkbuild from temporalio/features
1 parent d99355b commit a26539c

File tree

10 files changed

+992
-34
lines changed

10 files changed

+992
-34
lines changed

cmd/prepare_worker.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ import (
1010

1111
"github.com/spf13/cobra"
1212
"github.com/spf13/pflag"
13-
"github.com/temporalio/features/sdkbuild"
1413
"github.com/temporalio/omes/cmd/cmdoptions"
14+
"github.com/temporalio/omes/sdkbuild"
1515
"go.uber.org/zap"
1616
)
1717

cmd/run_worker.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ import (
1414

1515
"github.com/spf13/cobra"
1616
"github.com/spf13/pflag"
17-
"github.com/temporalio/features/sdkbuild"
1817
"github.com/temporalio/omes/cmd/cmdoptions"
1918
"github.com/temporalio/omes/loadgen"
19+
"github.com/temporalio/omes/sdkbuild"
2020
"go.temporal.io/sdk/client"
2121
"go.temporal.io/sdk/testsuite"
2222
)

go.mod

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,18 @@ go 1.20
55
require (
66
github.com/gogo/protobuf v1.3.2
77
github.com/golang/protobuf v1.5.3
8+
github.com/otiai10/copy v1.14.0
89
github.com/prometheus/client_golang v1.16.0
910
github.com/spf13/cobra v1.7.0
1011
github.com/spf13/pflag v1.0.5
1112
github.com/stretchr/testify v1.8.4
12-
github.com/temporalio/features v0.0.0-20231218231852-27c681667dae
1313
go.temporal.io/api v1.26.1
14-
go.temporal.io/sdk v1.25.2-0.20231129171107-288a04f72145
14+
go.temporal.io/sdk v1.25.2-0.20240109200522-5ca9a4dfd4c3
1515
go.uber.org/zap v1.25.0
16-
golang.org/x/mod v0.12.0
16+
golang.org/x/mod v0.14.0
1717
golang.org/x/sync v0.5.0
1818
golang.org/x/sys v0.15.0
19-
google.golang.org/protobuf v1.31.0
19+
google.golang.org/protobuf v1.32.0
2020
)
2121

2222
require (
@@ -36,27 +36,20 @@ require (
3636
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
3737
github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.1 // indirect
3838
github.com/inconshreveable/mousetrap v1.1.0 // indirect
39-
github.com/otiai10/copy v1.14.0 // indirect
4039
github.com/pborman/uuid v1.2.1 // indirect
4140
github.com/pmezard/go-difflib v1.0.0 // indirect
4241
github.com/robfig/cron v1.2.0 // indirect
4342
github.com/stretchr/objx v0.5.1 // indirect
4443
go.uber.org/atomic v1.11.0 // indirect
4544
go.uber.org/goleak v1.2.1 // indirect
4645
go.uber.org/multierr v1.11.0 // indirect
46+
golang.org/x/exp v0.0.0-20231127185646-65229373498e // indirect
4747
golang.org/x/net v0.19.0 // indirect
4848
golang.org/x/text v0.14.0 // indirect
4949
golang.org/x/time v0.3.0 // indirect
50-
google.golang.org/genproto v0.0.0-20231127180814-3a041ad873d4 // indirect
51-
google.golang.org/genproto/googleapis/api v0.0.0-20231127180814-3a041ad873d4 // indirect
52-
google.golang.org/genproto/googleapis/rpc v0.0.0-20231127180814-3a041ad873d4 // indirect
53-
google.golang.org/grpc v1.59.0 // indirect
50+
google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917 // indirect
51+
google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 // indirect
52+
google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917 // indirect
53+
google.golang.org/grpc v1.60.1 // indirect
5454
gopkg.in/yaml.v3 v3.0.1 // indirect
5555
)
56-
57-
// This is dumb, but necesary because Go (for some commands) can't figure out the transitive
58-
// local-replace inside of the features module itself, so we have to help it.
59-
replace (
60-
github.com/temporalio/features/features => github.com/temporalio/features/features v0.0.0-20231218231852-27c681667dae
61-
github.com/temporalio/features/harness/go => github.com/temporalio/features/harness/go v0.0.0-20231218231852-27c681667dae
62-
)

go.sum

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -98,15 +98,13 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
9898
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
9999
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
100100
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
101-
github.com/temporalio/features v0.0.0-20231218231852-27c681667dae h1:d5LK3X10VZEWpLhZ5dIPcirvELKVtT4rEV+8wzfgBRM=
102-
github.com/temporalio/features v0.0.0-20231218231852-27c681667dae/go.mod h1:Jm0Yq8DKEkSzcQ1YbZ5yeqrD6iyyWzQMcsXF0G1ylM4=
103101
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
104102
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
105103
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
106104
go.temporal.io/api v1.26.1 h1:YqGQsOr/Tx4nVdA8wCv74AxesaIzCRHWb3KkHrYqI8k=
107105
go.temporal.io/api v1.26.1/go.mod h1:Y/rALXTprFO+bvAlAfLFoJj7KpQIcL4GDQVN6fhYIa4=
108-
go.temporal.io/sdk v1.25.2-0.20231129171107-288a04f72145 h1:aV7tRpzB3tr9LGs4/SN7MSWSbVx+bgDYfOoGMjk4oEM=
109-
go.temporal.io/sdk v1.25.2-0.20231129171107-288a04f72145/go.mod h1:MHw8PEOVmOJC1yduTVxYq1GsM5kkQg0sIwRST7cRHoo=
106+
go.temporal.io/sdk v1.25.2-0.20240109200522-5ca9a4dfd4c3 h1:XzkvOc0UATBM0SC2SO/GKaXq3JkJwe2rDeRhW2u11zM=
107+
go.temporal.io/sdk v1.25.2-0.20240109200522-5ca9a4dfd4c3/go.mod h1:nRT6pheoo7UXrrgMh26r7t4IuJFZmu277SkaiVp/tZE=
110108
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
111109
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
112110
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
@@ -123,15 +121,17 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
123121
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
124122
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
125123
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
124+
golang.org/x/exp v0.0.0-20231127185646-65229373498e h1:Gvh4YaCaXNs6dKTlfgismwWZKyjVZXwOPfIyUaqU3No=
125+
golang.org/x/exp v0.0.0-20231127185646-65229373498e/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
126126
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
127127
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
128128
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
129129
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
130130
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
131131
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
132132
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
133-
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
134-
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
133+
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
134+
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
135135
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
136136
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
137137
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -190,23 +190,23 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
190190
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
191191
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
192192
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
193-
google.golang.org/genproto v0.0.0-20231127180814-3a041ad873d4 h1:W12Pwm4urIbRdGhMEg2NM9O3TWKjNcxQhs46V0ypf/k=
194-
google.golang.org/genproto v0.0.0-20231127180814-3a041ad873d4/go.mod h1:5RBcpGRxr25RbDzY5w+dmaqpSEvl8Gwl1x2CICf60ic=
195-
google.golang.org/genproto/googleapis/api v0.0.0-20231127180814-3a041ad873d4 h1:ZcOkrmX74HbKFYnpPY8Qsw93fC29TbJXspYKaBkSXDQ=
196-
google.golang.org/genproto/googleapis/api v0.0.0-20231127180814-3a041ad873d4/go.mod h1:k2dtGpRrbsSyKcNPKKI5sstZkrNCZwpU/ns96JoHbGg=
197-
google.golang.org/genproto/googleapis/rpc v0.0.0-20231127180814-3a041ad873d4 h1:DC7wcm+i+P1rN3Ff07vL+OndGg5OhNddHyTA+ocPqYE=
198-
google.golang.org/genproto/googleapis/rpc v0.0.0-20231127180814-3a041ad873d4/go.mod h1:eJVxU6o+4G1PSczBr85xmyvSNYAKvAYgkub40YGomFM=
193+
google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917 h1:nz5NESFLZbJGPFxDT/HCn+V1mZ8JGNoY4nUpmW/Y2eg=
194+
google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917/go.mod h1:pZqR+glSb11aJ+JQcczCvgf47+duRuzNSKqE8YAQnV0=
195+
google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 h1:rcS6EyEaoCO52hQDupoSfrxI3R6C2Tq741is7X8OvnM=
196+
google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917/go.mod h1:CmlNWB9lSezaYELKS5Ym1r44VrrbPUa7JTvw+6MbpJ0=
197+
google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917 h1:6G8oQ016D88m1xAKljMlBOOGWDZkes4kMhgGFlf8WcQ=
198+
google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917/go.mod h1:xtjpI3tXFPP051KaWnhvxkiubL/6dJ18vLVf7q2pTOU=
199199
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
200200
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
201201
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
202202
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
203203
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
204-
google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
205-
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
204+
google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU=
205+
google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM=
206206
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
207207
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
208-
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
209-
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
208+
google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
209+
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
210210
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
211211
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
212212
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=

sdkbuild/dotnet.go

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
package sdkbuild
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"html"
7+
"os"
8+
"os/exec"
9+
"path/filepath"
10+
"runtime"
11+
"strings"
12+
)
13+
14+
// BuildDotNetProgramOptions are options for BuildDotNetProgram.
15+
type BuildDotNetProgramOptions struct {
16+
// Directory that will have a temporary directory created underneath.
17+
BaseDir string
18+
// Required version. If it contains a slash, it is assumed to be a path to the
19+
// base of the repo (and will have a src/Temporalio/Temporalio.csproj child).
20+
// Otherwise it is a NuGet version.
21+
Version string
22+
// If present, this directory is expected to exist beneath base dir. Otherwise
23+
// a temporary dir is created.
24+
DirName string
25+
// Required Program.cs content. If not set, no Program.cs is created (so it)
26+
ProgramContents string
27+
// Required csproj content. This should not contain a dependency on Temporalio
28+
// because this adds a package/project reference near the end.
29+
CsprojContents string
30+
}
31+
32+
// DotNetProgram is a .NET-specific implementation of Program.
33+
type DotNetProgram struct {
34+
dir string
35+
}
36+
37+
var _ Program = (*DotNetProgram)(nil)
38+
39+
func BuildDotNetProgram(ctx context.Context, options BuildDotNetProgramOptions) (*DotNetProgram, error) {
40+
if options.BaseDir == "" {
41+
return nil, fmt.Errorf("base dir required")
42+
} else if options.Version == "" {
43+
return nil, fmt.Errorf("version required")
44+
} else if options.ProgramContents == "" {
45+
return nil, fmt.Errorf("program contents required")
46+
} else if options.CsprojContents == "" {
47+
return nil, fmt.Errorf("csproj contents required")
48+
}
49+
50+
// Create temp dir if needed that we will remove if creating is unsuccessful
51+
success := false
52+
var dir string
53+
if options.DirName != "" {
54+
dir = filepath.Join(options.BaseDir, options.DirName)
55+
} else {
56+
var err error
57+
dir, err = os.MkdirTemp(options.BaseDir, "program-")
58+
if err != nil {
59+
return nil, fmt.Errorf("failed making temp dir: %w", err)
60+
}
61+
defer func() {
62+
if !success {
63+
// Intentionally swallow error
64+
_ = os.RemoveAll(dir)
65+
}
66+
}()
67+
}
68+
69+
// Create program.csproj
70+
var depLine string
71+
// Slash means it is a path
72+
if strings.ContainsAny(options.Version, `/\`) {
73+
// Get absolute path of csproj file
74+
absCsproj, err := filepath.Abs(filepath.Join(options.Version, "src/Temporalio/Temporalio.csproj"))
75+
if err != nil {
76+
return nil, fmt.Errorf("cannot make absolute path from version: %w", err)
77+
} else if _, err := os.Stat(absCsproj); err != nil {
78+
return nil, fmt.Errorf("cannot find version path of %v: %w", absCsproj, err)
79+
}
80+
depLine = `<ProjectReference Include="` + html.EscapeString(absCsproj) + `" />`
81+
// Need to build this csproj first
82+
cmd := exec.CommandContext(ctx, "dotnet", "build", absCsproj)
83+
cmd.Dir = dir
84+
cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
85+
if err := cmd.Run(); err != nil {
86+
return nil, fmt.Errorf("failed dotnet build of csproj in version: %w", err)
87+
}
88+
} else {
89+
depLine = `<PackageReference Include="Temporalio" Version="` +
90+
html.EscapeString(strings.TrimPrefix(options.Version, "v")) + `" />`
91+
}
92+
// Add the item group for the Temporalio dep just before the ending project tag
93+
endProjectTag := strings.LastIndex(options.CsprojContents, "</Project>")
94+
if endProjectTag == -1 {
95+
return nil, fmt.Errorf("no ending project tag found in csproj contents")
96+
}
97+
csproj := options.CsprojContents[:endProjectTag] + "\n <ItemGroup>\n " + depLine +
98+
"\n </ItemGroup>\n" + options.CsprojContents[endProjectTag:]
99+
if err := os.WriteFile(filepath.Join(dir, "program.csproj"), []byte(csproj), 0644); err != nil {
100+
return nil, fmt.Errorf("failed writing program.csproj: %w", err)
101+
}
102+
103+
// Create Program.cs
104+
if err := os.WriteFile(filepath.Join(dir, "Program.cs"), []byte(options.ProgramContents), 0644); err != nil {
105+
return nil, fmt.Errorf("failed writing Program.cs: %w", err)
106+
}
107+
108+
// Build it into build folder
109+
cmd := exec.CommandContext(ctx, "dotnet", "build", "--output", "build")
110+
cmd.Dir = dir
111+
cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
112+
if err := cmd.Run(); err != nil {
113+
return nil, fmt.Errorf("failed dotnet build: %w", err)
114+
}
115+
116+
// All good
117+
success = true
118+
return &DotNetProgram{dir}, nil
119+
}
120+
121+
// DotNetProgramFromDir recreates the Go program from a Dir() result of a
122+
// BuildDotNetProgram().
123+
func DotNetProgramFromDir(dir string) (*DotNetProgram, error) {
124+
// Quick sanity check on the presence of program.csproj
125+
if _, err := os.Stat(filepath.Join(dir, "program.csproj")); err != nil {
126+
return nil, fmt.Errorf("failed finding program.csproj in dir: %w", err)
127+
}
128+
return &DotNetProgram{dir}, nil
129+
}
130+
131+
// Dir is the directory to run in.
132+
func (d *DotNetProgram) Dir() string { return d.dir }
133+
134+
// NewCommand makes a new command for the given args.
135+
func (d *DotNetProgram) NewCommand(ctx context.Context, args ...string) (*exec.Cmd, error) {
136+
exe := "./build/program"
137+
if runtime.GOOS == "windows" {
138+
exe += ".exe"
139+
}
140+
cmd := exec.CommandContext(ctx, exe, args...)
141+
cmd.Dir = d.dir
142+
cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
143+
return cmd, nil
144+
}

0 commit comments

Comments
 (0)