-
Notifications
You must be signed in to change notification settings - Fork 105
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
489 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# TOML file for generating the applecrate package with applecrate | ||
# The version in this file will be updated by bump2version | ||
|
||
app = "osxphotos" | ||
version = "0.69.0" | ||
identifier = "org.rhettbull.osxphotos" | ||
license = "LICENSE" | ||
install = [ | ||
[ | ||
"build/osxphotos-0.69.0-{{ machine }}", | ||
"/usr/local/bin/osxphotos", | ||
], | ||
] | ||
pre_install = "scripts/preinstall.sh" | ||
output = "dist/{{ app }}-{{ version }}-{{ machine }}-installer.pkg" | ||
sign = "$DEVELOPER_ID_INSTALLER" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
""" Auto-update the installed version """ | ||
|
||
from __future__ import annotations | ||
|
||
import json | ||
import os | ||
import runpy | ||
import ssl | ||
import subprocess | ||
import sys | ||
import urllib.request | ||
from typing import Iterable | ||
|
||
from packaging.version import parse as version_parse | ||
|
||
VERSION_INFO_URL = "https://pypi.org/pypi/{}/json" | ||
|
||
|
||
def pyapp() -> bool: | ||
"""Check if we are running in a pyapp environment.""" | ||
return os.environ.get("PYAPP") == "1" | ||
|
||
|
||
def install(packages: Iterable[str], upgrade: bool = False) -> int: | ||
"""Install Python packages into the same environment as the current script using the pip module. | ||
Args: | ||
packages: The names of the packages to install. | ||
upgrade: Whether to upgrade the packages if they are already installed. | ||
Returns: The exit code of the pip command. | ||
""" | ||
args = ["pip", "--disable-pip-version-check", "--verbose", "install"] | ||
if upgrade: | ||
args += ["--upgrade"] | ||
args += list(packages) | ||
sys.argv = args | ||
|
||
# monkey patch sys.exit to catch the exit code when running pip | ||
# otherwise, pip.__main__ will call sys.exit and stop execution | ||
original_exit = sys.exit | ||
exit_code = None | ||
|
||
def _exit(code): | ||
nonlocal exit_code | ||
exit_code = code | ||
|
||
sys.exit = _exit | ||
try: | ||
runpy.run_module("pip", run_name="__main__") | ||
finally: | ||
sys.exit = original_exit | ||
return exit_code | ||
|
||
|
||
def update(package: str, version: str, pyapp_binary: str) -> None: | ||
"""Update the installation to the latest version. | ||
Args: | ||
package: The name of the package to update. | ||
version: The current version of the package. | ||
pyapp_binary: The name of the package binary built with PyApp to use for updating. | ||
Note: | ||
Updating PyApp package requires the pyapp_binary to be available in the PATH. | ||
This will work for most users but may fail if the binary is not in the path and | ||
was instead invoked using an absolute path, e.g. /path/to/pyapp_binary. | ||
I am not aware of a way to get the absolute path of the binary from the package | ||
itself as the PyApp binary will execute python, replacing the current process. | ||
""" | ||
if pyapp(): | ||
# let pyapp handle the update | ||
command = [pyapp_binary, "self", "update"] | ||
subprocess.run(command, check=True) | ||
return | ||
else: | ||
# otherwise let's update in place | ||
# check if there is a newer version of the package | ||
latest_version = get_latest_version(package) | ||
if version_parse(latest_version) > version_parse(version): | ||
print(f"Updating from version {version} to {latest_version}.") | ||
install([package], upgrade=True) | ||
print(f"Updated {package} to version {latest_version}.") | ||
else: | ||
print(f"{package} is already up to date: {version}.") | ||
|
||
|
||
def get_latest_version(package_name: str) -> str: | ||
"""Get latest version of package_name from PyPI | ||
Note: This uses the standard library instead of `requests` | ||
to avoid adding a dependency to the project. | ||
""" | ||
try: | ||
url = VERSION_INFO_URL.format(package_name) | ||
ssl_context = ssl._create_unverified_context() | ||
response = urllib.request.urlopen(url, context=ssl_context) | ||
data = json.load(response) | ||
return data["info"]["version"] | ||
except Exception as e: | ||
raise ValueError(f"Error retrieving version for {package_name}: {e}") from e |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
"""Self-update command for osxphotos""" | ||
|
||
import click | ||
|
||
from osxphotos._constants import APP_NAME | ||
from osxphotos._version import __version__ | ||
|
||
from .selfupdate import update | ||
|
||
|
||
@click.command(name="update") | ||
def update_command(): | ||
"""Update the installation to the latest version.""" | ||
update(APP_NAME, __version__, APP_NAME) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#!/bin/bash | ||
|
||
# This script is very specific to my particular setup on my machine. | ||
# It must be run after the package has been updated on PyPI. | ||
# It uses `pyapp-runner.sh`, a simple CI script that runs via ssh, | ||
# to build and sign the binaries for the package and then build the installer package. | ||
# | ||
# To run the script, run it from the project root directory: | ||
# ./scripts/build_cli.sh | ||
# | ||
|
||
# Get the current version of the package from the source | ||
PACKAGE_NAME="osxphotos" | ||
VERSION=$(grep __version__ $PACKAGE_NAME/_version.py | cut -d "\"" -f 2) | ||
|
||
# verify VERSION is valid | ||
# PyApp will happily build with an invalid version number | ||
# get directory of this script | ||
# DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" | ||
PYPI_VERSION=$(python scripts/get_latest_pypi_version.py $PACKAGE_NAME) | ||
if [ "$PYPI_VERSION" != "$VERSION" ]; then | ||
echo "Invalid version number: $VERSION" | ||
echo "Latest version on PyPI: $PYPI_VERSION" | ||
echo "Did you forget to run 'flit publish'?" | ||
exit 1 | ||
fi | ||
|
||
# Build the binaries and package them | ||
# arm64 binary built on a remote M1 Mac | ||
# echo "Building version $VERSION for Apple Silicon" | ||
# bash scripts/pyapp-runner.sh m1 $PACKAGE_NAME $VERSION | ||
|
||
echo "Building version $VERSION for Intel" | ||
bash scripts/pyapp-runner.sh macbook $PACKAGE_NAME $VERSION |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
"""Given a PyPI package name, print the latest version number of the package. | ||
This uses the standard library instead of requests to avoid adding a dependency to the project. | ||
""" | ||
|
||
from __future__ import annotations | ||
|
||
import json | ||
import ssl | ||
import sys | ||
import urllib.request | ||
|
||
VERSION_INFO_URL = "https://pypi.org/pypi/{}/json" | ||
|
||
|
||
def get_latest_version(package_name: str) -> str: | ||
"""Get latest version of package_name from PyPI""" | ||
try: | ||
url = VERSION_INFO_URL.format(package_name) | ||
ssl_context = ssl._create_unverified_context() | ||
response = urllib.request.urlopen(url, context=ssl_context) | ||
data = json.load(response) | ||
return data["info"]["version"] | ||
except Exception as e: | ||
raise ValueError(f"Error retrieving version for {package_name}: {e}") | ||
|
||
|
||
if __name__ == "__main__": | ||
if len(sys.argv) != 2: | ||
print(f"Usage: {sys.argv[0]} PACKAGE_NAME") | ||
sys.exit(1) | ||
package_name = sys.argv[1] | ||
try: | ||
print(get_latest_version(package_name)) | ||
except ValueError as e: | ||
print(e) | ||
sys.exit(1) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
#!/bin/bash | ||
|
||
# This script used by applecrate to install the applecrate executable | ||
# into the /usr/local/bin directory | ||
# It will link the correct executable depending on machine CPU | ||
# The applecrate binaries should be named as follows: | ||
# {{ app }}-{{ version }}-x86_64 or {{ app }}-{{ version }}-arm64 | ||
# and they should be installed with the following directory structure: | ||
# /Library/Application Support/{{ app }}/{{ version }}/{{ app }}-{{ version }}-x86_64 | ||
# /Library/Application Support/{{ app }}/{{ version }}/{{ app }}-{{ version }}-arm64 | ||
|
||
|
||
# CPU will be x86_64 or arm64 | ||
CPU=$(uname -m) | ||
|
||
ln -s "/Library/Application Support/{{ app }}/{{ version }}/{{ app }}-{{ version }}-$CPU" "/usr/local/bin/applecrate" | ||
chmod 755 "/usr/local/bin/applecrate" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#!/bin/bash | ||
|
||
# Preinstall script for applecrate installer | ||
# This will remove the applecrate binary from /usr/local/bin if it exists | ||
|
||
rm -f /usr/local/bin/applecrate |
Oops, something went wrong.