Skip to content

Commit 7486621

Browse files
authored
Merge pull request #8 from kuafuai/feat/abc
refactor(*):introduce interface design
2 parents a673f5b + 756190d commit 7486621

39 files changed

+779
-560
lines changed

backend/app/controllers/step_api.py

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,22 @@
11
from flask import request, session
22
from app.controllers.common import json_response
33
from flask import Blueprint
4-
from app.pkgs.prompt.api import clarifyAPI
5-
from app.pkgs.prompt.api_pro import clarifyAPIPro
64
from app.pkgs.tools.i18b import getI18n
7-
from config import GRADE
5+
from app.pkgs.prompt.prompt import clarifyAPI
86

97
bp = Blueprint('step_api', __name__, url_prefix='/step_api')
108

119
@bp.route('/clarify', methods=['POST'])
1210
@json_response
1311
def gen_interface_doc():
1412
_ = getI18n("controllers")
15-
user_prompt = request.json.get('user_prompt')
13+
userPrompt = request.json.get('user_prompt')
1614
username = session["username"]
1715
apiDocUrl = session[username]['memory']['appconfig']['apiDocUrl']
1816

19-
if GRADE == "base":
20-
msg, success = clarifyAPI(user_prompt, apiDocUrl)
21-
else:
22-
msg, success = clarifyAPIPro(user_prompt, apiDocUrl)
17+
msg, success = clarifyAPI(userPrompt, apiDocUrl)
2318

24-
session[username]['memory']['originalPrompt'] = user_prompt
19+
session[username]['memory']['originalPrompt'] = userPrompt
2520
session.update()
2621

2722
if success:

backend/app/controllers/step_code.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
from flask import request, session
2-
import json
3-
import re
42
from app.controllers.common import json_response
5-
from app.pkgs.prompt.code import aiReferenceRepair
63
from app.pkgs.tools.i18b import getI18n
7-
from config import GRADE
8-
from app.pkgs.prompt.code import aiGenCode, aiMergeCode, aiCheckCode, aiFixError
9-
from app.pkgs.devops.devops import get_file_content
4+
from app.pkgs.prompt.prompt import aiGenCode, aiMergeCode, aiCheckCode, aiFixError, aiReferenceRepair
5+
from app.pkgs.devops.local_tools import getFileContent
106
from flask import Blueprint
117

128
bp = Blueprint('step_code', __name__, url_prefix='/step_code')
@@ -68,7 +64,7 @@ def reference_repair():
6864
appName = session[userName]['memory']['appconfig']['appName']
6965
branch = session[userName]['memory']['appconfig']['sourceBranch']
7066

71-
hasGitCode, referenceCode = get_file_content(referenceFile, branch, repo)
67+
hasGitCode, referenceCode = getFileContent(referenceFile, branch, repo)
7268
if not hasGitCode:
7369
raise Exception(_("Failed to reference repair no reference file found."))
7470

backend/app/controllers/step_devops.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
from flask import request, session
22
from app.controllers.common import json_response
3-
from app.pkgs.prompt.code import aiAnalyzeError
4-
from app.pkgs.devops.gitlab_tools import get_pipeline_status
5-
from app.pkgs.devops.devops import trigger_pipeline
6-
from app.pkgs.devops.local_tools import compile_check, lint_check
3+
from app.pkgs.prompt.prompt import aiAnalyzeError
4+
from app.pkgs.devops.local_tools import compileCheck, lintCheck
75
from app.pkgs.tools.i18b import getI18n
6+
from app.pkgs.devops.devops import triggerPipeline, getPipelineStatus
87
from config import WORKSPACE_PATH
98
from flask import Blueprint
109

@@ -18,7 +17,7 @@ def trigger_ci():
1817
username = session['username']
1918
branch = session[username]['memory']['appconfig']['featureBranch']
2019

21-
result, piplineID, piplineUrl, success = trigger_pipeline(branch, repo_path)
20+
result, piplineID, piplineUrl, success = triggerPipeline(branch, repo_path)
2221
if success:
2322
return {"name": 'ci', "info": {"piplineID": piplineID, "repopath": repo_path, "piplineUrl": piplineUrl}}
2423
else:
@@ -31,7 +30,7 @@ def plugin_ci():
3130
pipeline_id = request.args.get('piplineID')
3231
repopath = request.args.get('repopath')
3332

34-
piplineJobs = get_pipeline_status(pipeline_id, repopath)
33+
piplineJobs = getPipelineStatus(pipeline_id, repopath)
3534
print("piplineJobs:", piplineJobs)
3635

