initial commit
This commit is contained in:
@@ -0,0 +1,3 @@
|
|||||||
|
Brewfile
|
||||||
|
Brewfile_*.backup
|
||||||
|
.DS_Store
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
Todo:
|
||||||
|
☐ Make dependency not hardcoded
|
||||||
|
☐ Pass depencency detect if package is in list
|
||||||
Binary file not shown.
@@ -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
|
||||||
|
@@ -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()
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
## Installation / Uninstallation
|
||||||
|
```sh
|
||||||
|
brew install <formula> # CLI
|
||||||
|
brew install --cask <app> # GUI
|
||||||
|
brew uninstall <formula> # Uninstall
|
||||||
|
brew uninstall --zap --cask <app> # Uninstall including cask config
|
||||||
|
brew reinstall <name>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Search
|
||||||
|
```sh
|
||||||
|
brew search <keyword> # List matching packages (formula + cask)
|
||||||
|
brew info <name> # detailed info
|
||||||
|
brew home <name> # Open homepage
|
||||||
|
```
|
||||||
|
|
||||||
|
## List
|
||||||
|
```sh
|
||||||
|
brew list
|
||||||
|
brew list --formula
|
||||||
|
brew list --cask
|
||||||
|
brew list --versions <name> # version of specific package
|
||||||
|
brew leaves # List only user installed (not dependencies)
|
||||||
|
brew deps <name> # List dependencies
|
||||||
|
brew uses <name> --installed # List packages that use this package
|
||||||
|
```
|
||||||
|
|
||||||
|
## Update / Upgrade
|
||||||
|
```sh
|
||||||
|
brew update
|
||||||
|
brew upgrade
|
||||||
|
brew upgrade <name>
|
||||||
|
brew outdated # List upgradable packages
|
||||||
|
```
|
||||||
|
|
||||||
|
## Pin version
|
||||||
|
```sh
|
||||||
|
brew pin <name> # Pin specific package version to currently installed one
|
||||||
|
brew unpin <name>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 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 <user/repo> # add repo
|
||||||
|
brew untap <user/repo> # 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 <name> # run + autostart on boot
|
||||||
|
brew services stop <name>
|
||||||
|
brew services restart <name>
|
||||||
|
brew services run <name> # run only once
|
||||||
|
```
|
||||||
|
|
||||||
|
## Miscellaneous
|
||||||
|
```sh
|
||||||
|
brew --prefix # Get brew path
|
||||||
|
brew --prefix <name> # Get package path
|
||||||
|
```
|
||||||
@@ -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
|
||||||
Reference in New Issue
Block a user