Skip to content

Commit 8149774

Browse files
authored
Merge pull request #68 from mehcode/windows_build
Introduced windows support
2 parents d6fb258 + bed23d0 commit 8149774

21 files changed

+759
-281
lines changed

.appveyor.yml

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
version: 1.3.{build}
2+
3+
environment:
4+
matrix:
5+
- python: 27
6+
- python: 27-x64
7+
- python: 35
8+
- python: 35-x64
9+
- python: 36
10+
- python: 36-x64
11+
12+
install:
13+
- SET PATH=C:\\Python%PYTHON%;c:\\Python%PYTHON%\\scripts;%PATH%
14+
- python -m pip.__main__ install -U pip wheel setuptools
15+
- pip install -r requirements-test.txt
16+
17+
build: off
18+
build_script:
19+
# configure version
20+
- ps: >-
21+
If ($env:APPVEYOR_REPO_TAG -Eq "true" ) {
22+
$version = "$env:APPVEYOR_REPO_TAG_NAME"
23+
} Else {
24+
$version = "$env:APPVEYOR_BUILD_VERSION.dev0"
25+
}
26+
$version | Set-Content version.txt
27+
- python setup.py build bdist_wheel
28+
- ps: Get-ChildItem dist\*.whl | % { pip install $_.FullName }
29+
30+
test: off
31+
test_script:
32+
- pip list
33+
- py.test -v tests
34+
- ps: Get-ChildItem dist\*.whl | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name }

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
.*
33
!.editorconfig
44
!.travis*
5+
!.appveyor*
56
!.git*
67

78
# Python

.travis.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ addons:
1818
- libxslt1-dev
1919
- pkg-config
2020
before_install:
21-
- sed -i "s/1.0.1/${TRAVIS_TAG:-1.0.1}/" setup.py
21+
- echo "${TRAVIS_TAG:-1.0.1.dev}" >version.txt
2222
install:
2323
- travis_retry pip install -r requirements-test.txt
2424
- travis_retry pip install -e "."

