Skip to content

Commit 75cbcd7

Browse files
authored
make pipeline name optional (#2130)
fixes #2129
1 parent de1579d commit 75cbcd7

File tree

2 files changed

+149
-17
lines changed

2 files changed

+149
-17
lines changed

Diff for: cmd/conduit/root/pipelines/init.go

+38-17
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,13 @@ var (
4141
)
4242

4343
const (
44-
defaultSource = "generator"
45-
defaultDestination = "file"
44+
defaultSource = "generator"
45+
defaultDestination = "file"
46+
defaultPipelineName = "generator-to-file"
4647
)
4748

4849
type InitArgs struct {
49-
name string
50+
pipelineName string
5051
}
5152

5253
type InitFlags struct {
@@ -76,26 +77,27 @@ func (c *InitCommand) Flags() []ecdysis.Flag {
7677
}
7778

7879
func (c *InitCommand) Args(args []string) error {
79-
if len(args) == 0 {
80-
return cerrors.Errorf("requires a pipeline name")
81-
}
82-
83-
if len(args) > 1 {
80+
switch len(args) {
81+
case 0:
82+
c.args.pipelineName = defaultPipelineName
83+
case 1:
84+
c.args.pipelineName = args[0]
85+
default:
8486
return cerrors.Errorf("too many arguments")
8587
}
86-
c.args.name = args[0]
8788
return nil
8889
}
8990

90-
func (c *InitCommand) Usage() string { return "init PIPELINE_NAME" }
91+
func (c *InitCommand) Usage() string { return "init [PIPELINE_NAME]" }
9192

9293
func (c *InitCommand) Docs() ecdysis.Docs {
9394
return ecdysis.Docs{
9495
Short: "Initialize an example pipeline.",
9596
Long: `Initialize a pipeline configuration file, with all of parameters for source and destination connectors
9697
initialized and described. The source and destination connector can be chosen via flags. If no connectors are chosen, then
97-
a simple and runnable generator-to-log pipeline is configured.`,
98-
Example: "conduit pipelines init awesome-pipeline-name --source postgres --destination kafka \n" +
98+
a simple and runnable generator-to-log pipeline is configured. `,
99+
Example: "conduit pipelines init\n" +
100+
"conduit pipelines init awesome-pipeline-name --source postgres --destination kafka \n" +
99101
"conduit pipelines init file-to-pg --source file --destination postgres --pipelines.path ./my-pipelines",
100102
}
101103
}
@@ -201,7 +203,7 @@ func (c *InitCommand) buildTemplatePipeline() (pipelineTemplate, error) {
201203
}
202204

203205
return pipelineTemplate{
204-
Name: c.args.name,
206+
Name: c.getPipelineName(),
205207
SourceSpec: srcSpec,
206208
DestinationSpec: dstSpec,
207209
}, nil
@@ -233,8 +235,28 @@ func (c *InitCommand) write(pipeline pipelineTemplate) error {
233235
return nil
234236
}
235237

238+
// getPipelineName returns the desired pipeline name based on configuration.
239+
// If user provided one, it'll respect it. Otherwise, it'll be based on source and dest connectors.
240+
func (c *InitCommand) getPipelineName() string {
241+
src := defaultSource
242+
dest := defaultDestination
243+
244+
if c.args.pipelineName != defaultPipelineName {
245+
return c.args.pipelineName
246+
}
247+
248+
if c.flags.Source != "" {
249+
src = c.flags.Source
250+
}
251+
252+
if c.flags.Destination != "" {
253+
dest = c.flags.Destination
254+
}
255+
return fmt.Sprintf("%s-to-%s", src, dest)
256+
}
257+
236258
func (c *InitCommand) Execute(_ context.Context) error {
237-
c.configFilePath = filepath.Join(c.flags.PipelinesPath, fmt.Sprintf("pipeline-%s.yaml", c.args.name))
259+
c.configFilePath = filepath.Join(c.flags.PipelinesPath, fmt.Sprintf("pipeline-%s.yaml", c.getPipelineName()))
238260

239261
pipeline, err := c.buildTemplatePipeline()
240262
if err != nil {
@@ -245,9 +267,8 @@ func (c *InitCommand) Execute(_ context.Context) error {
245267
return cerrors.Errorf("could not write pipeline: %w", err)
246268
}
247269

248-
fmt.Printf(`Your pipeline has been initialized and created at %s.
249-
250-
To run the pipeline, simply run 'conduit run'.`, c.configFilePath)
270+
fmt.Printf("Your pipeline has been initialized and created at %q.\n"+
271+
"To run the pipeline, simply run `conduit run`.\n", c.configFilePath)
251272

252273
return nil
253274
}

Diff for: cmd/conduit/root/pipelines/init_test.go

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
// Copyright © 2025 Meroxa, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package pipelines
16+
17+
import (
18+
"fmt"
19+
"testing"
20+
21+
"github.com/matryer/is"
22+
)
23+
24+
func TestInitExecutionNoArgs(t *testing.T) {
25+
is := is.New(t)
26+
27+
c := InitCommand{}
28+
err := c.Args([]string{})
29+
is.NoErr(err)
30+
is.Equal(defaultPipelineName, c.args.pipelineName)
31+
}
32+
33+
func TestInitExecutionMultipleArgs(t *testing.T) {
34+
is := is.New(t)
35+
36+
c := InitCommand{}
37+
err := c.Args([]string{"foo", "bar"})
38+
is.True((err != nil))
39+
is.Equal(err.Error(), "too many arguments")
40+
}
41+
42+
func TestInitExecutionOneArg(t *testing.T) {
43+
is := is.New(t)
44+
45+
pipelineName := "pipeline-name"
46+
47+
c := InitCommand{}
48+
err := c.Args([]string{pipelineName})
49+
is.NoErr(err)
50+
is.Equal(pipelineName, c.args.pipelineName)
51+
}
52+
53+
func TestInit_getPipelineName(t *testing.T) {
54+
tests := []struct {
55+
name string
56+
argsPipelineName string
57+
flagsSource string
58+
flagsDestination string
59+
expected string
60+
}{
61+
{
62+
name: "Custom pipeline name",
63+
argsPipelineName: "custom-pipeline",
64+
flagsSource: "",
65+
flagsDestination: "",
66+
expected: "custom-pipeline",
67+
},
68+
{
69+
name: "Default pipeline name with custom source and destination",
70+
argsPipelineName: defaultPipelineName,
71+
flagsSource: "custom-source",
72+
flagsDestination: "custom-destination",
73+
expected: "custom-source-to-custom-destination",
74+
},
75+
{
76+
name: "Default pipeline name with custom source only",
77+
argsPipelineName: defaultPipelineName,
78+
flagsSource: "custom-source",
79+
flagsDestination: "",
80+
expected: fmt.Sprintf("custom-source-to-%s", defaultDestination),
81+
},
82+
{
83+
name: "Default pipeline name with custom destination only",
84+
argsPipelineName: defaultPipelineName,
85+
flagsSource: "",
86+
flagsDestination: "custom-destination",
87+
expected: fmt.Sprintf("%s-to-custom-destination", defaultSource),
88+
},
89+
{
90+
name: "Default pipeline name with default source and destination",
91+
argsPipelineName: defaultPipelineName,
92+
flagsSource: "",
93+
flagsDestination: "",
94+
expected: fmt.Sprintf("%s-to-%s", defaultSource, defaultDestination),
95+
},
96+
}
97+
98+
for _, tt := range tests {
99+
t.Run(tt.name, func(t *testing.T) {
100+
is := is.New(t)
101+
c := &InitCommand{}
102+
103+
c.args.pipelineName = tt.argsPipelineName
104+
c.flags.Source = tt.flagsSource
105+
c.flags.Destination = tt.flagsDestination
106+
107+
got := c.getPipelineName()
108+
is.Equal(got, tt.expected)
109+
})
110+
}
111+
}

0 commit comments

Comments
 (0)