Skip to content
This repository has been archived by the owner on Oct 3, 2021. It is now read-only.

Commit

Permalink
Merge pull request #35 from MikeStall/master
Browse files Browse the repository at this point in the history
Support for Components
  • Loading branch information
daryllabar committed Jul 2, 2020
2 parents 21ea136 + 5424c47 commit 1173825
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 47 deletions.
52 changes: 36 additions & 16 deletions CanvasAppPackager/PackLogic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,15 @@ private static void PackApp(string appPath, string mainAppPath)
var zipPath = GetTemporaryDirectory();
try
{
Logger.Log("Parsing Auto Values");
var extractor = AutoValueExtractor.Parse(Path.Combine(appPath, UnpackLogic.Paths.Code, UnpackLogic.Paths.AutoValues) + UnpackLogic.DataFileExt);

Logger.Log("Copying app files for zip creation.");
CopyFilesToZipFolder(appPath, zipPath, "MsApp", UnpackLogic.Paths.Code, UnpackLogic.Paths.Metadata);
CopyFilesToZipFolder(appPath, zipPath, "MsApp", UnpackLogic.Paths.Code, UnpackLogic.Paths.ComponentCode, UnpackLogic.Paths.Metadata);

Logger.Log("Packaging Code files");
PackScreens(appPath, zipPath, extractor);

PackScreens(appPath, zipPath, UnpackLogic.Paths.Code, UnpackLogic.Paths.Controls);

Logger.Log("Packaging Component Code files");
PackScreens(appPath, zipPath, UnpackLogic.Paths.ComponentCode, UnpackLogic.Paths.Components);

Logger.Log("Parsing AppInfo");
var sourcePath = Path.Combine(appPath, UnpackLogic.Paths.Metadata);
string msAppZipPath;
Expand Down Expand Up @@ -97,12 +97,20 @@ private static void PackApp(string appPath, string mainAppPath)
}
}

private static void PackScreens(string appPath, string zipPath, AutoValueExtractor extractor)
private static void PackScreens(string appPath, string zipPath, string pathCode, string pathControls)
{
foreach (var codeDirectory in Directory.GetDirectories(Path.Combine(appPath, UnpackLogic.Paths.Code)))
if (!Directory.Exists(Path.Combine(appPath, pathCode)))
{
return;
}

Logger.Log("Parsing Auto Values");
var extractor = AutoValueExtractor.Parse(Path.Combine(appPath, pathCode, UnpackLogic.Paths.AutoValues) + UnpackLogic.DataFileExt);

foreach (var codeDirectory in Directory.GetDirectories(Path.Combine(appPath, pathCode)))
{
var screen = PackScreen(codeDirectory, extractor);
var dir = Path.Combine(zipPath, UnpackLogic.Paths.Controls);
var dir = Path.Combine(zipPath, pathControls);
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
Expand Down Expand Up @@ -275,26 +283,38 @@ private static void RestoreAutoNamedFiles(string appDirectory)
Logger.Log("Extracting file " + publishInfo);
var json = File.ReadAllText(publishInfo);
var info = JsonConvert.DeserializeObject<PublishInfo>(json);

// Copy Logo. Optional file.
var fromName = Path.Combine(resourceFilesPath, UnpackLogic.Paths.LogoImage + Path.GetExtension(info.LogoFileName));
var toName = Path.Combine(appDirectory, UnpackLogic.Paths.Resources, info.LogoFileName);
Logger.Log($"Restoring auto named file '{fromName}' to '{toName}'.");
File.Move(fromName, toName);
if (File.Exists(fromName))
{
var toName = Path.Combine(appDirectory, UnpackLogic.Paths.Resources, info.LogoFileName);
Logger.Log($"Restoring auto named file '{fromName}' to '{toName}'.");
File.Move(fromName, toName);
}

// Rename Component Files
// There were 2 formats for unpacking components.
// Newer format: treated just like controls. There is a ComponentCode directory. Packs with controls.
// Older format: it was just a rename. There is just a Components directory. Pack here.
var componentsPath = Path.Combine(appDirectory, UnpackLogic.Paths.Components);
if (Directory.Exists(componentsPath))
{
RestoreRenamedComponetFiles(componentsPath);
}
RestoreRenamedComponentFiles(componentsPath);
}
}

