Skip to content

Commit

Permalink
feat: better version detection, ping() builtin improvements
Browse files Browse the repository at this point in the history
- Distinguish between dev and release version by using IS_DEV_BUILD constant in tgpy/version.py. It's set to False only during release build process.
- Allow version detection in docker container by using COMMIT_HASH constant in tgpy/version.py, which is set during docker build
- utils.get_version() tries to get version from (in order): __version__ variable, commit hash from `git rev-parse`, commit hash from COMMIT_HASH  constant
- update() builtin now shows friendly message when: running in docker, git is not installed, installation method is unknown (not pypi package, not docker image, not git)
  • Loading branch information
vanutp committed May 9, 2022
1 parent f8cb28d commit 265b83f
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 20 deletions.
5 changes: 2 additions & 3 deletions .dockerignore
@@ -1,3 +1,2 @@
.git/
__pycache__
guide/site
**/__pycache__/
guide/site
10 changes: 7 additions & 3 deletions Dockerfile
Expand Up @@ -3,7 +3,7 @@ FROM python:3.10-alpine as base
WORKDIR /app

FROM base as builder
RUN apk add --no-cache gcc musl-dev libffi-dev
RUN apk add --no-cache gcc musl-dev libffi-dev git

ENV PIP_DISABLE_PIP_VERSION_CHECK=1 \
POETRY_VERSION=1.1.13
Expand All @@ -16,11 +16,15 @@ COPY pyproject.toml poetry.lock ./
RUN --mount=type=cache,target=/root/.cache/pip \
poetry export -f requirements.txt | /venv/bin/pip install -r /dev/stdin

COPY . .
RUN git status
RUN sed -i "s/\(COMMIT_HASH *= *\).*/\1'$(git rev-parse HEAD)'/" tgpy/version.py

FROM base as runner
COPY --from=builder /venv /venv
COPY tgpy tgpy
COPY --from=builder /app/tgpy tgpy

ENV TGPY_DATA=/data
VOLUME /data

ENTRYPOINT ["/venv/bin/python", "-m", "tgpy"]
ENTRYPOINT ["/venv/bin/python", "-m", "tgpy"]
4 changes: 2 additions & 2 deletions pyproject.toml
Expand Up @@ -16,13 +16,13 @@ tgpy = 'tgpy.main:main'

[tool.semantic_release]
version_variable = [
"tgpy/__init__.py:__version__",
"tgpy/version.py:__version__",
"pyproject.toml:version"
]
branch = "master"
upload_to_repository = true
upload_to_release = true
build_command = "poetry build"
build_command = """sed -i "s/\\(IS_DEV_BUILD *= *\\).*/\\1False/" tgpy/version.py && poetry build"""
commit_subject = 'chore(release): v{version} [skip ci]'
commit_message = ''

Expand Down
3 changes: 3 additions & 0 deletions release.Dockerfile
@@ -0,0 +1,3 @@
FROM tgpy-tmpimage:latest

RUN sed -i "s/\(IS_DEV_BUILD *= *\).*/\1False/" tgpy/version.py
3 changes: 1 addition & 2 deletions tgpy/__init__.py
Expand Up @@ -7,8 +7,7 @@
from tgpy.app_config import Config
from tgpy.console import console
from tgpy.context import Context

__version__ = "0.4.1"
from tgpy.version import __version__

logging.basicConfig(
level=logging.INFO, format='%(message)s', datefmt="[%X]", handlers=[RichHandler()]
Expand Down
22 changes: 18 additions & 4 deletions tgpy/builtin_functions.py
@@ -1,6 +1,4 @@
import getpass
import os
import socket
import sys
from datetime import datetime
from textwrap import dedent
Expand All @@ -22,14 +20,19 @@
get_version,
installed_as_package,
run_cmd,
REPO_ROOT,
execute_in_repo_root,
get_user,
running_in_docker,
get_hostname,
)


