runbot/runbot/models/version.py
Christophe Monniez 981cb7e1b6 [IMP] runbot: use a Dockerfile model
Currently, runbot is using a single Dockerfile maintained in a data file
in the source code. This situation is not convenient for testing Odoo in
different environments.

With this commit, a Dockerfile Odoo model is used to allow usage of
multiple Docker containers.

This model comes with a pre-defined Dockerfile that can be used to build
the current Odoo supported versions (12.0 up to 14.0).
2020-11-10 09:52:48 +01:00

105 lines
4.8 KiB
Python

import logging
import re
from odoo import models, fields, api, tools
_logger = logging.getLogger(__name__)
class Version(models.Model):
_name = 'runbot.version'
_description = "Version"
_order = 'sequence desc, number desc,id'
name = fields.Char('Version name')
number = fields.Char('Version number', compute='_compute_version_number', store=True, help="Usefull to sort by version")
sequence = fields.Integer('sequence')
is_major = fields.Char('Is major version', compute='_compute_version_number', store=True)
base_bundle_id = fields.Many2one('runbot.bundle', compute='_compute_base_bundle_id')
previous_major_version_id = fields.Many2one('runbot.version', compute='_compute_version_relations')
intermediate_version_ids = fields.Many2many('runbot.version', compute='_compute_version_relations')
next_major_version_id = fields.Many2one('runbot.version', compute='_compute_version_relations')
next_intermediate_version_ids = fields.Many2many('runbot.version', compute='_compute_version_relations')
dockerfile_id = fields.Many2one('runbot.dockerfile', default=lambda self: self.env.ref('runbot.docker_default', raise_if_not_found=False))
@api.depends('name')
def _compute_version_number(self):
for version in self:
if version.name == 'master':
version.number = '~'
version.is_major = False
else:
# max version number with this format: 99.99
version.number = '.'.join([elem.zfill(2) for elem in re.sub(r'[^0-9\.]', '', version.name).split('.')])
version.is_major = all(elem == '00' for elem in version.number.split('.')[1:])
def create(self, values):
model = self.browse()
model._get_id.clear_cache(model)
return super().create(values)
def _get(self, name):
return self.browse(self._get_id(name))
@tools.ormcache('name')
def _get_id(self, name):
version = self.search([('name', '=', name)])
if not version:
version = self.create({
'name': name,
})
return version.id
@api.depends('is_major', 'number')
def _compute_version_relations(self):
all_versions = self.search([], order='sequence, number')
for version in self:
version.previous_major_version_id = next(
(
v
for v in reversed(all_versions)
if v.is_major and v.number < version.number and v.sequence <= version.sequence # TODO FIXME, make version comparable?
), self.browse())
if version.previous_major_version_id:
version.intermediate_version_ids = all_versions.filtered(
lambda v, current=version: v.number > current.previous_major_version_id.number and v.number < current.number and v.sequence <= current.sequence and v.sequence >= current.previous_major_version_id.sequence
)
else:
version.intermediate_version_ids = all_versions.filtered(
lambda v, current=version: v.number < current.number and v.sequence <= current.sequence
)
version.next_major_version_id = next(
(
v
for v in all_versions
if (v.is_major or v.name == 'master') and v.number > version.number and v.sequence >= version.sequence
), self.browse())
if version.next_major_version_id:
version.next_intermediate_version_ids = all_versions.filtered(
lambda v, current=version: v.number < current.next_major_version_id.number and v.number > current.number and v.sequence <= current.next_major_version_id.sequence and v.sequence >= current.sequence
)
else:
version.next_intermediate_version_ids = all_versions.filtered(
lambda v, current=version: v.number > current.number and v.sequence >= current.sequence
)
# @api.depends('base_bundle_id.is_base', 'base_bundle_id.version_id', 'base_bundle_id.project_id')
@api.depends_context('project_id')
def _compute_base_bundle_id(self):
project_id = self.env.context.get('project_id')
if not project_id:
_logger.warning("_compute_base_bundle_id: no project_id in context")
project_id = self.env.ref('runbot.main_project').id
bundles = self.env['runbot.bundle'].search([
('version_id', 'in', self.ids),
('is_base', '=', True),
('project_id', '=', project_id)
])
bundle_by_version = {bundle.version_id.id: bundle for bundle in bundles}
for version in self:
version.base_bundle_id = bundle_by_version.get(version.id)