Skip to content

Instantly share code, notes, and snippets.

@darkr4y
Last active November 7, 2023 15:23
Show Gist options
  • Save darkr4y/84c148c70ef2b66165216aec49b746f7 to your computer and use it in GitHub Desktop.
Save darkr4y/84c148c70ef2b66165216aec49b746f7 to your computer and use it in GitHub Desktop.
Script to get macOS apps info and write to CSV.
"""
Script to get macOS apps info and write to CSV.
"""
import argparse
import csv
import os
import plistlib
import subprocess
SP_FILE = 'info.spx'
EXCLUDED_PATHS = [
'/System/Library',
'/Library/Image Capture/',
'/Library/Printers',
'/Library/Application Support/Script Editor',
'/Library/Application Scripts'
]
def is_excluded_path(app):
"""Check if app path is in excluded paths."""
path = app.get('path')
for excluded in EXCLUDED_PATHS:
if excluded in path:
return True
return False
def get_macos_apps_info():
"""Get macOS apps info as .spx file."""
with open(SP_FILE, 'wb') as file:
subprocess.run(['system_profiler', '-xml', 'SPApplicationsDataType'], stdout=file)
def get_brew_casks():
"""Get list of installed brew casks."""
output = subprocess.check_output(['brew', 'list', '--cask']).decode()
return output.splitlines()
def parse_macos_apps_info():
"""Parse macOS apps info from .spx file."""
with open(SP_FILE, 'rb') as file:
plist = plistlib.load(file)
return plist[0]['_items']
def is_preinstalled_app(app):
"""Check if app is preinstalled by macOS."""
return app.get('obtained_from') == 'apple'
def write_to_csv(apps, casks, output_file):
"""Write macOS apps info to CSV file."""
with open(output_file, 'w', newline='') as file:
writer = csv.writer(file)
writer.writerow(['name', 'arch', 'modified', 'obtained', 'path', 'version', 'brew'])
for app in apps:
app_name = app['_name'].lower()
if is_preinstalled_app(app):
continue
if is_excluded_path(app):
continue
brew = f"brew install --cask {app_name}" if app_name in casks else ""
writer.writerow([app.get(key) for key in ['_name', 'arch_kind', 'lastModified', 'obtained_from', 'path', 'version']] + [brew])
def delete_file(filename):
"""Delete file if exists."""
if os.path.exists(filename):
os.remove(filename)
def main(output_file):
"""Main function."""
delete_file(SP_FILE)
get_macos_apps_info()
casks = get_brew_casks()
apps = parse_macos_apps_info()
write_to_csv(apps, casks, output_file)
delete_file(SP_FILE)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Get macOS apps info and write to CSV.')
parser.add_argument('-o', '--output', default='output.csv', help='output CSV file')
args = parser.parse_args()
main(args.output)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment