Skip to content

Commit 4d45860

Browse files
committed
Inject files into package instead of creating symlinks
- symlinks are still not working properly on windows (it fails deleting them because they're actually folders) - IDE indexes the symlinked folders while they're there which slows things down - any failure, like a file being in use, causes all symlinks to be left behind
1 parent 3f5cc1b commit 4d45860

File tree

3 files changed

+76
-191
lines changed

3 files changed

+76
-191
lines changed

index.js

+3-4
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
const BbPromise = require('bluebird');
55
const fse = require('fs-extra');
66
const {addVendorHelper, removeVendorHelper, packRequirements} = require('./lib/zip');
7+
const {injectAllRequirements} = require('./lib/inject');
78
const {installAllRequirements} = require('./lib/pip');
89
const {pipfileToRequirements} = require('./lib/pipenv');
9-
const {linkAllRequirements, unlinkAllRequirements} = require('./lib/link');
1010
const {cleanup} = require('./lib/clean');
1111

1212
BbPromise.promisifyAll(fse);
@@ -101,12 +101,11 @@ class ServerlessPythonRequirements {
101101
.then(pipfileToRequirements)
102102
.then(addVendorHelper)
103103
.then(installAllRequirements)
104-
.then(packRequirements)
105-
.then(linkAllRequirements);
104+
.then(packRequirements);
106105

107106
const after = () => BbPromise.bind(this)
108107
.then(removeVendorHelper)
109-
.then(unlinkAllRequirements);
108+
.then(injectAllRequirements);
110109

111110
const invalidateCaches = () => {
112111
if (this.options.invalidateCaches) {

lib/inject.js

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
const fse = require('fs-extra');
2+
const glob = require('glob-all');
3+
const get = require('lodash.get');
4+
const set = require('lodash.set');
5+
const path = require('path');
6+
const values = require('lodash.values');
7+
const zipper = require('zip-local');
8+
9+
/**
10+
* inject requirements into packaged application
11+
* @param {string} requirementsPath requirements folder path
12+
* @param {string} packagePath target package path
13+
* @param {Object} options our options object
14+
*/
15+
function injectRequirements(requirementsPath, packagePath, options) {
16+
const noDeploy = new Set(options.noDeploy || []);
17+
18+
const zip = zipper.sync.unzip(packagePath).lowLevel();
19+
20+
glob.sync([path.join(requirementsPath, '**')], {mark: true, dot: true}).forEach((file) => {
21+
if (file.endsWith('/')) {
22+
return;
23+
}
24+
25+
if (noDeploy.has(file.split(/[-\\\/]/, 1)[0])) {
26+
return;
27+
}
28+
29+
zip.file(path.relative(requirementsPath, file), fse.readFileSync(file), {
30+
date: new Date(0), // necessary to get the same hash when zipping the same content
31+
});
32+
});
33+
34+
const buff = zip.generate({
35+
type: 'nodebuffer',
36+
compression: 'DEFLATE',
37+
});
38+
39+
fse.writeFileSync(packagePath, buff);
40+
}
41+
42+
/**
43+
* inject requirements into packaged application
44+
*/
45+
function injectAllRequirements() {
46+
this.serverless.cli.log('Injecting required Python packages to package...');
47+
48+
if (this.serverless.service.package.individually) {
49+
let doneModules = [];
50+
values(this.serverless.service.functions)
51+
.forEach((f) => {
52+
if (!get(f, 'module')) {
53+
set(f, ['module'], '.');
54+
}
55+
if (!doneModules.includes(f.module)) {
56+
injectRequirements(
57+
path.join('.serverless', f.module, 'requirements'),
58+
f.package.artifact,
59+
this.options
60+
);
61+
doneModules.push(f.module);
62+
}
63+
});
64+
} else {
65+
injectRequirements(
66+
path.join('.serverless', 'requirements'),
67+
this.serverless.service.package.artifact,
68+
this.options
69+
);
70+
}
71+
}
72+
73+
module.exports = {injectAllRequirements};

lib/link.js

-187
This file was deleted.

0 commit comments

Comments
 (0)