MANIFEST.in

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
include src/*
22
include requirements*.txt
33
include LICENSE
4-
4+
include version.txt
5+
include setupinfo.py
6+
include extra.py

README.rst

+52-26
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ python-xmlsec
33

44
.. image:: https://travis-ci.org/mehcode/python-xmlsec.png?branch=master
55
:target: https://travis-ci.org/mehcode/python-xmlsec
6+
.. image:: https://ci.appveyor.com/api/projects/status/20rtt2wv96gag9cy?svg=true
7+
:target: https://ci.appveyor.com/project/bgaifullin/python-xmlsec
68
.. image:: https://img.shields.io/pypi/v/xmlsec.svg
79
:target: https://pypi.python.org/pypi/xmlsec
810
.. image:: https://img.shields.io/badge/docs-latest-green.svg
@@ -80,27 +82,52 @@ Mac
8082
If you get any fatal errors about missing .h files, update your C_INCLUDE_PATH environment variable to
8183
include the appropriate files from the libxml2 and libxmlsec1 libraries.
8284

85+
86+
Windows (Wheel)
87+
^^^^^^^^^^^^^^^
88+
89+
#. Download appropriate binary wheel from `ci.appveyor.com <https://ci.appveyor.com/project/bgaifullin/python-xmlsec>`_ (see build`s artifacts).
90+
91+
#. Install wheel
92+
93+
.. code-block:: bash
94+
95+
pip install <wheel filename>
96+
97+
98+
Windows (pip)
99+
^^^^^^^^^^^^^
100+
101+
#. Configure build environment, see `wiki.python.org <https://wiki.python.org/moin/WindowsCompilers>`_ for more details.
102+
103+
#. Install from pip
104+
105+
.. code-block:: bash
106+
107+
pip install xmlsec
108+
109+
83110
Manual
84111
------
85112

86-
1. Clone the **xmlsec** repository to your local computer.
113+
#. Clone the **xmlsec** repository to your local computer.
87114

88-
.. code-block:: bash
115+
.. code-block:: bash
89116
90-
git clone git://github.com/mehcode/python-xmlsec.git
117+
git clone git://github.com/mehcode/python-xmlsec.git
91118
92-
2. Change into the **xmlsec** root directory.
119+
#. Change into the **xmlsec** root directory.
93120

94-
.. code-block:: bash
121+
.. code-block:: bash
95122
96-
cd /path/to/xmlsec
123+
cd /path/to/xmlsec
97124
98125
99-
3. Install the project and all its dependencies using `pip`.
126+
#. Install the project and all its dependencies using `pip`.
100127

101-
.. code-block:: bash
128+
.. code-block:: bash
102129
103-
pip install .
130+
pip install .
104131
105132
106133
************
@@ -110,44 +137,43 @@ Contributing
110137
Setting up your environment
111138
---------------------------
112139

113-
1. Follow steps 1 and 2 of the [manual installation instructions][].
140+
#. Follow steps 1 and 2 of the `manual installation instructions <#manual>`_.
114141

115-
[manual installation instructions]: #manual
116142

117-
2. Initialize a virtual environment to develop in.
143+
#. Initialize a virtual environment to develop in.
118144
This is done so as to ensure every contributor is working with
119145
close-to-identicial versions of packages.
120146

121-
.. code-block:: bash
147+
.. code-block:: bash
122148
123-
mkvirtualenv xmlsec
149+
mkvirtualenv xmlsec
124150
125151
126-
The `mkvirtualenv` command is available from `virtualenvwrapper` which
127-
can be installed by following: http://virtualenvwrapper.readthedocs.org/en/latest/install.html#basic-installation
152+
The `mkvirtualenv` command is available from `virtualenvwrapper` which
153+
can be installed by following `link <http://virtualenvwrapper.readthedocs.org/en/latest/install.html#basic-installation>`_
128154

129-
3. Install **xmlsec** in development mode with testing enabled.
155+
#. Install **xmlsec** in development mode with testing enabled.
130156
This will download all dependencies required for running the unit tests.
131157

132-
.. code-block:: bash
158+
.. code-block:: bash
133159
134-
pip install -r requirements-test.txt
135-
pip install -e "."
160+
pip install -r requirements-test.txt
161+
pip install -e "."
136162
137163
138164
Running the test suite
139165
----------------------
140166

141-
1. [Set up your environment](#setting-up-your-environment).
167+
#. [Set up your environment](#setting-up-your-environment).
142168

143-
2. Run the unit tests.
169+
#. Run the unit tests.
144170

145-
.. code-block:: bash
171+
.. code-block:: bash
146172
147-
py.test tests
173+
py.test tests
148174
149-
3. Tests configuration
150-
Env variable **PYXMLSEC_TEST_ITERATIONS** specifies number of test iterations to detect memory leaks.
175+
#. Tests configuration
176+
Env variable **PYXMLSEC_TEST_ITERATIONS** specifies number of test iterations to detect memory leaks.
151177

152178
Reporting a issue
153179
-----------------

doc/source/install.rst

+25
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,28 @@ Mac
4040
brew install libxml2 libxmlsec1
4141
pip install xmlsec
4242
43+
44+
45+
Windows (Wheel)
46+
^^^^^^^^^^^^^^^
47+
48+
#. Download appropriate binary wheels from `appveyor <https://ci.appveyor.com/project/bgaifullin/python-xmlsec>`_ (see build`s artifacts).
49+
50+
#. Install downloaded wheel
51+
52+
.. code-block:: bash
53+
54+
pip install <downloaded wheel filename>
55+
56+
57+
Windows (pip)
58+
^^^^^^^^^^^^^
59+
60+
#. Configure build environment, see `wiki.python.org <https://wiki.python.org/moin/WindowsCompilers>`_ for more details.
61+
62+
#. Install from pip
63+
64+
.. code-block:: bash
65+
66+
pip install xmlsec
67+

extra.py

+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import os
2+
import sys
3+
4+
try:
5+
from urlparse import urljoin
6+
from urllib import urlretrieve, urlcleanup
7+
except ImportError:
8+
from urllib.parse import urljoin
9+
from urllib.request import urlretrieve, urlcleanup
10+
11+
12+
# use pre-built libraries on Windows
13+
def get_prebuilt_libs(download_dir, static_include_dirs, static_library_dirs):
14+
assert sys.platform.startswith('win')
15+
libs = download_and_extract_windows_binaries(download_dir)
16+
for ln, path in libs.items():
17+
if ln == 'xmlsec1':
18+
i = os.path.join(path, 'include', 'xmlsec1')
19+
else:
20+
i = os.path.join(path, 'include')
21+
22+
l = os.path.join(path, 'lib')
23+
assert os.path.exists(i), 'does not exist: %s' % i
24+
assert os.path.exists(l), 'does not exist: %s' % l
25+
static_include_dirs.append(i)
26+
static_library_dirs.append(l)
27+
28+
29+
def download_and_extract_windows_binaries(destdir):
30+
if sys.version_info < (3, 5):
31+
if sys.maxsize > 2147483647:
32+
url = "https://ci.appveyor.com/api/buildjobs/7q4nvmkdnu05dul6/artifacts/"
33+
suffix = "vs2008.win64"
34+
else:
35+
url = "https://ci.appveyor.com/api/buildjobs/tdpx6rprr5431ec9/artifacts/"
36+
suffix = "vs2008.win32"
37+
else:
38+
if sys.maxsize > 2147483647:
39+
url = "https://ci.appveyor.com/api/buildjobs/hij3a6776pdv2007/artifacts/"
40+
suffix = "win64"
41+
else:
42+
url = "https://ci.appveyor.com/api/buildjobs/7k878q7rvogcdyd9/artifacts/"
43+
suffix = "win32"
44+
45+
libs = {
46+
'libxml2': 'libxml2-2.9.4.{}.zip'.format(suffix),
47+
'libxslt': 'libxslt-1.1.29.{}.zip'.format(suffix),
48+
'zlib': 'zlib-1.2.8.{}.zip'.format(suffix),
49+
'iconv': 'iconv-1.14.{}.zip'.format(suffix),
50+
'openssl': 'openssl-1.0.1.{}.zip'.format(suffix),
51+
'xmlsec': 'xmlsec-1.2.24.{}.zip'.format(suffix),
52+
}
53+
54+
if not os.path.exists(destdir):
55+
os.makedirs(destdir)
56+
57+
for ln, fn in libs.items():
58+
srcfile = urljoin(url, fn)
59+
destfile = os.path.join(destdir, fn)
60+
if os.path.exists(destfile + ".keep"):
61+
print('Using local copy of "{}"'.format(srcfile))
62+
else:
63+
print('Retrieving "%s" to "%s"' % (srcfile, destfile))
64+
urlcleanup() # work around FTP bug 27973 in Py2.7.12+
65+
urlretrieve(srcfile, destfile)
66+
67+
libs[ln] = unpack_zipfile(destfile, destdir)
68+
69+
return libs
70+
71+
72+
def find_top_dir_of_zipfile(zipfile):
73+
topdir = None
74+
files = [f.filename for f in zipfile.filelist]
75+
dirs = [d for d in files if d.endswith('/')]
76+
if dirs:
77+
dirs.sort(key=len)
78+
topdir = dirs[0]
79+
topdir = topdir[:topdir.index("/")+1]
80+
for path in files:
81+
if not path.startswith(topdir):
82+
topdir = None
83+
break
84+
assert topdir, (
85+
"cannot determine single top-level directory in zip file %s" %
86+
zipfile.filename)
87+
return topdir.rstrip('/')
88+
89+
90+
def unpack_zipfile(zipfn, destdir):
91+
assert zipfn.endswith('.zip')
92+
import zipfile
93+
print('Unpacking %s into %s' % (os.path.basename(zipfn), destdir))
94+
f = zipfile.ZipFile(zipfn)
95+
try:
96+
extracted_dir = os.path.join(destdir, find_top_dir_of_zipfile(f))
97+
f.extractall(path=destdir)
98+
finally:
99+
f.close()
100+
assert os.path.exists(extracted_dir), 'missing: %s' % extracted_dir
101+
return extracted_dir

0 commit comments

Comments
 (0)