Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package terragrunt for openSUSE:Factory 
checked in at 2023-05-18 15:19:32
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/terragrunt (Old)
 and      /work/SRC/openSUSE:Factory/.terragrunt.new.1533 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "terragrunt"

Thu May 18 15:19:32 2023 rev:45 rq:1087699 version:0.45.13

Changes:
--------
--- /work/SRC/openSUSE:Factory/terragrunt/terragrunt.changes    2023-05-11 
12:34:15.150929042 +0200
+++ /work/SRC/openSUSE:Factory/.terragrunt.new.1533/terragrunt.changes  
2023-05-18 15:19:39.881979001 +0200
@@ -1,0 +2,17 @@
+Wed May 17 17:42:37 UTC 2023 - ka...@b1-systems.de
+
+- Update to version 0.45.13:
+  * feat: add `timecmp` config function (#2571)
+
+-------------------------------------------------------------------
+Wed May 17 17:38:30 UTC 2023 - ka...@b1-systems.de
+
+- Update to version 0.45.12:
+  * Handle provider lock file when fetching dependency outputs
+    (#2568)
+  * Update aws-auth.md (#2563)
+  * Add missing IAM Permissions s3:PutBucketOwnershipControls to
+    docs this is required now with TG versions starting from
+    v0.45.4 (#2562)
+
+-------------------------------------------------------------------

Old:
----
  terragrunt-0.45.11.obscpio

New:
----
  terragrunt-0.45.13.obscpio

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ terragrunt.spec ++++++
--- /var/tmp/diff_new_pack.XMjAYy/_old  2023-05-18 15:19:41.757990504 +0200
+++ /var/tmp/diff_new_pack.XMjAYy/_new  2023-05-18 15:19:41.765990553 +0200
@@ -19,7 +19,7 @@
 %define __arch_install_post export NO_BRP_STRIP_DEBUG=true
 
 Name:           terragrunt
-Version:        0.45.11
+Version:        0.45.13
 Release:        0
 Summary:        Thin wrapper for Terraform for working with multiple Terraform 
modules
 License:        MIT

++++++ _service ++++++
--- /var/tmp/diff_new_pack.XMjAYy/_old  2023-05-18 15:19:41.833990970 +0200
+++ /var/tmp/diff_new_pack.XMjAYy/_new  2023-05-18 15:19:41.837990994 +0200
@@ -3,7 +3,7 @@
     <param name="url">https://github.com/gruntwork-io/terragrunt</param>
     <param name="scm">git</param>
     <param name="exclude">.git</param>
-    <param name="revision">v0.45.11</param>
+    <param name="revision">v0.45.13</param>
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="changesgenerate">enable</param>
     <param name="versionrewrite-pattern">v(.*)</param>

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.XMjAYy/_old  2023-05-18 15:19:41.865991166 +0200
+++ /var/tmp/diff_new_pack.XMjAYy/_new  2023-05-18 15:19:41.869991191 +0200
@@ -1,6 +1,6 @@
 <servicedata>
 <service name="tar_scm">
                 <param 
name="url">https://github.com/gruntwork-io/terragrunt</param>
-              <param 
name="changesrevision">fcfb391b5be91c67e9c0fb66ce41a4cc507c6c53</param></service></servicedata>
+              <param 
name="changesrevision">9015f781c2ffae79d8bace26e45ca20b86b99bbb</param></service></servicedata>
 (No newline at EOF)
 

++++++ terragrunt-0.45.11.obscpio -> terragrunt-0.45.13.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/terragrunt-0.45.11/cli/cli_app.go 
new/terragrunt-0.45.13/cli/cli_app.go
--- old/terragrunt-0.45.11/cli/cli_app.go       2023-05-10 20:59:43.000000000 
+0200
+++ new/terragrunt-0.45.13/cli/cli_app.go       2023-05-17 18:49:48.000000000 
+0200
@@ -15,7 +15,6 @@
        "github.com/gruntwork-io/gruntwork-cli/collections"
        "github.com/hashicorp/go-multierror"
        "github.com/mattn/go-zglob"
-       "github.com/sirupsen/logrus"
        "github.com/urfave/cli"
 
        "github.com/gruntwork-io/terragrunt/aws_helper"
@@ -845,7 +844,7 @@
                        // case, we are using the user's working dir here, 
rather than just looking at the parent dir of the
                        // terragrunt.hcl. However, the default value for the 
user's working dir, set in options.go, IS just the
                        // parent dir of terragrunt.hcl, so these will likely 
always be the same.
-                       lockFileError = 
copyLockFile(terragruntOptions.WorkingDir, 
originalTerragruntOptions.WorkingDir, terragruntOptions.Logger)
+                       lockFileError = 
util.CopyLockFile(terragruntOptions.WorkingDir, 
originalTerragruntOptions.WorkingDir, terragruntOptions.Logger)
                }
 
                return multierror.Append(runTerraformError, 
lockFileError).ErrorOrNil()
@@ -903,20 +902,6 @@
        return false
 }
 
-// Terraform 0.14 now generates a lock file when you run `terraform init`.
-// If any such file exists, this function will copy the lock file to the 
destination folder
-func copyLockFile(sourceFolder string, destinationFolder string, logger 
*logrus.Entry) error {
-       sourceLockFilePath := util.JoinPath(sourceFolder, 
util.TerraformLockFile)
-       destinationLockFilePath := util.JoinPath(destinationFolder, 
util.TerraformLockFile)
-
-       if util.FileExists(sourceLockFilePath) {
-               logger.Debugf("Copying lock file from %s to %s", 
sourceLockFilePath, destinationFolder)
-               return util.CopyFile(sourceLockFilePath, 
destinationLockFilePath)
-       }
-
-       return nil
-}
-
 // Run the given action function surrounded by hooks. That is, run the before 
hooks first, then, if there were no
 // errors, run the action, and finally, run the after hooks. Return any errors 
hit from the hooks or action.
 func runActionWithHooks(description string, terragruntOptions 
*options.TerragruntOptions, terragruntConfig *config.TerragruntConfig, action 
func() error) error {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/terragrunt-0.45.11/config/config_helpers.go 
new/terragrunt-0.45.13/config/config_helpers.go
--- old/terragrunt-0.45.11/config/config_helpers.go     2023-05-10 
20:59:43.000000000 +0200
+++ new/terragrunt-0.45.13/config/config_helpers.go     2023-05-17 
18:49:48.000000000 +0200
@@ -147,6 +147,7 @@
        terraformCompatibilityFunctions := map[string]function.Function{
                "startswith": wrapStringSliceToBoolAsFuncImpl(startsWith, 
extensions.TrackInclude, terragruntOptions),
                "endswith":   wrapStringSliceToBoolAsFuncImpl(endsWith, 
extensions.TrackInclude, terragruntOptions),
+               "timecmp":    wrapStringSliceToNumberAsFuncImpl(timeCmp, 
extensions.TrackInclude, terragruntOptions),
        }
 
        functions := map[string]function.Function{}
@@ -602,7 +603,6 @@
 // source param in module's terragrunt.hcl: 
git::g...@github.com:acme/infrastructure-modules.git//networking/vpc?ref=v0.0.1
 //
 // This method will return: /source/infrastructure-modules//networking/vpc
-//
 func GetTerragruntSourceForModule(sourcePath string, modulePath string, 
moduleTerragruntConfig *TerragruntConfig) (string, error) {
        if sourcePath == "" || moduleTerragruntConfig.Terraform == nil || 
moduleTerragruntConfig.Terraform.Source == nil || 
*moduleTerragruntConfig.Terraform.Source == "" {
                return "", nil
@@ -652,14 +652,12 @@
        return matches[1], nil
 }
 
-//
 // A cache of the results of a decrypt operation via sops. Each decryption
 // operation can take several seconds, so this cache speeds up terragrunt 
executions
 // where the same sops files are referenced multiple times.
 //
 // The cache keys are the canonical paths to the encrypted files, and the 
values are the
 // plain-text result of the decrypt operation.
-//
 var sopsCache = NewStringCache()
 
 // decrypts and returns sops encrypted utf-8 yaml or json data as a string
@@ -726,11 +724,11 @@
 }
 
 // Return the selected include block based on a label passed in as a function 
param. Note that the assumption is that:
-// - If the Original attribute is set, we are in the parent context so return 
that.
-// - If there are no include blocks, no param is required and nil is returned.
-// - If there is only one include block, no param is required and that is 
automatically returned.
-// - If there is more than one include block, 1 param is required to use as 
the label name to lookup the include block
-//   to use.
+//   - If the Original attribute is set, we are in the parent context so 
return that.
+//   - If there are no include blocks, no param is required and nil is 
returned.
+//   - If there is only one include block, no param is required and that is 
automatically returned.
+//   - If there is more than one include block, 1 param is required to use as 
the label name to lookup the include block
+//     to use.
 func getSelectedIncludeBlock(trackInclude TrackInclude, params []string) 
(*IncludeConfig, error) {
        importMap := trackInclude.CurrentMap
 
@@ -791,6 +789,32 @@
        return false, nil
 }
 
+// timeCmp implements Terraform's `timecmp` function that compares two 
timestamps.
+func timeCmp(args []string, trackInclude *TrackInclude, terragruntOptions 
*options.TerragruntOptions) (int64, error) {
+       if len(args) != 2 {
+               return 0, errors.WithStackTrace(fmt.Errorf("function can take 
only two parameters: timestamp_a and timestamp_b"))
+       }
+
+       tsA, err := util.ParseTimestamp(args[0])
+       if err != nil {
+               return 0, errors.WithStackTrace(fmt.Errorf("could not parse 
first parameter %q: %w", args[0], err))
+       }
+       tsB, err := util.ParseTimestamp(args[1])
+       if err != nil {
+               return 0, errors.WithStackTrace(fmt.Errorf("could not parse 
second parameter %q: %w", args[1], err))
+       }
+
+       switch {
+       case tsA.Equal(tsB):
+               return 0, nil
+       case tsA.Before(tsB):
+               return -1, nil
+       default:
+               // By elimination, tsA must be after tsB.
+               return 1, nil
+       }
+}
+
 // Custom error types
 type WrongNumberOfParams struct {
        Func     string
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/terragrunt-0.45.11/config/config_helpers_test.go 
new/terragrunt-0.45.13/config/config_helpers_test.go
--- old/terragrunt-0.45.11/config/config_helpers_test.go        2023-05-10 
20:59:43.000000000 +0200
+++ new/terragrunt-0.45.13/config/config_helpers_test.go        2023-05-17 
18:49:48.000000000 +0200
@@ -1055,6 +1055,43 @@
        }
 }
 
+func TestTimeCmp(t *testing.T) {
+       t.Parallel()
+
+       testCases := []struct {
+               config *options.TerragruntOptions
+               args   []string
+               value  int64
+               err    string
+       }{
+               {terragruntOptionsForTest(t, ""), 
[]string{"2017-11-22T00:00:00Z", "2017-11-22T00:00:00Z"}, 0, ""},
+               {terragruntOptionsForTest(t, ""), 
[]string{"2017-11-22T00:00:00Z", "2017-11-22T01:00:00+01:00"}, 0, ""},
+               {terragruntOptionsForTest(t, ""), 
[]string{"2017-11-22T00:00:01Z", "2017-11-22T01:00:00+01:00"}, 1, ""},
+               {terragruntOptionsForTest(t, ""), 
[]string{"2017-11-22T01:00:00Z", "2017-11-22T00:59:00-01:00"}, -1, ""},
+               {terragruntOptionsForTest(t, ""), 
[]string{"2017-11-22T01:00:00+01:00", "2017-11-22T01:00:00-01:00"}, -1, ""},
+               {terragruntOptionsForTest(t, ""), 
[]string{"2017-11-22T01:00:00-01:00", "2017-11-22T01:00:00+01:00"}, 1, ""},
+               {terragruntOptionsForTest(t, ""), 
[]string{"2017-11-22T00:00:00Z", "bloop"}, 0, `could not parse second parameter 
"bloop": not a valid RFC3339 timestamp: cannot use "bloop" as year`},
+               {terragruntOptionsForTest(t, ""), []string{"2017-11-22 
00:00:00Z", "2017-11-22T00:00:00Z"}, 0, `could not parse first parameter 
"2017-11-22 00:00:00Z": not a valid RFC3339 timestamp: missing required time 
introducer 'T'`},
+       }
+
+       for _, testCase := range testCases {
+               testCase := testCase
+
+               t.Run(fmt.Sprintf("TimeCmp(%#v, %#v)", testCase.args[0], 
testCase.args[1]), func(t *testing.T) {
+                       t.Parallel()
+
+                       actual, err := timeCmp(testCase.args, nil, 
testCase.config)
+                       if testCase.err != "" {
+                               assert.EqualError(t, err, testCase.err)
+                       } else {
+                               assert.NoError(t, err)
+                       }
+
+                       assert.Equal(t, testCase.value, actual)
+               })
+       }
+}
+
 func mockConfigWithSource(sourceUrl string) *TerragruntConfig {
        cfg := TerragruntConfig{IsPartial: true}
        cfg.Terraform = &TerraformConfig{Source: &sourceUrl}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/terragrunt-0.45.11/config/cty_helpers.go 
new/terragrunt-0.45.13/config/cty_helpers.go
--- old/terragrunt-0.45.11/config/cty_helpers.go        2023-05-10 
20:59:43.000000000 +0200
+++ new/terragrunt-0.45.13/config/cty_helpers.go        2023-05-17 
18:49:48.000000000 +0200
@@ -38,6 +38,28 @@
        })
 }
 
+func wrapStringSliceToNumberAsFuncImpl(
+       toWrap func(params []string, trackInclude *TrackInclude, 
terragruntOptions *options.TerragruntOptions) (int64, error),
+       trackInclude *TrackInclude,
+       terragruntOptions *options.TerragruntOptions,
+) function.Function {
+       return function.New(&function.Spec{
+               VarParam: &function.Parameter{Type: cty.String},
+               Type:     function.StaticReturnType(cty.Number),
+               Impl: func(args []cty.Value, retType cty.Type) (cty.Value, 
error) {
+                       params, err := ctySliceToStringSlice(args)
+                       if err != nil {
+                               return cty.StringVal(""), err
+                       }
+                       out, err := toWrap(params, trackInclude, 
terragruntOptions)
+                       if err != nil {
+                               return cty.NumberIntVal(0), err
+                       }
+                       return cty.NumberIntVal(out), nil
+               },
+       })
+}
+
 func wrapStringSliceToBoolAsFuncImpl(
        toWrap func(params []string, trackInclude *TrackInclude, 
terragruntOptions *options.TerragruntOptions) (bool, error),
        trackInclude *TrackInclude,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/terragrunt-0.45.11/config/dependency.go 
new/terragrunt-0.45.13/config/dependency.go
--- old/terragrunt-0.45.11/config/dependency.go 2023-05-10 20:59:43.000000000 
+0200
+++ new/terragrunt-0.45.13/config/dependency.go 2023-05-17 18:49:48.000000000 
+0200
@@ -654,6 +654,7 @@
 // To do this, this function will:
 // - Create a temporary folder
 // - Generate the backend.tf file with the backend configuration from the 
remote_state block
+// - Copy the provider lock file, if there is one in the dependency's working 
directory
 // - Run terraform init and terraform output
 // - Clean up folder once json file is generated
 // NOTE: terragruntOptions should be in the context of the targetConfig 
already.
@@ -713,6 +714,12 @@
        }
        terragruntOptions.Logger.Debugf("Generated remote state configuration 
in working dir %s", tempWorkDir)
 
+       // Check for a provider lock file and copy it to the working dir if it 
exists.
+       terragruntDir := filepath.Dir(terragruntOptions.TerragruntConfigPath)
+       if err := util.CopyLockFile(terragruntDir, tempWorkDir, 
terragruntOptions.Logger); err != nil {
+               return nil, err
+       }
+
        // The working directory is now set up to interact with the state, so 
pull it down to get the json output.
 
        // First run init to setup the backend configuration so that we can run 
output.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/terragrunt-0.45.11/docs/_docs/02_features/aws-auth.md 
new/terragrunt-0.45.13/docs/_docs/02_features/aws-auth.md
--- old/terragrunt-0.45.11/docs/_docs/02_features/aws-auth.md   2023-05-10 
20:59:43.000000000 +0200
+++ new/terragrunt-0.45.13/docs/_docs/02_features/aws-auth.md   2023-05-17 
18:49:48.000000000 +0200
@@ -76,7 +76,8 @@
                 "s3:GetEncryptionConfiguration",
                 "s3:GetBucketPolicy",
                 "s3:GetBucketPublicAccessBlock",
-                "s3:PutLifecycleConfiguration"
+                "s3:PutLifecycleConfiguration",
+                "s3:PutBucketOwnershipControls"
             ],
             "Resource": "arn:aws:s3:::BUCKET_NAME"
         },
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/terragrunt-0.45.11/test/fixture-timecmp/main.tf 
new/terragrunt-0.45.13/test/fixture-timecmp/main.tf
--- old/terragrunt-0.45.11/test/fixture-timecmp/main.tf 1970-01-01 
01:00:00.000000000 +0100
+++ new/terragrunt-0.45.13/test/fixture-timecmp/main.tf 2023-05-17 
18:49:48.000000000 +0200
@@ -0,0 +1,47 @@
+variable "timecmp1" {
+  type = number
+}
+
+variable "timecmp2" {
+  type = number
+}
+
+variable "timecmp3" {
+  type = number
+}
+
+variable "timecmp4" {
+  type = number
+}
+
+variable "timecmp5" {
+  type = number
+}
+
+variable "timecmp6" {
+  type = number
+}
+
+output "timecmp1" {
+  value = var.timecmp1
+}
+
+output "timecmp2" {
+  value = var.timecmp2
+}
+
+output "timecmp3" {
+  value = var.timecmp3
+}
+
+output "timecmp4" {
+  value = var.timecmp4
+}
+
+output "timecmp5" {
+  value = var.timecmp5
+}
+
+output "timecmp6" {
+  value = var.timecmp6
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/terragrunt-0.45.11/test/fixture-timecmp/terragrunt.hcl 
new/terragrunt-0.45.13/test/fixture-timecmp/terragrunt.hcl
--- old/terragrunt-0.45.11/test/fixture-timecmp/terragrunt.hcl  1970-01-01 
01:00:00.000000000 +0100
+++ new/terragrunt-0.45.13/test/fixture-timecmp/terragrunt.hcl  2023-05-17 
18:49:48.000000000 +0200
@@ -0,0 +1,8 @@
+inputs = {
+  timecmp1 = timecmp("2017-11-22T00:00:00Z", "2017-11-22T00:00:00Z")
+  timecmp2 = timecmp("2017-11-22T00:00:00Z", "2017-11-22T01:00:00+01:00")
+  timecmp3 = timecmp("2017-11-22T00:00:01Z", "2017-11-22T01:00:00+01:00")
+  timecmp4 = timecmp("2017-11-22T01:00:00Z", "2017-11-22T00:59:00-01:00")
+  timecmp5 = timecmp("2017-11-22T01:00:00+01:00", "2017-11-22T01:00:00-01:00")
+  timecmp6 = timecmp("2017-11-22T01:00:00-01:00", "2017-11-22T01:00:00+01:00")
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/terragrunt-0.45.11/test/fixture-timecmp-errors/invalid-timestamp/main.tf 
new/terragrunt-0.45.13/test/fixture-timecmp-errors/invalid-timestamp/main.tf
--- 
old/terragrunt-0.45.11/test/fixture-timecmp-errors/invalid-timestamp/main.tf    
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/terragrunt-0.45.13/test/fixture-timecmp-errors/invalid-timestamp/main.tf    
    2023-05-17 18:49:48.000000000 +0200
@@ -0,0 +1,7 @@
+variable "timecmp1" {
+  type = number
+}
+
+output "timecmp1" {
+  value = var.timecmp1
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/terragrunt-0.45.11/test/fixture-timecmp-errors/invalid-timestamp/terragrunt.hcl
 
new/terragrunt-0.45.13/test/fixture-timecmp-errors/invalid-timestamp/terragrunt.hcl
--- 
old/terragrunt-0.45.11/test/fixture-timecmp-errors/invalid-timestamp/terragrunt.hcl
 1970-01-01 01:00:00.000000000 +0100
+++ 
new/terragrunt-0.45.13/test/fixture-timecmp-errors/invalid-timestamp/terragrunt.hcl
 2023-05-17 18:49:48.000000000 +0200
@@ -0,0 +1,3 @@
+inputs = {
+  timecmp1 = timecmp("2017-11-22 00:00:00Z", "2017-11-22T01:00:00+01:00")
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/terragrunt-0.45.11/test/integration_test.go 
new/terragrunt-0.45.13/test/integration_test.go
--- old/terragrunt-0.45.11/test/integration_test.go     2023-05-10 
20:59:43.000000000 +0200
+++ new/terragrunt-0.45.13/test/integration_test.go     2023-05-17 
18:49:48.000000000 +0200
@@ -134,6 +134,8 @@
        TEST_FIXTURE_RENDER_JSON_METADATA                       = 
"fixture-render-json-metadata"
        TEST_FIXTURE_RENDER_JSON_MOCK_OUTPUTS                   = 
"fixture-render-json-mock-outputs"
        TEST_FIXTURE_STARTSWITH                                 = 
"fixture-startswith"
+       TEST_FIXTURE_TIMECMP                                    = 
"fixture-timecmp"
+       TEST_FIXTURE_TIMECMP_INVALID_TIMESTAMP                  = 
"fixture-timecmp-errors/invalid-timestamp"
        TEST_FIXTURE_ENDSWITH                                   = 
"fixture-endswith"
        TEST_FIXTURE_TFLINT_NO_ISSUES_FOUND                     = 
"fixture-tflint/no-issues-found"
        TEST_FIXTURE_TFLINT_ISSUES_FOUND                        = 
"fixture-tflint/issues-found"
@@ -5169,15 +5171,62 @@
 
        require.NoError(t, json.Unmarshal([]byte(stdout.String()), &outputs))
 
-       validateBoolOutput(t, outputs, "startswith1", true)
-       validateBoolOutput(t, outputs, "startswith2", false)
-       validateBoolOutput(t, outputs, "startswith3", true)
-       validateBoolOutput(t, outputs, "startswith4", false)
-       validateBoolOutput(t, outputs, "startswith5", true)
-       validateBoolOutput(t, outputs, "startswith6", false)
-       validateBoolOutput(t, outputs, "startswith7", true)
-       validateBoolOutput(t, outputs, "startswith8", false)
-       validateBoolOutput(t, outputs, "startswith9", false)
+       validateOutput(t, outputs, "startswith1", true)
+       validateOutput(t, outputs, "startswith2", false)
+       validateOutput(t, outputs, "startswith3", true)
+       validateOutput(t, outputs, "startswith4", false)
+       validateOutput(t, outputs, "startswith5", true)
+       validateOutput(t, outputs, "startswith6", false)
+       validateOutput(t, outputs, "startswith7", true)
+       validateOutput(t, outputs, "startswith8", false)
+       validateOutput(t, outputs, "startswith9", false)
+}
+
+func TestTimeCmp(t *testing.T) {
+       t.Parallel()
+
+       cleanupTerraformFolder(t, TEST_FIXTURE_TIMECMP)
+       tmpEnvPath := copyEnvironment(t, TEST_FIXTURE_TIMECMP)
+       rootPath := util.JoinPath(tmpEnvPath, TEST_FIXTURE_TIMECMP)
+
+       runTerragrunt(t, fmt.Sprintf("terragrunt apply-all 
--terragrunt-non-interactive --terragrunt-working-dir %s", rootPath))
+
+       // verify expected outputs are not empty
+       stdout := bytes.Buffer{}
+       stderr := bytes.Buffer{}
+
+       require.NoError(
+               t,
+               runTerragruntCommand(t, fmt.Sprintf("terragrunt output 
-no-color -json --terragrunt-non-interactive --terragrunt-working-dir %s", 
rootPath), &stdout, &stderr),
+       )
+
+       outputs := map[string]TerraformOutput{}
+
+       require.NoError(t, json.Unmarshal([]byte(stdout.String()), &outputs))
+
+       validateOutput(t, outputs, "timecmp1", float64(0))
+       validateOutput(t, outputs, "timecmp2", float64(0))
+       validateOutput(t, outputs, "timecmp3", float64(1))
+       validateOutput(t, outputs, "timecmp4", float64(-1))
+       validateOutput(t, outputs, "timecmp5", float64(-1))
+       validateOutput(t, outputs, "timecmp6", float64(1))
+}
+
+func TestTimeCmpInvalidTimestamp(t *testing.T) {
+       t.Parallel()
+
+       cleanupTerraformFolder(t, TEST_FIXTURE_TIMECMP_INVALID_TIMESTAMP)
+       tmpEnvPath := copyEnvironment(t, TEST_FIXTURE_TIMECMP_INVALID_TIMESTAMP)
+       rootPath := util.JoinPath(tmpEnvPath, 
TEST_FIXTURE_TIMECMP_INVALID_TIMESTAMP)
+
+       // verify expected outputs are not empty
+       stdout := bytes.Buffer{}
+       stderr := bytes.Buffer{}
+
+       err := runTerragruntCommand(t, fmt.Sprintf("terragrunt apply 
--terragrunt-non-interactive --terragrunt-working-dir %s", rootPath), &stdout, 
&stderr)
+
+       expectedError := `not a valid RFC3339 timestamp: missing required time 
introducer 'T'`
+       require.ErrorContains(t, err, expectedError)
 }
 
 func TestEndsWith(t *testing.T) {
@@ -5202,15 +5251,15 @@
 
        require.NoError(t, json.Unmarshal([]byte(stdout.String()), &outputs))
 
-       validateBoolOutput(t, outputs, "endswith1", true)
-       validateBoolOutput(t, outputs, "endswith2", false)
-       validateBoolOutput(t, outputs, "endswith3", true)
-       validateBoolOutput(t, outputs, "endswith4", false)
-       validateBoolOutput(t, outputs, "endswith5", true)
-       validateBoolOutput(t, outputs, "endswith6", false)
-       validateBoolOutput(t, outputs, "endswith7", true)
-       validateBoolOutput(t, outputs, "endswith8", false)
-       validateBoolOutput(t, outputs, "endswith9", false)
+       validateOutput(t, outputs, "endswith1", true)
+       validateOutput(t, outputs, "endswith2", false)
+       validateOutput(t, outputs, "endswith3", true)
+       validateOutput(t, outputs, "endswith4", false)
+       validateOutput(t, outputs, "endswith5", true)
+       validateOutput(t, outputs, "endswith6", false)
+       validateOutput(t, outputs, "endswith7", true)
+       validateOutput(t, outputs, "endswith8", false)
+       validateOutput(t, outputs, "endswith9", false)
 }
 
 func TestMockOutputsMergeWithState(t *testing.T) {
@@ -5319,7 +5368,7 @@
        assert.Contains(t, explanation, "Check your credentials and 
permissions")
 }
 
-func validateBoolOutput(t *testing.T, outputs map[string]TerraformOutput, key 
string, value bool) {
+func validateOutput(t *testing.T, outputs map[string]TerraformOutput, key 
string, value interface{}) {
        t.Helper()
        output, hasPlatform := outputs[key]
        require.Truef(t, hasPlatform, "Expected output %s to be defined", key)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/terragrunt-0.45.11/util/datetime.go 
new/terragrunt-0.45.13/util/datetime.go
--- old/terragrunt-0.45.11/util/datetime.go     1970-01-01 01:00:00.000000000 
+0100
+++ new/terragrunt-0.45.13/util/datetime.go     2023-05-17 18:49:48.000000000 
+0200
@@ -0,0 +1,67 @@
+package util
+
+import (
+       "fmt"
+       "time"
+)
+
+func ParseTimestamp(ts string) (time.Time, error) {
+       t, err := time.Parse(time.RFC3339, ts)
+       if err != nil {
+               switch err := err.(type) {
+               case *time.ParseError:
+                       // If err is a time.ParseError then its string 
representation is not
+                       // appropriate since it relies on details of Go's 
strange date format
+                       // representation, which a caller of our functions is 
not expected
+                       // to be familiar with.
+                       //
+                       // Therefore we do some light transformation to get a 
more suitable
+                       // error that should make more sense to our callers. 
These are
+                       // still not awesome error messages, but at least they 
refer to
+                       // the timestamp portions by name rather than by Go's 
example
+                       // values.
+                       if err.LayoutElem == "" && err.ValueElem == "" && 
err.Message != "" {
+                               // For some reason err.Message is populated 
with a ": " prefix
+                               // by the time package.
+                               return time.Time{}, fmt.Errorf("not a valid 
RFC3339 timestamp%s", err.Message)
+                       }
+                       var what string
+                       switch err.LayoutElem {
+                       case "2006":
+                               what = "year"
+                       case "01":
+                               what = "month"
+                       case "02":
+                               what = "day of month"
+                       case "15":
+                               what = "hour"
+                       case "04":
+                               what = "minute"
+                       case "05":
+                               what = "second"
+                       case "Z07:00":
+                               what = "UTC offset"
+                       case "T":
+                               return time.Time{}, fmt.Errorf("not a valid 
RFC3339 timestamp: missing required time introducer 'T'")
+                       case ":", "-":
+                               if err.ValueElem == "" {
+                                       return time.Time{}, fmt.Errorf("not a 
valid RFC3339 timestamp: end of string where %q is expected", err.LayoutElem)
+                               } else {
+                                       return time.Time{}, fmt.Errorf("not a 
valid RFC3339 timestamp: found %q where %q is expected", err.ValueElem, 
err.LayoutElem)
+                               }
+                       default:
+                               // Should never get here, because time.RFC3339 
includes only the
+                               // above portions, but since that might change 
in future we'll
+                               // be robust here.
+                               what = "timestamp segment"
+                       }
+                       if err.ValueElem == "" {
+                               return time.Time{}, fmt.Errorf("not a valid 
RFC3339 timestamp: end of string before %s", what)
+                       } else {
+                               return time.Time{}, fmt.Errorf("not a valid 
RFC3339 timestamp: cannot use %q as %s", err.ValueElem, what)
+                       }
+               }
+               return time.Time{}, err
+       }
+       return t, nil
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/terragrunt-0.45.11/util/datetime_test.go 
new/terragrunt-0.45.13/util/datetime_test.go
--- old/terragrunt-0.45.11/util/datetime_test.go        1970-01-01 
01:00:00.000000000 +0100
+++ new/terragrunt-0.45.13/util/datetime_test.go        2023-05-17 
18:49:48.000000000 +0200
@@ -0,0 +1,41 @@
+package util
+
+import (
+       "fmt"
+       "testing"
+       "time"
+
+       "github.com/stretchr/testify/assert"
+)
+
+func TestParseTimestamp(t *testing.T) {
+       t.Parallel()
+
+       testCases := []struct {
+               arg   string
+               value time.Time
+               err   string
+       }{
+               {"2017-11-22T00:00:00Z", time.Date(2017, time.Month(11), 22, 0, 
0, 0, 0, time.UTC), ""},
+               {"2017-11-22T01:00:00+01:00", time.Date(2017, time.Month(11), 
22, 1, 0, 0, 0, time.FixedZone("", 3600)), ""},
+               {"bloop", time.Time{}, `not a valid RFC3339 timestamp: cannot 
use "bloop" as year`},
+               {"2017-11-22 00:00:00Z", time.Time{}, `not a valid RFC3339 
timestamp: missing required time introducer 'T'`},
+       }
+
+       for _, testCase := range testCases {
+               testCase := testCase
+
+               t.Run(fmt.Sprintf("ParseTimestamp(%#v)", testCase.arg), func(t 
*testing.T) {
+                       t.Parallel()
+
+                       actual, err := ParseTimestamp(testCase.arg)
+                       if testCase.err != "" {
+                               assert.EqualError(t, err, testCase.err)
+                       } else {
+                               assert.NoError(t, err)
+                       }
+
+                       assert.Equal(t, testCase.value, actual)
+               })
+       }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/terragrunt-0.45.11/util/file.go 
new/terragrunt-0.45.13/util/file.go
--- old/terragrunt-0.45.11/util/file.go 2023-05-10 20:59:43.000000000 +0200
+++ new/terragrunt-0.45.13/util/file.go 2023-05-17 18:49:48.000000000 +0200
@@ -14,6 +14,7 @@
        "github.com/gruntwork-io/terragrunt/errors"
        "github.com/mattn/go-zglob"
        homedir "github.com/mitchellh/go-homedir"
+       "github.com/sirupsen/logrus"
 )
 
 const TerraformLockFile = ".terraform.lock.hcl"
@@ -511,3 +512,17 @@
 func (err PathIsNotFile) Error() string {
        return fmt.Sprintf("%s is not a file", err.path)
 }
+
+// Terraform 0.14 now generates a lock file when you run `terraform init`.
+// If any such file exists, this function will copy the lock file to the 
destination folder
+func CopyLockFile(sourceFolder string, destinationFolder string, logger 
*logrus.Entry) error {
+       sourceLockFilePath := JoinPath(sourceFolder, TerraformLockFile)
+       destinationLockFilePath := JoinPath(destinationFolder, 
TerraformLockFile)
+
+       if FileExists(sourceLockFilePath) {
+               logger.Debugf("Copying lock file from %s to %s", 
sourceLockFilePath, destinationFolder)
+               return CopyFile(sourceLockFilePath, destinationLockFilePath)
+       }
+
+       return nil
+}

++++++ terragrunt.obsinfo ++++++
--- /var/tmp/diff_new_pack.XMjAYy/_old  2023-05-18 15:19:42.645995950 +0200
+++ /var/tmp/diff_new_pack.XMjAYy/_new  2023-05-18 15:19:42.645995950 +0200
@@ -1,5 +1,5 @@
 name: terragrunt
-version: 0.45.11
-mtime: 1683745183
-commit: fcfb391b5be91c67e9c0fb66ce41a4cc507c6c53
+version: 0.45.13
+mtime: 1684342188
+commit: 9015f781c2ffae79d8bace26e45ca20b86b99bbb
 

++++++ vendor.tar.gz ++++++
/work/SRC/openSUSE:Factory/terragrunt/vendor.tar.gz 
/work/SRC/openSUSE:Factory/.terragrunt.new.1533/vendor.tar.gz differ: char 5, 
line 1

Reply via email to