3736
return {'piplineJobs': piplineJobs}
@@ -45,7 +44,7 @@ def check_compile():
4544
repo_path = request.json.get('repo_path')
4645
ws_path = WORKSPACE_PATH+task_id+'/'+repo_path
4746

48-
success, message = compile_check(ws_path, repo_path)
47+
success, message = compileCheck(ws_path, repo_path)
4948

5049
if success:
5150
reasoning = _("Compile check pass.")
@@ -67,7 +66,7 @@ def check_lint():
6766
repo_path = request.json.get('service_name')
6867
ws_path = WORKSPACE_PATH+task_id+'/'+repo_path
6968

70-
success, message = lint_check(ws_path, repo_path, file_path)
69+
success, message = lintCheck(ws_path, repo_path, file_path)
7170

7271
if success:
7372
reasoning = _("Static code scan passed.")

backend/app/controllers/step_requirement.py

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,24 @@
11
from flask import request, session
22
from app.controllers.common import json_response
33
from flask import Blueprint
4-
from app.pkgs.prompt.requirement import clarifyRequirement
5-
from app.pkgs.prompt.requirement_pro import clarifyRequirementPro
64
from app.pkgs.tools.i18b import getI18n
7-
from config import GRADE
5+
from app.pkgs.prompt.prompt import clarifyRequirement
86

97
bp = Blueprint('step_requirement', __name__, url_prefix='/step_requirement')
108

119
@bp.route('/clarify', methods=['POST'])
1210
@json_response
1311
def clarify():
1412
_ = getI18n("controllers")
15-
user_prompt = request.json.get('user_prompt')
16-
global_context = request.json.get('global_context')
13+
userPrompt = request.json.get('user_prompt')
14+
globalContext = request.json.get('global_context')
1715
userName = session["username"]
1816

1917
appName = session[userName]['memory']['appconfig']['appName']
2018
if len(appName) == 0:
2119
raise Exception(_("Please select the application you want to develop."))
22-
23-
if GRADE == "base":
24-
msg, success = clarifyRequirement(user_prompt, global_context, appName)
25-
else:
26-
msg, success = clarifyRequirementPro(user_prompt, global_context, appName)
20+
21+
msg, success = clarifyRequirement(userPrompt, globalContext)
2722

2823
if success:
2924
return {'message': msg, 'memory': session[userName]['memory']}

backend/app/controllers/step_subtask.py

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
1-
import time
21
from flask import request, session
32
from app.controllers.common import json_response
4-
from app.pkgs.prompt.subtask import splitTask
5-
from app.pkgs.prompt.subtask_java_pro import splitTaskJavaPro
6-
from app.pkgs.prompt.subtask_vue_pro import splitTaskVuePro
7-
from app.pkgs.devops.devops import get_file_content
3+
from app.pkgs.devops.local_tools import getFileContent
84
from app.pkgs.tools.i18b import getI18n
95
from app.pkgs.knowledge.app_info import getSwagger
10-
from config import GRADE
116
from app.pkgs.tools.file_tool import get_ws_path
127
from flask import Blueprint
8+
from app.pkgs.prompt.prompt import splitTask
139

1410
bp = Blueprint('step_subtask', __name__, url_prefix='/step_subtask')
1511

@@ -39,25 +35,17 @@ def analysis():
3935
else:
4036
newfeature = requirementDoc
4137

42-
if GRADE == "base":
43-
filesToEdit, success = splitTask(newfeature, serviceName, apiDocUrl)
44-
else:
45-
if "java" in serviceName:
46-
filesToEdit, success = splitTaskJavaPro(newfeature, serviceName, wsPath)
47-
if "vue" in serviceName:
48-
filesToEdit, success = splitTaskVuePro(newfeature, serviceName)
49-
else:
50-
filesToEdit, success = splitTask(newfeature, serviceName)
38+
filesToEdit, success = splitTask(newfeature, serviceName, apiDocUrl)
5139

5240
if success:
5341
for serviceIdx, service in enumerate(filesToEdit):
5442
for index, file in enumerate(service["files"]):
55-
isSuccess, oldCode = get_file_content(file["file-path"], sourceBranch, filesToEdit[serviceIdx]["service-name"])
43+
isSuccess, oldCode = getFileContent(file["file-path"], sourceBranch, filesToEdit[serviceIdx]["service-name"])
5644
filesToEdit[serviceIdx]["files"][index]["old-code"] = oldCode
5745
if not isSuccess:
5846
filesToEdit[serviceIdx]["files"][index]["old-code"] = ''
5947

