Skip to content

Commit 8f9cfc0

Browse files
authored
refactor(internal/librarian): remove contentLoader (#1698)
The release code will also need to use some of this functionality and to make the code easier to call/read I refactored out the idea of a content loader that I believe was added to help coverage. I am fine taking a couple points of a coverage hit to make the code, in my opinion, more readable. Updates: #1009
1 parent bdeeb20 commit 8f9cfc0

File tree

3 files changed

+41
-87
lines changed

3 files changed

+41
-87
lines changed

internal/librarian/generate.go

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ package librarian
1616

1717
import (
1818
"context"
19-
"encoding/json"
2019
"errors"
2120
"fmt"
2221
"io/fs"
@@ -274,9 +273,6 @@ func (r *generateRunner) runGenerateCommand(ctx context.Context, libraryID, outp
274273

275274
// Read the library state from the response.
276275
if _, err := readLibraryState(
277-
func(data []byte, libraryState *config.LibraryState) error {
278-
return json.Unmarshal(data, libraryState)
279-
},
280276
filepath.Join(generateRequest.RepoDir, config.LibrarianDir, config.GenerateResponse)); err != nil {
281277
return "", err
282278
}
@@ -334,10 +330,8 @@ func (r *generateRunner) runBuildCommand(ctx context.Context, libraryID string)
334330

335331
// Read the library state from the response.
336332
_, err := readLibraryState(
337-
func(data []byte, libraryState *config.LibraryState) error {
338-
return json.Unmarshal(data, libraryState)
339-
},
340-
filepath.Join(buildRequest.RepoDir, config.LibrarianDir, config.BuildResponse))
333+
filepath.Join(buildRequest.RepoDir, config.LibrarianDir, config.BuildResponse),
334+
)
341335

342336
return err
343337
}
@@ -529,9 +523,6 @@ func (r *generateRunner) runConfigureCommand(ctx context.Context) (string, error
529523

530524
if err := populateServiceConfigIfEmpty(
531525
r.state,
532-
func(file string) ([]byte, error) {
533-
return os.ReadFile(file)
534-
},
535526
r.cfg.APISource); err != nil {
536527
return "", err
537528
}
@@ -550,10 +541,8 @@ func (r *generateRunner) runConfigureCommand(ctx context.Context) (string, error
550541

551542
// Read the new library state from the response.
552543
libraryState, err := readLibraryState(
553-
func(data []byte, libraryState *config.LibraryState) error {
554-
return json.Unmarshal(data, libraryState)
555-
},
556-
filepath.Join(r.repo.GetDir(), config.LibrarianDir, config.ConfigureResponse))
544+
filepath.Join(r.repo.GetDir(), config.LibrarianDir, config.ConfigureResponse),
545+
)
557546
if err != nil {
558547
return "", err
559548
}

internal/librarian/state.go

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package librarian
1616

1717
import (
18+
"encoding/json"
1819
"errors"
1920
"fmt"
2021
"log/slog"
@@ -36,35 +37,25 @@ const (
3637

3738
// Utility functions for saving and loading pipeline state and config from various places.
3839

39-
func loadRepoState(languageRepo *gitrepo.LocalRepository, source string) (*config.LibrarianState, error) {
40-
if languageRepo == nil {
40+
func loadRepoState(repo *gitrepo.LocalRepository, source string) (*config.LibrarianState, error) {
41+
if repo == nil {
42+
slog.Info("repo is nil, skipping state loading")
4143
return nil, nil
4244
}
43-
state, err := loadLibrarianState(languageRepo, source)
44-
if err != nil {
45-
return nil, err
46-
}
47-
return state, nil
48-
}
49-
50-
func loadLibrarianState(languageRepo *gitrepo.LocalRepository, source string) (*config.LibrarianState, error) {
51-
if languageRepo == nil {
52-
return nil, nil
53-
}
54-
path := filepath.Join(languageRepo.Dir, config.LibrarianDir, pipelineStateFile)
55-
return parseLibrarianState(func(file string) ([]byte, error) { return os.ReadFile(file) }, path, source)
45+
path := filepath.Join(repo.Dir, config.LibrarianDir, pipelineStateFile)
46+
return parseLibrarianState(path, source)
5647
}
5748

58-
func parseLibrarianState(contentLoader func(file string) ([]byte, error), path, source string) (*config.LibrarianState, error) {
59-
bytes, err := contentLoader(path)
49+
func parseLibrarianState(path, source string) (*config.LibrarianState, error) {
50+
bytes, err := os.ReadFile(path)
6051
if err != nil {
6152
return nil, err
6253
}
6354
var s config.LibrarianState
6455
if err := yaml.Unmarshal(bytes, &s); err != nil {
6556
return nil, fmt.Errorf("unmarshaling librarian state: %w", err)
6657
}
67-
if err := populateServiceConfigIfEmpty(&s, contentLoader, source); err != nil {
58+
if err := populateServiceConfigIfEmpty(&s, source); err != nil {
6859
return nil, fmt.Errorf("populating service config: %w", err)
6960
}
7061
if err := s.Validate(); err != nil {
@@ -73,15 +64,19 @@ func parseLibrarianState(contentLoader func(file string) ([]byte, error), path,
7364
return &s, nil
7465
}
7566

76-
func populateServiceConfigIfEmpty(state *config.LibrarianState, contentLoader func(file string) ([]byte, error), source string) error {
67+
func populateServiceConfigIfEmpty(state *config.LibrarianState, source string) error {
68+
if source == "" {
69+
slog.Info("source not specified, skipping service config population")
70+
return nil
71+
}
7772
for i, library := range state.Libraries {
7873
for j, api := range library.APIs {
7974
if api.ServiceConfig != "" {
8075
// Do not change API if the service config has already been set.
8176
continue
8277
}
8378
apiPath := filepath.Join(source, api.Path)
84-
serviceConfig, err := findServiceConfigIn(contentLoader, apiPath)
79+
serviceConfig, err := findServiceConfigIn(apiPath)
8580
if err != nil {
8681
return err
8782
}
@@ -100,7 +95,7 @@ func populateServiceConfigIfEmpty(state *config.LibrarianState, contentLoader fu
10095
// 1. the file ends with `.yaml` and it is a valid yaml file.
10196
//
10297
// 2. the file contains `type: google.api.Service`.
103-
func findServiceConfigIn(contentLoader func(file string) ([]byte, error), path string) (string, error) {
98+
func findServiceConfigIn(path string) (string, error) {
10499
entries, err := os.ReadDir(path)
105100
if err != nil {
106101
return "", fmt.Errorf("failed to read dir %q: %w", path, err)
@@ -110,7 +105,7 @@ func findServiceConfigIn(contentLoader func(file string) ([]byte, error), path s
110105
if !strings.HasSuffix(entry.Name(), ".yaml") {
111106
continue
112107
}
113-
bytes, err := contentLoader(filepath.Join(path, entry.Name()))
108+
bytes, err := os.ReadFile(filepath.Join(path, entry.Name()))
114109
if err != nil {
115110
return "", err
116111
}
@@ -138,7 +133,7 @@ func saveLibrarianState(repoDir string, state *config.LibrarianState) error {
138133
// readLibraryState reads the library state from a container response.
139134
//
140135
// The response file is removed afterwards.
141-
func readLibraryState(contentLoader func(data []byte, state *config.LibraryState) error, jsonFilePath string) (*config.LibraryState, error) {
136+
func readLibraryState(jsonFilePath string) (*config.LibraryState, error) {
142137
data, err := os.ReadFile(jsonFilePath)
143138
defer func() {
144139
if err := os.Remove(jsonFilePath); err != nil {
@@ -149,9 +144,9 @@ func readLibraryState(contentLoader func(data []byte, state *config.LibraryState
149144
return nil, fmt.Errorf("failed to read response file, path: %s, error: %w", jsonFilePath, err)
150145
}
151146

152-
libraryState := &config.LibraryState{}
147+
var libraryState *config.LibraryState
153148

154-
if err := contentLoader(data, libraryState); err != nil {
149+
if err := json.Unmarshal(data, &libraryState); err != nil {
155150
return nil, fmt.Errorf("failed to load file, %s, to state: %w", jsonFilePath, err)
156151
}
157152

internal/librarian/state_test.go

Lines changed: 17 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
package librarian
1616

1717
import (
18-
"encoding/json"
1918
"errors"
2019
"fmt"
2120
"io"
@@ -96,10 +95,11 @@ libraries:
9695
},
9796
} {
9897
t.Run(test.name, func(t *testing.T) {
99-
contentLoader := func(path string) ([]byte, error) {
100-
return []byte(path), nil
98+
path := filepath.Join(t.TempDir(), "state.yaml")
99+
if err := os.WriteFile(path, []byte(test.content), 0644); err != nil {
100+
t.Fatalf("os.WriteFile() failed: %v", err)
101101
}
102-
got, err := parseLibrarianState(contentLoader, test.content, test.source)
102+
got, err := parseLibrarianState(path, test.source)
103103
if (err != nil) != test.wantErr {
104104
t.Errorf("parseLibrarianState() error = %v, wantErr %v", err, test.wantErr)
105105
return
@@ -113,59 +113,43 @@ libraries:
113113

114114
func TestFindServiceConfigIn(t *testing.T) {
115115
for _, test := range []struct {
116-
name string
117-
contentLoader func(file string) ([]byte, error)
118-
path string
119-
want string
120-
wantErr bool
116+
name string
117+
path string
118+
want string
119+
wantErr bool
121120
}{
122121
{
123122
name: "find a service config",
124-
contentLoader: func(file string) ([]byte, error) {
125-
return os.ReadFile(file)
126-
},
127123
path: filepath.Join("..", "..", "testdata", "find_a_service_config"),
128124
want: "service_config.yaml",
129125
},
130126
{
131-
name: "non existed source path",
132-
contentLoader: func(file string) ([]byte, error) {
133-
return os.ReadFile(file)
134-
},
127+
name: "non existed source path",
135128
path: filepath.Join("..", "..", "testdata", "non-existed-path"),
136129
want: "",
137130
wantErr: true,
138131
},
139132
{
140-
name: "non service config in a source path",
141-
contentLoader: func(file string) ([]byte, error) {
142-
return os.ReadFile(file)
143-
},
133+
name: "non service config in a source path",
144134
path: filepath.Join("..", "..", "testdata", "no_service_config"),
145135
want: "",
146136
wantErr: true,
147137
},
148138
{
149-
name: "simulated load error",
150-
contentLoader: func(file string) ([]byte, error) {
151-
return nil, errors.New("simulate loading error for testing")
152-
},
139+
name: "simulated load error",
153140
path: filepath.Join("..", "..", "testdata", "no_service_config"),
154141
want: "",
155142
wantErr: true,
156143
},
157144
{
158-
name: "invalid yaml",
159-
contentLoader: func(file string) ([]byte, error) {
160-
return os.ReadFile(file)
161-
},
145+
name: "invalid yaml",
162146
path: filepath.Join("..", "..", "testdata", "invalid_yaml"),
163147
want: "",
164148
wantErr: true,
165149
},
166150
} {
167151
t.Run(test.name, func(t *testing.T) {
168-
got, err := findServiceConfigIn(test.contentLoader, test.path)
152+
got, err := findServiceConfigIn(test.path)
169153
if test.wantErr {
170154
if err == nil {
171155
t.Errorf("findServiceConfigIn() should return error")
@@ -245,10 +229,7 @@ func TestPopulateServiceConfig(t *testing.T) {
245229
},
246230
} {
247231
t.Run(test.name, func(t *testing.T) {
248-
contentLoader := func(file string) ([]byte, error) {
249-
return os.ReadFile(file)
250-
}
251-
err := populateServiceConfigIfEmpty(test.state, contentLoader, test.path)
232+
err := populateServiceConfigIfEmpty(test.state, test.path)
252233
if test.wantErr {
253234
if err == nil {
254235
t.Errorf("findServiceConfigIn() should return error")
@@ -310,9 +291,6 @@ func TestSaveLibrarianState(t *testing.T) {
310291

311292
func TestReadConfigureResponseJSON(t *testing.T) {
312293
t.Parallel()
313-
contentLoader := func(data []byte, state *config.LibraryState) error {
314-
return json.Unmarshal(data, state)
315-
}
316294
for _, test := range []struct {
317295
name string
318296
jsonFilePath string
@@ -350,17 +328,12 @@ func TestReadConfigureResponseJSON(t *testing.T) {
350328
name: "invalid file name",
351329
wantState: nil,
352330
},
353-
{
354-
name: "invalid content loader",
355-
jsonFilePath: "../../testdata/invalid-contentLoader.json",
356-
wantState: nil,
357-
},
358331
} {
359332
t.Run(test.name, func(t *testing.T) {
360333
tempDir := t.TempDir()
361334
if test.name == "invalid file name" {
362335
filePath := filepath.Join(tempDir, "my\x00file.json")
363-
_, err := readLibraryState(contentLoader, filePath)
336+
_, err := readLibraryState(filePath)
364337
if err == nil {
365338
t.Error("readLibraryState() expected an error but got nil")
366339
}
@@ -373,14 +346,11 @@ func TestReadConfigureResponseJSON(t *testing.T) {
373346
}
374347

375348
if test.name == "invalid content loader" {
376-
invalidContentLoader := func(data []byte, state *config.LibraryState) error {
377-
return errors.New("simulated Unmarshal error")
378-
}
379349
dst := fmt.Sprintf("%s/copy.json", os.TempDir())
380350
if err := copyFile(dst, test.jsonFilePath); err != nil {
381351
t.Error(err)
382352
}
383-
_, err := readLibraryState(invalidContentLoader, dst)
353+
_, err := readLibraryState(dst)
384354
if err == nil {
385355
t.Errorf("readLibraryState() expected an error but got nil")
386356
}
@@ -398,7 +368,7 @@ func TestReadConfigureResponseJSON(t *testing.T) {
398368
t.Error(err)
399369
}
400370

401-
gotState, err := readLibraryState(contentLoader, dstFilePath)
371+
gotState, err := readLibraryState(dstFilePath)
402372

403373
if test.name == "load content with an error message" {
404374
if err == nil {

0 commit comments

Comments
 (0)