Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
33 changes: 29 additions & 4 deletions build/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,35 @@ 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
tempDirPath string
logger utils.Log
buildDirectory string
}

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{}, buildDirectory: userSpecificBuildDir}
}

func (bis *BuildInfoService) GetUserSpecificBuildDirName() string {
if bis.buildDirectory == "" {
bis.buildDirectory = resolveUserSpecificBuildDirName()
}
return bis.buildDirectory
}

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

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

}
122 changes: 122 additions & 0 deletions build/service_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
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)

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

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",
buildDirectory: "", // Empty to trigger lazy init
}

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)

// Should also update the service's buildDirectory field
assert.Equal(t, dirName, service.buildDirectory,
"buildDirectory field should be updated after lazy init")
}

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