Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions Mist/Commands/Download/DownloadFirmwareCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -200,16 +200,25 @@ struct DownloadFirmwareCommand: ParsableCommand {
let required: Int64 = firmware.size

for url in [outputURL, temporaryURL] {
let values: URLResourceValues = try url.resourceValues(forKeys: [.volumeAvailableCapacityForImportantUsageKey, .volumeAvailableCapacityKey])
let free: Int64
var free: Int64 = 0

#if os(Linux)
let values: URLResourceValues = try url.resourceValues(forKeys: [.volumeAvailableCapacityKey])
if let volumeAvailableCapacity: Int = values.volumeAvailableCapacity {
free = Int64(volumeAvailableCapacity)
}
#else
let values: URLResourceValues = try url.resourceValues(forKeys: [.volumeAvailableCapacityForImportantUsageKey, .volumeAvailableCapacityKey])
if
let volumeAvailableCapacityForImportantUsage: Int64 = values.volumeAvailableCapacityForImportantUsage,
volumeAvailableCapacityForImportantUsage > 0 {
free = volumeAvailableCapacityForImportantUsage
} else if let volumeAvailableCapacity: Int = values.volumeAvailableCapacity {
free = Int64(volumeAvailableCapacity)
} else {
}
#endif

if free == 0 {
throw MistError.notEnoughFreeSpace(volume: url.path, free: 0, required: required)
}

Expand Down
15 changes: 12 additions & 3 deletions Mist/Commands/Download/DownloadInstallerCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -397,16 +397,25 @@ struct DownloadInstallerCommand: ParsableCommand {
for volume in volumes {
let required: Int64 = installer.size * volume.count
let url: URL = .init(fileURLWithPath: volume.path)
let values: URLResourceValues = try url.resourceValues(forKeys: [.volumeAvailableCapacityForImportantUsageKey, .volumeAvailableCapacityKey])
let free: Int64
var free: Int64 = 0

#if os(Linux)
let values: URLResourceValues = try url.resourceValues(forKeys: [.volumeAvailableCapacityKey])
if let volumeAvailableCapacity: Int = values.volumeAvailableCapacity {
free = Int64(volumeAvailableCapacity)
}
#else
let values: URLResourceValues = try url.resourceValues(forKeys: [.volumeAvailableCapacityForImportantUsageKey, .volumeAvailableCapacityKey])
if
let volumeAvailableCapacityForImportantUsage: Int64 = values.volumeAvailableCapacityForImportantUsage,
volumeAvailableCapacityForImportantUsage > 0 {
free = volumeAvailableCapacityForImportantUsage
} else if let volumeAvailableCapacity: Int = values.volumeAvailableCapacity {
free = Int64(volumeAvailableCapacity)
} else {
}
#endif

if free == 0 {
throw MistError.notEnoughFreeSpace(volume: url.path, free: 0, required: required)
}

Expand Down
2 changes: 1 addition & 1 deletion Mist/Extensions/URL+Extension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Created by Nindi Gill on 15/8/2022.
//

import CryptoKit
import Crypto
import Foundation

extension URL {
Expand Down
12 changes: 12 additions & 0 deletions Mist/Helpers/Downloader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@

import Foundation

#if canImport(FoundationNetworking)
import FoundationNetworking
#endif

/// Helper Class used to download macOS Firmwares and Installers.
class Downloader: NSObject {
private static let maximumWidth: Int = 95
Expand Down Expand Up @@ -70,12 +74,14 @@ class Downloader: NSObject {

while urlError != nil {
if retries >= options.retries {
#if !os(Linux)
if
let error: URLError = urlError,
let data: Data = error.downloadTaskResumeData {
!quiet ? PrettyPrint.print("Saving resume data to '\(resumeDataURL.path)'...", noAnsi: noAnsi) : Mist.noop()
try data.write(to: resumeDataURL)
}
#endif

throw MistError.maximumRetriesReached
}
Expand Down Expand Up @@ -168,12 +174,14 @@ class Downloader: NSObject {

while urlError != nil {
if retries >= options.retries {
#if !os(Linux)
if
let error: URLError = urlError,
let data: Data = error.downloadTaskResumeData {
!quiet ? PrettyPrint.print("Saving resume data to '\(resumeDataURL.path)'...", noAnsi: noAnsi) : Mist.noop()
try data.write(to: resumeDataURL)
}
#endif

throw MistError.maximumRetriesReached
}
Expand Down Expand Up @@ -225,6 +233,9 @@ class Downloader: NSObject {
}

private func retry(attempt retry: Int, of maximumRetries: Int, with delay: Int, using session: URLSession) {
#if os(Linux)
mistError = MistError.generalError("Cannot retry downloads on Linux")
#else
guard
let urlError: URLError = urlError,
let data: Data = urlError.downloadTaskResumeData else {
Expand All @@ -242,6 +253,7 @@ class Downloader: NSObject {
updateProgress(replacing: false)
task.resume()
semaphore.wait()
#endif
}

private func updateProgress(replacing: Bool = true) {
Expand Down
2 changes: 1 addition & 1 deletion Mist/Helpers/Validator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Created by Nindi Gill on 29/4/2022.
//

import CryptoKit
import Crypto
import Foundation

/// Helper Struct used to validate macOS Firmware and Installer downloads.
Expand Down
5 changes: 5 additions & 0 deletions Mist/Model/Hardware.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ enum Hardware {
///
/// - Returns: The entity property for the provided key.
private static func registryProperty(for key: String) -> String? {
#if os(Linux)
// Cannot use Darwin/XNU kernel APIs on Linux
return nil;
#else
let entry: io_service_t = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice"))

defer {
Expand All @@ -74,5 +78,6 @@ enum Hardware {

let string: String = .init(decoding: data, as: UTF8.self)
return string.trimmingCharacters(in: CharacterSet(["\0"]))
#endif
}
}
15 changes: 15 additions & 0 deletions Mist/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,23 @@

import Foundation

#if os(Linux)
/// A shim for Linux that runs the given block of code.
///
/// The existence of this shim allows you the use of auto-release pools to optimize memory footprint on Darwin platforms while maintaining
/// compatibility with Linux where this API is not implemented.
@discardableResult
public func autoreleasepool<Result>(_ block: () throws -> Result) rethrows -> Result {
return try block()
}

public func autoreleasepool<E, Result>(invoking body: () throws(E) -> Result) throws(E) -> Result where E: Error, Result : ~Copyable {
return try body()
}
#else
// Disable stdout stream buffering for more immediate output.
setbuf(__stdoutp, nil)
#endif

Mist.main()
exit(0)
2 changes: 2 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ let package: Package = .init(
],
dependencies: [
.package(url: "https://github.com/apple/swift-argument-parser", from: "1.6.1"),
.package(url: "https://github.com/apple/swift-crypto.git", "1.0.0" ..< "5.0.0"),
// .package(url: "https://github.com/nicklockwood/SwiftFormat", from: "0.57.2"),
.package(url: "https://github.com/SimplyDanny/SwiftLintPlugins", from: "0.61.0"),
.package(url: "https://github.com/jpsim/Yams", from: "6.1.0")
Expand All @@ -23,6 +24,7 @@ let package: Package = .init(
name: "Mist",
dependencies: [
.product(name: "ArgumentParser", package: "swift-argument-parser"),
.product(name: "Crypto", package: "swift-crypto"),
.product(name: "Yams", package: "Yams")
],
path: "Mist"
Expand Down