forked from aws/aws-lambda-builders
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathactions.py
248 lines (185 loc) · 8.39 KB
/
actions.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
"""
Action to resolve NodeJS dependencies using NPM
"""
import logging
from aws_lambda_builders.actions import BaseAction, Purpose, ActionFailedError
from .npm import NpmExecutionError
LOG = logging.getLogger(__name__)
class NodejsNpmPackAction(BaseAction):
"""
A Lambda Builder Action that packages a Node.js package using NPM to extract the source and remove test resources
"""
NAME = 'NpmPack'
DESCRIPTION = "Packaging source using NPM"
PURPOSE = Purpose.COPY_SOURCE
def __init__(self, artifacts_dir, scratch_dir, manifest_path, osutils, subprocess_npm):
"""
:type artifacts_dir: str
:param artifacts_dir: an existing (writable) directory where to store the output.
Note that the actual result will be in the 'package' subdirectory here.
:type scratch_dir: str
:param scratch_dir: an existing (writable) directory for temporary files
:type manifest_path: str
:param manifest_path: path to package.json of an NPM project with the source to pack
:type osutils: aws_lambda_builders.workflows.nodejs_npm.utils.OSUtils
:param osutils: An instance of OS Utilities for file manipulation
:type subprocess_npm: aws_lambda_builders.workflows.nodejs_npm.npm.SubprocessNpm
:param subprocess_npm: An instance of the NPM process wrapper
"""
super(NodejsNpmPackAction, self).__init__()
self.artifacts_dir = artifacts_dir
self.manifest_path = manifest_path
self.scratch_dir = scratch_dir
self.osutils = osutils
self.subprocess_npm = subprocess_npm
def execute(self):
"""
Runs the action.
:raises lambda_builders.actions.ActionFailedError: when NPM packaging fails
"""
try:
package_path = "file:{}".format(self.osutils.abspath(self.osutils.dirname(self.manifest_path)))
LOG.debug("NODEJS packaging %s to %s", package_path, self.scratch_dir)
tarfile_name = self.subprocess_npm.run(['pack', '-q', package_path], cwd=self.scratch_dir)
LOG.debug("NODEJS packed to %s", tarfile_name)
tarfile_path = self.osutils.joinpath(self.scratch_dir, tarfile_name)
LOG.debug("NODEJS extracting to %s", self.artifacts_dir)
self.osutils.extract_tarfile(tarfile_path, self.artifacts_dir)
except NpmExecutionError as ex:
raise ActionFailedError(str(ex))
class NodejsNpmInstallAction(BaseAction):
"""
A Lambda Builder Action that installs NPM project dependencies
"""
NAME = 'NpmInstall'
DESCRIPTION = "Installing dependencies from NPM"
PURPOSE = Purpose.RESOLVE_DEPENDENCIES
def __init__(self, artifacts_dir, subprocess_npm):
"""
:type artifacts_dir: str
:param artifacts_dir: an existing (writable) directory with project source files.
Dependencies will be installed in this directory.
:type subprocess_npm: aws_lambda_builders.workflows.nodejs_npm.npm.SubprocessNpm
:param subprocess_npm: An instance of the NPM process wrapper
"""
super(NodejsNpmInstallAction, self).__init__()
self.artifacts_dir = artifacts_dir
self.subprocess_npm = subprocess_npm
def execute(self):
"""
Runs the action.
:raises lambda_builders.actions.ActionFailedError: when NPM execution fails
"""
try:
LOG.debug("NODEJS installing in: %s", self.artifacts_dir)
self.subprocess_npm.run(
['install', '-q', '--no-audit', '--no-save', '--production'],
cwd=self.artifacts_dir
)
except NpmExecutionError as ex:
raise ActionFailedError(str(ex))
class NodejsNpmrcCopyAction(BaseAction):
"""
A Lambda Builder Action that copies NPM config file .npmrc
"""
NAME = 'CopyNpmrc'
DESCRIPTION = "Copying configuration from .npmrc"
PURPOSE = Purpose.COPY_SOURCE
def __init__(self, artifacts_dir, source_dir, osutils):
"""
:type artifacts_dir: str
:param artifacts_dir: an existing (writable) directory with project source files.
Dependencies will be installed in this directory.
:type source_dir: str
:param source_dir: directory containing project source files.
:type osutils: aws_lambda_builders.workflows.nodejs_npm.utils.OSUtils
:param osutils: An instance of OS Utilities for file manipulation
"""
super(NodejsNpmrcCopyAction, self).__init__()
self.artifacts_dir = artifacts_dir
self.source_dir = source_dir
self.osutils = osutils
def execute(self):
"""
Runs the action.
:raises lambda_builders.actions.ActionFailedError: when .npmrc copying fails
"""
try:
npmrc_path = self.osutils.joinpath(self.source_dir, ".npmrc")
if self.osutils.file_exists(npmrc_path):
LOG.debug(".npmrc copying in: %s", self.artifacts_dir)
self.osutils.copy_file(npmrc_path, self.artifacts_dir)
except OSError as ex:
raise ActionFailedError(str(ex))
class NodejsNpmrcCleanUpAction(BaseAction):
"""
A Lambda Builder Action that cleans NPM config file .npmrc
"""
NAME = 'CleanUpNpmrc'
DESCRIPTION = "Cleans artifacts dir"
PURPOSE = Purpose.COPY_SOURCE
def __init__(self, artifacts_dir, osutils):
"""
:type artifacts_dir: str
:param artifacts_dir: an existing (writable) directory with project source files.
Dependencies will be installed in this directory.
:type osutils: aws_lambda_builders.workflows.nodejs_npm.utils.OSUtils
:param osutils: An instance of OS Utilities for file manipulation
"""
super(NodejsNpmrcCleanUpAction, self).__init__()
self.artifacts_dir = artifacts_dir
self.osutils = osutils
def execute(self):
"""
Runs the action.
:raises lambda_builders.actions.ActionFailedError: when .npmrc copying fails
"""
try:
npmrc_path = self.osutils.joinpath(self.artifacts_dir, ".npmrc")
if self.osutils.file_exists(npmrc_path):
LOG.debug(".npmrc cleanup in: %s", self.artifacts_dir)
self.osutils.remove_file(npmrc_path)
except OSError as ex:
raise ActionFailedError(str(ex))
class NodejsNpmRewriteLocalDependenciesAction(BaseAction):
"""
A Lambda Builder Action that rewrites local dependencies
"""
NAME = 'RewriteLocalDependencies'
DESCRIPTION = "Rewrites local dependencies"
PURPOSE = Purpose.RESOLVE_DEPENDENCIES
def __init__(
self,
work_dir,
original_package_dir,
scratch_dir,
npm_modules_utils,
osutils
):
super(NodejsNpmRewriteLocalDependenciesAction, self).__init__()
self.work_dir = work_dir
self.original_package_dir = original_package_dir
self.scratch_dir = scratch_dir
self.npm_modules_utils = npm_modules_utils
self.osutils = osutils
def __rewrite_local_dependencies(self, work_dir, original_package_dir):
for dependency_key in ['dependencies', 'optionalDependencies']:
for (name, module_path) in self.npm_modules_utils.get_local_dependencies(work_dir, dependency_key).items():
if module_path.startswith('file:'):
module_path = module_path[5:]
actual_path = self.osutils.joinpath(original_package_dir, module_path)
if self.osutils.is_dir(actual_path):
if self.npm_modules_utils.has_local_dependencies(actual_path):
module_path = self.npm_modules_utils.clean_copy(actual_path, delete_package_lock=True)
self.__rewrite_local_dependencies(module_path, actual_path)
actual_path = module_path
new_module_path = self.npm_modules_utils.pack_to_tar(actual_path)
else:
new_module_path = actual_path
new_module_path = 'file:{}'.format(new_module_path)
self.npm_modules_utils.update_dependency(work_dir, name, new_module_path, dependency_key)
def execute(self):
try:
self.__rewrite_local_dependencies(self.work_dir, self.original_package_dir)
except OSError as ex:
raise ActionFailedError(str(ex))