|
8 | 8 | [string[]]$PackageNames,
|
9 | 9 | [Parameter(ParameterSetName = 'PackageInfo')]
|
10 | 10 | [string]$PackageInfoDirectory,
|
11 |
| - [switch]$NoVerify |
| 11 | + [switch]$Verify |
12 | 12 | )
|
13 | 13 |
|
14 | 14 | $ErrorActionPreference = 'Stop'
|
@@ -80,8 +80,8 @@ function Get-CargoPackages() {
|
80 | 80 | }
|
81 | 81 |
|
82 | 82 | function Get-PackagesToBuild() {
|
83 |
| - $packages = Get-CargoPackages |
84 |
| - $outputPackageNames = Get-OutputPackageNames $packages |
| 83 | + [array]$packages = Get-CargoPackages |
| 84 | + [array]$outputPackageNames = Get-OutputPackageNames $packages |
85 | 85 |
|
86 | 86 | # We start with output packages, then recursively add unreleased dependencies to the list of packages that need to be built
|
87 | 87 | [array]$packagesToBuild = $packages | Where-Object { $outputPackageNames.Contains($_.name) }
|
@@ -126,105 +126,151 @@ function Get-PackagesToBuild() {
|
126 | 126 | return $buildOrder
|
127 | 127 | }
|
128 | 128 |
|
129 |
| -function Initialize-VendorDirectory() { |
130 |
| - $path = "$RepoRoot/target/vendor" |
131 |
| - Invoke-LoggedCommand "cargo vendor $path" -GroupOutput | Out-Host |
132 |
| - return $path |
133 |
| -} |
| 129 | +# https://doc.rust-lang.org/cargo/reference/registry-web-api.html#publish |
| 130 | +# https://github.com/rust-lang/cargo/blob/5c87c14f9a162daf10d4133fdaab35c72d67b018/crates/crates-io/lib.rs#L42 |
| 131 | +function Get-ApiMetadata($package) { |
| 132 | + $packagePath = Split-Path -Path $package.manifest_path -Parent |
| 133 | + $readmePath = $package.readme ? (Join-Path -Path $packagePath -ChildPath $package.readme) : $null |
| 134 | + |
| 135 | + $jsonBody = [ordered]@{ |
| 136 | + 'name' = $package.name |
| 137 | + 'vers' = $package.version |
| 138 | + 'deps' = @() |
| 139 | + 'features' = $package.features |
| 140 | + 'authors' = $package.authors |
| 141 | + 'description' = $package.description |
| 142 | + 'documentation' = $package.documentation |
| 143 | + 'homepage' = $package.homepage |
| 144 | + 'readme' = if ($readmePath -and (Test-Path -Path $readmePath)) { |
| 145 | + Get-Content -Path $readmePath -Raw |
| 146 | + } |
| 147 | + else { |
| 148 | + $null |
| 149 | + } |
| 150 | + 'readme_file' = $package.readme |
| 151 | + 'keywords' = $package.keywords |
| 152 | + 'categories' = $package.categories |
| 153 | + 'license' = $package.license |
| 154 | + 'license_file' = $package.license_file |
| 155 | + 'repository' = $package.repository |
| 156 | + 'links' = $package.links |
| 157 | + 'rust_version' = $package.rust_version |
| 158 | + } |
134 | 159 |
|
135 |
| -function Add-CrateToLocalRegistry($LocalRegistryPath, $Package) { |
136 |
| - $packageName = $Package.name |
137 |
| - $packageVersion = $Package.version |
| 160 | + foreach ($dependency in $package.dependencies) { |
| 161 | + $jsonBody.deps += @{ |
| 162 | + 'name' = $dependency.name |
| 163 | + 'version_req' = $dependency.req |
| 164 | + 'features' = $dependency.features |
| 165 | + 'optional' = $dependency.optional |
| 166 | + 'default_features' = $dependency.default_features |
| 167 | + 'target' = $dependency.target |
| 168 | + 'kind' = $dependency.kind |
| 169 | + 'explicit_name_in_toml' = $dependency.rename |
| 170 | + } |
| 171 | + } |
| 172 | + |
| 173 | + return $jsonBody |
| 174 | +} |
138 | 175 |
|
139 |
| - # create an index entry for the package |
140 |
| - $packagePath = "$RepoRoot/target/package/$packageName-$packageVersion" |
| 176 | +function New-ApiPutFile($crateMetadata, $crateFilePath) { |
| 177 | + $metadataBytes = [Text.Encoding]::Utf8.GetBytes($crateMetadata) |
| 178 | + $metadataLengthBytes = [BitConverter]::GetBytes([UInt32]$metadataBytes.Length) |
| 179 | + $crateBytes = [IO.File]::ReadAllBytes($crateFilePath) |
| 180 | + $crateLengthBytes = [BitConverter]::GetBytes([UInt32]$crateBytes.Length) |
141 | 181 |
|
142 |
| - Write-Host "Copying package '$packageName' to vendor directory '$LocalRegistryPath'" |
143 |
| - Copy-Item -Path $packagePath -Destination $LocalRegistryPath -Recurse |
| 182 | + $bytes += $metadataLengthBytes + $metadataBytes + $crateLengthBytes + $crateBytes |
144 | 183 |
|
145 |
| - #write an empty checksum file |
146 |
| - '{"files":{}}' | Out-File -FilePath "$LocalRegistryPath/$packageName-$packageVersion/.cargo-checksum.json" -Encoding utf8 |
| 184 | + return $bytes |
147 | 185 | }
|
148 | 186 |
|
149 |
| -# For all dependencies with paths, but no versions, add the version from the path |
150 |
| -function Add-PathVersions($packages) { |
151 |
| - # Install PSToml if it's not already installed |
152 |
| - if (-not (PowerShellGet\Get-InstalledModule -Name PSToml -ErrorAction SilentlyContinue)) { |
153 |
| - PowerShellGet\Install-Module -Name PSToml -Scope CurrentUser -Force |
154 |
| - } |
| 187 | +function Create-ApiReview($package) { |
| 188 | + $command = "cargo run --manifest-path $RepoRoot/eng/tools/generate_api_report/Cargo.toml -- --package $($package.name)" |
| 189 | + Invoke-LoggedCommand $command -GroupOutput | Out-Host |
155 | 190 |
|
156 |
| - foreach ($package in $packages) { |
157 |
| - $dirty = $false |
158 |
| - $toml = Get-Content -Path $Package.manifest_path -Raw | ConvertFrom-Toml |
159 |
| - |
160 |
| - foreach ($name in $toml.dependencies.Keys) { |
161 |
| - # we want to look at the dependency as it was resolved by `cargo metadata` |
162 |
| - # this will resolve workspace depdencies, but retain their path/no-version state |
163 |
| - $dependency = $package.dependencies | Where-Object -Property name -EQ -Value $name | Select-Object -First 1 |
164 |
| - # If the dependency is a path dependency, set the version to the version of the package in the workspace |
165 |
| - if ($dependency.path -and !$dependency.version) { |
166 |
| - $tomlDependency = $toml.dependencies.$name |
167 |
| - $dependencyVersion = $packages | Where-Object -Property name -EQ -Value $name | Select-Object -ExpandProperty version -First 1 |
168 |
| - |
169 |
| - $tomlDependency.version = $dependencyVersion |
170 |
| - $dirty = $true |
171 |
| - } |
172 |
| - } |
173 |
| - if ($dirty) { |
174 |
| - $toml | ConvertTo-Toml -Depth 10 | Set-Content -Path $Package.manifest_path -Encoding utf8 |
175 |
| - } |
176 |
| - } |
| 191 | + $packagePath = Split-Path -Path $package.manifest_path -Parent |
| 192 | + |
| 193 | + "$packagePath/review/$($package.name).rust.json" |
177 | 194 | }
|
178 | 195 |
|
179 | 196 | Push-Location $RepoRoot
|
180 | 197 | try {
|
181 |
| - $localRegistryPath = Initialize-VendorDirectory |
182 |
| - |
183 | 198 | [array]$packages = Get-PackagesToBuild
|
184 | 199 |
|
185 |
| - Write-Host "Building packages in the following order:" |
| 200 | + $command = "cargo +nightly -Zpackage-workspace package --allow-dirty --locked" |
| 201 | + |
| 202 | + Write-Host "Building packages:" |
186 | 203 | foreach ($package in $packages) {
|
187 | 204 | $packageName = $package.name
|
188 | 205 | $type = if ($package.OutputPackage) { "output" } else { "dependency" }
|
189 | 206 | Write-Host " $packageName ($type)"
|
| 207 | + $command += " --package $packageName" |
190 | 208 | }
|
191 | 209 |
|
192 |
| - foreach ($package in $packages) { |
193 |
| - Write-Host "" |
| 210 | + if (!$Verify) { |
| 211 | + $command += " --no-verify" |
| 212 | + } |
| 213 | + |
| 214 | + if ($env:SYSTEM_DEBUG -eq 'true') { |
| 215 | + Write-Host "##[group] $RepoRoot/Cargo.lock" |
| 216 | + Get-Content "$RepoRoot/Cargo.lock" |
| 217 | + Write-Host "##[endgroup]" |
| 218 | + } |
| 219 | + |
| 220 | + Invoke-LoggedCommand -Command $command -GroupOutput |
| 221 | + |
| 222 | + if ($env:SYSTEM_DEBUG -eq 'true') { |
| 223 | + Write-Host "##[group] $RepoRoot/Cargo.lock" |
| 224 | + Get-Content "$RepoRoot/Cargo.lock" |
| 225 | + Write-Host "##[endgroup]" |
| 226 | + } |
194 | 227 |
|
| 228 | + foreach ($package in $packages) { |
195 | 229 | $packageName = $package.name
|
196 | 230 | $packageVersion = $package.version
|
197 | 231 |
|
198 |
| - $command = "cargo publish --locked --dry-run --package $packageName --registry crates-io --config `"source.crates-io.replace-with='local'`" --config `"source.local.directory='$localRegistryPath'`" --allow-dirty" |
| 232 | + if ($OutputPath -and $package.OutputPackage) { |
| 233 | + Write-Host "`nProcessing package '$($package.name)'" |
199 | 234 |
|
200 |
| - if ($NoVerify) { |
201 |
| - $command += " --no-verify" |
202 |
| - } |
| 235 | + $sourceCrateFile = "$RepoRoot/target/package/$packageName-$packageVersion.crate" |
203 | 236 |
|
204 |
| - Invoke-LoggedCommand -Command $command -GroupOutput |
| 237 | + New-Item -ItemType Directory -Path "$OutputPath/$packageName" -Force | Out-Null |
205 | 238 |
|
| 239 | + $targetExpandedDirectory = "$OutputPath/$packageName/contents" |
| 240 | + $targetCrateFile = "$OutputPath/$packageName/$packageName-$packageVersion.crate" |
| 241 | + $targetJsonFile = "$OutputPath/$packageName/$packageName-$packageVersion.json" |
| 242 | + $targetBinFile = "$OutputPath/$packageName/$packageName.bin" |
| 243 | + $targetApiReviewFile = "$OutputPath/$packageName/$packageName`_rust.json" |
206 | 244 |
|
207 |
| - # copy the package to the local registry |
208 |
| - Add-CrateToLocalRegistry ` |
209 |
| - -LocalRegistryPath $localRegistryPath ` |
210 |
| - -Package $package |
| 245 | + Write-Host "Copying crate file to '$targetCrateFile'" |
| 246 | + Copy-Item -Path $sourceCrateFile -Destination $targetCrateFile -Force |
211 | 247 |
|
212 |
| - if ($OutputPath -and $package.OutputPackage) { |
213 |
| - $packageOutputPath = "$OutputPath/$packageName" |
214 |
| - $targetPackagePath = "$RepoRoot/target/package/$packageName-$packageVersion" |
| 248 | + $crateMetadata = Get-ApiMetadata $package | ConvertTo-Json -Depth 10 |
215 | 249 |
|
216 |
| - if (Test-Path -Path $packageOutputPath) { |
217 |
| - Remove-Item -Path $packageOutputPath -Recurse -Force |
| 250 | + Write-Host "Writing crates.io request metadata to '$targetJsonFile'" |
| 251 | + $crateMetadata | Out-File -FilePath "$targetJsonFile" -Encoding utf8 |
| 252 | + |
| 253 | + $uploadBytes = New-ApiPutFile $crateMetadata $sourceCrateFile |
| 254 | + Write-Host "Writing crates.io request bundle to '$targetBinFile'" |
| 255 | + [IO.File]::WriteAllBytes($targetBinFile, $uploadBytes) |
| 256 | + |
| 257 | + if (Test-Path $targetExpandedDirectory) { |
| 258 | + Write-Host "Removing existing directory '$targetExpandedDirectory'" |
| 259 | + Remove-Item -Path $targetExpandedDirectory -Recurse -Force |
218 | 260 | }
|
219 | 261 |
|
220 |
| - Write-Host "Copying package '$packageName' to '$packageOutputPath'" |
221 |
| - New-Item -ItemType Directory -Path $packageOutputPath -Force | Out-Null |
222 |
| - Copy-Item -Path $targetPackagePath/* -Destination $packageOutputPath -Recurse -Exclude "Cargo.toml.orig" |
| 262 | + Write-Host "Exctracting crate file to '$targetExpandedDirectory'" |
| 263 | + New-Item -ItemType Directory -Path $targetExpandedDirectory -Force | Out-Null |
| 264 | + tar -xf $sourceCrateFile --directory $targetExpandedDirectory --strip-components=1 |
| 265 | + |
| 266 | + |
| 267 | + Write-Host "Creating API review file" |
| 268 | + $apiReviewFile = Create-ApiReview $package |
| 269 | + |
| 270 | + Write-Host "Copying API review file to '$targetApiReviewFile'" |
| 271 | + Copy-Item -Path $apiReviewFile -Destination $targetApiReviewFile -Force |
223 | 272 | }
|
224 | 273 | }
|
225 |
| - |
226 |
| - Write-Host "Removing local registry" |
227 |
| - Remove-Item -Path $localRegistryPath -Recurse -Force | Out-Null |
228 | 274 | }
|
229 | 275 | finally {
|
230 | 276 | Pop-Location
|
|
0 commit comments