mirror of
https://github.com/laosb/SwiftTailwind.git
synced 2025-11-29 06:11:38 +00:00
Compare commits
No commits in common. "main" and "1.1.0.test.1+tw.4.1.14" have entirely different histories.
main
...
1.1.0.test
9 changed files with 106 additions and 265 deletions
22
.github/workflows/ci.yml
vendored
22
.github/workflows/ci.yml
vendored
|
|
@ -12,22 +12,13 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
swift-version: ["6.1", "6.2"]
|
swift-version: ["6.1"]
|
||||||
container:
|
container:
|
||||||
image: swift:${{ matrix.swift-version }}
|
image: swift:${{ matrix.swift-version }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Cache Swift packages
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: .build
|
|
||||||
key: ${{ runner.os }}-spm-${{ matrix.swift-version }}-${{ hashFiles('**/Package.resolved') }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-spm-${{ matrix.swift-version }}-
|
|
||||||
${{ runner.os }}-spm-
|
|
||||||
|
|
||||||
- name: Build package
|
- name: Build package
|
||||||
run: swift build --verbose
|
run: swift build --verbose
|
||||||
|
|
||||||
|
|
@ -39,7 +30,7 @@ jobs:
|
||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
swift-version: ["6.1", "6.2"]
|
swift-version: ["6.1"]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
@ -49,15 +40,6 @@ jobs:
|
||||||
with:
|
with:
|
||||||
swift-version: ${{ matrix.swift-version }}
|
swift-version: ${{ matrix.swift-version }}
|
||||||
|
|
||||||
- name: Cache Swift packages
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: .build
|
|
||||||
key: ${{ runner.os }}-spm-${{ matrix.swift-version }}-${{ hashFiles('**/Package.resolved') }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-spm-${{ matrix.swift-version }}-
|
|
||||||
${{ runner.os }}-spm-
|
|
||||||
|
|
||||||
- name: Build package
|
- name: Build package
|
||||||
run: swift build --verbose
|
run: swift build --verbose
|
||||||
|
|
||||||
|
|
|
||||||
104
.github/workflows/release-tailwindcss-cli.yml
vendored
104
.github/workflows/release-tailwindcss-cli.yml
vendored
|
|
@ -1,104 +0,0 @@
|
||||||
name: Release TailwindCSS CLI Artifacts
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
tailwind_version:
|
|
||||||
description: "TailwindCSS release version (e.g., v4.1.14)"
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build-and-release:
|
|
||||||
name: Build and Release Artifacts
|
|
||||||
runs-on: macos-latest
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Setup Swift
|
|
||||||
uses: swift-actions/setup-swift@v2
|
|
||||||
with:
|
|
||||||
swift-version: "6.1"
|
|
||||||
|
|
||||||
- name: Cache Swift packages
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: .build
|
|
||||||
key: ${{ runner.os }}-spm-release-${{ hashFiles('**/Package.resolved') }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-spm-release-
|
|
||||||
${{ runner.os }}-spm-
|
|
||||||
|
|
||||||
- name: Validate version format
|
|
||||||
run: |
|
|
||||||
if [[ ! "${{ inputs.tailwind_version }}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
||||||
echo "Error: Version must be in format vX.Y.Z (e.g., v4.1.14)"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "Version format is valid: ${{ inputs.tailwind_version }}"
|
|
||||||
|
|
||||||
- name: Build artifact bundler
|
|
||||||
run: |
|
|
||||||
echo "Building TailwindCSSCLIArtifactBundler..."
|
|
||||||
swift build -c release --product TailwindCSSCLIArtifactBundler
|
|
||||||
|
|
||||||
- name: Create artifact bundles
|
|
||||||
run: |
|
|
||||||
echo "Creating artifact bundles for TailwindCSS ${{ inputs.tailwind_version }}..."
|
|
||||||
mkdir -p ./artifacts
|
|
||||||
.build/release/TailwindCSSCLIArtifactBundler \
|
|
||||||
--version "${{ inputs.tailwind_version }}" \
|
|
||||||
--work-dir "${{ runner.temp }}/tailwindcss-bundles" \
|
|
||||||
--output-dir ./artifacts
|
|
||||||
|
|
||||||
- name: List generated artifacts
|
|
||||||
run: |
|
|
||||||
echo "Generated artifacts:"
|
|
||||||
ls -lh artifacts/
|
|
||||||
|
|
||||||
- name: Compute checksum
|
|
||||||
id: checksum
|
|
||||||
run: |
|
|
||||||
CHECKSUM=$(shasum -a 256 artifacts/tailwindcss.artifactbundleindex | awk '{print $1}')
|
|
||||||
echo "checksum=$CHECKSUM" >> $GITHUB_OUTPUT
|
|
||||||
echo "Artifact bundle index checksum: $CHECKSUM"
|
|
||||||
|
|
||||||
- name: Create release
|
|
||||||
uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 # v2.4.1
|
|
||||||
with:
|
|
||||||
tag_name: TailwindCSSCLI-${{ inputs.tailwind_version }}
|
|
||||||
name: TailwindCSS CLI ${{ inputs.tailwind_version }}
|
|
||||||
body: |
|
|
||||||
## TailwindCSS CLI Artifact Bundles
|
|
||||||
|
|
||||||
This release contains Swift Package Manager artifact bundles for TailwindCSS CLI version `${{ inputs.tailwind_version }}`.
|
|
||||||
|
|
||||||
### Included Artifacts
|
|
||||||
- Linux x64 (`x86_64-unknown-linux-gnu`)
|
|
||||||
- macOS x64 (`x86_64-apple-darwin`)
|
|
||||||
- macOS ARM64 (`aarch64-apple-darwin`)
|
|
||||||
|
|
||||||
### Usage
|
|
||||||
Add the artifact bundle to your `Package.swift`:
|
|
||||||
```swift
|
|
||||||
.binaryTarget(
|
|
||||||
name: "TailwindCSSCLI",
|
|
||||||
url: "https://github.com/${{ github.repository }}/releases/download/TailwindCSSCLI@${{ inputs.tailwind_version }}/tailwindcss.artifactbundleindex",
|
|
||||||
checksum: "${{ steps.checksum.outputs.checksum }}"
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Checksum
|
|
||||||
```
|
|
||||||
${{ steps.checksum.outputs.checksum }}
|
|
||||||
```
|
|
||||||
draft: false
|
|
||||||
prerelease: false
|
|
||||||
make_latest: false
|
|
||||||
files: |
|
|
||||||
artifacts/*.zip
|
|
||||||
artifacts/tailwindcss.artifactbundleindex
|
|
||||||
|
|
@ -25,8 +25,8 @@ let package = Package(
|
||||||
.binaryTarget(
|
.binaryTarget(
|
||||||
name: "TailwindCSSCLI",
|
name: "TailwindCSSCLI",
|
||||||
url:
|
url:
|
||||||
"https://github.com/laosb/SwiftTailwind/releases/download/1.1.0-test.4+tw.4.1.14/tailwindcss.artifactbundleindex",
|
"https://github.com/laosb/SwiftTailwind/releases/download/1.1.0.test.0%2Btw.4.1.14/tailwindcss.artifactbundleindex",
|
||||||
checksum: "ec4df49e361db5fc3159c431e5661af2e1b22d8575c64ce0482a8e84cfd93d04"
|
checksum: "cdc10d3dbd0ad593d68df5564f22c5fc6ffe57facb30a8665d0be073e7fb9c66"
|
||||||
),
|
),
|
||||||
.target(
|
.target(
|
||||||
name: "SwiftTailwindExample",
|
name: "SwiftTailwindExample",
|
||||||
|
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
import Foundation
|
|
||||||
|
|
||||||
extension ArtifactBundleBuilder {
|
|
||||||
func downloadFile(from urlString: String, to destination: String) throws {
|
|
||||||
guard let url = URL(string: urlString) else {
|
|
||||||
throw ArtifactBundleError.invalidURL(urlString)
|
|
||||||
}
|
|
||||||
|
|
||||||
let data = try Data(contentsOf: url)
|
|
||||||
try data.write(to: URL(fileURLWithPath: destination))
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeExecutable(path: String) throws {
|
|
||||||
let attributes = [FileAttributeKey.posixPermissions: 0o755]
|
|
||||||
try fileManager.setAttributes(attributes, ofItemAtPath: path)
|
|
||||||
}
|
|
||||||
|
|
||||||
func createZipFile(bundleDir: String, zipPath: String) throws {
|
|
||||||
// Remove existing ZIP file if it exists
|
|
||||||
if fileManager.fileExists(atPath: zipPath) {
|
|
||||||
try fileManager.removeItem(atPath: zipPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
let bundleDirURL = URL(fileURLWithPath: bundleDir)
|
|
||||||
let workDirURL = bundleDirURL.deletingLastPathComponent()
|
|
||||||
let bundleName = bundleDirURL.lastPathComponent
|
|
||||||
|
|
||||||
let process = Process()
|
|
||||||
process.executableURL = URL(fileURLWithPath: "/usr/bin/zip")
|
|
||||||
process.arguments = ["-r", zipPath, bundleName]
|
|
||||||
process.currentDirectoryURL = workDirURL
|
|
||||||
|
|
||||||
try process.run()
|
|
||||||
process.waitUntilExit()
|
|
||||||
|
|
||||||
guard process.terminationStatus == 0 else {
|
|
||||||
throw ArtifactBundleError.zipCreationFailed
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
import Crypto
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
extension ArtifactBundleBuilder {
|
|
||||||
/// Computes the SHA256 checksum of a file.
|
|
||||||
///
|
|
||||||
/// If `usingSHA256Directly` is true, it uses Swift Crypto's SHA256 implementation.
|
|
||||||
/// This is to workaround https://github.com/swiftlang/swift-package-manager/issues/9219.
|
|
||||||
func computeChecksum(
|
|
||||||
filePath: String,
|
|
||||||
usingSHA256Directly: Bool = false
|
|
||||||
) throws -> String {
|
|
||||||
if usingSHA256Directly {
|
|
||||||
// Use swift-crypto's SHA256 implementation
|
|
||||||
let fileURL = URL(fileURLWithPath: filePath)
|
|
||||||
let data = try Data(contentsOf: fileURL)
|
|
||||||
let hash = SHA256.hash(data: data)
|
|
||||||
return hash.compactMap { String(format: "%02x", $0) }.joined()
|
|
||||||
} else {
|
|
||||||
// Use swift package compute-checksum command
|
|
||||||
let process = Process()
|
|
||||||
process.executableURL = URL(fileURLWithPath: "/usr/bin/swift")
|
|
||||||
process.arguments = ["package", "compute-checksum", filePath]
|
|
||||||
|
|
||||||
let pipe = Pipe()
|
|
||||||
process.standardOutput = pipe
|
|
||||||
|
|
||||||
try process.run()
|
|
||||||
process.waitUntilExit()
|
|
||||||
|
|
||||||
guard process.terminationStatus == 0 else {
|
|
||||||
throw ArtifactBundleError.checksumComputationFailed
|
|
||||||
}
|
|
||||||
|
|
||||||
let data = pipe.fileHandleForReading.readDataToEndOfFile()
|
|
||||||
let output = String(data: data, encoding: .utf8)?.trimmingCharacters(
|
|
||||||
in: .whitespacesAndNewlines)
|
|
||||||
|
|
||||||
guard let checksum = output, !checksum.isEmpty else {
|
|
||||||
throw ArtifactBundleError.checksumComputationFailed
|
|
||||||
}
|
|
||||||
|
|
||||||
return checksum
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
extension ArtifactBundleBuilder {
|
|
||||||
/// Expands a list of triples into a stricter list of triples.
|
|
||||||
///
|
|
||||||
/// To workaround https://github.com/swiftlang/swift-package-manager/issues/7362.
|
|
||||||
func expandingTriple(_ triple: String) -> [String] {
|
|
||||||
switch triple {
|
|
||||||
case "aarch64-apple-darwin":
|
|
||||||
[
|
|
||||||
"aarch64-apple-darwin",
|
|
||||||
"arm64-apple-macosx12.0",
|
|
||||||
"arm64-apple-macosx13.0",
|
|
||||||
"arm64-apple-macosx14.0",
|
|
||||||
"arm64-apple-macosx15.0",
|
|
||||||
"arm64-apple-macosx26.0",
|
|
||||||
]
|
|
||||||
case "x86_64-apple-darwin":
|
|
||||||
[
|
|
||||||
"x86_64-apple-darwin",
|
|
||||||
"x86_64-apple-macosx12.0",
|
|
||||||
"x86_64-apple-macosx13.0",
|
|
||||||
"x86_64-apple-macosx14.0",
|
|
||||||
"x86_64-apple-macosx15.0",
|
|
||||||
"x86_64-apple-macosx26.0",
|
|
||||||
]
|
|
||||||
// TODO: Does linux need more detailed triple variants?
|
|
||||||
default: [triple]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
|
import Crypto
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
class ArtifactBundleBuilder {
|
class ArtifactBundleBuilder {
|
||||||
private let version: String
|
private let version: String
|
||||||
private let workDir: String
|
private let workDir: String
|
||||||
private let outputDir: String
|
private let outputDir: String
|
||||||
let fileManager = FileManager.default
|
private let fileManager = FileManager.default
|
||||||
|
|
||||||
private let binaryConfigurations: [BinaryConfiguration] = [
|
private let binaryConfigurations: [BinaryConfiguration] = [
|
||||||
BinaryConfiguration(binaryName: "tailwindcss-linux-x64", triple: "x86_64-unknown-linux-gnu"),
|
BinaryConfiguration(binaryName: "tailwindcss-linux-x64", triple: "x86_64-unknown-linux-gnu"),
|
||||||
|
|
@ -105,12 +106,26 @@ class ArtifactBundleBuilder {
|
||||||
return BundleInfo(fileName: zipFileName, checksum: checksum, triple: config.triple)
|
return BundleInfo(fileName: zipFileName, checksum: checksum, triple: config.triple)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func downloadFile(from urlString: String, to destination: String) throws {
|
||||||
|
guard let url = URL(string: urlString) else {
|
||||||
|
throw ArtifactBundleError.invalidURL(urlString)
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = try Data(contentsOf: url)
|
||||||
|
try data.write(to: URL(fileURLWithPath: destination))
|
||||||
|
}
|
||||||
|
|
||||||
|
private func makeExecutable(path: String) throws {
|
||||||
|
let attributes = [FileAttributeKey.posixPermissions: 0o755]
|
||||||
|
try fileManager.setAttributes(attributes, ofItemAtPath: path)
|
||||||
|
}
|
||||||
|
|
||||||
private func createInfoJSON(bundleDir: String, binaryPath: String, triple: String) throws {
|
private func createInfoJSON(bundleDir: String, binaryPath: String, triple: String) throws {
|
||||||
let artifact = Artifact(
|
let artifact = Artifact(
|
||||||
version: version,
|
version: version,
|
||||||
type: "executable",
|
type: "executable",
|
||||||
variants: [
|
variants: [
|
||||||
ArtifactVariant(path: binaryPath, supportedTriples: expandingTriple(triple))
|
ArtifactVariant(path: binaryPath, supportedTriples: [triple])
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -127,6 +142,71 @@ class ArtifactBundleBuilder {
|
||||||
try jsonData.write(to: URL(fileURLWithPath: infoPath))
|
try jsonData.write(to: URL(fileURLWithPath: infoPath))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func createZipFile(bundleDir: String, zipPath: String) throws {
|
||||||
|
// Remove existing ZIP file if it exists
|
||||||
|
if fileManager.fileExists(atPath: zipPath) {
|
||||||
|
try fileManager.removeItem(atPath: zipPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
let bundleDirURL = URL(fileURLWithPath: bundleDir)
|
||||||
|
let workDirURL = bundleDirURL.deletingLastPathComponent()
|
||||||
|
let bundleName = bundleDirURL.lastPathComponent
|
||||||
|
|
||||||
|
let process = Process()
|
||||||
|
process.executableURL = URL(fileURLWithPath: "/usr/bin/zip")
|
||||||
|
process.arguments = ["-r", zipPath, bundleName]
|
||||||
|
process.currentDirectoryURL = workDirURL
|
||||||
|
|
||||||
|
try process.run()
|
||||||
|
process.waitUntilExit()
|
||||||
|
|
||||||
|
guard process.terminationStatus == 0 else {
|
||||||
|
throw ArtifactBundleError.zipCreationFailed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Computes the SHA256 checksum of a file.
|
||||||
|
///
|
||||||
|
/// If `usingSHA256Directly` is true, it uses Swift Crypto's SHA256 implementation.
|
||||||
|
/// This is to workaround https://github.com/swiftlang/swift-package-manager/issues/9219.
|
||||||
|
private func computeChecksum(
|
||||||
|
filePath: String,
|
||||||
|
usingSHA256Directly: Bool = false
|
||||||
|
) throws -> String {
|
||||||
|
if usingSHA256Directly {
|
||||||
|
// Use swift-crypto's SHA256 implementation
|
||||||
|
let fileURL = URL(fileURLWithPath: filePath)
|
||||||
|
let data = try Data(contentsOf: fileURL)
|
||||||
|
let hash = SHA256.hash(data: data)
|
||||||
|
return hash.compactMap { String(format: "%02x", $0) }.joined()
|
||||||
|
} else {
|
||||||
|
// Use swift package compute-checksum command
|
||||||
|
let process = Process()
|
||||||
|
process.executableURL = URL(fileURLWithPath: "/usr/bin/swift")
|
||||||
|
process.arguments = ["package", "compute-checksum", filePath]
|
||||||
|
|
||||||
|
let pipe = Pipe()
|
||||||
|
process.standardOutput = pipe
|
||||||
|
|
||||||
|
try process.run()
|
||||||
|
process.waitUntilExit()
|
||||||
|
|
||||||
|
guard process.terminationStatus == 0 else {
|
||||||
|
throw ArtifactBundleError.checksumComputationFailed
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = pipe.fileHandleForReading.readDataToEndOfFile()
|
||||||
|
let output = String(data: data, encoding: .utf8)?.trimmingCharacters(
|
||||||
|
in: .whitespacesAndNewlines)
|
||||||
|
|
||||||
|
guard let checksum = output, !checksum.isEmpty else {
|
||||||
|
throw ArtifactBundleError.checksumComputationFailed
|
||||||
|
}
|
||||||
|
|
||||||
|
return checksum
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func generateArtifactBundleIndex(bundleInfos: [BundleInfo]) throws {
|
private func generateArtifactBundleIndex(bundleInfos: [BundleInfo]) throws {
|
||||||
print("Generating tailwindcss.artifactbundleindex...")
|
print("Generating tailwindcss.artifactbundleindex...")
|
||||||
|
|
||||||
|
|
@ -139,13 +219,13 @@ class ArtifactBundleBuilder {
|
||||||
Bundle(
|
Bundle(
|
||||||
fileName: bundleInfo.fileName,
|
fileName: bundleInfo.fileName,
|
||||||
checksum: bundleInfo.checksum,
|
checksum: bundleInfo.checksum,
|
||||||
supportedTriples: expandingTriple(bundleInfo.triple)
|
supportedTriples: [bundleInfo.triple]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
let index = ArtifactBundleIndex(
|
let index = ArtifactBundleIndex(
|
||||||
schemaVersion: "1.0",
|
schemaVersion: "1.0",
|
||||||
archives: bundles
|
bundles: bundles
|
||||||
)
|
)
|
||||||
|
|
||||||
let encoder = JSONEncoder()
|
let encoder = JSONEncoder()
|
||||||
|
|
@ -156,3 +236,20 @@ class ArtifactBundleBuilder {
|
||||||
try jsonData.write(to: URL(fileURLWithPath: indexPath))
|
try jsonData.write(to: URL(fileURLWithPath: indexPath))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum ArtifactBundleError: Error, LocalizedError {
|
||||||
|
case invalidURL(String)
|
||||||
|
case zipCreationFailed
|
||||||
|
case checksumComputationFailed
|
||||||
|
|
||||||
|
var errorDescription: String? {
|
||||||
|
switch self {
|
||||||
|
case .invalidURL(let url):
|
||||||
|
return "Invalid URL: \(url)"
|
||||||
|
case .zipCreationFailed:
|
||||||
|
return "Failed to create ZIP file"
|
||||||
|
case .checksumComputationFailed:
|
||||||
|
return "Failed to compute checksum"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
import Foundation
|
|
||||||
|
|
||||||
enum ArtifactBundleError: Error, LocalizedError {
|
|
||||||
case invalidURL(String)
|
|
||||||
case zipCreationFailed
|
|
||||||
case checksumComputationFailed
|
|
||||||
|
|
||||||
var errorDescription: String? {
|
|
||||||
switch self {
|
|
||||||
case .invalidURL(let url):
|
|
||||||
return "Invalid URL: \(url)"
|
|
||||||
case .zipCreationFailed:
|
|
||||||
return "Failed to create ZIP file"
|
|
||||||
case .checksumComputationFailed:
|
|
||||||
return "Failed to compute checksum"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -28,7 +28,7 @@ struct ArtifactVariant: Codable {
|
||||||
/// Represents the .artifactbundleindex file structure
|
/// Represents the .artifactbundleindex file structure
|
||||||
struct ArtifactBundleIndex: Codable {
|
struct ArtifactBundleIndex: Codable {
|
||||||
let schemaVersion: String
|
let schemaVersion: String
|
||||||
let archives: [Bundle] // The proposal says it's "bundles" but the actual implementation uses "archives"
|
let bundles: [Bundle]
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Bundle: Codable {
|
struct Bundle: Codable {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue