<commit_before>//
//  Outdated.swift
//  mas-cli
//
//  Created by <NAME> on 21/08/2015.
//  Copyright (c) 2015 <NAME>. All rights reserved.
//

import Commandant
import Foundation
import PromiseKit

import enum Swift.Result

/// Command which displays a list of installed apps which have available updates
/// ready to be installed from the Mac App Store.
public struct OutdatedCommand: CommandProtocol {
    public typealias Options = OutdatedOptions
    public let verb = "outdated"
    public let function = "Lists pending updates from the Mac App Store"

    private let appLibrary: AppLibrary
    private let storeSearch: StoreSearch

    /// Public initializer.
    public init() {
        self.init(appLibrary: MasAppLibrary())
    }

    /// Internal initializer.
    /// - Parameter appLibrary: AppLibrary manager.
    /// - Parameter storeSearch: StoreSearch manager.
    init(appLibrary: AppLibrary = MasAppLibrary(), storeSearch: StoreSearch = MasStoreSearch()) {
        self.appLibrary = appLibrary
        self.storeSearch = storeSearch
    }

    /// Runs the command.
    public func run(_ options: Options) -> Result<Void, MASError> {
        let promises = appLibrary.installedApps.map { installedApp in
            firstly {
                storeSearch.lookup(app: installedApp.itemIdentifier.intValue)
            }.done { storeApp in
                guard let storeApp = storeApp else {
                    if options.verbose {
                        printWarning(
                            """
                            Identifier \(installedApp.itemIdentifier) not found in store. \
                            Was expected to identify \(installedApp.appName).
                            """)
                    }
                    return
                }

                if installedApp.isOutdatedWhenComparedTo(storeApp) {
                    print(
                        """
                        \(installedApp.itemIdentifier) \(installedApp.appName) \
                        (\(installedApp.bundleVersion) -> \(storeApp.version))
                        """)
                }
            }
        }

        return firstly {
            when(fulfilled: promises)
        }.map {
            Result<Void, MASError>.success(())
        }.recover { error in
            // Bubble up MASErrors
            .value(Result<Void, MASError>.failure(error as? MASError ?? .searchFailed))
        }.wait()
    }
}


public struct OutdatedOptions: OptionsProtocol {
    public typealias ClientError = MASError

    let verbose: Bool

    static func create(verbose: Bool) -> OutdatedOptions {
        OutdatedOptions(verbose: verbose)
    }

    public static func evaluate(_ mode: CommandMode) -> Result<OutdatedOptions, CommandantError<MASError>> {
        create
        <*> mode <| Switch(flag: nil, key: "verbose", usage: "Show warnings about apps")
    }
}
<commit_msg>🚨 Remove extra linefeed<commit_after>//
//  Outdated.swift
//  mas-cli
//
//  Created by <NAME> on 21/08/2015.
//  Copyright (c) 2015 <NAME>. All rights reserved.
//

import Commandant
import Foundation
import PromiseKit

import enum Swift.Result

/// Command which displays a list of installed apps which have available updates
/// ready to be installed from the Mac App Store.
public struct OutdatedCommand: CommandProtocol {
    public typealias Options = OutdatedOptions
    public let verb = "outdated"
    public let function = "Lists pending updates from the Mac App Store"

    private let appLibrary: AppLibrary
    private let storeSearch: StoreSearch

    /// Public initializer.
    public init() {
        self.init(appLibrary: MasAppLibrary())
    }

    /// Internal initializer.
    /// - Parameter appLibrary: AppLibrary manager.
    /// - Parameter storeSearch: StoreSearch manager.
    init(appLibrary: AppLibrary = MasAppLibrary(), storeSearch: StoreSearch = MasStoreSearch()) {
        self.appLibrary = appLibrary
        self.storeSearch = storeSearch
    }

    /// Runs the command.
    public func run(_ options: Options) -> Result<Void, MASError> {
        let promises = appLibrary.installedApps.map { installedApp in
            firstly {
                storeSearch.lookup(app: installedApp.itemIdentifier.intValue)
            }.done { storeApp in
                guard let storeApp = storeApp else {
                    if options.verbose {
                        printWarning(
                            """
                            Identifier \(installedApp.itemIdentifier) not found in store. \
                            Was expected to identify \(installedApp.appName).
                            """)
                    }
                    return
                }

                if installedApp.isOutdatedWhenComparedTo(storeApp) {
                    print(
                        """
                        \(installedApp.itemIdentifier) \(installedApp.appName) \
                        (\(installedApp.bundleVersion) -> \(storeApp.version))
                        """)
                }
            }
        }

        return firstly {
            when(fulfilled: promises)
        }.map {
            Result<Void, MASError>.success(())
        }.recover { error in
            // Bubble up MASErrors
            .value(Result<Void, MASError>.failure(error as? MASError ?? .searchFailed))
        }.wait()
    }
}

public struct OutdatedOptions: OptionsProtocol {
    public typealias ClientError = MASError

    let verbose: Bool

    static func create(verbose: Bool) -> OutdatedOptions {
        OutdatedOptions(verbose: verbose)
    }

    public static func evaluate(_ mode: CommandMode) -> Result<OutdatedOptions, CommandantError<MASError>> {
        create
        <*> mode <| Switch(flag: nil, key: "verbose", usage: "Show warnings about apps")
    }
}

{'fraction_non_alphanumeric': 0.09140799176813583, 'fraction_numerical': 0.004115932087120563, 'mean_word_length': 1.7944417824628653, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7375931', 'n_tokens_mistral': 1519, 'n_tokens_neox': 1392, 'n_words': 415}