Skip to content

Commit

Permalink
Setup Command - configure Gradle
Browse files Browse the repository at this point in the history
  • Loading branch information
omerzi committed Jan 27, 2025
1 parent 134977b commit 3dac034
Show file tree
Hide file tree
Showing 4 changed files with 215 additions and 0 deletions.
81 changes: 81 additions & 0 deletions artifactory/commands/gradle/gradle.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package gradle

import (
_ "embed"
"fmt"
"github.com/jfrog/jfrog-cli-core/v2/artifactory/commands/generic"
commandsutils "github.com/jfrog/jfrog-cli-core/v2/artifactory/commands/utils"
Expand All @@ -15,9 +16,15 @@ import (
"github.com/jfrog/jfrog-client-go/utils/errorutils"
"github.com/jfrog/jfrog-client-go/utils/io/fileutils"
"github.com/spf13/viper"
"os"
"path/filepath"
"strings"
"text/template"
)

//go:embed resources/init.gradle
var gradleInitScript string

const (
usePlugin = "useplugin"
useWrapper = "usewrapper"
Expand Down Expand Up @@ -231,6 +238,80 @@ func (gc *GradleCommand) setResult(result *commandsutils.Result) *GradleCommand
return gc
}

type InitScriptAuthConfig struct {
ArtifactoryURL string
ArtifactoryRepositoryKey string
ArtifactoryUsername string
ArtifactoryAccessToken string
}

// GenerateInitScript generates a Gradle init script with the provided authentication configuration.
func GenerateInitScript(config InitScriptAuthConfig) (string, error) {
tmpl, err := template.New("gradleTemplate").Parse(gradleInitScript)
if err != nil {
return "", fmt.Errorf("failed to parse Gradle init script template: %s", err)
}

var result strings.Builder
err = tmpl.Execute(&result, config)
if err != nil {
return "", fmt.Errorf("failed to execute Gradle init script template: %s", err)
}

return result.String(), nil
}

// WriteInitScriptWithBackup write the Gradle init script to the Gradle user home directory.
// If init scripts already exists, they will be backed up.
// Allows the user to interactively decide whether to overwrite existing init scripts.
func WriteInitScriptWithBackup(initScript string, interactUser bool) error {
gradleHome := os.Getenv("GRADLE_USER_HOME")
if gradleHome == "" {
homeDir, err := os.UserHomeDir()
if err != nil {
return fmt.Errorf("failed to get user home directory: %w", err)
}
gradleHome = filepath.Join(homeDir, ".gradle")
}
initScripts, err := getExistingGradleInitScripts(gradleHome)
if err != nil {
return err
}
if len(initScripts) > 0 && interactUser {
toContinue := coreutils.AskYesNo("Existing Gradle init scripts have been found. Do you want to overwrite them?", false)
if !toContinue {
return nil
}
}
if err = backupExistingGradleInitScripts(initScripts); err != nil {
return err
}
initScriptPath := filepath.Join(gradleHome, "init.gradle")
if err = os.WriteFile(initScriptPath, []byte(initScript), 0644); err != nil {
return fmt.Errorf("failed to write Gradle init script to %s: %w", initScriptPath, err)
}
return nil
}

func getExistingGradleInitScripts(gradleHome string) ([]string, error) {
gradleInitScripts, err := filepath.Glob(filepath.Join(gradleHome, "init.gradle*"))
if err != nil {
return nil, fmt.Errorf("failed while searching for Gradle init scripts: %w", err)
}
return gradleInitScripts, nil
}

// backupExistingGradleInitScripts backup existing Gradle init scripts in the Gradle user home directory.
func backupExistingGradleInitScripts(gradleInitScripts []string) error {
for _, script := range gradleInitScripts {
backupPath := script + ".bak"
if err := os.Rename(script, backupPath); err != nil {
return fmt.Errorf("failed to backup Gradle init script %s: %w", script, err)
}
}
return nil
}

func runGradle(vConfig *viper.Viper, tasks []string, deployableArtifactsFile string, configuration *build.BuildConfiguration, threads int, disableDeploy bool) error {
buildInfoService := build.CreateBuildInfoService()
buildName, err := configuration.GetBuildName()
Expand Down
73 changes: 73 additions & 0 deletions artifactory/commands/gradle/gradle_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package gradle

import (
"github.com/stretchr/testify/require"
"os"
"path/filepath"
"testing"

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

func TestGenerateInitScript(t *testing.T) {
config := InitScriptAuthConfig{
ArtifactoryURL: "http://example.com/artifactory",
ArtifactoryRepositoryKey: "example-repo",
ArtifactoryUsername: "user",
ArtifactoryAccessToken: "token",
}
script, err := GenerateInitScript(config)
assert.NoError(t, err)
assert.Contains(t, script, "http://example.com/artifactory")
assert.Contains(t, script, "example-repo")
assert.Contains(t, script, "user")
assert.Contains(t, script, "token")
}

func TestWriteInitScriptWithBackup(t *testing.T) {
tests := []struct {
name string
existingScript bool
expectedBackup bool
}{
{name: "No existing init.gradle", existingScript: false, expectedBackup: false},
{name: "Existing init.gradle", existingScript: true, expectedBackup: true},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Set up a temporary directory to act as the Gradle user home
tempDir := t.TempDir()
require.NoError(t, os.Setenv("GRADLE_USER_HOME", tempDir))
defer func() {
assert.NoError(t, os.Unsetenv("GRADLE_USER_HOME"))
}()

// Create a dummy init script
initScript := "init script content"

if tt.existingScript {
existingScriptPath := filepath.Join(tempDir, "init.gradle")
require.NoError(t, os.WriteFile(existingScriptPath, []byte("existing content"), 0644))
}

// Call the function
err := WriteInitScriptWithBackup(initScript, false)
assert.NoError(t, err)

// Verify the init script was written to the correct location
initScriptPath := filepath.Join(tempDir, "init.gradle")
content, err := os.ReadFile(initScriptPath)
assert.NoError(t, err)
assert.Equal(t, initScript, string(content))

// Verify backup if there was an existing script
if tt.expectedBackup {
backupScriptPath := initScriptPath + ".bak"
backupContent, err := os.ReadFile(backupScriptPath)
assert.NoError(t, err)
assert.Equal(t, "existing content", string(backupContent))
}
})
}
}
31 changes: 31 additions & 0 deletions artifactory/commands/gradle/resources/init.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
def artifactoryUrl = '{{ .ArtifactoryURL }}'
def artifactoryRepoKey = '{{ .ArtifactoryRepositoryKey }}'
def artifactoryUsername = '{{ .ArtifactoryUsername }}'
def artifactoryAccessToken = '{{ .ArtifactoryAccessToken }}'

gradle.settingsEvaluated { settings ->
settings.pluginManagement {
repositories {
maven {
url "${artifactoryUrl}/${artifactoryRepoKey}"
credentials {
username = artifactoryUsername
password = artifactoryAccessToken
}
}
gradlePluginPortal() // Fallback to Gradle Plugin Portal
}
}
}

allprojects { project ->
project.repositories {
maven {
url "${artifactoryUrl}/${artifactoryRepoKey}"
credentials {
username = artifactoryUsername
password = artifactoryAccessToken
}
}
}
}
30 changes: 30 additions & 0 deletions artifactory/commands/setup/setup.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package setup

import (
_ "embed"
"fmt"
bidotnet "github.com/jfrog/build-info-go/build/utils/dotnet"
biutils "github.com/jfrog/build-info-go/utils"
"github.com/jfrog/jfrog-cli-core/v2/artifactory/commands/dotnet"
gocommands "github.com/jfrog/jfrog-cli-core/v2/artifactory/commands/golang"
"github.com/jfrog/jfrog-cli-core/v2/artifactory/commands/gradle"
pythoncommands "github.com/jfrog/jfrog-cli-core/v2/artifactory/commands/python"
"github.com/jfrog/jfrog-cli-core/v2/artifactory/commands/repository"
commandsutils "github.com/jfrog/jfrog-cli-core/v2/artifactory/commands/utils"
Expand All @@ -17,12 +19,14 @@ import (
"github.com/jfrog/jfrog-cli-core/v2/utils/config"
"github.com/jfrog/jfrog-cli-core/v2/utils/coreutils"
"github.com/jfrog/jfrog-client-go/artifactory/services"
"github.com/jfrog/jfrog-client-go/auth"
"github.com/jfrog/jfrog-client-go/utils/errorutils"
"github.com/jfrog/jfrog-client-go/utils/log"
"golang.org/x/exp/maps"
"net/url"
"os"
"slices"
"strings"
)

// packageManagerToRepositoryPackageType maps project types to corresponding Artifactory repository package types.
Expand All @@ -46,6 +50,8 @@ var packageManagerToRepositoryPackageType = map[project.ProjectType]string{
project.Podman: repository.Docker,

project.Go: repository.Go,

project.Gradle: repository.Gradle,
}

// SetupCommand configures registries and authentication for various package manager (npm, Yarn, Pip, Pipenv, Poetry, Go)
Expand Down Expand Up @@ -147,6 +153,8 @@ func (sc *SetupCommand) Run() (err error) {
err = sc.configureDotnetNuget()
case project.Docker, project.Podman:
err = sc.configureContainer()
case project.Gradle:
err = sc.configureGradle()
default:
err = errorutils.CheckErrorf("unsupported package manager: %s", sc.packageManager)
}
Expand Down Expand Up @@ -349,3 +357,25 @@ func (sc *SetupCommand) configureContainer() error {
containerManagerType,
)
}

// configureGradle configures Gradle to use the specified Artifactory repository.
func (sc *SetupCommand) configureGradle() error {
password := sc.serverDetails.GetPassword()
username := sc.serverDetails.GetUser()
if sc.serverDetails.GetAccessToken() != "" {
password = sc.serverDetails.GetAccessToken()
username = auth.ExtractUsernameFromAccessToken(password)
}
initScriptAuthConfig := gradle.InitScriptAuthConfig{
ArtifactoryURL: strings.TrimSuffix(sc.serverDetails.GetArtifactoryUrl(), "/"),
ArtifactoryRepositoryKey: sc.repoName,
ArtifactoryAccessToken: password,
ArtifactoryUsername: username,
}
initScript, err := gradle.GenerateInitScript(initScriptAuthConfig)
if err != nil {
return err
}

return gradle.WriteInitScriptWithBackup(initScript, true)
}

0 comments on commit 3dac034

Please sign in to comment.