Skip to content

Commit 696a8d7

Browse files
authored
Fixing up more tests, making pipfile work again, adding some tests
Bringing this closer...
2 parents 66b54e3 + 8b432b9 commit 696a8d7

File tree

5 files changed

+84
-34
lines changed

5 files changed

+84
-34
lines changed

index.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const {addVendorHelper, removeVendorHelper, packRequirements} = require('./lib/z
77
const {injectAllRequirements} = require('./lib/inject');
88
const {installAllRequirements} = require('./lib/pip');
99
const {pipfileToRequirements} = require('./lib/pipenv');
10-
const {cleanup, cleanupStaticCache} = require('./lib/clean');
10+
const {cleanup, cleanupCache} = require('./lib/clean');
1111

1212
BbPromise.promisifyAll(fse);
1313

@@ -32,7 +32,8 @@ class ServerlessPythonRequirements {
3232
dockerImage: null,
3333
dockerFile: null,
3434
useStaticCache: false,
35-
staticCacheLocation: false,
35+
useDownloadCache: false,
36+
cacheLocation: false,
3637
staticCacheMaxVersions: 0,
3738
pipCmdExtraArgs: [],
3839
noDeploy: [
@@ -131,7 +132,7 @@ class ServerlessPythonRequirements {
131132
};
132133

133134
const cleanStatic = () => BbPromise.bind(this)
134-
.then(cleanupStaticCache);
135+
.then(cleanupCache);
135136

136137

137138
this.hooks = {

lib/clean.js

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ const BbPromise = require('bluebird');
22
const fse = require('fs-extra');
33
const path = require('path');
44
const glob = require('glob-all');
5-
const {getStaticCachePath} = require('./shared');
5+
const {getUserCachePath} = require('./shared');
66

77
BbPromise.promisifyAll(fse);
88

@@ -34,24 +34,26 @@ function cleanup() {
3434
* Clean up static cache, remove all items in there
3535
* @return {Promise}
3636
*/
37-
function cleanupStaticCache() {
38-
const staticCacheLocation = getStaticCachePath(this.options);
39-
if (fse.existsSync(staticCacheLocation)) {
40-
this.serverless.cli.log(`Removing static caches at: ${staticCacheLocation}`);
37+
function cleanupCache() {
38+
const cacheLocation = getUserCachePath(this.options);
39+
if (fse.existsSync(cacheLocation)) {
40+
if (this.serverless) {
41+
this.serverless.cli.log(`Removing static caches at: ${cacheLocation}`);
42+
}
4143

4244
// Only remove cache folders that we added, just incase someone accidentally puts a weird
4345
// static cache location so we don't remove a bunch of personal stuff
4446
promises = [];
45-
glob.sync([path.join(staticCacheLocation, '*')], {mark: true, dot: false}).forEach((file) => {
46-
if (file.endsWith('_slspyc/')) {
47-
promises.push( fse.removeAsync(file) );
48-
}
47+
glob.sync([path.join(cacheLocation, '*slspyc/')], {mark: true, dot: false}).forEach((file) => {
48+
promises.push( fse.removeAsync(file) );
4949
});
5050
return BbPromise.all( promises );
5151
} else {
52-
this.serverless.cli.log(`No static cache found`);
52+
if (this.serverless) {
53+
this.serverless.cli.log(`No static cache found`);
54+
}
5355
return BbPromise.resolve();
5456
}
5557
}
5658

57-
module.exports = {cleanup, cleanupStaticCache};
59+
module.exports = {cleanup, cleanupCache};

lib/pip.js

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const {spawnSync} = require('child_process');
77
const values = require('lodash.values');
88
const {buildImage, getBindPath, getDockerUid} = require('./docker');
99
const {
10-
checkForAndDeleteMaxCacheVersions, getRequirementsWorkingPath, md5Path,
10+
checkForAndDeleteMaxCacheVersions, getRequirementsWorkingPath, getUserCachePath, md5Path,
1111
} = require('./shared');
1212

1313
/**
@@ -63,6 +63,14 @@ function installRequirements(targetFolder, serverless, options) {
6363
pipCmd.push('-t', targetFolder);
6464
pipCmd.push('-r', targetRequirementsTxt);
6565

66+
// If we want a download cache...
67+
if (options.useDownloadCache) {
68+
const downloadCacheDir = path.join(getUserCachePath(options), 'downloadCacheslspyc');
69+
serverless.cli.log(`Using download cache directory ${downloadCacheDir}`);
70+
fse.ensureDirSync(downloadCacheDir);
71+
pipCmd.push('--cache-dir', downloadCacheDir);
72+
}
73+
6674
// Check if pip has Debian's --system option and set it if so
6775
const pipTestRes = spawnSync(
6876
options.pythonBin, ['-m', 'pip', 'help', 'install']);
@@ -82,11 +90,8 @@ function installRequirements(targetFolder, serverless, options) {
8290
// If we are dockerizing pip
8391
if (options.dockerizePip) {
8492
cmd = 'docker';
85-
// Push docker-specific paths for requirements and target directory
86-
pipCmd.push('-t', '/var/task/');
87-
pipCmd.push('-r', '/var/task/requirements.txt');
8893

89-
// Build docker image if required
94+
// First, build docker image if required
9095
let dockerImage;
9196
if (options.dockerFile) {
9297
serverless.cli.log(`Building custom docker image from ${options.dockerFile}...`);
@@ -96,6 +101,10 @@ function installRequirements(targetFolder, serverless, options) {
96101
}
97102
serverless.cli.log(`Docker Image: ${dockerImage}`);
98103

104+
// Push docker-specific paths for requirements and target directory
105+
pipCmd.push('-t', '/var/task/');
106+
pipCmd.push('-r', '/var/task/requirements.txt');
107+
99108
// Prepare bind path depending on os platform
100109
const bindPath = getBindPath(targetFolder);
101110

@@ -110,6 +119,16 @@ function installRequirements(targetFolder, serverless, options) {
110119
cmdOptions.push('-v', `${process.env.SSH_AUTH_SOCK}:/tmp/ssh_sock:z`);
111120
cmdOptions.push('-e', 'SSH_AUTH_SOCK=/tmp/ssh_sock');
112121
}
122+
// If we want a download cache...
123+
if (options.useDownloadCache) {
124+
const downloadCacheDir = path.join(getUserCachePath(options), 'downloadCacheslspyc');
125+
serverless.cli.log(`Using download cache directory ${downloadCacheDir}`);
126+
fse.ensureDirSync(downloadCacheDir);
127+
// And now push it to a volume mount and to pip...
128+
cmdOptions.push('-v', `${downloadCacheDir}:/var/useDownloadCache:z`);
129+
pipCmd.push('--cache-dir', '/var/useDownloadCache');
130+
}
131+
113132
if (process.platform === 'linux') {
114133
// Use same user so requirements folder is not root and so --cache-dir works
115134
cmdOptions.push('-u', `${process.getuid()}`);
@@ -207,10 +226,7 @@ function installRequirementsIfNeeded(servicePath, modulePath, options, serverles
207226
// First, generate the requirements file to our local .serverless folder
208227
fse.ensureDirSync(path.join(servicePath, '.serverless'));
209228
const slsReqsTxt = path.join(servicePath, '.serverless', 'requirements.txt');
210-
// Incase it's laying around from a previous package (when individually/failed packaging)
211-
if (fse.existsSync(slsReqsTxt)) {
212-
fse.removeSync(slsReqsTxt);
213-
}
229+
214230
installRequirementsFile(
215231
fileName,
216232
slsReqsTxt,
@@ -242,7 +258,6 @@ function installRequirementsIfNeeded(servicePath, modulePath, options, serverles
242258
serverless.cli.log(`Using static cache of requirements found at ${workingReqsFolder} ...`);
243259
// We'll "touch" the folder, as to bring it to the start of the FIFO cache
244260
fse.utimesSync(workingReqsFolder, new Date(), new Date());
245-
fse.removeSync(slsReqsTxt);
246261
return workingReqsFolder;
247262
}
248263
// Remove our old folder if it didn't complete properly, but _just incase_ only remove it if named properly...
@@ -276,7 +291,6 @@ function installRequirementsIfNeeded(servicePath, modulePath, options, serverles
276291
if (options.useStaticCache) {
277292
fse.closeSync(fse.openSync(path.join(workingReqsFolder, '.completed_requirements'), 'w'));
278293
}
279-
fse.removeSync(slsReqsTxt); // Clean up after ourselves
280294
return workingReqsFolder;
281295
}
282296

lib/shared.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ function checkForAndDeleteMaxCacheVersions(options, serverless) {
1919
options.staticCacheMaxVersions &&
2020
parseInt(options.staticCacheMaxVersions) > 0) {
2121
// Get the list of our cache files
22-
files = glob.sync([path.join(getStaticCachePath(options), '*_slspyc/')], {mark: true});
22+
files = glob.sync([path.join(getUserCachePath(options), '*_slspyc/')], {mark: true});
2323
// Check if we have too many
2424
if (files.length >= options.staticCacheMaxVersions) {
2525
// Sort by modified time
@@ -53,7 +53,7 @@ function getRequirementsWorkingPath(subfolder, servicePath, options) {
5353
}
5454
// If we have max number of cache items...
5555

56-
return path.join( getStaticCachePath(options), subfolder);
56+
return path.join( getUserCachePath(options), subfolder);
5757
}
5858

5959
// If we don't want to use the static cache, then fallback to the way things used to work
@@ -66,10 +66,10 @@ function getRequirementsWorkingPath(subfolder, servicePath, options) {
6666
* @param {Object} options
6767
* @return {string}
6868
*/
69-
function getStaticCachePath(options) {
69+
function getUserCachePath(options) {
7070
// If we've manually set the static cache location
71-
if (options && options.staticCacheLocation) {
72-
return path.join(options.staticCacheLocation);
71+
if (options && options.cacheLocation) {
72+
return path.resolve(options.cacheLocation);
7373
}
7474

7575
// Otherwise, find/use the python-ey appdirs cache location
@@ -93,6 +93,6 @@ function md5Path(fullpath) {
9393
module.exports = {
9494
checkForAndDeleteMaxCacheVersions,
9595
getRequirementsWorkingPath,
96-
getStaticCachePath,
96+
getUserCachePath,
9797
md5Path,
9898
};

test.bats

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,15 @@ setup() {
77
export LC_ALL=C.UTF-8
88
export LANG=C.UTF-8
99
fi
10+
export USR_CACHE_DIR=`node -e 'console.log(require("./lib/shared").getUserCachePath())'`
1011
}
1112

1213
teardown() {
1314
rm -rf puck puck2 puck3 node_modules .serverless .requirements.zip .requirements-cache
1415
if [ -f serverless.yml.bak ]; then mv serverless.yml.bak serverless.yml; fi
16+
if [ -d "${USR_CACHE_DIR}" ] ; then
17+
rm -Rf "${USR_CACHE_DIR}"
18+
fi
1519
}
1620

1721
@test "py3.6 can package flask with default options" {
@@ -67,13 +71,42 @@ teardown() {
6771
ls puck/flask
6872
}
6973

70-
@test "py3.6 uses cache with dockerizePip option" {
74+
@test "py3.6 uses download cache with useDownloadCache option" {
75+
cd tests/base
76+
npm i $(npm pack ../..)
77+
! uname -sm|grep Linux || groups|grep docker || id -u|egrep '^0$' || skip "can't dockerize on linux if not root & not in docker group"
78+
perl -p -i'.bak' -e 's/(pythonRequirements:$)/\1\n useDownloadCache: true/' serverless.yml
79+
sls package
80+
USR_CACHE_DIR=`node -e 'console.log(require("../../lib/shared").getUserCachePath())'`
81+
ls $USR_CACHE_DIR/downloadCacheslspyc/http
82+
}
83+
84+
@test "py3.6 uses download cache with useDownloadCache + cacheLocation option" {
85+
cd tests/base
86+
npm i $(npm pack ../..)
87+
! uname -sm|grep Linux || groups|grep docker || id -u|egrep '^0$' || skip "can't dockerize on linux if not root & not in docker group"
88+
perl -p -i'.bak' -e 's/(pythonRequirements:$)/\1\n useDownloadCache: true\n cacheLocation: .requirements-cache/' serverless.yml
89+
sls package
90+
ls .requirements-cache/downloadCacheslspyc/http
91+
}
92+
93+
@test "py3.6 uses download cache with dockerizePip + useDownloadCache option" {
94+
cd tests/base
95+
npm i $(npm pack ../..)
96+
! uname -sm|grep Linux || groups|grep docker || id -u|egrep '^0$' || skip "can't dockerize on linux if not root & not in docker group"
97+
perl -p -i'.bak' -e 's/(pythonRequirements:$)/\1\n useDownloadCache: true/' serverless.yml
98+
sls --dockerizePip=true package
99+
USR_CACHE_DIR=`node -e 'console.log(require("../../lib/shared").getUserCachePath())'`
100+
ls $USR_CACHE_DIR/downloadCacheslspyc/http
101+
}
102+
103+
@test "py3.6 uses download cache with dockerizePip + useDownloadCache + cacheLocation option" {
71104
cd tests/base
72105
npm i $(npm pack ../..)
73106
! uname -sm|grep Linux || groups|grep docker || id -u|egrep '^0$' || skip "can't dockerize on linux if not root & not in docker group"
74-
perl -p -i'.bak' -e 's/(pythonRequirements:$)/\1\n pipCmdExtraArgs: ["--cache-dir", ".requirements-cache"]/' serverless.yml
107+
perl -p -i'.bak' -e 's/(pythonRequirements:$)/\1\n useDownloadCache: true\n cacheLocation: .requirements-cache/' serverless.yml
75108
sls --dockerizePip=true package
76-
ls .requirements-cache/http
109+
ls .requirements-cache/downloadCacheslspyc/http
77110
}
78111

79112
@test "py2.7 can package flask with default options" {

0 commit comments

Comments
 (0)