-
Notifications
You must be signed in to change notification settings - Fork 1
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
redockerize and deproxify #58
base: develop
Are you sure you want to change the base?
Changes from all commits
45e0a3f
4a27342
db6befc
cd1fdbe
ea08831
db63f6f
50e350c
8c43343
fe957db
d0b59f9
5fd98de
53c658b
e69f522
5bb82f4
e723a4c
a9cd3ef
aa299e3
8b0b458
a574ccd
05a9ca5
8f0089c
975fdb7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
FROM python:3.9 | ||
|
||
WORKDIR /usr/src/app/backend | ||
COPY requirements.in . | ||
RUN pip install -U pip pip-tools | ||
|
||
CMD pip-compile |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -191,110 +191,23 @@ def make_access_db_command(psql_cmd): | |
) | ||
|
||
|
||
def merge_json(target, source): | ||
for key, value in source.items(): | ||
if value is None: | ||
del target[key] | ||
elif key in target and isinstance(target[key], dict) and \ | ||
isinstance(source[key], dict): | ||
merge_json(target[key], source[key]) | ||
else: | ||
target[key] = value | ||
return target | ||
|
||
|
||
def activate_frontend(): | ||
framework = '{{cookiecutter.frontend}}' | ||
os.rename('package.{{cookiecutter.frontend}}.json', 'package.json') | ||
|
||
if framework == 'backbone': | ||
os.rename('frontend.backbone', 'frontend') | ||
shutil.move(op.join('frontend', 'proxy.json'), 'proxy.json') | ||
override_json('package') | ||
elif framework == 'angular': | ||
project_name = '{{cookiecutter.slug}}'.replace('_', '-') | ||
Command( | ||
'Install dependencies', | ||
['yarn', 'install', '--ignore-scripts'] | ||
)() | ||
Command( | ||
'Creating project', | ||
['yarn', 'ng', 'new', project_name, '--prefix={{cookiecutter.app_prefix}}', | ||
'--ssr', | ||
'--skip-git=true', | ||
'--skip-install=true', | ||
'--package-manager=yarn', | ||
'--style=scss', | ||
'--routing=true'] | ||
)() | ||
shutil.copytree('frontend.angular', project_name, dirs_exist_ok=True) | ||
os.rename(project_name, 'frontend') | ||
shutil.move(op.join('frontend', 'proxy.conf.json'), 'proxy.conf.json') | ||
override_json('package') | ||
Command( | ||
'Install frontend dependencies using Yarn', | ||
['yarn'], | ||
cwd="frontend" | ||
)() | ||
# Remove favicon.ico | ||
os.remove(os.path.join('frontend', 'src', 'favicon.ico')) | ||
# Remove editorconfig | ||
os.remove(os.path.join('frontend', '.editorconfig')) | ||
Command( | ||
'ng add @angular/localize', | ||
['yarn', 'ng', 'add', '@angular/localize', '--skip-confirmation'], | ||
cwd="frontend" | ||
)() | ||
Comment on lines
-234
to
-247
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This part is implemented in the |
||
|
||
override_json('angular') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This line is retained, but appears as deleted in the current diff because I outcommented it in debugging. |
||
Command( | ||
'Creating localizations', | ||
['yarn', 'i18n'], | ||
cwd="frontend" | ||
)() | ||
Comment on lines
-250
to
-254
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This part is implemented in the |
||
for lang in '{{cookiecutter.localizations}}'.split(','): | ||
[code, lang_name] = lang.split(':') | ||
with open(f'frontend/locale/messages.xlf', 'r') as file: | ||
messages = file.read() | ||
if code != '{{cookiecutter.default_localization}}': | ||
with open(f'frontend/locale/messages.{code}.xlf', 'w') as file: | ||
# add the target-language attribute after the source-language attribute | ||
targeted = re.sub(r'(source-language="[^"]+"[^>]*)', f'\\g<1> target-language="{code}"', messages) | ||
try: | ||
with open(f'frontend/locale/messages.{code}.json', 'r') as pretranslated: | ||
translations = json.load(pretranslated) | ||
for key, value in translations.items(): | ||
targeted = targeted.replace(f'<source>{key}</source>', f'<source>{key}</source>\n <target state="translated">{value}</target>') | ||
os.remove(f'frontend/locale/messages.{code}.json') | ||
except FileNotFoundError: | ||
pass | ||
file.write(targeted) | ||
Comment on lines
-255
to
-271
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This part is retained, but currently appears deleted because I outcommented it. |
||
if '{{cookiecutter.frontend_port}}' != '4200': | ||
Command( | ||
'Set frontend port', | ||
['yarn', 'ng', 'config', "projects.{{cookiecutter.slug | replace('_', '-')}}.architect.serve.options.port", '{{cookiecutter.frontend_port}}'], | ||
cwd="frontend" | ||
)() | ||
Comment on lines
-272
to
-277
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I plan to just drop this. Frontend port customization should no longer be necessary with the finished Docker setup. |
||
else: | ||
print('Unknown framework {{cookiecutter.frontend}} specified!') | ||
# remove other frameworks | ||
for path in glob.glob("frontend.*"): | ||
shutil.rmtree(path) | ||
for path in glob.glob("package.*.json"): | ||
os.remove(path) | ||
|
||
|
||
def override_json(filename): | ||
if os.path.isfile(f'frontend/{filename}.overwrite.json'): | ||
print(f'Overriding {filename}.json') | ||
with open(f'frontend/{filename}.overwrite.json', 'r') as file: | ||
overwrite = json.load(file) | ||
with open(f'frontend/{filename}.json', 'r') as file: | ||
data = json.load(file) | ||
with open(f'frontend/{filename}.json', 'w') as file: | ||
merge_json(data, overwrite) | ||
json.dump(data, file, indent=4) | ||
os.remove(f'frontend/{filename}.overwrite.json') | ||
os.remove(op.join('frontend', 'Dockerfile-postgenerate')) | ||
shutil.rmtree(op.join('frontend', 'bootstrap')) | ||
|
||
|
||
install_pip_tools = Command( | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
services: | ||
backend: | ||
build: | ||
context: ./backend | ||
dockerfile: Dockerfile-postgenerate | ||
volumes: | ||
- ./backend:/usr/src/app/backend | ||
frontend: | ||
build: | ||
context: ./frontend.{{cookiecutter.frontend}} | ||
dockerfile: Dockerfile-postgenerate | ||
volumes: | ||
- ./frontend:/usr/src/app/frontend | ||
- frnomo:/usr/src/app/frontend/node_modules | ||
|
||
volumes: | ||
frnomo: |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
FROM node:18 AS bootstrap-1 | ||
|
||
WORKDIR /usr/src/app | ||
RUN yarn init -yp && \ | ||
yarn add "@angular/cli@17" && \ | ||
yarn ng new {{cookiecutter.npm_slug}} \ | ||
--prefix={{cookiecutter.app_prefix}} \ | ||
--ssr \ | ||
--skip-git=true \ | ||
--skip-install=true \ | ||
--package-manager=yarn \ | ||
--style=scss \ | ||
--routing=true | ||
|
||
WORKDIR /usr/src/app/{{cookiecutter.npm_slug}} | ||
COPY . . | ||
|
||
FROM python:3.9 AS bootstrap-2 | ||
|
||
WORKDIR /usr/src/app | ||
COPY --from=bootstrap-1 \ | ||
/usr/src/app/{{cookiecutter.npm_slug}} frontend/ | ||
|
||
WORKDIR /usr/src/app/frontend | ||
RUN python bootstrap/override_json.py package | ||
|
||
FROM node:18 AS bootstrap-3 | ||
|
||
WORKDIR /usr/src/app/frontend | ||
RUN rm src/favicon.ico .editorconfig && \ | ||
yarn && \ | ||
yarn ng add @angular/localize --skip-confirmation | ||
|
||
FROM python:3.9 AS bootstrap-4 | ||
|
||
WORKDIR /usr/src/app/frontend | ||
RUN python bootstrap/override_json.py angular | ||
|
||
FROM node:18 AS bootstrap-5 | ||
|
||
WORKDIR /usr/src/app/frontend | ||
RUN yarn ng extract-i18n --output-path locale | ||
|
||
FROM python:3.9 AS bootstrap-6 | ||
|
||
WORKDIR /usr/src/app/frontend | ||
RUN python bootstrap/finish_localizations.py |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import re | ||
import json | ||
import os | ||
|
||
|
||
def main(): | ||
for lang in '{{cookiecutter.localizations}}'.split(','): | ||
[code, lang_name] = lang.split(':') | ||
with open(f'locale/messages.xlf', 'r') as file: | ||
messages = file.read() | ||
if code != '{{cookiecutter.default_localization}}': | ||
with open(f'locale/messages.{code}.xlf', 'w') as file: | ||
# add the target-language attribute after the source-language attribute | ||
targeted = re.sub(r'(source-language="[^"]+"[^>]*)', f'\\g<1> target-language="{code}"', messages) | ||
try: | ||
with open(f'locale/messages.{code}.json', 'r') as pretranslated: | ||
translations = json.load(pretranslated) | ||
for key, value in translations.items(): | ||
targeted = targeted.replace(f'<source>{key}</source>', f'<source>{key}</source>\n <target state="translated">{value}</target>') | ||
os.remove(f'locale/messages.{code}.json') | ||
except FileNotFoundError: | ||
pass | ||
file.write(targeted) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import os | ||
import sys | ||
|
||
|
||
def merge_json(target, source): | ||
for key, value in source.items(): | ||
if value is None: | ||
del target[key] | ||
elif key in target and isinstance(target[key], dict) and \ | ||
isinstance(source[key], dict): | ||
merge_json(target[key], source[key]) | ||
else: | ||
target[key] = value | ||
return target | ||
|
||
|
||
def override_json(filename): | ||
if os.path.isfile(f'{filename}.overwrite.json'): | ||
print(f'Overriding {filename}.json') | ||
with open(f'{filename}.overwrite.json', 'r') as file: | ||
overwrite = json.load(file) | ||
with open(f'{filename}.json', 'r') as file: | ||
data = json.load(file) | ||
with open(f'{filename}.json', 'w') as file: | ||
merge_json(data, overwrite) | ||
json.dump(data, file, indent=4) | ||
os.remove(f'{filename}.overwrite.json') | ||
|
||
|
||
if __name__ == '__main__': | ||
override_json(sys.argv[1]) |
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.
Some, but not all, of this logic is or will be restored via the
bootstrap_subprojects
command, which relies ondocker-compose
.