@@ -9,6 +9,32 @@ private import Atomics
99private import Foundation
1010private import ObjectiveC
1111
12+ private extension URL {
13+ var installedAppURLs : [ URL ] {
14+ FileManager . default // swiftformat:disable indent
15+ . enumerator ( at: self , includingPropertiesForKeys: [ . isDirectoryKey] , options: [ . skipsHiddenFiles] )
16+ . map { enumerator in
17+ enumerator. compactMap { item in
18+ guard
19+ let url = item as? URL ,
20+ ( try ? url. resourceValues ( forKeys: [ . isDirectoryKey] ) . isDirectory) == true ,
21+ url. lastPathComponent == " Contents "
22+ else {
23+ return nil as URL ?
24+ }
25+
26+ enumerator. skipDescendants ( )
27+ return
28+ ( try ? url. appending ( path: " _MASReceipt/receipt " , directoryHint: . notDirectory) . checkResourceIsReachable ( ) )
29+ == true
30+ ? url. deletingLastPathComponent ( )
31+ : nil
32+ }
33+ }
34+ ?? [ ]
35+ } // swiftformat:enable indent
36+ }
37+
1238var installedApps : [ InstalledApp ] {
1339 get async throws {
1440 try await mas. installedApps ( matching: " kMDItemAppStoreAdamID LIKE '*' " )
@@ -53,22 +79,52 @@ func installedApps(matching metadataQuery: String) async throws -> [InstalledApp
5379
5480 query. stop ( )
5581
56- continuation. resume (
57- returning: query. results
58- . compactMap { result in // swiftformat:disable indent
59- ( result as? NSMetadataItem ) . map { item in
60- InstalledApp (
61- adamID: item. value ( forAttribute: " kMDItemAppStoreAdamID " ) as? ADAMID ?? 0 ,
62- bundleID: item. value ( forAttribute: NSMetadataItemCFBundleIdentifierKey) as? String ?? " " ,
63- name: ( item. value ( forAttribute: " _kMDItemDisplayNameWithExtensions " ) as? String ?? " " )
64- . removingSuffix ( " .app " ) ,
65- path: item. value ( forAttribute: NSMetadataItemPathKey) as? String ?? " " ,
66- version: item. value ( forAttribute: NSMetadataItemVersionKey) as? String ?? " " ,
67- )
82+ let installedApps = query. results
83+ . compactMap { result in // swiftformat:disable indent
84+ ( result as? NSMetadataItem ) . map { item in
85+ InstalledApp (
86+ adamID: item. value ( forAttribute: " kMDItemAppStoreAdamID " ) as? ADAMID ?? 0 ,
87+ bundleID: item. value ( forAttribute: NSMetadataItemCFBundleIdentifierKey) as? String ?? " " ,
88+ name: ( item. value ( forAttribute: " _kMDItemDisplayNameWithExtensions " ) as? String ?? " " )
89+ . removingSuffix ( " .app " ) ,
90+ path: item. value ( forAttribute: NSMetadataItemPathKey) as? String ?? " " ,
91+ version: item. value ( forAttribute: NSMetadataItemVersionKey) as? String ?? " " ,
92+ )
93+ }
94+ }
95+ . sorted ( using: KeyPathComparator ( \. name, comparator: . localizedStandard) ) // swiftformat:enable indent
96+
97+ if ![ " 1 " , " true " , " yes " ] . contains ( ProcessInfo . processInfo. environment [ " MAS_NO_AUTO_INDEX " ] ? . lowercased ( ) ) {
98+ let installedAppPathSet = Set ( installedApps. map ( \. path) )
99+ for installedAppURL in applicationsFolderURLs. flatMap ( \. installedAppURLs)
100+ where !installedAppPathSet. contains ( installedAppURL. filePath) { // swiftformat:disable:this indent
101+ MAS . printer. warning (
102+ " Found a likely App Store app that is not indexed in Spotlight in " ,
103+ installedAppURL. filePath,
104+ """
105+
106+
107+ Indexing now, which will not complete until sometime after mas exits
108+
109+ Disable auto-indexing via: export MAS_NO_AUTO_INDEX=1
110+ """ ,
111+ separator: " " ,
112+ )
113+ Task {
114+ do {
115+ _ = try await run (
116+ " /usr/bin/mdimport " ,
117+ installedAppURL. filePath,
118+ errorMessage: " Failed to index the Spotlight data for \( installedAppURL. filePath) " ,
119+ )
120+ } catch {
121+ MAS . printer. error ( error: error)
122+ }
68123 }
69124 }
70- . sorted ( using: KeyPathComparator ( \. name, comparator: . localizedStandard) ) , // swiftformat:enable indent
71- )
125+ }
126+
127+ continuation. resume ( returning: installedApps)
72128 }
73129
74130 query. start ( )
0 commit comments