Skip to content

Commit

Permalink
fix: preserve files correctly when rendering to a local directory (#268)
Browse files Browse the repository at this point in the history
Signed-off-by: Kent Rancourt <[email protected]>
  • Loading branch information
krancour authored Mar 25, 2024
1 parent 89fd5f9 commit 093186b
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 50 deletions.
14 changes: 14 additions & 0 deletions branches.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ package render
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"

"github.com/ghodss/yaml"

libExec "github.com/akuity/kargo-render/internal/exec"
"github.com/akuity/kargo-render/internal/file"
"github.com/akuity/kargo-render/pkg/git"
)
Expand Down Expand Up @@ -183,6 +185,18 @@ func cleanCommitBranch(dir string, preservedPaths []string) error {
return err
}

// copyBranchContents copies the entire contents of the source directory to the
// destination directory, except for .git.
func copyBranchContents(srcDir, dstDir string) error {
// nolint: gosec
if _, err := libExec.Exec(
exec.Command("cp", "-r", srcDir, dstDir),
); err != nil {
return err
}
return os.RemoveAll(filepath.Join(dstDir, ".git"))
}

// normalizePreservedPaths converts the relative paths in the preservedPaths
// argument to absolute paths relative to the workingDir argument. It also
// removes any trailing path separators from the paths.
Expand Down
65 changes: 39 additions & 26 deletions branches_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@ func TestLoadBranchMetadata(t *testing.T) {
{
name: "metadata does not exist",
setup: func() string {
repoDir, err := os.MkdirTemp("", "")
require.NoError(t, err)
return repoDir
return t.TempDir()
},
assertions: func(t *testing.T, md *branchMetadata, err error) {
require.NoError(t, err)
Expand All @@ -32,10 +30,9 @@ func TestLoadBranchMetadata(t *testing.T) {
{
name: "invalid YAML",
setup: func() string {
repoDir, err := os.MkdirTemp("", "")
require.NoError(t, err)
repoDir := t.TempDir()
bkDir := filepath.Join(repoDir, ".kargo-render")
err = os.Mkdir(bkDir, 0755)
err := os.Mkdir(bkDir, 0755)
require.NoError(t, err)
err = os.WriteFile(
filepath.Join(bkDir, "metadata.yaml"),
Expand All @@ -53,10 +50,9 @@ func TestLoadBranchMetadata(t *testing.T) {
{
name: "valid YAML",
setup: func() string {
repoDir, err := os.MkdirTemp("", "")
require.NoError(t, err)
repoDir := t.TempDir()
bkDir := filepath.Join(repoDir, ".kargo-render")
err = os.Mkdir(bkDir, 0755)
err := os.Mkdir(bkDir, 0755)
require.NoError(t, err)
err = os.WriteFile(
filepath.Join(bkDir, "metadata.yaml"),
Expand All @@ -80,9 +76,8 @@ func TestLoadBranchMetadata(t *testing.T) {
}

func TestWriteBranchMetadata(t *testing.T) {
repoDir, err := os.MkdirTemp("", "")
require.NoError(t, err)
err = writeBranchMetadata(
repoDir := t.TempDir()
err := writeBranchMetadata(
branchMetadata{
SourceCommit: "1234567",
},
Expand All @@ -99,8 +94,7 @@ func TestCleanCommitBranch(t *testing.T) {
const subdirCount = 50
const fileCount = 50
// Create dummy repo dir
dir, err := createDummyCommitBranchDir(subdirCount, fileCount)
defer os.RemoveAll(dir)
dir, err := createDummyCommitBranchDir(t, subdirCount, fileCount)
require.NoError(t, err)
// Double-check the setup
dirEntries, err := os.ReadDir(dir)
Expand All @@ -121,6 +115,30 @@ func TestCleanCommitBranch(t *testing.T) {
require.Len(t, dirEntries, 2)
}

func TestCopyBranchContents(t *testing.T) {
const subdirCount = 50
const fileCount = 50
// Create dummy repo srcDir
srcDir, err := createDummyCommitBranchDir(t, subdirCount, fileCount)
require.NoError(t, err)
// Double-check the setup
dirEntries, err := os.ReadDir(srcDir)
require.NoError(t, err)
require.Len(t, dirEntries, subdirCount+fileCount+2)
dstDir := filepath.Join(t.TempDir(), "dst")
// Copy
err = copyBranchContents(srcDir, dstDir)
require.NoError(t, err)
// .git should not have been included
_, err = os.Stat(filepath.Join(dstDir, ".git"))
require.Error(t, err)
require.True(t, os.IsNotExist(err))
// Everything else should have been copied
dirEntries, err = os.ReadDir(dstDir)
require.NoError(t, err)
require.Len(t, dirEntries, subdirCount+fileCount+1)
}

func TestNormalizePreservedPaths(t *testing.T) {
preservedPaths := []string{
"foo/bar",
Expand All @@ -139,9 +157,7 @@ func TestNormalizePreservedPaths(t *testing.T) {
}

func TestCleanDir(t *testing.T) {
dir, err := os.MkdirTemp("", "")
defer os.RemoveAll(dir)
require.NoError(t, err)
dir := t.TempDir()

// This is what the test directory structure will look like:
// .
Expand All @@ -155,7 +171,7 @@ func TestCleanDir(t *testing.T) {

// Create the test directory structure
fooDir := filepath.Join(dir, "foo")
err = os.Mkdir(fooDir, 0755)
err := os.Mkdir(fooDir, 0755)
require.NoError(t, err)
fooFile := filepath.Join(fooDir, "foo.txt")
err = os.WriteFile(fooFile, []byte("foo"), 0600)
Expand Down Expand Up @@ -222,23 +238,20 @@ func TestIsPathPreserved(t *testing.T) {
require.False(t, isPathPreserved("/foo/baz", preservedPaths))
}

func createDummyCommitBranchDir(dirCount, fileCount int) (string, error) {
func createDummyCommitBranchDir(t *testing.T, dirCount, fileCount int) (string, error) {
// Create a directory
dir, err := os.MkdirTemp("", "")
if err != nil {
return dir, err
}
dir := t.TempDir()
// Add a dummy .git/ subdir
if err = os.Mkdir(filepath.Join(dir, ".git"), 0755); err != nil {
if err := os.Mkdir(filepath.Join(dir, ".git"), 0755); err != nil {
return dir, err
}
// Add a dummy .kargo-render/ subdir
if err = os.Mkdir(filepath.Join(dir, ".kargo-render"), 0755); err != nil {
if err := os.Mkdir(filepath.Join(dir, ".kargo-render"), 0755); err != nil {
return dir, err
}
// Add some other dummy dirs
for i := 0; i < dirCount; i++ {
if err = os.Mkdir(
if err := os.Mkdir(
filepath.Join(dir, fmt.Sprintf("dir-%d", i)),
0755,
); err != nil {
Expand Down
20 changes: 8 additions & 12 deletions config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@ func TestLoadRepoConfig(t *testing.T) {
{
name: "invalid JSON",
setup: func() string {
dir, err := os.MkdirTemp("", "")
require.NoError(t, err)
err = os.WriteFile(
dir := t.TempDir()
err := os.WriteFile(
filepath.Join(dir, "kargo-render.json"),
[]byte("bogus"),
0600,
Expand All @@ -40,9 +39,8 @@ func TestLoadRepoConfig(t *testing.T) {
{
name: "invalid YAML",
setup: func() string {
dir, err := os.MkdirTemp("", "")
require.NoError(t, err)
err = os.WriteFile(
dir := t.TempDir()
err := os.WriteFile(
filepath.Join(dir, "kargo-render.yaml"),
[]byte("bogus"),
0600,
Expand All @@ -62,9 +60,8 @@ func TestLoadRepoConfig(t *testing.T) {
{
name: "valid JSON",
setup: func() string {
dir, err := os.MkdirTemp("", "")
require.NoError(t, err)
err = os.WriteFile(
dir := t.TempDir()
err := os.WriteFile(
filepath.Join(dir, "kargo-render.json"),
[]byte(`{"configVersion": "v1alpha1"}`),
0600,
Expand All @@ -79,9 +76,8 @@ func TestLoadRepoConfig(t *testing.T) {
{
name: "valid YAML",
setup: func() string {
dir, err := os.MkdirTemp("", "")
require.NoError(t, err)
err = os.WriteFile(
dir := t.TempDir()
err := os.WriteFile(
filepath.Join(dir, "kargo-render.yaml"),
[]byte("configVersion: v1alpha1"),
0600,
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/30-how-to-guides/30-docker-image.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ easiest option for experimenting locally with Kargo Render!
Example usage:

```shell
docker run -it ghcr.io/akuity/kargo-render:v0.1.0-rc.37 \
docker run -it ghcr.io/akuity/kargo-render:v0.1.0-rc.38 \
--repo https://github.com/<your GitHub handle>/kargo-render-demo-deploy \
--repo-username <your GitHub handle> \
--repo-password <a GitHub personal access token> \
Expand Down
10 changes: 7 additions & 3 deletions pkg/git/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ import (
libExec "github.com/akuity/kargo-render/internal/exec"
)

const RemoteOrigin = "origin"
const (
RemoteOrigin = "origin"

tmpPrefix = "repo-"
)

// RepoCredentials represents the credentials for connecting to a private git
// repository.
Expand Down Expand Up @@ -113,7 +117,7 @@ func Clone(
cloneURL string,
repoCreds RepoCredentials,
) (Repo, error) {
homeDir, err := os.MkdirTemp("", "")
homeDir, err := os.MkdirTemp("", tmpPrefix)
if err != nil {
return nil, fmt.Errorf(
"error creating home directory for repo %q: %w",
Expand Down Expand Up @@ -155,7 +159,7 @@ func CopyRepo(path string, repoCreds RepoCredentials) (Repo, error) {
return nil, fmt.Errorf("path %s is not a git repository: %w", path, err)
}

homeDir, err := os.MkdirTemp("", "")
homeDir, err := os.MkdirTemp("", tmpPrefix)
if err != nil {
return nil, fmt.Errorf(
"error creating directory for copy of repo at %s: %w",
Expand Down
2 changes: 1 addition & 1 deletion rendering.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func renderLastMile(
) ([]string, map[string][]byte, error) {
logger := rc.logger

tempDir, err := os.MkdirTemp("", "")
tempDir, err := os.MkdirTemp("", "repo-scrap-")
if err != nil {
return nil, nil, fmt.Errorf(
"error creating temporary directory %q for last mile rendering: %w",
Expand Down
5 changes: 2 additions & 3 deletions service.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,10 +258,9 @@ func (s *service) RenderManifests(
outputDir := rc.repo.WorkingDir()
if rc.request.LocalOutPath != "" {
outputDir = rc.request.LocalOutPath
// Create a directory for the output
if err = os.MkdirAll(outputDir, 0755); err != nil {
if err = copyBranchContents(rc.repo.WorkingDir(), outputDir); err != nil {
return res, fmt.Errorf(
"error creating local output directory %q: %w",
"error copying branch contents to local output directory %q: %w",
outputDir,
err,
)
Expand Down
6 changes: 2 additions & 4 deletions service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,8 @@ metadata:
},
[]byte("---\n"),
)
testDir, err := os.MkdirTemp("", "")
require.NoError(t, err)
defer os.RemoveAll(testDir)
err = writeManifests(testDir, testYAMLBytes)
testDir := t.TempDir()
err := writeManifests(testDir, testYAMLBytes)
require.NoError(t, err)
filename := filepath.Join(testDir, "foobar-deployment.yaml")
exists, err := file.Exists(filename)
Expand Down

0 comments on commit 093186b

Please sign in to comment.