private static void RestoreRenamedComponetFiles(string componentsPath)
private static void RestoreRenamedComponentFiles(string componentsPath)
{
foreach (var file in Directory.GetFiles(componentsPath))
{
Logger.Log("Extracting file " + file);
var component = JsonConvert.DeserializeObject<CanvasAppScreen>(File.ReadAllText(file));
var toName = Path.Combine(componentsPath, component.TopParent.ControlUniqueId + Path.GetExtension(file));
if (File.Exists(toName))
{
continue; // File was already created via the code extraction path.
}

Logger.Log($"Renaming component file '{file}' to '{toName}'.");
File.Delete(toName);
File.Move(file, toName);
Expand Down
8 changes: 7 additions & 1 deletion CanvasAppPackager/Poco/App.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@

namespace CanvasAppPackager.Poco
{
class Header
{
public string DocVersion { get; set; }
// There are more properties ...
}

public class OverridableProperties
{
}
Expand Down Expand Up @@ -64,7 +70,7 @@ public class Rule
public string Category { get; set; }
public string InvariantScript { get; set; }
public string RuleProviderType { get; set; }
public string NameMap { get; set; }
public string NameMap { get; set; }
}

/// <summary>
Expand Down
59 changes: 29 additions & 30 deletions CanvasAppPackager/UnpackLogic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@
using System.IO.Compression;
using System.Text;
using CanvasAppPackager.Poco;
using CanvasAppPackager.Args;

namespace CanvasAppPackager
{
class UnpackLogic
{
{
public const string CodeFileExt = ".js";
public const string DataFileExt = ".json";
public const string EndOfRuleCode = "} // End of ";
public static readonly Version MinimumDocVersion = new Version("1.280");
public const string UnformattedPrefix = "//// Unformatted: ";
private const string DocVersionStartText = "\"DocVersion\"";

public struct Paths
{
Expand All @@ -24,12 +24,13 @@ public struct Paths
public const string AutoValues = "AutoValues";
public const string BackgroundImage = "BackgroundImage.png";
public const string Code = "Code";
public const string ComponentCode = "ComponentCode";
public const string Components = "Components";
public const string Controls = "Controls";
public const string Header = "Header.json";
public const string Icons = "Icons";
public const string ManifestFileName = "manifest.json";
public const string Metadata= "MetadataFiles";
public const string Metadata = "MetadataFiles";
public const string MsPowerApps = "Microsoft.PowerApps";
public const string Resources = "Resources";
public const string ResourcePublishFileName = "PublishInfo.json";
Expand All @@ -44,7 +45,7 @@ public static void Unpack(string file, string outputDirectory, Args.Args options
Directory.Delete(outputDirectory, true);
}

Logger.Log("Extracting files from " + file + " to " + outputDirectory );
Logger.Log("Extracting files from " + file + " to " + outputDirectory);
if (Path.GetExtension(file).ToLower() == ".zip")
{
ZipFile.ExtractToDirectory(file, outputDirectory, true);
Expand Down Expand Up @@ -72,7 +73,7 @@ private static void ExtractApps(string outputDirectory, Args.Args options)
foreach (var appSourcePath in Directory.GetDirectories(appsPath))
{
var appInfo = AppInfo.Parse(File.ReadAllText(Path.Join(appSourcePath, Path.GetFileName(appSourcePath)) + ".json"));
var appOutputPath = Path.Combine(outputDirectory, Paths.Apps, string.IsNullOrWhiteSpace(options.NameOfApplication) ? appInfo.DisplayName: options.NameOfApplication);
var appOutputPath = Path.Combine(outputDirectory, Paths.Apps, string.IsNullOrWhiteSpace(options.NameOfApplication) ? appInfo.DisplayName : options.NameOfApplication);
Logger.Log($"Extracting App {appInfo.DisplayName} - {appInfo.Description}");
var msAppFilePath = Path.Combine(appsPath, appInfo.MsAppPath);
Unpack(msAppFilePath, appOutputPath, options);
Expand Down Expand Up @@ -143,26 +144,11 @@ private static void RenameAutoNamedFiles(string appDirectory)
File.Delete(toName);
File.Move(fromName, toName);
}

//Rename Component Files
var componentsPath = Path.Combine(appDirectory, Paths.Components);
if(Directory.Exists(componentsPath)){
foreach (var file in Directory.GetFiles(componentsPath))
{
Logger.Log("Extracting file " + file);
json = File.ReadAllText(file);
var component = JsonConvert.DeserializeObject<CanvasAppScreen>(json);
var toName = Path.Combine(componentsPath, component.TopParent.Name + Path.GetExtension(file));
Logger.Log($"Renaming component file '{file}' to '{toName}'.");
File.Delete(toName);
File.Move(file, toName);
}
}
}

private static Dictionary<string, string> GetMetadataFileMappings(AppInfo appInfo)
{
var fileMapping = new Dictionary<string, string> {{appInfo.BackgroundImage, Paths.BackgroundImage}};
var fileMapping = new Dictionary<string, string> { { appInfo.BackgroundImage, Paths.BackgroundImage } };
foreach (var icon in appInfo.Icons)
{
var key = icon.Key;
Expand All @@ -180,14 +166,29 @@ private static void RenameAutoNamedFiles(string appDirectory)
private static void ExtractCanvasApp(string appDirectory, Args.Args options)
{
var codeDirectory = Path.Combine(appDirectory, Paths.Code);
var componentCodeDirectory = Path.Combine(appDirectory, Paths.ComponentCode);
var controlsDir = Path.Combine(appDirectory, Paths.Controls);
var autoValueExtractor = new AutoValueExtractor();
var componentsDir = Path.Combine(appDirectory, Paths.Components);
var header = File.ReadAllText(Path.Combine(appDirectory, Paths.Header));
var indexOfDocVersion = header.IndexOf(DocVersionStartText, StringComparison.InvariantCultureIgnoreCase) + DocVersionStartText.Length;
indexOfDocVersion = header.IndexOf('"', indexOfDocVersion) + 1;
var version = new Version(header[indexOfDocVersion
..
header.IndexOf("\"", indexOfDocVersion, StringComparison.InvariantCultureIgnoreCase)]);


// It's important to use proper JSON deserialization since the whitepsace is unpredictable.
var headerObj = JsonConvert.DeserializeObject<Header>(header);
var version = new Version(headerObj.DocVersion);

ExtraCodeful(controlsDir, codeDirectory, version, options);
ExtraCodeful(componentsDir, componentCodeDirectory, version, options);

RenameAutoNamedFiles(appDirectory);
}

private static void ExtraCodeful(string controlsDir, string codeDirectory, Version version, Args.Args options)
{
if (!Directory.Exists(controlsDir))
{
return;
}
var autoValueExtractor = new AutoValueExtractor();

foreach (var file in Directory.GetFiles(controlsDir))
{
Expand All @@ -204,9 +205,7 @@ private static void ExtractCanvasApp(string appDirectory, Args.Args options)
}
File.WriteAllText(Path.Combine(codeDirectory, Paths.AutoValues) + DataFileExt, autoValueExtractor.Serialize());
Directory.Delete(controlsDir, true);

RenameAutoNamedFiles(appDirectory);
}
}

private static string RenameControls(string app, Args.Args options)
{
Expand Down

0 comments on commit 1173825

Please sign in to comment.