Introducing `quickpkg`

This tool will quickly and easily build a package from an installed application, a disk image file or zip archive with an enclosed application bundle. It will also extract the application name and version and use it to name the resulting pkg file.

The tool will look for applications on the first level of the disk image or archive. If it finds no or more than one application it will error.

The name of the resulting package will be of the form {name}-{version}.pkg. Spaces will be removed from the name. The package will be written to the current working directory.

Get the tool at the quickpkg repository.

Examples

Build package from installed application:

quickpkg /Applications/Numbers.app

Build package from a disk image:

quickpkg ~/Downloads/Firefox\ 43.0.4.dmg

Build package from a zip archive:

quickpkg ~/Downloads/Things.zip

Background

OS X has had the pkgbuild tool since Xcode 3.2 on Snow Leopard. With pkgbuild you can directly build a installer package from an application in the /Applications folder:

pkgbuild --component /Applications/Numbers.app Numbers.pkg

Or even an application inside a mounted dmg:

pkgbuild --component /Volumes/Firefox/Firefox.app \
         --install-location /Applications \
         Firefox.pkg

This tool even does the work of determining a bundle’s identifier and version and sets the identifier and version of the pkg to the same values.

However, while pkgbuild does automatically name the package, it does not include the version, which is important when you tracking many versions of the same application. It also doesn’t automatically look into a dmg file or zip archive.

quickpkg vs autopkg

This tool is not meant to replace autopkg. autopkg will automate the download, the re-packaging (if necessary) and the upload to and configuration of your client management system. It can also handle much more complex setups than quickpkg. autopkg is far superior and should be your tool of choice.

However, there are situations where autopkg does not work well. The most common reason is if the download cannot be automated because the download page is behind a paywall. Also autopkg requires a recipe for a given piece of software. If no recipe exists, quickpkg may be a simple alternative. (Though if quickpkg works, creating an autopkg recipe should not be hard.)

Warning

All quickpkg does is identify an application bundle and package it in a way that the package will install that application bundle into the /Applications folder. If the application needs other files (libraries, frameworks, configuration files, license files, preferences etc.) to run and work they are your responsibility.

Creating a Droplet for munkiimport

You can use Automator to build an applet for munkiimport. Then you can just drag and drop pkgs, dmgs and Applications on it to import them.

However, can’t just use do shell script since munkiimport will prompt for some extra information. Instead you can use Terminal’s command do script. While do shell script will execute then given command quietly in the background, do script will open a new Terminal window and run the given command – just what we need.

Open Automator and create a new workflow. Choose ‘Application’ as the template. This template will accept files and folders dropped on it. Add a ‘Run AppleScript’ action and fill in the following code:

on run {input, parameters}
  repeat with x in input
    tell application "Terminal"
      do script "munkiimport" & space & quoted form of POSIX path of (x as alias)
    end tell
  end repeat
  return input
end run

Then save the Automator applet as ‘MunkImport’. (or whatever suites you)

The downside of do script versusĀ do shell script is that you cannot receive and process the result.

MacID adds Scripting Support

MacID is a very useful application which automatically locks a Mac when a paired iOS device moves out of range. It will also offer to unlock the Mac using Touch ID on the device, but I use that part less than I would expect. (You can also unlock with Apple Watch, which is cool.)
The latest update adds scripting support:

You can now extend MacID by dropping AppleScript text files (they MUST be exported as text files) into onSleep, onLock, onWake, onUnlock directories in ~/Application Support/MacID/. MacID will execute these scripts at the respective event. For example, you could pause iTunes when your Mac locks, and resume playing when your Mac unlocks.

To try this, I created a simple AppleScript

tell application "iTunes"
  pause
end tell

and saved it as a text AppleScript document in the onUnlock folder. Works as expected!

Typefaces for Terminal and text editing

Many users on Twitter pointed out a new typeface designed for terminals and text editors called Hack. It looks nice but I thought I’d make a list of other useful open source typefaces:

  • Source Code Pro from Adobe is designed for code editing. This is my favorite and I have set it in Terminal and BBEdit. It has many different weights, italics, and also related typefaces Source Sans Pro and Source Serif Pro in case you want proportional typefaces as well. These are regularly updated with minor improvements and new glyphs.

  • Courier Prime is an improvement on the standard Courier typeface. There are also sans serif and code versions available.

  • Hack is the new typeface which inspired this post. The characters seem much larger than similar fonts at the same point size, but according to the page that is intentional.

