Skip to content

Commit fcba7b0

Browse files
authored
chore: refactor common functions to librarian package (#1799)
- Refactor common functions to `librarian` package so that they can be reused. - Simplify logic in `docker` package. Updates #1008
1 parent e945da1 commit fcba7b0

File tree

14 files changed

+436
-657
lines changed

14 files changed

+436
-657
lines changed

generate_e2e_test.go

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ package librarian
1919

2020
import (
2121
"fmt"
22-
"math/rand"
2322
"os"
2423
"os/exec"
2524
"path/filepath"
@@ -34,9 +33,7 @@ import (
3433

3534
func TestRunGenerate(t *testing.T) {
3635
const (
37-
repo = "repo"
3836
initialRepoStateDir = "testdata/e2e/generate/repo_init"
39-
APISourceRepo = "apisource"
4037
localAPISource = "testdata/e2e/generate/api_root"
4138
)
4239
t.Parallel()
@@ -56,9 +53,9 @@ func TestRunGenerate(t *testing.T) {
5653
},
5754
} {
5855
t.Run(test.name, func(t *testing.T) {
59-
workRoot := filepath.Join(t.TempDir())
60-
repo := filepath.Join(workRoot, repo)
61-
APISourceRepo := filepath.Join(workRoot, APISourceRepo)
56+
workRoot := t.TempDir()
57+
repo := t.TempDir()
58+
APISourceRepo := t.TempDir()
6259
if err := initRepo(t, repo, initialRepoStateDir); err != nil {
6360
t.Fatalf("languageRepo prepare test error = %v", err)
6461
}
@@ -104,9 +101,8 @@ func TestRunConfigure(t *testing.T) {
104101
const (
105102
localRepoDir = "testdata/e2e/configure/repo"
106103
initialRepoStateDir = "testdata/e2e/configure/repo_init"
107-
repo = "repo"
108-
APISourceRepo = "apisource"
109104
)
105+
t.Parallel()
110106
for _, test := range []struct {
111107
name string
112108
api string
@@ -132,10 +128,9 @@ func TestRunConfigure(t *testing.T) {
132128
},
133129
} {
134130
t.Run(test.name, func(t *testing.T) {
135-
t.Parallel()
136-
workRoot := filepath.Join(os.TempDir(), fmt.Sprintf("rand-%d", rand.Intn(1000)))
137-
repo := filepath.Join(workRoot, repo)
138-
APISourceRepo := filepath.Join(workRoot, APISourceRepo)
131+
workRoot := t.TempDir()
132+
repo := t.TempDir()
133+
APISourceRepo := t.TempDir()
139134
if err := initRepo(t, repo, initialRepoStateDir); err != nil {
140135
t.Fatalf("prepare test error = %v", err)
141136
}

internal/docker/docker.go

Lines changed: 5 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import (
2222
"context"
2323
"encoding/json"
2424
"fmt"
25-
"io"
2625
"log/slog"
2726
"os"
2827
"os/exec"
@@ -135,10 +134,10 @@ type ReleaseInitRequest struct {
135134
// Output specifies the empty output directory into which the command should
136135
// generate code.
137136
Output string
138-
// partialRepoDir is the local root directory of language repository contains
137+
// PartialRepoDir is the local root directory of language repository contains
139138
// files that make up libraries and global files.
140139
// This is the directory that container can access.
141-
partialRepoDir string
140+
PartialRepoDir string
142141
}
143142

144143
// New constructs a Docker instance which will invoke the specified
@@ -253,7 +252,7 @@ func (c *Docker) Configure(ctx context.Context, request *ConfigureRequest) (stri
253252

254253
// ReleaseInit initiates a release for a given language repository.
255254
func (c *Docker) ReleaseInit(ctx context.Context, request *ReleaseInitRequest) error {
256-
requestFilePath := filepath.Join(request.Cfg.Repo, config.LibrarianDir, config.ReleaseInitRequest)
255+
requestFilePath := filepath.Join(request.PartialRepoDir, config.LibrarianDir, config.ReleaseInitRequest)
257256
if err := writeLibrarianState(request.State, requestFilePath); err != nil {
258257
return err
259258
}
@@ -275,14 +274,10 @@ func (c *Docker) ReleaseInit(ctx context.Context, request *ReleaseInitRequest) e
275274
commandArgs = append(commandArgs, fmt.Sprintf("--library-version=%s", request.LibraryVersion))
276275
}
277276

278-
if err := setupPartialRepo(request); err != nil {
279-
return err
280-
}
281-
282-
librarianDir := filepath.Join(request.partialRepoDir, config.LibrarianDir)
277+
librarianDir := filepath.Join(request.PartialRepoDir, config.LibrarianDir)
283278
mounts := []string{
284279
fmt.Sprintf("%s:/librarian", librarianDir),
285-
fmt.Sprintf("%s:/repo:ro", request.partialRepoDir), // readonly volume
280+
fmt.Sprintf("%s:/repo:ro", request.PartialRepoDir), // readonly volume
286281
fmt.Sprintf("%s:/output", request.Output),
287282
}
288283

@@ -347,96 +342,6 @@ func (c *Docker) runCommand(cmdName string, args ...string) error {
347342
return err
348343
}
349344

350-
// setupPartialRepo copies the following files from the [config.Config.Repo] to
351-
// partialRepoDir in the given ReleaseInitRequest:
352-
//
353-
// 1. all directories that make up all libraries, or one library, if the library
354-
// ID is specified.
355-
//
356-
// 2. the .librarian directory.
357-
//
358-
// 3. global files declared in config.yaml.
359-
func setupPartialRepo(request *ReleaseInitRequest) error {
360-
if request.partialRepoDir == "" {
361-
request.partialRepoDir = filepath.Join(request.Cfg.WorkRoot, "release-init")
362-
}
363-
dst := request.partialRepoDir
364-
src := request.Cfg.Repo
365-
if err := os.MkdirAll(dst, 0755); err != nil {
366-
return fmt.Errorf("failed to make directory: %w", err)
367-
}
368-
369-
for _, library := range request.State.Libraries {
370-
// Only copy files that make up one library.
371-
if request.LibraryID != "" {
372-
if library.ID == request.LibraryID {
373-
if err := copyOneLibrary(dst, src, library); err != nil {
374-
return err
375-
}
376-
break
377-
}
378-
continue
379-
}
380-
381-
// Copy all files make up all libraries.
382-
if err := copyOneLibrary(dst, src, library); err != nil {
383-
return err
384-
}
385-
}
386-
387-
// Copy the .librarian directory.
388-
if err := os.CopyFS(
389-
filepath.Join(dst, config.LibrarianDir),
390-
os.DirFS(filepath.Join(src, config.LibrarianDir))); err != nil {
391-
return fmt.Errorf("failed to copy librarian dir to %s: %w", dst, err)
392-
}
393-
394-
// Copy global files declared in librarian config.
395-
for _, globalFile := range request.LibrarianConfig.GlobalFilesAllowlist {
396-
dstPath := filepath.Join(dst, globalFile.Path)
397-
srcPath := filepath.Join(src, globalFile.Path)
398-
if err := copyFile(dstPath, srcPath); err != nil {
399-
return err
400-
}
401-
}
402-
403-
return nil
404-
}
405-
406-
func copyOneLibrary(dst, src string, library *config.LibraryState) error {
407-
for _, srcRoot := range library.SourceRoots {
408-
dstPath := filepath.Join(dst, srcRoot)
409-
srcPath := filepath.Join(src, srcRoot)
410-
if err := os.CopyFS(dstPath, os.DirFS(srcPath)); err != nil {
411-
return fmt.Errorf("failed to copy %s to %s: %w", library.ID, dstPath, err)
412-
}
413-
}
414-
415-
return nil
416-
}
417-
418-
func copyFile(dst, src string) (err error) {
419-
sourceFile, err := os.Open(src)
420-
if err != nil {
421-
return fmt.Errorf("failed to open file: %q: %w", src, err)
422-
}
423-
defer sourceFile.Close()
424-
425-
if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
426-
return fmt.Errorf("failed to make directory: %s", src)
427-
}
428-
429-
destinationFile, err := os.Create(dst)
430-
if err != nil {
431-
return fmt.Errorf("failed to create file: %s", dst)
432-
}
433-
defer destinationFile.Close()
434-
435-
_, err = io.Copy(destinationFile, sourceFile)
436-
437-
return err
438-
}
439-
440345
func writeLibraryState(state *config.LibrarianState, libraryID, jsonFilePath string) error {
441346
if err := os.MkdirAll(filepath.Dir(jsonFilePath), 0755); err != nil {
442347
return fmt.Errorf("failed to make directory: %w", err)

0 commit comments

Comments
 (0)