diff --git a/features/check-recipes.feature b/features/check-recipes.feature index c60616ae..1352e3e5 100644 --- a/features/check-recipes.feature +++ b/features/check-recipes.feature @@ -105,4 +105,18 @@ Feature: Check for new recipe versions Then execution of the recipe has succeeded # Note the lack of explicitly setting the source for the sauce And I check new versions for recipe "foo" - Then CLI produced an output "new versions found: v0.0.2" \ No newline at end of file + Then CLI produced an output "new versions found: v0.0.2" + + Scenario: Manually override the check from URL for locally executed recipe + Given a project directory + And a recipes directory + And a recipe "foo" that generates file "README.md" + And a local OCI registry + When I execute recipe "foo" + Then execution of the recipe has succeeded + When the recipe "foo" is pushed to the local OCI repository "foo:v0.0.1" + And I change recipe "foo" to version "v0.0.2" + And the recipe "foo" is pushed to the local OCI repository "foo:v0.0.2" + And I check new versions for recipe "foo" from the local OCI repository "foo" + Then CLI produced an output "new versions found: v0.0.2" + And the sauce file contains a sauce in index 0 which should have property "from" with value "^oci://localhost:\d+/foo$" \ No newline at end of file diff --git a/features/execute-recipes.feature b/features/execute-recipes.feature index 011aad70..4aaffaf4 100644 --- a/features/execute-recipes.feature +++ b/features/execute-recipes.feature @@ -8,7 +8,7 @@ Feature: Execute recipes When I execute recipe "foo" Then execution of the recipe has succeeded And the project directory should contain file "README.md" - And the sauce file contains a sauce in index 0 which should have property "name" with value "foo" + And the sauce file contains a sauce in index 0 which should have property "name" with value "^foo$" And the sauce file contains a sauce in index 0 which should have property "id" that is a valid UUID Scenario: Execute single recipe from remote registry @@ -34,8 +34,8 @@ Feature: Execute recipes And no errors were printed And the project directory should contain file "README.md" And the project directory should contain file "Taskfile.yml" - And the sauce file contains a sauce in index 0 which should have property "name" with value "foo" - And the sauce file contains a sauce in index 1 which should have property "name" with value "bar" + And the sauce file contains a sauce in index 0 which should have property "name" with value "^foo$" + And the sauce file contains a sauce in index 1 which should have property "name" with value "^bar$" Scenario: New recipe conflicts with the previous recipe Given a project directory diff --git a/internal/cli/check.go b/internal/cli/check.go index e4652011..feae15de 100644 --- a/internal/cli/check.go +++ b/internal/cli/check.go @@ -13,6 +13,7 @@ import ( type checkOptions struct { RecipeName string + CheckFrom string UseDetailedExitCode bool option.Common option.WorkingDirectory @@ -45,10 +46,14 @@ func NewCheckCmd() *cobra.Command { jalapeno check # Check updates for a single recipe -jalapeno check --recipe my-recipe`, +jalapeno check --recipe my-recipe + +# Add check URL for recipe which does not have it yet +jalapeno check --recipe my-recipe --from oci://my-registry.com/my-recipe`, } cmd.Flags().StringVar(&opts.RecipeName, "recipe", "", "Name of the recipe to check for new versions") + cmd.Flags().StringVar(&opts.CheckFrom, "from", "", "Add or override the URL used for checking updates for the recipe. Works only with --recipe flag") cmd.Flags().BoolVar(&opts.UseDetailedExitCode, "detailed-exitcode", false, fmt.Sprintf("Returns a detailed exit code when the command exits. When provided, this argument changes the exit codes and their meanings to provide more granular information about what the resulting plan contains: 0 = Succeeded with no updates available, 1 = Error, %d = Succeeded with updates available", ExitCodeUpdatesAvailable)) if err := option.ApplyFlags(&opts, cmd.Flags()); err != nil { @@ -82,6 +87,16 @@ func runCheck(cmd *cobra.Command, opts checkOptions) error { } sauces = filtered + + if opts.CheckFrom != "" { + for i := range sauces { + // Save new check URL for sauces + sauces[i].CheckFrom = opts.CheckFrom + sauces[i].Save(opts.Dir) + } + } + } else if opts.CheckFrom != "" { + return fmt.Errorf("can not use --from flag without --recipe flag") } cmd.Println("Checking for new versions...") diff --git a/internal/cli/check_test.go b/internal/cli/check_test.go index 184e0424..0aa693e7 100644 --- a/internal/cli/check_test.go +++ b/internal/cli/check_test.go @@ -42,6 +42,17 @@ func iRunCheckForRecipe(ctx context.Context, recipe string) (context.Context, er return iRunCheck(ctx) } +func iRunCheckForRecipeFrom(ctx context.Context, recipe, from string) (context.Context, error) { + ociRegistry := ctx.Value(ociRegistryCtxKey{}).(OCIRegistry) + additionalFlags := ctx.Value(cmdAdditionalFlagsCtxKey{}).(map[string]string) + + additionalFlags["recipe"] = recipe + additionalFlags["from"] = fmt.Sprintf("oci://%s/%s", ociRegistry.Resource.GetHostPort("5000/tcp"), from) + + ctx = context.WithValue(ctx, cmdAdditionalFlagsCtxKey{}, additionalFlags) + return iRunCheck(ctx) +} + func sourceOfTheSauceIsTheLocalOCIRegistry(ctx context.Context, recipeName string) (context.Context, error) { projectDir := ctx.Value(projectDirectoryPathCtxKey{}).(string) ociRegistry := ctx.Value(ociRegistryCtxKey{}).(OCIRegistry) diff --git a/internal/cli/cmds_test.go b/internal/cli/cmds_test.go index b28fabd2..7db5cfed 100644 --- a/internal/cli/cmds_test.go +++ b/internal/cli/cmds_test.go @@ -82,6 +82,7 @@ func TestFeatures(t *testing.T) { s.Step(`^I change recipe "([^"]*)" to version "([^"]*)"$`, iChangeRecipeToVersion) s.Step(`^I check new versions$`, iRunCheck) s.Step(`^I check new versions for recipe "([^"]*)"$`, iRunCheckForRecipe) + s.Step(`^I check new versions for recipe "([^"]*)" from the local OCI repository "([^"]*)"$`, iRunCheckForRecipeFrom) s.Step(`^I upgrade recipe "([^"]*)"$`, iRunUpgrade) s.Step(`^I upgrade recipe from the local OCI repository "([^"]*)"$`, iRunUpgradeFromRemoteRecipe) s.Step(`^I create a recipe with name "([^"]*)"$`, iRunCreate) @@ -383,8 +384,9 @@ func theSauceFileShouldHavePropertyWithValue(ctx context.Context, index int, pro if !exists { return fmt.Errorf("recipe file does not have property %s", propertyName) } - if value != expectedValue { - return fmt.Errorf("expected property %s to have value %s, got %s", propertyName, expectedValue, value) + + if !regexp.MustCompile(expectedValue).MatchString(value) { + return fmt.Errorf("expected property %s to match regex '%s', got '%s'", propertyName, expectedValue, value) } return nil }