mirror of
https://gh.wpcy.net/https://github.com/WeblateOrg/weblate.git
synced 2026-04-26 06:14:35 +08:00
* new Component.file_format_params field and format_params helper * new labelled_multiwidget template * only display applicable fields with JS * add params for xml and yaml formats * use file_formar_params to setup serialization * use file format params to load bilingual update args * migrating from addons to file_format_params * pass file_format_params parameter to TranslationFormat.load for parsing customization * only relevant file format params are stored in component * comma typo fix * not using direct foreign key assignment * only create scoped addons in v5.5 and on * refactor: update file format handling and migration logic for addons * refactor: remove unused addons and update migration logic for file format parameters * adjust addon tests * use uv run in run migrate * minor test fixes * remove unused forms * new list_file_format_params * update documentation * added support for XML file format params * documentation update * remove store_post_load signal and triggers * improve test coverage * fix migration errors * use rst helper function in list_file_format_params * documentation fixes * fix mypy errors * update store config with file_format_params * additional mypy ignore * Add missing whitespace Co-authored-by: Benjamin Alan Jamie <benjamin@weblate.org> Co-authored-by: Michal Čihař <michal@cihar.com>
187 lines
6.7 KiB
Bash
Executable file
187 lines
6.7 KiB
Bash
Executable file
#!/bin/sh
|
|
|
|
# Copyright © Michal Čihař <michal@weblate.org>
|
|
#
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
# Migrations test executor
|
|
|
|
. ci/lib.sh
|
|
|
|
if [ -n "$1" ]; then
|
|
TAG="weblate-$1"
|
|
else
|
|
echo "Missing version to migrate from!"
|
|
exit 1
|
|
fi
|
|
|
|
HEAD_COMMIT=$(git rev-parse HEAD)
|
|
|
|
# Copy the current file to survive checkout
|
|
cp ci/migrate-override.txt /tmp/migrate-override.txt
|
|
|
|
print_step "Testing migration from $TAG on $CI_DATABASE..."
|
|
cleanup_database
|
|
check
|
|
if ! git fetch --depth 1 origin tag "$TAG"; then
|
|
git remote add upstream https://github.com/WeblateOrg/weblate.git
|
|
git fetch --depth 1 upstream tag "$TAG"
|
|
fi
|
|
check
|
|
git checkout "$TAG"
|
|
check
|
|
# Use clean virtualenv for each version, this avoids problems when trying to downgrade from current versions
|
|
uv venv --python python3.11 ".venv-$TAG"
|
|
check
|
|
# shellcheck source=/dev/null
|
|
. ".venv-$TAG/bin/activate"
|
|
# Install matching Weblate package
|
|
# - Need to keep "ci" as Weblate 5.8 and older have the dependency separately
|
|
# - Force PyGobject 3.52 to be compatible with girepository-2.0
|
|
uv pip install --override /tmp/migrate-override.txt -e ".[all,ci,mysql]"
|
|
check
|
|
echo "DATABASES['default']['HOST'] = '$CI_DB_HOST'" >> weblate/settings_test.py
|
|
check
|
|
if [ -n "$CI_DB_PASSWORD" ]; then
|
|
echo "DATABASES['default']['PASSWORD'] = '$CI_DB_PASSWORD'" >> weblate/settings_test.py
|
|
check
|
|
fi
|
|
if [ -n "$CI_DB_PORT" ]; then
|
|
echo "DATABASES['default']['PORT'] = '$CI_DB_PORT'" >> weblate/settings_test.py
|
|
check
|
|
fi
|
|
./manage.py migrate
|
|
check
|
|
|
|
# Delete automatically created languages to be able to load fixture
|
|
./manage.py shell -c 'from weblate.lang.models import Language; Language.objects.all().delete()'
|
|
check
|
|
|
|
# Load basic project fixture from the older version
|
|
./manage.py loaddata simple-project.json
|
|
check
|
|
|
|
# Force creating project groups
|
|
./manage.py shell -c 'from weblate.trans.models import Project; [project.save() for project in Project.objects.iterator()]'
|
|
check
|
|
# Enable suggestion voting
|
|
./manage.py shell -c 'from weblate.trans.models import Component; Component.objects.all().update(suggestion_voting=True, suggestion_autoaccept=2)'
|
|
check
|
|
# Add suggestions
|
|
./manage.py add_suggestions test test cs weblate/trans/tests/data/cs.po
|
|
check
|
|
# Add vote for suggestion
|
|
./manage.py shell -c 'from weblate.trans.models import Vote, Suggestion; s = Suggestion.objects.all()[0]; vote = Vote(suggestion=s, user=s.user); vote.value = 1; vote.positive = True; vote.save()'
|
|
check
|
|
# Add a global metric
|
|
./manage.py shell -c 'from weblate.metrics.models import METRIC_ORDER, Metric; Metric.objects.create(scope=Metric.SCOPE_GLOBAL, data=[1] * len(METRIC_ORDER), relation=0, changes=1)'
|
|
check
|
|
# Load translation memory
|
|
./manage.py import_memory ./weblate/trans/tests/data/memory.json
|
|
check
|
|
# Create huge translation memory entry
|
|
./manage.py shell -c 'from weblate.memory.models import Memory; from weblate.lang.models import Language; Memory.objects.create(source_language=Language.objects.get(code="en"), target_language=Language.objects.get(code="cs"), source="source"*1000, target="target"*1000, origin="origin"*1000)'
|
|
check
|
|
|
|
# Add a pending unit
|
|
semver_compare "$1" "<" "5.12"
|
|
pending_migration_test=$?
|
|
if [ "$pending_migration_test" -eq 0 ]; then
|
|
./manage.py shell << EOF
|
|
from django.contrib.auth import get_user_model
|
|
from weblate.trans.models import Unit, Change
|
|
from weblate.utils.state import STATE_TRANSLATED
|
|
User = get_user_model()
|
|
user = User.objects.create(username="migratetest")
|
|
unit = Unit.objects.all()[0]
|
|
unit.target = "Test Target"
|
|
unit.explanation = "Test Explanation"
|
|
unit.state = STATE_TRANSLATED
|
|
unit.save()
|
|
Change.objects.create(translation=unit.translation, user=user, action=1, unit=unit, target=unit.target)
|
|
unit.pending = True
|
|
unit.save()
|
|
EOF
|
|
check
|
|
fi
|
|
|
|
semver_compare "$1" ">" "5.5"
|
|
addon_scopes=$?
|
|
# Create addons with different scopes
|
|
semver_compare "$1" "<" "5.12"
|
|
file_format_params=$?
|
|
|
|
if [ "$addon_scopes" -eq 0 ] && [ "$file_format_params" -eq 0 ]; then
|
|
./manage.py shell << EOF
|
|
from weblate.addons.models import Addon
|
|
from weblate.trans.models import Component, Project
|
|
Addon.objects.bulk_create([
|
|
Addon(name="weblate.gettext.msgmerge", configuration={"previous": False}),
|
|
Addon(project_id=1, name="weblate.gettext.customize", configuration={"width": -1}),
|
|
Addon(component_id=1, name="weblate.gettext.msgmerge", configuration={"no_location": True}),
|
|
Addon(name="weblate.yaml.customize", configuration={"line_break": "dos"}),
|
|
Addon(project_id=1, name="weblate.yaml.customize", configuration={"indent": 2}),
|
|
Addon(component_id=1, name="weblate.json.customize", configuration={"style": "spaces"}),
|
|
])
|
|
EOF
|
|
check
|
|
fi
|
|
|
|
git reset --hard
|
|
check
|
|
git checkout "$HEAD_COMMIT"
|
|
check
|
|
# Use CI environment
|
|
deactivate
|
|
check
|
|
run_coverage ./manage.py migrate
|
|
check
|
|
# Check migrated vote exists
|
|
uv run --all-extras ./manage.py shell -c 'from weblate.trans.models import Vote; Vote.objects.get(value=1)'
|
|
check
|
|
|
|
# Check migrated pending unit
|
|
if [ "$pending_migration_test" -eq 0 ]; then
|
|
uv run --all-extras ./manage.py shell << EOF
|
|
from weblate.trans.models import PendingUnitChange
|
|
|
|
change = PendingUnitChange.objects.get()
|
|
unit = change.unit
|
|
|
|
errors = []
|
|
if change.target != unit.target:
|
|
errors.append(f"Target mismatch: '{change.target}' != '{unit.target}'")
|
|
if change.explanation != unit.explanation:
|
|
errors.append(f"Explanation mismatch: '{change.explanation}' != '{unit.explanation}'")
|
|
if change.state != unit.state:
|
|
errors.append(f"State mismatch: {change.state} != {unit.state}")
|
|
# The migration uses get_last_content_change to get author
|
|
author = unit.get_last_content_change()[0]
|
|
if change.author != author:
|
|
errors.append(f"Author mismatch: {change.author} != {author}")
|
|
if change.source_unit_explanation != unit.source_unit.explanation:
|
|
errors.append(f"Source unit explanation mismatch: '{change.source_unit_explanation}' != '{unit.source_unit.explanation}'")
|
|
assert not errors, "\n".join(errors)
|
|
EOF
|
|
check
|
|
fi
|
|
|
|
if [ "$addon_scopes" -eq 0 ] && [ "$file_format_params" -eq 0 ]; then
|
|
# check that relevant addon parameters have been migrated to file_format_params
|
|
uv run --all-extras ./manage.py shell << EOF
|
|
from weblate.addons.models import Addon
|
|
from weblate.trans.models import Component
|
|
file_format_params = Component.objects.get(pk=1).file_format_params
|
|
# check site wide params are migrated
|
|
assert 'yaml_line_break' not in file_format_params
|
|
assert 'yaml_indent' not in file_format_params
|
|
assert 'json_indent_style' not in file_format_params
|
|
assert file_format_params['po_line_wrap'] == -1
|
|
assert file_format_params['po_keep_previous'] is False
|
|
assert file_format_params['po_no_location'] is True
|
|
assert not Addon.objects.filter(name="weblate.json.customize").exists()
|
|
assert not Addon.objects.filter(name="weblate.gettext.customize").exists()
|
|
assert Addon.objects.filter(name="weblate.gettext.msgmerge").exists()
|
|
EOF
|
|
check
|
|
fi
|