Skip to content

Commit 7c51c32

Browse files
committed
Merge pull request #35 from martinb3/more_virtualenv_options
Add --no-virtualenv flag
2 parents c40923a + 38e24fb commit 7c51c32

File tree

5 files changed

+127
-45
lines changed

5 files changed

+127
-45
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ To specify an alternative, prexisting virtualenv use the `--virtualenv` paramete
5757
lambda-uploader --virtualenv=~/.virtualenv/my_custom_virtualenv
5858
```
5959

60+
To omit using a virtualenv use the `--no-virtualenv` parameter.
61+
```shell
62+
lambda-uploader --no-virtualenv
63+
```
64+
6065
If you would prefer to upload another way you can tell the uploader to ignore the upload.
6166
This will create a package and leave it in the project directory.
6267
```shell

README.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@ To specify an alternative, prexisting virtualenv use the
7575
7676
lambda-uploader --virtualenv=~/.virtualenv/my_custom_virtualenv
7777
78+
To omit using a virtualenv use the ``--no-virtualenv`` parameter.
79+
80+
.. code:: shell
81+
82+
lambda-uploader --no-virtualenv
83+
7884
If you would prefer to upload another way you can tell the uploader to
7985
ignore the upload. This will create a package and leave it in the
8086
project directory.

lambda_uploader/package.py

Lines changed: 66 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -27,37 +27,24 @@
2727

2828

2929
def build_package(path, requirements, virtualenv=None, ignore=[]):
30-
pkg = Package(path, virtualenv)
30+
pkg = Package(path, virtualenv, requirements)
3131

3232
pkg.clean_workspace()
3333
pkg.clean_zipfile()
3434
pkg.prepare_workspace()
35-
if virtualenv:
36-
if not os.path.isdir(virtualenv):
37-
raise Exception("supplied virtualenv %s not found" % virtualenv)
38-
LOG.info("Using existing virtualenv found in %s" % virtualenv)
39-
else:
40-
LOG.info('Building new virtualenv and installing requirements')
41-
pkg.prepare_virtualenv()
42-
pkg.install_requirements(requirements)
35+
pkg.prepare_virtualenv()
4336
pkg.package(ignore)
4437
return pkg
4538

4639

4740
class Package(object):
48-
def __init__(self, path, virtualenv=None):
41+
def __init__(self, path, virtualenv=None, requirements=[]):
4942
self._path = path
5043
self._temp_workspace = os.path.join(path,
5144
TEMP_WORKSPACE_NAME)
5245
self.zip_file = os.path.join(path, ZIPFILE_NAME)
53-
54-
if virtualenv:
55-
self._pkg_venv = virtualenv
56-
else:
57-
self._pkg_venv = os.path.join(self._temp_workspace, 'venv')
58-
self._venv_pip = 'bin/pip'
59-
if sys.platform == 'win32' or sys.platform == 'cygwin':
60-
self._venv_pip = 'Scripts\pip.exe'
46+
self._virtualenv = virtualenv
47+
self._requirements = requirements
6148

6249
def clean_workspace(self):
6350
if os.path.isdir(self._temp_workspace):
@@ -72,21 +59,59 @@ def prepare_workspace(self):
7259
os.mkdir(self._temp_workspace)
7360

