mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-21 19:34:40 +08:00
More work for various recipe handlers.
--HG-- branch : recipe
This commit is contained in:
@@ -10,7 +10,7 @@
|
||||
</Recipe>
|
||||
|
||||
<!-- Steps -->
|
||||
<Module src="source directory" replace="false" />
|
||||
<Module src="http://" replace="false" />
|
||||
<Module name="module1" repository="somerepo" version="1.1" replace="true" />
|
||||
|
||||
<Feature disable="f1, f2" enable="f3,f4" />
|
||||
@@ -23,8 +23,6 @@
|
||||
</Types>
|
||||
<Parts>
|
||||
</Parts>
|
||||
<Fields>
|
||||
</Fields>
|
||||
</Metadata>
|
||||
|
||||
<Command>
|
||||
@@ -38,7 +36,7 @@
|
||||
<CommentSettingsPart enableSpamProtection="true" />
|
||||
</Settings>
|
||||
|
||||
<Migration feature="f2"/>
|
||||
<Migration features="f2,f4"/>
|
||||
|
||||
<Theme src="source dir" enabled="true" current="true" />
|
||||
<Theme name="theme1" repository="somerepo" replace="true" />
|
||||
|
@@ -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 <CleanUpInactive> step
|
||||
// <CleanUpInactive />
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -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 <Command> step
|
||||
/*
|
||||
<Command>
|
||||
command1
|
||||
command2
|
||||
command3
|
||||
</Command>
|
||||
*/
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -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 <Feature> step
|
||||
// <Feature enable="f1,f2,f3" disable="f4" />
|
||||
// Enable/Disable features.
|
||||
public void ExecuteRecipeStep(RecipeContext recipeContext) {
|
||||
if (!String.Equals(recipeContext.RecipeStep.Name, "Feature", StringComparison.OrdinalIgnoreCase)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var featuresToEnable = new List<string>();
|
||||
var featuresToDisable = new List<string>();
|
||||
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<string> ParseFeatures(string csv) {
|
||||
return csv.Split(',')
|
||||
.Select(value => value.Trim())
|
||||
.Where(sanitizedValue => !String.IsNullOrEmpty(sanitizedValue))
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
}
|
@@ -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 <Metadata> step
|
||||
/*
|
||||
<Metadata>
|
||||
<Types>
|
||||
<Blog creatable="true">
|
||||
<Body format="abodyformat"/>
|
||||
</Blog>
|
||||
</Types>
|
||||
<Parts>
|
||||
</Parts>
|
||||
</Metadata>
|
||||
*/
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -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 <Migration> step
|
||||
// <Migration features="f1, f2" />
|
||||
// <Migration features="*" />
|
||||
// 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<string>();
|
||||
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<string> ParseFeatures(string csv) {
|
||||
return csv.Split(',')
|
||||
.Select(value => value.Trim())
|
||||
.Where(sanitizedValue => !String.IsNullOrEmpty(sanitizedValue))
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
}
|
@@ -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 <Module> step
|
||||
// <Module src="http://" replace="false" />
|
||||
// <Module name="module1" [repository="somerepo"] version="1.1" replace="true" />
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -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 <Settings> step
|
||||
/*
|
||||
<Settings>
|
||||
<SiteSettingsPart PageSize="30" />
|
||||
<CommentSettingsPart enableSpamProtection="true" />
|
||||
</Settings>
|
||||
*/
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -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 <Theme> step
|
||||
// <Theme src="http://" enabled="true" current="true />
|
||||
// <Theme name="theme1" repository="somethemerepo" version="1.1" replace="true" />
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -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.
|
||||
|
@@ -217,6 +217,9 @@ namespace Orchard.Setup.Services {
|
||||
|
||||
private void CreateTenantData(SetupContext context, IWorkContextScope environment) {
|
||||
var recipeManager = environment.Resolve<IRecipeManager>();
|
||||
if (context.Recipe != null) {
|
||||
recipeManager.Execute(Recipes().Where(r => r.Name == context.Recipe).FirstOrDefault());
|
||||
}
|
||||
|
||||
// create superuser
|
||||
var membershipService = environment.Resolve<IMembershipService>();
|
||||
|
Reference in New Issue
Block a user