My thinking was fuzzy in regards to what’s wrong with git submodules. So I finally opened up an editor window and started typing how I think an Ideal Submodule System should work. I wound up with this:
The subproject is copied into the super-project’s repo. At least a snapshot of it, if not the entire history. It’s a fact of life external resources have a habit of disappearing — this helps makes your project resilient.
git clone foo is enough. None of this git clone --recursive foo or git submodule init && git submodule update business.
Can easily pull subproject updates.
Can easily push subproject updates.
Can easily handle super-project branching.
Super-project’s commits don’t wind up in subproject’s history.
Subproject’s commits don’t wind up in super-project’s history.
Armed with clearer thinking, I reexamined my options and have settled on Avery Pennarun’s git-subtree.
Unfortunately its CLI UX is lacking (you have to specify the subproject’s entire remote repo URL each time you pull or push) and Avery hasn’t accepted pull requests or budged the project for a year. Fortunately Helmo forked Avery’s repo, added .gittrees support and push-all and pull-all subcommands, and generally seems to be keeping on top of pull requests and moving the project forward.
I just started using git-subtree, but so far it’s making my life better than before.
P.S. Here’s a short primer on using git-subtree.
Update: Hmm, I discovered and turned to Helmo’s fork after I got tired of reentering my remote repo URL each time I wanted to push or pull a subtree. Turns out Helmo’s fork is currently unstable — the tests don’t pass and there’s a definite bug in it when adding a repo as a subtree that doesn’t show up until you attempt push it back. So I recommend using Avery’s original repo until it’s fixed.
Update 2: I fixed the bug and tests are passing in my git-subtree fork. git subtree push-all away!
DTerm is a free app that uses the Accessibility API to figure out the current document you’re looking at. When you hit a hotkey (mine is bound to command-shift-return), it pops up a window with a shell command line with the working directory already set to the frontmost document’s folder.
DTerm works awesomely with Finder, BBEdit, TextMate, Xcode, GitX and a bunch of other Mac apps.
Protip: instead of typing return to execute your DTerm command, type command-return to open a new Terminal.app window with your command. Great if you plan a few follow-up commands or want colored output.
I accidentally stumbled across my notes for what would become C4, and I realized I’ve been using Yojimbo for a very long while.
Yojimbo is such a great app, it hard for me to think of the time before I used to use it.
I use Yojimbo as a digital junk drawer, storing programming snippets, shell invocations, SQL nuggets, notes on different projects & processions and archives of web pages that I fear will vanish (most of which have).
It does a little bit too much for me, but it’s easy to ignore the things I don’t used it for (like storing serial numbers).
I’m actually still using Yojimbo 1.5.2 since I love its original icon so much. I’m planning on upgrading to Yojimbo 4 once the iCloud dust settles, but I’ll have to copy and paste 1.x’s icon onto the new version. Can’t live without it.
If you use VNC much at all, you need JollysFastVNC:
Here’s how it’s better than Apple’s Remote Desktop, which I struggled along with for too many years:
The only thing bad about it JollysFastVNC is… its name.
P.S. You should buy it directly (through Esellerate) instead of through the Mac App Store — Apple is restricting functionality more and more. Patrick’s putting up a valiant effort, but the writing’s on the wall.
I’ve mentioned before that Pear Note is an App I Love.
Pear Note 2.0 just shipped with a UI overhaul, web sharing and playback speed control. I just gave it a whirl and it seems even slicker than before.
Recommended.
Pester is Nicholas Riley’s free-and-awesome app for setting alarms for yourself in the future.
Need to catch the train in 20 minutes? Is your show coming on at 7 pm?
Pester is easier to enter such alarms than iCal, and gives you a nice countdown in its dock icon.
Nicholas has done a stellar job over the years polishing the app’s UI to ease the creation of new alarms. It’s obviously an app Nicholas uses himself.
Protip #1: while Pester offers a combo box to make it easy to enter and re-enter an alarm’s message, the message is optional. I usually leave mine blank since the context is obvious.
Protip #2: Pester supports shorthand for time entry. Type 90m to set a relative alarm ninety minutes in the future or 3h for one in three hours. Likewise, 3p expands to 3:00 pm when dealing with absolute times.
I used to keep my serial numbers in a simple text file. But I’d fall behind in keeping it up-to-date, and inevitably have to resort to searching my inbox whenever I’d need a serial number again.
But things got better when I bought Jon Trainer’s LicenseKeeper.
It’s actually fun now to import serial numbers, so I always do it.
It’s fun to drag the app into LicenseKeeper and have it appear in my now well-organized collection.
It’s fun to use the “Attach Email” feature that attaches the registration email to LicenseKeeper’s serial number record and attempts to extract the serial number text embedded within the email.
I like to guess whether or not the extraction feature will work. How is the email formatted? Small software shop (and thus unlikely Jon has encountered their registration email before) or a BigCo? Does the serial number follow common conventions or is it weird somehow?
Most of the time, the extraction feature amazingly works. (When it doesn’t, no biggie — my human eyes have already picked out the magical text I need to copy+paste into LicenseKeeper’s fields.)
There must be boatload of heuristics in LicenseKeeper to pull off extraction.
Jon also does a great job of keeping LicenseKeeper fresh: usually when I launch it, there’s an update available.
This year I jumped from Liquid Ledger to MoneyWell for doing my taxes.
It was a bit of a leap of faith, but it turned out well — MoneyWell is simply the best personal finance app I’ve ever used.
※ ※ ※
I dismissed MoneyWell 1.0 a while back based on its design decisions (a shallow reason I know, but the field is littered with non-native or just-plain-weird apps and painful experience has taught me if it looks out of place, it’s not a great Mac app).
1.5 features a redesign that streamlines the UI. Button margins are no longer askew and the inexplicable use of Matt Gemmell’s RoundedBox has thankfully been removed (I don’t have a beef with RoundedBox per se — it’s just its use was out of place).
1.5 is lighter and brighter, leaving behind the 1.0’s use of heavy gray-gradient section-separator title bars.
Unfortunately as of this writing, Kevin hasn’t updated the screenshots on MoneyWell’s site to reflect the 1.5’s redesigned UI, so you’ll need to download and try the app yourself if you want to see the improved UI.
MoneyWell was able to connect to every financial institution that offered direct connections, and correctly imported the QFX/OFX files from those that don’t.
MoneyWell is the first personal finance app I used that didn’t feel clunky. Instead, it feels fluid, with lots of attention to the details that makes Mac indie software great.
I have a lot of passwords. Always have, probably always will (although SuperGenPass mitigates the need for a lot of one-off passwords — I ‘m looking forward to when something like it comes built-in to browsers).
There’s always been a lot of password management apps on the Mac, but my weapon of choice is PasswordWallet.
I decided on it back in the Mac OS 8 days because it also had a Palm version and synced my encrypted password file like a dream.
Numerous times I’ve been saved by having all my private passwords and info on me at all times. At ATMs and banks. At government offices. And especially at colo racks.
There seems to be even more password management apps now then there were when I selected PasswordWallet. Even though it has a funky UI, I stay with PasswordWallet for a few different reasons:
Stores passwords separately from Mac OS X’s keychain. I try not to store Very Important passwords in Mac OS X’s built-in keychain. Perhaps just paranoia on my part, but the system keychain strikes me as a well-known centralized place for extraction attacks. Keychain Access.app’s icon may as well have a big red target on it.
PasswordWallet can be configured to store your master password in the keychain, but I leave this option off.
No plugins. PasswordWallet is Just An App, and I like its code that reads+writes my passwords doesn’t wind up in other processes’ address space. Again, this is mostly paranoia.
Best-in-class Auto-typing. Since PasswordWallet is Just An App, its primary shuttle for getting its passwords out of its encrypted storage and into some godforsaken text field is auto-typing.
Auto-typing is when a program puppets (probably via CGEventCreateKeyboardEvent()) the event posting mechanism to make other software believe the user is keying in the long password herself.
Getting auto-typing right is tricky in the face of things like Secure Keyboard Entry, but PasswordWallet always operates correctly for me.
PasswordWallet’s typing abilities are more extensive than you may first realize — it was straight-forward for me to automate logging into EFTPS to pay my US941’s, supplying my segmented EIN, pin and password all in one click. Handy, and makes paying the tax man just a little less painful.
And of course there’s an iPhone version of PasswordWallet nowadays which nicely synchronizes with my desktop machine.
Long story, short: PasswordWallet has been there for me for years and shows no signs of quitting.
My desktop is clear again, and I didn’t have to lift a finger thanks to Hazel.
I have a script that auto-archives all items on my Desktop and Download folders that I haven’t looked at for a week.
Above is the selection criteria I use to tell Hazel when to fire my script. My script is:
on run
tell application "Finder"
set victimList to (selection as list)
repeat with victimItem in victimList
my archiveVictim(victimItem as alias)
end repeat
end tell
end run
on hazelProcessFile(infile)
my archiveVictim(infile)
end hazelProcessFile
on archiveVictim(victim)
tell application "Finder"
set accessDate to metadata access date of victim
set archiveFolder to my archiveFolderForDate(accessDate)
try
move victim to archiveFolder
on error errMsg number errNum
if errNum = -15267 then
set fileName to (name of victim)
reveal item fileName of archiveFolder
reveal victim
tell me
set dialogAnswer to display dialog ¬
"Duplicate Name: " & fileName buttons {"Cancel", "Trash Archived", "Trash Victim"} ¬
default button "Trash Victim"
if button returned of dialogAnswer is "Trash Victim" then
tell application "Finder" to delete victim
else
tell application "Finder"
delete item fileName of archiveFolder
move victim to archiveFolder
end tell
end if
end tell
else
error errMsg number errNum
end if
end try
end tell
end archiveVictim
on archiveFolderForDate(inDate_)
tell application "Finder"
-- archive folder
set documentsFolder to path to documents folder
if not (exists folder "archive" of documentsFolder) then ¬
make new folder at documentsFolder with properties {name:"archive"}
set archiveFolder to folder "archive" of documentsFolder
-- date folder
set dateFolderName to "" & year of inDate_ & "-" & my weeknum(inDate_)
if not (exists folder dateFolderName of archiveFolder) then ¬
make new folder at archiveFolder with properties {name:dateFolderName}
set dateFolder to folder dateFolderName of archiveFolder
return dateFolder as alias
end tell
end archiveFolderForDate
on weeknum(inDate_)
set firstDayOfYear to date ("1/1/" & (year of inDate_))
set dayNumberOfYear to (((inDate_ - firstDayOfYear) / days) as integer) + 1
set numberOfLastYearsDaysInFirstWeek to (weekday of firstDayOfYear) - 1
set paddedDayNumberOfYear to dayNumberOfYear + numberOfLastYearsDaysInFirstWeek
round paddedDayNumberOfYear / 7 rounding up
end weeknum
This script files all its “victims” into a folder called “archive” in my Documents folder.
If a victim already exists there (this can happen if I absent-mindedly download the same file twice), the script shows does nothing except reveal both competing files, with the idea that I’ll probably delete one of them later.
The script also has a run handler so I can invoke it directly in the Finder via FastScripts.
Note: this script makes use of my access date AppleScript addition to access the victim’s metadata access date to figure out where to temporally file the victim.
The script creates dated folders in the format of <YEAR>-<WEEK_NUMBER> which looking at it now I don’t think is perfectly ideal. If I had to do it over, I’d probably do <YEAR>-<MONTH>-<WEEK_NUMBER> since it’s hard to pick out, say June, from a list of week numbers.
I kinda wish this archiving was built into Hazel instead of me having to write+maintain my own script.
Fun fact: prior to Hazel and this script, I’d create a folder called “_clean” every time I had to give a presentation (a lot) or my Desktop overwhelmed me and dump everything in there. This lead to insane nesting of _clean folders inside of _clean folders, many layers deep.
I think that’s how I ran into PATH_MAX blackholing.
Update: Here’s how to get Hazel to auto-archive stuff sans scripting.