From 7727833ead5edcbef1ab36480091ee70015b669c Mon Sep 17 00:00:00 2001 From: zhu327 Date: Tue, 19 Mar 2024 19:18:18 +0800 Subject: [PATCH 1/2] ci: add import linter --- .github/workflows/python.yml | 2 + saas/.importlinter | 35 ++++++++++++ saas/.pre-commit-config.yaml | 5 ++ saas/Makefile | 1 + saas/backend/apps/group/views.py | 2 +- saas/backend/apps/handover/constants.py | 19 ------- saas/backend/apps/handover/models.py | 3 +- saas/backend/apps/organization/constants.py | 3 - saas/backend/apps/organization/models.py | 17 +++++- saas/backend/apps/role/constants.py | 14 ----- saas/backend/apps/role/serializers.py | 3 +- saas/backend/apps/user/tasks.py | 2 +- saas/backend/apps/user/views.py | 2 +- saas/backend/biz/application.py | 2 +- saas/backend/biz/constants.py | 45 ++++++++++++++- saas/backend/biz/handover.py | 2 +- saas/backend/biz/org_sync/syncer.py | 2 +- saas/backend/biz/organization.py | 33 ----------- saas/backend/biz/permission_audit.py | 2 +- saas/poetry.lock | 62 ++++++++++++++++++++- saas/pyproject.toml | 1 + saas/requirements_dev.txt | 7 ++- 22 files changed, 180 insertions(+), 84 deletions(-) create mode 100644 saas/.importlinter delete mode 100644 saas/backend/biz/organization.py diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 586d96c89..2ff6881ed 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -37,5 +37,7 @@ jobs: run: bandit -c saas/pyproject.toml -r saas - name: Lint with mypy run: mypy --config-file=saas/pyproject.toml saas + - name: Import Linter + run: cd saas && lint-imports --config=./.importlinter && cd .. - name: Test with pytest run: pytest -c saas/pyproject.toml saas diff --git a/saas/.importlinter b/saas/.importlinter new file mode 100644 index 000000000..499e756bc --- /dev/null +++ b/saas/.importlinter @@ -0,0 +1,35 @@ +[importlinter] +root_package = backend +include_external_packages = True + +[importlinter:contract:layers-apps-service-biz] +name=apps service biz component +type=layers +layers = + backend.apps + backend.trans + backend.biz + backend.service + backend.component +ignore_imports = + backend.trans.* -> backend.apps.*.models + backend.biz.* -> backend.apps.*.models + backend.biz.*.* -> backend.apps.*.models + backend.service.* -> backend.apps.*.models + backend.service.*.* -> backend.apps.*.models + backend.biz.org_sync.syncer -> backend.apps.organization.tasks + backend.biz.application -> backend.apps.role.tasks + backend.biz.application -> backend.audit.audit + backend.biz.handover -> backend.audit.audit + +[importlinter:contract:layers-api-service-biz] +name=api service biz component +type=layers +layers = + backend.api + backend.trans + backend.biz + backend.service + backend.component +ignore_imports = + backend.biz.model_event -> backend.api.authorization.models diff --git a/saas/.pre-commit-config.yaml b/saas/.pre-commit-config.yaml index 4e8514397..ed88182fc 100644 --- a/saas/.pre-commit-config.yaml +++ b/saas/.pre-commit-config.yaml @@ -36,6 +36,11 @@ repos: language: python pass_filenames: false entry: mypy --config-file=saas/pyproject.toml saas + - id: import-linter + name: import-linter + language: python + pass_filenames: false + entry: cd saas && lint-imports --config=./.importlinter && cd .. - id: pytest name: pytest language: python diff --git a/saas/Makefile b/saas/Makefile index 2b3092b9e..ab6294c91 100644 --- a/saas/Makefile +++ b/saas/Makefile @@ -25,6 +25,7 @@ lint: pflake8 --config=./pyproject.toml . bandit -c ./pyproject.toml -r . mypy --config-file=./pyproject.toml . + lint-imports --config .importlinter fmt: isort --settings-path=./pyproject.toml . diff --git a/saas/backend/apps/group/views.py b/saas/backend/apps/group/views.py index 4114e4ed1..e25d39459 100644 --- a/saas/backend/apps/group/views.py +++ b/saas/backend/apps/group/views.py @@ -26,7 +26,6 @@ from backend.apps.group import tasks # noqa from backend.apps.group.models import Group from backend.apps.policy.serializers import PolicyDeleteSLZ, PolicySLZ, PolicySystemSLZ -from backend.apps.role.constants import PermissionTypeEnum from backend.apps.role.models import Role, RoleRelatedObject from backend.apps.subject_template.models import SubjectTemplate, SubjectTemplateGroup from backend.apps.template.audit import TemplateMemberDeleteAuditProvider @@ -34,6 +33,7 @@ from backend.apps.template.models import PermTemplate, PermTemplatePolicyAuthorized, PermTemplatePreUpdateLock from backend.apps.template.serializers import TemplateListSchemaSLZ, TemplateListSLZ from backend.audit.audit import audit_context_setter, log_api_event, view_audit_decorator +from backend.biz.constants import PermissionTypeEnum from backend.biz.group import GroupBiz, GroupCheckBiz, GroupMemberExpiredAtBean from backend.biz.permission_audit import QueryAuthorizedSubjects from backend.biz.policy import PolicyBean, PolicyOperationBiz, PolicyQueryBiz diff --git a/saas/backend/apps/handover/constants.py b/saas/backend/apps/handover/constants.py index 703e8dfeb..d57a97176 100644 --- a/saas/backend/apps/handover/constants.py +++ b/saas/backend/apps/handover/constants.py @@ -32,25 +32,6 @@ class HandoverStatus(ChoicesEnum, LowerStrEnum): ) -class HandoverTaskStatus(ChoicesEnum, LowerStrEnum): - """权限交接具体任务的执行状态""" - - RUNNING = auto() - SUCCEED = auto() - FAILED = auto() - - _choices_labels = skip( - ( - (RUNNING, _("正在交接")), - (SUCCEED, _("交接成功")), - ( - FAILED, - _("交接失败"), - ), - ) - ) - - class HandoverObjectType(ChoicesEnum, LowerStrEnum): """交接的权限类型""" diff --git a/saas/backend/apps/handover/models.py b/saas/backend/apps/handover/models.py index 263191e8c..9a055c311 100644 --- a/saas/backend/apps/handover/models.py +++ b/saas/backend/apps/handover/models.py @@ -10,7 +10,8 @@ """ from django.db import models -from backend.apps.handover.constants import HandoverObjectType, HandoverStatus, HandoverTaskStatus +from backend.apps.handover.constants import HandoverObjectType, HandoverStatus +from backend.biz.constants import HandoverTaskStatus from backend.common.models import TimestampedModel diff --git a/saas/backend/apps/organization/constants.py b/saas/backend/apps/organization/constants.py index 290ee5067..5f65ee02b 100644 --- a/saas/backend/apps/organization/constants.py +++ b/saas/backend/apps/organization/constants.py @@ -55,6 +55,3 @@ class TriggerType(ChoicesEnum, LowerStrEnum): SYNC_TASK_DEFAULT_EXECUTOR = "periodic_task" - -# 新用户自动同步的用户数量 -NEW_USER_AUTO_SYNC_COUNT_LIMIT = 50 diff --git a/saas/backend/apps/organization/models.py b/saas/backend/apps/organization/models.py index 841b00db4..0dd9d3d9e 100644 --- a/saas/backend/apps/organization/models.py +++ b/saas/backend/apps/organization/models.py @@ -25,13 +25,28 @@ TriggerType, ) from backend.apps.organization.managers import SyncErrorLogManager -from backend.biz.organization import get_category_name +from backend.common.cache import cached from backend.common.models import TimestampedModel +from backend.component import usermgr from backend.util.json import json_dumps logger = logging.getLogger("app") +@cached(timeout=5 * 60) +def _get_category_dict() -> Dict[int, str]: + """获取所有目录的ID与Name映射""" + # TODO: 需要修改为直接读取DB数据,避免因为usermgr的及时变更引起未同步前的数据不一致问题 + categories = usermgr.list_category() + return {i["id"]: i["display_name"] for i in categories} + + +def get_category_name(category_id: int): + """获取目录名称""" + category_dict = _get_category_dict() + return category_dict.get(category_id) or "默认目录" + + class Category(models.Model): id = models.IntegerField("目录ID", primary_key=True) type = models.CharField("类型", max_length=32) diff --git a/saas/backend/apps/role/constants.py b/saas/backend/apps/role/constants.py index 27440c3ed..cc8e263cb 100644 --- a/saas/backend/apps/role/constants.py +++ b/saas/backend/apps/role/constants.py @@ -10,11 +10,7 @@ """ from enum import Enum -from aenum import LowerStrEnum, auto, skip -from django.utils.translation import gettext as _ - from backend.service.constants import PermissionCodeEnum, RoleType -from backend.util.enum import ChoicesEnum # 角色默认权限 DEFAULT_ROLE_PERMISSIONS = { # 超级管理员不能操作子集管理员 @@ -59,16 +55,6 @@ } -class PermissionTypeEnum(ChoicesEnum, LowerStrEnum): - """权限类型""" - - CUSTOM = auto() - TEMPLATE = auto() - RESOURCE_INSTANCE = auto() - - _choices_labels = skip(((CUSTOM, _("自定义权限")), (TEMPLATE, _("模板权限")), (RESOURCE_INSTANCE, _("资源实例")))) - - class ManagementCommonActionNameEnum(Enum): OPS = "业务运维" READ = "业务只读" diff --git a/saas/backend/apps/role/serializers.py b/saas/backend/apps/role/serializers.py index 2f353ffc5..0365e6d22 100644 --- a/saas/backend/apps/role/serializers.py +++ b/saas/backend/apps/role/serializers.py @@ -19,6 +19,7 @@ from backend.apps.organization.models import Department, User from backend.apps.policy.serializers import ConditionSLZ, InstanceSLZ, ResourceGroupSLZ, ResourceSLZ, ResourceTypeSLZ from backend.apps.role.models import Role, RoleCommonAction, RoleRelation, RoleUser +from backend.biz.constants import PermissionTypeEnum from backend.biz.role import RoleBiz from backend.biz.subject import SubjectInfoList from backend.common.serializers import GroupMemberSLZ, GroupSearchSLZ, ResourceInstancesSLZ @@ -33,8 +34,6 @@ SubjectType, ) -from .constants import PermissionTypeEnum - class RoleScopeSubjectSLZ(serializers.Serializer): type = serializers.ChoiceField(label="成员类型", choices=RoleScopeSubjectType.get_choices()) diff --git a/saas/backend/apps/user/tasks.py b/saas/backend/apps/user/tasks.py index 211be9f9a..12ea289f6 100644 --- a/saas/backend/apps/user/tasks.py +++ b/saas/backend/apps/user/tasks.py @@ -20,12 +20,12 @@ from django.template.loader import render_to_string from django.utils import timezone -from backend.apps.organization.constants import StaffStatus from backend.apps.organization.models import User from backend.apps.policy.models import Policy from backend.apps.subject.audit import log_user_cleanup_policy_audit_event from backend.apps.subject_template.models import SubjectTemplateRelation from backend.apps.user.models import UserPermissionCleanupRecord +from backend.biz.constants import StaffStatus from backend.biz.group import GroupBiz from backend.biz.helper import RoleWithPermGroupBiz from backend.biz.policy import PolicyOperationBiz, PolicyQueryBiz diff --git a/saas/backend/apps/user/views.py b/saas/backend/apps/user/views.py index b9fcf8301..ee588fc3b 100644 --- a/saas/backend/apps/user/views.py +++ b/saas/backend/apps/user/views.py @@ -22,11 +22,11 @@ from backend.apps.group.models import Group from backend.apps.group.serializers import GroupSearchSLZ from backend.apps.policy.serializers import PolicySLZ -from backend.apps.role.constants import PermissionTypeEnum from backend.apps.role.serializers import RoleCommonActionSLZ from backend.apps.subject.serializers import SubjectGroupSLZ, UserRelationSLZ from backend.apps.user.models import UserProfile from backend.audit.audit import audit_context_setter, view_audit_decorator +from backend.biz.constants import PermissionTypeEnum from backend.biz.group import GroupBiz from backend.biz.permission_audit import QueryAuthorizedSubjects from backend.biz.policy import ConditionBean, InstanceBean, PathNodeBeanList, PolicyOperationBiz, PolicyQueryBiz diff --git a/saas/backend/biz/application.py b/saas/backend/biz/application.py index 1489c92d2..3ebcd45f8 100644 --- a/saas/backend/biz/application.py +++ b/saas/backend/biz/application.py @@ -22,7 +22,6 @@ from backend.apps.application.models import Application from backend.apps.group.models import Group -from backend.apps.organization.constants import StaffStatus from backend.apps.organization.models import User as UserModel from backend.apps.policy.models import Policy from backend.apps.role.models import Role, RoleRelatedObject, RoleSource @@ -30,6 +29,7 @@ from backend.apps.template.models import PermTemplatePolicyAuthorized from backend.audit.audit import log_group_event, log_role_event, log_user_event from backend.audit.constants import AuditSourceType, AuditType +from backend.biz.constants import StaffStatus from backend.common.cache import cachedmethod from backend.common.error_codes import error_codes from backend.common.time import expired_at_display diff --git a/saas/backend/biz/constants.py b/saas/backend/biz/constants.py index 4a2c7cfc9..29710c81f 100644 --- a/saas/backend/biz/constants.py +++ b/saas/backend/biz/constants.py @@ -8,7 +8,10 @@ an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. """ -from aenum import LowerStrEnum, auto +from aenum import LowerStrEnum, StrEnum, auto, skip +from django.utils.translation import gettext as _ + +from backend.util.enum import ChoicesEnum class PolicyTag(LowerStrEnum): @@ -34,3 +37,43 @@ class ActionTag(LowerStrEnum): CHECKED = auto() UNCHECKED = auto() DELETE = auto() + + +# 新用户自动同步的用户数量 +NEW_USER_AUTO_SYNC_COUNT_LIMIT = 50 + + +class StaffStatus(ChoicesEnum, StrEnum): + IN = auto() + OUT = auto() + + _choices_labels = skip(((IN, _("在职")), (OUT, _("离职")))) + + +class HandoverTaskStatus(ChoicesEnum, LowerStrEnum): + """权限交接具体任务的执行状态""" + + RUNNING = auto() + SUCCEED = auto() + FAILED = auto() + + _choices_labels = skip( + ( + (RUNNING, _("正在交接")), + (SUCCEED, _("交接成功")), + ( + FAILED, + _("交接失败"), + ), + ) + ) + + +class PermissionTypeEnum(ChoicesEnum, LowerStrEnum): + """权限类型""" + + CUSTOM = auto() + TEMPLATE = auto() + RESOURCE_INSTANCE = auto() + + _choices_labels = skip(((CUSTOM, _("自定义权限")), (TEMPLATE, _("模板权限")), (RESOURCE_INSTANCE, _("资源实例")))) diff --git a/saas/backend/biz/handover.py b/saas/backend/biz/handover.py index d711e041b..4f9e74356 100644 --- a/saas/backend/biz/handover.py +++ b/saas/backend/biz/handover.py @@ -12,11 +12,11 @@ from abc import ABC, abstractmethod from typing import List -from backend.apps.handover.constants import HandoverTaskStatus from backend.apps.handover.models import HandoverTask from backend.apps.role.models import Role from backend.audit.audit import log_group_event, log_role_event, log_subject_template_event, log_user_event from backend.audit.constants import AuditSourceType, AuditType +from backend.biz.constants import HandoverTaskStatus from backend.biz.group import GroupBiz from backend.biz.helper import RoleWithPermGroupBiz from backend.biz.policy import PolicyOperationBiz, PolicyQueryBiz diff --git a/saas/backend/biz/org_sync/syncer.py b/saas/backend/biz/org_sync/syncer.py index dc364dac5..a823b209a 100644 --- a/saas/backend/biz/org_sync/syncer.py +++ b/saas/backend/biz/org_sync/syncer.py @@ -12,8 +12,8 @@ """ import datetime -from backend.apps.organization.constants import NEW_USER_AUTO_SYNC_COUNT_LIMIT from backend.apps.organization.models import Department, DepartmentMember, SubjectToDelete, User +from backend.biz.constants import NEW_USER_AUTO_SYNC_COUNT_LIMIT from backend.component import iam, usermgr from backend.service.constants import SubjectType diff --git a/saas/backend/biz/organization.py b/saas/backend/biz/organization.py deleted file mode 100644 index c0ed6c824..000000000 --- a/saas/backend/biz/organization.py +++ /dev/null @@ -1,33 +0,0 @@ -# -*- coding: utf-8 -*- -""" -TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-权限中心(BlueKing-IAM) available. -Copyright (C) 2017-2021 THL A29 Limited, a Tencent company. All rights reserved. -Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. -You may obtain a copy of the License at http://opensource.org/licenses/MIT -Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on -an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the -specific language governing permissions and limitations under the License. -""" -from typing import Dict - -from backend.common.cache import cached -from backend.component import usermgr - - -@cached(timeout=5 * 60) -def _get_category_dict() -> Dict[int, str]: - """获取所有目录的ID与Name映射""" - # TODO: 需要修改为直接读取DB数据,避免因为usermgr的及时变更引起未同步前的数据不一致问题 - categories = usermgr.list_category() - return {i["id"]: i["display_name"] for i in categories} - - -def get_category_name(category_id: int): - """获取目录名称""" - category_dict = _get_category_dict() - return category_dict.get(category_id) or "默认目录" - - -# ---------------------------------------------------------------------------------------------- # -# [重构] biz.Organization:提供组织架构相关数据组装、校验、填充后数据等给到View层调用,调用service层获取相关数据 -# ---------------------------------------------------------------------------------------------- # diff --git a/saas/backend/biz/permission_audit.py b/saas/backend/biz/permission_audit.py index 2462f93a8..ce1e24f00 100644 --- a/saas/backend/biz/permission_audit.py +++ b/saas/backend/biz/permission_audit.py @@ -15,8 +15,8 @@ from openpyxl.styles import Font, colors from backend.apps.policy.models import Policy -from backend.apps.role.constants import PermissionTypeEnum from backend.apps.template.models import PermTemplate, PermTemplatePolicyAuthorized +from backend.biz.constants import PermissionTypeEnum from backend.biz.subject import SubjectInfoList from backend.biz.utils import fill_resources_attribute from backend.service.action import ActionService diff --git a/saas/poetry.lock b/saas/poetry.lock index 330c1c5a6..9fd043209 100644 --- a/saas/poetry.lock +++ b/saas/poetry.lock @@ -826,6 +826,17 @@ python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" [package.extras] docs = ["sphinx"] +[[package]] +name = "grimp" +version = "1.3" +description = "Builds a queryable graph of the imports within one or more Python packages." +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +networkx = ">=2.1,<3" + [[package]] name = "grpcio" version = "1.42.0" @@ -887,6 +898,21 @@ typing-extensions = {version = ">=3.7.4.3", markers = "python_version < \"3.8\"" [package.extras] test = ["flake8 (>=3.8.4,<3.9.0)", "mypy (>=0.910)", "pycodestyle (>=2.6.0,<2.7.0)", "pytest (>=6.2.4,<6.3.0)"] +[[package]] +name = "import-linter" +version = "1.2.6" +description = "Enforces rules for the imports within and between Python packages." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +click = ">=6,<9" +grimp = ">=1.2.3,<2" + +[package.extras] +toml = ["toml"] + [[package]] name = "importlib-metadata" version = "4.8.3" @@ -1044,6 +1070,30 @@ category = "main" optional = false python-versions = ">=3.5" +[[package]] +name = "networkx" +version = "2.5" +description = "Python package for creating and manipulating graphs and networks" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +decorator = ">=4.3.0" + +[package.extras] +all = ["lxml", "matplotlib", "numpy", "pandas", "pydot", "pygraphviz", "pytest", "pyyaml", "scipy"] +gdal = ["gdal"] +lxml = ["lxml"] +matplotlib = ["matplotlib"] +numpy = ["numpy"] +pandas = ["pandas"] +pydot = ["pydot"] +pygraphviz = ["pygraphviz"] +pytest = ["pytest"] +pyyaml = ["pyyaml"] +scipy = ["scipy"] + [[package]] name = "openpyxl" version = "3.0.9" @@ -1947,7 +1997,7 @@ testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"] [metadata] lock-version = "1.1" python-versions = "3.6.6" -content-hash = "391d2b592400593add8682f32c572fb876350b91a72ec8454d544575eb03a6ac" +content-hash = "07721f30bef1325deca5db1751a7f5994aac3813e85e8d07575e991bef9f2ff7" [metadata.files] aenum = [ @@ -2380,6 +2430,9 @@ greenlet = [ {file = "greenlet-1.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:013d61294b6cd8fe3242932c1c5e36e5d1db2c8afb58606c5a67efce62c1f5fd"}, {file = "greenlet-1.1.2.tar.gz", hash = "sha256:e30f5ea4ae2346e62cedde8794a56858a67b878dd79f7df76a0767e356b1744a"}, ] +grimp = [ + {file = "grimp-1.3.tar.gz", hash = "sha256:ed42a6f41cebef8ceec440d6ba3c0f0e1c8b09a601223881d02cbd5e7260baf5"}, +] grpcio = [ {file = "grpcio-1.42.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:6e5eec67909795f7b1ff2bd941bd6c2661ca5217ea9c35003d73314100786f60"}, {file = "grpcio-1.42.0-cp310-cp310-macosx_10_10_universal2.whl", hash = "sha256:8e8cd9909fdd232ecffb954936fd90c935ebe0b5fce36c88813f8247ce54019c"}, @@ -2467,6 +2520,9 @@ immutables = [ {file = "immutables-0.16-cp39-cp39-win_amd64.whl", hash = "sha256:2505d93395d3f8ae4223e21465994c3bc6952015a38dc4f03cb3e07a2b8d8325"}, {file = "immutables-0.16.tar.gz", hash = "sha256:d67e86859598eed0d926562da33325dac7767b7b1eff84e232c22abea19f4360"}, ] +import-linter = [ + {file = "import-linter-1.2.6.tar.gz", hash = "sha256:d1f8d4cbc0a7bb3030b7738d7e2eadcff918f070a9db0522b95df2a8834d47de"}, +] importlib-metadata = [ {file = "importlib_metadata-4.8.3-py3-none-any.whl", hash = "sha256:65a9576a5b2d58ca44d133c42a241905cc45e34d2c06fd5ba2bafa221e5d7b5e"}, {file = "importlib_metadata-4.8.3.tar.gz", hash = "sha256:766abffff765960fcc18003801f7044eb6755ffae4521c8e8ce8e83b9c9b0668"}, @@ -2592,6 +2648,10 @@ mysqlclient = [ {file = "mysqlclient-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:a6b5648f648b16335e3b1aaec93dc3fcc81a9a661180e306936437cc522c810b"}, {file = "mysqlclient-2.0.1.tar.gz", hash = "sha256:fb2f75aea14722390d2d8ddf384ad99da708c707a96656210a7be8af20a2c5e5"}, ] +networkx = [ + {file = "networkx-2.5-py3-none-any.whl", hash = "sha256:8c5812e9f798d37c50570d15c4a69d5710a18d77bafc903ee9c5fba7454c616c"}, + {file = "networkx-2.5.tar.gz", hash = "sha256:7978955423fbc9639c10498878be59caf99b44dc304c2286162fd24b458c1602"}, +] openpyxl = [ {file = "openpyxl-3.0.9-py2.py3-none-any.whl", hash = "sha256:8f3b11bd896a95468a4ab162fc4fcd260d46157155d1f8bfaabb99d88cfcf79f"}, {file = "openpyxl-3.0.9.tar.gz", hash = "sha256:40f568b9829bf9e446acfffce30250ac1fa39035124d55fc024025c41481c90f"}, diff --git a/saas/pyproject.toml b/saas/pyproject.toml index 6c694a257..b000c8ecd 100644 --- a/saas/pyproject.toml +++ b/saas/pyproject.toml @@ -153,6 +153,7 @@ isort = "^5.9.2" pytest-cov = "^3.0.0" flake8-bugbear = "22.9.23" bandit = "1.7.1" +import-linter = "1.2.6" [build-system] requires = ["poetry-core>=1.0.0"] diff --git a/saas/requirements_dev.txt b/saas/requirements_dev.txt index 317bc8af6..207e0b30e 100644 --- a/saas/requirements_dev.txt +++ b/saas/requirements_dev.txt @@ -26,7 +26,7 @@ charset-normalizer==2.0.4; python_full_version >= "3.6.2" and python_version >= click-didyoumean==0.3.0; python_full_version >= "3.6.2" and python_full_version < "4.0.0" and python_version >= "3.6" click-plugins==1.1.1; python_version >= "3.6" click-repl==0.2.0; python_version >= "3.6" -click==7.1.2; python_full_version >= "3.6.2" and python_version >= "3.6" and python_version < "3.11" and python_full_version < "4.0.0" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6") +click==7.1.2; python_full_version >= "3.6.2" and python_version >= "3.6" and python_version < "3.11" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6") and python_full_version < "4.0.0" colorama==0.4.4; python_version >= "3.6" and python_full_version < "3.0.0" and sys_platform == "win32" and platform_system == "Windows" or sys_platform == "win32" and python_version >= "3.6" and python_full_version >= "3.5.0" and platform_system == "Windows" contextvars==2.4; python_version < "3.7" and python_version >= "3.6" converge==0.9.8 @@ -36,7 +36,7 @@ coverage==6.2; python_version >= "3.6" cryptography==3.3.2; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.6.0") curlify==2.2.1; python_full_version >= "3.6.2" and python_version < "3.11" and (python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version < "4") and python_full_version < "4.0.0" and (python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0") dataclasses==0.7; python_version >= "3.6" and python_version < "3.7" -decorator==5.0.9; python_version >= "3.5" +decorator==5.0.9; python_version >= "3.6" deprecated==1.2.13; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6" django-celery-beat==2.2.1 django-cors-headers==3.4.0; python_version >= "3.5" @@ -62,11 +62,13 @@ gitdb==4.0.9; python_version >= "3.6" gitpython==3.1.20; python_version >= "3.6" googleapis-common-protos==1.54.0; python_version >= "3.6" greenlet==1.1.2; python_version >= "2.7" and python_full_version < "3.0.0" and platform_python_implementation == "CPython" or python_version > "3.5" and python_full_version < "3.0.0" and platform_python_implementation == "CPython" or python_version > "3.5" and platform_python_implementation == "CPython" and python_full_version >= "3.5.0" +grimp==1.3; python_version >= "3.6" grpcio==1.42.0; python_version >= "3.6" gunicorn==20.1.0; python_version >= "3.5" httplib2==0.19.0 idna==2.10; python_full_version >= "3.6.2" and python_version >= "3" and python_version < "3.11" and (python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version < "4") and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6") and python_full_version < "4.0.0" and (python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0") immutables==0.16; python_version < "3.7" and python_version >= "3.6" +import-linter==1.2.6; python_version >= "3.6" importlib-metadata==4.8.3; python_version >= "3.6" inflection==0.5.1; python_version >= "3.6" iniconfig==1.1.1; python_version >= "3.6" @@ -80,6 +82,7 @@ mock==1.0.1 mypy-extensions==0.4.3; python_full_version >= "3.6.2" and python_version >= "3.5" mypy==0.910; python_version >= "3.5" mysqlclient==2.0.1; python_version >= "3.5" +networkx==2.5; python_version >= "3.6" openpyxl==3.0.9; python_version >= "3.6" opentelemetry-api==1.7.1; python_version >= "3.6" opentelemetry-exporter-jaeger-proto-grpc==1.7.1; python_version >= "3.6" From b9d65af75e67ce831a19915db3e05a1ba517a0a4 Mon Sep 17 00:00:00 2001 From: zhu327 Date: Tue, 19 Mar 2024 19:24:57 +0800 Subject: [PATCH 2/2] ci: update import linter --- saas/.importlinter | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/saas/.importlinter b/saas/.importlinter index 499e756bc..687bd8c52 100644 --- a/saas/.importlinter +++ b/saas/.importlinter @@ -20,7 +20,7 @@ ignore_imports = backend.biz.org_sync.syncer -> backend.apps.organization.tasks backend.biz.application -> backend.apps.role.tasks backend.biz.application -> backend.audit.audit - backend.biz.handover -> backend.audit.audit + backend.audit.audit -> backend.apps.*.models [importlinter:contract:layers-api-service-biz] name=api service biz component