diff --git a/bitrise.yml b/bitrise.yml
index 4da805c4..f7b5d6c9 100644
--- a/bitrise.yml
+++ b/bitrise.yml
@@ -269,7 +269,7 @@ workflows:
inputs:
- content: |-
set -exo pipefail
- ../bitrise-build-cache-cli enable-for gradle --metrics -d
+ ../bitrise-build-cache-cli activate gradle -d --cache
- script:
title: Build and capture logs
inputs:
@@ -299,7 +299,7 @@ workflows:
inputs:
- content: |-
set -exo pipefail
- ../bitrise-build-cache-cli enable-for gradle --metrics -d
+ ../bitrise-build-cache-cli activate gradle -d --cache
- script:
title: Create local configuration cache
inputs:
@@ -406,7 +406,7 @@ workflows:
inputs:
- content: |-
set -exo pipefail
- ../bitrise-build-cache-cli enable-for gradle --metrics -d
+ ../bitrise-build-cache-cli activate gradle -d --cache
- script:
title: Create local configuration cache
inputs:
@@ -465,7 +465,7 @@ workflows:
inputs:
- content: |-
set -exo pipefail
- ../bitrise-build-cache-cli enable-for gradle --metrics -d
+ ../bitrise-build-cache-cli activate gradle -d --cache
- script:
title: Create local configuration cache
inputs:
diff --git a/cmd/activate.go b/cmd/activate.go
new file mode 100644
index 00000000..9ed36e16
--- /dev/null
+++ b/cmd/activate.go
@@ -0,0 +1,17 @@
+package cmd
+
+import (
+ "github.com/spf13/cobra"
+)
+
+// activateCmd represents the activate command
+var activateCmd = &cobra.Command{ //nolint:gochecknoglobals
+ Use: "activate",
+ Short: "Activate various bitrise plugins",
+ Long: `Activate Gradle, Bazel, etc. plugins
+Call the subcommands with the name of the tool you want to activate plugins for.`,
+}
+
+func init() {
+ rootCmd.AddCommand(activateCmd)
+}
diff --git a/cmd/activate_for_gradle.go b/cmd/activate_for_gradle.go
new file mode 100644
index 00000000..5df1967d
--- /dev/null
+++ b/cmd/activate_for_gradle.go
@@ -0,0 +1,116 @@
+package cmd
+
+import (
+ "fmt"
+ "os"
+
+ gradleconfig "github.com/bitrise-io/bitrise-build-cache-cli/internal/config/gradle"
+ "github.com/bitrise-io/go-utils/v2/log"
+ "github.com/bitrise-io/go-utils/v2/pathutil"
+ "github.com/spf13/cobra"
+)
+
+const (
+ errFmtFailedToUpdateProps = `failed to update gradle.properties: %w"`
+)
+
+// activateForGradleCmd represents the `gradle` subcommand under `activate`
+var activateForGradleCmd = &cobra.Command{ //nolint:gochecknoglobals
+ Use: "gradle",
+ Short: "Activate Bitrise Plugins for Gradle",
+ Long: `Activate Bitrise Plugins for Gradle.
+This command will:
+
+- Create a ~/.gradle/init.d/bitrise-build-cache.init.gradle.kts file with the necessary configs. This file will be overwritten.
+- Create a ~/.gradle/gradle.properties file with org.gradle.caching=true when adding the caching plugin.
+
+The gradle.properties file will be created if it doesn't exist.
+If it already exists a "# [start/end] generated-by-bitrise-build-cache" block will be added to the end of the file.
+If the "# [start/end] generated-by-bitrise-build-cache" block is already present in the file then only the block's content will be modified.
+`,
+ SilenceUsage: true,
+ RunE: func(cmd *cobra.Command, _ []string) error {
+ logger := log.NewLogger()
+ logger.EnableDebugLog(isDebugLogMode)
+ logger.TInfof("Activate Bitrise plugins for Gradle")
+
+ gradleHome, err := pathutil.NewPathModifier().AbsPath(gradleHomeNonExpanded)
+ if err != nil {
+ return fmt.Errorf("expand Gradle home path (%s), error: %w", gradleHome, err)
+ }
+
+ if err := getPlugins(cmd.Context(), logger, os.Getenv); err != nil {
+ return fmt.Errorf("failed to fetch plugins: %w", err)
+ }
+
+ if err := activateForGradleCmdFn(
+ logger,
+ gradleHome,
+ os.Getenv,
+ activateForGradleParams.TemplateInventory,
+ func(
+ inventory gradleconfig.TemplateInventory,
+ path string,
+ ) error {
+ return inventory.WriteToGradleInit(
+ logger,
+ path,
+ gradleconfig.DefaultOsProxy(),
+ gradleconfig.DefaultTemplateProxy(),
+ )
+ },
+ gradleconfig.DefaultGradlePropertiesUpdater(),
+ ); err != nil {
+ return fmt.Errorf("activate plugins for Gradle: %w", err)
+ }
+
+ logger.TInfof("✅ Bitrise plugins activated")
+
+ return nil
+ },
+}
+
+//nolint:gochecknoglobals
+var activateForGradleParams = gradleconfig.DefaultActivateForGradleParams()
+
+func init() {
+ activateCmd.AddCommand(activateForGradleCmd)
+ activateForGradleCmd.Flags().BoolVar(&activateForGradleParams.Cache.Enabled, "cache", activateForGradleParams.Cache.Enabled, "Activate cache plugin. Will override cache-dep.")
+ activateForGradleCmd.Flags().BoolVar(&activateForGradleParams.Cache.JustDependency, "cache-dep", activateForGradleParams.Cache.JustDependency, "Add cache plugin as a dependency only.")
+ activateForGradleCmd.Flags().BoolVar(&activateForGradleParams.Cache.PushEnabled, "cache-push", activateForGradleParams.Cache.PushEnabled, "Push enabled/disabled. Enabled means the build can also write new entries to the remote cache. Disabled means the build can only read from the remote cache.")
+ activateForGradleCmd.Flags().StringVar(&activateForGradleParams.Cache.ValidationLevel, "cache-validation", activateForGradleParams.Cache.ValidationLevel, "Level of cache entry validation for both uploads and downloads. Possible values: none, warning, error")
+ activateForGradleCmd.Flags().StringVar(&activateForGradleParams.Cache.Endpoint, "cache-endpoint", activateForGradleParams.Cache.Endpoint, "The endpoint can be manually provided here for caching operations.")
+
+ activateForGradleCmd.Flags().BoolVar(&activateForGradleParams.Analytics.Enabled, "analytics", activateForGradleParams.Analytics.Enabled, "Activate analytics plugin. Will override analytics-dep.")
+ activateForGradleCmd.Flags().BoolVar(&activateForGradleParams.Analytics.JustDependency, "analytics-dep", activateForGradleParams.Analytics.JustDependency, "Add analytics plugin as a dependency only.")
+
+ activateForGradleCmd.Flags().BoolVar(&activateForGradleParams.TestDistro.Enabled, "test-distribution", activateForGradleParams.TestDistro.Enabled, "Activate test distribution plugin for the provided app slug. Will override test-distribution-dep.")
+ activateForGradleCmd.Flags().BoolVar(&activateForGradleParams.TestDistro.JustDependency, "test-distribution-dep", activateForGradleParams.TestDistro.JustDependency, "Add test distribution plugin as a dependency only.")
+}
+
+func activateForGradleCmdFn(
+ logger log.Logger,
+ gradleHomePath string,
+ envProvider func(string) string,
+ templateInventoryProvider func(log.Logger, func(string) string, bool) (gradleconfig.TemplateInventory, error),
+ templateWriter func(gradleconfig.TemplateInventory, string) error,
+ updater gradleconfig.GradlePropertiesUpdater,
+) error {
+ templateInventory, err := templateInventoryProvider(logger, envProvider, isDebugLogMode)
+ if err != nil {
+ return err
+ }
+
+ if err := templateWriter(
+ templateInventory,
+ gradleHomePath,
+ ); err != nil {
+ return err
+ }
+
+ if err := updater.UpdateGradleProps(activateForGradleParams, logger, gradleHomePath); err != nil {
+ return fmt.Errorf(errFmtFailedToUpdateProps, err)
+ }
+
+ return nil
+}
diff --git a/cmd/activate_for_gradle_cmd_test.go b/cmd/activate_for_gradle_cmd_test.go
new file mode 100644
index 00000000..7949f2a2
--- /dev/null
+++ b/cmd/activate_for_gradle_cmd_test.go
@@ -0,0 +1,181 @@
+//nolint:dupl
+package cmd
+
+import (
+ "errors"
+ "fmt"
+ "os"
+ "testing"
+
+ gradleconfig "github.com/bitrise-io/bitrise-build-cache-cli/internal/config/gradle"
+ "github.com/bitrise-io/go-utils/v2/log"
+ "github.com/bitrise-io/go-utils/v2/mocks"
+ "github.com/stretchr/testify/mock"
+ "github.com/stretchr/testify/require"
+)
+
+func Test_activateForGradleCmdFn(t *testing.T) {
+ prep := func() log.Logger {
+ mockLogger := &mocks.Logger{}
+ mockLogger.On("Infof", mock.Anything).Return()
+ mockLogger.On("Infof", mock.Anything, mock.Anything).Return()
+ mockLogger.On("Debugf", mock.Anything).Return()
+ mockLogger.On("Debugf", mock.Anything, mock.Anything).Return()
+ mockLogger.On("Errorf", mock.Anything).Return()
+ mockLogger.On("Errorf", mock.Anything, mock.Anything).Return()
+
+ return mockLogger
+ }
+
+ t.Run("activateForGradleCmdFn", func(t *testing.T) {
+ mockLogger := prep()
+ templateInventory := gradleconfig.TemplateInventory{
+ Common: gradleconfig.PluginCommonTemplateInventory{
+ AppSlug: "AppSlugValue",
+ },
+ }
+
+ var actualTemplateInventory *gradleconfig.TemplateInventory
+ var actualPath *string
+
+ // when
+ err := activateForGradleCmdFn(
+ mockLogger,
+ "~/.gradle",
+ func(string) string { return "" },
+ func(log.Logger, func(string) string, bool) (gradleconfig.TemplateInventory, error) {
+ return templateInventory, nil
+ },
+ func(
+ inventory gradleconfig.TemplateInventory,
+ _ string,
+ ) error {
+ actualTemplateInventory = &inventory
+
+ return nil
+ },
+ gradleconfig.GradlePropertiesUpdater{
+ OsProxy: gradleconfig.OsProxy{
+ ReadFileIfExists: func(pth string) (string, bool, error) {
+ actualPath = &pth
+
+ return "", true, nil
+ },
+ WriteFile: func(string, []byte, os.FileMode) error { return nil },
+ },
+ },
+ )
+
+ // then
+ require.NoError(t, err)
+ require.Equal(t, templateInventory, *actualTemplateInventory)
+ require.Equal(t, "~/.gradle/gradle.properties", *actualPath)
+ })
+
+ t.Run("when templateInventory creation fails activateForGradleCmdFn throws error", func(t *testing.T) {
+ mockLogger := prep()
+ inventoryCreationError := errors.New("failed to create inventory")
+
+ // when
+ err := activateForGradleCmdFn(
+ mockLogger,
+ "~/.gradle",
+ func(string) string { return "" },
+ func(log.Logger, func(string) string, bool) (gradleconfig.TemplateInventory, error) {
+ return gradleconfig.TemplateInventory{}, inventoryCreationError
+ },
+ func(
+ gradleconfig.TemplateInventory,
+ string,
+ ) error {
+ return nil
+ },
+ gradleconfig.GradlePropertiesUpdater{
+ OsProxy: gradleconfig.OsProxy{
+ ReadFileIfExists: func(string) (string, bool, error) {
+ return "", true, nil
+ },
+ WriteFile: func(string, []byte, os.FileMode) error { return nil },
+ },
+ },
+ )
+
+ // then
+ require.EqualError(t, err, inventoryCreationError.Error())
+ })
+
+ t.Run("when template writing fails activateForGradleCmdFn throws error", func(t *testing.T) {
+ mockLogger := prep()
+ templateWriteError := errors.New("failed to write template")
+
+ // when
+ err := activateForGradleCmdFn(
+ mockLogger,
+ "~/.gradle",
+ func(string) string { return "" },
+ func(log.Logger, func(string) string, bool) (gradleconfig.TemplateInventory, error) {
+ return gradleconfig.TemplateInventory{}, nil
+ },
+ func(
+ gradleconfig.TemplateInventory,
+ string,
+ ) error {
+ return templateWriteError
+ },
+ gradleconfig.GradlePropertiesUpdater{
+ OsProxy: gradleconfig.OsProxy{
+ ReadFileIfExists: func(string) (string, bool, error) {
+ return "", true, nil
+ },
+ WriteFile: func(string, []byte, os.FileMode) error { return nil },
+ },
+ },
+ )
+
+ // then
+ require.EqualError(t, err, templateWriteError.Error())
+ })
+
+ t.Run("when gradle.property update fails activateForGradleCmdFn throws error", func(t *testing.T) {
+ mockLogger := prep()
+ gradlePropertiesUpdateError := errors.New("failed to update gradle.properties")
+
+ // when
+ err := activateForGradleCmdFn(
+ mockLogger,
+ "~/.gradle",
+ func(string) string { return "" },
+ func(log.Logger, func(string) string, bool) (gradleconfig.TemplateInventory, error) {
+ return gradleconfig.TemplateInventory{}, nil
+ },
+ func(
+ gradleconfig.TemplateInventory,
+ string,
+ ) error {
+ return nil
+ },
+ gradleconfig.GradlePropertiesUpdater{
+ OsProxy: gradleconfig.OsProxy{
+ ReadFileIfExists: func(string) (string, bool, error) {
+ return "", true, nil
+ },
+ WriteFile: func(string, []byte, os.FileMode) error { return gradlePropertiesUpdateError },
+ },
+ },
+ )
+
+ // then
+ require.EqualError(
+ t,
+ err,
+ fmt.Errorf(
+ errFmtFailedToUpdateProps,
+ fmt.Errorf(
+ gradleconfig.ErrFmtGradlePropertyWrite,
+ "~/.gradle/gradle.properties",
+ gradlePropertiesUpdateError,
+ ),
+ ).Error(),
+ )
+ })
+}
diff --git a/cmd/asset/verification-metadata.xml b/cmd/asset/verification-metadata.xml
index f3294b0a..d4218be1 100644
--- a/cmd/asset/verification-metadata.xml
+++ b/cmd/asset/verification-metadata.xml
@@ -47,11 +47,6 @@
-
-
-
-
-
@@ -60,11 +55,6 @@
-
-
-
-
-
@@ -78,6 +68,11 @@
+
+
+
+
+
@@ -91,6 +86,11 @@
+
+
+
+
+
@@ -133,6 +133,14 @@
+
+
+
+
+
+
+
+
@@ -141,6 +149,14 @@
+
+
+
+
+
+
+
+
@@ -196,6 +212,14 @@
+
+
+
+
+
+
+
+
@@ -220,6 +244,14 @@
+
+
+
+
+
+
+
+
@@ -236,6 +268,14 @@
+
+
+
+
+
+
+
+
@@ -260,6 +300,14 @@
+
+
+
+
+
+
+
+
@@ -325,6 +373,11 @@
+
+
+
+
+
@@ -341,11 +394,6 @@
-
-
-
-
-
@@ -354,6 +402,11 @@
+
+
+
+
+
@@ -367,6 +420,11 @@
+
+
+
+
+
@@ -395,11 +453,6 @@
-
-
-
-
-
@@ -541,11 +594,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -572,6 +664,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -642,6 +747,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cmd/client.go b/cmd/client.go
index 11bb308d..a589f7d8 100644
--- a/cmd/client.go
+++ b/cmd/client.go
@@ -47,7 +47,7 @@ func createKVClient(ctx context.Context,
ClientName: params.ClientName,
AuthConfig: params.AuthConfig,
Logger: params.Logger,
- CacheConfigMetadata: common.NewCacheConfigMetadata(params.EnvProvider, params.CommandFunc, params.Logger),
+ CacheConfigMetadata: common.NewMetadata(params.EnvProvider, params.CommandFunc, params.Logger),
CacheOperationID: params.CacheOperationID,
})
if err != nil {
diff --git a/cmd/enableForBazel.go b/cmd/enableForBazel.go
index 0afaf959..8b6ef7e4 100644
--- a/cmd/enableForBazel.go
+++ b/cmd/enableForBazel.go
@@ -81,8 +81,8 @@ func enableForBazelCmdFn(logger log.Logger, homeDirPath string, envProvider func
logger.Infof("(i) RBE is not available at this location")
}
}
- // Metadata
- cacheConfig := common.NewCacheConfigMetadata(os.Getenv,
+ // CacheConfigMetadata
+ cacheConfig := common.NewMetadata(os.Getenv,
func(name string, v ...string) (string, error) {
output, err := exec.Command(name, v...).Output()
diff --git a/cmd/enable_for_gradle.go b/cmd/enable_for_gradle.go
index 3c62d6ba..3cf5cfb0 100644
--- a/cmd/enable_for_gradle.go
+++ b/cmd/enable_for_gradle.go
@@ -2,23 +2,23 @@ package cmd
import (
"context"
- "errors"
"fmt"
"os"
"os/exec"
- "path/filepath"
"github.com/bitrise-io/bitrise-build-cache-cli/internal/config/common"
gradleconfig "github.com/bitrise-io/bitrise-build-cache-cli/internal/config/gradle"
"github.com/bitrise-io/bitrise-build-cache-cli/internal/gradle"
- "github.com/bitrise-io/bitrise-build-cache-cli/internal/stringmerge"
"github.com/bitrise-io/go-utils/v2/log"
"github.com/bitrise-io/go-utils/v2/pathutil"
"github.com/google/uuid"
"github.com/spf13/cobra"
)
-const gradleHomeNonExpanded = "~/.gradle"
+const (
+ gradleHomeNonExpanded = "~/.gradle"
+ FmtErrorEnableForGradle = "adding Gradle plugins failed: %w"
+)
//nolint:gochecknoglobals
var (
@@ -28,8 +28,6 @@ var (
paramRemoteCacheEndpoint string
)
-var errInvalidCacheLevel = errors.New("invalid cache validation level, valid options: none, warning, error")
-
// enableForGradleCmd represents the gradle command
var enableForGradleCmd = &cobra.Command{ //nolint:gochecknoglobals
Use: "gradle",
@@ -79,99 +77,30 @@ func init() {
enableForGradleCmd.Flags().StringVar(¶mRemoteCacheEndpoint, "remote-cache-endpoint", "", "Remote cache endpoint URL")
}
-func writeGradleInit(logger log.Logger, gradleHomePath string, endpointURL string, authToken string, cacheConfigMetadata common.CacheConfigMetadata, prefs gradleconfig.Preferences) error {
- logger.Infof("(i) Ensure ~/.gradle and ~/.gradle/init.d directories exist")
- gradleInitDPath := filepath.Join(gradleHomePath, "init.d")
- err := os.MkdirAll(gradleInitDPath, 0755) //nolint:gomnd,mnd
- if err != nil {
- return fmt.Errorf("ensure ~/.gradle/init.d exists: %w", err)
- }
-
- logger.Infof("(i) Generate ~/.gradle/init.d/bitrise-build-cache.init.gradle.kts")
- initGradleContent, err := gradleconfig.GenerateInitGradle(endpointURL, authToken, prefs, cacheConfigMetadata)
- if err != nil {
- return fmt.Errorf("generate bitrise-build-cache.init.gradle.kts: %w", err)
- }
-
- logger.Infof("(i) Write ~/.gradle/init.d/bitrise-build-cache.init.gradle.kts")
- {
- initGradlePath := filepath.Join(gradleInitDPath, "bitrise-build-cache.init.gradle.kts")
- err = os.WriteFile(initGradlePath, []byte(initGradleContent), 0755) //nolint:gosec,gomnd,mnd
- if err != nil {
- return fmt.Errorf("write bitrise-build-cache.init.gradle.kts to %s, error: %w", initGradlePath, err)
- }
- }
-
- return nil
-}
-
func enableForGradleCmdFn(logger log.Logger, gradleHomePath string, envProvider func(string) string) error {
- logger.Infof("(i) Checking parameters")
-
- // Required configs
- logger.Infof("(i) Check Auth Config")
- authConfig, err := common.ReadAuthConfigFromEnvironments(envProvider)
+ activateForGradleParams.Cache.Enabled = true
+ activateForGradleParams.Cache.PushEnabled = paramIsPushEnabled
+ activateForGradleParams.Cache.ValidationLevel = paramValidationLevel
+ activateForGradleParams.Cache.Endpoint = paramRemoteCacheEndpoint
+ activateForGradleParams.Analytics.Enabled = paramIsGradleMetricsEnabled
+ activateForGradleParams.TestDistro.Enabled = false
+
+ templateInventory, err := activateForGradleParams.TemplateInventory(logger, envProvider, isDebugLogMode)
if err != nil {
- return fmt.Errorf("read auth config from environment variables: %w", err)
- }
- authToken := authConfig.TokenInGradleFormat()
-
- // Optional configs
- // EndpointURL
- endpointURL := common.SelectCacheEndpointURL(paramRemoteCacheEndpoint, envProvider)
- logger.Infof("(i) Build Cache Endpoint URL: %s", endpointURL)
- logger.Infof("(i) Push new cache entries: %t", paramIsPushEnabled)
- logger.Infof("(i) Cache entry validation level: %s", paramValidationLevel)
- logger.Infof("(i) Collect metrics for cache insights: %t", paramIsGradleMetricsEnabled)
- logger.Infof("(i) Debug mode and verbose logs: %t", isDebugLogMode)
-
- if paramValidationLevel != string(gradleconfig.CacheValidationLevelNone) &&
- paramValidationLevel != string(gradleconfig.CacheValidationLevelWarning) &&
- paramValidationLevel != string(gradleconfig.CacheValidationLevelError) {
- logger.Errorf("Invalid validation level: '%s'", paramValidationLevel)
-
- return errInvalidCacheLevel
- }
- // Metadata
- cacheConfigMetadata := common.NewCacheConfigMetadata(os.Getenv,
- func(name string, v ...string) (string, error) {
- output, err := exec.Command(name, v...).Output()
-
- return string(output), err
- }, logger)
- logger.Infof("(i) Cache Config Metadata: %+v", cacheConfigMetadata)
-
- prefs := gradleconfig.Preferences{
- IsDependencyOnly: false,
- IsPushEnabled: paramIsPushEnabled,
- CacheLevelValidation: gradleconfig.CacheValidationLevel(paramValidationLevel),
- IsAnalyticsEnabled: paramIsGradleMetricsEnabled,
- IsDebugEnabled: isDebugLogMode,
+ return fmt.Errorf(FmtErrorEnableForGradle, err)
}
- if err := writeGradleInit(logger, gradleHomePath, endpointURL, authToken, cacheConfigMetadata, prefs); err != nil {
- return err
- }
-
- logger.Infof("(i) Write ~/.gradle/gradle.properties")
- {
- gradlePropertiesPath := filepath.Join(gradleHomePath, "gradle.properties")
- currentGradlePropsFileContent, isGradlePropsExists, err := readFileIfExists(gradlePropertiesPath)
- if err != nil {
- return fmt.Errorf("check if gradle.properties exists at %s, error: %w", gradlePropertiesPath, err)
- }
- logger.Debugf("isGradlePropsExists: %t", isGradlePropsExists)
- gradlePropertiesContent := stringmerge.ChangeContentInBlock(
- currentGradlePropsFileContent,
- "# [start] generated-by-bitrise-build-cache",
- "# [end] generated-by-bitrise-build-cache",
- "org.gradle.caching=true",
- )
+ if err := templateInventory.WriteToGradleInit(
+ logger,
+ gradleHomePath,
+ gradleconfig.DefaultOsProxy(),
+ gradleconfig.DefaultTemplateProxy(),
+ ); err != nil {
+ return fmt.Errorf(FmtErrorEnableForGradle, err)
+ }
- err = os.WriteFile(gradlePropertiesPath, []byte(gradlePropertiesContent), 0755) //nolint:gosec,gomnd,mnd
- if err != nil {
- return fmt.Errorf("write gradle.properties to %s, error: %w", gradlePropertiesPath, err)
- }
+ if err := gradleconfig.DefaultGradlePropertiesUpdater().UpdateGradleProps(activateForGradleParams, logger, gradleHomePath); err != nil {
+ return fmt.Errorf(FmtErrorEnableForGradle, err)
}
return nil
@@ -204,10 +133,7 @@ func getPlugins(ctx context.Context, logger log.Logger, envProvider func(string)
pluginCacher := gradle.PluginCacher{}
- if err = pluginCacher.CachePlugins(ctx, kvClient, logger, []gradle.Plugin{
- gradle.PluginAnalytics(),
- gradle.PluginCache(),
- }); err != nil {
+ if err = pluginCacher.CachePlugins(ctx, kvClient, logger, gradle.Plugins()); err != nil {
return fmt.Errorf("caching plugins: %w", err)
}
diff --git a/cmd/enable_for_gradle_test.go b/cmd/enable_for_gradle_test.go
index bc47c11b..5b8068c8 100644
--- a/cmd/enable_for_gradle_test.go
+++ b/cmd/enable_for_gradle_test.go
@@ -1,9 +1,12 @@
package cmd
import (
+ "fmt"
"path/filepath"
"testing"
+ "github.com/bitrise-io/bitrise-build-cache-cli/internal/config/common"
+ gradleconfig "github.com/bitrise-io/bitrise-build-cache-cli/internal/config/gradle"
"github.com/bitrise-io/go-utils/v2/log"
"github.com/bitrise-io/go-utils/v2/mocks"
"github.com/bitrise-io/go-utils/v2/pathutil"
@@ -35,10 +38,10 @@ func Test_enableForGradleCmdFn(t *testing.T) {
err := enableForGradleCmdFn(mockLogger, tmpGradleHomeDir, envVars)
// then
- require.EqualError(t, err, "read auth config from environment variables: BITRISE_BUILD_CACHE_AUTH_TOKEN or BITRISEIO_BITRISE_SERVICES_ACCESS_TOKEN environment variable not set")
+ require.EqualError(t, err, fmt.Errorf(FmtErrorEnableForGradle, fmt.Errorf(gradleconfig.ErrFmtReadAutConfig, common.ErrAuthTokenNotProvided)).Error())
})
- t.Run("No envs specified", func(t *testing.T) {
+ t.Run("Envs specified", func(t *testing.T) {
mockLogger, tmpGradleHomeDir := prep()
envVars := createEnvProvider(map[string]string{
"BITRISE_BUILD_CACHE_AUTH_TOKEN": "AuthTokenValue",
diff --git a/cmd/gradleVerificationAddDeps.go b/cmd/gradleVerificationAddDeps.go
index 6bcd85bd..50304e0d 100644
--- a/cmd/gradleVerificationAddDeps.go
+++ b/cmd/gradleVerificationAddDeps.go
@@ -3,9 +3,7 @@ package cmd
import (
"fmt"
"os"
- "os/exec"
- "github.com/bitrise-io/bitrise-build-cache-cli/internal/config/common"
gradleconfig "github.com/bitrise-io/bitrise-build-cache-cli/internal/config/gradle"
"github.com/bitrise-io/go-utils/v2/log"
"github.com/bitrise-io/go-utils/v2/pathutil"
@@ -15,8 +13,8 @@ import (
// addGradleVerificationReferenceDeps represents the gradle command
var addGradleVerificationReferenceDeps = &cobra.Command{ //nolint:gochecknoglobals
Use: "add-reference-deps",
- Short: "Add Bitrise Build Cache plugins to the project (but do not enable it)",
- Long: `Add Bitrise Build Cache plugins to the project (but do not enable it)
+ Short: "Add Bitrise Build Cache plugins to the project (but do not enable them)",
+ Long: `Add Bitrise Build Cache plugins to the project (but do not enable them)
This command will:
- Create a ~/.gradle/init.d/bitrise-build-cache.init.gradle.kts file with the necessary configs. This file will be overwritten.
@@ -49,33 +47,31 @@ func init() {
}
func addGradlePluginsFn(logger log.Logger, gradleHomePath string, envProvider func(string) string) error {
- logger.Infof("(i) Checking parameters")
+ activateForGradleParams.Cache.Enabled = false
+ activateForGradleParams.Cache.JustDependency = true
+ activateForGradleParams.Analytics.Enabled = false
+ activateForGradleParams.Analytics.JustDependency = true
+ activateForGradleParams.TestDistro.Enabled = false
+ activateForGradleParams.TestDistro.JustDependency = true
- // Optional configs
- // EndpointURL
- endpointURL := common.SelectCacheEndpointURL(paramRemoteCacheEndpoint, envProvider)
- logger.Infof("(i) Build Cache Endpoint URL: %s", endpointURL)
- logger.Infof("(i) Debug mode and verbose logs: %t", isDebugLogMode)
-
- // Metadata
- cacheConfigMetadata := common.NewCacheConfigMetadata(os.Getenv, func(name string, v ...string) (string, error) {
- output, err := exec.Command(name, v...).Output()
-
- return string(output), err
- }, logger)
- logger.Infof("(i) Cache Config Metadata: %+v", cacheConfigMetadata)
-
- authToken := "placeholder-token"
- prefs := gradleconfig.Preferences{
- IsDependencyOnly: true,
- IsPushEnabled: false,
- CacheLevelValidation: gradleconfig.CacheValidationLevelNone,
- IsAnalyticsEnabled: true,
- IsDebugEnabled: isDebugLogMode,
+ templateInventory, err := activateForGradleParams.TemplateInventory(logger, envProvider, isDebugLogMode)
+ if err != nil {
+ return fmt.Errorf(FmtErrorGradleVerification, err)
}
- if err := writeGradleInit(logger, gradleHomePath, endpointURL, authToken, cacheConfigMetadata, prefs); err != nil {
- return err
+
+ if err := templateInventory.WriteToGradleInit(
+ logger,
+ gradleHomePath,
+ gradleconfig.DefaultOsProxy(),
+ gradleconfig.DefaultTemplateProxy(),
+ ); err != nil {
+ return fmt.Errorf(FmtErrorGradleVerification, err)
}
return nil
}
+
+//nolint:gochecknoglobals
+var (
+ FmtErrorGradleVerification = "adding Gradle plugins failed: %w"
+)
diff --git a/internal/config/bazel/bazel_config.go b/internal/config/bazel/bazel_config.go
index f9fd66d2..332b6894 100644
--- a/internal/config/bazel/bazel_config.go
+++ b/internal/config/bazel/bazel_config.go
@@ -24,7 +24,7 @@ type templateInventory struct {
WorkspaceID string
AuthToken string
IsTimestampsEnabled bool
- // Metadata
+ // CacheConfigMetadata
CacheConfigMetadata common.CacheConfigMetadata
}
diff --git a/internal/config/common/auth.go b/internal/config/common/auth.go
index 10577682..725acef4 100644
--- a/internal/config/common/auth.go
+++ b/internal/config/common/auth.go
@@ -3,8 +3,8 @@ package common
import "errors"
var (
- errAuthTokenNotProvided = errors.New("BITRISE_BUILD_CACHE_AUTH_TOKEN or BITRISEIO_BITRISE_SERVICES_ACCESS_TOKEN environment variable not set")
- errWorkspaceIDNotProvided = errors.New("BITRISE_BUILD_CACHE_WORKSPACE_ID environment variable not set")
+ ErrAuthTokenNotProvided = errors.New("BITRISE_BUILD_CACHE_AUTH_TOKEN or BITRISEIO_BITRISE_SERVICES_ACCESS_TOKEN environment variable not set")
+ ErrWorkspaceIDNotProvided = errors.New("BITRISE_BUILD_CACHE_WORKSPACE_ID environment variable not set")
)
// CacheAuthConfig holds the auth config for the cache.
@@ -44,8 +44,8 @@ func ReadAuthConfigFromEnvironments(envProvider func(string) string) (CacheAuthC
// Write specific errors for each case.
if len(authTokenEnv) < 1 {
- return CacheAuthConfig{}, errAuthTokenNotProvided
+ return CacheAuthConfig{}, ErrAuthTokenNotProvided
}
- return CacheAuthConfig{}, errWorkspaceIDNotProvided
+ return CacheAuthConfig{}, ErrWorkspaceIDNotProvided
}
diff --git a/internal/config/common/auth_test.go b/internal/config/common/auth_test.go
index a1badcc4..c89844f9 100644
--- a/internal/config/common/auth_test.go
+++ b/internal/config/common/auth_test.go
@@ -16,7 +16,7 @@ func TestReadAuthConfigFromEnvironments(t *testing.T) {
{
name: "No envs specified",
envVars: map[string]string{},
- expectedError: errAuthTokenNotProvided,
+ expectedError: ErrAuthTokenNotProvided,
},
{
name: "Only BITRISEIO_BITRISE_SERVICES_ACCESS_TOKEN set",
@@ -45,14 +45,14 @@ func TestReadAuthConfigFromEnvironments(t *testing.T) {
envVars: map[string]string{
"BITRISE_BUILD_CACHE_AUTH_TOKEN": "auth-token",
},
- expectedError: errWorkspaceIDNotProvided,
+ expectedError: ErrWorkspaceIDNotProvided,
},
{
name: "Only BITRISE_BUILD_CACHE_WORKSPACE_ID set",
envVars: map[string]string{
"BITRISE_BUILD_CACHE_WORKSPACE_ID": "workspace-id",
},
- expectedError: errAuthTokenNotProvided,
+ expectedError: ErrAuthTokenNotProvided,
},
}
diff --git a/internal/config/common/cache_config.go b/internal/config/common/cache_config.go
index 66a47868..e72ff05d 100644
--- a/internal/config/common/cache_config.go
+++ b/internal/config/common/cache_config.go
@@ -90,8 +90,8 @@ func createCacheConfigMetadata(provider, repoURL string,
}
}
-// NewCacheConfigMetadata creates a new CacheConfigMetadata instance based on the environment variables.
-func NewCacheConfigMetadata(envProvider EnvProviderFunc, commandFunc CommandFunc, logger log.Logger) CacheConfigMetadata {
+// NewMetadata creates a new CacheConfigMetadata instance based on the environment variables.
+func NewMetadata(envProvider EnvProviderFunc, commandFunc CommandFunc, logger log.Logger) CacheConfigMetadata {
hostMetadata := generateHostMetadata(envProvider, commandFunc, logger)
provider := detectCIProvider(envProvider)
diff --git a/internal/config/common/cache_config_test.go b/internal/config/common/cache_config_test.go
index 41a7315b..0548719e 100644
--- a/internal/config/common/cache_config_test.go
+++ b/internal/config/common/cache_config_test.go
@@ -200,10 +200,10 @@ func TestNewCacheConfigMetadata(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
- if got := NewCacheConfigMetadata(tt.args.envProvider,
+ if got := NewMetadata(tt.args.envProvider,
tt.args.commandFunc,
log.NewLogger()); !reflect.DeepEqual(got, tt.want) {
- t.Errorf("NewCacheConfigMetadata() = %v, want %v", got, tt.want)
+ t.Errorf("NewMetadata() = %v, want %v", got, tt.want)
}
})
}
diff --git a/internal/config/gradle/activate_for_gradle_params.go b/internal/config/gradle/activate_for_gradle_params.go
new file mode 100644
index 00000000..d1b488f2
--- /dev/null
+++ b/internal/config/gradle/activate_for_gradle_params.go
@@ -0,0 +1,248 @@
+package gradleconfig
+
+import (
+ "errors"
+ "fmt"
+ "os/exec"
+
+ "github.com/bitrise-io/bitrise-build-cache-cli/internal/config/common"
+ "github.com/bitrise-io/bitrise-build-cache-cli/internal/consts"
+ "github.com/bitrise-io/go-utils/v2/log"
+)
+
+const (
+ errFmtInvalidCacheLevel = "invalid cache validation level, valid options: none, warning, error"
+ errFmtTestDistroAppSlug = "test distribution plugin was enabled but no BITRISE_APP_SLUG was specified"
+ ErrFmtReadAutConfig = "read auth config from environment variables: %w"
+ errFmtCacheConfigCreation = "couldn't create cache configuration: %w"
+ errFmtTestDistroConfigCreation = "couldn't create test distribution configuration: %w"
+ errFmtInvalidValidationLevel = "invalid validation level: '%s'"
+)
+
+type CacheParams struct {
+ Enabled bool
+ JustDependency bool
+ PushEnabled bool
+ ValidationLevel string
+ Endpoint string
+}
+
+type AnalyticsParams struct {
+ Enabled bool
+ JustDependency bool
+}
+
+type TestDistroParams struct {
+ Enabled bool
+ JustDependency bool
+}
+
+type ActivateForGradleParams struct {
+ Cache CacheParams
+ Analytics AnalyticsParams
+ TestDistro TestDistroParams
+}
+
+func DefaultActivateForGradleParams() ActivateForGradleParams {
+ return ActivateForGradleParams{
+ Cache: CacheParams{
+ Enabled: false,
+ JustDependency: false,
+ PushEnabled: false,
+ ValidationLevel: string(CacheValidationLevelWarning),
+ },
+ Analytics: AnalyticsParams{
+ Enabled: true,
+ JustDependency: false,
+ },
+ TestDistro: TestDistroParams{
+ Enabled: false,
+ JustDependency: false,
+ },
+ }
+}
+
+func (params ActivateForGradleParams) TemplateInventory(
+ logger log.Logger,
+ envProvider func(string) string,
+ isDebug bool,
+) (TemplateInventory, error) {
+ logger.Infof("(i) Checking parameters")
+
+ commonInventory, err := params.commonTemplateInventory(logger, envProvider, isDebug)
+ if err != nil {
+ return TemplateInventory{}, err
+ }
+
+ cacheInventory, err := params.cacheTemplateInventory(logger, envProvider)
+ if err != nil {
+ return TemplateInventory{}, fmt.Errorf(errFmtCacheConfigCreation, err)
+ }
+
+ analyticsInventory := params.analyticsTemplateInventory(logger)
+
+ testDistroInventory, err := params.testDistroTemplateInventory(logger, envProvider, isDebug)
+ if err != nil {
+ return TemplateInventory{}, fmt.Errorf(errFmtTestDistroConfigCreation, err)
+ }
+
+ return TemplateInventory{
+ Common: commonInventory,
+ Cache: cacheInventory,
+ Analytics: analyticsInventory,
+ TestDistro: testDistroInventory,
+ }, nil
+}
+
+func (params ActivateForGradleParams) commonTemplateInventory(
+ logger log.Logger,
+ envProvider func(string) string,
+ isDebug bool,
+) (PluginCommonTemplateInventory, error) {
+ logger.Infof("(i) Debug mode and verbose logs: %t", isDebug)
+
+ // Required configs
+ logger.Infof("(i) Check Auth Config")
+ authConfig, err := common.ReadAuthConfigFromEnvironments(envProvider)
+ if err != nil {
+ return PluginCommonTemplateInventory{},
+ fmt.Errorf(ErrFmtReadAutConfig, err)
+ }
+ authToken := authConfig.TokenInGradleFormat()
+
+ cacheConfig := common.NewMetadata(envProvider,
+ func(name string, v ...string) (string, error) {
+ output, err := exec.Command(name, v...).Output()
+
+ return string(output), err
+ },
+ logger)
+ logger.Infof("(i) Cache Config: %+v", cacheConfig)
+
+ return PluginCommonTemplateInventory{
+ AuthToken: authToken,
+ Debug: isDebug,
+ AppSlug: cacheConfig.BitriseAppID,
+ CIProvider: cacheConfig.CIProvider,
+ }, nil
+}
+
+func (params ActivateForGradleParams) cacheTemplateInventory(
+ logger log.Logger,
+ envProvider func(string) string,
+) (CacheTemplateInventory, error) {
+ if !params.Cache.JustDependency && !params.Cache.Enabled {
+ logger.Infof("(i) Cache plugin usage: %+v", UsageLevelNone)
+
+ return CacheTemplateInventory{
+ Usage: UsageLevelNone,
+ }, nil
+ }
+
+ if params.Cache.JustDependency && !params.Cache.Enabled {
+ logger.Infof("(i) Cache plugin usage: %+v", UsageLevelDependency)
+
+ return CacheTemplateInventory{
+ Usage: UsageLevelDependency,
+ Version: consts.GradleRemoteBuildCachePluginDepVersion,
+ }, nil
+ }
+
+ logger.Infof("(i) Cache plugin usage: %+v", UsageLevelEnabled)
+
+ cacheEndpointURL := common.SelectCacheEndpointURL(params.Cache.Endpoint, envProvider)
+ logger.Infof("(i) Build Cache Endpoint URL: %s", cacheEndpointURL)
+ logger.Infof("(i) Push new cache entries: %t", params.Cache.PushEnabled)
+ logger.Infof("(i) Cache entry validation level: %s", params.Cache.ValidationLevel)
+
+ if params.Cache.ValidationLevel != string(CacheValidationLevelNone) &&
+ params.Cache.ValidationLevel != string(CacheValidationLevelWarning) &&
+ params.Cache.ValidationLevel != string(CacheValidationLevelError) {
+ logger.Errorf(errFmtInvalidValidationLevel, params.Cache.ValidationLevel)
+
+ return CacheTemplateInventory{}, errors.New(errFmtInvalidCacheLevel)
+ }
+
+ return CacheTemplateInventory{
+ Usage: UsageLevelEnabled,
+ Version: consts.GradleRemoteBuildCachePluginDepVersion,
+ EndpointURLWithPort: cacheEndpointURL,
+ IsPushEnabled: params.Cache.PushEnabled,
+ ValidationLevel: params.Cache.ValidationLevel,
+ }, nil
+}
+
+func (params ActivateForGradleParams) analyticsTemplateInventory(
+ logger log.Logger,
+) AnalyticsTemplateInventory {
+ if !params.Analytics.JustDependency && !params.Analytics.Enabled {
+ logger.Infof("(i) Analytics plugin usage: %+v", UsageLevelNone)
+
+ return AnalyticsTemplateInventory{
+ Usage: UsageLevelNone,
+ }
+ }
+
+ if params.Analytics.JustDependency && !params.Analytics.Enabled {
+ logger.Infof("(i) Analytics plugin usage: %+v", UsageLevelDependency)
+
+ return AnalyticsTemplateInventory{
+ Usage: UsageLevelDependency,
+ Version: consts.GradleAnalyticsPluginDepVersion,
+ }
+ }
+
+ logger.Infof("(i) Analytics plugin usage: %+v", UsageLevelEnabled)
+
+ return AnalyticsTemplateInventory{
+ Usage: UsageLevelEnabled,
+ Version: consts.GradleAnalyticsPluginDepVersion,
+ Endpoint: consts.GradleAnalyticsEndpoint,
+ Port: consts.GradleAnalyticsPort,
+ HTTPEndpoint: consts.GradleAnalyticsHTTPEndpoint,
+ }
+}
+
+func (params ActivateForGradleParams) testDistroTemplateInventory(
+ logger log.Logger,
+ envProvider func(string) string,
+ isDebug bool,
+) (TestDistroTemplateInventory, error) {
+ if !params.TestDistro.JustDependency && !params.TestDistro.Enabled {
+ logger.Infof("(i) Test distribution plugin usage: %+v", UsageLevelNone)
+
+ return TestDistroTemplateInventory{
+ Usage: UsageLevelNone,
+ }, nil
+ }
+
+ if params.TestDistro.JustDependency && !params.TestDistro.Enabled {
+ logger.Infof("(i) Test distribution plugin usage: %+v", UsageLevelDependency)
+
+ return TestDistroTemplateInventory{
+ Usage: UsageLevelDependency,
+ Version: consts.GradleTestDistributionPluginDepVersion,
+ }, nil
+ }
+
+ logger.Infof("(i) Test distribution plugin usage: %+v", UsageLevelEnabled)
+
+ appSlug := envProvider("BITRISE_APP_SLUG")
+ if len(appSlug) < 1 {
+ return TestDistroTemplateInventory{}, errors.New(errFmtTestDistroAppSlug)
+ }
+
+ logLevel := "warning"
+ if isDebug {
+ logLevel = "debug"
+ }
+
+ return TestDistroTemplateInventory{
+ Usage: UsageLevelEnabled,
+ Version: consts.GradleTestDistributionPluginDepVersion,
+ Endpoint: consts.GradleTestDistributionEndpoint,
+ KvEndpoint: consts.GradleTestDistributionKvEndpoint,
+ Port: consts.GradleTestDistributionPort,
+ LogLevel: logLevel,
+ }, nil
+}
diff --git a/internal/config/gradle/activate_for_gradle_params_test.go b/internal/config/gradle/activate_for_gradle_params_test.go
new file mode 100644
index 00000000..7e3da02f
--- /dev/null
+++ b/internal/config/gradle/activate_for_gradle_params_test.go
@@ -0,0 +1,345 @@
+//nolint:maintidx
+package gradleconfig
+
+import (
+ "errors"
+ "fmt"
+ "testing"
+
+ "github.com/bitrise-io/bitrise-build-cache-cli/internal/config/common"
+ "github.com/bitrise-io/bitrise-build-cache-cli/internal/consts"
+ "github.com/bitrise-io/go-utils/v2/log"
+ "github.com/bitrise-io/go-utils/v2/mocks"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/mock"
+ "github.com/stretchr/testify/require"
+)
+
+func Test_activateForGradleParams(t *testing.T) {
+ prep := func() log.Logger {
+ mockLogger := &mocks.Logger{}
+ mockLogger.On("Infof", mock.Anything).Return()
+ mockLogger.On("Infof", mock.Anything, mock.Anything).Return()
+ mockLogger.On("Debugf", mock.Anything).Return()
+ mockLogger.On("Debugf", mock.Anything, mock.Anything).Return()
+ mockLogger.On("Errorf", mock.Anything).Return()
+ mockLogger.On("Errorf", mock.Anything, mock.Anything).Return()
+
+ return mockLogger
+ }
+
+ tests := []struct {
+ name string
+ debug bool
+ params ActivateForGradleParams
+ envVars map[string]string
+ want TemplateInventory
+ wantErr string
+ }{
+ {
+ name: "no auth token",
+ params: ActivateForGradleParams{
+ Cache: CacheParams{Enabled: false},
+ Analytics: AnalyticsParams{Enabled: false},
+ TestDistro: TestDistroParams{Enabled: false},
+ },
+ envVars: map[string]string{},
+ wantErr: fmt.Errorf(ErrFmtReadAutConfig, common.ErrAuthTokenNotProvided).Error(),
+ },
+ {
+ name: "no workspaceID",
+ params: ActivateForGradleParams{
+ Cache: CacheParams{Enabled: false},
+ Analytics: AnalyticsParams{Enabled: false},
+ TestDistro: TestDistroParams{Enabled: false},
+ },
+ envVars: map[string]string{
+ "BITRISE_BUILD_CACHE_AUTH_TOKEN": "AuthTokenValue",
+ },
+ wantErr: fmt.Errorf(ErrFmtReadAutConfig, common.ErrWorkspaceIDNotProvided).Error(),
+ },
+ {
+ name: "no plugins",
+ params: ActivateForGradleParams{
+ Cache: CacheParams{Enabled: false},
+ Analytics: AnalyticsParams{Enabled: false},
+ TestDistro: TestDistroParams{Enabled: false},
+ },
+ envVars: map[string]string{
+ "BITRISE_BUILD_CACHE_AUTH_TOKEN": "AuthTokenValue",
+ "BITRISE_BUILD_CACHE_WORKSPACE_ID": "WorkspaceIDValue",
+ },
+ want: TemplateInventory{
+ Common: PluginCommonTemplateInventory{
+ AuthToken: "WorkspaceIDValue:AuthTokenValue",
+ },
+ Cache: CacheTemplateInventory{
+ Usage: UsageLevelNone,
+ },
+ Analytics: AnalyticsTemplateInventory{
+ Usage: UsageLevelNone,
+ },
+ TestDistro: TestDistroTemplateInventory{
+ Usage: UsageLevelNone,
+ },
+ },
+ },
+ {
+ name: "dependency only plugins",
+ params: ActivateForGradleParams{
+ Cache: CacheParams{
+ Enabled: false,
+ JustDependency: true,
+ },
+ Analytics: AnalyticsParams{
+ Enabled: false,
+ JustDependency: true,
+ },
+ TestDistro: TestDistroParams{
+ Enabled: false,
+ JustDependency: true,
+ },
+ },
+ envVars: map[string]string{
+ "BITRISE_BUILD_CACHE_AUTH_TOKEN": "AuthTokenValue",
+ "BITRISE_BUILD_CACHE_WORKSPACE_ID": "WorkspaceIDValue",
+ },
+ want: TemplateInventory{
+ Common: PluginCommonTemplateInventory{
+ AuthToken: "WorkspaceIDValue:AuthTokenValue",
+ },
+ Cache: CacheTemplateInventory{
+ Usage: UsageLevelDependency,
+ Version: consts.GradleRemoteBuildCachePluginDepVersion,
+ },
+ Analytics: AnalyticsTemplateInventory{
+ Usage: UsageLevelDependency,
+ Version: consts.GradleAnalyticsPluginDepVersion,
+ },
+ TestDistro: TestDistroTemplateInventory{
+ Usage: UsageLevelDependency,
+ Version: consts.GradleTestDistributionPluginDepVersion,
+ },
+ },
+ },
+ {
+ name: "activate cache",
+ params: ActivateForGradleParams{
+ Cache: CacheParams{
+ Enabled: true,
+ JustDependency: true, // gets overridden by enable
+ ValidationLevel: string(CacheValidationLevelError),
+ Endpoint: "EndpointValue",
+ PushEnabled: true,
+ },
+ Analytics: AnalyticsParams{
+ Enabled: false,
+ },
+ TestDistro: TestDistroParams{
+ Enabled: false,
+ },
+ },
+ envVars: map[string]string{
+ "BITRISE_BUILD_CACHE_AUTH_TOKEN": "AuthTokenValue",
+ "BITRISE_BUILD_CACHE_WORKSPACE_ID": "WorkspaceIDValue",
+ },
+ want: TemplateInventory{
+ Common: PluginCommonTemplateInventory{
+ AuthToken: "WorkspaceIDValue:AuthTokenValue",
+ },
+ Cache: CacheTemplateInventory{
+ Usage: UsageLevelEnabled,
+ Version: consts.GradleRemoteBuildCachePluginDepVersion,
+ EndpointURLWithPort: "EndpointValue",
+ IsPushEnabled: true,
+ ValidationLevel: string(CacheValidationLevelError),
+ },
+ Analytics: AnalyticsTemplateInventory{
+ Usage: UsageLevelNone,
+ },
+ TestDistro: TestDistroTemplateInventory{
+ Usage: UsageLevelNone,
+ },
+ },
+ },
+ {
+ name: "given invalid cache validation level cache activation throws error",
+ params: ActivateForGradleParams{
+ Cache: CacheParams{
+ Enabled: true,
+ ValidationLevel: "InvalidLevel",
+ Endpoint: "EndpointValue",
+ PushEnabled: true,
+ },
+ Analytics: AnalyticsParams{
+ Enabled: false,
+ },
+ TestDistro: TestDistroParams{
+ Enabled: false,
+ },
+ },
+ envVars: map[string]string{
+ "BITRISE_BUILD_CACHE_AUTH_TOKEN": "AuthTokenValue",
+ "BITRISE_BUILD_CACHE_WORKSPACE_ID": "WorkspaceIDValue",
+ },
+ wantErr: fmt.Errorf(errFmtCacheConfigCreation, errors.New(errFmtInvalidCacheLevel)).Error(),
+ },
+ {
+ name: "activate analytics",
+ params: ActivateForGradleParams{
+ Cache: CacheParams{
+ Enabled: false,
+ },
+ Analytics: AnalyticsParams{
+ Enabled: true,
+ JustDependency: true, // gets overridden by enable
+ },
+ TestDistro: TestDistroParams{
+ Enabled: false,
+ },
+ },
+ envVars: map[string]string{
+ "BITRISE_BUILD_CACHE_AUTH_TOKEN": "AuthTokenValue",
+ "BITRISE_BUILD_CACHE_WORKSPACE_ID": "WorkspaceIDValue",
+ },
+ want: TemplateInventory{
+ Common: PluginCommonTemplateInventory{
+ AuthToken: "WorkspaceIDValue:AuthTokenValue",
+ },
+ Cache: CacheTemplateInventory{
+ Usage: UsageLevelNone,
+ },
+ Analytics: AnalyticsTemplateInventory{
+ Usage: UsageLevelEnabled,
+ Version: consts.GradleAnalyticsPluginDepVersion,
+ Endpoint: consts.GradleAnalyticsEndpoint,
+ Port: consts.GradleAnalyticsPort,
+ HTTPEndpoint: consts.GradleAnalyticsHTTPEndpoint,
+ },
+ TestDistro: TestDistroTemplateInventory{
+ Usage: UsageLevelNone,
+ },
+ },
+ },
+ {
+ name: "activate test distro",
+ params: ActivateForGradleParams{
+ Cache: CacheParams{
+ Enabled: false,
+ },
+ Analytics: AnalyticsParams{
+ Enabled: false,
+ },
+ TestDistro: TestDistroParams{
+ Enabled: true,
+ JustDependency: true, // gets overridden by enable
+ },
+ },
+ envVars: map[string]string{
+ "BITRISE_BUILD_CACHE_AUTH_TOKEN": "AuthTokenValue",
+ "BITRISE_BUILD_CACHE_WORKSPACE_ID": "WorkspaceIDValue",
+ "BITRISE_IO": "true",
+ "BITRISE_APP_SLUG": "AppSlugValue",
+ },
+ want: TemplateInventory{
+ Common: PluginCommonTemplateInventory{
+ AuthToken: "WorkspaceIDValue:AuthTokenValue",
+ AppSlug: "AppSlugValue",
+ CIProvider: "bitrise",
+ },
+ Cache: CacheTemplateInventory{
+ Usage: UsageLevelNone,
+ },
+ Analytics: AnalyticsTemplateInventory{
+ Usage: UsageLevelNone,
+ },
+ TestDistro: TestDistroTemplateInventory{
+ Usage: UsageLevelEnabled,
+ Version: consts.GradleTestDistributionPluginDepVersion,
+ Endpoint: consts.GradleTestDistributionEndpoint,
+ KvEndpoint: consts.GradleTestDistributionKvEndpoint,
+ Port: consts.GradleTestDistributionPort,
+ LogLevel: "warning",
+ },
+ },
+ },
+ {
+ name: "activating test distro while missing app slug throws error",
+ params: ActivateForGradleParams{
+ Cache: CacheParams{
+ Enabled: false,
+ },
+ Analytics: AnalyticsParams{
+ Enabled: false,
+ },
+ TestDistro: TestDistroParams{
+ Enabled: true,
+ JustDependency: true, // gets overridden by enable
+ },
+ },
+ envVars: map[string]string{
+ "BITRISE_BUILD_CACHE_AUTH_TOKEN": "AuthTokenValue",
+ "BITRISE_BUILD_CACHE_WORKSPACE_ID": "WorkspaceIDValue",
+ "BITRISE_IO": "true",
+ },
+ wantErr: fmt.Errorf(errFmtTestDistroConfigCreation, errors.New(errFmtTestDistroAppSlug)).Error(),
+ },
+ {
+ name: "activate plugins with debug mode",
+ debug: true,
+ params: ActivateForGradleParams{
+ Cache: CacheParams{
+ Enabled: false,
+ },
+ Analytics: AnalyticsParams{
+ Enabled: false,
+ },
+ TestDistro: TestDistroParams{
+ Enabled: true,
+ JustDependency: true, // gets overridden by enable
+ },
+ },
+ envVars: map[string]string{
+ "BITRISE_BUILD_CACHE_AUTH_TOKEN": "AuthTokenValue",
+ "BITRISE_BUILD_CACHE_WORKSPACE_ID": "WorkspaceIDValue",
+ "BITRISE_IO": "true",
+ "BITRISE_APP_SLUG": "AppSlugValue",
+ },
+ want: TemplateInventory{
+ Common: PluginCommonTemplateInventory{
+ AuthToken: "WorkspaceIDValue:AuthTokenValue",
+ Debug: true,
+ AppSlug: "AppSlugValue",
+ CIProvider: "bitrise",
+ },
+ Cache: CacheTemplateInventory{
+ Usage: UsageLevelNone,
+ },
+ Analytics: AnalyticsTemplateInventory{
+ Usage: UsageLevelNone,
+ },
+ TestDistro: TestDistroTemplateInventory{
+ Usage: UsageLevelEnabled,
+ Version: consts.GradleTestDistributionPluginDepVersion,
+ Endpoint: consts.GradleTestDistributionEndpoint,
+ KvEndpoint: consts.GradleTestDistributionKvEndpoint,
+ Port: consts.GradleTestDistributionPort,
+ LogLevel: "debug",
+ },
+ },
+ },
+ }
+ for _, tt := range tests { //nolint:varnamelen
+ t.Run(tt.name, func(t *testing.T) {
+ mockLogger := prep()
+ envProvider := func(key string) string { return tt.envVars[key] }
+ got, err := tt.params.TemplateInventory(mockLogger, envProvider, tt.debug)
+ if tt.wantErr != "" {
+ require.EqualError(t, err, tt.wantErr)
+ } else {
+ require.NoError(t, err)
+ }
+ assert.Equal(t, tt.want, got)
+ })
+ }
+}
diff --git a/internal/config/gradle/cache_validation_level.go b/internal/config/gradle/cache_validation_level.go
new file mode 100644
index 00000000..8203475f
--- /dev/null
+++ b/internal/config/gradle/cache_validation_level.go
@@ -0,0 +1,10 @@
+package gradleconfig
+
+type CacheValidationLevel string
+
+//nolint:gochecknoglobals
+var (
+ CacheValidationLevelNone CacheValidationLevel = "none"
+ CacheValidationLevelWarning CacheValidationLevel = "warning"
+ CacheValidationLevelError CacheValidationLevel = "error"
+)
diff --git a/internal/config/gradle/gradle_init_template_inventory.go b/internal/config/gradle/gradle_init_template_inventory.go
new file mode 100644
index 00000000..5a4cb4f7
--- /dev/null
+++ b/internal/config/gradle/gradle_init_template_inventory.go
@@ -0,0 +1,63 @@
+package gradleconfig
+
+type UsageLevel string
+
+//nolint:gochecknoglobals
+var (
+ UsageLevelNone UsageLevel = "none"
+ UsageLevelDependency UsageLevel = "dependency"
+ UsageLevelEnabled UsageLevel = "enabled"
+)
+
+type CacheTemplateInventory struct {
+ Usage UsageLevel
+ Version string
+ EndpointURLWithPort string
+ IsPushEnabled bool
+ ValidationLevel string
+}
+
+type AnalyticsTemplateInventory struct {
+ Usage UsageLevel
+ Version string
+ Endpoint string
+ Port int
+ HTTPEndpoint string
+}
+
+type TestDistroTemplateInventory struct {
+ Usage UsageLevel
+ Version string
+ Endpoint string
+ KvEndpoint string
+ Port int
+ LogLevel string
+}
+
+type PluginCommonTemplateInventory struct {
+ AuthToken string
+ Debug bool
+ AppSlug string
+ CIProvider string
+}
+
+type TemplateInventory struct {
+ Common PluginCommonTemplateInventory
+ Cache CacheTemplateInventory
+ Analytics AnalyticsTemplateInventory
+ TestDistro TestDistroTemplateInventory
+}
+
+func (inventory TemplateInventory) HasDependencies() bool {
+ if inventory.Analytics.Usage == UsageLevelDependency || inventory.Analytics.Usage == UsageLevelEnabled {
+ return true
+ }
+ if inventory.Cache.Usage == UsageLevelDependency || inventory.Cache.Usage == UsageLevelEnabled {
+ return true
+ }
+ if inventory.TestDistro.Usage == UsageLevelDependency || inventory.TestDistro.Usage == UsageLevelEnabled {
+ return true
+ }
+
+ return false
+}
diff --git a/internal/config/gradle/gradle_properties_from_params.go b/internal/config/gradle/gradle_properties_from_params.go
new file mode 100644
index 00000000..d29093b9
--- /dev/null
+++ b/internal/config/gradle/gradle_properties_from_params.go
@@ -0,0 +1,58 @@
+package gradleconfig
+
+import (
+ "fmt"
+ "path/filepath"
+
+ "github.com/bitrise-io/bitrise-build-cache-cli/internal/stringmerge"
+ "github.com/bitrise-io/go-utils/v2/log"
+)
+
+const (
+ ErrFmtGradlePropertiesCheck = "check if gradle.properties exists at %s, error: %w"
+ ErrFmtGradlePropertyWrite = "write gradle.properties to %s, error: %w"
+)
+
+type GradlePropertiesUpdater struct {
+ OsProxy OsProxy
+}
+
+func DefaultGradlePropertiesUpdater() GradlePropertiesUpdater {
+ return GradlePropertiesUpdater{
+ OsProxy: DefaultOsProxy(),
+ }
+}
+
+func (updater GradlePropertiesUpdater) UpdateGradleProps(
+ params ActivateForGradleParams,
+ logger log.Logger,
+ gradleHomePath string,
+) error {
+ logger.Infof("(i) Write ~/.gradle/gradle.properties")
+
+ gradlePropertiesPath := filepath.Join(gradleHomePath, "gradle.properties")
+ currentGradlePropsFileContent, isGradlePropsExists, err := updater.OsProxy.ReadFileIfExists(gradlePropertiesPath)
+ if err != nil {
+ return fmt.Errorf(ErrFmtGradlePropertiesCheck, gradlePropertiesPath, err)
+ }
+ logger.Debugf("isGradlePropsExists: %t", isGradlePropsExists)
+
+ cachingLine := "org.gradle.caching=true"
+ if !params.Cache.Enabled {
+ cachingLine = "org.gradle.caching=false"
+ }
+
+ gradlePropertiesContent := stringmerge.ChangeContentInBlock(
+ currentGradlePropsFileContent,
+ "# [start] generated-by-bitrise-build-cache",
+ "# [end] generated-by-bitrise-build-cache",
+ cachingLine,
+ )
+
+ err = updater.OsProxy.WriteFile(gradlePropertiesPath, []byte(gradlePropertiesContent), 0755) //nolint:gosec,gomnd,mnd
+ if err != nil {
+ return fmt.Errorf(ErrFmtGradlePropertyWrite, gradlePropertiesPath, err)
+ }
+
+ return nil
+}
diff --git a/internal/config/gradle/gradle_properties_from_params_test.go b/internal/config/gradle/gradle_properties_from_params_test.go
new file mode 100644
index 00000000..b411d07d
--- /dev/null
+++ b/internal/config/gradle/gradle_properties_from_params_test.go
@@ -0,0 +1,134 @@
+package gradleconfig
+
+import (
+ "fmt"
+ "os"
+ "path/filepath"
+ "testing"
+
+ "github.com/bitrise-io/go-utils/v2/log"
+ "github.com/bitrise-io/go-utils/v2/mocks"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/mock"
+ "github.com/stretchr/testify/require"
+)
+
+func Test_gradlePropertiesFromParams(t *testing.T) {
+ prep := func() (log.Logger, string, string) {
+ mockLogger := &mocks.Logger{}
+ mockLogger.On("Infof", mock.Anything).Return()
+ mockLogger.On("Infof", mock.Anything, mock.Anything).Return()
+ mockLogger.On("Debugf", mock.Anything).Return()
+ mockLogger.On("Debugf", mock.Anything, mock.Anything).Return()
+ mockLogger.On("Errorf", mock.Anything).Return()
+ mockLogger.On("Errorf", mock.Anything, mock.Anything).Return()
+
+ tmpPath := t.TempDir()
+ tmpGradleHomeDir := filepath.Join(tmpPath, ".gradle")
+ _ = os.MkdirAll(tmpGradleHomeDir, 0755)
+
+ propertyFilePath := filepath.Join(tmpGradleHomeDir, "gradle.properties")
+
+ return mockLogger, tmpGradleHomeDir, propertyFilePath
+ }
+
+ t.Run("Update gradle properties", func(t *testing.T) {
+ updater := GradlePropertiesUpdater{DefaultOsProxy()}
+
+ mockLogger, tmpGradleHomeDir, propertyFilePath := prep()
+
+ // when
+ err := updater.UpdateGradleProps(
+ ActivateForGradleParams{
+ Cache: CacheParams{
+ Enabled: true,
+ },
+ },
+ mockLogger,
+ tmpGradleHomeDir,
+ )
+
+ // then
+ require.NoError(t, err)
+ //
+ data, err := os.ReadFile(propertyFilePath)
+ require.NoError(t, err)
+ content := string(data)
+ assert.Contains(t, content, "org.gradle.caching=true")
+ })
+
+ t.Run("Update gradle properties when caching is disabled", func(t *testing.T) {
+ updater := GradlePropertiesUpdater{DefaultOsProxy()}
+
+ mockLogger, tmpGradleHomeDir, propertyFilePath := prep()
+
+ // when
+ err := updater.UpdateGradleProps(
+ ActivateForGradleParams{
+ Cache: CacheParams{
+ Enabled: false,
+ },
+ },
+ mockLogger,
+ tmpGradleHomeDir,
+ )
+
+ // then
+ require.NoError(t, err)
+ //
+ data, err := os.ReadFile(propertyFilePath)
+ require.NoError(t, err)
+ content := string(data)
+ assert.Contains(t, content, "org.gradle.caching=false")
+ })
+
+ t.Run("When gradle properties file is missing throws error", func(t *testing.T) {
+ noFileError := fmt.Errorf("there is no gradle properties file")
+ osProxy := DefaultOsProxy()
+ osProxy.ReadFileIfExists = func(string) (string, bool, error) {
+ return "", false, noFileError
+ }
+ updater := GradlePropertiesUpdater{osProxy}
+
+ mockLogger, tmpGradleHomeDir, propertyFilePath := prep()
+
+ // when
+ err := updater.UpdateGradleProps(
+ ActivateForGradleParams{
+ Cache: CacheParams{
+ Enabled: true,
+ },
+ },
+ mockLogger,
+ tmpGradleHomeDir,
+ )
+
+ // then
+ require.EqualError(t, err, fmt.Errorf(ErrFmtGradlePropertiesCheck, propertyFilePath, noFileError).Error())
+ })
+
+ t.Run("When failing to update gradle.properties throws error", func(t *testing.T) {
+ failedToWriteError := fmt.Errorf("couldn't write gradle properties file")
+ osProxy := DefaultOsProxy()
+ osProxy.WriteFile = func(string, []byte, os.FileMode) error {
+ return failedToWriteError
+ }
+ updater := GradlePropertiesUpdater{osProxy}
+
+ mockLogger, tmpGradleHomeDir, propertyFilePath := prep()
+
+ // when
+ err := updater.UpdateGradleProps(
+ ActivateForGradleParams{
+ Cache: CacheParams{
+ Enabled: true,
+ },
+ },
+ mockLogger,
+ tmpGradleHomeDir,
+ )
+
+ // then
+ require.EqualError(t, err, fmt.Errorf(ErrFmtGradlePropertyWrite, propertyFilePath, failedToWriteError).Error())
+ })
+}
diff --git a/internal/config/gradle/gradleconfig.go b/internal/config/gradle/gradleconfig.go
index 7ba38183..0ab4472b 100644
--- a/internal/config/gradle/gradleconfig.go
+++ b/internal/config/gradle/gradleconfig.go
@@ -3,95 +3,122 @@ package gradleconfig
import (
"bytes"
_ "embed"
- "errors"
"fmt"
+ "os"
+ "path/filepath"
"text/template"
- "github.com/bitrise-io/bitrise-build-cache-cli/internal/config/common"
- "github.com/bitrise-io/bitrise-build-cache-cli/internal/consts"
+ "github.com/bitrise-io/go-utils/v2/log"
+ "github.com/bitrise-io/go-utils/v2/pathutil"
)
//go:embed initd.gradle.kts.gotemplate
var gradleTemplateText string
+//nolint:gochecknoglobals
var (
- errAuthTokenNotProvided = errors.New("AuthToken not provided")
- errEndpointURLNotProvided = errors.New("EndpointURL not provided")
+ errFmtInvalidTemplate = "generate init.gradle: invalid template: %w"
+ errFmtGradleGeneration = "couldn't generate gradle init content: %w"
+ errFmtEnsureGradleInitDirExists = "ensure ~/.gradle/init.d exists: %w"
+ errFmtWritingGradleInitFile = "write bitrise-build-cache.init.gradle.kts to %s, error: %w"
)
-type CacheValidationLevel string
+// Generate init.gradle content.
+// Recommended to save the content into $HOME/.gradle/init.d/ instead of
+// overwriting the $HOME/.gradle/init.gradle file.
+func (inventory TemplateInventory) GenerateInitGradle(templateProxy TemplateProxy) (string, error) {
+ tmpl, err := templateProxy.parse("init.gradle", gradleTemplateText)
+ if err != nil {
+ return "", fmt.Errorf(errFmtInvalidTemplate, err)
+ }
-//nolint:gochecknoglobals
-var (
- CacheValidationLevelNone CacheValidationLevel = "none"
- CacheValidationLevelWarning CacheValidationLevel = "warning"
- CacheValidationLevelError CacheValidationLevel = "error"
-)
+ resultBuffer := bytes.Buffer{}
+ if err = templateProxy.execute(tmpl, &resultBuffer, inventory); err != nil {
+ return "", err
+ }
-type Preferences struct {
- IsDependencyOnly bool
- IsPushEnabled bool
- CacheLevelValidation CacheValidationLevel
- IsAnalyticsEnabled bool
- IsDebugEnabled bool
+ return resultBuffer.String(), nil
}
-type templateInventory struct {
- IsDependencyOnly bool
- AuthToken string
- CacheEndpointURLWithPort string
- CachePluginVersion string
- IsPushEnabled bool
- IsDebugEnabled bool
- ValidationLevel string
- IsAnalyticsEnabled bool
- AnalyticsPluginVersion string
- AnalyticsEndpoint string
- AnalyticsPort int
- AnalyticsHTTPEndpoint string
- // Metadata
- CacheConfigMetadata common.CacheConfigMetadata
-}
+func (inventory TemplateInventory) WriteToGradleInit(
+ logger log.Logger,
+ gradleHomePath string,
+ osProxy OsProxy,
+ templateProxy TemplateProxy,
+) error {
+ logger.Infof("(i) Ensure ~/.gradle and ~/.gradle/init.d directories exist")
+ gradleInitDPath := filepath.Join(gradleHomePath, "init.d")
+ err := osProxy.MkdirAll(gradleInitDPath, 0755) //nolint:gomnd,mnd
+ if err != nil {
+ return fmt.Errorf(errFmtEnsureGradleInitDirExists, err)
+ }
-// Generate init.gradle content.
-// Recommended to save the content into $HOME/.gradle/init.d/ instead of
-// overwriting the $HOME/.gradle/init.gradle file.
-func GenerateInitGradle(endpointURL, authToken string, preferences Preferences, cacheConfigMetadata common.CacheConfigMetadata) (string, error) {
- // required check
- if len(authToken) < 1 {
- return "", fmt.Errorf("generate init.gradle, error: %w", errAuthTokenNotProvided)
+ logger.Infof("(i) Generate ~/.gradle/init.d/bitrise-build-cache.init.gradle.kts")
+ initGradleContent, err := inventory.GenerateInitGradle(templateProxy)
+ if err != nil {
+ return fmt.Errorf(errFmtGradleGeneration, err)
+ }
+
+ logger.Infof("(i) Write ~/.gradle/init.d/bitrise-build-cache.init.gradle.kts")
+ {
+ initGradlePath := filepath.Join(gradleInitDPath, "bitrise-build-cache.init.gradle.kts")
+ err = osProxy.WriteFile(initGradlePath, []byte(initGradleContent), 0755) //nolint:gosec,gomnd,mnd
+ if err != nil {
+ return fmt.Errorf(errFmtWritingGradleInitFile, initGradlePath, err)
+ }
}
- if len(endpointURL) < 1 {
- return "", fmt.Errorf("generate init.gradle, error: %w", errEndpointURLNotProvided)
+ return nil
+}
+
+type TemplateProxy struct {
+ parse func(name string, templateText string) (*template.Template, error)
+ execute func(*template.Template, *bytes.Buffer, TemplateInventory) error
+}
+
+func DefaultTemplateProxy() TemplateProxy {
+ return TemplateProxy{
+ parse: func(name string, templateText string) (*template.Template, error) {
+ funcMap := template.FuncMap{
+ "hasDependencies": TemplateInventory.HasDependencies,
+ }
+
+ return template.New(name).Funcs(funcMap).Parse(templateText)
+ },
+ execute: func(template *template.Template, buffer *bytes.Buffer, inventory TemplateInventory) error {
+ return template.Execute(buffer, inventory)
+ },
}
+}
+
+type OsProxy struct {
+ ReadFileIfExists func(pth string) (string, bool, error)
+ MkdirAll func(string, os.FileMode) error
+ WriteFile func(string, []byte, os.FileMode) error
+}
- // create inventory
- inventory := templateInventory{
- IsDependencyOnly: preferences.IsDependencyOnly,
- AuthToken: authToken,
- CacheEndpointURLWithPort: endpointURL,
- CachePluginVersion: consts.GradleRemoteBuildCachePluginDepVersion,
- IsPushEnabled: preferences.IsPushEnabled,
- IsDebugEnabled: preferences.IsDebugEnabled,
- ValidationLevel: string(preferences.CacheLevelValidation),
- IsAnalyticsEnabled: preferences.IsAnalyticsEnabled,
- AnalyticsPluginVersion: consts.GradleAnalyticsPluginDepVersion,
- AnalyticsEndpoint: consts.GradleAnalyticsEndpoint,
- AnalyticsPort: consts.GradleAnalyticsPort,
- AnalyticsHTTPEndpoint: consts.GradleAnalyticsHTTPEndpoint,
- CacheConfigMetadata: cacheConfigMetadata,
+func DefaultOsProxy() OsProxy {
+ return OsProxy{
+ ReadFileIfExists: readFileIfExists,
+ MkdirAll: os.MkdirAll,
+ WriteFile: os.WriteFile,
}
+}
- tmpl, err := template.New("init.gradle").Parse(gradleTemplateText)
+func readFileIfExists(pth string) (string, bool, error) {
+ fileContent := ""
+ isFileExist, err := pathutil.NewPathChecker().IsPathExists(pth)
if err != nil {
- return "", fmt.Errorf("generate init.gradle: invalid template: %w", err)
+ return "", false, fmt.Errorf("check if file exists at %s, error: %w", pth, err)
}
- resultBuffer := bytes.Buffer{}
- if err = tmpl.Execute(&resultBuffer, inventory); err != nil {
- return "", fmt.Errorf("GenerateInitGradle: %w", err)
+ if isFileExist {
+ fContent, err := os.ReadFile(pth)
+ if err != nil {
+ return "", false, fmt.Errorf("read file at %s, error: %w", pth, err)
+ }
+ fileContent = string(fContent)
}
- return resultBuffer.String(), nil
+ return fileContent, isFileExist, nil
}
diff --git a/internal/config/gradle/gradleconfig_generate_test.go b/internal/config/gradle/gradleconfig_generate_test.go
new file mode 100644
index 00000000..784fd9c7
--- /dev/null
+++ b/internal/config/gradle/gradleconfig_generate_test.go
@@ -0,0 +1,195 @@
+package gradleconfig
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func Test_GenerateInitGradle(t *testing.T) {
+ tests := []struct {
+ name string
+ inventory TemplateInventory
+ want string
+ wantErr string
+ }{
+ {
+ name: "No plugins",
+ inventory: TemplateInventory{
+ Common: PluginCommonTemplateInventory{
+ AuthToken: "AuthTokenValue",
+ Debug: true,
+ AppSlug: "AppSlugValue",
+ CIProvider: "CIProviderValue",
+ },
+ Cache: CacheTemplateInventory{
+ Usage: UsageLevelNone,
+ },
+ Analytics: AnalyticsTemplateInventory{
+ Usage: UsageLevelNone,
+ },
+ TestDistro: TestDistroTemplateInventory{
+ Usage: UsageLevelNone,
+ },
+ },
+ want: expectedNoPluginActivated,
+ wantErr: "",
+ },
+ {
+ name: "Dep only plugins",
+ inventory: TemplateInventory{
+ Common: PluginCommonTemplateInventory{
+ AuthToken: "AuthTokenValue",
+ Debug: true,
+ AppSlug: "AppSlugValue",
+ CIProvider: "CIProviderValue",
+ },
+ Cache: CacheTemplateInventory{
+ Usage: UsageLevelDependency,
+ Version: "CacheVersionValue",
+ },
+ Analytics: AnalyticsTemplateInventory{
+ Usage: UsageLevelDependency,
+ Version: "AnalyticsVersionValue",
+ },
+ TestDistro: TestDistroTemplateInventory{
+ Usage: UsageLevelDependency,
+ Version: "TestDistroVersionValue",
+ },
+ },
+ want: expectedDepOnlyPlugins,
+ wantErr: "",
+ },
+ {
+ name: "Activated plugins gets values from inventory",
+ inventory: TemplateInventory{
+ Common: PluginCommonTemplateInventory{
+ AuthToken: "AuthTokenValue",
+ Debug: true,
+ AppSlug: "AppSlugValue",
+ CIProvider: "CIProviderValue",
+ },
+ Cache: CacheTemplateInventory{
+ Usage: UsageLevelEnabled,
+ Version: "CacheVersionValue",
+ EndpointURLWithPort: "CacheEndpointURLValue",
+ IsPushEnabled: true,
+ ValidationLevel: "ValidationLevelValue",
+ },
+ Analytics: AnalyticsTemplateInventory{
+ Usage: UsageLevelEnabled,
+ Version: "AnalyticsVersionValue",
+ Endpoint: "AnalyticsEndpointURLValue",
+ Port: 123,
+ HTTPEndpoint: "AnalyticsHttpEndpointValue",
+ },
+ TestDistro: TestDistroTemplateInventory{
+ Usage: UsageLevelEnabled,
+ Version: "TestDistroVersionValue",
+ Endpoint: "TestDistroEndpointValue",
+ KvEndpoint: "TestDistroKvEndpointValue",
+ Port: 321,
+ LogLevel: "TestDistroLogLevelValue",
+ },
+ },
+ want: expectedAllPlugins,
+ wantErr: "",
+ },
+ }
+ for _, tt := range tests { //nolint:varnamelen
+ t.Run(tt.name, func(t *testing.T) {
+ got, err := tt.inventory.GenerateInitGradle(DefaultTemplateProxy())
+ if tt.wantErr != "" {
+ require.EqualError(t, err, tt.wantErr)
+ } else {
+ require.NoError(t, err)
+ }
+ assert.Equal(t, tt.want, got)
+ })
+ }
+}
+
+const expectedImports = `import io.bitrise.gradle.cache.BitriseBuildCache
+import io.bitrise.gradle.cache.BitriseBuildCacheServiceFactory`
+
+const expectedRepositories = ` repositories {
+ mavenLocal()
+ maven {
+ name = "artifactRegistry"
+ url = uri("https://us-maven.pkg.dev/ip-build-cache-prod/build-cache-maven")
+ }
+ maven {
+ name = "gradlePlugins"
+ url = uri("https://plugins.gradle.org/m2/")
+ }
+ mavenCentral()
+ google()
+ maven {
+ name = "jitpackIO"
+ url = uri("https://jitpack.io")
+ }
+ }`
+
+const expectedDependencies = ` dependencies {
+ classpath("io.bitrise.gradle:gradle-analytics:AnalyticsVersionValue")
+ classpath("io.bitrise.gradle:remote-cache:CacheVersionValue")
+ classpath("io.bitrise.gradle:test-distribution:TestDistroVersionValue")
+ }`
+
+const expectedNoPluginActivated = "\ninitscript {\n" + expectedRepositories + "\n}"
+
+const expectedDepOnlyPlugins = "\ninitscript {\n" + expectedRepositories + "\n" + expectedDependencies + "\n}"
+
+const expectedAllPlugins = expectedImports +
+ "\n\ninitscript {\n" +
+ expectedRepositories + "\n" +
+ expectedDependencies + "\n}" +
+ `
+settingsEvaluated {
+ buildCache {
+ local {
+ isEnabled = false
+ }
+
+ registerBuildCacheService(BitriseBuildCache::class.java, BitriseBuildCacheServiceFactory::class.java)
+ remote(BitriseBuildCache::class.java) {
+ endpoint = "CacheEndpointURLValue"
+ authToken = "AuthTokenValue"
+ isPush = true
+ debug = true
+ blobValidationLevel = "ValidationLevelValue"
+ collectMetadata = false
+ }
+ }
+ rootProject {
+ apply()
+ extensions.configure{
+ endpoint.set("AnalyticsEndpointURLValue:123")
+ httpEndpoint.set("AnalyticsHttpEndpointValue")
+ authToken.set("AuthTokenValue")
+ dumpEventsToFiles.set(true)
+ debug.set(true)
+ enabled.set(true)
+
+ providerName.set("CIProviderValue")
+
+ bitrise {
+ appSlug.set("AppSlugValue")
+ }
+ }
+ }
+}
+rootProject {
+ extensions.create("rbe", io.bitrise.gradle.rbe.RBEPluginExtension::class.java).with {
+ endpoint.set("TestDistroEndpointValue:321")
+ kvEndpoint.set("TestDistroKvEndpointValue:321")
+ authToken.set("AuthTokenValue")
+ logLevel.set("TestDistroLogLevelValue")
+ bitrise {
+ appSlug.set("AppSlugValue")
+ }
+ }
+
+ apply()
+}`
diff --git a/internal/config/gradle/gradleconfig_test.go b/internal/config/gradle/gradleconfig_test.go
deleted file mode 100644
index 2d01a899..00000000
--- a/internal/config/gradle/gradleconfig_test.go
+++ /dev/null
@@ -1,362 +0,0 @@
-package gradleconfig
-
-import (
- _ "embed"
- "testing"
-
- "github.com/bitrise-io/bitrise-build-cache-cli/internal/config/common"
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
-)
-
-func TestGenerateInitGradle(t *testing.T) {
- type args struct {
- endpointURL string
- authToken string
- userPrefs Preferences
- cacheConfigMetadata common.CacheConfigMetadata
- }
- tests := []struct {
- name string
- args args
- want string
- wantErr string
- }{
- {
- name: "No Auth Token provided",
- args: args{
- endpointURL: "grpcs://bitrise-accelerate.services.bitrise.io",
- },
- want: "",
- wantErr: "generate init.gradle, error: AuthToken not provided",
- },
- {
- name: "No EndpointURL provided",
- args: args{
- authToken: "AuthT0ken",
- },
- want: "",
- wantErr: "generate init.gradle, error: EndpointURL not provided",
- },
- {
- name: "MetricsEnabled=false",
- args: args{
- endpointURL: "grpcs://bitrise-accelerate.services.bitrise.io",
- authToken: "AuthT0ken",
- userPrefs: Preferences{
- IsPushEnabled: true,
- CacheLevelValidation: CacheValidationLevelWarning,
- IsAnalyticsEnabled: false,
- IsDebugEnabled: true,
- },
- cacheConfigMetadata: common.CacheConfigMetadata{
- CIProvider: "BestCI",
- RepoURL: "https://github.com/some/repo",
- // Bitrise CI specific
- BitriseAppID: "BitriseAppID1",
- },
- },
- want: expectedInitScriptWithoutMetrics,
- wantErr: "",
- },
- {
- name: "MetricsEnabled=true",
- args: args{
- endpointURL: "grpcs://bitrise-accelerate.services.bitrise.io",
- authToken: "AuthT0ken",
- userPrefs: Preferences{
- IsPushEnabled: true,
- CacheLevelValidation: CacheValidationLevelWarning,
- IsAnalyticsEnabled: true,
- IsDebugEnabled: true,
- },
- cacheConfigMetadata: common.CacheConfigMetadata{
- CIProvider: "BestCI",
- RepoURL: "https://github.com/some/repo",
- // Bitrise CI specific
- BitriseAppID: "BitriseAppID1",
- },
- },
- want: expectedInitScriptWithMetrics,
- wantErr: "",
- },
- {
- name: "MetricsEnabled=true but empty metadata",
- args: args{
- endpointURL: "grpcs://bitrise-accelerate.services.bitrise.io",
- authToken: "AuthT0ken",
- userPrefs: Preferences{
- IsPushEnabled: true,
- CacheLevelValidation: CacheValidationLevelWarning,
- IsAnalyticsEnabled: true,
- IsDebugEnabled: true,
- },
- cacheConfigMetadata: common.CacheConfigMetadata{},
- },
- want: expectedInitScriptWithMetricsButNoMetadata,
- wantErr: "",
- },
- {
- name: "Push disabled, debug enabled, metrics disabled",
- args: args{
- endpointURL: "grpcs://bitrise-accelerate.services.bitrise.io",
- authToken: "AuthT0ken",
- userPrefs: Preferences{
- IsPushEnabled: false,
- CacheLevelValidation: CacheValidationLevelError,
- IsAnalyticsEnabled: false,
- IsDebugEnabled: true,
- },
- cacheConfigMetadata: common.CacheConfigMetadata{},
- },
- want: expectedInitScriptNoPushYesDebugNoMetrics,
- },
- {
- name: "Push enabled, debug disabled, metrics disabled",
- args: args{
- endpointURL: "grpcs://bitrise-accelerate.services.bitrise.io",
- authToken: "AuthT0ken",
- userPrefs: Preferences{
- IsPushEnabled: true,
- CacheLevelValidation: CacheValidationLevelError,
- IsAnalyticsEnabled: false,
- IsDebugEnabled: false,
- },
- cacheConfigMetadata: common.CacheConfigMetadata{},
- },
- want: expectedInitScriptYesPushNoDebugNoMetrics,
- },
- }
- for _, tt := range tests { //nolint:varnamelen
- t.Run(tt.name, func(t *testing.T) {
- got, err := GenerateInitGradle(tt.args.endpointURL, tt.args.authToken, tt.args.userPrefs, tt.args.cacheConfigMetadata)
- if tt.wantErr != "" {
- require.EqualError(t, err, tt.wantErr)
- } else {
- require.NoError(t, err)
- }
- assert.Equal(t, tt.want, got)
- })
- }
-}
-
-const expectedInitScriptWithMetrics = `import io.bitrise.gradle.cache.BitriseBuildCache
-import io.bitrise.gradle.cache.BitriseBuildCacheServiceFactory
-
-initscript {
- repositories {
- mavenLocal()
- maven(url="https://us-maven.pkg.dev/ip-build-cache-prod/build-cache-maven")
- maven(url="https://plugins.gradle.org/m2/")
- mavenCentral()
- google()
- maven(url="https://jitpack.io")
- }
- dependencies {
- classpath("io.bitrise.gradle:remote-cache:1.2.19")
- classpath("io.bitrise.gradle:gradle-analytics:2.1.28")
- }
-}
-
-settingsEvaluated {
- buildCache {
- local {
- isEnabled = false
- }
-
- registerBuildCacheService(BitriseBuildCache::class.java, BitriseBuildCacheServiceFactory::class.java)
- remote(BitriseBuildCache::class.java) {
- endpoint = "grpcs://bitrise-accelerate.services.bitrise.io"
- authToken = "AuthT0ken"
- isEnabled = true
- isPush = true
- debug = true
- blobValidationLevel = "warning"
- collectMetadata = false
- }
- }
-}
-
-rootProject {
- apply()
-
- extensions.configure{
- endpoint.set("gradle-analytics.services.bitrise.io:443")
- httpEndpoint.set("https://gradle-sink.services.bitrise.io")
- authToken.set("AuthT0ken")
- dumpEventsToFiles.set(true)
- debug.set(true)
- enabled.set(true)
-
- providerName.set("BestCI")
-
- bitrise {
- appSlug.set("BitriseAppID1")
- }
- }
-}
-`
-
-const expectedInitScriptWithMetricsButNoMetadata = `import io.bitrise.gradle.cache.BitriseBuildCache
-import io.bitrise.gradle.cache.BitriseBuildCacheServiceFactory
-
-initscript {
- repositories {
- mavenLocal()
- maven(url="https://us-maven.pkg.dev/ip-build-cache-prod/build-cache-maven")
- maven(url="https://plugins.gradle.org/m2/")
- mavenCentral()
- google()
- maven(url="https://jitpack.io")
- }
- dependencies {
- classpath("io.bitrise.gradle:remote-cache:1.2.19")
- classpath("io.bitrise.gradle:gradle-analytics:2.1.28")
- }
-}
-
-settingsEvaluated {
- buildCache {
- local {
- isEnabled = false
- }
-
- registerBuildCacheService(BitriseBuildCache::class.java, BitriseBuildCacheServiceFactory::class.java)
- remote(BitriseBuildCache::class.java) {
- endpoint = "grpcs://bitrise-accelerate.services.bitrise.io"
- authToken = "AuthT0ken"
- isEnabled = true
- isPush = true
- debug = true
- blobValidationLevel = "warning"
- collectMetadata = false
- }
- }
-}
-
-rootProject {
- apply()
-
- extensions.configure{
- endpoint.set("gradle-analytics.services.bitrise.io:443")
- httpEndpoint.set("https://gradle-sink.services.bitrise.io")
- authToken.set("AuthT0ken")
- dumpEventsToFiles.set(true)
- debug.set(true)
- enabled.set(true)
-
- providerName.set("")
-
- bitrise {
- }
- }
-}
-`
-
-const expectedInitScriptWithoutMetrics = `import io.bitrise.gradle.cache.BitriseBuildCache
-import io.bitrise.gradle.cache.BitriseBuildCacheServiceFactory
-
-initscript {
- repositories {
- mavenLocal()
- maven(url="https://us-maven.pkg.dev/ip-build-cache-prod/build-cache-maven")
- maven(url="https://plugins.gradle.org/m2/")
- mavenCentral()
- google()
- maven(url="https://jitpack.io")
- }
- dependencies {
- classpath("io.bitrise.gradle:remote-cache:1.2.19")
- }
-}
-
-settingsEvaluated {
- buildCache {
- local {
- isEnabled = false
- }
-
- registerBuildCacheService(BitriseBuildCache::class.java, BitriseBuildCacheServiceFactory::class.java)
- remote(BitriseBuildCache::class.java) {
- endpoint = "grpcs://bitrise-accelerate.services.bitrise.io"
- authToken = "AuthT0ken"
- isEnabled = true
- isPush = true
- debug = true
- blobValidationLevel = "warning"
- }
- }
-}
-`
-
-const expectedInitScriptNoPushYesDebugNoMetrics = `import io.bitrise.gradle.cache.BitriseBuildCache
-import io.bitrise.gradle.cache.BitriseBuildCacheServiceFactory
-
-initscript {
- repositories {
- mavenLocal()
- maven(url="https://us-maven.pkg.dev/ip-build-cache-prod/build-cache-maven")
- maven(url="https://plugins.gradle.org/m2/")
- mavenCentral()
- google()
- maven(url="https://jitpack.io")
- }
- dependencies {
- classpath("io.bitrise.gradle:remote-cache:1.2.19")
- }
-}
-
-settingsEvaluated {
- buildCache {
- local {
- isEnabled = false
- }
-
- registerBuildCacheService(BitriseBuildCache::class.java, BitriseBuildCacheServiceFactory::class.java)
- remote(BitriseBuildCache::class.java) {
- endpoint = "grpcs://bitrise-accelerate.services.bitrise.io"
- authToken = "AuthT0ken"
- isEnabled = true
- isPush = false
- debug = true
- blobValidationLevel = "error"
- }
- }
-}
-`
-
-const expectedInitScriptYesPushNoDebugNoMetrics = `import io.bitrise.gradle.cache.BitriseBuildCache
-import io.bitrise.gradle.cache.BitriseBuildCacheServiceFactory
-
-initscript {
- repositories {
- mavenLocal()
- maven(url="https://us-maven.pkg.dev/ip-build-cache-prod/build-cache-maven")
- maven(url="https://plugins.gradle.org/m2/")
- mavenCentral()
- google()
- maven(url="https://jitpack.io")
- }
- dependencies {
- classpath("io.bitrise.gradle:remote-cache:1.2.19")
- }
-}
-
-settingsEvaluated {
- buildCache {
- local {
- isEnabled = false
- }
-
- registerBuildCacheService(BitriseBuildCache::class.java, BitriseBuildCacheServiceFactory::class.java)
- remote(BitriseBuildCache::class.java) {
- endpoint = "grpcs://bitrise-accelerate.services.bitrise.io"
- authToken = "AuthT0ken"
- isEnabled = true
- isPush = true
- debug = false
- blobValidationLevel = "error"
- }
- }
-}
-`
diff --git a/internal/config/gradle/gradleconfig_write_test.go b/internal/config/gradle/gradleconfig_write_test.go
new file mode 100644
index 00000000..8188c6ce
--- /dev/null
+++ b/internal/config/gradle/gradleconfig_write_test.go
@@ -0,0 +1,121 @@
+package gradleconfig
+
+import (
+ "bytes"
+ "errors"
+ "os"
+ "path/filepath"
+ "testing"
+ "text/template"
+
+ "github.com/bitrise-io/go-utils/v2/log"
+ "github.com/bitrise-io/go-utils/v2/mocks"
+ "github.com/bitrise-io/go-utils/v2/pathutil"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/mock"
+ "github.com/stretchr/testify/require"
+)
+
+func Test_writeGradleInitGradle(t *testing.T) {
+ prep := func() (log.Logger, string) {
+ mockLogger := &mocks.Logger{}
+ mockLogger.On("Infof", mock.Anything).Return()
+ mockLogger.On("Infof", mock.Anything, mock.Anything).Return()
+ mockLogger.On("Debugf", mock.Anything).Return()
+ mockLogger.On("Debugf", mock.Anything, mock.Anything).Return()
+ mockLogger.On("Errorf", mock.Anything).Return()
+ mockLogger.On("Errorf", mock.Anything, mock.Anything).Return()
+ tmpPath := t.TempDir()
+ tmpGradleHomeDir := filepath.Join(tmpPath, ".gradle")
+
+ return mockLogger, tmpGradleHomeDir
+ }
+
+ t.Run("writes the gradle init file", func(t *testing.T) {
+ mockLogger, tmpGradleHomeDir := prep()
+
+ inventory := TemplateInventory{}
+
+ // when
+ err := inventory.WriteToGradleInit(mockLogger, tmpGradleHomeDir, DefaultOsProxy(), DefaultTemplateProxy())
+
+ // then
+ require.NoError(t, err)
+ //
+ isInitFileExists, err := pathutil.NewPathChecker().IsPathExists(filepath.Join(tmpGradleHomeDir, "init.d", "bitrise-build-cache.init.gradle.kts"))
+ require.NoError(t, err)
+ assert.True(t, isInitFileExists)
+ })
+
+ t.Run("when can't make directories throws error", func(t *testing.T) {
+ mockLogger, tmpGradleHomeDir := prep()
+
+ inventory := TemplateInventory{}
+ expectedError := errors.New("failed to create directories")
+ osProxy := OsProxy{
+ MkdirAll: func(string, os.FileMode) error { return expectedError },
+ }
+
+ // when
+ err := inventory.WriteToGradleInit(mockLogger, tmpGradleHomeDir, osProxy, DefaultTemplateProxy())
+
+ // then
+ require.ErrorIs(t, err, expectedError)
+ })
+
+ t.Run("when template parsing fails throws error", func(t *testing.T) {
+ mockLogger, tmpGradleHomeDir := prep()
+
+ inventory := TemplateInventory{}
+ expectedError := errors.New("failed to parse template")
+ templateProxy := TemplateProxy{
+ parse: func(string, string) (*template.Template, error) {
+ return nil, expectedError
+ },
+ }
+
+ // when
+ err := inventory.WriteToGradleInit(mockLogger, tmpGradleHomeDir, DefaultOsProxy(), templateProxy)
+
+ // then
+ require.ErrorIs(t, err, expectedError)
+ })
+
+ t.Run("when template execution fails throws error", func(t *testing.T) {
+ mockLogger, tmpGradleHomeDir := prep()
+
+ inventory := TemplateInventory{}
+ expectedError := errors.New("failed to execute template")
+ templateProxy := TemplateProxy{
+ parse: DefaultTemplateProxy().parse,
+ execute: func(*template.Template, *bytes.Buffer, TemplateInventory) error {
+ return expectedError
+ },
+ }
+
+ // when
+ err := inventory.WriteToGradleInit(mockLogger, tmpGradleHomeDir, DefaultOsProxy(), templateProxy)
+
+ // then
+ require.ErrorIs(t, err, expectedError)
+ })
+
+ t.Run("when writing init.gradle fails throws error", func(t *testing.T) {
+ mockLogger, tmpGradleHomeDir := prep()
+
+ inventory := TemplateInventory{}
+ expectedError := errors.New("failed to write init.gradle")
+ osProxy := OsProxy{
+ MkdirAll: DefaultOsProxy().MkdirAll,
+ WriteFile: func(string, []byte, os.FileMode) error {
+ return expectedError
+ },
+ }
+
+ // when
+ err := inventory.WriteToGradleInit(mockLogger, tmpGradleHomeDir, osProxy, DefaultTemplateProxy())
+
+ // then
+ require.ErrorIs(t, err, expectedError)
+ })
+}
diff --git a/internal/config/gradle/initd.gradle.kts.gotemplate b/internal/config/gradle/initd.gradle.kts.gotemplate
index 7eafe905..d4f66dcf 100644
--- a/internal/config/gradle/initd.gradle.kts.gotemplate
+++ b/internal/config/gradle/initd.gradle.kts.gotemplate
@@ -1,24 +1,42 @@
+{{- if eq .Cache.Usage "enabled" -}}
import io.bitrise.gradle.cache.BitriseBuildCache
-import io.bitrise.gradle.cache.BitriseBuildCacheServiceFactory
-
+import io.bitrise.gradle.cache.BitriseBuildCacheServiceFactory
+{{ end }}
initscript {
repositories {
mavenLocal()
- maven(url="https://us-maven.pkg.dev/ip-build-cache-prod/build-cache-maven")
- maven(url="https://plugins.gradle.org/m2/")
+ maven {
+ name = "artifactRegistry"
+ url = uri("https://us-maven.pkg.dev/ip-build-cache-prod/build-cache-maven")
+ }
+ maven {
+ name = "gradlePlugins"
+ url = uri("https://plugins.gradle.org/m2/")
+ }
mavenCentral()
google()
- maven(url="https://jitpack.io")
+ maven {
+ name = "jitpackIO"
+ url = uri("https://jitpack.io")
+ }
}
+ {{- if hasDependencies . }}
dependencies {
- classpath("io.bitrise.gradle:remote-cache:{{ .CachePluginVersion }}")
- {{- if .IsAnalyticsEnabled }}
- classpath("io.bitrise.gradle:gradle-analytics:{{ .AnalyticsPluginVersion }}")
+ {{- if eq .Analytics.Usage "dependency" "enabled" }}
+ classpath("io.bitrise.gradle:gradle-analytics:{{ .Analytics.Version }}")
+ {{- end }}
+ {{- if eq .Cache.Usage "dependency" "enabled" }}
+ classpath("io.bitrise.gradle:remote-cache:{{ .Cache.Version }}")
+ {{- end }}
+ {{- if eq .TestDistro.Usage "dependency" "enabled" }}
+ classpath("io.bitrise.gradle:test-distribution:{{ .TestDistro.Version }}")
{{- end }}
}
+ {{- end }}
}
-
+{{- if or (eq .Cache.Usage "enabled") (eq .Analytics.Usage "enabled") }}
settingsEvaluated {
+ {{- if eq .Cache.Usage "enabled" }}
buildCache {
local {
isEnabled = false
@@ -26,39 +44,52 @@ settingsEvaluated {
registerBuildCacheService(BitriseBuildCache::class.java, BitriseBuildCacheServiceFactory::class.java)
remote(BitriseBuildCache::class.java) {
- endpoint = "{{ .CacheEndpointURLWithPort }}"
- authToken = "{{ .AuthToken }}"
- isEnabled = {{ not .IsDependencyOnly }}
- isPush = {{ .IsPushEnabled }}
- debug = {{ .IsDebugEnabled }}
- blobValidationLevel = "{{ .ValidationLevel }}"
- {{- if .IsAnalyticsEnabled }}
+ endpoint = "{{ .Cache.EndpointURLWithPort }}"
+ authToken = "{{ .Common.AuthToken }}"
+ isPush = {{ .Cache.IsPushEnabled }}
+ debug = {{ .Common.Debug }}
+ blobValidationLevel = "{{ .Cache.ValidationLevel }}"
+ {{- if eq .Analytics.Usage "dependency" "enabled" }}
collectMetadata = false
{{- end }}
}
}
-}
+ {{- end }}
+ {{- if eq .Analytics.Usage "enabled" }}
+ rootProject {
+ apply()
+ extensions.configure{
+ endpoint.set("{{ .Analytics.Endpoint }}:{{ .Analytics.Port }}")
+ httpEndpoint.set("{{ .Analytics.HTTPEndpoint }}")
+ authToken.set("{{ .Common.AuthToken }}")
+ dumpEventsToFiles.set({{ .Common.Debug }})
+ debug.set({{ .Common.Debug }})
+ enabled.set(true)
-{{- if .IsAnalyticsEnabled }}
+ providerName.set("{{ .Common.CIProvider }}")
+ bitrise {
+ {{- if .Common.AppSlug }}
+ appSlug.set("{{ .Common.AppSlug }}")
+ {{- end }}
+ }
+ }
+ }
+ {{- end }}
+}
+{{- end -}}
+{{- if eq .TestDistro.Usage "enabled" }}
rootProject {
- apply()
-
- extensions.configure{
- endpoint.set("{{ .AnalyticsEndpoint }}:{{ .AnalyticsPort }}")
- httpEndpoint.set("{{ .AnalyticsHTTPEndpoint }}")
- authToken.set("{{ .AuthToken }}")
- dumpEventsToFiles.set({{ .IsDebugEnabled }})
- debug.set({{ .IsDebugEnabled }})
- enabled.set({{ not .IsDependencyOnly }})
-
- providerName.set("{{ .CacheConfigMetadata.CIProvider }}")
-
+ extensions.create("rbe", io.bitrise.gradle.rbe.RBEPluginExtension::class.java).with {
+ endpoint.set("{{ .TestDistro.Endpoint }}:{{ .TestDistro.Port }}")
+ kvEndpoint.set("{{ .TestDistro.KvEndpoint }}:{{ .TestDistro.Port }}")
+ authToken.set("{{ .Common.AuthToken }}")
+ logLevel.set("{{ .TestDistro.LogLevel }}")
bitrise {
- {{- if .CacheConfigMetadata.BitriseAppID }}
- appSlug.set("{{ .CacheConfigMetadata.BitriseAppID }}")
- {{- end }}
+ appSlug.set("{{ .Common.AppSlug }}")
}
}
+
+ apply()
}
-{{- end }}
+{{- end -}}
\ No newline at end of file
diff --git a/internal/consts/consts.go b/internal/consts/consts.go
index 70bd7c9b..a93f640c 100644
--- a/internal/consts/consts.go
+++ b/internal/consts/consts.go
@@ -39,4 +39,7 @@ const (
// Gradle Test Distribution Plugin version
GradleTestDistributionPluginDepVersion = "2.1.24"
+ GradleTestDistributionEndpoint = "grpcs://remote-execution-ord.services.bitrise.io"
+ GradleTestDistributionKvEndpoint = "grpcs://build-cache-api-ord.services.bitrise.io"
+ GradleTestDistributionPort = 443
)
diff --git a/internal/gradle/plugin.go b/internal/gradle/plugin.go
index 4b9ab460..06c23f52 100644
--- a/internal/gradle/plugin.go
+++ b/internal/gradle/plugin.go
@@ -7,10 +7,12 @@ import (
"strings"
"github.com/bitrise-io/bitrise-build-cache-cli/internal/consts"
+ "github.com/bitrise-io/go-utils/v2/log"
)
const (
bitriseGradlePluginGroup = "io.bitrise.gradle"
+ WarnNoHome = "Could not determine home directory, falling back to $PWD, error: %s"
)
type PluginFile struct {
@@ -47,10 +49,11 @@ func (gf *PluginFile) dirPath() string {
)
}
-func (gf *PluginFile) absoluteDirPath() string {
+func (gf *PluginFile) absoluteDirPath(logger log.Logger) string {
home, err := os.UserHomeDir()
if err != nil {
home = os.Getenv("PWD")
+ logger.Warnf(WarnNoHome, err)
}
return filepath.Join(home, ".m2", "repository", gf.dirPath())
diff --git a/internal/gradle/plugin_cacher.go b/internal/gradle/plugin_cacher.go
index 659e31bd..4d4cfcf7 100644
--- a/internal/gradle/plugin_cacher.go
+++ b/internal/gradle/plugin_cacher.go
@@ -42,8 +42,8 @@ func (pluginCacher PluginCacher) CachePlugins(
for _, file := range plugin.files() {
// Try to fetch from cache
- if downloaded, err := pluginCacher.fetchFromCache(ctx, kvClient, file); err == nil {
- if !downloaded {
+ if skipped, err := pluginCacher.fetchFromCache(ctx, kvClient, file, logger); err == nil {
+ if !skipped {
logger.Debugf("(i) " + file.name() + " fetched from kv cache")
} else {
logger.Debugf("(i) " + file.name() + " was already in the local repository")
@@ -64,7 +64,7 @@ func (pluginCacher PluginCacher) CachePlugins(
logger.Debugf("(i) " + file.name() + " fetched from artifact repositories: " + source)
// Upload to cache if fetched from repositories
- if err := pluginCacher.cache(ctx, kvClient, file); err != nil {
+ if err := pluginCacher.cache(ctx, kvClient, file, logger); err != nil {
errs = append(errs, err)
return
@@ -90,10 +90,11 @@ func (pluginCacher PluginCacher) fetchFromCache(
ctx context.Context,
kvClient *kv.Client,
file PluginFile,
+ logger log.Logger,
) (bool, error) {
downloaded, err := kvClient.DownloadFile(
ctx,
- filepath.Join(file.absoluteDirPath(), file.name()),
+ filepath.Join(file.absoluteDirPath(logger), file.name()),
file.key(),
0,
true,
@@ -112,10 +113,11 @@ func (pluginCacher PluginCacher) cache(
ctx context.Context,
kvClient *kv.Client,
file PluginFile,
+ logger log.Logger,
) error {
err := kvClient.UploadFileToBuildCache(
ctx,
- filepath.Join(file.absoluteDirPath(), file.name()),
+ filepath.Join(file.absoluteDirPath(logger), file.name()),
file.key(),
)
diff --git a/internal/gradle/plugin_file_downloader.go b/internal/gradle/plugin_file_downloader.go
index 39fc2c94..c7590e22 100644
--- a/internal/gradle/plugin_file_downloader.go
+++ b/internal/gradle/plugin_file_downloader.go
@@ -43,10 +43,10 @@ func (downloader PluginFileDownloader) Download() error {
}
// Create the file
- if err := os.MkdirAll(downloader.file.absoluteDirPath(), os.ModePerm); err != nil {
+ if err := os.MkdirAll(downloader.file.absoluteDirPath(downloader.logger), os.ModePerm); err != nil {
return fmt.Errorf(errFmtCreateFile, err)
}
- out, err := os.Create(filepath.Join(downloader.file.absoluteDirPath(), downloader.file.name()))
+ out, err := os.Create(filepath.Join(downloader.file.absoluteDirPath(downloader.logger), downloader.file.name()))
if err != nil {
return fmt.Errorf(errFmtCreateFile, err)
}
diff --git a/internal/xcode/mocks/tracker_mock.go b/internal/xcode/mocks/tracker_mock.go
index 5ece8ded..c6f86adb 100644
--- a/internal/xcode/mocks/tracker_mock.go
+++ b/internal/xcode/mocks/tracker_mock.go
@@ -4,10 +4,11 @@
package mocks
import (
- "github.com/bitrise-io/bitrise-build-cache-cli/internal/build_cache/kv"
- "github.com/bitrise-io/bitrise-build-cache-cli/internal/xcode"
"sync"
"time"
+
+ "github.com/bitrise-io/bitrise-build-cache-cli/internal/build_cache/kv"
+ "github.com/bitrise-io/bitrise-build-cache-cli/internal/xcode"
)
// Ensure, that StepAnalyticsTrackerMock does implement xcode.StepAnalyticsTracker.
diff --git a/proto/build/bazel/remote/execution/v2/remote_execution.pb.go b/proto/build/bazel/remote/execution/v2/remote_execution.pb.go
index 80c1333a..d7555b87 100644
--- a/proto/build/bazel/remote/execution/v2/remote_execution.pb.go
+++ b/proto/build/bazel/remote/execution/v2/remote_execution.pb.go
@@ -21,6 +21,9 @@
package remoteexecution
import (
+ reflect "reflect"
+ sync "sync"
+
longrunningpb "cloud.google.com/go/longrunning/autogen/longrunningpb"
semver "github.com/bazelbuild/remote-apis/build/bazel/semver"
_ "google.golang.org/genproto/googleapis/api/annotations"
@@ -31,8 +34,6 @@ import (
durationpb "google.golang.org/protobuf/types/known/durationpb"
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
wrapperspb "google.golang.org/protobuf/types/known/wrapperspb"
- reflect "reflect"
- sync "sync"
)
const (
diff --git a/proto/build/bazel/remote/execution/v2/remote_execution_grpc.pb.go b/proto/build/bazel/remote/execution/v2/remote_execution_grpc.pb.go
index 743418c0..681e6685 100644
--- a/proto/build/bazel/remote/execution/v2/remote_execution_grpc.pb.go
+++ b/proto/build/bazel/remote/execution/v2/remote_execution_grpc.pb.go
@@ -7,8 +7,9 @@
package remoteexecution
import (
- longrunningpb "cloud.google.com/go/longrunning/autogen/longrunningpb"
context "context"
+
+ longrunningpb "cloud.google.com/go/longrunning/autogen/longrunningpb"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
diff --git a/proto/kv_storage/kv_storage.pb.go b/proto/kv_storage/kv_storage.pb.go
index 6c7facf7..d2ccafa9 100644
--- a/proto/kv_storage/kv_storage.pb.go
+++ b/proto/kv_storage/kv_storage.pb.go
@@ -7,11 +7,12 @@
package kv_storage
import (
+ reflect "reflect"
+ sync "sync"
+
bytestream "google.golang.org/genproto/googleapis/bytestream"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
- reflect "reflect"
- sync "sync"
)
const (
diff --git a/proto/kv_storage/kv_storage_grpc.pb.go b/proto/kv_storage/kv_storage_grpc.pb.go
index ed6f21ba..b7c46120 100644
--- a/proto/kv_storage/kv_storage_grpc.pb.go
+++ b/proto/kv_storage/kv_storage_grpc.pb.go
@@ -8,6 +8,7 @@ package kv_storage
import (
context "context"
+
bytestream "google.golang.org/genproto/googleapis/bytestream"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
diff --git a/scripts/generate-dependency-matrix.sh b/scripts/generate-dependency-matrix.sh
index d732ad2c..ac0c7dc9 100644
--- a/scripts/generate-dependency-matrix.sh
+++ b/scripts/generate-dependency-matrix.sh
@@ -20,8 +20,8 @@ git clone https://github.com/bitrise-io/bitrise-build-cache-cli.git
git clone https://github.com/bitrise-steplib/bitrise-step-activate-gradle-remote-cache.git
export tmp_md="release-table.md"
-echo "| Step version | CLI version | Analytics plugin version | Cache plugin version |" >> $tmp_md
-echo "|--------------|-------------|--------------------------|----------------------|" >> $tmp_md
+echo "| Step version | CLI version | Analytics plugin version | Cache plugin version | Test Distribution plugin version |" >> $tmp_md
+echo "|--------------|-------------|--------------------------|----------------------|----------------------------------|" >> $tmp_md
find "bitrise-steplib/steps/activate-build-cache-for-gradle" -mindepth 1 -maxdepth 1 -type d | while read -r dir; do
@@ -52,7 +52,7 @@ sort -Vr | while read -r step_version; do
cd ../bitrise-build-cache-cli
git checkout "$cli_version"
- go run main.go enable-for gradle
+ go run main.go activate gradle --cache --test-distribution
if [ ! -f "$HOME/.gradle/init.d/bitrise-build-cache.init.gradle.kts" ]; then
echo "Gradle build cache not enabled in $HOME/.gradle/init.d/bitrise-build-cache.init.gradle.kts"
@@ -62,11 +62,12 @@ sort -Vr | while read -r step_version; do
analytics_version=$(grep 'classpath("io.bitrise.gradle:gradle-analytics:' "$HOME/.gradle/init.d/bitrise-build-cache.init.gradle.kts" | sed -n -E 's/.*gradle-analytics:([0-9]+\.[0-9]+\.[0-9]+).*/\1/p')
cache_version=$(grep 'classpath("io.bitrise.gradle:remote-cache:' "$HOME/.gradle/init.d/bitrise-build-cache.init.gradle.kts" | sed -n -E 's/.*remote-cache:([0-9]+\.[0-9]+\.[0-9]+).*/\1/p')
+ test_distro_version=$(grep 'classpath("io.bitrise.gradle:test-distribution:' "$HOME/.gradle/init.d/bitrise-build-cache.init.gradle.kts" | sed -n -E 's/.*test-distribution:([0-9]+\.[0-9]+\.[0-9]+).*/\1/p')
- echo "Gradle build cache enabled with analytics version: $analytics_version and cache version: $cache_version"
+ echo "Gradle build cache enabled with analytics version: $analytics_version, cache version: $cache_version, test-distribution version: $test_distro_version"
cd ..
- echo "| $step_version | [$cli_version]($CLI_RELEASE_URL_PREFIX/$cli_version) | $analytics_version | $cache_version |" >> $tmp_md
+ echo "| $step_version | [$cli_version]($CLI_RELEASE_URL_PREFIX/$cli_version) | $analytics_version | $cache_version | $test_distro_version |" >> $tmp_md
done
popd
diff --git a/scripts/update_plugins.sh b/scripts/update_plugins.sh
index 301147d7..cbaf1994 100755
--- a/scripts/update_plugins.sh
+++ b/scripts/update_plugins.sh
@@ -2,7 +2,6 @@
set -e
VERSION_FILE="./internal/consts/consts.go"
-TEST_FILE="./internal/config/gradle/gradleconfig_test.go"
SED_IN_PLACE_COMMAND=(-i)
if [[ "$OSTYPE" == "darwin"* ]]; then
@@ -45,7 +44,6 @@ update() {
# Compare versions and update if the latest is greater
if compare_versions "$current_version" "$latest_version"; then
sed "${SED_IN_PLACE_COMMAND[@]}" "s/$dep_version_name = \".*\"/$dep_version_name = \"$latest_version\"/" "$VERSION_FILE"
- sed "${SED_IN_PLACE_COMMAND[@]}" "s/classpath(\"io.bitrise.gradle:$artifact_name:.*\")/classpath(\"io.bitrise.gradle:$artifact_name:$latest_version\")/" "$TEST_FILE"
echo "Updated to version $latest_version"
else
echo "No update needed. Current version ($current_version) is up-to-date or newer."