From 566e641be1ae493d90b8617fc27e5e48317d681c Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 10 Jan 2018 07:44:16 +0530 Subject: [PATCH] Allow easily building a kitty.app wrapper to run kitty from source --- README.asciidoc | 29 ++++++----------------------- kitty/main.py | 3 +-- setup.py | 24 ++++++++++++++++++++++-- 3 files changed, 29 insertions(+), 27 deletions(-) diff --git a/README.asciidoc b/README.asciidoc index 7398d8246..dd1ac54c6 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -422,33 +422,16 @@ the approach using ligatures. === How do I build kitty.app on macOS? -You dont need to build kitty.app to run kitty from source. Simply install the dependencies -listed above using brew/MacPorts or similar and then compile and run with: - +Run: ``` -make -python3 . +logo/make.py +./setup.py kitty.app ``` -You can also create a shell script to run kitty: - -``` -#!/bin/sh -exec python3 /path/to/kitty/source/dir -``` - -And using something like link:https://mathiasbynens.be/notes/shell-script-mac-apps[app-wrapper-for-shell-script] -you can create a simple launcher app to run the shell script. - -If you only want to make some small changes to a python file, you can do that -and simply replace the corresponding file inside an existing kitty.app. (Note -that kitty.app will contain `.pyo` files which are compiled versions of `.py` -files, delete the `.pyo` file and replace it with a `.py` file). - -Finally, note that the released kitty.dmg is built automatically by using the -`kitty` branch of +Note that the released kitty.dmg includes all dependencies, unlike the +`kitty.app` built above and is built automatically by using the `kitty` branch of link:https://github.com/kovidgoyal/build-calibre[build-calibre] however, that -is designed to run on linux and is not for the faint of heart. +is designed to run on Linux and is not for the faint of heart. == A tribute diff --git a/kitty/main.py b/kitty/main.py index 29e99361e..a64cc0a87 100644 --- a/kitty/main.py +++ b/kitty/main.py @@ -122,8 +122,7 @@ def main(): if rpath and rpath not in items: os.environ['PATH'] += os.pathsep + rpath - if os.environ.pop('KITTY_LAUNCHED_BY_LAUNCH_SERVICES', - None) == '1' and getattr(sys, 'frozen', True): + if os.environ.pop('KITTY_LAUNCHED_BY_LAUNCH_SERVICES', None) == '1': os.chdir(os.path.expanduser('~')) if not os.path.isdir(os.getcwd()): os.chdir(os.path.expanduser('~')) diff --git a/setup.py b/setup.py index 1ef935892..a4adc586a 100755 --- a/setup.py +++ b/setup.py @@ -476,7 +476,7 @@ def build_linux_launcher(args, launcher_dir='.', for_bundle=False): run_tool(cmd) -def package(args, for_bundle=False): # {{{ +def package(args, for_bundle=False, sh_launcher=False): # {{{ ddir = args.prefix libdir = os.path.join(ddir, 'lib', 'kitty') if os.path.exists(libdir): @@ -532,6 +532,7 @@ Categories=System; if for_bundle: # OS X bundle gunk {{{ import plistlib logo_dir = os.path.abspath(os.path.join('logo', appname + '.iconset')) + exe_path = os.path.abspath(sys.executable) os.chdir(ddir) os.mkdir('Contents') os.chdir('Contents') @@ -568,6 +569,20 @@ Categories=System; 'iconutil', '-c', 'icns', logo_dir, '-o', os.path.join('Resources', os.path.basename(logo_dir).partition('.')[0] + '.icns') ]) + if sh_launcher: + with open('MacOS/kitty', 'r+') as f: + f.seek(0), f.truncate() + f.write('''\ +#!EXE_PATH +import os, sys +base = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +kitty = os.path.join(base, 'Frameworks', 'kitty') +sys.path.insert(0, kitty) +with open(os.path.join(kitty, '__main__.py')) as f: + code = f.read() +code = compile(code, f.name, 'exec') +exec(code, {'__name__': '__main__'}) +'''.replace('EXE_PATH', exe_path, 1)) # }}} # }}} @@ -589,7 +604,7 @@ def option_parser(): 'action', nargs='?', default='build', - choices='build test linux-package osx-bundle clean'.split(), + choices='build test linux-package kitty.app osx-bundle clean'.split(), help='Action to perform (default is build)' ) p.add_argument( @@ -658,6 +673,11 @@ def main(): elif args.action == 'osx-bundle': build(args, native_optimizations=False) package(args, for_bundle=True) + elif args.action == 'kitty.app': + args.prefix = 'kitty.app' + build(args) + package(args, for_bundle=True, sh_launcher=True) + print('kitty.app successfully built!') elif args.action == 'clean': clean()