feat(wpcarro/emacs): Package emacs GUI for OSX

Did a little reverse-engineering to try and figure out how to package GUIs for
OSX, which where I learned about:
- `Info.plist`
- `version.plist`
- `pkgs.lib.generators.toPlist`

I'm sure there is more to do to make idiomatically pkg this, but this is enough
to get started, and I need to move-on.

Change-Id: I5168eada32223c5cc2f20defd3d27bccaceb3775
Reviewed-on: https://cl.tvl.fyi/c/depot/+/7317
Autosubmit: wpcarro <wpcarro@gmail.com>
Tested-by: BuildkiteCI
Reviewed-by: wpcarro <wpcarro@gmail.com>
This commit is contained in:
William Carroll 2022-11-20 19:20:26 -08:00 committed by clbot
parent 4cd4111d0d
commit e5b9eafb8d
2 changed files with 66 additions and 14 deletions

Binary file not shown.

View file

@ -3,7 +3,7 @@
# - Darwin # - Darwin
# #
# USAGE: # USAGE:
# $ mg build //users/wpcarro/emacs:osx # $ nix-build -A users.wpcarro.emacs.osx -o /Applications/BillsEmacs.app
{ depot, pkgs, lib, ... }: { depot, pkgs, lib, ... }:
# TODO(wpcarro): See if it's possible to expose emacsclient on PATH, so that I # TODO(wpcarro): See if it's possible to expose emacsclient on PATH, so that I
@ -32,10 +32,10 @@ let
rust-analyzer rust-analyzer
rustc rustc
rustfmt rustfmt
xorg.xset
] ++ ] ++
(if pkgs.stdenv.isLinux then [ (if pkgs.stdenv.isLinux then [
scrot scrot
xorg.xset
] else [ ])) ] else [ ]))
); );
@ -174,25 +174,75 @@ let
${concatStringsSep "\n " (map (el: "--load ${el} \\") load)} ${concatStringsSep "\n " (map (el: "--load ${el} \\") load)}
"$@" "$@"
''; '';
# I can't figure out how to augment LSEnvironment.PATH such that it inherits
# the default $PATH and adds the things that I need as well, so let's
# hardcode the desired outcome in the meantime.
osxDefaultPath = builtins.concatStringsSep ":" [
"/Users/bill/.nix-profile/bin"
"/nix/var/nix/profiles/default/bin"
"/opt/homebrew/bin"
"/opt/homebrew/sbin"
"/usr/local/bin"
"/usr/bin"
"/bin"
"/usr/sbin"
"/sbin"
"/opt/X11/bin"
];
infoPlist = pkgs.writeText "Info.plist" (pkgs.lib.generators.toPlist { } {
LSEnvironment = {
PATH = "${emacsBinPath}:${osxDefaultPath}";
};
CFBundleExecutable = "BillsEmacs";
CFBundleDisplayName = "BillsEmacs";
CFBundleIconFile = "AppIcon";
CFBundleIconName = "AppIcon";
});
versionPlist = pkgs.writeText "version.plist" (pkgs.lib.generators.toPlist { } {
ProjectName = "OSXPlatformSupport";
});
in in
depot.nix.readTree.drvTargets { {
# TODO(wpcarro): Support this with base.overrideAttrs or something similar. # TODO(wpcarro): Support this with base.overrideAttrs or something similar.
nixos = { load ? [ ] }: withEmacsPath { nixos = { load ? [ ] }: withEmacsPath {
inherit load; inherit load;
emacsBin = "${wpcarrosEmacs}/bin/emacs"; emacsBin = "${wpcarrosEmacs}/bin/emacs";
}; };
osx = writeShellScriptBin "wpcarros-emacs" '' # To install GUI:
export PATH="${emacsBinPath}:$PATH" # $ nix-build -A users.wpcarro.emacs.osx -o /Applications/BillsEmacs.app
osx = pkgs.stdenv.mkDerivation {
pname = "bills-emacs";
version = "0.0.1";
src = ./.;
dontFixup = true;
installPhase = ''
runHook preInstall
APP="$out"
mkdir -p "$APP/Contents/MacOS"
mkdir -p "$APP/Contents/Resources"
cp ${infoPlist} "$APP/Contents/Info.plist"
cp ${versionPlist} "$APP/Contents/version.plist"
cp ${./AppIcon.icns} "$APP/Contents/Resources/AppIcon.icns"
echo "APPL????" > "$APP/Contents/PkgInfo"
cat << EOF > "$APP/Contents/MacOS/BillsEmacs"
#!${pkgs.stdenvNoCC.shell}
export EMACSLOADPATH="${loadPath}" export EMACSLOADPATH="${loadPath}"
exec ${wpcarrosEmacs}/bin/emacs \ exec ${wpcarrosEmacs}/bin/emacs \
--debug-init \ --debug-init \
--no-init-file \ --no-init-file \
--no-site-file \ --no-site-file \
--no-site-lisp \ --no-site-lisp \
--load ${./.emacs.d/init.el} \ --load ${./.emacs.d/init.el}
"$@" EOF
chmod +x "$APP/Contents/MacOS/BillsEmacs"
runHook postInstall
''; '';
meta.platforms = [ "aarch64-darwin" ];
};
# Script that asserts my Emacs can initialize without warnings or errors. # Script that asserts my Emacs can initialize without warnings or errors.
check = runCommand "check-emacs" { } '' check = runCommand "check-emacs" { } ''
@ -209,4 +259,6 @@ depot.nix.readTree.drvTargets {
${./.emacs.d/init.el} && \ ${./.emacs.d/init.el} && \
touch $out touch $out
''; '';
meta.ci.targets = [ "check" ];
} }