Skip to content

Commit

Permalink
Clean code, remove redundant, and unite common build tools logic (#1287)
Browse files Browse the repository at this point in the history
  • Loading branch information
sverdlov93 authored Nov 7, 2024
1 parent 85df769 commit 59ac976
Show file tree
Hide file tree
Showing 36 changed files with 572 additions and 1,008 deletions.
17 changes: 1 addition & 16 deletions artifactory/commands/dotnet/dotnetcommand.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,23 +159,8 @@ func changeWorkingDir(newWorkingDir string) (string, error) {
return newWorkingDir, errorutils.CheckError(err)
}

// Set Artifactory repo as source using the toolchain's `add source` command
func (dc *DotnetCommand) AddNugetAuthToConfig(cmdType dotnet.ToolchainType, configFile *os.File, sourceUrl, user, password string) error {
content := dotnet.ConfigFileTemplate
_, err := configFile.WriteString(content)
if err != nil {
return errorutils.CheckError(err)
}
// We need to close the config file to let the toolchain modify it.
err = configFile.Close()
if err != nil {
return errorutils.CheckError(err)
}
return addSourceToNugetConfig(cmdType, configFile.Name(), sourceUrl, user, password)
}

// Runs nuget sources add command
func addSourceToNugetConfig(cmdType dotnet.ToolchainType, configFileName, sourceUrl, user, password string) error {
func AddSourceToNugetConfig(cmdType dotnet.ToolchainType, configFileName, sourceUrl, user, password string) error {
cmd, err := dotnet.CreateDotnetAddSourceCmd(cmdType, sourceUrl)
if err != nil {
return err
Expand Down
87 changes: 81 additions & 6 deletions artifactory/commands/golang/go.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ import (
"github.com/jfrog/jfrog-cli-core/v2/common/project"
"github.com/jfrog/jfrog-cli-core/v2/utils/config"
"github.com/jfrog/jfrog-cli-core/v2/utils/coreutils"
goutils "github.com/jfrog/jfrog-cli-core/v2/utils/golang"
"github.com/jfrog/jfrog-client-go/auth"
"github.com/jfrog/jfrog-client-go/http/httpclient"
rtutils "github.com/jfrog/jfrog-client-go/utils"
"github.com/jfrog/jfrog-client-go/utils/errorutils"
"github.com/jfrog/jfrog-client-go/utils/io/fileutils"
"github.com/jfrog/jfrog-client-go/utils/log"
"net/http"
"net/url"
"os"
"path"
"path/filepath"
Expand Down Expand Up @@ -135,7 +135,7 @@ func (gc *GoCommand) extractNoFallbackFromArgs() (cleanArgs []string, err error)
}

func (gc *GoCommand) run() (err error) {
err = goutils.LogGoVersion()
err = logGoVersion()
if err != nil {
return
}
Expand All @@ -154,7 +154,7 @@ func (gc *GoCommand) run() (err error) {
return
}
// If noFallback=false, missing packages will be fetched directly from VCS
repoUrl, err := goutils.GetArtifactoryRemoteRepoUrl(resolverDetails, gc.resolverParams.TargetRepo(), goutils.GoProxyUrlParams{Direct: !gc.noFallback})
repoUrl, err := getArtifactoryRemoteRepoUrl(resolverDetails, gc.resolverParams.TargetRepo(), GoProxyUrlParams{Direct: !gc.noFallback})
if err != nil {
return
}
Expand Down Expand Up @@ -328,15 +328,15 @@ func buildPackageVersionRequest(name, branchName string) string {
return path.Join(packageVersionRequest, "latest.info")
}

func SetArtifactoryAsResolutionServer(serverDetails *config.ServerDetails, depsRepo string, goProxyParams goutils.GoProxyUrlParams) (err error) {
func SetArtifactoryAsResolutionServer(serverDetails *config.ServerDetails, depsRepo string, goProxyParams GoProxyUrlParams) (err error) {
if err = setGoProxy(serverDetails, depsRepo, goProxyParams); err != nil {
err = fmt.Errorf("failed while setting Artifactory as a dependencies resolution registry: %s", err.Error())
}
return
}

func setGoProxy(server *config.ServerDetails, remoteGoRepo string, goProxyParams goutils.GoProxyUrlParams) error {
repoUrl, err := goutils.GetArtifactoryRemoteRepoUrl(server, remoteGoRepo, goProxyParams)
func setGoProxy(server *config.ServerDetails, remoteGoRepo string, goProxyParams GoProxyUrlParams) error {
repoUrl, err := getArtifactoryRemoteRepoUrl(server, remoteGoRepo, goProxyParams)
if err != nil {
return err
}
Expand All @@ -346,3 +346,78 @@ func setGoProxy(server *config.ServerDetails, remoteGoRepo string, goProxyParams
func SetGoModCache(cacheFolder string) error {
return os.Setenv("GOMODCACHE", cacheFolder)
}

func logGoVersion() error {
version, err := biutils.GetParsedGoVersion()
if err != nil {
return errorutils.CheckError(err)
}
log.Info("Using go:", version.GetVersion())
return nil
}

type GoProxyUrlParams struct {
// Fallback to retrieve the modules directly from the source if
// the module failed to be retrieved from the proxy.
// add |direct to the end of the url.
// example: https://gocenter.io|direct
Direct bool
// The path from baseUrl to the standard Go repository path
// URL structure: <baseUrl>/<EndpointPrefix>/api/go/<repoName>
EndpointPrefix string
}

func (gdu *GoProxyUrlParams) BuildUrl(url *url.URL, repoName string) string {
url.Path = path.Join(url.Path, gdu.EndpointPrefix, "api/go/", repoName)

return gdu.addDirect(url.String())
}

func (gdu *GoProxyUrlParams) addDirect(url string) string {
if gdu.Direct && !strings.HasSuffix(url, "|direct") {
return url + "|direct"
}
return url
}

func getArtifactoryRemoteRepoUrl(serverDetails *config.ServerDetails, repo string, goProxyParams GoProxyUrlParams) (string, error) {
authServerDetails, err := serverDetails.CreateArtAuthConfig()
if err != nil {
return "", err
}
return getArtifactoryApiUrl(repo, authServerDetails, goProxyParams)
}

// Gets the URL of the specified repository Go API in Artifactory.
// The URL contains credentials (username and access token or password).
func getArtifactoryApiUrl(repoName string, details auth.ServiceDetails, goProxyParams GoProxyUrlParams) (string, error) {
rtUrl, err := url.Parse(details.GetUrl())
if err != nil {
return "", errorutils.CheckError(err)
}

username := details.GetUser()
password := details.GetPassword()

// Get credentials from access-token if exists.
if details.GetAccessToken() != "" {
log.Debug("Using proxy with access-token.")
if username == "" {
username = auth.ExtractUsernameFromAccessToken(details.GetAccessToken())
}
password = details.GetAccessToken()
}
if password != "" {
rtUrl.User = url.UserPassword(username, password)
}

return goProxyParams.BuildUrl(rtUrl, repoName), nil
}

func GetModuleName(projectDir string) (string, error) {
path, err := biutils.GetModuleNameByDir(projectDir, log.Logger)
if err != nil {
return "", errorutils.CheckError(err)
}
return path, nil
}
97 changes: 93 additions & 4 deletions artifactory/commands/golang/go_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ package golang

import (
"fmt"
biutils "github.com/jfrog/build-info-go/utils"
"github.com/jfrog/jfrog-cli-core/v2/utils/config"
"github.com/jfrog/jfrog-cli-core/v2/utils/coreutils"
goutils "github.com/jfrog/jfrog-cli-core/v2/utils/golang"
"github.com/jfrog/jfrog-client-go/artifactory/auth"
testsutils "github.com/jfrog/jfrog-client-go/utils/tests"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"net/url"
"os"
"path/filepath"
"strings"
Expand Down Expand Up @@ -34,7 +37,7 @@ func TestBuildPackageVersionRequest(t *testing.T) {
}

func TestGetPackageFilesPath(t *testing.T) {
packageCachePath, err := goutils.GetGoModCachePath()
packageCachePath, err := biutils.GetGoModCachePath()
assert.NoError(t, err)
packageName := "github.com/golang/mock/mockgen"
version := "v1.4.1"
Expand All @@ -61,7 +64,7 @@ func TestSetArtifactoryAsResolutionServer(t *testing.T) {
cleanup := testsutils.SetEnvWithCallbackAndAssert(t, "GOPROXY", "")
defer cleanup()

assert.NoError(t, SetArtifactoryAsResolutionServer(server, repo, goutils.GoProxyUrlParams{Direct: true}))
assert.NoError(t, SetArtifactoryAsResolutionServer(server, repo, GoProxyUrlParams{Direct: true}))

serverUrlWithoutHttp := strings.TrimPrefix(server.ArtifactoryUrl, "http://")
expectedGoProxy := fmt.Sprintf("http://%s:%s@%sapi/go/%s|direct", server.User, server.Password, serverUrlWithoutHttp, repo)
Expand All @@ -70,9 +73,95 @@ func TestSetArtifactoryAsResolutionServer(t *testing.T) {
// Verify that the EndpointPrefix value is correctly added to the GOPROXY.
// In this test case, the endpoint prefix is set to api/curation/audit/.
// This parameter allows downloading dependencies from a custom API instead of the default one.
assert.NoError(t, SetArtifactoryAsResolutionServer(server, repo, goutils.GoProxyUrlParams{Direct: true, EndpointPrefix: coreutils.CurationPassThroughApi}))
assert.NoError(t, SetArtifactoryAsResolutionServer(server, repo, GoProxyUrlParams{Direct: true, EndpointPrefix: coreutils.CurationPassThroughApi}))

serverUrlWithoutHttp = strings.TrimPrefix(server.ArtifactoryUrl, "http://")
expectedGoProxy = fmt.Sprintf("http://%s:%s@%sapi/curation/audit/api/go/%s|direct", server.User, server.Password, serverUrlWithoutHttp, repo)
assert.Equal(t, expectedGoProxy, os.Getenv("GOPROXY"))
}

func TestGetArtifactoryRemoteRepoUrl(t *testing.T) {
server := &config.ServerDetails{
ArtifactoryUrl: "https://server.com/artifactory",
AccessToken: "eyJ0eXAiOiJKV1QifQ.eyJzdWIiOiJmYWtlXC91c2Vyc1wvdGVzdCJ9.MTIzNDU2Nzg5MA",
}
repoName := "test-repo"
repoUrl, err := getArtifactoryRemoteRepoUrl(server, repoName, GoProxyUrlParams{})
assert.NoError(t, err)
assert.Equal(t, "https://test:eyJ0eXAiOiJKV1QifQ.eyJzdWIiOiJmYWtlXC91c2Vyc1wvdGVzdCJ9.MTIzNDU2Nzg5MA@server.com/artifactory/api/go/test-repo", repoUrl)
}

func TestGetArtifactoryApiUrl(t *testing.T) {
details := auth.NewArtifactoryDetails()
details.SetUrl("https://test.com/artifactory/")

// Test username and password
details.SetUser("frog")
details.SetPassword("passfrog")
url, err := getArtifactoryApiUrl("test-repo", details, GoProxyUrlParams{})
assert.NoError(t, err)
assert.Equal(t, "https://frog:[email protected]/artifactory/api/go/test-repo", url)

// Test username and password with EndpointPrefix and direct
details.SetUser("frog")
details.SetPassword("passfrog")
url, err = getArtifactoryApiUrl("test-repo", details, GoProxyUrlParams{EndpointPrefix: "test", Direct: true})
assert.NoError(t, err)
assert.Equal(t, "https://frog:[email protected]/artifactory/test/api/go/test-repo|direct", url)

// Test access token
// Set fake access token with username "test"
details.SetUser("")
details.SetAccessToken("eyJ0eXAiOiJKV1QifQ.eyJzdWIiOiJmYWtlXC91c2Vyc1wvdGVzdCJ9.MTIzNDU2Nzg5MA")
url, err = getArtifactoryApiUrl("test-repo", details, GoProxyUrlParams{})
assert.NoError(t, err)
assert.Equal(t, "https://test:eyJ0eXAiOiJKV1QifQ.eyJzdWIiOiJmYWtlXC91c2Vyc1wvdGVzdCJ9.MTIzNDU2Nzg5MA@test.com/artifactory/api/go/test-repo", url)

// Test access token with username
// Set fake access token with username "test"
// Expect username to be "frog"
details.SetUser("frog")
details.SetAccessToken("eyJ0eXAiOiJKV1QifQ.eyJzdWIiOiJmYWtlXC91c2Vyc1wvdGVzdCJ9.MTIzNDU2Nzg5MA")
url, err = getArtifactoryApiUrl("test-repo", details, GoProxyUrlParams{})
assert.NoError(t, err)
assert.Equal(t, "https://frog:eyJ0eXAiOiJKV1QifQ.eyJzdWIiOiJmYWtlXC91c2Vyc1wvdGVzdCJ9.MTIzNDU2Nzg5MA@test.com/artifactory/api/go/test-repo", url)
}

func TestGoProxyUrlParams_BuildUrl(t *testing.T) {
tests := []struct {
name string
RepoName string
Direct bool
EndpointPrefix string
ExpectedUrl string
}{
{
name: "Url Without direct or Prefix",
RepoName: "go",
ExpectedUrl: "https://test/api/go/go",
},
{
name: "Url With direct",
RepoName: "go",
Direct: true,
ExpectedUrl: "https://test/api/go/go|direct",
},
{
name: "Url With Prefix",
RepoName: "go",
EndpointPrefix: "prefix",
ExpectedUrl: "https://test/prefix/api/go/go",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
remoteUrl, err := url.Parse("https://test")
require.NoError(t, err)
gdu := &GoProxyUrlParams{
Direct: tt.Direct,
EndpointPrefix: tt.EndpointPrefix,
}
assert.Equalf(t, tt.ExpectedUrl, gdu.BuildUrl(remoteUrl, tt.RepoName), "BuildUrl(%v, %v)", remoteUrl, tt.RepoName)
})
}
}
3 changes: 1 addition & 2 deletions artifactory/commands/golang/gopublish.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"github.com/jfrog/jfrog-cli-core/v2/artifactory/utils"
buildUtils "github.com/jfrog/jfrog-cli-core/v2/common/build"
"github.com/jfrog/jfrog-cli-core/v2/common/project"
goutils "github.com/jfrog/jfrog-cli-core/v2/utils/golang"
clientutils "github.com/jfrog/jfrog-client-go/utils"
"github.com/jfrog/jfrog-client-go/utils/errorutils"
)
Expand Down Expand Up @@ -58,7 +57,7 @@ func (gpc *GoPublishCommand) Run() error {
return err
}

err = goutils.LogGoVersion()
err = logGoVersion()
if err != nil {
return err
}
Expand Down
14 changes: 11 additions & 3 deletions artifactory/commands/golang/publish.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"errors"
"fmt"
buildinfo "github.com/jfrog/build-info-go/entities"
"github.com/jfrog/build-info-go/utils"
"github.com/jfrog/gofrog/crypto"
"github.com/jfrog/gofrog/version"
"io"
Expand All @@ -17,7 +18,6 @@ import (
"time"

"github.com/jfrog/jfrog-cli-core/v2/common/build"
goutils "github.com/jfrog/jfrog-cli-core/v2/utils/golang"
"github.com/jfrog/jfrog-client-go/artifactory"
_go "github.com/jfrog/jfrog-client-go/artifactory/services/go"
servicesutils "github.com/jfrog/jfrog-client-go/artifactory/services/utils"
Expand All @@ -28,13 +28,13 @@ import (

// Publish go project to Artifactory.
func publishPackage(packageVersion, targetRepo, buildName, buildNumber, projectKey string, excludedPatterns []string, servicesManager artifactory.ArtifactoryServicesManager) (summary *servicesutils.OperationSummary, artifacts []buildinfo.Artifact, err error) {
projectPath, err := goutils.GetProjectRoot()
projectPath, err := getProjectRoot()
if err != nil {
return nil, nil, errorutils.CheckError(err)
}

// Read module name
moduleName, err := goutils.GetModuleName(projectPath)
moduleName, err := GetModuleName(projectPath)
if err != nil {
return nil, nil, err
}
Expand Down Expand Up @@ -238,3 +238,11 @@ type goInfo struct {
Version string `json:"Version"`
Time string `json:"Time"`
}

func getProjectRoot() (string, error) {
path, err := utils.GetProjectRoot()
if err != nil {
return "", errorutils.CheckError(err)
}
return path, nil
}
Loading

0 comments on commit 59ac976

Please sign in to comment.