internal void BuildExtension(string sourcePath, string targetPath = null)
{
if (!Path.IsPathRooted(sourcePath))
sourcePath = Path.Combine(Directory.GetCurrentDirectory(), sourcePath);
string extensionName = Path.GetFileName(sourcePath);
string configSourcePath = Path.Combine(sourcePath, ProjectConfiguration.ProjectConfigName);
string configTargetPath = Path.Combine(Program.ApplicationPath, ProjectConfiguration.ExtensionConfigName);
string extensionBuildScript = Path.Combine(sourcePath, BuildFileName);
string extensionPath = targetPath;
if (string.IsNullOrWhiteSpace(extensionPath))
extensionPath = Path.Combine(Path.GetDirectoryName(sourcePath), Path.ChangeExtension(extensionName, "zip"));
if (!Path.IsPathRooted(extensionPath))
extensionPath = Path.Combine(Directory.GetCurrentDirectory(), extensionPath);
if (!Directory.Exists(sourcePath))
{
throw new FileNotFoundException(
string.Format("The specified extension source path '{0}' doesn't exist", sourcePath));
}
if (!File.Exists(configSourcePath))
{
throw new FileNotFoundException(
string.Format("The specified project configuration path '{0}' doesn't exist", configSourcePath));
}
if (File.Exists(extensionBuildScript))
{
try
{
log.DebugFormat("Running nant on build file '{0}'", extensionBuildScript);
ConsoleDriver.Main(new[] { "-buildfile:" + extensionBuildScript });
// nantProject = new Project(extensionBuildScript, Level.Error, 1);
// nantProject.Run();
}
catch (Exception ex)
{
log.ErrorFormat("Running nant failed: {0}", ex.Message);
throw;
}
}
sourcePath = new DirectoryInfo(sourcePath).FullName;
XmlDocument configurationDocument = ExtensionBuilder.CreateExtensionConfigurationDocument(extensionName);
XmlElement extensionRoot = configurationDocument.DocumentElement;
ProjectConfiguration config = ProjectConfiguration.Create(configSourcePath);
if (!config.ValidationResult.Success)
throw config.ValidationResult.Exception;
XmlElement configRoot = config.ToXml(configurationDocument);
if (targetPath == null && !string.IsNullOrWhiteSpace(config.Name))
{
extensionName = config.Name;
extensionPath = Path.Combine(Path.GetDirectoryName(sourcePath), config.Name + ".zip");
extensionPath = new FileInfo(extensionPath).FullName;
}
log.InfoFormat("Building extension '{0}'.", extensionName);
log.DebugFormat(" (source: {0})", sourcePath);
log.DebugFormat(" (target: {0})", extensionPath);
if (File.Exists(extensionPath))
File.Delete(extensionPath);
string targetDir = Path.GetDirectoryName(extensionPath);
Directory.CreateDirectory(targetDir);
SageContext context = Program.CreateSageContext("/",
config, path =>
{
if (path == "/")
path = "~/";
string result = path
.Replace("~", sourcePath)
.Replace("//", "/")
.Replace("/", "\\");
return new FileInfo(result).FullName;
});
using (ZipOutputStream zipfile = new ZipOutputStream(File.Create(extensionPath)))
{
// Disable Zip64 for Mac compatibility
zipfile.UseZip64 = UseZip64.Off;
zipfile.SetLevel(9);
// assets
string assetSourcePath = context.Path.Resolve(context.Path.AssetPath);
foreach (string file in config.Package.Assets.GetFiles(context))
{
string childPath = file.ReplaceAll(assetSourcePath.EscapeMeta(), string.Empty).Trim('/', '\\');
this.PackFile(zipfile, file, "assets/" + childPath);
}
// binaries
string binarySourcePath = context.Path.Resolve("~/bin");
foreach (string file in config.Package.Binaries.GetFiles(context))
{
string childPath = file.ReplaceAll(binarySourcePath.EscapeMeta(), string.Empty).Trim('/', '\\');
this.PackFile(zipfile, file, "bin/" + childPath);
}
XmlElement linkingElement =
configurationDocument.CreateElement("p:linking", XmlNamespaces.ProjectConfigurationNamespace);
// libraries, modules, links, metaviews, routes
ExtensionBuilder.CopyConfiguration(config.Package.Links, "p:link", "p:link", linkingElement, extensionRoot);
ExtensionBuilder.CopyConfiguration(config.Package.Formats, "p:formats", "p:format", linkingElement, extensionRoot);
if (linkingElement.SelectNodes("*").Count != 0)
extensionRoot.AppendElement(linkingElement);
ExtensionBuilder.CopyConfiguration(config.Package.MetaViews, "p:metaViews", "p:metaView", configRoot, extensionRoot);
ExtensionBuilder.CopyConfiguration(config.Package.Routes, "p:routing", "p:route", configRoot, extensionRoot);
ExtensionBuilder.CopyConfiguration(config.Package.Libraries, "p:libraries", "p:library", configRoot, extensionRoot);
ExtensionBuilder.CopyConfiguration(config.Package.Modules, "p:modules", "p:module", configRoot, extensionRoot);
configurationDocument.Save(configTargetPath);
this.PackFile(zipfile, configTargetPath, ProjectConfiguration.ExtensionConfigName);
zipfile.IsStreamOwner = true;
zipfile.Finish();
zipfile.Close();
}
log.InfoFormat("Extension build completed");
}