diff --git a/vcp_psc/README.rst b/vcp_psc/README.rst new file mode 100644 index 0000000..ded7102 --- /dev/null +++ b/vcp_psc/README.rst @@ -0,0 +1,81 @@ +======================= +Contributors Github Psc +======================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:183c6a4f3366dc8045913f644b065e91fe8cd0cc8f869dc7b02ca87df5267e50 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fversion--control--platform-lightgray.png?logo=github + :target: https://github.com/OCA/version-control-platform/tree/18.0/vcp_psc + :alt: OCA/version-control-platform +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/version-control-platform-18-0/version-control-platform-18-0-vcp_psc + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/version-control-platform&target_branch=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module adds PSCs information to users by following a repository of +configuration that executes + +https://github.com/OCA/repo-maintainer + +**Table of contents** + +.. contents:: + :local: + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* Dixmit + +Contributors +------------ + +- `Dixmit `__ + + - Enric Tobella + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/version-control-platform `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/vcp_psc/__init__.py b/vcp_psc/__init__.py new file mode 100644 index 0000000..0650744 --- /dev/null +++ b/vcp_psc/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/vcp_psc/__manifest__.py b/vcp_psc/__manifest__.py new file mode 100644 index 0000000..25005e9 --- /dev/null +++ b/vcp_psc/__manifest__.py @@ -0,0 +1,22 @@ +# Copyright 2026 Dixmit +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +{ + "name": "Contributors Github Psc", + "summary": """Integrate PSCs""", + "version": "18.0.1.0.0", + "license": "AGPL-3", + "author": "Dixmit,Odoo Community Association (OCA)", + "website": "https://github.com/OCA/version-control-platform", + "depends": ["vcp_git"], + "data": [ + "data/vcp_rule.xml", + "views/vcp_repository.xml", + "security/ir.model.access.csv", + "views/vcp_platform_psc.xml", + "views/vcp_platform.xml", + # "templates/templates.xml", + ], + "assets": {}, + "demo": [], +} diff --git a/vcp_psc/data/vcp_rule.xml b/vcp_psc/data/vcp_rule.xml new file mode 100644 index 0000000..95e332e --- /dev/null +++ b/vcp_psc/data/vcp_rule.xml @@ -0,0 +1,11 @@ + + + + + PSC Detection + psc + ^master$ + + + diff --git a/vcp_psc/models/__init__.py b/vcp_psc/models/__init__.py new file mode 100644 index 0000000..5d6e001 --- /dev/null +++ b/vcp_psc/models/__init__.py @@ -0,0 +1,5 @@ +from . import vcp_platform +from . import vcp_platform_psc +from . import vcp_repository +from . import vcp_rule +from . import vcp_user diff --git a/vcp_psc/models/vcp_platform.py b/vcp_psc/models/vcp_platform.py new file mode 100644 index 0000000..3273f4d --- /dev/null +++ b/vcp_psc/models/vcp_platform.py @@ -0,0 +1,39 @@ +# Copyright 2026 Dixmit +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + + +from odoo import fields, models + + +class VCPPlatform(models.Model): + _inherit = "vcp.platform" + + psc_ids = fields.One2many( + "vcp.platform.psc", + inverse_name="platform_id", + readonly=True, + ) + + def _get_merged_domain(self, start, end, psc_id=None, **values): + result = super()._get_merged_domain(start, end, psc_id=psc_id, **values) + if psc_id: + result.append(("repository_id.psc_id", "=", int(psc_id))) + return result + + def _get_created_domain(self, start, end, psc_id=None, **values): + result = super()._get_created_domain(start, end, psc_id=psc_id, **values) + if psc_id: + result.append(("repository_id.psc_id", "=", int(psc_id))) + return result + + def _get_comments_domain(self, start, end, psc_id=None, **values): + result = super()._get_comments_domain(start, end, psc_id=psc_id, **values) + if psc_id: + result.append(("repository_id.psc_id", "=", int(psc_id))) + return result + + def _get_reviews_domain(self, start, end, psc_id=None, **values): + result = super()._get_reviews_domain(start, end, psc_id=psc_id, **values) + if psc_id: + result.append(("repository_id.psc_id", "=", int(psc_id))) + return result diff --git a/vcp_psc/models/vcp_platform_psc.py b/vcp_psc/models/vcp_platform_psc.py new file mode 100644 index 0000000..e3ccd9d --- /dev/null +++ b/vcp_psc/models/vcp_platform_psc.py @@ -0,0 +1,21 @@ +# Copyright 2026 Dixmit +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class VCPPlatformPsc(models.Model): + _name = "vcp.platform.psc" + _description = "Version Control Platform PSC" + + platform_id = fields.Many2one( + comodel_name="vcp.platform", + string="Platform", + required=True, + ) + name = fields.Char(required=True) + key = fields.Char(required=True) + member_ids = fields.Many2many( + "vcp.user", + readonly=True, + ) diff --git a/vcp_psc/models/vcp_repository.py b/vcp_psc/models/vcp_repository.py new file mode 100644 index 0000000..2c1af3b --- /dev/null +++ b/vcp_psc/models/vcp_repository.py @@ -0,0 +1,13 @@ +# Copyright 2026 Dixmit +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class VCPRepository(models.Model): + _inherit = "vcp.repository" + + psc_id = fields.Many2one( + "vcp.platform.psc", + readonly=True, + ) diff --git a/vcp_psc/models/vcp_rule.py b/vcp_psc/models/vcp_rule.py new file mode 100644 index 0000000..b3526e5 --- /dev/null +++ b/vcp_psc/models/vcp_rule.py @@ -0,0 +1,161 @@ +# Copyright 2026 Dixmit +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +import logging +import os +import re + +import yaml + +from odoo import fields, models + +_logger = logging.getLogger(__name__) + + +class VcpRule(models.Model): + _inherit = "vcp.rule" + + rule_type = fields.Selection( + selection_add=[("psc", "PSC Analysis")], + ondelete={"psc": "cascade"}, + ) + + def _process_rule_psc(self, record, parameters=None): + """ + Process a PSC rule for a given repository. + + :param repository: The repository to process the rule for. + :param rule: The PSC rule to process. + """ + if record._name != "vcp.repository.branch": + # It doesn't make sense to process this kind of rules outside + # of a repository branch, as they need the code to be downloaded + # and analyzed. + return + record._download_code() + _logger.info("Downloaded code for repository branch '%s'", record.display_name) + for conf in self.paths.splitlines(): + conf = conf.strip() + if not conf or conf.startswith("#"): + continue + conf = record.local_path + "/" + conf + if not os.path.exists(conf): + _logger.warning( + "Path '%s' does not exist for repository branch '%s'", + conf, + record.display_name, + ) + continue + _logger.info(f"Found {conf}") + for psc_file in os.listdir(os.path.join(record.local_path, conf, "psc")): + if re.match(r"^.*\.yml$", psc_file): + psc_path = os.path.join(record.local_path, conf, "psc", psc_file) + with open(psc_path) as f: + try: + psc_data = yaml.safe_load(f) + except yaml.YAMLError as e: + _logger.error(f"Error parsing PSC file '{psc_path}': {e}") + continue + self._process_psc_data(record, psc_data) + for psc_repo_file in os.listdir( + os.path.join(record.local_path, conf, "repo") + ): + if re.match(r"^.*\.yml$", psc_repo_file): + psc_repo_path = os.path.join( + record.local_path, conf, "repo", psc_repo_file + ) + with open(psc_repo_path) as f: + try: + psc_repo_data = yaml.safe_load(f) + except yaml.YAMLError as e: + _logger.error( + f"Error parsing PSC file '{psc_repo_path}': {e}" + ) + continue + self._process_psc_repo_data(record, psc_repo_data) + + def _process_psc_data(self, record, psc_data): + """ + Process the PSC data. + + :param record: The repository branch record to process the PSC data for. + :param psc_data: The PSC data to process. + """ + if not psc_data: + _logger.warning( + "No PSC data found for repository branch '%s'", record.display_name + ) + return + for psc_name in psc_data: + psc_record = self.env["vcp.platform.psc"].search( + [ + ("platform_id", "=", record.platform_id.id), + ("key", "=", psc_name), + ], + limit=1, + ) + if not psc_record: + psc_record = ( + self.env["vcp.platform.psc"] + .sudo() + .create( + { + "platform_id": record.platform_id.id, + "key": psc_name, + "name": psc_data[psc_name].get("name", psc_name), + } + ) + ) + else: + psc_record.sudo().write( + { + "name": psc_data[psc_name].get("name", psc_name), + } + ) + member_logins = psc_data[psc_name].get("members", []) + psc_data[ + psc_name + ].get("representatives", []) + members = [] + for member in member_logins: + members.append(record.platform_id.host_id._get_user(member)) + psc_record.sudo().member_ids = self.env["vcp.user"].browse(members) + + def _process_psc_repo_data(self, record, psc_repo_data): + """ + Process the PSC Repository data + + :param record: The repository branch record to process the PSC data for. + :param psc_repo_data: The PSC Repository data to process. + """ + if not psc_repo_data: + _logger.warning( + "No data found for repository branch '%s'", record.display_name + ) + return + for repo_name in psc_repo_data: + psc_name = psc_repo_data[repo_name].get("psc") + psc_record = self.env["vcp.platform.psc"].search( + [ + ("platform_id", "=", record.platform_id.id), + ("key", "=", psc_name), + ], + limit=1, + ) + if not psc_record: + continue + repo_record = ( + self.env["vcp.repository"] + .sudo() + .search( + [ + ("platform_id", "=", record.platform_id.id), + ("name", "=", repo_name), + ], + limit=1, + ) + ) + if repo_record: + repo_record.sudo().write( + { + "psc_id": psc_record.id, + } + ) diff --git a/vcp_psc/models/vcp_user.py b/vcp_psc/models/vcp_user.py new file mode 100644 index 0000000..54e49aa --- /dev/null +++ b/vcp_psc/models/vcp_user.py @@ -0,0 +1,13 @@ +# Copyright 2026 Dixmit +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class VCPUser(models.Model): + _inherit = "vcp.user" + + psc_ids = fields.Many2many( + comodel_name="vcp.platform.psc", + readonly=True, + ) diff --git a/vcp_psc/pyproject.toml b/vcp_psc/pyproject.toml new file mode 100644 index 0000000..4231d0c --- /dev/null +++ b/vcp_psc/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/vcp_psc/readme/CONTRIBUTORS.md b/vcp_psc/readme/CONTRIBUTORS.md new file mode 100644 index 0000000..2c066ba --- /dev/null +++ b/vcp_psc/readme/CONTRIBUTORS.md @@ -0,0 +1,2 @@ +- [Dixmit](https://www.dixmit.com) + - Enric Tobella diff --git a/vcp_psc/readme/DESCRIPTION.md b/vcp_psc/readme/DESCRIPTION.md new file mode 100644 index 0000000..026a305 --- /dev/null +++ b/vcp_psc/readme/DESCRIPTION.md @@ -0,0 +1,3 @@ +This module adds PSCs information to users by following a repository of configuration that executes + +https://github.com/OCA/repo-maintainer diff --git a/vcp_psc/security/ir.model.access.csv b/vcp_psc/security/ir.model.access.csv new file mode 100644 index 0000000..c6795c6 --- /dev/null +++ b/vcp_psc/security/ir.model.access.csv @@ -0,0 +1,3 @@ +"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" +access_vcp_psc,Access VCP PSC,model_vcp_platform_psc,base.group_user,1,0,0,0 +access_vcp_portal_psc,Access VCP PSC,model_vcp_platform_psc,base.group_portal,1,0,0,0 diff --git a/vcp_psc/static/description/icon.png b/vcp_psc/static/description/icon.png new file mode 100644 index 0000000..3a0328b Binary files /dev/null and b/vcp_psc/static/description/icon.png differ diff --git a/vcp_psc/static/description/index.html b/vcp_psc/static/description/index.html new file mode 100644 index 0000000..a469241 --- /dev/null +++ b/vcp_psc/static/description/index.html @@ -0,0 +1,428 @@ + + + + + +Contributors Github Psc + + + +
+

