ssg: StaticSiteConfigValidator impl, move validation from wizard panels

This commit is contained in:
Nick Vella 2019-07-29 23:37:37 +10:00
parent 6de3348b88
commit a6b7b81cb6
9 changed files with 257 additions and 125 deletions

View File

@ -127,6 +127,8 @@ namespace OpenLiveWriter.BlogClient.Clients.StaticSite
public StaticSiteConfigFrontMatterKeys FrontMatterKeys => new StaticSiteConfigFrontMatterKeys(); // stub for now public StaticSiteConfigFrontMatterKeys FrontMatterKeys => new StaticSiteConfigFrontMatterKeys(); // stub for now
public StaticSiteConfigValidator Validator => new StaticSiteConfigValidator(this);
/// <summary> /// <summary>
/// Load site configuration from blog credentials /// Load site configuration from blog credentials
/// </summary> /// </summary>

View File

@ -0,0 +1,199 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using OpenLiveWriter.Extensibility.BlogClient;
namespace OpenLiveWriter.BlogClient.Clients.StaticSite
{
public class StaticSiteConfigValidator
{
private StaticSiteConfig _config;
public StaticSiteConfigValidator(StaticSiteConfig config)
{
_config = config;
}
public StaticSiteConfigValidator ValidateAll()
=> this
.ValidateLocalSitePath()
.ValidatePostsPath()
.ValidatePagesPath()
.ValidateDraftsPath()
.ValidateImagesPath()
.ValidateOutputPath()
.ValidatePostUrlFormat()
.ValidateBuildCommand()
.ValidatePublishCommand();
// TODO replace errors with strings from resources
#region Path Validation
public StaticSiteConfigValidator ValidateLocalSitePath()
{
if(!Directory.Exists(_config.LocalSitePath))
throw new StaticSiteConfigValidationException(
"Folder not found",
"Local Site Path '{0}' does not exist.",
_config.LocalSitePath);
return this;
}
public StaticSiteConfigValidator ValidatePostsPath()
{
var postsPathFull = $"{_config.LocalSitePath}\\{_config.PostsPath}";
// If the Posts path is empty, display an error
if (_config.PostsPath.Trim() == string.Empty)
throw new StaticSiteConfigValidationException(
"Folder not found",
"Posts path is empty.");
// If the Posts path doesn't exist, display an error
if (!Directory.Exists(postsPathFull))
throw new StaticSiteConfigValidationException(
"Folder not found",
"Posts path '{0}' does not exist.",
postsPathFull);
return this;
}
public StaticSiteConfigValidator ValidatePagesPath()
{
if (!_config.PagesEnabled) return this; // Don't validate if pages aren't enabled
var pagesPathFull = $"{_config.LocalSitePath}\\{_config.PagesPath}";
// If the Pages path is empty, display an error
if (_config.PagesPath.Trim() == string.Empty)
throw new StaticSiteConfigValidationException(
"Folder not found",
"Pages path is empty.");
// If the path doesn't exist, display an error
if (!Directory.Exists(pagesPathFull))
throw new StaticSiteConfigValidationException(
"Folder not found",
"Pages path '{0}' does not exist.",
pagesPathFull);
return this;
}
public StaticSiteConfigValidator ValidateDraftsPath()
{
if (!_config.DraftsEnabled) return this; // Don't validate if drafts aren't enabled
var draftsPathFull = $"{_config.LocalSitePath}\\{_config.DraftsPath}";
// If the Drafts path is empty, display an error
if (_config.DraftsPath.Trim() == string.Empty)
throw new StaticSiteConfigValidationException(
"Folder not found",
"Drafts path is empty.");
// If the path doesn't exist, display an error
if (!Directory.Exists(draftsPathFull))
throw new StaticSiteConfigValidationException(
"Folder not found",
"Drafts path '{0}' does not exist.",
draftsPathFull);
return this;
}
public StaticSiteConfigValidator ValidateImagesPath()
{
if (!_config.ImagesEnabled) return this; // Don't validate if images aren't enabled
var imagesPathFull = $"{_config.LocalSitePath}\\{_config.ImagesPath}";
// If the Images path is empty, display an error
if (_config.ImagesPath.Trim() == string.Empty)
throw new StaticSiteConfigValidationException(
"Folder not found",
"Images path is empty.");
// If the path doesn't exist, display an error
if (!Directory.Exists(imagesPathFull))
throw new StaticSiteConfigValidationException(
"Folder not found",
"Images path '{0}' does not exist.",
imagesPathFull);
return this;
}
public StaticSiteConfigValidator ValidateOutputPath()
{
if (!_config.BuildingEnabled) return this; // Don't validate if building isn't enabled
var outputPathFull = $"{_config.LocalSitePath}\\{_config.OutputPath}";
// If the Output path is empty, display an error
if (_config.OutputPath.Trim() == string.Empty)
throw new StaticSiteConfigValidationException(
"Folder not found",
"Output path is empty.");
// If the path doesn't exist, display an error
if (!Directory.Exists(outputPathFull))
throw new StaticSiteConfigValidationException(
"Folder not found",
"Output path '{0}' does not exist.",
outputPathFull);
return this;
}
#endregion
public StaticSiteConfigValidator ValidatePostUrlFormat()
{
if (!_config.PostUrlFormat.Contains("%f"))
throw new StaticSiteConfigValidationException(
"Invalid Post URL format",
"Post URL format does not contain filename variable (%f)");
return this;
}
public StaticSiteConfigValidator ValidateBuildCommand()
{
if (!_config.BuildingEnabled) return this; // Don't validate if building isn't enabled
if (_config.BuildCommand.Trim() == string.Empty)
throw new StaticSiteConfigValidationException(
"Build command empty",
"A build command is required when local site building is enabled.");
return this;
}
public StaticSiteConfigValidator ValidatePublishCommand()
{
if (_config.PublishCommand.Trim() == string.Empty)
throw new StaticSiteConfigValidationException(
"Publish command empty",
"A publish command is required.");
return this;
}
}
public class StaticSiteConfigValidationException : BlogClientException
{
public StaticSiteConfigValidationException(string title, string text, params object[] textFormatArgs) : base(title, text, textFormatArgs)
{
}
}
}

