From b66b738a24582eb8ef42177d2fc528dacdfdc925 Mon Sep 17 00:00:00 2001 From: Suha Can Date: Mon, 14 Feb 2011 14:00:48 -0800 Subject: [PATCH] More work for various recipe handlers. --HG-- branch : recipe --- .../Sample1/Recipes/cms.recipe.xml | 6 +-- .../CleanUpInactiveRecipeHandler.cs | 12 ++++- .../RecipeHandlers/CommandRecipeHandler.cs | 25 ++++++++++- .../RecipeHandlers/FeatureRecipeHandler.cs | 38 +++++++++++++++- .../RecipeHandlers/MetaDataRecipeHandler.cs | 37 +++++++++++++++- .../RecipeHandlers/MigrationRecipeHandler.cs | 35 ++++++++++++++- .../RecipeHandlers/ModuleRecipeHandler.cs | 38 +++++++++++++++- .../RecipeHandlers/SettingsRecipeHandler.cs | 22 ++++++++-- .../RecipeHandlers/ThemeRecipeHandler.cs | 44 ++++++++++++++++++- .../Orchard.Recipes/Services/RecipeManager.cs | 3 ++ .../Orchard.Setup/Services/SetupService.cs | 3 ++ 11 files changed, 242 insertions(+), 21 deletions(-) diff --git a/src/Orchard.Tests.Modules/Recipes/Services/FoldersData/Sample1/Recipes/cms.recipe.xml b/src/Orchard.Tests.Modules/Recipes/Services/FoldersData/Sample1/Recipes/cms.recipe.xml index 60a780329..28153f635 100644 --- a/src/Orchard.Tests.Modules/Recipes/Services/FoldersData/Sample1/Recipes/cms.recipe.xml +++ b/src/Orchard.Tests.Modules/Recipes/Services/FoldersData/Sample1/Recipes/cms.recipe.xml @@ -10,7 +10,7 @@ - + @@ -23,8 +23,6 @@ - - @@ -38,7 +36,7 @@ - + diff --git a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/CleanUpInactiveRecipeHandler.cs b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/CleanUpInactiveRecipeHandler.cs index c779ddae8..f84472138 100644 --- a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/CleanUpInactiveRecipeHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/CleanUpInactiveRecipeHandler.cs @@ -1,4 +1,5 @@ -using Orchard.Localization; +using System; +using Orchard.Localization; using Orchard.Logging; using Orchard.Recipes.Models; using Orchard.Recipes.Services; @@ -13,8 +14,15 @@ namespace Orchard.Recipes.RecipeHandlers { public Localizer T { get; set; } ILogger Logger { get; set; } - // handles the step + // + // Delete inactive modules and themes. public void ExecuteRecipeStep(RecipeContext recipeContext) { + if (!String.Equals(recipeContext.RecipeStep.Name, "CleanUpInactive", StringComparison.OrdinalIgnoreCase)) { + return; + } + + // remove modules and themes. + recipeContext.Executed = true; } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/CommandRecipeHandler.cs b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/CommandRecipeHandler.cs index 4df974d79..a86a2e73f 100644 --- a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/CommandRecipeHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/CommandRecipeHandler.cs @@ -1,4 +1,7 @@ -using Orchard.Localization; +using System; +using System.Collections.Generic; +using System.Linq; +using Orchard.Localization; using Orchard.Logging; using Orchard.Recipes.Models; using Orchard.Recipes.Services; @@ -13,8 +16,26 @@ namespace Orchard.Recipes.RecipeHandlers { public Localizer T { get; set; } ILogger Logger { get; set; } - // handles the step + /* + + command1 + command2 + command3 + + */ + // run Orchard commands. public void ExecuteRecipeStep(RecipeContext recipeContext) { + if (!String.Equals(recipeContext.RecipeStep.Name, "Command", StringComparison.OrdinalIgnoreCase)) { + return; + } + + var commands = + recipeContext.RecipeStep.Step.Value + .Split(new[] {"\r\n", "\n"}, StringSplitOptions.RemoveEmptyEntries) + .Select(commandEntry => commandEntry.Trim()); + + // run commands. + recipeContext.Executed = true; } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/FeatureRecipeHandler.cs b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/FeatureRecipeHandler.cs index 47d899c62..218992c16 100644 --- a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/FeatureRecipeHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/FeatureRecipeHandler.cs @@ -1,4 +1,7 @@ -using Orchard.Localization; +using System; +using System.Collections.Generic; +using System.Linq; +using Orchard.Localization; using Orchard.Logging; using Orchard.Recipes.Models; using Orchard.Recipes.Services; @@ -13,8 +16,39 @@ namespace Orchard.Recipes.RecipeHandlers { public Localizer T { get; set; } ILogger Logger { get; set; } - // handles the step + // + // Enable/Disable features. public void ExecuteRecipeStep(RecipeContext recipeContext) { + if (!String.Equals(recipeContext.RecipeStep.Name, "Feature", StringComparison.OrdinalIgnoreCase)) { + return; + } + + var featuresToEnable = new List(); + var featuresToDisable = new List(); + foreach (var attribute in recipeContext.RecipeStep.Step.Attributes()) { + if (String.Equals(attribute.Name.LocalName, "disable", StringComparison.OrdinalIgnoreCase)) { + featuresToDisable = ParseFeatures(attribute.Value); + } + else if (String.Equals(attribute.Name.LocalName, "enable", StringComparison.OrdinalIgnoreCase)) { + featuresToEnable = ParseFeatures(attribute.Value); + } + else { + Logger.Error("Unrecognized attribute {0} encountered in step Feature. Skipping.", attribute.Name.LocalName); + } + } + + // if both, tx and disable happens first. + // force cascading enabling and disabling. + // run migrations. + + recipeContext.Executed = true; + } + + private static List ParseFeatures(string csv) { + return csv.Split(',') + .Select(value => value.Trim()) + .Where(sanitizedValue => !String.IsNullOrEmpty(sanitizedValue)) + .ToList(); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/MetaDataRecipeHandler.cs b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/MetaDataRecipeHandler.cs index 29c59faf2..ec48b039b 100644 --- a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/MetaDataRecipeHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/MetaDataRecipeHandler.cs @@ -1,4 +1,5 @@ -using Orchard.Localization; +using System; +using Orchard.Localization; using Orchard.Logging; using Orchard.Recipes.Models; using Orchard.Recipes.Services; @@ -13,8 +14,40 @@ namespace Orchard.Recipes.RecipeHandlers { public Localizer T { get; set; } ILogger Logger { get; set; } - // handles the step + /* + + + + + + + + + + */ + // Set type settings and attach parts to types. + // Create dynamic parts. public void ExecuteRecipeStep(RecipeContext recipeContext) { + if (!String.Equals(recipeContext.RecipeStep.Name, "Metadata", StringComparison.OrdinalIgnoreCase)) { + return; + } + + foreach (var element in recipeContext.RecipeStep.Step.Elements()) { + switch (element.Name.LocalName) { + case "Types": + // alter type's definition. + break; + case "Parts": + // create dynamic part. + break; + default: + Logger.Error("Unrecognized element {0} encountered in step Metadata. Skipping.", element.Name.LocalName); + break; + } + } + + // alter definitions. + recipeContext.Executed = true; } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/MigrationRecipeHandler.cs b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/MigrationRecipeHandler.cs index c5bed473a..7927a466b 100644 --- a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/MigrationRecipeHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/MigrationRecipeHandler.cs @@ -1,4 +1,7 @@ -using Orchard.Localization; +using System; +using System.Collections.Generic; +using System.Linq; +using Orchard.Localization; using Orchard.Logging; using Orchard.Recipes.Models; using Orchard.Recipes.Services; @@ -13,8 +16,36 @@ namespace Orchard.Recipes.RecipeHandlers { public Localizer T { get; set; } ILogger Logger { get; set; } - // handles the step + // + // + // Run migration for features. public void ExecuteRecipeStep(RecipeContext recipeContext) { + if (!String.Equals(recipeContext.RecipeStep.Name, "Migration", StringComparison.OrdinalIgnoreCase)) { + return; + } + + bool runAll = false; + var features = new List(); + foreach (var attribute in recipeContext.RecipeStep.Step.Attributes()) { + if (String.Equals(attribute.Name.LocalName, "features", StringComparison.OrdinalIgnoreCase)) { + features = ParseFeatures(attribute.Value); + if (features.Contains("*")) + runAll = true; + } + else { + Logger.Error("Unrecognized attribute {0} encountered in step Migration. Skipping.", attribute.Name.LocalName); + } + } + + // run migrations + recipeContext.Executed = true; + } + + private static List ParseFeatures(string csv) { + return csv.Split(',') + .Select(value => value.Trim()) + .Where(sanitizedValue => !String.IsNullOrEmpty(sanitizedValue)) + .ToList(); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/ModuleRecipeHandler.cs b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/ModuleRecipeHandler.cs index 0c39ac604..64c5b537e 100644 --- a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/ModuleRecipeHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/ModuleRecipeHandler.cs @@ -1,4 +1,5 @@ -using Orchard.Localization; +using System; +using Orchard.Localization; using Orchard.Logging; using Orchard.Recipes.Models; using Orchard.Recipes.Services; @@ -13,8 +14,41 @@ namespace Orchard.Recipes.RecipeHandlers { public Localizer T { get; set; } ILogger Logger { get; set; } - // handles the step + // + // + // install modules from url or feed. public void ExecuteRecipeStep(RecipeContext recipeContext) { + if (!String.Equals(recipeContext.RecipeStep.Name, "Module", StringComparison.OrdinalIgnoreCase)) { + return; + } + + bool replace; + string source, name, version, repository; + + foreach (var attribute in recipeContext.RecipeStep.Step.Attributes()) { + if (String.Equals(attribute.Name.LocalName, "src", StringComparison.OrdinalIgnoreCase)) { + source = attribute.Value; + } + else if (String.Equals(attribute.Name.LocalName, "replace", StringComparison.OrdinalIgnoreCase)) { + replace = attribute.Value == "true"; + } + else if (String.Equals(attribute.Name.LocalName, "name", StringComparison.OrdinalIgnoreCase)) { + name = attribute.Value; + } + else if (String.Equals(attribute.Name.LocalName, "version", StringComparison.OrdinalIgnoreCase)) { + version = attribute.Value; + } + else if (String.Equals(attribute.Name.LocalName, "repository", StringComparison.OrdinalIgnoreCase)) { + repository = attribute.Value; + } + else { + Logger.Error("Unrecognized attribute {0} encountered in step Module. Skipping.", attribute.Name.LocalName); + } + } + + // download and install module. + + recipeContext.Executed = true; } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/SettingsRecipeHandler.cs b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/SettingsRecipeHandler.cs index 37dc5f435..60616ef98 100644 --- a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/SettingsRecipeHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/SettingsRecipeHandler.cs @@ -1,4 +1,5 @@ -using Orchard.Localization; +using System; +using Orchard.Localization; using Orchard.Logging; using Orchard.Recipes.Models; using Orchard.Recipes.Services; @@ -13,8 +14,23 @@ namespace Orchard.Recipes.RecipeHandlers { public Localizer T { get; set; } ILogger Logger { get; set; } - // handles the step + /* + + + + + */ + // Set site and part settings. public void ExecuteRecipeStep(RecipeContext recipeContext) { + if (!String.Equals(recipeContext.RecipeStep.Name, "Settings", StringComparison.OrdinalIgnoreCase)) { + return; + } + + foreach (var element in recipeContext.RecipeStep.Step.Elements()) { + // set part settings. + } + + recipeContext.Executed = true; } } -} \ No newline at end of file +} diff --git a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/ThemeRecipeHandler.cs b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/ThemeRecipeHandler.cs index 8686cdb20..427a413fa 100644 --- a/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/ThemeRecipeHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Recipes/RecipeHandlers/ThemeRecipeHandler.cs @@ -1,4 +1,5 @@ -using Orchard.Localization; +using System; +using Orchard.Localization; using Orchard.Logging; using Orchard.Recipes.Models; using Orchard.Recipes.Services; @@ -13,8 +14,47 @@ namespace Orchard.Recipes.RecipeHandlers { public Localizer T { get; set; } ILogger Logger { get; set; } - // handles the step + // + // install themes from url or feed. public void ExecuteRecipeStep(RecipeContext recipeContext) { + if (!String.Equals(recipeContext.RecipeStep.Name, "Theme", StringComparison.OrdinalIgnoreCase)) { + return; + } + + bool replace, enabled, current; + string source, name, version, repository; + + foreach (var attribute in recipeContext.RecipeStep.Step.Attributes()) { + if (String.Equals(attribute.Name.LocalName, "src", StringComparison.OrdinalIgnoreCase)) { + source = attribute.Value; + } + else if (String.Equals(attribute.Name.LocalName, "replace", StringComparison.OrdinalIgnoreCase)) { + replace = attribute.Value == "true"; + } + else if (String.Equals(attribute.Name.LocalName, "enabled", StringComparison.OrdinalIgnoreCase)) { + enabled = attribute.Value == "true"; + } + else if (String.Equals(attribute.Name.LocalName, "current", StringComparison.OrdinalIgnoreCase)) { + current = attribute.Value == "true"; + } + else if (String.Equals(attribute.Name.LocalName, "name", StringComparison.OrdinalIgnoreCase)) { + name = attribute.Value; + } + else if (String.Equals(attribute.Name.LocalName, "version", StringComparison.OrdinalIgnoreCase)) { + version = attribute.Value; + } + else if (String.Equals(attribute.Name.LocalName, "repository", StringComparison.OrdinalIgnoreCase)) { + repository = attribute.Value; + } + else { + Logger.Error("Unrecognized attribute {0} encountered in step Theme. Skipping.", attribute.Name.LocalName); + } + } + + // download and install theme. + + recipeContext.Executed = true; } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Recipes/Services/RecipeManager.cs b/src/Orchard.Web/Modules/Orchard.Recipes/Services/RecipeManager.cs index da1e4fdba..c1626fe5a 100644 --- a/src/Orchard.Web/Modules/Orchard.Recipes/Services/RecipeManager.cs +++ b/src/Orchard.Web/Modules/Orchard.Recipes/Services/RecipeManager.cs @@ -18,6 +18,9 @@ namespace Orchard.Recipes.Services { ILogger Logger { get; set; } public void Execute(Recipe recipe) { + if (recipe == null) + return; + var recipeContext = new RecipeContext { Recipe = recipe }; // TODO: Run each step inside a transaction boundary. diff --git a/src/Orchard.Web/Modules/Orchard.Setup/Services/SetupService.cs b/src/Orchard.Web/Modules/Orchard.Setup/Services/SetupService.cs index 6108170c9..3d194bbf3 100644 --- a/src/Orchard.Web/Modules/Orchard.Setup/Services/SetupService.cs +++ b/src/Orchard.Web/Modules/Orchard.Setup/Services/SetupService.cs @@ -217,6 +217,9 @@ namespace Orchard.Setup.Services { private void CreateTenantData(SetupContext context, IWorkContextScope environment) { var recipeManager = environment.Resolve(); + if (context.Recipe != null) { + recipeManager.Execute(Recipes().Where(r => r.Name == context.Recipe).FirstOrDefault()); + } // create superuser var membershipService = environment.Resolve();