60-
isSuccess, referenceCode = get_file_content(file["reference-file"], sourceBranch, filesToEdit[serviceIdx]["service-name"])
48+
isSuccess, referenceCode = getFileContent(file["reference-file"], sourceBranch, filesToEdit[serviceIdx]["service-name"])
6149
filesToEdit[serviceIdx]["files"][index]["reference-code"] = referenceCode
6250
if not isSuccess:
6351
filesToEdit[serviceIdx]["files"][index]["reference-code"] = ''

backend/app/controllers/task.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
from app.controllers.common import json_response
33
from app.models.task import getTaskInfo, getEmptyTaskInfo
44
from app.pkgs.tools.i18b import getI18n
5-
from app.pkgs.tools.i18b import getFrontendText
65
from config import GRADE
76

87
bp = Blueprint('task', __name__, url_prefix='/task')

backend/app/controllers/workspace.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import re
22
from flask import request, session
33
from app.controllers.common import json_response
4-
from app.pkgs.devops.gitlab_tools import pull_code
5-
from app.pkgs.devops.gitlab_tools import check_and_create_branch, update_file_content
64
from app.pkgs.tools.i18b import getI18n
5+
from app.pkgs.devops.git_tools import pullCode, createBranch, pushCode
76
from config import GRADE
87
from config import WORKSPACE_PATH
98
from app.pkgs.tools.file_tool import get_ws_path, write_file_content
@@ -34,10 +33,11 @@ def create():
3433
fature_branch = request.json.get('feature_branch')
3534
ws_path = get_ws_path(task_id)
3635

36+
# todo clone template from git(by independent config)
3737
if GRADE == "base":
3838
success = True
3939
else:
40-
success = pull_code(ws_path, repo_path, base_branch, fature_branch)
40+
success = pullCode(ws_path, repo_path, base_branch, fature_branch)
4141

4242
if success:
4343
return _("Create workspace successfully.")
@@ -76,9 +76,9 @@ def gitpush():
7676

7777
plugin = {"name": 'push_code', "uuid": frontUuid}
7878