View File

@ -166,6 +166,7 @@
<Compile Include="Clients\StaticSite\StaticSiteConfigDetector.cs" /> <Compile Include="Clients\StaticSite\StaticSiteConfigDetector.cs" />
<Compile Include="Clients\StaticSite\StaticSiteClient.cs" /> <Compile Include="Clients\StaticSite\StaticSiteClient.cs" />
<Compile Include="Clients\StaticSite\StaticSiteConfig.cs" /> <Compile Include="Clients\StaticSite\StaticSiteConfig.cs" />
<Compile Include="Clients\StaticSite\StaticSiteConfigValidator.cs" />
<Compile Include="Clients\StaticSite\StaticSitePage.cs" /> <Compile Include="Clients\StaticSite\StaticSitePage.cs" />
<Compile Include="Clients\StaticSite\StaticSiteItem.cs" /> <Compile Include="Clients\StaticSite\StaticSiteItem.cs" />
<Compile Include="Clients\StaticSite\StaticSiteItemFrontMatter.cs" /> <Compile Include="Clients\StaticSite\StaticSiteItemFrontMatter.cs" />

View File

@ -483,7 +483,7 @@ namespace OpenLiveWriter.PostEditor.Configuration.Wizard
new WizardSubStep(new WeblogConfigurationWizardPanelStaticSiteInitial(), new WizardSubStep(new WeblogConfigurationWizardPanelStaticSiteInitial(),
null, null,
new DisplayCallback(OnStaticSiteInitialDisplayed), new DisplayCallback(OnStaticSiteInitialDisplayed),
new VerifyStepCallback(OnValidatePanel), new VerifyStepCallback(OnStaticSiteValidatePanel),
new NextCallback(OnStaticSiteInitialCompleted), new NextCallback(OnStaticSiteInitialCompleted),
null, null,
new BackCallback(OnStaticSiteBack))); new BackCallback(OnStaticSiteBack)));
@ -540,7 +540,7 @@ namespace OpenLiveWriter.PostEditor.Configuration.Wizard
new WizardSubStep(new WeblogConfigurationWizardPanelStaticSitePaths1(), new WizardSubStep(new WeblogConfigurationWizardPanelStaticSitePaths1(),
null, null,
new DisplayCallback(OnStaticSiteConfigProviderDisplayed), new DisplayCallback(OnStaticSiteConfigProviderDisplayed),
new VerifyStepCallback(OnValidatePanel), new VerifyStepCallback(OnStaticSiteValidatePanel),
new NextCallback(OnStaticSitePaths1Completed), new NextCallback(OnStaticSitePaths1Completed),
null, null,
new BackCallback(OnStaticSiteBack))); new BackCallback(OnStaticSiteBack)));
@ -563,7 +563,7 @@ namespace OpenLiveWriter.PostEditor.Configuration.Wizard
new WizardSubStep(new WeblogConfigurationWizardPanelStaticSitePaths2(), new WizardSubStep(new WeblogConfigurationWizardPanelStaticSitePaths2(),
null, null,
new DisplayCallback(OnStaticSiteConfigProviderDisplayed), new DisplayCallback(OnStaticSiteConfigProviderDisplayed),
new VerifyStepCallback(OnValidatePanel), new VerifyStepCallback(OnStaticSiteValidatePanel),
new NextCallback(OnStaticSitePaths2Completed), new NextCallback(OnStaticSitePaths2Completed),
null, null,
new BackCallback(OnStaticSiteBack))); new BackCallback(OnStaticSiteBack)));
@ -586,7 +586,7 @@ namespace OpenLiveWriter.PostEditor.Configuration.Wizard
new WizardSubStep(new WeblogConfigurationWizardPanelStaticSiteFeatures(), new WizardSubStep(new WeblogConfigurationWizardPanelStaticSiteFeatures(),
null, null,
new DisplayCallback(OnStaticSiteConfigProviderDisplayed), new DisplayCallback(OnStaticSiteConfigProviderDisplayed),
new VerifyStepCallback(OnValidatePanel), new VerifyStepCallback(OnStaticSiteValidatePanel),
new NextCallback(OnStaticSiteFeaturesCompleted), new NextCallback(OnStaticSiteFeaturesCompleted),
null, null,
new BackCallback(OnStaticSiteBack))); new BackCallback(OnStaticSiteBack)));
@ -609,7 +609,7 @@ namespace OpenLiveWriter.PostEditor.Configuration.Wizard
new WizardSubStep(new WeblogConfigurationWizardPanelStaticSiteCommands(), new WizardSubStep(new WeblogConfigurationWizardPanelStaticSiteCommands(),
null, null,
new DisplayCallback(OnStaticSiteConfigProviderDisplayed), new DisplayCallback(OnStaticSiteConfigProviderDisplayed),
new VerifyStepCallback(OnValidatePanel), new VerifyStepCallback(OnStaticSiteValidatePanel),
new NextCallback(OnStaticSiteCommandsCompleted), new NextCallback(OnStaticSiteCommandsCompleted),
null, null,
new BackCallback(OnStaticSiteBack))); new BackCallback(OnStaticSiteBack)));
@ -629,7 +629,25 @@ namespace OpenLiveWriter.PostEditor.Configuration.Wizard
private void OnStaticSiteBack(object step) private void OnStaticSiteBack(object step)
{ {
// Save panel values before going back // Save panel values before going back
(step as IWizardPanelStaticSiteConfigProvider).SaveToConfig(staticSiteConfig); (step as IWizardPanelStaticSite).SaveToConfig(staticSiteConfig);
}
private bool OnStaticSiteValidatePanel(object step)
{
var newConfig = staticSiteConfig.Clone();
IWizardPanelStaticSite panel = step as IWizardPanelStaticSite;
panel.SaveToConfig(newConfig);
try
{
panel.ValidateWithConfig(newConfig);
} catch(StaticSiteConfigValidationException ex)
{
MessageBox.Show(ex.Text, ex.Title, MessageBoxButtons.OK, MessageBoxIcon.Warning);
return false;
}
return true;
} }
private void PerformStaticSiteWizardCompletion() private void PerformStaticSiteWizardCompletion()
@ -659,7 +677,7 @@ namespace OpenLiveWriter.PostEditor.Configuration.Wizard
private void OnStaticSiteConfigProviderDisplayed(Object stepControl) private void OnStaticSiteConfigProviderDisplayed(Object stepControl)
{ {
// Populate data // Populate data
var panel = (stepControl as IWizardPanelStaticSiteConfigProvider); var panel = (stepControl as IWizardPanelStaticSite);
// Load panel values from config // Load panel values from config
panel.LoadFromConfig(staticSiteConfig); panel.LoadFromConfig(staticSiteConfig);
@ -1017,8 +1035,14 @@ namespace OpenLiveWriter.PostEditor.Configuration.Wizard
} }
internal interface IWizardPanelStaticSiteConfigProvider internal interface IWizardPanelStaticSite
{ {
/// <summary>
/// Validate the relevant parts of the Static Site Config, raising an exception if the configuration is invalid.
/// </summary>
/// <param name="config">a StaticSiteConfig instance</param>
void ValidateWithConfig(StaticSiteConfig config);
/// <summary> /// <summary>
/// Saves panel form fields into a StaticSiteConfig /// Saves panel form fields into a StaticSiteConfig
/// </summary> /// </summary>

View File

@ -23,7 +23,7 @@ namespace OpenLiveWriter.PostEditor.Configuration.Wizard
/// <summary> /// <summary>
/// Summary description for WelcomeToBlogControl. /// Summary description for WelcomeToBlogControl.
/// </summary> /// </summary>
internal class WeblogConfigurationWizardPanelStaticSiteCommands : WeblogConfigurationWizardPanel, IWizardPanelStaticSiteConfigProvider internal class WeblogConfigurationWizardPanelStaticSiteCommands : WeblogConfigurationWizardPanel, IWizardPanelStaticSite
{ {
private Label labelPublishCommand; private Label labelPublishCommand;
private TextBox textBoxBuildCommand; private TextBox textBoxBuildCommand;
@ -111,30 +111,10 @@ namespace OpenLiveWriter.PostEditor.Configuration.Wizard
set => textBoxBuildCommand.Text = value; set => textBoxBuildCommand.Text = value;
} }
public override bool ValidatePanel() public void ValidateWithConfig(StaticSiteConfig config)
{ => config.Validator
// TODO .ValidateBuildCommand()
// If building enabled, and build command empty, throw validation error .ValidatePublishCommand();
// If publish command empty, throw validation error
if(BuildingEnabled && BuildCommand.Trim() == string.Empty)
{
ShowValidationError(
textBoxBuildCommand,
MessageId.SSGBuildCommandRequired);
return false;
}
if(PublishCommand.Trim() == string.Empty)
{
ShowValidationError(
textBoxPublishCommand,
MessageId.SSGPublishCommandRequired);
return false;
}
return true;
}
/// <summary> /// <summary>
/// Saves panel form fields into a StaticSiteConfig /// Saves panel form fields into a StaticSiteConfig

View File

@ -24,7 +24,7 @@ namespace OpenLiveWriter.PostEditor.Configuration.Wizard
/// <summary> /// <summary>
/// Summary description for WelcomeToBlogControl. /// Summary description for WelcomeToBlogControl.
/// </summary> /// </summary>
internal class WeblogConfigurationWizardPanelStaticSiteFeatures : WeblogConfigurationWizardPanel, IWizardPanelStaticSiteConfigProvider internal class WeblogConfigurationWizardPanelStaticSiteFeatures : WeblogConfigurationWizardPanel, IWizardPanelStaticSite
{ {
private CheckBox checkBoxPagesEnabled; private CheckBox checkBoxPagesEnabled;
private CheckBox checkBoxBuildingEnabled; private CheckBox checkBoxBuildingEnabled;
@ -106,11 +106,8 @@ namespace OpenLiveWriter.PostEditor.Configuration.Wizard
set => checkBoxBuildingEnabled.Checked = value; set => checkBoxBuildingEnabled.Checked = value;
} }
public override bool ValidatePanel() // No validation is required on this panel
{ public void ValidateWithConfig(StaticSiteConfig config) { }
// No validation required on this page
return true;
}
/// <summary> /// <summary>
/// Saves panel form fields into a StaticSiteConfig /// Saves panel form fields into a StaticSiteConfig

View File

@ -24,7 +24,7 @@ namespace OpenLiveWriter.PostEditor.Configuration.Wizard
/// <summary> /// <summary>
/// Summary description for WelcomeToBlogControl. /// Summary description for WelcomeToBlogControl.
/// </summary> /// </summary>
internal class WeblogConfigurationWizardPanelStaticSiteInitial : WeblogConfigurationWizardPanel, IWizardPanelStaticSiteConfigProvider internal class WeblogConfigurationWizardPanelStaticSiteInitial : WeblogConfigurationWizardPanel, IWizardPanelStaticSite
{ {
private System.Windows.Forms.Label labelSubtitle; private System.Windows.Forms.Label labelSubtitle;
private System.Windows.Forms.Label labelLocalSitePath; private System.Windows.Forms.Label labelLocalSitePath;
@ -80,16 +80,8 @@ namespace OpenLiveWriter.PostEditor.Configuration.Wizard
set { textBoxLocalSitePath.Text = value; } set { textBoxLocalSitePath.Text = value; }
} }
public override bool ValidatePanel() public void ValidateWithConfig(StaticSiteConfig config)
{ => config.Validator.ValidateLocalSitePath();
if (!Directory.Exists(LocalSitePath))
{
ShowValidationError(textBoxLocalSitePath, MessageId.FolderNotFound, LocalSitePath);
return false;
}
return true;
}
/// <summary> /// <summary>
/// Saves panel form fields into a StaticSiteConfig /// Saves panel form fields into a StaticSiteConfig

View File

@ -24,7 +24,7 @@ namespace OpenLiveWriter.PostEditor.Configuration.Wizard
/// <summary> /// <summary>
/// Summary description for WelcomeToBlogControl. /// Summary description for WelcomeToBlogControl.
/// </summary> /// </summary>
internal class WeblogConfigurationWizardPanelStaticSitePaths1 : WeblogConfigurationWizardPanel, IWizardPanelStaticSiteConfigProvider internal class WeblogConfigurationWizardPanelStaticSitePaths1 : WeblogConfigurationWizardPanel, IWizardPanelStaticSite
{ {
/// <summary> /// <summary>
/// Local site path, loaded from config, used for validation /// Local site path, loaded from config, used for validation
@ -145,43 +145,11 @@ namespace OpenLiveWriter.PostEditor.Configuration.Wizard
set { checkBoxPagesInRoot.Checked = value; } set { checkBoxPagesInRoot.Checked = value; }
} }
public override bool ValidatePanel() public void ValidateWithConfig(StaticSiteConfig config)
{ => config.Validator
var postsPathFull = $"{_localSitePath}\\{PostsPath}"; .ValidatePostsPath()
var pagesPathFull = $"{_localSitePath}\\{PagesPath}"; .ValidatePagesPath()
var draftsPathFull = $"{_localSitePath}\\{DraftsPath}"; .ValidateDraftsPath();
// If the Posts path is empty or doesn't exist, display an error
if (PostsPath.Trim() == string.Empty || !Directory.Exists(postsPathFull))
{
ShowValidationError(
textBoxPostsPath,
MessageId.FolderNotFound,
PostsPath.Trim() == string.Empty ? "Posts path empty" : postsPathFull); // TODO Replace string from with string from resources
return false;
}
// If Pages are enabled and the path doesn't exist/is empty, display an error
if (PagesEnabled && (PagesPath.Trim() == string.Empty || !Directory.Exists(pagesPathFull)))
{
ShowValidationError(
textBoxPagesPath,
MessageId.FolderNotFound,
PagesPath.Trim() == string.Empty ? "Pages path empty" : pagesPathFull); // TODO Replace string from with string from resources
return false;
}
// If Drafts are enabled and the path doesn't exist/is empty, display an error
if (DraftsEnabled && (DraftsPath.Trim() == string.Empty || !Directory.Exists(draftsPathFull)))
{
ShowValidationError(textBoxDraftsPath,
MessageId.FolderNotFound,
DraftsPath.Trim() == string.Empty ? "Drafts path empty" : draftsPathFull); // TODO Replace string with string from resources
return false;
}
return true;
}
/// <summary> /// <summary>
/// Saves panel form fields into a StaticSiteConfig /// Saves panel form fields into a StaticSiteConfig

View File

@ -24,7 +24,7 @@ namespace OpenLiveWriter.PostEditor.Configuration.Wizard
/// <summary> /// <summary>
/// Summary description for WelcomeToBlogControl. /// Summary description for WelcomeToBlogControl.
/// </summary> /// </summary>
internal class WeblogConfigurationWizardPanelStaticSitePaths2 : WeblogConfigurationWizardPanel, IWizardPanelStaticSiteConfigProvider internal class WeblogConfigurationWizardPanelStaticSitePaths2 : WeblogConfigurationWizardPanel, IWizardPanelStaticSite
{ {
private Label labelImagesPath; private Label labelImagesPath;
private TextBox textBoxImagesPath; private TextBox textBoxImagesPath;
@ -120,42 +120,11 @@ namespace OpenLiveWriter.PostEditor.Configuration.Wizard
set => textBoxUrlFormat.Text = value; set => textBoxUrlFormat.Text = value;
} }
public override bool ValidatePanel() public void ValidateWithConfig(StaticSiteConfig config)
{ => config.Validator
var imagesPathFull = $"{_localSitePath}\\{ImagesPath}"; .ValidateImagesPath()
var outputPathFull = $"{_localSitePath}\\{OutputPath}"; .ValidateOutputPath()
.ValidatePostUrlFormat();
// If images are enabled, and the images path is empty or doesn't exist, display an error
if (ImagesEnabled && (ImagesPath.Trim() == string.Empty || !Directory.Exists(imagesPathFull)))
{
ShowValidationError(
textBoxImagesPath,
MessageId.FolderNotFound,
ImagesPath.Trim() == string.Empty ? "Images path empty" : imagesPathFull); // TODO Replace string from with string from resources
return false;
}
// If local building is enabled, and the site output path is empty or doesn't exist, display an error
if (BuildingEnabled && (OutputPath == string.Empty || !Directory.Exists(outputPathFull)))
{
ShowValidationError(
textBoxOutputPath,
MessageId.FolderNotFound,
OutputPath.Trim() == string.Empty ? "Output path empty" : outputPathFull); // TODO Replace string from with string from resources
return false;
}
// If post url format doesn't contain a filename variable, display an error
if(!UrlFormat.Contains("%f"))
{
ShowValidationError(textBoxUrlFormat, MessageId.SSGUrlFormatStringInvalid);
return false;
}
return true;
}
/// <summary> /// <summary>
/// Saves panel form fields into a StaticSiteConfig /// Saves panel form fields into a StaticSiteConfig