Work in Progress
This commit is contained in:
parent
d64140487f
commit
e81e22e91b
7
.gitignore
vendored
7
.gitignore
vendored
|
|
@ -1,2 +1,7 @@
|
|||
env
|
||||
__pycache__
|
||||
__pycache__
|
||||
.tox
|
||||
.coverage
|
||||
.pytest_cache
|
||||
/tests/output/*
|
||||
log/
|
||||
|
|
|
|||
61
.gitlab-ci.yml
Normal file
61
.gitlab-ci.yml
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
---
|
||||
image: python
|
||||
|
||||
cache:
|
||||
key: one-key-to-rule-them-all
|
||||
paths:
|
||||
- .venv
|
||||
|
||||
stages:
|
||||
- prepare
|
||||
- linting
|
||||
- tests
|
||||
|
||||
|
||||
install_tools:
|
||||
stage: prepare
|
||||
script:
|
||||
- python -m venv .venv
|
||||
- source .venv/bin/activate
|
||||
- pip install poetry
|
||||
- poetry --version
|
||||
- poetry install -v
|
||||
- echo $PATH
|
||||
- echo $PYTHONPATH
|
||||
|
||||
black:
|
||||
stage: linting
|
||||
script:
|
||||
- source .venv/bin/activate
|
||||
- pip install black
|
||||
- black --version
|
||||
- black --check .
|
||||
|
||||
pylint:
|
||||
stage: linting
|
||||
script:
|
||||
- source .venv/bin/activate
|
||||
- pylint --version
|
||||
# - pylint --disable fixme ociedoo
|
||||
# - pylint --disable fixme tests
|
||||
|
||||
pytest:
|
||||
stage: tests
|
||||
image: python
|
||||
cache: {}
|
||||
script:
|
||||
- pip install poetry
|
||||
- poetry --version
|
||||
- poetry install -v
|
||||
- poetry run pytest --version
|
||||
- poetry run pytest --cov odoo_openupgrade_wizard -v
|
||||
|
||||
tox:
|
||||
stage: tests
|
||||
image: themattrix/tox
|
||||
cache: {}
|
||||
script:
|
||||
- pip install poetry tox
|
||||
- tox --version
|
||||
- poetry --version
|
||||
- tox
|
||||
36
.pre-commit-config.yaml
Normal file
36
.pre-commit-config.yaml
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
---
|
||||
# See https://pre-commit.com for more information
|
||||
# See https://pre-commit.com/hooks.html for more hooks
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v3.4.0
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
- id: end-of-file-fixer
|
||||
- id: debug-statements
|
||||
- id: mixed-line-ending
|
||||
- id: name-tests-test
|
||||
- id: check-yaml
|
||||
- id: check-json
|
||||
- id: check-toml
|
||||
- id: check-added-large-files
|
||||
args: ['--maxkb=2048']
|
||||
- id: check-docstring-first
|
||||
- id: check-merge-conflict
|
||||
- id: check-symlinks
|
||||
- repo: https://github.com/pre-commit/mirrors-isort
|
||||
rev: v5.7.0
|
||||
hooks:
|
||||
- id: isort
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 20.8b1
|
||||
hooks:
|
||||
- id: black
|
||||
- repo: https://github.com/PyCQA/flake8
|
||||
rev: "3.9.2"
|
||||
hooks:
|
||||
- id: flake8
|
||||
# - repo: https://gitlab.com/smop/pre-commit-hooks
|
||||
# rev: v1.0.0
|
||||
# hooks:
|
||||
# - id: check-gitlab-ci
|
||||
81
README.md
81
README.md
|
|
@ -1,9 +1,82 @@
|
|||
# odoo-openupgrade-wizard
|
||||
|
||||
Odoo Openupgrade Wizard is a tool that helps developpers to make major
|
||||
upgrade of Odoo Community Edition. (formely OpenERP).
|
||||
It works with Openupgrade OCA tools. (https://github.com/oca/openupgrade)
|
||||
|
||||
this tool is useful for complex migrations:
|
||||
- skip several versions
|
||||
- complex custom code
|
||||
|
||||
It will create a migration environment (with all the code available)
|
||||
and provides helpers to run (and replay) migrations until it works.
|
||||
|
||||
## Commands
|
||||
|
||||
### ``odoo-openupgrade-wizard init``
|
||||
|
||||
```
|
||||
odoo-openupgrade-wizard init\
|
||||
--initial-version=10.0\
|
||||
--final-version=12.0\
|
||||
--extra-repository=OCA/web,OCA/server-tools
|
||||
```
|
||||
|
||||
Initialize a folder to make a migration from a 10.0 and a 12.0 database.
|
||||
This will generate the following structure :
|
||||
|
||||
```
|
||||
config.yml
|
||||
log/
|
||||
2022_03_25__23_12_41__init.log
|
||||
...
|
||||
repos/
|
||||
10.0.yml
|
||||
11.0.yml
|
||||
12.0.yml
|
||||
requirements/
|
||||
10.0_requirements.txt
|
||||
11.0_requirements.txt
|
||||
12.0_requirements.txt
|
||||
scripts/
|
||||
step_1__update__10.0/
|
||||
pre-migration.sql
|
||||
post-migration.py
|
||||
step_2__upgrade__11.0/
|
||||
pre-migration.sql
|
||||
post-migration.py
|
||||
step_2__upgrade__12.0/
|
||||
pre-migration.sql
|
||||
post-migration.py
|
||||
step_4__update__12.0/
|
||||
pre-migration.sql
|
||||
post-migration.py
|
||||
src/
|
||||
```
|
||||
|
||||
* ``log/`` will contains all the log of the ``odoo-openupgrade-wizard``
|
||||
and the logs of the odoo instance that will be executed.
|
||||
|
||||
|
||||
* ``repos/`` contains a file per version of odoo, that enumerates the
|
||||
list of the repositories to use to run each odoo instance.
|
||||
The syntax should respect the ``gitaggregate`` command.
|
||||
(See : https://pypi.org/project/git-aggregator/)
|
||||
Repo files are pre-generated. You can update them with your custom settings.
|
||||
(custom branches, extra PRs, git shallow options, etc...)
|
||||
|
||||
* ``requirements/`` contains a file per version of odoo, that enumerates the
|
||||
list of extra python librairies required to run each odoo instance.
|
||||
The syntax should respect the ``pip install -r`` command.
|
||||
(See : https://pip.pypa.io/en/stable/reference/requirements-file-format/)
|
||||
|
||||
* ``scripts`` contains a folder per migration step. In each step folder:
|
||||
- ``pre-migration.sql`` can contains extra SQL queries you want to execute
|
||||
before beginning the step.
|
||||
- ``post-migration.py`` can contains extra python command to execute
|
||||
after the execution of the step. (the orm will be available)
|
||||
|
||||
# TODO
|
||||
|
||||
* restore ``# @click.version_option(version=ociedoo.__version__)`` when we know how
|
||||
to avoid to duplicate information in ``pyproject.toml`` file and ``__init__.py`` file.
|
||||
|
||||
* move jinja2 templates files into dedicated files.
|
||||
* with coop it easy :
|
||||
- short_help of group decorator ? seems useless...
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
from pathlib import Path
|
||||
|
||||
from single_source import get_version
|
||||
|
||||
__version__ = get_version(__name__, Path(__file__).parent.parent)
|
||||
|
|
@ -1,47 +1,45 @@
|
|||
import datetime
|
||||
# import os
|
||||
# import signal
|
||||
# import subprocess
|
||||
# import time
|
||||
from pathlib import Path
|
||||
from plumbum.cmd import mkdir
|
||||
from jinja2 import Template
|
||||
|
||||
import time
|
||||
import click
|
||||
import yaml
|
||||
from loguru import logger
|
||||
from plumbum.cmd import mkdir
|
||||
|
||||
import odoo_openupgrade_wizard
|
||||
from odoo_openupgrade_wizard.configuration_version_dependant import (
|
||||
_get_odoo_version_str_list,
|
||||
_get_odoo_versions,
|
||||
)
|
||||
from odoo_openupgrade_wizard.templates import (
|
||||
_CONFIG_YML_TEMPLATE,
|
||||
_REPO_YML_TEMPLATE,
|
||||
_REQUIREMENTS_TXT_TEMPLATE,
|
||||
_PRE_MIGRATION_SQL_TEMPLATE,
|
||||
_POST_MIGRATION_PY_TEMPLATE,
|
||||
)
|
||||
from odoo_openupgrade_wizard.cli_build import build
|
||||
from odoo_openupgrade_wizard.cli_init import init
|
||||
|
||||
# ############################################################################
|
||||
# main()
|
||||
# ############################################################################
|
||||
@click.group(
|
||||
short_help="Provide a wizard to simplify the use of OpenUpgrade.",
|
||||
|
||||
@click.group()
|
||||
@click.version_option(version=odoo_openupgrade_wizard.__version__)
|
||||
@click.option(
|
||||
"-ef",
|
||||
"--env-folder",
|
||||
default="./",
|
||||
type=click.Path(
|
||||
exists=True,
|
||||
dir_okay=True,
|
||||
file_okay=False,
|
||||
writable=True,
|
||||
resolve_path=True,
|
||||
),
|
||||
help="Folder that will contains all the configuration of the wizard"
|
||||
" and all the Odoo code required to make the migrations. Let empty to"
|
||||
" use current folder (./).",
|
||||
)
|
||||
@click.option(
|
||||
"-fs",
|
||||
"--filestore-folder",
|
||||
type=click.Path(dir_okay=True, file_okay=False, resolve_path=True),
|
||||
help="Folder that contains the Odoo filestore of the database(s)"
|
||||
" to migrate. Let empty to use the subfolder 'filestore' of the"
|
||||
" environment folder.",
|
||||
)
|
||||
|
||||
@click.option("-ef", "--env-folder", required=True,
|
||||
type=click.Path(exists=True, dir_okay=True, file_okay=False, writable=True,
|
||||
resolve_path=True))
|
||||
@click.option("-fs", "--filestore-folder",
|
||||
type=click.Path(dir_okay=True, file_okay=False,
|
||||
resolve_path=True))
|
||||
|
||||
@click.pass_context
|
||||
def main(ctx, env_folder, filestore_folder):
|
||||
"""
|
||||
TODO
|
||||
Provides a command set to perform odoo Community Edition migrations.
|
||||
"""
|
||||
date_begin = datetime.datetime.now()
|
||||
logger.debug("Beginning script '%s' ..." % (ctx.invoked_subcommand))
|
||||
|
|
@ -72,8 +70,11 @@ def main(ctx, env_folder, filestore_folder):
|
|||
mkdir(["--mode", "777", log_folder_path])
|
||||
|
||||
# Create log file
|
||||
log_file_path = log_folder_path / Path("{}__{}.log".format(
|
||||
date_begin.strftime("%Y_%m_%d__%H_%M_%S"), ctx.invoked_subcommand))
|
||||
log_file_path = log_folder_path / Path(
|
||||
"{}__{}.log".format(
|
||||
date_begin.strftime("%Y_%m_%d__%H_%M_%S"), ctx.invoked_subcommand
|
||||
)
|
||||
)
|
||||
logger.add(log_file_path)
|
||||
ctx.obj["env_folder_path"] = env_folder_path
|
||||
ctx.obj["src_folder_path"] = src_folder_path
|
||||
|
|
@ -82,133 +83,18 @@ def main(ctx, env_folder, filestore_folder):
|
|||
ctx.obj["filestore_folder_path"] = filestore_folder_path
|
||||
ctx.obj["config_file_path"] = config_file_path
|
||||
ctx.obj["requirement_folder_path"] = requirement_folder_path
|
||||
# logger.info(ctx.obj)
|
||||
|
||||
if config_file_path.exists():
|
||||
with open(config_file_path) as file:
|
||||
config = yaml.safe_load(file)
|
||||
for step in config["migration_steps"]:
|
||||
step["local_path"] = src_folder_path / Path(
|
||||
"env_%s" % step["version"]
|
||||
)
|
||||
ctx.obj["config"] = config
|
||||
elif ctx.invoked_subcommand != "init":
|
||||
raise
|
||||
|
||||
|
||||
# ############################################################################
|
||||
# init()
|
||||
# ############################################################################
|
||||
@main.command(
|
||||
short_help="Initialize OpenUpgrade Wizard Environment.",
|
||||
)
|
||||
@click.option("-iv", "--initial-version", required=True, prompt=True,
|
||||
type=click.Choice(_get_odoo_version_str_list("initial")))
|
||||
@click.option("-fv", "--final-version", required=True, prompt=True,
|
||||
type=click.Choice(_get_odoo_version_str_list("final")))
|
||||
@click.option("-er", "--extra-repository", "extra_repository_list",
|
||||
# TODO, add a callback to check the quality of the argument
|
||||
help="Coma separated extra repositories to use in the odoo environment."
|
||||
"Ex: 'OCA/web,OCA/server-tools,GRAP/grap-odoo-incubator'")
|
||||
@click.pass_context
|
||||
def init(ctx, initial_version, final_version, extra_repository_list):
|
||||
"""
|
||||
TODO
|
||||
"""
|
||||
# 1. create src directory if not exists
|
||||
if not ctx.obj["src_folder_path"].exists():
|
||||
logger.info("Creating folder '%s' ..." % (ctx.obj["src_folder_path"]))
|
||||
mkdir(["--mode", "777", ctx.obj["src_folder_path"]])
|
||||
|
||||
# 2. create filestore directory if not exists
|
||||
if not ctx.obj["filestore_folder_path"].exists():
|
||||
logger.info("Creating folder '%s' ..." % (ctx.obj["filestore_folder_path"]))
|
||||
mkdir(["--mode", "777", ctx.obj["filestore_folder_path"]])
|
||||
|
||||
# 3. Create main config file
|
||||
series = _get_odoo_versions(float(initial_version), float(final_version))
|
||||
|
||||
# Create initial first step
|
||||
steps = [series[0].copy()]
|
||||
steps[0].update({
|
||||
"name": "step_1",
|
||||
"action": "update",
|
||||
"complete_name": "step_1__update__%s" % (steps[0]["version"]),
|
||||
})
|
||||
|
||||
# Add all upgrade steps
|
||||
count = 1
|
||||
for serie in series[1:]:
|
||||
steps.append(serie.copy())
|
||||
steps[count].update({
|
||||
"name": "step_%d" % (count+1),
|
||||
"action": "upgrade",
|
||||
"complete_name": "step_%d__upgrade__%s" % (count+1, serie["version"]),
|
||||
})
|
||||
count += 1
|
||||
|
||||
# add final update step
|
||||
steps.append(series[-1].copy())
|
||||
steps[-1].update({
|
||||
"name": "step_%d" % (count + 1),
|
||||
"action": "update",
|
||||
"complete_name": "step_%d__update__%s" % (count+1, steps[-1]["version"]),
|
||||
})
|
||||
|
||||
template = Template(_CONFIG_YML_TEMPLATE)
|
||||
output = template.render(steps=steps)
|
||||
with open(ctx.obj["config_file_path"], "w") as f:
|
||||
logger.info("Creating configuration file '%s' ..." % (ctx.obj["config_file_path"]))
|
||||
f.write(output)
|
||||
f.close()
|
||||
|
||||
distinct_versions = list(set(x["version"] for x in series))
|
||||
|
||||
# 4. Create Repo folder and files
|
||||
if not ctx.obj["repo_folder_path"].exists():
|
||||
logger.info("Creating folder '%s' ..." % (ctx.obj["repo_folder_path"]))
|
||||
mkdir([ctx.obj["repo_folder_path"]])
|
||||
|
||||
extra_repositories = extra_repository_list.split(",")
|
||||
|
||||
orgs = {x: [] for x in set([x.split("/")[0] for x in extra_repositories])}
|
||||
for extra_repository in extra_repositories:
|
||||
org, repo = extra_repository.split("/")
|
||||
orgs[org].append(repo)
|
||||
|
||||
for version in distinct_versions:
|
||||
template = Template(_REPO_YML_TEMPLATE)
|
||||
output = template.render(version=version, orgs=orgs)
|
||||
file_name =ctx.obj["repo_folder_path"] / Path("%s.yml" % (version))
|
||||
with open(file_name, "w") as f:
|
||||
logger.info("Creating Repo file '%s' ..." % (file_name))
|
||||
f.write(output)
|
||||
f.close()
|
||||
|
||||
# 5. Create Requirements folder and files
|
||||
if not ctx.obj["requirement_folder_path"].exists():
|
||||
logger.info("Creating folder '%s' ..." % (ctx.obj["requirement_folder_path"]))
|
||||
mkdir([ctx.obj["requirement_folder_path"]])
|
||||
|
||||
for serie in series:
|
||||
template = Template(_REQUIREMENTS_TXT_TEMPLATE)
|
||||
output = template.render(python_libraries=serie["python_libraries"])
|
||||
file_name =ctx.obj["requirement_folder_path"] / Path("%s_requirements.txt" % (serie["version"]))
|
||||
with open(file_name, "w") as f:
|
||||
logger.info("Creating Requirements file '%s' ..." % (file_name))
|
||||
f.write(output)
|
||||
f.close()
|
||||
|
||||
# 6. Create Scripts folder and files
|
||||
if not ctx.obj["script_folder_path"].exists():
|
||||
logger.info("Creating folder '%s' ..." % (ctx.obj["script_folder_path"]))
|
||||
mkdir([ctx.obj["script_folder_path"]])
|
||||
|
||||
for step in steps:
|
||||
step_path = ctx.obj["script_folder_path"] / step["complete_name"]
|
||||
if not step_path.exists():
|
||||
logger.info("Creating folder '%s' ..." % (step_path))
|
||||
mkdir([step_path])
|
||||
template = Template(_PRE_MIGRATION_SQL_TEMPLATE)
|
||||
output = template.render()
|
||||
file_name =step_path / Path("pre-migration.sql")
|
||||
with open(file_name, "w") as f:
|
||||
logger.info("Creating pre-migration.sql file '%s' ..." % (file_name))
|
||||
f.write(output)
|
||||
f.close()
|
||||
template = Template(_POST_MIGRATION_PY_TEMPLATE)
|
||||
output = template.render()
|
||||
file_name =step_path / Path("post-migration.py")
|
||||
with open(file_name, "w") as f:
|
||||
logger.info("Creating post-migration.py file '%s' ..." % (file_name))
|
||||
f.write(output)
|
||||
f.close()
|
||||
main.add_command(init)
|
||||
main.add_command(build)
|
||||
|
|
|
|||
28
odoo_openupgrade_wizard/cli_build.py
Normal file
28
odoo_openupgrade_wizard/cli_build.py
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
# from pathlib import Path
|
||||
|
||||
import click
|
||||
from loguru import logger
|
||||
from plumbum.cmd import mkdir
|
||||
|
||||
|
||||
@click.command()
|
||||
@click.pass_context
|
||||
def build(ctx):
|
||||
"""
|
||||
Build OpenUpgrade Wizard Environment:
|
||||
- gitaggregate all the repositories
|
||||
- build virtualenv (TODO)
|
||||
"""
|
||||
|
||||
# distinct_versions = list(set(x["version"] for x in series))
|
||||
|
||||
for step in ctx.obj["config"]["migration_steps"]:
|
||||
# 1. Create main folder for the odoo version
|
||||
if not step["local_path"].exists():
|
||||
logger.info("Creating folder '%s' ..." % (step["local_path"]))
|
||||
mkdir(["--mode", "777", step["local_path"]])
|
||||
|
||||
# # 2. gitaggregate source code
|
||||
# repo_file = ctx.obj["repo_folder_path"] / Path(
|
||||
# "%s.yml" % (step["version"])
|
||||
# )
|
||||
180
odoo_openupgrade_wizard/cli_init.py
Normal file
180
odoo_openupgrade_wizard/cli_init.py
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
from pathlib import Path
|
||||
|
||||
import click
|
||||
from jinja2 import Template
|
||||
from loguru import logger
|
||||
from plumbum.cmd import mkdir
|
||||
|
||||
from odoo_openupgrade_wizard.configuration_version_dependant import (
|
||||
_get_odoo_version_str_list,
|
||||
_get_odoo_versions,
|
||||
)
|
||||
from odoo_openupgrade_wizard.templates import (
|
||||
_CONFIG_YML_TEMPLATE,
|
||||
_POST_MIGRATION_PY_TEMPLATE,
|
||||
_PRE_MIGRATION_SQL_TEMPLATE,
|
||||
_REPO_YML_TEMPLATE,
|
||||
_REQUIREMENTS_TXT_TEMPLATE,
|
||||
)
|
||||
|
||||
|
||||
@click.command()
|
||||
@click.option(
|
||||
"-iv",
|
||||
"--initial-version",
|
||||
required=True,
|
||||
prompt=True,
|
||||
type=click.Choice(_get_odoo_version_str_list("initial")),
|
||||
)
|
||||
@click.option(
|
||||
"-fv",
|
||||
"--final-version",
|
||||
required=True,
|
||||
prompt=True,
|
||||
type=click.Choice(_get_odoo_version_str_list("final")),
|
||||
)
|
||||
@click.option(
|
||||
"-er",
|
||||
"--extra-repository",
|
||||
"extra_repository_list",
|
||||
# TODO, add a callback to check the quality of the argument
|
||||
help="Coma separated extra repositories to use in the odoo environment."
|
||||
"Ex: 'OCA/web,OCA/server-tools,GRAP/grap-odoo-incubator'",
|
||||
)
|
||||
@click.pass_context
|
||||
def init(ctx, initial_version, final_version, extra_repository_list):
|
||||
"""
|
||||
Initialize OpenUpgrade Wizard Environment based on the initial and
|
||||
the final version of Odoo you want to migrate.
|
||||
"""
|
||||
# 1. create src directory if not exists
|
||||
if not ctx.obj["src_folder_path"].exists():
|
||||
logger.info("Creating folder '%s' ..." % (ctx.obj["src_folder_path"]))
|
||||
mkdir(["--mode", "777", ctx.obj["src_folder_path"]])
|
||||
|
||||
# 2. create filestore directory if not exists
|
||||
if not ctx.obj["filestore_folder_path"].exists():
|
||||
logger.info(
|
||||
"Creating folder '%s' ..." % (ctx.obj["filestore_folder_path"])
|
||||
)
|
||||
mkdir(["--mode", "777", ctx.obj["filestore_folder_path"]])
|
||||
|
||||
# 3. Create main config file
|
||||
series = _get_odoo_versions(float(initial_version), float(final_version))
|
||||
|
||||
# Create initial first step
|
||||
steps = [series[0].copy()]
|
||||
steps[0].update(
|
||||
{
|
||||
"name": "step_1",
|
||||
"action": "update",
|
||||
"complete_name": "step_1__update__%s" % (steps[0]["version"]),
|
||||
}
|
||||
)
|
||||
|
||||
# Add all upgrade steps
|
||||
count = 1
|
||||
for serie in series[1:]:
|
||||
steps.append(serie.copy())
|
||||
steps[count].update(
|
||||
{
|
||||
"name": "step_%d" % (count + 1),
|
||||
"action": "upgrade",
|
||||
"complete_name": "step_%d__upgrade__%s"
|
||||
% (count + 1, serie["version"]),
|
||||
}
|
||||
)
|
||||
count += 1
|
||||
|
||||
# add final update step
|
||||
steps.append(series[-1].copy())
|
||||
steps[-1].update(
|
||||
{
|
||||
"name": "step_%d" % (count + 1),
|
||||
"action": "update",
|
||||
"complete_name": "step_%d__update__%s"
|
||||
% (count + 1, steps[-1]["version"]),
|
||||
}
|
||||
)
|
||||
|
||||
template = Template(_CONFIG_YML_TEMPLATE)
|
||||
output = template.render(steps=steps)
|
||||
with open(ctx.obj["config_file_path"], "w") as f:
|
||||
logger.info(
|
||||
"Creating configuration file '%s' ..."
|
||||
% (ctx.obj["config_file_path"])
|
||||
)
|
||||
f.write(output)
|
||||
f.close()
|
||||
|
||||
distinct_versions = list(set(x["version"] for x in series))
|
||||
|
||||
# 4. Create Repo folder and files
|
||||
if not ctx.obj["repo_folder_path"].exists():
|
||||
logger.info("Creating folder '%s' ..." % (ctx.obj["repo_folder_path"]))
|
||||
mkdir([ctx.obj["repo_folder_path"]])
|
||||
|
||||
extra_repositories = extra_repository_list.split(",")
|
||||
|
||||
orgs = {x: [] for x in set([x.split("/")[0] for x in extra_repositories])}
|
||||
for extra_repository in extra_repositories:
|
||||
org, repo = extra_repository.split("/")
|
||||
orgs[org].append(repo)
|
||||
|
||||
for version in distinct_versions:
|
||||
template = Template(_REPO_YML_TEMPLATE)
|
||||
output = template.render(version=version, orgs=orgs)
|
||||
file_name = ctx.obj["repo_folder_path"] / Path("%s.yml" % (version))
|
||||
with open(file_name, "w") as f:
|
||||
logger.info("Creating Repo file '%s' ..." % (file_name))
|
||||
f.write(output)
|
||||
f.close()
|
||||
|
||||
# 5. Create Requirements folder and files
|
||||
if not ctx.obj["requirement_folder_path"].exists():
|
||||
logger.info(
|
||||
"Creating folder '%s' ..." % (ctx.obj["requirement_folder_path"])
|
||||
)
|
||||
mkdir([ctx.obj["requirement_folder_path"]])
|
||||
|
||||
for serie in series:
|
||||
template = Template(_REQUIREMENTS_TXT_TEMPLATE)
|
||||
output = template.render(python_libraries=serie["python_libraries"])
|
||||
file_name = ctx.obj["requirement_folder_path"] / Path(
|
||||
"%s_requirements.txt" % (serie["version"])
|
||||
)
|
||||
with open(file_name, "w") as f:
|
||||
logger.info("Creating Requirements file '%s' ..." % (file_name))
|
||||
f.write(output)
|
||||
f.close()
|
||||
|
||||
# 6. Create Scripts folder and files
|
||||
if not ctx.obj["script_folder_path"].exists():
|
||||
logger.info(
|
||||
"Creating folder '%s' ..." % (ctx.obj["script_folder_path"])
|
||||
)
|
||||
mkdir([ctx.obj["script_folder_path"]])
|
||||
|
||||
for step in steps:
|
||||
step_path = ctx.obj["script_folder_path"] / step["complete_name"]
|
||||
if not step_path.exists():
|
||||
logger.info("Creating folder '%s' ..." % (step_path))
|
||||
mkdir([step_path])
|
||||
template = Template(_PRE_MIGRATION_SQL_TEMPLATE)
|
||||
output = template.render()
|
||||
file_name = step_path / Path("pre-migration.sql")
|
||||
with open(file_name, "w") as f:
|
||||
logger.info(
|
||||
"Creating pre-migration.sql file '%s' ..." % (file_name)
|
||||
)
|
||||
f.write(output)
|
||||
f.close()
|
||||
template = Template(_POST_MIGRATION_PY_TEMPLATE)
|
||||
output = template.render()
|
||||
file_name = step_path / Path("post-migration.py")
|
||||
with open(file_name, "w") as f:
|
||||
logger.info(
|
||||
"Creating post-migration.py file '%s' ..." % (file_name)
|
||||
)
|
||||
f.write(output)
|
||||
f.close()
|
||||
|
|
@ -2,19 +2,64 @@
|
|||
# python version is defined, based on the OCA CI.
|
||||
# https://github.com/OCA/oca-addons-repo-template/blob/master/src/.github/workflows/%7B%25%20if%20ci%20%3D%3D%20'GitHub'%20%25%7Dtest.yml%7B%25%20endif%20%25%7D.jinja
|
||||
_ODOO_SERIES = [
|
||||
{"version": 6.0, "python": "python2.7", "python_libraries": ["openupgradelib"]},
|
||||
{"version": 6.1, "python": "python2.7", "python_libraries": ["openupgradelib"]},
|
||||
{"version": 7.0, "python": "python2.7", "python_libraries": ["openupgradelib"]},
|
||||
{"version": 8.0, "python": "python2.7", "python_libraries": ["openupgradelib"]},
|
||||
{"version": 9.0, "python": "python2.7", "python_libraries": ["openupgradelib"]},
|
||||
{"version": 10.0, "python": "python2.7", "python_libraries": ["openupgradelib"]},
|
||||
{"version": 11.0, "python": "python3.5", "python_libraries": ["openupgradelib"]},
|
||||
{"version": 12.0, "python": "python3.6", "python_libraries": ["openupgradelib"]},
|
||||
{"version": 13.0, "python": "python3.6", "python_libraries": ["openupgradelib"]},
|
||||
{"version": 14.0, "python": "python3.6", "python_libraries": ["openupgradelib"]},
|
||||
{"version": 15.0, "python": "python3.8", "python_libraries": ["openupgradelib"]},
|
||||
{
|
||||
"version": 6.0,
|
||||
"python": "python2.7",
|
||||
"python_libraries": ["openupgradelib"],
|
||||
},
|
||||
{
|
||||
"version": 6.1,
|
||||
"python": "python2.7",
|
||||
"python_libraries": ["openupgradelib"],
|
||||
},
|
||||
{
|
||||
"version": 7.0,
|
||||
"python": "python2.7",
|
||||
"python_libraries": ["openupgradelib"],
|
||||
},
|
||||
{
|
||||
"version": 8.0,
|
||||
"python": "python2.7",
|
||||
"python_libraries": ["openupgradelib"],
|
||||
},
|
||||
{
|
||||
"version": 9.0,
|
||||
"python": "python2.7",
|
||||
"python_libraries": ["openupgradelib"],
|
||||
},
|
||||
{
|
||||
"version": 10.0,
|
||||
"python": "python2.7",
|
||||
"python_libraries": ["openupgradelib"],
|
||||
},
|
||||
{
|
||||
"version": 11.0,
|
||||
"python": "python3.5",
|
||||
"python_libraries": ["openupgradelib"],
|
||||
},
|
||||
{
|
||||
"version": 12.0,
|
||||
"python": "python3.6",
|
||||
"python_libraries": ["openupgradelib"],
|
||||
},
|
||||
{
|
||||
"version": 13.0,
|
||||
"python": "python3.6",
|
||||
"python_libraries": ["openupgradelib"],
|
||||
},
|
||||
{
|
||||
"version": 14.0,
|
||||
"python": "python3.6",
|
||||
"python_libraries": ["openupgradelib"],
|
||||
},
|
||||
{
|
||||
"version": 15.0,
|
||||
"python": "python3.8",
|
||||
"python_libraries": ["openupgradelib"],
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
def _get_odoo_version_str_list(mode):
|
||||
serie_list = [x["version"] for x in _ODOO_SERIES]
|
||||
if mode == "initial":
|
||||
|
|
@ -23,9 +68,10 @@ def _get_odoo_version_str_list(mode):
|
|||
serie_list = serie_list[1:]
|
||||
return [str(x) for x in serie_list]
|
||||
|
||||
|
||||
def _get_odoo_versions(initial, final):
|
||||
result = []
|
||||
for serie in _ODOO_SERIES:
|
||||
if serie["version"] >= initial and serie["version"] <= final:
|
||||
result.append(serie)
|
||||
return result
|
||||
return result
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
_CONFIG_YML_TEMPLATE = """
|
||||
migration_steps:
|
||||
_CONFIG_YML_TEMPLATE = """migration_steps:
|
||||
{% for step in steps %}
|
||||
- name: {{ step['name'] }}
|
||||
- complete_name: {{ step['complete_name'] }}
|
||||
complete_name: {{ step['complete_name'] }}
|
||||
version: {{ step['version'] }}
|
||||
action: {{ step['action'] }}
|
||||
python: {{ step['python'] }}
|
||||
|
|
@ -59,4 +58,4 @@ _PRE_MIGRATION_SQL_TEMPLATE = ""
|
|||
_POST_MIGRATION_PY_TEMPLATE = """
|
||||
def main(self, step):
|
||||
pass
|
||||
"""
|
||||
"""
|
||||
|
|
|
|||
877
poetry.lock
generated
877
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
|
|
@ -25,10 +25,11 @@ classifiers = [
|
|||
odoo-openupgrade-wizard = "odoo_openupgrade_wizard.cli:main"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.5"
|
||||
python = "^3.6"
|
||||
click = "^7.0"
|
||||
loguru = "^0.6"
|
||||
plumbum = "^1.7"
|
||||
single-source = "^0.3"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
pytest = [
|
||||
|
|
@ -59,4 +60,4 @@ line-length = 79
|
|||
|
||||
[tool.isort]
|
||||
profile = "black"
|
||||
line_length = 79
|
||||
line_length = 79
|
||||
|
|
|
|||
30
tests/cli_init_test.py
Normal file
30
tests/cli_init_test.py
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
import filecmp
|
||||
from pathlib import Path
|
||||
|
||||
from click.testing import CliRunner
|
||||
from plumbum.cmd import mkdir
|
||||
|
||||
from odoo_openupgrade_wizard.cli import main
|
||||
|
||||
|
||||
def test_cli_init():
|
||||
output_folder_path = Path("./tests/output")
|
||||
expected_folder_path = Path("./tests/output_expected")
|
||||
mkdir([output_folder_path, "--parents"])
|
||||
result = CliRunner().invoke(
|
||||
main,
|
||||
[
|
||||
"--env-folder=%s" % output_folder_path,
|
||||
"init",
|
||||
"--initial-version=9.0",
|
||||
"--final-version=12.0",
|
||||
"--extra-repository="
|
||||
"OCA/web,OCA/server-tools,GRAP/grap-odoo-incubator",
|
||||
],
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
|
||||
assert filecmp.cmp(
|
||||
output_folder_path / Path("config.yml"),
|
||||
expected_folder_path / Path("config.yml"),
|
||||
)
|
||||
31
tests/output_expected/config.yml
Normal file
31
tests/output_expected/config.yml
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
migration_steps:
|
||||
|
||||
- name: step_1
|
||||
complete_name: step_1__update__9.0
|
||||
version: 9.0
|
||||
action: update
|
||||
python: python2.7
|
||||
|
||||
- name: step_2
|
||||
complete_name: step_2__upgrade__10.0
|
||||
version: 10.0
|
||||
action: upgrade
|
||||
python: python2.7
|
||||
|
||||
- name: step_3
|
||||
complete_name: step_3__upgrade__11.0
|
||||
version: 11.0
|
||||
action: upgrade
|
||||
python: python3.5
|
||||
|
||||
- name: step_4
|
||||
complete_name: step_4__upgrade__12.0
|
||||
version: 12.0
|
||||
action: upgrade
|
||||
python: python3.6
|
||||
|
||||
- name: step_5
|
||||
complete_name: step_5__update__12.0
|
||||
version: 12.0
|
||||
action: update
|
||||
python: python3.6
|
||||
Loading…
Reference in New Issue
Block a user