Improve DocC.

Partial #592

Signed-off-by: Ross Goldberg <484615+rgoldberg@users.noreply.github.com>
This commit is contained in:
Ross Goldberg 2024-10-21 07:10:31 -04:00
parent a100f3acd0
commit 3eaffa5c3e
No known key found for this signature in database
22 changed files with 61 additions and 56 deletions

View file

@ -12,11 +12,12 @@ import StoreFoundation
/// Downloads a list of apps, one after the other, printing progress to the console.
///
/// - Parameter appIDs: The IDs of the apps to be downloaded
/// - Parameter purchase: Flag indicating whether the apps needs to be purchased.
/// Only works for free apps. Defaults to false.
/// - Parameters:
/// - appIDs: The IDs of the apps to be downloaded
/// - purchase: Flag indicating whether the apps needs to be purchased.
/// Only works for free apps. Defaults to false.
/// - Returns: A promise that completes when the downloads are complete. If any fail,
/// the promise is rejected with the first error, after all remaining downloads are attempted.
/// the promise is rejected with the first error, after all remaining downloads are attempted.
func downloadAll(_ appIDs: [AppID], purchase: Bool = false) -> Promise<Void> {
var firstError: Error?
return appIDs.reduce(Guarantee.value(())) { previous, appID in

View file

@ -10,8 +10,9 @@ import ArgumentParser
import CommerceKit
extension Mas {
/// Command which installs the first search result. This is handy as many MAS titles
/// can be long with embedded keywords.
/// Command which installs the first search result.
///
/// This is handy as many MAS titles can be long with embedded keywords.
struct Lucky: ParsableCommand {
static let configuration = CommandConfiguration(
abstract: "Install the first result from the Mac App Store"
@ -54,6 +55,7 @@ extension Mas {
/// - Parameters:
/// - appID: App identifier
/// - appLibrary: Library of installed apps
/// - Throws: Any error that occurs while attempting to install the app.
fileprivate func install(appID: AppID, appLibrary: AppLibrary) throws {
// Try to download applications with given identifiers and collect results
if let product = appLibrary.installedApp(withAppID: appID), !force {

View file

@ -9,8 +9,9 @@
import ArgumentParser
extension Mas {
/// Search the Mac App Store using the iTunes Search API:
/// https://performance-partners.apple.com/search-api
/// Search the Mac App Store using the iTunes Search API.
///
/// See - https://performance-partners.apple.com/search-api
struct Search: ParsableCommand {
static let configuration = CommandConfiguration(
abstract: "Search for apps from the Mac App Store"

View file

@ -17,7 +17,7 @@ extension Mas {
abstract: "Uninstall app installed from the Mac App Store"
)
/// Flag indicating that removal shouldn't be performed
/// Flag indicating that removal shouldn't be performed.
@Flag(help: "dry run")
var dryRun = false
@Argument(help: "ID of app to uninstall")

View file

@ -13,10 +13,10 @@ protocol AppLibrary {
/// Entire set of installed apps.
var installedApps: [SoftwareProduct] { get }
/// Finds an app by ID.
/// Finds an app for appID.
///
/// - Parameter withAppID: MAS ID for app.
/// - Returns: Software Product of app if found; nil otherwise.
/// - Parameter appID: app ID for app.
/// - Returns: SoftwareProduct of app if found; nil otherwise.
func installedApp(withAppID appID: AppID) -> SoftwareProduct?
/// Uninstalls an app.
@ -28,10 +28,10 @@ protocol AppLibrary {
/// Common logic
extension AppLibrary {
/// Finds an app by ID.
/// Finds an app for appID.
///
/// - Parameter withAppID: MAS ID for app.
/// - Returns: Software Product of app if found; nil otherwise.
/// - Parameter appID: app ID for app.
/// - Returns: SoftwareProduct of app if found; nil otherwise.
func installedApp(withAppID appID: AppID) -> SoftwareProduct? {
let appID = NSNumber(value: appID)
return installedApps.first { $0.itemIdentifier == appID }

View file

@ -34,9 +34,8 @@ class MasStoreSearch: StoreSearch {
/// Searches for an app.
///
/// - Parameter appName: MAS ID of app
/// - Parameter completion: A closure that receives the search results or an Error if there is a
/// problem with the network request. Results array will be empty if there were no matches.
/// - Parameter searchTerm: a search term matched against app names
/// - Returns: A Promise of an Array of SearchResults matching searchTerm
func search(for appName: String) -> Promise<[SearchResult]> {
// Search for apps for compatible platforms, in order of preference.
// Macs with Apple Silicon can run iPad and iPhone apps.
@ -115,11 +114,9 @@ class MasStoreSearch: StoreSearch {
}
}
// App Store pages indicate:
// - compatibility with Macs with Apple Silicon
// - (often) a version that is newer than what is listed in search results
//
// We attempt to scrape this information here.
/// Scrape the app version from the App Store webpage at the given URL.
///
/// App Store webpages frequently report a version that is newer than what is reported by the iTunes Search API.
private func scrapeAppStoreVersion(_ pageUrl: URL) -> Promise<Version?> {
firstly {
networkManager.loadData(from: pageUrl)

View file

@ -6,7 +6,7 @@
// Copyright © 2020 mas-cli. All rights reserved.
//
/// Somewhat analogous to CKSoftwareMap
/// Somewhat analogous to CKSoftwareMap.
protocol SoftwareMap {
func allSoftwareProducts() -> [SoftwareProduct]
func product(for bundleIdentifier: String) -> SoftwareProduct?

View file

@ -40,7 +40,10 @@ private enum URLAction {
extension StoreSearch {
/// Builds the search URL for an app.
///
/// - Parameter searchTerm: term for which to search in MAS.
/// - Parameters:
/// - searchTerm: term for which to search in MAS.
/// - country: 2-letter ISO region code of the MAS in which to search.
/// - entity: OS platform of apps for which to search.
/// - Returns: URL for the search service or nil if searchTerm can't be encoded.
func searchURL(
for searchTerm: String,
@ -52,7 +55,10 @@ extension StoreSearch {
/// Builds the lookup URL for an app.
///
/// - Parameter appID: MAS app identifier.
/// - Parameters:
/// - appID: MAS app identifier.
/// - country: 2-letter ISO region code of the MAS in which to search.
/// - entity: OS platform of apps for which to search.
/// - Returns: URL for the lookup service or nil if appID can't be encoded.
func lookupURL(
forAppID appID: AppID,

View file

@ -8,7 +8,7 @@
import Foundation
/// CLI command
/// Represents a CLI command.
protocol ExternalCommand {
var binaryPath: String { get set }

View file

@ -8,8 +8,7 @@
import Foundation
/// Wrapper for the external open system command.
/// https://ss64.com/osx/open.html
/// Wrapper for the external 'open' system command (https://ss64.com/osx/open.html).
struct OpenSystemCommand: ExternalCommand {
var binaryPath: String

View file

@ -8,8 +8,9 @@
import Foundation
/// Wrapper for the external sysctl system command.
/// https://ss64.com/osx/sysctl.html
/// Wrapper for the external 'sysctl' system command.
///
/// See - https://ss64.com/osx/sysctl.html
struct SysCtlSystemCommand: ExternalCommand {
var binaryPath: String

View file

@ -10,9 +10,11 @@ import Foundation
/// Formats text output for the search command.
enum SearchResultFormatter {
/// Formats text output with search results.
/// Formats search results as text.
///
/// - Parameter results: Search results with app data
/// - Parameters:
/// - results: Search results containing app data
/// - includePrice: Indicates whether to include prices in the output
/// - Returns: Multiline text output.
static func format(results: [SearchResult], includePrice: Bool = false) -> String {
// find longest appName for formatting, default 50

View file

@ -8,14 +8,15 @@
import Foundation
/// A collection of output formatting helpers
// A collection of output formatting helpers
/// Terminal Control Sequence Indicator
/// Terminal Control Sequence Indicator.
let csi = "\u{001B}["
private var standardError = FileHandle.standardError
extension FileHandle: TextOutputStream {
/// Appends the given string to the stream.
public func write(_ string: String) {
guard let data = string.data(using: .utf8) else { return }
write(data)

View file

@ -19,12 +19,15 @@ protocol SoftwareProduct {
}
extension SoftwareProduct {
/// Returns bundleIdentifier if appName is empty string.
/// - Returns: bundleIdentifier if appName is empty string.
var appNameOrBundleIdentifier: String {
appName.isEmpty ? bundleIdentifier : appName
}
/// Determines whether the app is considered outdated. Updates that require a higher OS version are excluded.
/// Determines whether the app is considered outdated.
///
/// Updates that require a higher OS version are excluded.
///
/// - Parameter storeApp: App from search result.
/// - Returns: true if the app is outdated; false otherwise.
func isOutdatedWhenComparedTo(_ storeApp: SearchResult) -> Bool {

View file

@ -9,11 +9,11 @@
import Foundation
import PromiseKit
/// Network abstraction
/// Network abstraction.
class NetworkManager {
private let session: NetworkSession
/// Designated initializer
/// Designated initializer.
///
/// - Parameter session: A networking session.
init(session: NetworkSession = URLSession(configuration: .ephemeral)) {
@ -28,8 +28,7 @@ class NetworkManager {
/// Loads data asynchronously.
///
/// - Parameters:
/// - url: URL to load data from.
/// - Parameter url: URL from which to load data.
/// - Returns: A Promise for the Data of the response.
func loadData(from url: URL) -> Promise<Data> {
session.loadData(from: url)

View file

@ -11,7 +11,7 @@ import Quick
@testable import mas
// Deprecated test
/// Deprecated test.
public class AccountSpec: QuickSpec {
override public func spec() {
beforeSuite {

View file

@ -11,7 +11,7 @@ import Quick
@testable import mas
// Deprecated test
/// Deprecated test.
public class SignInSpec: QuickSpec {
override public func spec() {
beforeSuite {

View file

@ -17,7 +17,9 @@ class MASErrorTestCase: XCTestCase {
var nserror: NSError!
/// Convenience property for setting the value which will be use for the localized description
/// value of the next NSError created. Only used when the NSError does not have a user info
/// value of the next NSError created.
///
/// Only used when the NSError does not have a user info
/// entry for localized description.
var localizedDescription: String {
get { "dummy value" }

View file

@ -10,7 +10,8 @@ import Foundation
extension Data {
/// Unsafe initializer for loading data from string paths.
/// - Parameter file: Relative path within the JSON folder
///
/// - Parameter fileName: Relative path within the JSON folder
init(from fileName: String) {
let fileURL = Bundle.url(for: fileName)!
try! self.init(contentsOf: fileURL, options: .mappedIfSafe)

View file

@ -18,11 +18,6 @@ class NetworkSessionMock: NetworkSession {
var data: Data?
var error: Error?
/// Immediately passes data and error to completion handler.
///
/// - Parameters:
/// - url: unused
/// - completionHandler: Closure which is delivered either data or an error.
func loadData(from _: URL) -> Promise<Data> {
guard let data else {
return Promise(error: error ?? MASError.noData)

View file

@ -21,11 +21,6 @@ class NetworkSessionMockFromFile: NetworkSessionMock {
self.responseFile = responseFile
}
/// Loads data from a file.
///
/// - Parameters:
/// - url: unused
/// - completionHandler: Closure which is delivered either data or an error.
override func loadData(from _: URL) -> Promise<Data> {
guard let fileURL = Bundle.url(for: responseFile)
else { fatalError("Unable to load file \(responseFile)") }

View file

@ -20,7 +20,7 @@ VERSION=$(git describe --abbrev=0 --tags)
VERSION=${VERSION#v}
cat <<EOF >"Sources/mas/Package.swift"
// Generated by: script/version
/// Generated by \`script/version\`.
enum Package {
static let version = "${VERSION}"
}