Skip to content

Commit 69d5601

Browse files
authored
Merge pull request #340 from SteveL-MSFT/msix
enable building msix package
2 parents 3119292 + d4962e3 commit 69d5601

File tree

11 files changed

+252
-86
lines changed

11 files changed

+252
-86
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ Cargo.lock
22
target
33
bin/
44
.DS_Store
5+
*.msix
56

67
# Node.js generated files for tree-sitter
78
build/

build.ps1

Lines changed: 172 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ param(
66
[ValidateSet('current','aarch64-pc-windows-msvc','x86_64-pc-windows-msvc','aarch64-apple-darwin','x86_64-apple-darwin','aarch64-unknown-linux-gnu','aarch64-unknown-linux-musl','x86_64-unknown-linux-gnu','x86_64-unknown-linux-musl')]
77
$architecture = 'current',
88
[switch]$Clippy,
9+
[switch]$SkipBuild,
10+
[switch]$Msix,
911
[switch]$Test,
1012
[switch]$GetPackageVersion,
1113
[switch]$SkipLinkCheck
@@ -52,7 +54,7 @@ function Find-LinkExe {
5254
}
5355
}
5456

55-
if (!$SkipLinkCheck -and $IsWindows -and !(Get-Command 'link.exe' -ErrorAction Ignore)) {
57+
if (!$SkipBuild -and !$SkipLinkCheck -and $IsWindows -and !(Get-Command 'link.exe' -ErrorAction Ignore)) {
5658
if (!(Test-Path $BuildToolsPath)) {
5759
Write-Verbose -Verbose "link.exe not found, installing C++ build tools"
5860
Invoke-WebRequest 'https://aka.ms/vs/17/release/vs_BuildTools.exe' -OutFile 'temp:/vs_buildtools.exe'
@@ -83,7 +85,6 @@ if (!$SkipLinkCheck -and $IsWindows -and !(Get-Command 'link.exe' -ErrorAction I
8385
#$env:PATH += ";$linkexe"
8486
}
8587

86-
## Create the output folder
8788
$configuration = $Release ? 'release' : 'debug'
8889
$flags = @($Release ? '-r' : $null)
8990
if ($architecture -eq 'current') {
@@ -98,13 +99,14 @@ else {
9899
$target = Join-Path $PSScriptRoot 'bin' $architecture $configuration
99100
}
100101

101-
if (Test-Path $target) {
102-
Remove-Item $target -Recurse -ErrorAction Stop
103-
}
104-
New-Item -ItemType Directory $target > $null
102+
if (!$SkipBuild) {
103+
if (Test-Path $target) {
104+
Remove-Item $target -Recurse -ErrorAction Stop
105+
}
106+
New-Item -ItemType Directory $target > $null
105107

106-
# make sure dependencies are built first so clippy runs correctly
107-
$windows_projects = @("pal", "ntreg", "ntstatuserror", "ntuserinfo", "registry")
108+
# make sure dependencies are built first so clippy runs correctly
109+
$windows_projects = @("pal", "ntreg", "ntstatuserror", "ntuserinfo", "registry")
108110

109111
# projects are in dependency order
110112
$projects = @(
@@ -125,74 +127,73 @@ $pedantic_unclean_projects = @("ntreg")
125127
$clippy_unclean_projects = @("tree-sitter-dscexpression")
126128
$skip_test_projects_on_windows = @("tree-sitter-dscexpression")
127129

128-
if ($IsWindows) {
129-
$projects += $windows_projects
130-
}
130+
if ($IsWindows) {
131+
$projects += $windows_projects
132+
}
131133

132-
$failed = $false
133-
foreach ($project in $projects) {
134-
## Build format_json
135-
Write-Host -ForegroundColor Cyan "Building $project ... for $architecture"
136-
try {
137-
Push-Location "$PSScriptRoot/$project" -ErrorAction Stop
134+
$failed = $false
135+
foreach ($project in $projects) {
136+
## Build format_json
137+
Write-Host -ForegroundColor Cyan "Building $project ... for $architecture"
138+
try {
139+
Push-Location "$PSScriptRoot/$project" -ErrorAction Stop
138140

139-
if ($project -eq 'tree-sitter-dscexpression') {
140-
./build.ps1
141-
}
141+
if ($project -eq 'tree-sitter-dscexpression') {
142+
./build.ps1
143+
}
142144

143-
if (Test-Path "./Cargo.toml")
144-
{
145-
if ($Clippy) {
146-
if ($clippy_unclean_projects -contains $project) {
147-
Write-Verbose -Verbose "Skipping clippy for $project"
148-
}
149-
elseif ($pedantic_unclean_projects -contains $project) {
150-
Write-Verbose -Verbose "Running clippy for $project"
151-
cargo clippy @flags -- -Dwarnings
145+
if (Test-Path "./Cargo.toml")
146+
{
147+
if ($Clippy) {
148+
if ($clippy_unclean_projects -contains $project) {
149+
Write-Verbose -Verbose "Skipping clippy for $project"
150+
}
151+
elseif ($pedantic_unclean_projects -contains $project) {
152+
Write-Verbose -Verbose "Running clippy for $project"
153+
cargo clippy @flags -- -Dwarnings
154+
}
155+
else {
156+
Write-Verbose -Verbose "Running clippy with pedantic for $project"
157+
cargo clippy @flags --% -- -Dwarnings -Dclippy::pedantic
158+
}
152159
}
153160
else {
154-
Write-Verbose -Verbose "Running clippy with pedantic for $project"
155-
cargo clippy @flags --% -- -Dwarnings -Dclippy::pedantic
161+
cargo build @flags
156162
}
157163
}
158-
else {
159-
cargo build @flags
160-
}
161-
}
162164

163-
if ($LASTEXITCODE -ne 0) {
164-
$failed = $true
165-
}
165+
if ($LASTEXITCODE -ne 0) {
166+
$failed = $true
167+
}
166168

167-
$binary = Split-Path $project -Leaf
169+
$binary = Split-Path $project -Leaf
168170

169-
if ($IsWindows) {
170-
Copy-Item "$path/$binary.exe" $target -ErrorAction Ignore
171-
}
172-
else {
173-
Copy-Item "$path/$binary" $target -ErrorAction Ignore
174-
}
171+
if ($IsWindows) {
172+
Copy-Item "$path/$binary.exe" $target -ErrorAction Ignore
173+
}
174+
else {
175+
Copy-Item "$path/$binary" $target -ErrorAction Ignore
176+
}
175177

176-
if (Test-Path "./copy_files.txt") {
177-
Get-Content "./copy_files.txt" | ForEach-Object {
178-
Copy-Item $_ $target -Force -ErrorAction Ignore
178+
if (Test-Path "./copy_files.txt") {
179+
Get-Content "./copy_files.txt" | ForEach-Object {
180+
Copy-Item $_ $target -Force -ErrorAction Ignore
181+
}
179182
}
180-
}
181183

182-
Copy-Item "*.dsc.resource.json" $target -Force -ErrorAction Ignore
184+
Copy-Item "*.dsc.resource.json" $target -Force -ErrorAction Ignore
183185

184-
} finally {
185-
Pop-Location
186+
} finally {
187+
Pop-Location
188+
}
186189
}
187-
}
188190

189-
if ($failed) {
190-
Write-Host -ForegroundColor Red "Build failed"
191-
exit 1
191+
if ($failed) {
192+
Write-Host -ForegroundColor Red "Build failed"
193+
exit 1
194+
}
192195
}
193196

194-
Copy-Item $PSScriptRoot/tools/add-path.ps1 $target -Force -ErrorAction Ignore
195-
196197
$relative = Resolve-Path $target -Relative
197198
if (!$Clippy) {
198199
Write-Host -ForegroundColor Green "`nEXE's are copied to $target ($relative)"
@@ -221,7 +222,7 @@ if (!$Clippy) {
221222

222223
if (!$found) {
223224
Write-Host -ForegroundCOlor Yellow "Adding $target to `$env:PATH"
224-
$env:PATH += [System.IO.Path]::PathSeparator + $target
225+
$env:PATH = $target + [System.IO.Path]::PathSeparator + $env:PATH
225226
}
226227
}
227228

@@ -293,4 +294,116 @@ if ($Test) {
293294
Invoke-Pester -ErrorAction Stop
294295
}
295296

297+
if ($Msix) {
298+
if (!$IsWindows) {
299+
throw "MSIX is only supported on Windows"
300+
}
301+
302+
if ($architecture -eq 'current') {
303+
throw 'MSIX requires a specific architecture'
304+
}
305+
306+
$makeappx = Get-Command makeappx -CommandType Application -ErrorAction Ignore
307+
if ($null -eq $makeappx) {
308+
# try to find
309+
if ($architecture -eq 'aarch64-pc-windows-msvc') {
310+
$arch = 'arm64'
311+
}
312+
else {
313+
$arch = 'x64'
314+
}
315+
316+
$makeappx = Get-ChildItem -Recurse -Path (Join-Path ${env:ProgramFiles(x86)} 'Windows Kits\10\bin\*\' $arch) -Filter makeappx.exe | Sort-Object FullName -Descending | Select-Object -First 1
317+
if ($null -eq $makeappx) {
318+
throw "makeappx not found, please install Windows SDK"
319+
}
320+
}
321+
322+
$makepri = Get-Item (Join-Path $makeappx.Directory "makepri.exe") -ErrorAction Stop
323+
$displayName = "DesiredStateConfiguration"
324+
$productVersion = ((Get-Content $PSScriptRoot/dsc/Cargo.toml) -match '^version\s*=\s*') -replace 'version\s*=\s*"(.*?)"', '$1'
325+
$isPreview = $productVersion -like '*-*'
326+
$productName = "DesiredStateConfiguration"
327+
if ($isPreview) {
328+
Write-Verbose -Verbose "Preview version detected"
329+
$productName += "-Preview"
330+
# save preview number
331+
$previewNumber = $productVersion -replace '.*?-[a-z]+\.([0-9]+)', '$1'
332+
# remove label from version
333+
$productVersion = $productVersion.Split('-')[0]
334+
# replace revision number with preview number
335+
$productVersion = $productVersion -replace '(\d+)$', "$previewNumber.0"
336+
$displayName += "-Preview"
337+
}
338+
Write-Verbose -Verbose "Product version is $productVersion"
339+
$arch = if ($architecture -eq 'aarch64-pc-windows-msvc') { 'arm64' } else { 'x64' }
340+
341+
# Appx manifest needs to be in root of source path, but the embedded version needs to be updated
342+
# cp-459155 is 'CN=Microsoft Windows Store Publisher (Store EKU), O=Microsoft Corporation, L=Redmond, S=Washington, C=US'
343+
# authenticodeFormer is 'CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US'
344+
$releasePublisher = 'CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US'
345+
346+
$appxManifest = Get-Content "$PSScriptRoot\packaging\msix\AppxManifest.xml" -Raw
347+
$appxManifest = $appxManifest.Replace('$VERSION$', $ProductVersion).Replace('$ARCH$', $Arch).Replace('$PRODUCTNAME$', $productName).Replace('$DISPLAYNAME$', $displayName).Replace('$PUBLISHER$', $releasePublisher)
348+
$msixTarget = Join-Path $PSScriptRoot 'bin' $architecture 'msix'
349+
if (Test-Path $msixTarget) {
350+
Remove-Item $msixTarget -Recurse -ErrorAction Stop
351+
}
352+
353+
New-Item -ItemType Directory $msixTarget > $null
354+
Set-Content -Path "$msixTarget\AppxManifest.xml" -Value $appxManifest -Force
355+
356+
$filesForMsix = @(
357+
'dsc.exe',
358+
'assertion.dsc.resource.json',
359+
'group.dsc.resource.json',
360+
'parallel.dsc.resource.json',
361+
'powershellgroup.dsc.resource.json',
362+
'powershellgroup.resource.ps1',
363+
'wmigroup.dsc.resource.json.optout',
364+
'wmigroup.resource.ps1'
365+
)
366+
367+
foreach ($file in $filesForMsix) {
368+
Copy-Item "$target\$file" $msixTarget -ErrorAction Stop
369+
}
370+
371+
# Necessary image assets need to be in source assets folder
372+
$assets = @(
373+
'Square150x150Logo'
374+
'Square64x64Logo'
375+
'Square44x44Logo'
376+
'Square44x44Logo.targetsize-48'
377+
'Square44x44Logo.targetsize-48_altform-unplated'
378+
'StoreLogo'
379+
)
380+
381+
New-Item -ItemType Directory "$msixTarget\assets" > $null
382+
foreach ($asset in $assets) {
383+
Copy-Item "$PSScriptRoot\packaging\assets\$asset.png" "$msixTarget\assets" -ErrorAction Stop
384+
}
385+
386+
Write-Verbose "Creating priconfig.xml" -Verbose
387+
& $makepri createconfig /o /cf (Join-Path $msixTarget "priconfig.xml") /dq en-US
388+
if ($LASTEXITCODE -ne 0) {
389+
throw "Failed to create priconfig.xml"
390+
}
391+
392+
Write-Verbose "Creating resources.pri" -Verbose
393+
Push-Location $msixTarget
394+
& $makepri new /v /o /pr $msixTarget /cf (Join-Path $msixTarget "priconfig.xml")
395+
Pop-Location
396+
if ($LASTEXITCODE -ne 0) {
397+
throw "Failed to create resources.pri"
398+
}
399+
400+
Write-Verbose "Creating msix package" -Verbose
401+
$packageName = "$productName-$productVersion-$arch"
402+
& $makeappx pack /o /v /h SHA256 /d $msixTarget /p (Join-Path -Path (Get-Location) -ChildPath "$packageName.msix")
403+
if ($LASTEXITCODE -ne 0) {
404+
throw "Failed to create msix package"
405+
}
406+
Write-Verbose "Created $packageName.msix" -Verbose
407+
}
408+
296409
$env:RUST_BACKTRACE=1

dsc_lib/src/discovery/command_discovery.rs

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use std::fs::File;
1414
use std::io::BufReader;
1515
use std::path::Path;
1616
use std::time::Duration;
17-
use tracing::{debug, error, warn};
17+
use tracing::{debug, error, trace, warn};
1818

1919
pub struct CommandDiscovery {
2020
}
@@ -28,6 +28,7 @@ impl CommandDiscovery {
2828
#[allow(clippy::too_many_lines)]
2929
fn search_for_resources(required_resource_types: &[String]) -> Result<BTreeMap<String, DscResource>, DscError>
3030
{
31+
debug!("Searching for resources: {:?}", required_resource_types);
3132
let return_all_resources = required_resource_types.len() == 1 && required_resource_types[0] == "*";
3233

3334
let multi_progress_bar = MultiProgress::new();
@@ -53,20 +54,37 @@ impl CommandDiscovery {
5354
let mut resources: BTreeMap<String, DscResource> = BTreeMap::new();
5455
let mut adapter_resources: Vec<String> = Vec::new();
5556
let mut remaining_required_resource_types = required_resource_types.to_owned();
57+
let mut using_custom_path = false;
58+
5659
// try DSC_RESOURCE_PATH env var first otherwise use PATH
57-
let path_env = match env::var_os("DSC_RESOURCE_PATH") {
58-
Some(value) => value,
59-
None => {
60-
match env::var_os("PATH") {
61-
Some(value) => value,
62-
None => {
63-
return Err(DscError::Operation("Failed to get PATH environment variable".to_string()));
64-
}
60+
let path_env = if let Some(value) = env::var_os("DSC_RESOURCE_PATH") {
61+
debug!("Using DSC_RESOURCE_PATH: {:?}", value.to_string_lossy());
62+
using_custom_path = true;
63+
value
64+
} else {
65+
trace!("DSC_RESOURCE_PATH not set, trying PATH");
66+
match env::var_os("PATH") {
67+
Some(value) => {
68+
debug!("Using PATH: {:?}", value.to_string_lossy());
69+
value
70+
},
71+
None => {
72+
return Err(DscError::Operation("Failed to get PATH environment variable".to_string()));
6573
}
6674
}
6775
};
6876

69-
for path in env::split_paths(&path_env) {
77+
let mut paths = env::split_paths(&path_env).collect::<Vec<_>>();
78+
79+
// add exe home to start of path
80+
if !using_custom_path {
81+
if let Some(exe_home) = env::current_exe()?.parent() {
82+
debug!("Adding exe home to path: {}", exe_home.to_string_lossy());
83+
paths.insert(0, exe_home.to_path_buf());
84+
}
85+
}
86+
87+
for path in paths {
7088
if path.exists() && path.is_dir() {
7189
for entry in path.read_dir().unwrap() {
7290
let entry = entry.unwrap();
57.1 KB
Loading
6.29 KB
Loading
6.29 KB
Loading
6.29 KB
Loading
12.2 KB
Loading

packaging/assets/StoreLogo.png

12.2 KB
Loading

0 commit comments

Comments
 (0)