* Remove unnecessary win_install.ps1. * Add appveyor version update to release script. * Make setup.py's pure Python fallback code less intrusive.tags/v0.4.1
| @@ -12,6 +12,8 @@ environment: | |||||
| global: | global: | ||||
| # See: http://stackoverflow.com/a/13751649/163740 | # See: http://stackoverflow.com/a/13751649/163740 | ||||
| WRAPPER: "cmd /E:ON /V:ON /C .\\scripts\\win_wrapper.cmd" | WRAPPER: "cmd /E:ON /V:ON /C .\\scripts\\win_wrapper.cmd" | ||||
| PIP: "%WRAPPER% %PYTHON%\\Scripts\\pip.exe" | |||||
| SETUPPY: "%WRAPPER% %PYTHON%\\python setup.py --with-extension" | |||||
| matrix: | matrix: | ||||
| - PYTHON: "C:\\Python27" | - PYTHON: "C:\\Python27" | ||||
| @@ -39,16 +41,16 @@ environment: | |||||
| PYTHON_ARCH: "64" | PYTHON_ARCH: "64" | ||||
| install: | install: | ||||
| - "powershell scripts\\win_install.ps1" | |||||
| - "%PIP% install wheel" | |||||
| build_script: | build_script: | ||||
| - "%WRAPPER% %PYTHON%\\python setup.py build" | |||||
| - "%SETUPPY% build" | |||||
| test_script: | test_script: | ||||
| - "%WRAPPER% %PYTHON%\\python setup.py -q test" | |||||
| - "%SETUPPY% -q test" | |||||
| after_test: | after_test: | ||||
| - "%WRAPPER% %PYTHON%\\python setup.py bdist_wheel" | |||||
| - "%SETUPPY% bdist_wheel" | |||||
| artifacts: | artifacts: | ||||
| - path: dist\* | - path: dist\* | ||||
| @@ -31,7 +31,12 @@ update_version() { | |||||
| echo " done." | echo " done." | ||||
| } | } | ||||
| # TODO: update appveyor version! | |||||
| update_appveyor() { | |||||
| filename="appveyor.yml" | |||||
| echo -n "Updating $filename..." | |||||
| sed -e "s/version: .*/version: $VERSION-b{build}/" -i "" $filename | |||||
| echo " done." | |||||
| } | |||||
| update_changelog() { | update_changelog() { | ||||
| filename="CHANGELOG" | filename="CHANGELOG" | ||||
| @@ -154,6 +159,7 @@ cd "$SCRIPT_DIR/.." | |||||
| check_git | check_git | ||||
| update_version | update_version | ||||
| update_appveyor | |||||
| update_changelog | update_changelog | ||||
| update_docs_changelog | update_docs_changelog | ||||
| do_git_stuff | do_git_stuff | ||||
| @@ -1,85 +0,0 @@ | |||||
| # Sample script to install Python and pip under Windows | |||||
| # Authors: Olivier Grisel and Kyle Kastner | |||||
| # License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/ | |||||
| $BASE_URL = "https://www.python.org/ftp/python/" | |||||
| $GET_PIP_URL = "https://bootstrap.pypa.io/get-pip.py" | |||||
| $GET_PIP_PATH = "C:\get-pip.py" | |||||
| function DownloadPython ($python_version, $platform_suffix) { | |||||
| $webclient = New-Object System.Net.WebClient | |||||
| $filename = "python-" + $python_version + $platform_suffix + ".msi" | |||||
| $url = $BASE_URL + $python_version + "/" + $filename | |||||
| $basedir = $pwd.Path + "\" | |||||
| $filepath = $basedir + $filename | |||||
| if (Test-Path $filename) { | |||||
| Write-Host "Reusing" $filepath | |||||
| return $filepath | |||||
| } | |||||
| # Download and retry up to 3 times in case of network transient errors. | |||||
| Write-Host "Downloading" $filename "from" $url | |||||
| $retry_attempts = 3 | |||||
| for($i=0; $i -lt $retry_attempts; $i++){ | |||||
| try { | |||||
| $webclient.DownloadFile($url, $filepath) | |||||
| break | |||||
| } | |||||
| Catch [Exception]{ | |||||
| Start-Sleep 1 | |||||
| } | |||||
| } | |||||
| Write-Host "File saved at" $filepath | |||||
| return $filepath | |||||
| } | |||||
| function InstallPython ($python_version, $architecture, $python_home) { | |||||
| Write-Host "Installing Python" $python_version "for" $architecture "bit architecture to" $python_home | |||||
| if (Test-Path $python_home) { | |||||
| Write-Host $python_home "already exists, skipping." | |||||
| return $false | |||||
| } | |||||
| if ($architecture -eq "32") { | |||||
| $platform_suffix = "" | |||||
| } else { | |||||
| $platform_suffix = ".amd64" | |||||
| } | |||||
| $filepath = DownloadPython $python_version $platform_suffix | |||||
| Write-Host "Installing" $filepath "to" $python_home | |||||
| $args = "/qn /i $filepath TARGETDIR=$python_home" | |||||
| Write-Host "msiexec.exe" $args | |||||
| Start-Process -FilePath "msiexec.exe" -ArgumentList $args -Wait -Passthru | |||||
| Write-Host "Python $python_version ($architecture) installation complete" | |||||
| return $true | |||||
| } | |||||
| function InstallPip ($python_home) { | |||||
| $pip_path = $python_home + "/Scripts/pip.exe" | |||||
| $python_path = $python_home + "/python.exe" | |||||
| if (-not(Test-Path $pip_path)) { | |||||
| Write-Host "Installing pip..." | |||||
| $webclient = New-Object System.Net.WebClient | |||||
| $webclient.DownloadFile($GET_PIP_URL, $GET_PIP_PATH) | |||||
| Write-Host "Executing:" $python_path $GET_PIP_PATH | |||||
| Start-Process -FilePath "$python_path" -ArgumentList "$GET_PIP_PATH" -Wait -Passthru | |||||
| } else { | |||||
| Write-Host "pip already installed." | |||||
| } | |||||
| } | |||||
| function InstallPackage ($python_home, $pkg) { | |||||
| $pip_path = $python_home + "/Scripts/pip.exe" | |||||
| & $pip_path install $pkg | |||||
| } | |||||
| function main () { | |||||
| InstallPython $env:PYTHON_VERSION $env:PYTHON_ARCH $env:PYTHON | |||||
| InstallPip $env:PYTHON | |||||
| InstallPackage $env:PYTHON wheel | |||||
| } | |||||
| main | |||||
| @@ -21,17 +21,17 @@ | |||||
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
| # SOFTWARE. | # SOFTWARE. | ||||
| import os | |||||
| from __future__ import print_function | |||||
| from distutils.errors import DistutilsError, CCompilerError | |||||
| from os import environ | |||||
| import sys | import sys | ||||
| if (sys.version_info[0] == 2 and sys.version_info[1] < 6) or \ | |||||
| (sys.version_info[1] == 3 and sys.version_info[1] < 2): | |||||
| raise Exception("mwparserfromhell needs Python 2.6+ or 3.2+") | |||||
| if sys.version_info >= (3, 0): | |||||
| basestring = (str, ) | |||||
| if ((sys.version_info[0] == 2 and sys.version_info[1] < 6) or | |||||
| (sys.version_info[1] == 3 and sys.version_info[1] < 2)): | |||||
| raise RuntimeError("mwparserfromhell needs Python 2.6+ or 3.2+") | |||||
| from setuptools import setup, find_packages, Extension | from setuptools import setup, find_packages, Extension | ||||
| from setuptools.command.build_ext import build_ext | |||||
| from mwparserfromhell import __version__ | from mwparserfromhell import __version__ | ||||
| from mwparserfromhell.compat import py26, py3k | from mwparserfromhell.compat import py26, py3k | ||||
| @@ -44,65 +44,41 @@ tokenizer = Extension("mwparserfromhell.parser._tokenizer", | |||||
| depends=["mwparserfromhell/parser/tokenizer.h"]) | depends=["mwparserfromhell/parser/tokenizer.h"]) | ||||
| use_extension = True | use_extension = True | ||||
| fallback = True | |||||
| # Allow env var WITHOUT_EXTENSION and args --with[out]-extension | |||||
| if '--without-extension' in sys.argv: | |||||
| use_extension = False | |||||
| elif '--with-extension' in sys.argv: | |||||
| pass | |||||
| elif os.environ.get('WITHOUT_EXTENSION', '0') == '1': | |||||
| use_extension = False | |||||
| # Remove the command line argument as it isn't understood by | |||||
| # setuptools/distutils | |||||
| sys.argv = [arg for arg in sys.argv | |||||
| if not arg.startswith('--with') | |||||
| and not arg.endswith('-extension')] | |||||
| def optional_compile_setup(func=setup, use_ext=use_extension, | |||||
| *args, **kwargs): | |||||
| """ | |||||
| Wrap setup to allow optional compilation of extensions. | |||||
| Falls back to pure python mode (no extensions) | |||||
| if compilation of extensions fails. | |||||
| """ | |||||
| extensions = kwargs.get('ext_modules', None) | |||||
| # Allow env var WITHOUT_EXTENSION and args --with[out]-extension: | |||||
| if use_ext and extensions: | |||||
| try: | |||||
| func(*args, **kwargs) | |||||
| return | |||||
| except SystemExit as e: | |||||
| assert(e.args) | |||||
| if e.args[0] is False: | |||||
| raise | |||||
| elif isinstance(e.args[0], basestring): | |||||
| if e.args[0].startswith('usage: '): | |||||
| raise | |||||
| else: | |||||
| # Fallback to pure python mode | |||||
| print('setup with extension failed: %s' % repr(e)) | |||||
| pass | |||||
| except Exception as e: | |||||
| print('setup with extension failed: %s' % repr(e)) | |||||
| env_var = environ.get("WITHOUT_EXTENSION") | |||||
| if "--without-extension" in sys.argv: | |||||
| use_extension = False | |||||
| elif "--with-extension" in sys.argv: | |||||
| fallback = False | |||||
| elif env_var is not None: | |||||
| if env_var == "1": | |||||
| use_extension = False | |||||
| elif env_var == "0": | |||||
| fallback = False | |||||
| if extensions: | |||||
| if use_ext: | |||||
| print('Falling back to pure python mode.') | |||||
| else: | |||||
| print('Using pure python mode.') | |||||
| # Remove the command line argument as it isn't understood by setuptools: | |||||
| del kwargs['ext_modules'] | |||||
| sys.argv = [arg for arg in sys.argv | |||||
| if arg != "--without-extension" and arg != "--with-extension"] | |||||
| func(*args, **kwargs) | |||||
| def build_ext_patched(self): | |||||
| try: | |||||
| build_ext_original(self) | |||||
| except (DistutilsError, CCompilerError) as exc: | |||||
| print("error: " + str(exc)) | |||||
| print("Falling back to pure Python mode.") | |||||
| del self.extensions[:] | |||||
| if fallback: | |||||
| build_ext.run, build_ext_original = build_ext_patched, build_ext.run | |||||
| optional_compile_setup( | |||||
| setup( | |||||
| name = "mwparserfromhell", | name = "mwparserfromhell", | ||||
| packages = find_packages(exclude=("tests",)), | packages = find_packages(exclude=("tests",)), | ||||
| ext_modules = [tokenizer], | |||||
| ext_modules = [tokenizer] if use_extension else [], | |||||
| tests_require = ["unittest2"] if py26 else [], | tests_require = ["unittest2"] if py26 else [], | ||||
| test_suite = "tests.discover", | test_suite = "tests.discover", | ||||
| version = __version__, | version = __version__, | ||||