From 959db7ef50cdd68359243334b076e000d3f0992d Mon Sep 17 00:00:00 2001 From: Daniel Bayley Date: Tue, 2 Jun 2020 12:34:09 +0100 Subject: [PATCH 1/5] Align columns of list command output --- MasKit/Commands/List.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MasKit/Commands/List.swift b/MasKit/Commands/List.swift index 7665fe8..1e3e589 100644 --- a/MasKit/Commands/List.swift +++ b/MasKit/Commands/List.swift @@ -40,7 +40,7 @@ public struct ListCommand: CommandProtocol { if appName == "" { appName = product.bundleIdentifier } - print("\(product.itemIdentifier) \(appName) (\(product.bundleVersion))") + print("\(product.itemIdentifier)\t\(appName)\t(\(product.bundleVersion))") } return .success(()) } From d732d638707d4e6ed4b1d1f1442f8d5af9930a7d Mon Sep 17 00:00:00 2001 From: Daniel Bayley Date: Tue, 2 Jun 2020 12:34:09 +0100 Subject: [PATCH 2/5] Align columns of list command output --- CHANGELOG.md | 1 + MasKit/Commands/List.swift | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c492f6..7e5c7dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] - ✨ `Makefile` #277 +- 🎨 Improve `mas list` command output #278 ## [v1.7.0] 🛍 Purchase Command - 2020-05-24 diff --git a/MasKit/Commands/List.swift b/MasKit/Commands/List.swift index 7665fe8..1e3e589 100644 --- a/MasKit/Commands/List.swift +++ b/MasKit/Commands/List.swift @@ -40,7 +40,7 @@ public struct ListCommand: CommandProtocol { if appName == "" { appName = product.bundleIdentifier } - print("\(product.itemIdentifier) \(appName) (\(product.bundleVersion))") + print("\(product.itemIdentifier)\t\(appName)\t(\(product.bundleVersion))") } return .success(()) } From c2545346555f4778524976420240d4244ecaa8fa Mon Sep 17 00:00:00 2001 From: Ben Chatelain Date: Sun, 7 Jun 2020 14:01:34 -0600 Subject: [PATCH 3/5] =?UTF-8?q?=F0=9F=94=88=20Format=20list=20output=20usi?= =?UTF-8?q?ng=20AppListFormatter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MasKit/Commands/List.swift | 11 ++--- MasKit/Formatters/AppListFormatter.swift | 43 +++++++++++++++++++ mas-cli.xcodeproj/project.pbxproj | 4 ++ .../xcschemes/mas-cli Debug.xcscheme | 8 +++- 4 files changed, 58 insertions(+), 8 deletions(-) create mode 100644 MasKit/Formatters/AppListFormatter.swift diff --git a/MasKit/Commands/List.swift b/MasKit/Commands/List.swift index 1e3e589..8afa334 100644 --- a/MasKit/Commands/List.swift +++ b/MasKit/Commands/List.swift @@ -35,13 +35,10 @@ public struct ListCommand: CommandProtocol { print("No installed apps found") return .success(()) } - for product in products { - var appName = product.appName - if appName == "" { - appName = product.bundleIdentifier - } - print("\(product.itemIdentifier)\t\(appName)\t(\(product.bundleVersion))") - } + + let output = AppListFormatter.format(products: products) + print(output) + return .success(()) } } diff --git a/MasKit/Formatters/AppListFormatter.swift b/MasKit/Formatters/AppListFormatter.swift new file mode 100644 index 0000000..3afd481 --- /dev/null +++ b/MasKit/Formatters/AppListFormatter.swift @@ -0,0 +1,43 @@ +// +// AppListFormatter.swift +// MasKit +// +// Created by Ben Chatelain on 6/7/20. +// Copyright © 2019 mas-cli. All rights reserved. +// + +import Foundation + +/// Formats text output for the search command. +struct AppListFormatter { + /// Formats text output with list results. + /// + /// - Parameter products: List of sortware products app data. + /// - Returns: Multiliune text outoutp. + static func format(products: [SoftwareProduct]) -> String { + + // TODO: Catch empty appNames + // var appName = product.appName + // if appName == "" { + // appName = product.bundleIdentifier + // } + + let minWidth = 50 + // find longest appName for formatting, default 50 + let maxLength = products.map { $0.appName } + .max(by: { $1.count > $0.count })?.count + ?? minWidth + + var output: String = "" + + for product in products { + let appId = product.itemIdentifier.intValue + let appName = product.appName.padding(toLength: maxLength, withPad: " ", startingAt: 0) + let version = product.bundleVersion + + output += String(format: "%12d %@ (%@)\n", appId, appName, version) + } + + return output.trimmingCharacters(in: .newlines) + } +} diff --git a/mas-cli.xcodeproj/project.pbxproj b/mas-cli.xcodeproj/project.pbxproj index ccae1eb..f8a5914 100644 --- a/mas-cli.xcodeproj/project.pbxproj +++ b/mas-cli.xcodeproj/project.pbxproj @@ -110,6 +110,7 @@ F85DA8B0240C32FA00FE5650 /* SoftwareMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = F85DA8AF240C32FA00FE5650 /* SoftwareMap.swift */; }; F85DA8B2240CBAFE00FE5650 /* CKSoftwareMap+SoftwareMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = F85DA8B1240CBAFE00FE5650 /* CKSoftwareMap+SoftwareMap.swift */; }; F88CB8E12404DAAD00B691B5 /* OpenSystemCommandSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = F88CB8E02404DAAD00B691B5 /* OpenSystemCommandSpec.swift */; }; + F8A41ECE248D76CB00D374CF /* AppListFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8A41ECD248D76CB00D374CF /* AppListFormatter.swift */; }; F8FB715B20F2B41400F56FDC /* MasKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8FB715220F2B41400F56FDC /* MasKit.framework */; }; F8FB716220F2B41400F56FDC /* MasKit.h in Headers */ = {isa = PBXBuildFile; fileRef = F8FB715420F2B41400F56FDC /* MasKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; F8FB716A20F2B4DD00F56FDC /* Downloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0F238A1B87569C00AE40CD /* Downloader.swift */; }; @@ -326,6 +327,7 @@ F85DA8AF240C32FA00FE5650 /* SoftwareMap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SoftwareMap.swift; sourceTree = ""; }; F85DA8B1240CBAFE00FE5650 /* CKSoftwareMap+SoftwareMap.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CKSoftwareMap+SoftwareMap.swift"; sourceTree = ""; }; F88CB8E02404DAAD00B691B5 /* OpenSystemCommandSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenSystemCommandSpec.swift; sourceTree = ""; }; + F8A41ECD248D76CB00D374CF /* AppListFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppListFormatter.swift; sourceTree = ""; }; F8FB715220F2B41400F56FDC /* MasKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MasKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; F8FB715420F2B41400F56FDC /* MasKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MasKit.h; sourceTree = ""; }; F8FB715520F2B41400F56FDC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -527,6 +529,7 @@ isa = PBXGroup; children = ( B576FE2921E4240B0016B39D /* AppInfoFormatter.swift */, + F8A41ECD248D76CB00D374CF /* AppListFormatter.swift */, B576FE3221E985250016B39D /* SearchResultFormatter.swift */, EDCBF9541D89CFC7000039C6 /* Utilities.swift */, ); @@ -1029,6 +1032,7 @@ B576FE0021E113610016B39D /* NetworkSession.swift in Sources */, B5DBF80D21DEE4E600F3B151 /* Open.swift in Sources */, B576FDF721E107AA0016B39D /* OpenSystemCommand.swift in Sources */, + F8A41ECE248D76CB00D374CF /* AppListFormatter.swift in Sources */, F8FB717420F2B4DD00F56FDC /* Outdated.swift in Sources */, 75FB3E761F9F7841005B6F20 /* Purchase.swift in Sources */, F8FB716C20F2B4DD00F56FDC /* PurchaseDownloadObserver.swift in Sources */, diff --git a/mas-cli.xcodeproj/xcshareddata/xcschemes/mas-cli Debug.xcscheme b/mas-cli.xcodeproj/xcshareddata/xcschemes/mas-cli Debug.xcscheme index ab4b3db..d39aedc 100644 --- a/mas-cli.xcodeproj/xcshareddata/xcschemes/mas-cli Debug.xcscheme +++ b/mas-cli.xcodeproj/xcshareddata/xcschemes/mas-cli Debug.xcscheme @@ -71,7 +71,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - launchStyle = "1" + launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" debugDocumentVersioning = "YES" @@ -87,6 +87,12 @@ ReferencedContainer = "container:mas-cli.xcodeproj"> + + + + Date: Sun, 7 Jun 2020 14:17:07 -0600 Subject: [PATCH 4/5] =?UTF-8?q?=F0=9F=94=88=20Use=20appNameOrBundleIdentif?= =?UTF-8?q?ier=20to=20handle=20empty=20app=20names?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MasKit/Formatters/AppListFormatter.swift | 13 +++---------- MasKit/Models/SoftwareProduct.swift | 5 +++++ 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/MasKit/Formatters/AppListFormatter.swift b/MasKit/Formatters/AppListFormatter.swift index 3afd481..f05f5d1 100644 --- a/MasKit/Formatters/AppListFormatter.swift +++ b/MasKit/Formatters/AppListFormatter.swift @@ -15,16 +15,9 @@ struct AppListFormatter { /// - Parameter products: List of sortware products app data. /// - Returns: Multiliune text outoutp. static func format(products: [SoftwareProduct]) -> String { - - // TODO: Catch empty appNames - // var appName = product.appName - // if appName == "" { - // appName = product.bundleIdentifier - // } - - let minWidth = 50 // find longest appName for formatting, default 50 - let maxLength = products.map { $0.appName } + let minWidth = 50 + let maxLength = products.map { $0.appNameOrBbundleIdentifier } .max(by: { $1.count > $0.count })?.count ?? minWidth @@ -32,7 +25,7 @@ struct AppListFormatter { for product in products { let appId = product.itemIdentifier.intValue - let appName = product.appName.padding(toLength: maxLength, withPad: " ", startingAt: 0) + let appName = product.appNameOrBbundleIdentifier.padding(toLength: maxLength, withPad: " ", startingAt: 0) let version = product.bundleVersion output += String(format: "%12d %@ (%@)\n", appId, appName, version) diff --git a/MasKit/Models/SoftwareProduct.swift b/MasKit/Models/SoftwareProduct.swift index c6d186a..5f3a156 100644 --- a/MasKit/Models/SoftwareProduct.swift +++ b/MasKit/Models/SoftwareProduct.swift @@ -24,4 +24,9 @@ extension SoftwareProduct { && lhs.bundleVersion == rhs.bundleVersion && lhs.itemIdentifier == rhs.itemIdentifier } + + /// Returns bundleIdentifier if appName is empty string. + var appNameOrBbundleIdentifier: String { + appName == "" ? bundleIdentifier : appName + } } From 872f0e3faf4d2379ff1609cc476106ef2cc37c5a Mon Sep 17 00:00:00 2001 From: Ben Chatelain Date: Sat, 22 Aug 2020 20:43:21 -0600 Subject: [PATCH 5/5] =?UTF-8?q?=F0=9F=90=9B=20Left=20justify=20app=20ID=20?= =?UTF-8?q?column=20to=20restore=20brew=20bundle=20compatibility?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MasKit/Formatters/AppListFormatter.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MasKit/Formatters/AppListFormatter.swift b/MasKit/Formatters/AppListFormatter.swift index f05f5d1..f3bed4e 100644 --- a/MasKit/Formatters/AppListFormatter.swift +++ b/MasKit/Formatters/AppListFormatter.swift @@ -24,11 +24,11 @@ struct AppListFormatter { var output: String = "" for product in products { - let appId = product.itemIdentifier.intValue + let appId = product.itemIdentifier let appName = product.appNameOrBbundleIdentifier.padding(toLength: maxLength, withPad: " ", startingAt: 0) let version = product.bundleVersion - output += String(format: "%12d %@ (%@)\n", appId, appName, version) + output += "\(appId) \(appName) (\(version))\n" } return output.trimmingCharacters(in: .newlines)