79-
check_and_create_branch(session[userName]['memory']['appconfig']['sourceBranch'],
79+
createBranch(session[userName]['memory']['appconfig']['sourceBranch'],
8080
session[userName]['memory']['appconfig']['featureBranch'], parts[0])
81-
result, success = update_file_content(
81+
result, success = pushCode(
8282
parts[2], session[userName]['memory']['appconfig']['featureBranch'], parts[0], code, commitMsg)
8383
newPrompt = "基于 " + \
8484
session[userName]['memory']["repoPath"]+" 代码分支进行自动化集成测试"
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from abc import ABC, abstractmethod
2+
3+
from config import GRADE
4+
5+
# todo finish CD and cloud services
6+
class CDInterface(ABC):
7+
@abstractmethod
8+
def triggerPipeline(self, branchName, repoPath):
9+
pass
10+
11+
@abstractmethod
12+
def getPipelineStatus(self, pipelineId, repoPath):
13+
pass
14+
15+
@abstractmethod
16+
def getPipelineLogs(self, repopath, pipeline_id, job_id):
17+
pass

backend/app/pkgs/devops/devops.py

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,27 @@
1+
from app.pkgs.devops.devops_gitlab import DevopsGitlab
2+
from app.pkgs.devops.devops_local import DevopsLocal
13
from config import DEVOPS_TOOLS
2-
from app.pkgs.devops.gitlab_tools import get_file_content as gitlab_get_file_content
3-
from app.pkgs.devops.local_tools import get_file_content as local_get_file_content
4-
from app.pkgs.devops.gitlab_tools import trigger_pipeline as gitlab_trigger_pipeline
5-
from app.pkgs.devops.local_tools import trigger_pipeline as local_trigger_pipeline
64

5+
def triggerPipeline(filePath, branchName, repoPath):
6+
if DEVOPS_TOOLS == 'local':
7+
obj = DevopsLocal()
8+
elif DEVOPS_TOOLS == 'gitlab':
9+
obj = DevopsGitlab()
10+
11+
return obj.triggerPipeline(obj, filePath, branchName, repoPath)
712

8-
def get_file_content(file_path, branch_name, repopath):
9-
try:
10-
if DEVOPS_TOOLS == 'local':
11-
return local_get_file_content(file_path, branch_name, repopath)
12-
elif DEVOPS_TOOLS == 'gitlab':
13-
return gitlab_get_file_content(file_path, branch_name, repopath)
14-
except Exception as e:
15-
return False, ""
13+
def getPipelineStatus(piplineId, repoPath):
14+
if DEVOPS_TOOLS == 'local':
15+
obj = DevopsLocal()
16+
elif DEVOPS_TOOLS == 'gitlab':
17+
obj = DevopsGitlab()
18+
19+
return obj.getPipelineStatus(piplineId, repoPath)
1620

17-
def trigger_pipeline(branch_name, repopath):
18-
try:
19-
if DEVOPS_TOOLS == 'local':
20-
return local_trigger_pipeline(branch_name, repopath)
21-
elif DEVOPS_TOOLS == 'gitlab':
22-
return gitlab_trigger_pipeline(branch_name, repopath)
23-
except Exception as e:
24-
return False, ""
21+
def getPipelineJobLogs(repopath, pipeline_id, job_id):
22+
if DEVOPS_TOOLS == 'local':
23+
obj = DevopsLocal()
24+
elif DEVOPS_TOOLS == 'gitlab':
25+
obj = DevopsGitlab()
26+
27+
return obj.getPipelineJobLogs(obj, repopath, pipeline_id, job_id)
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import gitlab
2+
import html
3+
import re
4+
from app.pkgs.devops.devops_interface import DevopsInterface
5+
from config import GITLAB_TOKEN, GITLAB_URL, GITLAB_CLONE_URL
6+
7+
class DevopsGitlab(DevopsInterface):
8+
def triggerPipeline(self, branch_name, repopath):
9+
try:
10+
gl = gitlab.Gitlab(GITLAB_URL, GITLAB_TOKEN, api_version='4')
11+
12+
project = gl.projects.get(repopath)
13+
pipeline = project.pipelines.create({'ref': branch_name})
14+
pipeline_url = GITLAB_URL + \
15+
repopath + '/-/pipelines/' + str(pipeline.id)
16+
return "Get pipline status...", str(pipeline.get_id()), pipeline_url, True
17+
except Exception as e:
18+
return "Failed to trigger pipline:" + str(e), 0, "", False
19+
20+
21+
def getPipelineStatus(self, pipline_id, repopath):
22+
try:
23+
gl = gitlab.Gitlab(GITLAB_URL, GITLAB_TOKEN, api_version='4')
24+
25+
project = gl.projects.get(repopath)
26+
27+
pipeline = project.pipelines.get(pipline_id)
28+
29+
print("pipeline:", pipeline.status)
30+
31+
jobs = pipeline.jobs.list()
32+
33+
job_info = []
34+
for job in jobs:
35+
print("job:", job)
36+
job_info.append({
37+
'job_id': job.id,
38+
'job_name': job.name,
39+
'status': job.status,
40+
'duration': job.duration,
41+
'log': get_pipeline_job_logs(repopath, pipline_id, job.id)
42+
})
43+
44+
return list(reversed(job_info))
45+
except Exception as e:
46+
return "Failed to get pipline status:" + str(e)
47+
48+
def getPipelineJobLogs(self, repopath, pipeline_id, job_id):
49+
try:
50+
gl = gitlab.Gitlab(GITLAB_URL, GITLAB_TOKEN, api_version='4')
51+
52+
project = gl.projects.get(repopath)
53+
job = project.jobs.get(job_id)
54+
logs = job.trace()
55+
56+
return self.remove_color_codes(logs)
57+
except Exception as e:
58+
return "Failed to get log: " + str(e)
59+
60+
61+
def remove_color_codes(log_string):
62+
unicode_string = log_string.decode('unicode_escape')
63+
color_regex = re.compile(r'\x1b\[[0-9;]*m')
64+
cleaned_string = re.sub(color_regex, '', unicode_string)
65+
cleaned_string = re.sub(r'\n', '<br>', unicode_string)
66+
cleaned_string = re.sub(r'\r', '<br>', cleaned_string)
67+
cleaned_string = re.sub('"', ' ', cleaned_string)
68+
cleaned_string = re.sub("'", ' ', cleaned_string)
69+
cleaned_string = re.sub(
70+
r'(\x9B|\x1B\[)[0-?]*[ -\/]*[@-~]', ' ', cleaned_string)
71+
cleaned_string = html.escape(cleaned_string)
72+
return cleaned_string
73+
74+
# def getFileContent(self, file_path, branch_name, repopath):
75+
# try:
76+
# print("get_file_content-repopath:" + repopath)
77+
# print("get_file_content-branch_name:" + branch_name)
78+
# print("get_file_content-file_path:" + file_path)
79+
# gl = gitlab.Gitlab(GITLAB_URL, private_token=GITLAB_TOKEN, api_version='4')
80+
81+
# project = gl.projects.get(repopath)
82+
83+
# file = project.files.get(file_path, ref=branch_name)
84+
85+
# content = codecs.decode(file.decode(), 'utf-8')
86+
87+
# print(content)
88+
89+
# return True, content
90+
# except Exception as e:
91+
# return False, str(e)

0 commit comments

Comments
 (0)