Skip to content

Commit 5d9bd1d

Browse files
authored
chore: add release init cmd skeleton (#1742)
Updates #1008
1 parent d77b967 commit 5d9bd1d

File tree

3 files changed

+168
-0
lines changed

3 files changed

+168
-0
lines changed

internal/librarian/init.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Copyright 2025 Google LLC
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+
// https://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 librarian
16+
17+
import (
18+
"context"
19+
"errors"
20+
"fmt"
21+
22+
"github.com/googleapis/librarian/internal/cli"
23+
"github.com/googleapis/librarian/internal/config"
24+
)
25+
26+
// cmdInit is the command for the `release init` subcommand.
27+
var cmdInit = &cli.Command{
28+
Short: "release init initiates a release by creating a release pull request.",
29+
UsageLine: "librarian release init [arguments]",
30+
Long: `The release init command is the primary entry point for initiating a release.
31+
It orchestrates the process of parsing commits, determining new versions, generating
32+
a changelog, and creating a release pull request.`,
33+
Run: func(ctx context.Context, cfg *config.Config) error {
34+
runner, err := newInitRunner(cfg)
35+
if err != nil {
36+
return err
37+
}
38+
return runner.run(ctx)
39+
},
40+
}
41+
42+
func init() {
43+
cmdInit.Init()
44+
fs := cmdInit.Flags
45+
cfg := cmdInit.Config
46+
47+
addFlagRepo(fs, cfg)
48+
addFlagImage(fs, cfg)
49+
addFlagLibrary(fs, cfg)
50+
}
51+
52+
type initRunner struct {
53+
cfg *config.Config
54+
}
55+
56+
func newInitRunner(cfg *config.Config) (*initRunner, error) {
57+
if ok, err := cfg.IsValid(); !ok || err != nil {
58+
return nil, fmt.Errorf("invalid config: %+v", cfg)
59+
}
60+
61+
return &initRunner{
62+
cfg: cfg,
63+
}, nil
64+
}
65+
66+
func (r *initRunner) run(ctx context.Context) error {
67+
return errors.New("not implemented")
68+
}

internal/librarian/init_test.go

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// Copyright 2025 Google LLC
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+
// https://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 librarian
16+
17+
import (
18+
"context"
19+
"strings"
20+
"testing"
21+
22+
"github.com/googleapis/librarian/internal/config"
23+
)
24+
25+
func TestNewInitRunner(t *testing.T) {
26+
testcases := []struct {
27+
name string
28+
cfg *config.Config
29+
wantErr bool
30+
wantErrMsg string
31+
}{
32+
{
33+
name: "valid config",
34+
cfg: &config.Config{},
35+
},
36+
{
37+
name: "invalid config",
38+
cfg: &config.Config{
39+
Push: true,
40+
},
41+
wantErr: true,
42+
wantErrMsg: "invalid config",
43+
},
44+
}
45+
for _, test := range testcases {
46+
t.Run(test.name, func(t *testing.T) {
47+
_, err := newInitRunner(test.cfg)
48+
if test.wantErr {
49+
if err == nil {
50+
t.Error("newInitRunner() should return error")
51+
}
52+
53+
if !strings.Contains(err.Error(), test.wantErrMsg) {
54+
t.Errorf("want error message: %q, got %q", test.wantErrMsg, err.Error())
55+
}
56+
57+
return
58+
}
59+
if err != nil {
60+
t.Errorf("newInitRunner() got nil runner, want non-nil")
61+
}
62+
})
63+
}
64+
}
65+
66+
func TestInitRun(t *testing.T) {
67+
testcases := []struct {
68+
name string
69+
runner *initRunner
70+
wantErr bool
71+
wantErrMsg string
72+
}{
73+
{
74+
name: "invalid",
75+
runner: &initRunner{},
76+
wantErr: true,
77+
wantErrMsg: "not implemented",
78+
},
79+
}
80+
for _, test := range testcases {
81+
t.Run(test.name, func(t *testing.T) {
82+
err := test.runner.run(context.Background())
83+
if test.wantErr {
84+
if err == nil {
85+
t.Error("run() should return error")
86+
}
87+
88+
if !strings.Contains(err.Error(), test.wantErrMsg) {
89+
t.Errorf("want error message: %q, got %q", test.wantErrMsg, err.Error())
90+
}
91+
92+
return
93+
}
94+
if err != nil {
95+
t.Errorf("run() got nil runner, want non-nil")
96+
}
97+
})
98+
}
99+
}

internal/librarian/release.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ var cmdRelease = &cli.Command{
2828
func init() {
2929
cmdRelease.Init()
3030
CmdLibrarian.Commands = append(CmdLibrarian.Commands,
31+
cmdInit,
3132
cmdTagAndRelease,
3233
)
3334
}

0 commit comments

Comments
 (0)