Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions build/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,31 @@ import (
"bytes"
"encoding/json"
"os"
"os/user"
"path"
"path/filepath"
"time"

buildinfo "github.com/jfrog/build-info-go/entities"
"github.com/jfrog/build-info-go/utils"
)

const BuildsTempPath = "jfrog/builds/"
const BuildsJfrogPath = "jfrog-"
const BuildsDirPath = "builds"
const DefaultUser = "default"

type BuildInfoService struct {
tempDirPath string
logger utils.Log
}

func NewBuildInfoService() *BuildInfoService {
return &BuildInfoService{tempDirPath: filepath.Join(os.TempDir(), BuildsTempPath), logger: &utils.NullLog{}}
userSpecificBuildDir := resolveUserSpecificBuildDirName()
return &BuildInfoService{tempDirPath: filepath.Join(os.TempDir(), userSpecificBuildDir), logger: &utils.NullLog{}}
}

func (bis *BuildInfoService) GetUserSpecificBuildDirName() string {
return resolveUserSpecificBuildDirName()
}

func (bis *BuildInfoService) SetTempDirPath(tempDirPath string) {
Expand Down Expand Up @@ -80,3 +89,13 @@ func getOrCreateBuildGeneralDetails(buildName, buildNumber string, buildTime tim
}
return buildTime, os.WriteFile(detailsFilePath, content.Bytes(), 0600)
}

func resolveUserSpecificBuildDirName() string {
username := DefaultUser
currentUser, err := user.Current()
if err == nil {
username = currentUser.Username
}
return path.Join(BuildsJfrogPath+username, BuildsDirPath)

}
114 changes: 114 additions & 0 deletions build/service_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package build

import (
"os"
"os/user"
"path/filepath"
"runtime"
"strings"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestResolveUserSpecificBuildDirName(t *testing.T) {

// in windows temporary directories are per-user basis already
if runtime.GOOS == "windows" {
t.Skip("Skipping on Windows")
}
result := resolveUserSpecificBuildDirName()

// Should contain "jfrog-" prefix
assert.True(t, strings.Contains(result, BuildsJfrogPath), "Expected path to contain '%s', got: %s", BuildsJfrogPath, result)

// Should contain "builds" directory
assert.True(t, strings.Contains(result, BuildsDirPath), "Expected path to contain '%s', got: %s", BuildsDirPath, result)

// Should have format: jfrog-<username>/builds
parts := strings.Split(result, string(filepath.Separator))
// Handle both forward and backslash separators
if len(parts) == 1 {
parts = strings.Split(result, "/")
}
assert.Equal(t, 2, len(parts), "Expected 2 path components, got: %v", parts)
assert.True(t, strings.HasPrefix(parts[0], BuildsJfrogPath), "First component should start with '%s', got: %s", BuildsJfrogPath, parts[0])
assert.Equal(t, BuildsDirPath, parts[1], "Second component should be '%s', got: %s", BuildsDirPath, parts[1])
}

func TestResolveUserSpecificBuildDirNameContainsUsername(t *testing.T) {
currentUser, err := user.Current()
require.NoError(t, err, "Failed to get current user")

result := resolveUserSpecificBuildDirName()

// The path should contain the current username
expectedPrefix := BuildsJfrogPath + currentUser.Username
assert.True(t, strings.Contains(result, expectedPrefix),
"Expected path to contain '%s', got: %s", expectedPrefix, result)
}

func TestNewBuildInfoService(t *testing.T) {
service := NewBuildInfoService()

// Service should not be nil
require.NotNil(t, service, "NewBuildInfoService should not return nil")

// tempDirPath should be set
assert.NotEmpty(t, service.tempDirPath, "tempDirPath should not be empty")

// tempDirPath should start with OS temp directory
assert.True(t, strings.HasPrefix(service.tempDirPath, os.TempDir()),
"tempDirPath should start with OS temp dir. Got: %s, Expected prefix: %s",
service.tempDirPath, os.TempDir())

// tempDirPath should contain user-specific directory
assert.True(t, strings.Contains(service.tempDirPath, BuildsJfrogPath),
"tempDirPath should contain '%s', got: %s", BuildsJfrogPath, service.tempDirPath)
}

func TestGetUserSpecificBuildDirName(t *testing.T) {
service := NewBuildInfoService()

dirName := service.GetUserSpecificBuildDirName()

// Should not be empty
assert.NotEmpty(t, dirName, "GetUserSpecificBuildDirName should not return empty string")

// Should match the expected format
assert.True(t, strings.HasPrefix(dirName, BuildsJfrogPath),
"Directory name should start with '%s', got: %s", BuildsJfrogPath, dirName)
assert.True(t, strings.HasSuffix(dirName, BuildsDirPath),
"Directory name should end with '%s', got: %s", BuildsDirPath, dirName)
}

func TestGetUserSpecificBuildDirNameLazyInit(t *testing.T) {
// Create service with empty buildDirectory to test lazy initialization
service := &BuildInfoService{
tempDirPath: "/tmp/test",
}

dirName := service.GetUserSpecificBuildDirName()

// Should initialize and return valid directory name
assert.NotEmpty(t, dirName, "GetUserSpecificBuildDirName should initialize if empty")
assert.True(t, strings.HasPrefix(dirName, BuildsJfrogPath),
"Lazily initialized directory should start with '%s', got: %s", BuildsJfrogPath, dirName)
}

func TestMultipleUsersGetDifferentPaths(t *testing.T) {
// This test verifies that the path includes a user identifier
// that would be different for different users
service := NewBuildInfoService()

path := service.tempDirPath

// Path should contain username component
currentUser, err := user.Current()
require.NoError(t, err)

expectedUserDir := BuildsJfrogPath + currentUser.Username
assert.True(t, strings.Contains(path, expectedUserDir),
"Path should contain user-specific directory '%s', got: %s", expectedUserDir, path)
}
Loading