Update release

This commit is contained in:
Zihan Chen
2018-07-02 17:32:03 -07:00
parent 2d84caf076
commit 12c3234a89
10 changed files with 422 additions and 38 deletions
Binary file not shown.
+114
View File
@@ -0,0 +1,114 @@
<#
Do an incremental build to all GacUI Xml Resource files directly or indirectly in the folder containing $FileName.
If you set -Dump, then this scripts stops before the real building process, it outputs following files for debug:
$($FileName).log\ResourceFiles.txt: All resource files that are found
$($FileName).log\BuildCandidates.txt: All resource files that are outdated, so they will be build
$($FileName).log\ResourceAnonymousFiles.txt: All anonymous resource files
$($FileName).log\ResourceNamedFiles.txt: All named resource files in the correct order sorted using dependencies
$($FileName).log\ResourceNamedMapping.txt: Resource name to full path mappings for GacGen.exe /P <resource-xml> <HERE>
$FileName should points to an Xml file with this format:
<GacUI>
<Exclude Pattern="...."/>
...
</GacUI>
GacBuild.ps1 searches all GacUI Xml Resource files, but whose full patch matches one of the pattern will be ignored.
You should use "/" instead of "\" in the pattern attribute.
In order to make your resource file, be able to depend on others, or be able to be depended by others,
you should add the following metadata in GacGenConfig like this:
<Resource>
<Folder name="GacGenConfig">
<Xml name="Metadata">
<ResourceMetadata Name="NAME" Version="1.0">
<Dependencies>
<Resource Name="NAME-OF-RESOURCE-YOU-WANT-TO-DEPEND"/>
....
</Dependencies>
</ResourceMetadata>
</Xml>
<Folder name="Cpp">...</Folder>
<Folder name="ResX86">...</Folder>
<Folder name="ResX64">...</Folder>
</Folder>
</Folder>
...
</Resource>
#>
[CmdLetBinding()]
param (
[Parameter(Mandatory=$true)][String]$FileName,
[Switch]$Dump
)
. $PSScriptRoot\StartProcess.ps1
. $PSScriptRoot\GacCommon.ps1
# Prevent from displaying "Debug or Close Application" dialog on crash
$dontshowui_key = "HKCU:\Software\Microsoft\Windows\Windows Error Reporting"
$dontshowui_value = (Get-ItemProperty $dontshowui_key).DontShowUI
Set-ItemProperty $dontshowui_key -Name DontShowUI -Value 1
try {
if (-not (Test-Path -Path $FileName)) {
throw "Input does not exist: $FileName"
}
$FileName = (Resolve-Path -Path $FileName).Path
Remove-Item -Path "$($FileName).log" -Recurse | Out-Null
New-Item -ItemType Directory "$($FileName).log" | Out-Null
EnumerateResourceFiles $FileName
if (-not (Test-Path -Path "$($FileName).log\ResourceFiles.txt")) {
throw "Failed to enumerate GacUI Xml Resource files"
}
$resource_dump_files = @{}
$resource_dumps = @{}
DumpResourceFiles $FileName $resource_dump_files
$resource_dump_files.Keys | ForEach-Object {
$resource_dumps[$_] = [Xml](Get-Content $resource_dump_files[$_])
}
$build_candidates_file = "$($FileName).log\BuildCandidates.txt"
$anonymous_file = "$($FileName).log\ResourceAnonymousFiles.txt"
$named_file = "$($FileName).log\ResourceNamedFiles.txt"
$mapping_file = "$($FileName).log\ResourceNamedMapping.txt"
EnumerateBuildCandidates $resource_dumps $build_candidates_file
EnumerateAnonymousResources $resource_dumps $anonymous_file
EnumerateNamedResources $resource_dumps $named_file $mapping_file
if ($dump) {
Write-Host "Dumps:"
Write-Host " $($build_candidates_file)"
Write-Host " $($anonymous_file)"
Write-Host " $($named_file)"
Write-Host " $($mapping_file)"
}
if (-not $dump) {
Write-Host "Rebuilding all outdated binaries ..."
$build_candidates = Get-Content $build_candidates_file
(@() + (ForceArray (Get-Content $anonymous_file)) + (ForceArray(Get-Content $named_file))) | ForEach-Object {
try {
if ($build_candidates -contains $_) {
Write-Host "[BUILD] $($_)"
& $PSScriptRoot\GacGen.ps1 -FileName $_ -MappingFileName $mapping_file
} else {
Write-Host "[SKIPPED] $($_)"
}
} catch {
Write-Host $_.Exception.Message -ForegroundColor Red
}
}
}
}
catch {
Write-Host $_.Exception.Message -ForegroundColor Red
}
Set-ItemProperty $dontshowui_key -Name DontShowUI -Value $dontshowui_value
[Console]::ResetColor()
+46
View File
@@ -0,0 +1,46 @@
<#
See comments in GacBuild.ps1 for $FileName.
GacClear.ps1 deletes all cached compile result of all GacUI Xml Resource files, to cause GacBuild.ps1 do a full build.
If your resource files named Resource.xml, then the Resource.xml.log folder cached all files, which will be deleted.
#>
param (
[String]$FileName
)
. $PSScriptRoot\StartProcess.ps1
. $PSScriptRoot\GacCommon.ps1
# Prevent from displaying "Debug or Close Application" dialog on crash
$dontshowui_key = "HKCU:\Software\Microsoft\Windows\Windows Error Reporting"
$dontshowui_value = (Get-ItemProperty $dontshowui_key).DontShowUI
Set-ItemProperty $dontshowui_key -Name DontShowUI -Value 1
try {
if (-not (Test-Path -Path $FileName)) {
throw "Input does not exist: $FileName"
}
$FileName = (Resolve-Path -Path $FileName).Path
Remove-Item -Path "$($FileName).log" -Recurse | Out-Null
New-Item -ItemType Directory "$($FileName).log" | Out-Null
EnumerateResourceFiles $FileName
if (-not (Test-Path -Path "$($FileName).log\ResourceFiles.txt")) {
throw "Failed to enumerate GacUI Xml Resource files"
}
$search_directory = Split-Path -Parent (Resolve-Path $FileName)
Get-Content "$($FileName).log\ResourceFiles.txt" | ForEach-Object {
$input_file = Join-Path -Path $search_directory -ChildPath $_
$log_folder = "$($input_file).log"
if (Test-Path -Path $log_folder) {
Write-Host "Deleting: " $log_folder
Remove-Item -Path $log_folder -Recurse
}
}
}
catch {
Write-Host $_.Exception.Message -ForegroundColor Red
}
Set-ItemProperty $dontshowui_key -Name DontShowUI -Value $dontshowui_value
[Console]::ResetColor()
+240
View File
@@ -0,0 +1,240 @@
<#
Force the object from command or function result to array.
Sometimes when a command returns zero or one object, it becomes $null or the object.
Only when a command returns multiple objects, it becomes an array.
This function let you get an array anyway to make writing script easier.
#>
function ForceArray($nodes) {
if ($nodes -eq $null) {
return ,@()
} elseif (($nodes -is [System.Array]) -or ($nodes -is [System.Collections.ArrayList])) {
return $nodes
} else {
return ,@($nodes)
}
}
<#
Search all GacUI Xml Resource file names in the directory that contains GacUI.xml, which is specified by $FileName.
#>
function EnumerateResourceFiles([String] $FileName) {
Write-Host "Searching for all resource files ..."
<# Load GacUI.xml and find all path patterns that we want to exclude from our result #>
[Xml]$gacui_xml = Get-Content $FileName
$excludes = (ForceArray (Select-Xml -Xml $gacui_xml -XPath "//GacUI/Exclude/@Pattern")).Node.Value
$search_directory = Split-Path -Parent (Resolve-Path $FileName)
<# Enumerate all Xml file, if it is not excluded, and it matches <Resource><Folder name="GacGenConfig"/></Resource> #>
$resource_files = (Get-ChildItem $search_directory -Filter "*.xml" -Recurse | ForEach-Object {
$normalized_path = $_.FullName -replace '\\','/'
if (($excludes | Where-Object { $normalized_path.Contains($_) }).Length -eq 0) {
if ((Select-Xml -Path $_.FullName -XPath "//Resource/Folder[@name='GacGenConfig']") -ne $null) {
$_.FullName.Substring($search_directory.Length)
}
}
})
[System.IO.File]::WriteAllLines("$($FileName).log\ResourceFiles.txt", $resource_files)
}
<#
Call GacGen32.exe to dump metadatas from resource files.
Input files is save in $($FileName).log\ResourceFiles.txt, which is generated by EnumerateResourceFiles function
Output files is specified in $ResourceDumpFiles(resource_file_name => dump_file_name)
#>
function DumpResourceFiles([String] $FileName, [HashTable]$ResourceDumpFiles) {
Write-Host "Dumping all resource files ..."
$search_directory = Split-Path -Parent (Resolve-Path $FileName)
Get-Content "$($FileName).log\ResourceFiles.txt" | ForEach-Object {
$input_file = Join-Path -Path $search_directory -ChildPath $_
$output_file = "$($FileName).log\$($_ -replace '\\','_')"
$ResourceDumpFiles[$input_file] = $output_file
}
$ResourceDumpFiles.Keys | ForEach-Object {
$input_file = $_
$output_file = $ResourceDumpFiles[$_]
Start-Process-And-Wait (,("$PSScriptRoot\GacGen32.exe", "/D `"$($input_file)`" `"$($output_file)`"")) $true
if (-not (Test-Path -Path $output_file)) {
throw "Failed to dump GacUI Xml Resource File: " + $input_file
}
}
}
<#
Given a metadata dump, determine if the compile result of this resource file is outdated.
It collects last modify times of all input files and output files.
If any output files' time is eariler than any input files' time, it is outdated.
#>
function NeedBuild([Xml] $Dump) {
$input_files = (ForceArray (Select-Xml -Xml $Dump -XPath "//ResourceMetadata/Inputs/Input/@Path")).Node.Value
$output_files = (ForceArray (Select-Xml -Xml $Dump -XPath "//ResourceMetadata/Outputs/Output/@Path")).Node.Value
if (($output_files | Where-Object { -not [System.IO.File]::Exists($_) }) -ne $null) {
return $true
}
$input_file_times = ForceArray ($input_files | ForEach-Object {
[System.IO.FileInfo]::new($_).LastWriteTimeUtc
})
$output_file_times = ForceArray ($output_files | ForEach-Object {
[System.IO.FileInfo]::new($_).LastWriteTimeUtc
})
$outdated = $output_file_times | Where-Object {
$output = $_
$modifieds = $input_file_times | Where-Object {
return $_ -gt $output
}
return $modifieds -ne $null
}
return $outdated -ne $null
}
<#
Given all metadata dumps $ResourceDumps(resource_file_name => Xml dump),
generate $name_to_file_map(resource_name => resource_file_name),
and $name_to_dep_map(resource_name => all dependencies)
#>
function ExtractDeps([HashTable] $ResourceDumps, [HashTable] $name_to_file_map, [HashTable] $name_to_dep_map)
{
$ResourceDumps.Keys | ForEach-Object {
$xml = $ResourceDumps[$_]
$name = (Select-Xml -Xml $xml -XPath "//ResourceMetadata/ResourceMetadata/@Name").Node.Value
if ($name -ne "") {
$attrs = ForceArray (Select-Xml -Xml $xml -XPath "//ResourceMetadata/ResourceMetadata/Dependencies/Resource/@Name")
$deps = ForceArray $attrs.Node.Value
$name_to_file_map[$name] = $_
$name_to_dep_map[$name] = [System.Collections.ArrayList]::new($deps)
}
}
}
<#
Given all metadata dumps $ResourceDumps(resource_file_name => Xml dump),
write all resources that is outdated to $OutputFileName.
#>
function EnumerateBuildCandidates([HashTable] $ResourceDumps, [String] $OutputFileName) {
Write-Host "Finding resource files that need rebuild ..."
$direct_candidates = ForceArray ($ResourceDumps.Keys | Where-Object { NeedBuild $ResourceDumps[$_] })
$name_to_file_map = @{}
$name_to_dep_map = @{}
ExtractDeps $ResourceDumps $name_to_file_map $name_to_dep_map
$file_to_name_map = @{}
$name_to_file_map.Keys | ForEach-Object { $file_to_name_map[$name_to_file_map[$_]] = $_ }
<# Get all names of named resources that are outdated #>
$names = ForceArray ($direct_candidates | Where-Object { $file_to_name_map.ContainsKey($_) } | ForEach-Object { $file_to_name_map[$_] })
$names = [System.Collections.ArrayList]::new($names)
<# Get all names of named resources that are not outdated #>
$pool = ForceArray ($name_to_file_map.Keys | Where-Object { -not $names.Contains($_) })
$pool = [System.Collections.ArrayList]::new($pool)
<# Grow $names from $pool #>
while ($true)
{
<# If any resource in $pool depends on any resource in $name, it is moved from $pool to $names #>
$selection = ForceArray ($pool | Where-Object {
$deps = $name_to_dep_map[$_]
return (ForceArray ($deps | Where-Object { $names.Contains($_) })).Count -ne 0
})
if ($selection.Count -eq 0) { break }
$names.AddRange($selection)
$selection | ForEach-Object { $pool.Remove($_) }
}
<# List all anonymous resource files before named resource files #>
$anonymous_candidates = ForceArray ($direct_candidates | Where-Object { -not $name_to_file_map.ContainsValue($_) })
$named_candidates = ForceArray ($names | ForEach-Object { $name_to_file_map[$_] })
[System.IO.File]::WriteAllLines($OutputFileName, $anonymous_candidates + $named_candidates)
}
<#
Given all metadata dumps $ResourceDumps(resource_file_name => Xml dump),
Write all paths of anonymous resource files to $OutputFileName.
#>
function EnumerateAnonymousResources([HashTable] $ResourceDumps, [String] $OutputFileName) {
Write-Host "Finding anonymouse resource files ..."
$file_names = $ResourceDumps.Keys | Where-Object {
return (ForceArray (Select-Xml -Xml $ResourceDumps[$_] -XPath "//ResourceMetadata/ResourceMetadata/@Name"))[0].Node.Value -eq ""
} | Sort-Object
[System.IO.File]::WriteAllLines($OutputFileName, (ForceArray $file_names))
}
<#
Verify if $name_to_dep_name(resource_name => dependencies) contains any dependencies that are not in this map
#>
function ValidateDeps([HashTable] $name_to_dep_map)
{
$hasError = $false
$name_to_dep_map.Keys | ForEach-Object {
$key = $_
$name_to_dep_map[$key] | ForEach-Object {
if (-not $name_to_dep_map.ContainsKey($key)) {
$hasError = $true
Write-Host "Resource $($key) depends on $($_) but $($_) does not exist."
}
}
}
if ($hasError) { throw "Please check your metadata." }
}
<#
Sort all named resource files in partial order
#>
function SortDeps([HashTable] $name_to_dep_map)
{
$compile_order = [System.Collections.ArrayList]::new()
while ($name_to_dep_map.Count -gt 0) {
$selection = ForceArray ($name_to_dep_map.Keys | Where-Object { $name_to_dep_map[$_].Count -eq 0 })
if ($selection.Count -eq 0) {
Write-Host "Found circle dependency in the following resources:"
$name_to_dep_map.Keys | ForEach-Object { Write-Host " $($_)" }
$hasError = $true;
break
} else {
$compile_order.AddRange((ForceArray ($selection | Select-Object)))
$selection | ForEach-Object {
$ready = $_
$name_to_dep_map.Remove($ready)
$name_to_dep_map.Values | ForEach-Object { $_.Remove($ready) }
}
}
}
if ($hasError) { throw "Please check your metadata." }
return $compile_order
}
<#
Given all metadata dumps $ResourceDumps(resource_file_name => Xml dump),
write all paths of named resource files in the correct build order to $OutputNames,
with all "resource_name=>resource_file_path" to $OutputMapping.
The $OutputMapping will be consumed
GacGen32.exe /P <resource-xml> <HERE>
GacGen32.exe /P <resource-xml> <HERE>
as an optional parameter
#>
function EnumerateNamedResources([HashTable] $ResourceDumps, [String] $OutputNames, [String] $OutputMapping) {
Write-Host "Finding named resource files ..."
$name_to_file_map = @{}
$name_to_dep_map = @{}
ExtractDeps $ResourceDumps $name_to_file_map $name_to_dep_map
ValidateDeps $name_to_dep_map
$compile_order = ForceArray (SortDeps $name_to_dep_map)
$file_names = ForceArray ($compile_order | ForEach-Object {
return $name_to_file_map[$_]
})
$file_mapping = ForceArray ($name_to_file_map.Keys | ForEach-Object {
return "$($_)=>$($name_to_file_map[$_])"
} | Sort-Object)
[System.IO.File]::WriteAllLines($OutputNames, $file_names)
[System.IO.File]::WriteAllLines($OutputMapping, $file_mapping)
}
+17 -12
View File
@@ -1,12 +1,14 @@
param (
[String]$FileName
[Parameter(Mandatory=$true)][String]$FileName,
[String]$MappingFileName
)
. $PSScriptRoot\StartProcess.ps1
Write-Host "Compiling GacUI Resource: $FileName ..."
Start-Process-And-Wait (,("$PSScriptRoot\GacGen32.exe", "/P $FileName"))
Start-Process-And-Wait (,("$PSScriptRoot\GacGen64.exe", "/P $FileName"))
Remove-Item -Path "$($FileName).log" -Recurse -ErrorAction Ignore | Out-Null
Start-Process-And-Wait (,("$PSScriptRoot\GacGen32.exe", "/P $FileName $MappingFileName"))
Start-Process-And-Wait (,("$PSScriptRoot\GacGen64.exe", "/P $FileName $MappingFileName"))
if (Test-Path -Path "$($FileName).log\x32\Errors.txt") {
Write-Host (Get-Content "$($FileName).log\x32\Errors.txt") -ForegroundColor Red -Separator "`r`n"
@@ -17,15 +19,18 @@ if (Test-Path -Path "$($FileName).log\x64\Errors.txt") {
throw "Failed to compile GacUI Resource (x64): $FileName"
}
$output_folder = Get-Content "$($FileName).log\x32\CppOutput.txt"
$x32_folder = "$($FileName).log\x32\Source"
$x64_folder = "$($FileName).log\x64\Source"
if (!(Test-Path -Path $output_folder)) {
New-Item $output_folder -ItemType directory | Out-Null
}
Get-ChildItem -Path $x32_folder -ErrorAction SilentlyContinue | %{
Write-Host " Merging C++ Source File: $($_.Name) ..."
Start-Process-And-Wait (,("$PSScriptRoot\CppMerge.exe", "`"$x32_folder\$($_.Name)`" `"$x64_folder\$($_.Name)`" `"$output_folder\$($_.Name)`""))
$output_cpp = "$($FileName).log\x32\CppOutput.txt"
if (Test-Path -Path $output_cpp) {
$output_folder = Get-Content $output_cpp
$x32_folder = "$($FileName).log\x32\Source"
$x64_folder = "$($FileName).log\x64\Source"
if (!(Test-Path -Path $output_folder)) {
New-Item $output_folder -ItemType directory | Out-Null
}
Get-ChildItem -Path $x32_folder -ErrorAction SilentlyContinue | %{
Write-Host " Merging C++ Source File: $($_.Name) ..."
Start-Process-And-Wait (,("$PSScriptRoot\CppMerge.exe", "`"$x32_folder\$($_.Name)`" `"$x64_folder\$($_.Name)`" `"$output_folder\$($_.Name)`""))
}
}
$deploy = "$($FileName).log\x32\Deploy.bat"
Binary file not shown.
Binary file not shown.
@@ -124,46 +124,25 @@ namespace demo
USERIMPL(/* ::demo::DocumentEditorBase */)
void DocumentEditorBase::LoadAsPrivateFormat(const ::vl::WString& fileName)
{
vl::stream::FileStream fileStream(fileName, vl::stream::FileStream::ReadOnly);
auto model = vl::presentation::LoadDocumentFromClipboardStream(fileStream);
document->SetDocument(model);
throw ::vl::Exception(L"You should implement this function.");
}
USERIMPL(/* ::demo::DocumentEditorBase */)
void DocumentEditorBase::SaveAsPrivateFormat(const ::vl::WString& fileName)
{
document->SelectAll();
auto model = document->GetSelectionModel();
vl::presentation::ModifyDocumentForClipboard(model);
vl::stream::FileStream fileStream(fileName, vl::stream::FileStream::WriteOnly);
vl::presentation::SaveDocumentToClipboardStream(model, fileStream);
throw ::vl::Exception(L"You should implement this function.");
}
USERIMPL(/* ::demo::DocumentEditorBase */)
void DocumentEditorBase::SaveAsRTF(const ::vl::WString& fileName)
{
document->SelectAll();
auto model = document->GetSelectionModel();
vl::AString rtf;
vl::presentation::SaveDocumentToRtf(model, rtf);
vl::stream::FileStream fileStream(fileName, vl::stream::FileStream::WriteOnly);
fileStream.Write((void*)rtf.Buffer(), rtf.Length());
throw ::vl::Exception(L"You should implement this function.");
}
USERIMPL(/* ::demo::DocumentEditorBase */)
void DocumentEditorBase::SaveAsHTML(const ::vl::WString& fileName)
{
document->SelectAll();
auto model = document->GetSelectionModel();
vl::AString header, content, footer;
vl::presentation::SaveDocumentToHtmlUtf8(model, header, content, footer);
vl::stream::FileStream fileStream(fileName, vl::stream::FileStream::WriteOnly);
fileStream.Write((void*)header.Buffer(), header.Length());
fileStream.Write((void*)content.Buffer(), content.Length());
fileStream.Write((void*)footer.Buffer(), footer.Length());
throw ::vl::Exception(L"You should implement this function.");
}
void DocumentEditorBase::SaveDocument()
Binary file not shown.
Binary file not shown.