Hack will be nice to have around, but for now Source Code Pro remains my favorite.

(If you, like me, are curious when to use ‘typeface’ vs ‘font’ then read this helpful article.)

Mount a dmg off a web server

I saw this project by Douglas Nerad which stream lines the bootstrapping installation of Munki, so that you can do it while booted from the Recovery partition. This is useful to inject munkitools on a new Mac without having to go through setting up a user.

The read me recommends to put the script and other resources on a USB key, which works fine, as long you have only one USB key. If you have to share this tool among multiple admins keeping the keys up to date (and in your pocket) can be a pain.

If you put all the resources and the script in an dmg file on a web server, you can run

hdiutil attach http://webserver/path/to/InstallThis.dmg

and then run scripts and installer pkgs from the attached volume.

installer -pkg /Volumes/InstallThis/munkitools2-latest.pkg
/Volumes/InstallThis/setupEverything.sh

Note that you cannot run python scripts from the Recovery partition. It is best to use shell or bash scripts.

Check Python Syntax in BBEdit with flake8

There are existing scripts out there that will run flake8 against a python file in BBEdit, but none of them worked quite the way I wanted. So here is mine:

Before you can run this, you need to install flake with sudo easy_install flake8. Then you need to drop this script in ~/Library/Application Support/BBEdit/Scripts. You can launch it from the menu with the script icon.

On Internet Shortcut Files

If you are managing Macs and PCs, then you will frequently connect to other computers or virtual machines through screen sharing, secure shell or other means. Here is a simple trick to make those connections easier:

Open your favored UI text editor (Text Edit will do) and type

vnc://<username>@<hostname>

Replace <username> and <hostname> with your username and hostname for a Mac you frequently share the screen with.

Then select the entire text and drag it to the desktop. It will create a file with “@” sign on the icon. When you double click this file, Screen Sharing opens and asks for the password (unless it is stored in the Keychain) and connects the remote session.

Now rename this file to VNC <hostname>. Then activate Spotlight (cmd-space) and start typing “VNC” and the hostname. After a few characters the VNC link file should be the top result. Hit return and the session starts.

As an extra bonus you can put these files in a folder in your cloud file system of choice (iCloud Drive, Dropbox, Google Drive, Box, etc.) and they will sync to all your Macs.

Other Protocols

You can do the same with any URI scheme:

ssh://<username>@<hostname>:<port>

afp://<username>@<hostname>/<share>

smb://<username>@<hostname>/<share>

http://<hostname/<path>

Microsoft Remote Desktop/RDP

The new Microsoft Remote Desktop application available in the Mac App Store also supports rdp URI schemes, however the syntax is a bit odd. To connect to a remote host you have to use:

rdp://full%20address=s:<hostname>&username=s:<username>

You can find more options for this URI scheme in this technote. One I have found useful is screen mode id where a value of 1 means to open the remote screen in a window a value of 2 means full screen mode.

Looking into the files

If inspect the file generated by dragging, you can see that it is a property list file with a single key URL and a string value containing the link.

Files for a vnc URI get the .vncloc extension, http[s] URIs get the .webloc extension, ftp URIs get the .ftploc extension and everything else seems to get .inetloc extensions. (There may be more, let me know if you find any.)

This makes it easy to write a short script that simplifies the creation of these internet location files:

Sample use:

./create_netloc.py vnc://user@host.example.com

will create VNC host.vncloc

./create_netloc.py http://munki.example.com/munkireport-php/ Munkireport

will create Munkireport.webloc

./create_netloc.py "rdp://full%20address=s:host.example.com&username=s:name&screen%20mode%20id=i:1"

will create RDP host.inetloc

Note on rdp links: since the ‘&’ is special in shell commands you need to quote the uri if any are present.

Fun with find and git

find ~ -type d -name .git -exec dirname {} \;

will show you all folders in your home directory which have a .git subfolder — i.e. they are git repositories.

This is useful, but can be extended to:

find ~ -type d -name .git -exec dirname {} \; | tr '\n' '\000' | xargs -0 -n1 -I % git -C "%" status

to show the git status output of all your git repositories.

Time to clean up!