7461
def prepare_virtualenv(self):
75-
proc = Popen(["virtualenv", self._pkg_venv], stdout=PIPE, stderr=PIPE)
76-
stdout, stderr = proc.communicate()
77-
LOG.debug("Virtualenv stdout: %s" % stdout)
78-
LOG.debug("Virtualenv stderr: %s" % stderr)
62+
requirements_exist = \
63+
self._requirements or os.path.isfile("requirements.txt")
64+
if self._virtualenv and self._virtualenv is not False:
65+
if not os.path.isdir(self._virtualenv):
66+
raise Exception("virtualenv %s not found" % self._virtualenv)
67+
LOG.info("Using existing virtualenv at %s" % self._virtualenv)
68+
69+
# use supplied virtualenv path
70+
self._pkg_venv = self._virtualenv
71+
elif self._virtualenv is None and requirements_exist:
72+
LOG.info('Building new virtualenv and installing requirements')
73+
self.build_new_virtualenv()
74+
self.install_requirements()
75+
elif self._virtualenv is None and not requirements_exist:
76+
LOG.info('No requirements found, so no virtualenv will be made')
77+
self._pkg_venv = False
78+
elif self._virtualenv is False:
79+
LOG.info('Virtualenv has been omitted by supplied flag')
80+
self._pkg_venv = False
81+
else:
82+
raise Exception('Cannot determine what to do about virtualenv')
7983

80-
if proc.returncode is not 0:
81-
raise Exception('virtualenv returned unsuccessfully')
84+
def build_new_virtualenv(self):
85+
if self._virtualenv is None:
86+
# virtualenv was "None" which means "do default"
87+
self._pkg_venv = os.path.join(self._temp_workspace, 'venv')
88+
self._venv_pip = 'bin/pip'
89+
if sys.platform == 'win32' or sys.platform == 'cygwin':
90+
self._venv_pip = 'Scripts\pip.exe'
91+
92+
proc = Popen(["virtualenv", self._pkg_venv],
93+
stdout=PIPE, stderr=PIPE)
94+
stdout, stderr = proc.communicate()
95+
LOG.debug("Virtualenv stdout: %s" % stdout)
96+
LOG.debug("Virtualenv stderr: %s" % stderr)
97+
98+
if proc.returncode is not 0:
99+
raise Exception('virtualenv returned unsuccessfully')
100+
101+
else:
102+
raise Exception('cannot build a new virtualenv when asked to omit')
103+
104+
def install_requirements(self):
105+
if not hasattr(self, '_pkg_venv'):
106+
err = 'Must call build_new_virtualenv before install_requirements'
107+
raise Exception(err)
82108

83-
def install_requirements(self, requirements):
84109
cmd = None
85-
if requirements:
110+
if self._requirements:
86111
LOG.debug("Installing requirements found %s in config"
87-
% requirements)
112+
% self._requirements)
88113
cmd = [os.path.join(self._pkg_venv, self._venv_pip),
89-
'install'] + requirements
114+
'install'] + self._requirements
90115

91116
elif os.path.isfile("requirements.txt"):
92117
# Pip install
@@ -109,18 +134,19 @@ def package(self, ignore=[]):
109134
# Copy site packages into package base
110135
LOG.info('Copying site packages')
111136

112-
site_packages = 'lib/python2.7/site-packages'
113-
lib64_site_packages = 'lib64/python2.7/site-packages'
114-
if sys.platform == 'win32' or sys.platform == 'cygwin':
115-
lib64_site_packages = 'lib64\\site-packages'
116-
site_packages = 'lib\\site-packages'
117-
118-
utils.copy_tree(os.path.join(self._pkg_venv, site_packages),
119-
package)
120-
lib64_path = os.path.join(self._pkg_venv, lib64_site_packages)
121-
if not os.path.islink(lib64_path):
122-
LOG.info('Copying lib64 site packages')
123-
utils.copy_tree(lib64_path, package)
137+
if hasattr(self, '_pkg_venv') and self._pkg_venv:
138+
site_packages = 'lib/python2.7/site-packages'
139+
lib64_site_packages = 'lib64/python2.7/site-packages'
140+
if sys.platform == 'win32' or sys.platform == 'cygwin':
141+
lib64_site_packages = 'lib64\\site-packages'
142+
site_packages = 'lib\\site-packages'
143+
144+
utils.copy_tree(os.path.join(self._pkg_venv, site_packages),
145+
package)
146+
lib64_path = os.path.join(self._pkg_venv, lib64_site_packages)
147+
if not os.path.islink(lib64_path):
148+
LOG.info('Copying lib64 site packages')
149+
utils.copy_tree(lib64_path, package)
124150

