Skip to content

Commit 75b8c4e

Browse files
committed
[FIX] base{_import_module}: cloc should not count generated code
* Studio generate computed field "count" when the user add a button in the button box. Since those lines are written by studio with drag and drop it should not be counted for the maintenance subscription. We can detect them because field created by the user in studio start with x_studio and fields created outside studio does not have studio_customization xml_id * Add test to make no standard module introduce customization in the database during the install the will be counted by cloc see odoo/enterprise#22664
1 parent 6c80e7c commit 75b8c4e

File tree

4 files changed

+100
-4
lines changed

4 files changed

+100
-4
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# -*- coding: utf-8 -*-
2+
# Part of Odoo. See LICENSE file for full copyright and licensing details.
3+
from . import test_cloc
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# -*- coding: utf-8 -*-
2+
# Part of Odoo. See LICENSE file for full copyright and licensing details.
3+
4+
from odoo.tools import cloc
5+
from odoo.addons.base.tests import test_cloc
6+
7+
class TestClocFields(test_cloc.TestClocCustomization):
8+
9+
def test_fields_from_import_module(self):
10+
"""
11+
Check that custom computed fields installed with an imported module
12+
is counted as customization
13+
"""
14+
self.env['ir.module.module'].create({
15+
'name': 'imported_module',
16+
'state': 'installed',
17+
'imported': True,
18+
})
19+
f1 = self.create_field('x_imported_field')
20+
self.create_xml_id('import_field', f1.id, 'imported_module')
21+
cl = cloc.Cloc()
22+
cl.count_customization(self.env)
23+
self.assertEqual(cl.code.get('imported_module', 0), 1, 'Count fields with xml_id of imported module')
24+
f2 = self.create_field('x_base_field')
25+
self.create_xml_id('base_field', f2.id, 'base')
26+
cl = cloc.Cloc()
27+
cl.count_customization(self.env)
28+
self.assertEqual(cl.code.get('base', 0), 0, "Don't count fields from standard module")

odoo/addons/base/tests/test_cloc.py

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import sys
33

44
from odoo.tools import cloc
5-
from odoo.tests.common import TransactionCase
5+
from odoo.tests import TransactionCase, tagged
66

77
XML_TEST = """<!-- Comment -->
88
<?xml version="1.0" encoding="UTF-8"?>
@@ -79,7 +79,54 @@ def query():
7979
}
8080
'''
8181

82-
class TestCloc(TransactionCase):
82+
class TestClocCustomization(TransactionCase):
83+
def create_xml_id(self, name, res_id, module='studio_customization'):
84+
self.env['ir.model.data'].create({
85+
'name': name,
86+
'model': 'ir.model.fields',
87+
'res_id': res_id,
88+
'module': module,
89+
})
90+
91+
def create_field(self, name):
92+
return self.env['ir.model.fields'].with_context(studio=True).create({
93+
'name': name,
94+
'field_description': name,
95+
'model': 'res.partner',
96+
'model_id': self.env.ref('base.model_res_partner').id,
97+
'ttype': 'integer',
98+
'store': False,
99+
'compute': "for rec in self: rec['x_invoice_count'] = 10",
100+
})
101+
102+
def test_ignore_auto_generated_computed_field(self):
103+
"""
104+
Check that we count custom fields with no module or studio not auto generated
105+
Having an xml_id but no existing module is consider as not belonging to a module
106+
"""
107+
f1 = self.create_field('x_invoice_count')
108+
self.create_xml_id('invoice_count', f1.id)
109+
cl = cloc.Cloc()
110+
cl.count_customization(self.env)
111+
self.assertEqual(cl.code.get('odoo/studio', 0), 0, 'Studio auto generated count field should not be counted in cloc')
112+
f2 = self.create_field('x_studio_custom_field')
113+
self.create_xml_id('studio_custom', f2.id)
114+
cl = cloc.Cloc()
115+
cl.count_customization(self.env)
116+
self.assertEqual(cl.code.get('odoo/studio', 0), 1, 'Count other studio computed field')
117+
f3 = self.create_field('x_custom_field')
118+
cl = cloc.Cloc()
119+
cl.count_customization(self.env)
120+
self.assertEqual(cl.code.get('odoo/studio', 0), 2, 'Count fields without xml_id')
121+
f4 = self.create_field('x_custom_field_export')
122+
self.create_xml_id('studio_custom', f4.id, '__export__')
123+
cl = cloc.Cloc()
124+
cl.count_customization(self.env)
125+
self.assertEqual(cl.code.get('odoo/studio', 0), 3, 'Count fields with xml_id but without module')
126+
127+
128+
class TestClocParser(TransactionCase):
129+
83130
def test_parser(self):
84131
cl = cloc.Cloc()
85132
xml_count = cl.parse_xml(XML_TEST)
@@ -96,3 +143,16 @@ def test_parser(self):
96143
self.assertEqual(py_count, (8, 16))
97144
js_count = cl.parse_js(JS_TEST)
98145
self.assertEqual(js_count, (10, 17))
146+
147+
148+
@tagged('post_install', '-at_install')
149+
class TestClocStdNoCusto(TransactionCase):
150+
151+
def test_no_custo_install(self):
152+
"""
153+
Make sure after the installation of module
154+
no database customization is counted
155+
"""
156+
cl = cloc.Cloc()
157+
cl.count_customization(self.env)
158+
self.assertEqual(cl.code.get('odoo/studio', 0), 0, 'Module should not generate customization in database')

odoo/tools/cloc.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,16 @@ def count_customization(self, env):
159159
for a in env['ir.actions.server'].browse(data.keys()):
160160
self.book(data[a.id] or "odoo/studio", "ir.actions.server/%s: %s" % (a.id, a.name), self.parse_py(a.code))
161161

162-
query = """
162+
query = r"""
163163
SELECT f.id, m.name FROM ir_model_fields AS f
164164
LEFT JOIN ir_model_data AS d ON (d.res_id = f.id AND d.model = 'ir.model.fields')
165165
LEFT JOIN ir_module_module AS m ON m.name = d.module
166-
WHERE f.compute IS NOT null AND (m.name IS null {})
166+
WHERE f.compute IS NOT null AND (
167+
-- Do not count studio field
168+
(m.name IS null AND (d.module != 'studio_customization' or d.module is NULL))
169+
-- Unless they start with x_studio
170+
OR (d.module = 'studio_customization' AND f.name ilike 'x\_studio%')
171+
{})
167172
""".format(imported_module)
168173
env.cr.execute(query)
169174
data = {r[0]: r[1] for r in env.cr.fetchall()}

0 commit comments

Comments
 (0)