Package hdiutil provides a Go wrapper around the macOS hdiutil command-line tool
for creating, manipulating, and signing DMG disk images.
Note: This package requires macOS — it wraps native macOS tooling (
hdiutil,codesign,xcrun,bless).
| Image formats | UDZO (zlib, default), UDBZ (bzip2), ULFO (lzfse), ULMO (lzma) |
| Filesystems | HFS+ (default, with tuned allocation parameters) and APFS |
| Workflow orchestration | Runner manages the full lifecycle: create, mount, modify, convert, sign, notarize |
| Sandbox-safe images | Produce DMGs openable by sandboxed macOS applications |
| Code signing & notarization | Integrated codesign and Apple notarytool/stapler support |
| JSON configuration | Load/save Config from JSON files for CI/CD pipelines |
| Input sanitization | Rejects null bytes and dash-prefixed paths to prevent argument injection |
| Dry-run mode | Simulate() option previews all hdiutil invocations without executing them |
| Testable | Typed CommandExecutor interface with WithExecutor and Simulate options for mock injection |
go get al.essio.dev/pkg/hdiutilpackage main
import (
"log"
"al.essio.dev/pkg/hdiutil"
)
func main() {
cfg := &hdiutil.Config{
SourceDir: "./dist",
OutputPath: "MyApp.dmg",
VolumeName: "My App",
}
runner := hdiutil.New(cfg)
defer runner.Cleanup()
// 1. Validate config, create temp directory.
if err := runner.Setup(); err != nil {
log.Fatal(err)
}
// 2. Create a writable temporary image populated from SourceDir.
if err := runner.Start(); err != nil {
log.Fatal(err)
}
// 3. (Optional) Mount, modify contents, unmount.
// if err := runner.AttachDiskImage(); err != nil { log.Fatal(err) }
// ... copy files, customise .DS_Store, etc.
// _ = runner.Bless() // mark bootable (no-op unless Config.Bless is set)
// _ = runner.DetachDiskImage() // fixes permissions and unmounts
// 4. Convert to final compressed DMG.
if err := runner.FinalizeDMG(); err != nil {
log.Fatal(err)
}
// 5. (Optional) Sign and notarize — no-ops when credentials are empty.
if err := runner.Codesign(); err != nil {
log.Fatal(err)
}
if err := runner.Notarize(); err != nil {
log.Fatal(err)
}
}cfg := &hdiutil.Config{
SourceDir: "./dist",
OutputPath: "MyApp.dmg",
SandboxSafe: true,
FileSystem: "HFS+", // APFS is not supported in sandbox-safe mode
}The Runner goes through a fixed sequence of steps — calling methods out of order
returns an error.
Setup ➜ Start ➜ [Attach ➜ modify ➜ Bless ➜ Detach] ➜ FinalizeDMG ➜ [Codesign] ➜ [Notarize]
│ optional optional
└─ validates config, creates temp dir
This package is part of the unixtools project and is released under the same license.