|
@@ -1,2 +1,79 @@
|
|
# gpt-migrate
|
|
# gpt-migrate
|
|
|
|
|
|
|
|
+gpt 不同语言代码迁移,比如java项目转python项目
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+## Develop
|
|
|
|
+
|
|
|
|
+```
|
|
|
|
+python main.py --sourcedir /path/to/my-python-app --sourceentry app.py --targetdir /path/to/my-nodejs-app --targetlang nodejs
|
|
|
|
+```
|
|
|
|
+--sourcedir 指定原项目目录,--targetlang指定目标语言,如nodejs
|
|
|
|
+
|
|
|
|
+## 原理分析
|
|
|
|
+
|
|
|
|
+1、检测 sourcedir 是什么语言的代码:
|
|
|
|
+```
|
|
|
|
+ detected_language = detect_language(sourcedir) if not sourcelang else sourcelang
|
|
|
|
+
|
|
|
|
+```
|
|
|
|
+在 config.py 中,定义了常见的编程语言,detect_language 函数遍历 sourcedir 目录,找出后缀最多的文件的后缀,然后再确定是哪种编程语言。
|
|
|
|
+
|
|
|
|
+2、创建环境
|
|
|
|
+
|
|
|
|
+```
|
|
|
|
+ create_environment(globals)
|
|
|
|
+
|
|
|
|
+ docker_prompt_template = prompt_constructor(HIERARCHY, GUIDELINES, WRITE_CODE, CREATE_DOCKER, SINGLEFILE)
|
|
|
|
+```
|
|
|
|
+其实就是拼接 prompt , 替换 targetlang,targetdir 等几个变量:
|
|
|
|
+
|
|
|
|
+```
|
|
|
|
+ llm_write_file(prompt,
|
|
|
|
+ target_path="Dockerfile",
|
|
|
|
+ waiting_message="Creating your environment...",
|
|
|
|
+ success_message=f"Created Docker environment for {globals.targetlang} project in directory '{globals.targetdir}'.",
|
|
|
|
+ globals=globals)
|
|
|
|
+```
|
|
|
|
+prompt 模板在 gpt_migrate/prompts 目录中。注意,llm_write_file 函数写Dockerfile,怎么写呢?上面只是拼接了模板的 prompt而已,那这些 prompt 其实是调用openai来生成的:
|
|
|
|
+
|
|
|
|
+```
|
|
|
|
+
|
|
|
|
+ file_name,language,file_content = globals.ai.write_code(prompt)[0]
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ def write_code(self, prompt):
|
|
|
|
+ message=[{"role": "user", "content": str(prompt)}]
|
|
|
|
+ response = openai.ChatCompletion.create(
|
|
|
|
+ messages=message,
|
|
|
|
+ stream=False,
|
|
|
|
+ model=self.model_name,
|
|
|
|
+ max_tokens=self.max_tokens,
|
|
|
|
+ temperature=self.temperature
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+```
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+3、代码迁移,如java代码迁移到python语言:
|
|
|
|
+
|
|
|
|
+```
|
|
|
|
+ def migrate(sourcefile, globals, parent_file=None):
|
|
|
|
+ # recursively work through each of the files in the source directory, starting with the entrypoint.
|
|
|
|
+ internal_deps_list, external_deps_list = get_dependencies(sourcefile=sourcefile,globals=globals)
|
|
|
|
+ for dependency in internal_deps_list:
|
|
|
|
+ migrate(dependency, globals, parent_file=sourcefile)
|
|
|
|
+ file_name = write_migration(sourcefile, external_deps_list, target_deps_per_file.get(sourcefile), globals)
|
|
|
|
+ target_deps_per_file[parent_file].append(file_name)
|
|
|
|
+
|
|
|
|
+ migrate(sourceentry, globals)
|
|
|
|
+```
|
|
|
|
+
|
|
|
|
+仔细看发现 migrate 采用了递归,
|
|
|
|
+
|
|
|
|
+```
|
|
|
|
+ external_deps_prompt_template = prompt_constructor(HIERARCHY, GUIDELINES, GET_EXTERNAL_DEPS)
|
|
|
|
+
|
|
|
|
+```
|
|
|
|
+这里 prompt 发生了变化,GET_EXTERNAL_DEPS
|