def ping():
return dedent(
f'''
Pong!
Running on {getpass.getuser()}@{socket.gethostname()}
Running on {get_user()}@{get_hostname()}
Version: {get_version()}
'''
)
Expand Down Expand Up @@ -57,14 +60,25 @@ def restart(msg: Optional[str] = 'Restarted successfully'):

def update():
old_version = get_version()

if running_in_docker():
return 'Can\'t update a docker container'

if installed_as_package():
update_args = [sys.executable, '-m', 'pip', 'install', '-U', 'tgpy']
try:
run_cmd(update_args)
except RunCmdException:
run_cmd(update_args + ['--user'])
elif REPO_ROOT:
with execute_in_repo_root():
try:
run_cmd(['git', 'pull'])
except FileNotFoundError:
return 'Git is not installed'
else:
run_cmd(['git', 'pull'])
return 'Could not find suitable update method'

new_version = get_version()
if old_version == new_version:
return 'Already up to date'
Expand Down
64 changes: 58 additions & 6 deletions tgpy/utils.py
@@ -1,11 +1,17 @@
import getpass
import importlib.metadata
import os
import re
import shlex
import socket
from contextlib import contextmanager
from pathlib import Path
from subprocess import PIPE, Popen

import appdirs

from tgpy import version

ENV_TGPY_DATA = os.getenv('TGPY_DATA')
if ENV_TGPY_DATA:
DATA_DIR = Path(os.getenv('TGPY_DATA'))
Expand All @@ -16,10 +22,25 @@
WORKDIR = DATA_DIR / 'workdir'
CONFIG_FILENAME = DATA_DIR / 'config.yml'
SESSION_FILENAME = DATA_DIR / 'TGPy.session'
REPO_ROOT = Path(__file__).parent.parent
if not os.path.exists(REPO_ROOT / '.git'):
REPO_ROOT = None

filename_prefix = 'tgpy://'


@contextmanager
def execute_in_repo_root():
if not REPO_ROOT:
raise ValueError('No repository found')
old_cwd = os.getcwd()
os.chdir(REPO_ROOT)
try:
yield
finally:
os.chdir(old_cwd)


def create_config_dirs():
DATA_DIR.mkdir(exist_ok=True)
MODULES_DIR.mkdir(exist_ok=True)
Expand Down Expand Up @@ -50,14 +71,40 @@ def installed_as_package():
return False


def get_version():
if installed_as_package():
return importlib.metadata.version('tgpy')
def running_in_docker():
return os.path.exists('/.dockerenv')


def get_user():
try:
return 'git@' + run_cmd(['git', 'rev-parse', '--short', 'HEAD'])
except RunCmdException:
pass
return getpass.getuser()
except KeyError:
return str(os.getuid())


DOCKER_DEFAULT_HOSTNAME_RGX = re.compile(r'[0-9a-f]{12}')


def get_hostname():
real_hostname = socket.gethostname()
if running_in_docker() and DOCKER_DEFAULT_HOSTNAME_RGX.fullmatch(real_hostname):
return 'docker'
return real_hostname


def get_version():
if not version.IS_DEV_BUILD:
return version.__version__

if REPO_ROOT:
with execute_in_repo_root():
try:
return 'git@' + run_cmd(['git', 'rev-parse', '--short', 'HEAD'])
except (RunCmdException, FileNotFoundError):
pass

if version.COMMIT_HASH:
return 'git@' + version.COMMIT_HASH[:7]

return 'unknown'

Expand All @@ -68,10 +115,15 @@ def get_version():
'WORKDIR',
'CONFIG_FILENAME',
'SESSION_FILENAME',
'REPO_ROOT',
'run_cmd',
'get_version',
'create_config_dirs',
'installed_as_package',
'RunCmdException',
'filename_prefix',
'execute_in_repo_root',
'get_user',
'get_hostname',
'running_in_docker',
]
3 changes: 3 additions & 0 deletions tgpy/version.py
@@ -0,0 +1,3 @@
__version__ = '0.4.1'
IS_DEV_BUILD = True
COMMIT_HASH = None

0 comments on commit 265b83f

Please sign in to comment.