125151
# Append the temp workspace to the ignore list
126152
ignore.append("^%s/*" % self._temp_workspace)

lambda_uploader/shell.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,19 @@ def _execute(args):
4949

5050
cfg = config.Config(pth, args.config, role=args.role)
5151

52+
if args.no_virtualenv:
53+
# specified flag to omit entirely
54+
venv = False
55+
elif args.virtualenv:
56+
# specified a custom virtualenv
57+
venv = args.virtualenv
58+
else:
59+
# build and include virtualenv, the default
60+
venv = None
61+
5262
_print('Building Package')
5363
pkg = package.build_package(pth, cfg.requirements,
54-
args.virtualenv, cfg.ignore)
64+
venv, cfg.ignore)
5565

5666
if not args.no_clean:
5767
pkg.clean_workspace()
@@ -101,6 +111,10 @@ def main(arv=None):
101111
parser.add_argument('--virtualenv', '-e',
102112
help='use specified virtualenv instead of making one',
103113
default=None)
114+
parser.add_argument('--no-virtualenv', dest='no_virtualenv',
115+
action='store_const',
116+
help='do not create or include a virtualenv at all',
117+
const=True)
104118
parser.add_argument('--role', dest='role',
105119
default=getenv('LAMBDA_UPLOADER_ROLE'),
106120
help=('IAM role to assign the lambda function, '

test/test_package.py

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import os
22
import sys
3+
import pytest
34

45
from shutil import rmtree
56
from os import path
@@ -53,9 +54,9 @@ def test_install_requirements():
5354
temp_workspace = path.join(TESTING_TEMP_DIR,
5455
package.TEMP_WORKSPACE_NAME)
5556

56-
pkg = package.Package(TESTING_TEMP_DIR)
57-
# pkg.prepare_workspace()
58-
pkg.install_requirements(reqs)
57+
pkg = package.Package(TESTING_TEMP_DIR, requirements=reqs)
58+
pkg.prepare_virtualenv()
59+
5960
site_packages = path.join(temp_workspace,
6061
'venv/lib/python2.7/site-packages')
6162
if sys.platform == 'win32' or sys.platform == 'cygwin':
@@ -64,9 +65,39 @@ def test_install_requirements():
6465
assert path.isdir(path.join(site_packages, '_pytest'))
6566

6667

68+
def test_default_virtualenv():
69+
temp_workspace = path.join(TESTING_TEMP_DIR,
70+
package.TEMP_WORKSPACE_NAME)
71+
pkg = package.Package(TESTING_TEMP_DIR)
72+
pkg.prepare_virtualenv()
73+
# ensure we picked a real venv path if using default behavior
74+
assert pkg._pkg_venv == ("%s/venv" % temp_workspace)
75+
76+
6777
def test_existing_virtualenv():
78+
venv_dir = "virtualenv_test"
79+
temp_virtualenv = path.join(TESTING_TEMP_DIR, venv_dir)
80+
os.mkdir(temp_virtualenv)
81+
82+
pkg = package.Package(TESTING_TEMP_DIR, temp_virtualenv)
83+
pkg.prepare_virtualenv()
84+
85+
assert pkg._pkg_venv == temp_virtualenv
86+
87+
88+
def test_bad_existing_virtualenv():
6889
pkg = package.Package(TESTING_TEMP_DIR, 'abc')
69-
assert pkg._pkg_venv == 'abc'
90+
with pytest.raises(Exception):
91+
pkg.prepare_virtualenv()
92+
93+
94+
def test_omit_virtualenv():
95+
pkg = package.Package(TESTING_TEMP_DIR, False)
96+
pkg.prepare_virtualenv()
97+
assert pkg._pkg_venv is False
98+
99+
with pytest.raises(Exception):
100+
pkg.build_new_virtualenv()
70101

71102

72103
def test_package():

0 commit comments

Comments
 (0)