Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,6 @@ target/
profile_default/
ipython_config.py

# pyenv
.python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
Expand Down
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.2.0
rev: v6.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
Expand All @@ -12,10 +12,10 @@ repos:
- '--unsafe'
- id: check-added-large-files
- repo: https://github.com/pycqa/isort
rev: 5.12.0
rev: 7.0.0
hooks:
- id: isort
- repo: https://github.com/pycqa/flake8
rev: 4.0.1
rev: 7.3.0
hooks:
- id: flake8
1 change: 1 addition & 0 deletions .python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.13
3 changes: 0 additions & 3 deletions Dockerfile

This file was deleted.

1 change: 0 additions & 1 deletion PYTHON_VERSION

This file was deleted.

11 changes: 3 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,11 @@ Tools for developers
Installation
------------

Requires recent pip

```
sudo pip3 install -U pip
uv tool install git+https://github.com/timeoutdigital/timeout-tools
```

Install globally so its always avalible
or

```
sudo pip3 install git+https://github.com/timeoutdigital/timeout-tools
Expand All @@ -36,8 +34,5 @@ This:

- Clones the app into `<branch_name>--<app>`
- Checkout branch `<branch_name>` if it exists or creates it
- Installs python version specified in repos `PYTHON_VERSION` file, using pyenv
- Creates a pyenv virtualenv named `<app>-<version>`
- Installs requirements.txt (and requirements-dev.txt if it exists) in the virtualenv
- Creates `.python-version` file for pyenv-virtualenv to read
- Sets up python using uv pip for `PYTHON_VERSION` or uv sync for `.python-version`
- Runs `pre-commit install`
5 changes: 5 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,8 @@ dependencies = [

[project.scripts]
timeout-tools = "timeout_tools.cli:main"

[dependency-groups]
dev = [
"pre-commit>=4.3.0",
]
4 changes: 0 additions & 4 deletions requirements.in

This file was deleted.

48 changes: 0 additions & 48 deletions requirements.txt

This file was deleted.

13 changes: 0 additions & 13 deletions tasks.py

This file was deleted.

119 changes: 67 additions & 52 deletions timeout_tools/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ def main():
title="commands",
)

parser_pyenv_install = subparsers.add_parser(
'pyenv-install',
help='install pyenv',
parser_uv_install = subparsers.add_parser(
'uv-install',
help='install uv',
)
parser_pyenv_install.set_defaults(func=pyenv_install)
parser_uv_install.set_defaults(func=uv_install)

parser_python_setup = subparsers.add_parser(
'python-setup',
Expand Down Expand Up @@ -119,36 +119,32 @@ def run(cmd):
return (res.returncode, res.stderr.decode())


def pyenv_install(args):
home_directory = os.path.expanduser('~')
ret, out = run(f'ls -d {home_directory}/.pyenv')
def uv_install(args):
ret, out = run('which uv')
if ret == 0:
logging.debug("$HOME/.pyenv already exists")
sys.exit(1)
shell_rc = '.bashrc'
print("UV is already installed")
sys.exit(0)

if platform.system() == 'Linux':
ret, out = run('curl -s https://pyenv.run | bash')
ret, out = run('curl -LsSf https://astral.sh/uv/install.sh | sh')
elif platform.system() == 'Darwin':
shell_rc = '.zshrc'
ret, out = run('brew install pkg-config openssl@1.1 xz gdbm tcl-tk')
ret, out = run('brew install pyenv')
ret, out = run('brew install pyenv-virtualenv')
# try brew first
ret, out = run('which brew')
if ret == 0:
ret, out = run('brew install uv')
else:
ret, out = run('curl -LsSf https://astral.sh/uv/install.sh | sh')
else:
print(f'{platform.system()} unknown system')
sys.exit(1)

if ret == 0:
ret, out = run(f'grep "TIMEOUT-TOOLS START" {home_directory}/{shell_rc}')
if ret == 0:
logging.debug("pyenv already configured in .bashrc\n")
sys.exit(1)
with open(f'{home_directory}/{shell_rc}', 'a') as shellrc:
shellrc.write('\n## TIMEOUT-TOOLS START\n')
# shellrc.write('export PYENV_VIRTUALENV_DISABLE_PROMPT=1\n')
shellrc.write('export PATH="$HOME/.pyenv/bin:$PATH"\n')
shellrc.write('eval "$(pyenv init --path)"\n')
shellrc.write('eval "$(pyenv virtualenv-init -)"\n')
shellrc.write('\n## TIMEOUT-TOOLS END\n')
run(f'. {home_directory}/{shell_rc}')
print('UV installed successfully')
print('You may need to restart your shell')
else:
print('Failed to install UV')
print(out)
sys.exit(1)


def python_setup_func(args):
Expand All @@ -158,55 +154,61 @@ def python_setup_func(args):


def python_setup(app, branch, python_version):
pyenv_name = f'{app}-{python_version}'
print(f'- Creating virtualenv `{pyenv_name}`', end='', flush=True)
run(f'pyenv install -s {python_version}')
ret, out = run(f'pyenv virtualenv {python_version} {pyenv_name}')
if os.path.exists('PYTHON_VERSION'):
req_python_setup(app, branch, python_version)
else:
pypro_python_setup(app, branch, python_version)

print('- Running `pre-commit install`', end='', flush=True)
ret, out = run('uv run pre-commit install')
if ret != 0:
if 'already exists' in out:
print(' (already exists) ✅')
else:
print(' ❌')
print(out)
sys.exit(1)
print(' ❌')
print(out)
sys.exit(1)
else:
print(' ✅')
run(f'echo {pyenv_name} > .python-version')

init_active = f'eval "$(pyenv init -)" && pyenv activate {pyenv_name}'
print('- Upgrading pip', end='', flush=True)
ret, out = run(f'{init_active} && pip install -U pip')

def req_python_setup(app, branch, python_version):
print('- Creating venv', end='', flush=True)
ret, out = run(f'uv venv --python {python_version} --clear')
if ret != 0:
print(' ❌')
print(out)
sys.exit(1)
print(' ✅')
else:
print(' ✅')

print('- Installing requirements.txt', end='', flush=True)
ret, out = run(f'{init_active} && pip install -r requirements.txt')
ret, out = run('uv pip install -r requirements.txt')
if ret != 0:
print(' ❌')
print(out)
sys.exit(1)
print(' ✅')
else:
print(' ✅')

ret, out = run('ls requirements-dev.txt')
if ret == 0:
print('- Installing requirements-dev.txt', end='', flush=True)
ret, out = run(f'{init_active} && pip install -r requirements-dev.txt')
ret, out = run('uv pip install -r requirements-dev.txt')
if ret != 0:
print(' ❌')
print(out)
sys.exit(1)
print(' ✅')
else:
print(' ✅')

print('- Running `pre-commit install`', end='', flush=True)
ret, out = run(f'{init_active} && pre-commit install')

def pypro_python_setup(app, branch, python_version):
print('- uv sync', end='', flush=True)
ret, out = run('uv sync')
if ret != 0:
print(' ❌')
print(out)
sys.exit(1)
print(' ✅')
else:
print(' ✅')


def python_remove(args):
Expand Down Expand Up @@ -268,10 +270,23 @@ def load_python_version(ws=None):
os.chdir(ws)
try:
with open('PYTHON_VERSION', 'r') as pv:
return pv.read().rstrip()
version = pv.read().rstrip()
match = re.match(r'(\d+\.\d+)', version)
if match:
return match.group(1)
return version
except FileNotFoundError:
logging.debug('"PYTHON_VERSION" file not found')
return False
logging.debug('"PYTHON_VERSION" file not found, trying ".python-version"')
try:
with open('.python-version', 'r') as pv:
version = pv.read().rstrip()
match = re.match(r'(\d+\.\d+)', version)
if match:
return match.group(1)
return version
except FileNotFoundError:
logging.debug('".python-version" file not found')
return False


if __name__ == '__main__':
Expand Down
Loading