Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CI for Windows #1158

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
54 changes: 50 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
x-tox-env: &x-tox-env >
TOX_CMD="tox --skip-missing-interpreters=false -v"
TOX_CMD="${TOX_PATH:-tox} --skip-missing-interpreters=false -v"

x-tox-install: &x-tox-install |
pip install -U pip
pip install 'tox<=3.14.5' 'virtualenv<20.0.5'
${PIP_PATH:-pip} install -U pip
${PIP_PATH:-pip} install 'tox<=3.14.5' 'virtualenv<20.0.5'

x-linux-shard: &x-linux-shard
os: linux
Expand Down Expand Up @@ -51,6 +51,9 @@ x-pyenv-install: &x-pyenv-install |
"${PYENV}" install --keep --skip-existing ${PYENV_VERSION}
"${PYENV}" global ${PYENV_VERSION}

x-pyenv-27-env: &x-pyenv-27-env >
PYENV_VERSION=2.7.18

x-pyenv-39-env: &x-pyenv-39-env >
PYENV_VERSION=3.9.1

Expand Down Expand Up @@ -89,7 +92,7 @@ x-osx-27-shard: &x-osx-27-shard
env:
- *x-tox-env
- *x-pyenv-env
- PYENV_VERSION=2.7.18
- *x-pyenv-27-env

x-osx-39-shard: &x-osx-39-shard
<<: *x-osx-shard
Expand All @@ -98,6 +101,33 @@ x-osx-39-shard: &x-osx-39-shard
- *x-pyenv-env
- *x-pyenv-39-env

x-windows-shard: &x-windows-shard
os: windows
language: shell
cache:
# The default is 3 minutes (180).
timeout: 300
install:
- *x-tox-install

x-windows-27-shard: &x-windows-27-shard
<<: *x-windows-shard
before_install:
- choco install python2
chrisjbremner marked this conversation as resolved.
Show resolved Hide resolved
env:
- PIP_PATH="C:\Python27\python.exe -m pip"
- TOX_PATH="C:\Python27\Scripts\tox"
- *x-tox-env

x-windows-39-shard: &x-windows-39-shard
<<: *x-windows-shard
before_install:
- choco install python --version 3.9.1
env:
- PIP_PATH="C:\Python39\python.exe -m pip"
- TOX_PATH="C:\Python39\Scripts\tox"
- *x-tox-env

# NB: Travis partitions caches using a combination of os, language amd env vars. As such, we do not
# use TOXENV and instead pass the toxenv via -e on the command line. This helps ensure we share
# caches as much as possible (eg: all linux python 2.7.15 shards share a cache).
Expand Down Expand Up @@ -177,3 +207,19 @@ matrix:
- <<: *x-osx-39-shard
name: TOXENV=py39-integration
script: ${TOX_CMD} -e py39-integration

- <<: *x-windows-27-shard
name: TOXENV=py27
script: ${TOX_CMD} -e py27

- <<: *x-windows-39-shard
name: TOXENV=py39
script: ${TOX_CMD} -e py39

- <<: *x-windows-27-shard
name: TOXENV=py27-integration
script: ${TOX_CMD} -e py27-integration

- <<: *x-windows-39-shard
name: TOXENV=py39-integration
script: ${TOX_CMD} -e py39-integration
28 changes: 25 additions & 3 deletions pex/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import atexit
import contextlib
import errno
import fcntl
import os
import re
import shutil
Expand All @@ -21,8 +20,14 @@
from datetime import datetime
from uuid import uuid4

from pex.compatibility import WINDOWS
from pex.typing import TYPE_CHECKING

if WINDOWS:
import msvcrt
else:
import fcntl

if TYPE_CHECKING:
from typing import Any, DefaultDict, Iterable, Iterator, NoReturn, Optional, Set, Sized

Expand Down Expand Up @@ -393,7 +398,10 @@ def unlock():
if lock_fd is None:
return
try:
fcntl.lockf(lock_fd, fcntl.LOCK_UN)
if WINDOWS:
msvcrt.locking(lock_fd, msvcrt.LK_UNLCK, 1)
else:
fcntl.lockf(lock_fd, fcntl.LOCK_UN)
finally:
os.close(lock_fd)

Expand All @@ -410,7 +418,21 @@ def unlock():
# N.B.: Since lockf operates on an open file descriptor and these are guaranteed to be
# closed by the operating system when the owning process exits, this lock is immune to
# staleness.
fcntl.lockf(lock_fd, fcntl.LOCK_EX) # A blocking write lock.
if WINDOWS:
while True:
# Force the non-blocking lock to be blocking. LK_LOCK is msvcrt's implementation of
# a blocking lock, but it only tries 10 times, once per second before rasing an
# OSError.
try:
msvcrt.locking(lock_fd, msvcrt.LK_LOCK, 1)
break
except OSError as ex:
# Deadlock error is raised after failing to lock the file
if ex.errno != errno.EDEADLOCK:
raise
safe_sleep(1)
else:
fcntl.lockf(lock_fd, fcntl.LOCK_EX) # A blocking write lock.
if atomic_dir.is_finalized:
# We lost the double-checked locking race and our work was done for us by the race
# winner so exit early.
Expand Down