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

Develop #3

Open
wants to merge 33 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
1dea5a2
implemented windows platform support with cygwin
soulnai Dec 23, 2014
a1393dc
list function reworked to work with pip
soulnai Dec 23, 2014
5ee26a1
symlink creation function was reworked to work fine with pip git+ req…
soulnai Dec 24, 2014
1930b10
removed unused if-else branch
soulnai Dec 24, 2014
2eb0dad
version place changed - requirements should be installed automatically
soulnai Dec 24, 2014
71d1019
symlink creation fixed on apple&unix platforms
soulnai Dec 24, 2014
1835622
some functions reworked, non windows platform path handling fixed
soulnai Dec 25, 2014
4afbe24
Update README.rst
soulnai Dec 25, 2014
165078e
First test added
Dec 25, 2014
e32164f
link function reworked
soulnai Dec 26, 2014
a0ce9b1
closes #3
soulnai Dec 26, 2014
3892a60
dependencies symlinks support added
soulnai Dec 26, 2014
d437343
travis configured
soulnai Dec 26, 2014
9124ece
travis name changed
soulnai Dec 26, 2014
20ae50e
requirements for travis added
soulnai Dec 26, 2014
5f9e98f
test updated
soulnai Dec 26, 2014
4aa4928
travis-ci status added
soulnai Dec 26, 2014
d7f5c4a
test updated
soulnai Dec 26, 2014
707608e
test for link method: alfa-version added
Dec 27, 2014
761569d
some tests added
soulnai Jan 5, 2015
aeaf711
test for link rewritten, pip creating package name question still open
Jan 7, 2015
7090cc4
tests for winlink for file and dir added
Jan 7, 2015
003e32a
test_link_comparing_pip_installed will be modified
Jan 14, 2015
65732f9
test_winlink_directory modified
Jan 14, 2015
25a374e
exclude test if linux added
Jan 15, 2015
a43c4ed
Delete travis.yml
soulnai Jan 17, 2015
2aeb2f0
Update README.rst
soulnai Jan 23, 2015
858f218
pip 6+ support added
soulnai Jan 23, 2015
99da698
removed unnecessary requirements.txt, travis.yml updated
soulnai Jan 23, 2015
1f577cf
test_requirements fixed for support pip 6.0+
soulnai Jan 23, 2015
d643476
closes #5
soulnai Jan 23, 2015
15f4261
tests dependencies fixed
Jan 31, 2015
4e10265
pip6 error fixed
Jan 31, 2015
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ env
/build/
/dist/
/*.egg-info/
.idea
13 changes: 13 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
language: python
python:
- "2.7"
# command to install dependencies
install:
- "pip install -U pip"
- "pip install mock==1.0.1"
- "pip install pep8==1.5.7"
- "pip install pytest==2.6.4"
- "pip install requests==2.5.0"
- "pip install git+https://github.com/soulnai/gaeenv.git@develop#egg=gaeenv"
# command to run tests
script: py.test -pep8
16 changes: 14 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ Google App Engine virtual environment
``gaeenv`` (Google App Engine virtual environment) is a tool to integrate
Google App Engine SDK into existing environments built by virtualenv_

.. image:: https://travis-ci.org/soulnai/gaeenv.svg?branch=develop
:target: https://travis-ci.org/soulnai/gaeenv

Install
-------

Expand Down Expand Up @@ -33,10 +36,10 @@ virtual environment built with virtualenv_ or virtualenv_wrapper_::
If you want to work with the latest version of the gaeenv you can
install it from the github `repository`_::

$ git clone https://github.com/llinder/gaeenv.git
$ git clone https://github.com/soulnai/gaeenv.git@develop
$ ./gaeenv/gaeenv/main.py --help

.. _repository: https://github.com/llinder/gaeenv
.. _repository: https://github.com/soulnai/gaeenv.git@develop
.. _pip: http://pypi.python.org/pypi/pip
.. _easy_install: http://pypi.python.org/pypi/setuptools

Expand All @@ -47,14 +50,19 @@ Dependency
For gaeenv
^^^^^^^^^^^

* pip == 1.5.6
* python
* requests


Usage
-----

Basic
^^^^^
Important note - if you are running gaeenv on Windows platform:
- make sure you are working in cygwin environment
- cygwin console should be started with Administrator privilegies (it's required for symlink creation in Windows) or you can change it in System Permissions for everyone

Activate existing environment::

Expand Down Expand Up @@ -106,6 +114,10 @@ Install App Engine SDK "1.8.1"::

Link all packages in requirements.txt into src/lib::

If you want to use in requirements.txt links like git+git://github.com/anglinb/python-crunchbase you should add egg name at the end of string.
I.e. git+git://github.com/anglinb/python-crunchbase#egg=crunchbase. It's required to make all links correct.
Also #egg name should be equal to at least one of names listed in top-level.txt in project that you want to link.

$ . env/bin/activate
(env)$ pip install -r requirements.txt
(env)$ gaeenv install requirements -r requirements.txt
2 changes: 0 additions & 2 deletions gaeenv/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
:license: Apache 2.0, see LICENSE for more details.
"""

gaeenv_version = '0.1.2'

import sys
import os
import logging
Expand Down
151 changes: 96 additions & 55 deletions gaeenv/requirements.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,68 +2,109 @@
import re
import sys
import inspect
import pkg_resources
import pip
import pip.req
from types import NoneType

from distutils.sysconfig import get_python_lib
from utils import logger


def winlink(source, link_name):
'''symlink(source, link_name)
Creates a symbolic link pointing to source named link_name'''

import ctypes
csl = ctypes.windll.kernel32.CreateSymbolicLinkW
csl.argtypes = (ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_uint32)
csl.restype = ctypes.c_ubyte

flags = 0
if source is not None and os.path.isdir(source):
flags = 1
if csl(link_name, source, flags) == 0:
raise ctypes.WinError()


def list(req_file):
with open(req_file, 'r') as file:
requirements = [req for req in pkg_resources.parse_requirements(file.read())]
requirements = pip.req.parse_requirements(req_file, session=pip.download.PipSession())

for requirement in requirements:
print requirement
for requirement in requirements:
print requirement.req


def link(req_file, lib_dir):
# read requirements file
with open(req_file, 'r') as file:
requirements = [req for req in pkg_resources.parse_requirements(file.read())]

# ensure all requirements are installed
has_missing_requirement = False
packages = []
for requirement in requirements:
try:
packages.append(pkg_resources.get_provider(requirement))
except pkg_resources.DistributionNotFound:
has_missing_requirement = True
logger.error(' * Please install [%s]' % requirement)
except pkg_resources.VersionConflict:
has_missing_requirement = True
logger.error(' * Version don\'t match [%s] - create virtualenv or match the version' % requirement)

# if all requirements are found then create links to them all in the given libs dir
if not has_missing_requirement:
# create libs dir
if not os.path.exists(lib_dir):
os.makedirs(lib_dir)

# create new package file in the given libs dir
with open(os.path.join(lib_dir, '__init__.py'), 'wb') as f:
f.write((
"# Auto generated by gaeenv\n"
"import sys\n"
"import os\n"
"sys.path.insert(0, os.path.dirname(__file__))\n"))

for pkg in packages:
pkg_path = os.path.join(pkg.location, pkg.key)
sym_path = os.path.join(lib_dir, pkg.key)
# check if we are dealing with a file or directory package
is_file = (not os.path.exists(pkg_path) and os.path.exists(pkg_path + '.py'))

# add extension if we are dealing with a file
if is_file:
pkg_path = pkg_path + '.py'
sym_path = sym_path + '.py'

if os.path.islink(sym_path):
os.unlink(sym_path)

if os.path.exists(sym_path):
logger.error(' * Unable to link [%s] because a file already exists at [%s]' % (pkg, sym_path))
else:
logger.info(' * Linking [%s] in [%s]' % (pkg_path, sym_path))
os.symlink(pkg_path, sym_path)
all_requirements_set = set(pip.req.parse_requirements(req_file, session=pip.download.PipSession()) )
all_installed_packages__set = set(pip.get_installed_distributions())

ensure_packages_have_names(all_requirements_set)

dependencies = []

for package in all_installed_packages__set:
dependencies += package.requires()

for package in all_installed_packages__set:
for dependency in dependencies:
if dependency.key in package.key:
_create_symlink_for_package_content(package, lib_dir)

for package in all_installed_packages__set:
for requirement in all_requirements_set:
if requirement.req.key in package.key:
_create_symlink_for_package_content(package, lib_dir)

def make_package_from_links_folder(lib_dir):
"""Creates folder where symlinks will be stored. And adds __init__.py for it.
:param lib_dir: Path to folder where symlinks will be stored.
"""
if not os.path.exists(lib_dir):
os.makedirs(lib_dir)

with open(os.path.join(lib_dir, '__init__.py'), 'wb') as f:
f.write((
"# Auto generated by gaeenv\n"
"import sys\n"
"import os\n"
"sys.path.insert(0, os.path.dirname(__file__))\n"))


def get_package_folders_names(package):
return package._get_metadata("top_level.txt")


def make_symlink(pkg_path, sym_path):
if os.name == 'nt':
winlink(pkg_path, sym_path)
else:
os.symlink(pkg_path, sym_path)


def ensure_packages_have_names(all_requirements_set):
for requirement in all_requirements_set:
if requirement.req is None:
print("Requirement {} have not assigned package name and will not be linked. Please assign package name.")\
.format(str(requirement))
raise Exception("Linking interrupted!")


def _create_symlink_for_package_content(package, lib_dir):
package_folders = get_package_folders_names(package)
make_package_from_links_folder(lib_dir)
for folder_name in package_folders:
pkg_path = os.path.join(package.location, folder_name)
pkg_name = folder_name
is_file = (not os.path.exists(pkg_path) and os.path.exists(pkg_path + '.py'))
if is_file:
"""
Check if item that we want to link is a folder or a file. So we can build right link to it.
"""
pkg_path = pkg_path +'.py'
pkg_name = pkg_name + '.py'
if not os.path.exists(pkg_path):
continue
sym_path = os.path.join(lib_dir, pkg_name)
if os.path.exists(sym_path):
continue
print "Package {} linking into {}".format(str(pkg_path), str(sym_path))
make_symlink(str(pkg_path), sym_path)
Loading