Contributors Github Psc

+ + +

Beta License: AGPL-3 OCA/version-control-platform Translate me on Weblate Try me on Runboat

+

This module adds PSCs information to users by following a repository of +configuration that executes

+

https://github.com/OCA/repo-maintainer

+

Table of contents

+ +
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Dixmit
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/version-control-platform project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/vcp_psc/views/vcp_platform.xml b/vcp_psc/views/vcp_platform.xml new file mode 100644 index 0000000..c95c72a --- /dev/null +++ b/vcp_psc/views/vcp_platform.xml @@ -0,0 +1,16 @@ + + + + + vcp.platform + + + + + + + + + + diff --git a/vcp_psc/views/vcp_platform_psc.xml b/vcp_psc/views/vcp_platform_psc.xml new file mode 100644 index 0000000..85e0f7b --- /dev/null +++ b/vcp_psc/views/vcp_platform_psc.xml @@ -0,0 +1,31 @@ + + + + + vcp.platform.psc + +
+
+ + + + + + + + + + + + + vcp.platform.psc + + + + + + + + + diff --git a/vcp_psc/views/vcp_repository.xml b/vcp_psc/views/vcp_repository.xml new file mode 100644 index 0000000..c5a73ee --- /dev/null +++ b/vcp_psc/views/vcp_repository.xml @@ -0,0 +1,14 @@ + + + + + vcp.repository + + + + + + + +