|
import json |
|
import sys |
|
import subprocess |
|
import base64 |
|
import os |
|
import shutil |
|
|
|
# pip install custom package to /tmp/ and add to path |
|
subprocess.call('pip install cookiecutter jinja2-time -t /tmp/ --no-cache-dir'.split(), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) |
|
sys.path.insert(1, '/tmp/') |
|
|
|
from cookiecutter.main import cookiecutter |
|
|
|
def lambda_handler(event, context): |
|
# serialized array of template contents. Files are encoded as base64 |
|
template_json = event['template'] |
|
# key/value map of template variables |
|
template_vars = event['variables'] |
|
|
|
# use request_id in the folder name to prevent leaking across requests (just in case) |
|
rid = context.aws_request_id |
|
basePath = os.path.join('/tmp/', rid) |
|
|
|
# deserialize template contents |
|
template_dir = recreate_template_directory(template_json, basePath) |
|
|
|
|
|
# config reply directory |
|
replay_dir = os.path.join(basePath, 'cookiecutter_reply') |
|
os.makedirs(replay_dir, exist_ok=True) |
|
# custom config file |
|
configPath = os.path.join(basePath, 'cookiecutter') |
|
os.makedirs(configPath, exist_ok=True) |
|
configFile = os.path.join(configPath, 'custom-config.yaml') |
|
with open(configFile, 'w') as f: |
|
f.write('replay_dir: "{}"\ncookiecutters_dir: "{}"'.format(replay_dir,basePath)) |
|
os.environ['COOKIECUTTER_CONFIG'] = configFile |
|
|
|
# generate project using cookiecutter |
|
output_dir = cookiecutter(template_dir, extra_context=template_vars, no_input=True, output_dir=basePath) |
|
|
|
# serialize the generated project |
|
generated_project_json = serialize_project_directory(output_dir) |
|
|
|
# cleanup |
|
shutil.rmtree(template_dir) |
|
shutil.rmtree(output_dir) |
|
|
|
return generated_project_json |
|
|
|
def recreate_template_directory(template_json, basePath): |
|
tmp_dir = os.path.join(basePath, 'cookiecutter_template') |
|
os.makedirs(tmp_dir, exist_ok=True) |
|
|
|
for file_data in template_json: |
|
file_path = os.path.join(tmp_dir, file_data['path']) |
|
os.makedirs(os.path.dirname(file_path), exist_ok=True) |
|
if 'content' in file_data: |
|
with open(file_path, 'wb') as f: |
|
f.write(base64.b64decode(file_data['content'])) |
|
|
|
return tmp_dir |
|
|
|
def serialize_project_directory(directory): |
|
result = [] |
|
for root, dirs, files in os.walk(directory): |
|
for file in files: |
|
file_path = os.path.join(root, file) |
|
with open(file_path, 'rb') as f: |
|
result.append({ |
|
'path': os.path.relpath(file_path, directory), |
|
'content': base64.b64encode(f.read()).decode(), |
|
'type': 'file' |
|
}) |
|
for dir in dirs: |
|
dir_path = os.path.join(root, dir) |
|
result.append({ |
|
'path': os.path.relpath(dir_path, directory), |
|
'type': 'folder' |
|
}) |
|
return result |
|
|