-
Notifications
You must be signed in to change notification settings - Fork 293
Inject files into package instead of creating symlinks #147
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
Merged
Merged
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
4d45860
Inject files into package instead of creating symlinks
kichik d0a89c0
fix noDeploy
kichik 67a9eae
Fix lint issue
kichik 346db42
Exclude <noDeploy>.py too
kichik 3e3ddb9
Include requirements into every package, even when it's in the root
kichik 0941fd2
Fix lint issue
kichik c2a7360
Handle runtime that's not Python
kichik e43dcc6
Use function.module to name package
kichik 2812022
Filter files not in function.module with individually: true
kichik 18656a2
Don't inject requirements when zip: true is used
kichik bcd3059
Remove dependency
kichik 55a4402
Merge branch 'master' into inject
kichik cb590f5
Specifically add jszip
kichik bb7d493
We need an older version
kichik File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
const fse = require('fs-extra'); | ||
const glob = require('glob-all'); | ||
const get = require('lodash.get'); | ||
const set = require('lodash.set'); | ||
const path = require('path'); | ||
const values = require('lodash.values'); | ||
const zipper = require('zip-local'); | ||
const JSZip = require('jszip'); | ||
|
||
/** | ||
* write zip contents to a file | ||
* @param {Object} zip | ||
* @param {string} path | ||
*/ | ||
function writeZip(zip, path) { | ||
const buff = zip.generate({ | ||
type: 'nodebuffer', | ||
compression: 'DEFLATE', | ||
}); | ||
|
||
fse.writeFileSync(path, buff); | ||
} | ||
|
||
/** | ||
* add a new file to a zip file from a buffer | ||
* @param {Object} zip | ||
* @param {string} path path to put in zip | ||
* @param {string} buffer file contents | ||
*/ | ||
function zipFile(zip, path, buffer) { | ||
zip.file(path, buffer, { | ||
date: new Date(0), // necessary to get the same hash when zipping the same content | ||
}); | ||
} | ||
|
||
/** | ||
* inject requirements into packaged application | ||
* @param {string} requirementsPath requirements folder path | ||
* @param {string} packagePath target package path | ||
* @param {Object} options our options object | ||
*/ | ||
function injectRequirements(requirementsPath, packagePath, options) { | ||
const noDeploy = new Set(options.noDeploy || []); | ||
|
||
const zip = zipper.sync.unzip(packagePath).lowLevel(); | ||
|
||
glob.sync([path.join(requirementsPath, '**')], {mark: true, dot: true}).forEach((file) => { | ||
if (file.endsWith('/')) { | ||
return; | ||
} | ||
|
||
const relativeFile = path.relative(requirementsPath, file); | ||
|
||
if (relativeFile.match(/^__pycache__[\\\/]/)) { | ||
return; | ||
} | ||
if (noDeploy.has(relativeFile.split(/([-\\\/]|\.py$|\.pyc$)/, 1)[0])) { | ||
return; | ||
} | ||
|
||
zipFile(zip, relativeFile, fse.readFileSync(file)); | ||
}); | ||
|
||
writeZip(zip, packagePath); | ||
} | ||
|
||
/** | ||
* remove all modules but the selected module from a package | ||
* @param {string} source original package | ||
* @param {string} target result package | ||
* @param {string} module module to keep | ||
*/ | ||
function moveModuleUp(source, target, module) { | ||
const sourceZip = zipper.sync.unzip(source).memory(); | ||
const targetZip = JSZip.make(); | ||
|
||
sourceZip.contents().forEach((file) => { | ||
if (!file.startsWith(module + '/')) { | ||
return; | ||
} | ||
zipFile(targetZip, file.replace(module + '/', ''), sourceZip.read(file, 'buffer')); | ||
}); | ||
|
||
writeZip(targetZip, target); | ||
} | ||
|
||
/** | ||
* inject requirements into packaged application | ||
*/ | ||
function injectAllRequirements() { | ||
this.serverless.cli.log('Injecting required Python packages to package...'); | ||
|
||
if (this.options.zip) { | ||
return; | ||
} | ||
|
||
if (this.serverless.service.package.individually) { | ||
values(this.serverless.service.functions) | ||
.forEach((f) => { | ||
if (!(f.runtime || this.serverless.service.provider.runtime).match(/^python.*/)) { | ||
return; | ||
} | ||
if (!get(f, 'module')) { | ||
set(f, ['module'], '.'); | ||
} | ||
if (f.module !== '.') { | ||
const artifactPath = path.join('.serverless', `${f.module}.zip`); | ||
moveModuleUp(f.package.artifact, artifactPath, f.module); | ||
f.package.artifact = artifactPath; | ||
} | ||
injectRequirements( | ||
path.join('.serverless', f.module, 'requirements'), | ||
f.package.artifact, | ||
this.options | ||
); | ||
}); | ||
} else { | ||
injectRequirements( | ||
path.join('.serverless', 'requirements'), | ||
this.serverless.service.package.artifact, | ||
this.options | ||
); | ||
} | ||
} | ||
|
||
module.exports = {injectAllRequirements}; |
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why omit caches/pyc? IIRC they're cross platform(just tied to the version of python, which should be the same) and should provide a small perf boost.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's just the root
__pycache__
which contains mostlysix.pyc
that's not deployed by default and maybe other small files. This mimics the old behavior https://github.com/UnitedIncome/serverless-python-requirements/pull/147/files#diff-0ffe4d151b22eb4ec361c9b4faaa9b11L50 and might be improved in the future.I actually plan on trying to get rid of all
.pyc
files in the future with the--no-compile
flag to provide more stable builds (as in building twice produces the exact same result). But there's still some more research to be done there.