From 908054b42437c4b55e47dc611ac9d1c5ab64b687 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E4=BA=8C=E7=8C=9B?= Date: Mon, 16 Dec 2019 00:51:41 +0800 Subject: [PATCH] A api update --- spug_api/apps/app/urls.py | 1 + spug_api/apps/app/utils.py | 21 ++++++++++++++ spug_api/apps/app/views.py | 18 ++++++------ spug_api/apps/deploy/views.py | 3 -- spug_api/libs/gitlib.py | 52 +++++++++++++++++++++++++++++++++++ spug_api/spug/settings.py | 1 + 6 files changed, 84 insertions(+), 12 deletions(-) create mode 100644 spug_api/apps/app/utils.py create mode 100644 spug_api/libs/gitlib.py diff --git a/spug_api/apps/app/urls.py b/spug_api/apps/app/urls.py index e24322a..3095888 100644 --- a/spug_api/apps/app/urls.py +++ b/spug_api/apps/app/urls.py @@ -4,4 +4,5 @@ from .views import * urlpatterns = [ path('', AppView.as_view()), + path('/versions/', get_versions), ] diff --git a/spug_api/apps/app/utils.py b/spug_api/apps/app/utils.py new file mode 100644 index 0000000..aa096ac --- /dev/null +++ b/spug_api/apps/app/utils.py @@ -0,0 +1,21 @@ +from django.conf import settings +from apps.app.models import App +from libs.gitlib import Git +import os + + +def parse_envs(text): + data = {} + if data: + for line in text.split('\n'): + fields = line.split('=', 1) + if len(fields) != 2 or fields[0].strip() == '': + raise Exception(f'解析自定义全局变量{line!r}失败,确认其遵循 key = value 格式') + data[fields[0].strip()] = fields[1].strip() + return data + + +def fetch_versions(app: App): + git_repo = app.extend_obj.git_repo + repo_dir = os.path.join(settings.REPOS_DIR, str(app.id)) + return Git(git_repo, repo_dir).fetch_branches_tags() diff --git a/spug_api/apps/app/views.py b/spug_api/apps/app/views.py index 158465d..0ce2d6f 100644 --- a/spug_api/apps/app/views.py +++ b/spug_api/apps/app/views.py @@ -1,6 +1,7 @@ from django.views.generic import View from libs import JsonParser, Argument, json_response from apps.app.models import App, AppExtend1, AppExtend2 +from apps.app.utils import parse_envs, fetch_versions import json @@ -60,12 +61,11 @@ class AppView(View): return json_response(error=error) -def parse_envs(data): - tmp = {} - if data: - for line in data.split('\n'): - fields = line.split('=', 1) - if len(fields) != 2 or fields[0].strip() == '': - raise Exception(f'解析自定义全局变量{line!r}失败,确认其遵循 key = value 格式') - tmp[fields[0].strip()] = fields[1].strip() - return tmp +def get_versions(request, a_id): + app = App.objects.filter(pk=a_id).first() + if not app: + return json_response(error='未找到指定应用') + if app.extend == '2': + return json_response(error='该应用不支持此操作') + branches, tags = fetch_versions(app) + return json_response({'branches': branches, 'tags': tags}) diff --git a/spug_api/apps/deploy/views.py b/spug_api/apps/deploy/views.py index 99b149a..f32c3f7 100644 --- a/spug_api/apps/deploy/views.py +++ b/spug_api/apps/deploy/views.py @@ -21,6 +21,3 @@ class RequestView(View): form.host_ids = json.dumps(form.host_ids) DeployRequest.objects.create(**form) return json_response(error=error) - - - diff --git a/spug_api/libs/gitlib.py b/spug_api/libs/gitlib.py new file mode 100644 index 0000000..b55ed53 --- /dev/null +++ b/spug_api/libs/gitlib.py @@ -0,0 +1,52 @@ +from git import Repo, RemoteReference, TagReference, InvalidGitRepositoryError +import shutil +import os + + +class Git: + def __init__(self, git_repo, repo_dir): + self.repo = self._get_repo(git_repo, repo_dir) + + def archive(self, filepath, commit): + with open(filepath, 'wb') as f: + self.repo.archive(f, commit) + + def fetch_branches_tags(self): + self.repo.remotes.origin.fetch() + branches, tags = {}, {} + for ref in self.repo.references: + if isinstance(ref, RemoteReference): + if ref.remote_head != 'HEAD': + branches[ref.remote_head] = self._get_commits(f'origin/{ref.remote_head}') + elif isinstance(ref, TagReference): + tags[ref.name] = { + 'id': ref.tag.hexsha, + 'author': ref.tag.tagger.name, + 'date': ref.tag.tagged_date, + 'message': ref.tag.message.strip() + } + return branches, tags + + def _get_repo(self, git_repo, repo_dir): + if os.path.exists(repo_dir): + try: + return Repo(repo_dir) + except InvalidGitRepositoryError: + if os.path.isdir(repo_dir): + shutil.rmtree(repo_dir) + else: + os.remove(repo_dir) + return Repo.clone_from(git_repo, repo_dir) + + def _get_commits(self, branch, count=10): + commits = [] + for commit in self.repo.iter_commits(branch): + if len(commits) == count: + break + commits.append({ + 'id': commit.hexsha, + 'author': commit.author.name, + 'date': commit.committed_date, + 'message': commit.message.strip() + }) + return commits diff --git a/spug_api/spug/settings.py b/spug_api/spug/settings.py index 9ea2e38..d8ad11f 100644 --- a/spug_api/spug/settings.py +++ b/spug_api/spug/settings.py @@ -93,6 +93,7 @@ TEMPLATES = [ SCHEDULE_KEY = 'spug:schedule' MONITOR_KEY = 'spug:monitor' +REPOS_DIR = os.path.join(BASE_DIR, 'repos') # Internationalization # https://docs.djangoproject.com/en/2.2/topics/i18n/