From e8f6113d6a922064c3436c7c85fd15f40196199a Mon Sep 17 00:00:00 2001 From: seung6lee Date: Tue, 14 Jul 2026 23:50:05 +0900 Subject: [PATCH] initial commit --- .gitignore | 3 + TODO | 4 + __pycache__/brewfile_tool.cpython-314.pyc | Bin 0 -> 11161 bytes apps.csv | 94 +++++++++++ brewfile_tool.py | 185 ++++++++++++++++++++++ notes/brew.md | 79 +++++++++ notes/category.txt | 19 +++ 7 files changed, 384 insertions(+) create mode 100644 .gitignore create mode 100644 TODO create mode 100644 __pycache__/brewfile_tool.cpython-314.pyc create mode 100644 apps.csv create mode 100644 brewfile_tool.py create mode 100644 notes/brew.md create mode 100644 notes/category.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bab06b4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +Brewfile +Brewfile_*.backup +.DS_Store \ No newline at end of file diff --git a/TODO b/TODO new file mode 100644 index 0000000..e94f4b7 --- /dev/null +++ b/TODO @@ -0,0 +1,4 @@ + +Todo: + ☐ Make dependency not hardcoded + ☐ Pass depencency detect if package is in list diff --git a/__pycache__/brewfile_tool.cpython-314.pyc b/__pycache__/brewfile_tool.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0c1b8fe75249bd812a69aaf0369db8c87fc8f275 GIT binary patch literal 11161 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 Gr~d^{Rhel3 literal 0 HcmV?d00001 diff --git a/apps.csv b/apps.csv new file mode 100644 index 0000000..f12f044 --- /dev/null +++ b/apps.csv @@ -0,0 +1,94 @@ +ο»Ώname,type,mas_id,install_on_setup,category,description,price +ente-auth,cask,,yes,security,Free secure two-factor auth service,free +android-platform-tools,cask,,no,utilities,ADB tools,free +sozercan/repo/kaset,cask,,yes,media,MacOS YTM client,free +latest,cask,,yes,utilities,Check all app update,free +localsend,cask,,no,network,Share file between devices,free +modern-csv,cask,,no,development,CSV viewer for large file,free +motrix,cask,,no,network,Torrent download client,free +orbstack,cask,,yes,development,Docker replacement,free +pika,cask,,yes,utilities,Color picker,free +timescribe,cask,,yes,productivity,Time and App usage tracker,free +warp,cask,,yes,development,Best Terminal,free +fluent-reader,cask,,yes,productivity,RSS Reader,free +lunacy,cask,,yes,creativity,Figma alternative,free +zen,cask,,yes,productivity,Firefox based main browser,free +opencloud,cask,,yes,network,Opencloud desktop client,free +raycast,cask,,yes,personalization,Superior version of spotlight,free +claude,cask,,yes,ai,Claude desktop client,free +lookaway,cask,,yes,personalization,Eye protection,paid +notion,cask,,yes,knowledge,Notion desktop client,free +visual-studio-code,cask,,yes,development,Code editor,free +maccy,cask,,yes,personalization,Clipboard manager,free +iina,cask,,yes,media,Media player,free +itsycal,cask,,yes,personalization,Menubar calendar app,free +sidenotes,cask,,yes,knowledge,Sidepanel note app,paid +rectangle,cask,,yes,personalization,Window management tool,free +karabiner-elements,cask,,yes,personalization,Keyboard customization tool,free +zotero,cask,,no,knowledge,Reference organize tool,free +affine,cask,,yes,knowledge,Opensource notion alternative,free +busycontacts,cask,,yes,productivity,Contact management tool with CalDAV support,paid +affinity,cask,,yes,creativity,Photoshop alternative by canva,free +discord,cask,,yes,social,Discord desktop client,free +shifty,cask,,yes,personalization,Night shift adjust tool,free +keka,cask,,yes,utilities,File extraction enhancer,free +keyboardcleantool,cask,,yes,utilities,Lock keyboard input during cleaning,free +appcleaner,cask,,yes,utilities,Remove app without residue,free +monitorcontrol,cask,,yes,personalization,Control external monitor brightness,free +alcove,cask,,yes,personalization,Notch app,paid +tunnelbear,cask,,yes,network,VPN,free +arduino-ide,cask,,no,development,Arduino IDE,free +clop,cask,,yes,personalization,File compressor,free +insomnia,cask,,yes,development,API tester,free +obsidian,cask,,yes,knowledge,Knowledge management tool,free +openmtp,cask,,yes,utilities,Android device connector,free +responsively,cask,,no,development,Browser for responsible website development,free +telegram,cask,,yes,social,Telegram desktop client,free +wireshark-app,cask,,no,network,Network packets capturer,free +git,formula,,yes,development,Version management tool,free +mole,formula,,yes,utilities,System optimizer,free +fastfetch,formula,,yes,utilities,Neofetch alternative,free +mas,formula,,yes,utilities,CLI appstore,free +tree,formula,,yes,utilities,File structure tree,free +scrcpy,formula,,no,utilities,Android screen mirroring,free +thaw,formula,,yes,personalization,Menubar hidder,free +nmap,formula,,no,network,Network scanner,free +davinci resolve ,manual,,no,creativity,Video editor,free +reef,manual,,no,personalization,"Shortcuts based app switcher +https://github.com/gouwsxander/Reef",free +tageditor,mas,984278082,no,utilities,Audio file metadata editor,free +Allkdic,mas,1033453958,yes,productivity,Menubar dictionary,free +Bitwarden,mas,1352778147,yes,security,Password manager,free +Hancom Office HWP Viewer,mas,416746898,yes,productivity,Hancom Office HWP Viewer,free +KakaoTalk,mas,869223134,yes,social,KakaoTalk,free +Linearity Curve,mas,1219074514,no,creativity,Vector based design tool,free +Poolsuite FM,mas,1514817810,no,media,Internet music radio,free +Print to PDF,mas,1639234272,yes,utilities,Save pdf to file,free +RunCat,mas,1429033973,yes,personalization,Menubar system usage visualizer,free +Texty,mas,1538996043,yes,social,Third-party google chat desktop client,free +Windows App,mas,1295203466,yes,productivity,Windows RDP client,free +WireGuard,mas,1451685025,yes,network,Wireguard client,free +Xcode,mas,497799835,no,development,Xcode,free +anthropic.claude-code,vscode,,yes,tool,Claude integration,free +bierner.markdown-mermaid,vscode,,yes,integration,Support mermaid,free +esbenp.prettier-vscode,vscode,,yes,format,Formatter,free +fabiospampinato.vscode-todo-plus,vscode,,yes,tool,Todo management,free +formulahendry.code-runner,vscode,,yes,tool,Code runner with shortcuts support,free +inferrinizzard.prettier-sql-vscode,vscode,,yes,format,SQL formatter,free +james-yu.latex-workshop,vscode,,yes,integration,Latex integration,free +marp-team.marp-vscode,vscode,,no,integration,Support marp(MD based presentation),free +matt-meyers.vscode-dbml,vscode,,yes,integration,Support DBML,free +mechatroner.rainbow-csv,vscode,,yes,format,CSV highlighter,free +ms-azuretools.vscode-containers,vscode,,yes,tool,Container tool,free +ms-python.black-formatter,vscode,,yes,format,Python formatter,free +ms-python.python,vscode,,yes,language,Python integration,free +ms-vscode-remote.remote-ssh,vscode,,yes,tool,SSH conntection,free +pkief.material-icon-theme,vscode,,yes,theme,Best icon,free +pkief.material-product-icons,vscode,,yes,theme,Best product icon,free +pomdtr.excalidraw-editor,vscode,,no,integration,Excalidraw integration,free +rickaym.manim-sideview,vscode,,no,integration,Manim integration,free +ritwickdey.liveserver,vscode,,no,tool,Web frontend live server,free +svelte.svelte-vscode,vscode,,yes,language,Sevelte integration,free +wayou.vscode-todo-highlight,vscode,,yes,tool,Todo file highlighter,free +yzhang.markdown-all-in-one,vscode,,yes,language,Markdown highlighter & formatter,free +zhuangtongfa.material-theme,vscode,,yes,theme,Best darkmode theme (One Dark Pro),free \ No newline at end of file diff --git a/brewfile_tool.py b/brewfile_tool.py new file mode 100644 index 0000000..3d81cf4 --- /dev/null +++ b/brewfile_tool.py @@ -0,0 +1,185 @@ +# ====== Config ====== +CSV_FILE = './apps.csv' +BREWFILE = './Brewfile' +SUPPORT_CONFIG = { + 'formula': {'token': 'brew', 'structure': lambda data: f'brew "{data["name"]}"', 'dependency': [] }, + 'cask' : {'token': 'cask', 'structure': lambda data: f'cask "{data["name"]}"', 'dependency': [] }, + 'mas': {'token': 'mas', 'structure': lambda data: f'mas "{data["name"]}", id: {data["mas_id"]}', 'dependency': [{'name': 'mas', 'script': ['brew', 'install', 'mas']}] }, + 'vscode': {'token': 'vscode', 'structure': lambda data: f'vscode "{data["name"]}"', 'dependency': [{'name': 'code', 'script': ['brew', 'install', '--cask', 'visual-studio-code']}] } +} +MANUAL_TYPE = 'manual' + +support_types = list(SUPPORT_CONFIG.keys()) + + +import csv +import subprocess +import shutil +import datetime +import sys + +clear = lambda: subprocess.run(['clear']) + +def check_package(name): + path = shutil.which(name) + if not path: + return False + return True + +def check_brew(): + if not check_package('brew'): + print('❌ Unable to find brew') + sys.exit() + +def get_csv(): + with open(CSV_FILE, 'r', encoding='utf-8-sig') as f: + return list(csv.DictReader(f)) + +def create_brewfile(): + try: + with open(BREWFILE, 'r') as old: + stamp = datetime.datetime.now().strftime('%Y%m%d_%H%M%S') + with open(f'./Brewfile_{stamp}.backup', 'w') as new: + new.writelines(old.readlines()) + print(f'πŸ“’ Backup old Brewfile (Brewfile_{stamp}.backup)') + except FileNotFoundError: + pass + + raw_list = get_csv() + temp = {pkg_type:[] for pkg_type in support_types} + + for row in raw_list: + pkg_type = row['type'] + if pkg_type in temp.keys(): + if row['install_on_setup'] == 'yes': + content = f'# {row["description"]}\n{SUPPORT_CONFIG[pkg_type]["structure"](row)}\n' + temp[pkg_type].append(content) + elif pkg_type != MANUAL_TYPE: + print(f'Error: {row["name"]} {pkg_type}') + sys.exit() + + with open(BREWFILE, 'w') as f: + for pkg_type in support_types: + f.write(f'# {"=" * 15} {pkg_type} {"=" * 15}\n') + f.writelines(temp[pkg_type]) + f.write('\n') + + print('βœ… Successfully create Brewfile') + +def get_brewfile_types(): + token_to_type = {SUPPORT_CONFIG[t]['token']: t for t in support_types} + types = set() + try: + with open(BREWFILE, 'r') as f: + for line in f: + token = line.strip().split(' ', 1)[0] + if token in token_to_type: + types.add(token_to_type[token]) + except FileNotFoundError: + print('❌ Unable to find Brewfile (create it first)') + return types + +def install_dependencies(): + dependencies = [] + seen = set() + for pkg_type in get_brewfile_types(): + for dep in SUPPORT_CONFIG[pkg_type]['dependency']: + if dep['name'] not in seen: + seen.add(dep['name']) + dependencies.append(dep) + + for dep in dependencies: + if check_package(dep['name']): + print(f'βœ… Dependency "{dep["name"]}" already installed') + continue + print(f'πŸ“’ Installing missing dependency "{dep["name"]}"...') + try: + subprocess.run(dep['script'], check=True) + print(f'βœ… Successfully installed dependency "{dep["name"]}"') + except subprocess.CalledProcessError as e: + print(f'❌ Failed to install dependency "{dep["name"]}" ({e.returncode})') + return False + except FileNotFoundError: + print(f'❌ Unable to find command to install dependency "{dep["name"]}"') + return False + return True + +def bundle_install(): + if not install_dependencies(): + print('❌ Aborting install due to missing dependency') + return + + try: + subprocess.run(['brew', 'bundle', 'install', f'--file={BREWFILE}'], check=True) + print('βœ… Successfully install all packages') + except subprocess.CalledProcessError as e: + print(f'❌ Failed to install some packages ({e.returncode})') + except FileNotFoundError: + print('❌ Unable to find brew') + + +def bundle_check(): + try: + print('πŸ“’ Check script running') + result = subprocess.run( + ['brew', 'bundle', 'check', f'--file={BREWFILE}', '--verbose'] + ) + if result.returncode == 0: + print('βœ… Every packages are installed') + return True + else: + print('⚠️ There are uninstalled package(s)') + return False + except FileNotFoundError: + print('❌ Unable to find brew') + return False + + + +def bundle_cleanup(): + try: + subprocess.run(['brew', 'bundle', 'cleanup', f'--file={BREWFILE}']) + if input('⚠️ Are sure want to remove? (y/N): ').strip().lower() == 'y': + subprocess.run(['brew', 'bundle', 'cleanup', f'--file={BREWFILE}', '--force'], check=True) + print('βœ… Successfully cleanup') + else: + print('πŸ“’ Canceled') + except subprocess.CalledProcessError as e: + print(f'❌ Failed to cleanup ({e.returncode})') + except FileNotFoundError: + print('❌ Unable to find brew') + + +def select_option(): + options = [ + {'text': 'Create Brewfile', 'func': create_brewfile}, + {'text': 'Install packages', 'func': bundle_install}, + {'text': 'Check packages', 'func': bundle_check}, + {'text': 'Cleanup packages', 'func': bundle_cleanup}, + {'text': 'Exit', 'func': sys.exit} + ] + while True: + print('Select option') + for idx, row in enumerate(options, 1): + print(f' {idx}) {row["text"]}') + raw = input('option: ').strip() + try: + clear() + idx = int(raw) - 1 + if 0 <= idx < len(options): + options[idx]['func']() + print() + return + else: + print(f'⚠️ Write valid number\n') + except ValueError as e: + print(f'⚠️ Write valid number\n') + + +def main(): + check_brew() + while True: + select_option() + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/notes/brew.md b/notes/brew.md new file mode 100644 index 0000000..c4b4203 --- /dev/null +++ b/notes/brew.md @@ -0,0 +1,79 @@ +## Installation / Uninstallation +```sh +brew install # CLI +brew install --cask # GUI +brew uninstall # Uninstall +brew uninstall --zap --cask # Uninstall including cask config +brew reinstall +``` + +## Search +```sh +brew search # List matching packages (formula + cask) +brew info # detailed info +brew home # Open homepage +``` + +## List +```sh +brew list +brew list --formula +brew list --cask +brew list --versions # version of specific package +brew leaves # List only user installed (not dependencies) +brew deps # List dependencies +brew uses --installed # List packages that use this package +``` + +## Update / Upgrade +```sh +brew update +brew upgrade +brew upgrade +brew outdated # List upgradable packages +``` + +## Pin version +```sh +brew pin # Pin specific package version to currently installed one +brew unpin +``` + +## Cleanup +```sh +brew cleanup # Remove order version, cache +brew cleanup --prune=all # Remove all cache +brew autoremove # remove abandoned dependencies +brew doctor # detect problem +brew missing # find omitted dependencies +``` + +## Repo +```sh +brew tap # List all repo +brew tap # add repo +brew untap # remove repo +``` + +## Bundle +```sh +brew bundle dump # Export list of current installation +brew bundle install # Install via Brewfile +brew bundle check # Compare between cur status and Brewfile +brew bundle cleanup --force # Remove packages that are not in the Brewfile +``` + +## Services +```sh +brew services list +brew services start # run + autostart on boot +brew services stop +brew services restart +brew services run # run only once +``` + +## Miscellaneous +```sh +brew --prefix # Get brew path +brew --prefix # Get package path +``` \ No newline at end of file diff --git a/notes/category.txt b/notes/category.txt new file mode 100644 index 0000000..bdc5336 --- /dev/null +++ b/notes/category.txt @@ -0,0 +1,19 @@ +# Formula, Cask, MAS +creativity +development +ai +utilities +media +network +knowledge +productivity +security +social +personalization + +# VScode Extension +language +format +theme +integration +tool \ No newline at end of file