Update and add new actions in auto_command workflow

- Renamed and updated the get_project_tree action to use a Python handler.
- Added a new action load_file to load file content with a Python handler.
- Renamed and updated the new_document action to new_file with a Python handler.
- Added a new action search_text to search text in all files within the project.
- Removed the old load_file action from the extension_demo workflow.
This commit is contained in:
bobo.yang 2023-08-09 00:16:03 +08:00
parent 27bece07dc
commit c794e27c02
9 changed files with 206 additions and 22 deletions

View File

@ -1,9 +1,9 @@
{
"name": "get_project_tree",
"description": "Get project file list",
"description": "Get project file list.",
"type": ["project"],
"action": "get_project_tree",
"args": [
],
"handler": ["git", "ls-files"]
"handler": ["python", "${CurDir}/handler.py"]
}

View File

@ -0,0 +1,25 @@
"""
get project files by "git ls-files" command
如果项目文件数超出100那么结束执行退出码为1并且输出英文文件数太多需要通过ls命令逐层查看各个目录中的文件目录结构信息
"""
import subprocess
import sys
def get_project_tree():
"""
Get project files by "git ls-files" command
"""
try:
output = subprocess.check_output(["git", "ls-files"]).decode("utf-8").split("\n")
if len(output) > 100:
sys.stderr.write("Error: Too many files, you need to view the files and directory structure in each directory through the 'ls' command.\n")
sys.exit(1)
return output
except Exception as e:
sys.stderr.write(f"Error: {str(e)}\n")
sys.exit(1)
if __name__ == "__main__":
print(get_project_tree())
sys.exit(0)

View File

@ -0,0 +1,27 @@
{
"name": "load_file",
"description": "Load text file content.",
"type": ["file"],
"action": "load_file",
"args": [
{
"name": "fileName",
"description": "Specify the file, which content will be loaded",
"type": "string",
"from": "content.content.fileName"
},
{
"name": "startLine",
"description": "Specify the start line of content. It is not required if load the whole file.",
"type": "string",
"from": "content.content.startLine"
},
{
"name": "endLine",
"description": "Specify the end line of content. It is not required if load the whole file.",
"type": "string",
"from": "content.content.endLine"
}
],
"handler": ["python", "${CurDir}/handler.py", "${fileName}", "${startLine}", "${endLine}"]
}

View File

@ -0,0 +1,33 @@
"""
Load content in file.
"""
import sys
def load_file_content(file_name, start_line=0, end_line=1000):
"""
Load content in file from start_line to end_line.
If start_line and end_line are not provided, load the whole file.
"""
try:
with open(file_name, 'r') as file:
lines = file.readlines()
if start_line < 0 or end_line <= start_line:
sys.stderr.write("Error: start line must be greater than or equal to 0 and end line must be greater than start line.\n")
sys.exit(1)
content = "".join(lines[int(start_line):int(end_line)])
if len(content.split('\n')) > 500:
sys.stderr.write("Error: The content is too large, please set a reasonable reading range.\n")
sys.exit(1)
return content
except Exception as e:
sys.stderr.write(f"Error: {str(e)}\n")
sys.exit(1)
if __name__ == "__main__":
file_name = sys.argv[1]
start_line = int(sys.argv[2]) if sys.argv[2] != '${startLine}' else 0
end_line = int(sys.argv[3]) if sys.argv[3] != '${endLine}' else 1000
print(load_file_content(file_name, start_line, end_line))
sys.exit(0)

View File

@ -20,9 +20,5 @@
}
],
"action": "new_file",
"handler": [
"cp",
"${content}",
"${fileName}"
]
"handler": ["python", "${CurDir}/handler.py", "${content}", "${fileName}"]
}

View File

@ -0,0 +1,29 @@
"""
Create new file.
arg:
content: current file name with content
fileName: new file name.
Rename content to fileName.
"""
import os
import sys
import shutil
def create_new_file(content_file, new_file):
"""
Create new file or replace file with new content.
"""
try:
if os.path.exists(new_file):
os.remove(new_file)
shutil.move(content_file, new_file)
except Exception as e:
sys.stderr.write(f"Error: {str(e)}\n")
sys.exit(1)
if __name__ == "__main__":
content_file = sys.argv[1]
new_file = sys.argv[2]
create_new_file(content_file, new_file)
sys.exit(0)

View File

@ -0,0 +1,23 @@
{
"name": "search_text",
"description": "Search text in all files within project. Search text with match whole word. Text search is an alternative to finding symbol references, mainly for scenarios where symbol references cannot be used, such as searching for references to a specific string.",
"type": ["none"],
"args": [{
"name": "text",
"description": "text to search",
"type": "string",
"from": "content.content.text"
}, {
"name": "include_files",
"description": "search text within setting include files, support multi pattern. The parameter format is based on the corresponding configuration in vscode search.",
"type": "string",
"from": "content.content.include_files"
}, {
"name": "exclude_files",
"description": "search text not within setting exclude files, support multi pattern. The parameter format is based on the corresponding configuration in vscode search.",
"type": "string",
"from": "content.content.exclude_files"
}],
"action": "search_text",
"handler": ["python", "${CurDir}/handler.py", "${text}", "${include_files}", "${exclude_files}"]
}

View File

@ -0,0 +1,66 @@
"""
Search text in all files within project. Search text with match whole word mode.
"""
import sys
import os
import fnmatch
import re
def search_text(text, include_files=None, exclude_files=None):
"""
Search text in all files within project. Search text with match whole word mode.
"""
# Get the current working directory
cwd = os.getcwd()
# Prepare the include and exclude patterns
include_patterns = include_files.split(',') if include_files else ['*']
exclude_patterns = exclude_files.split(',') if exclude_files else []
# Initialize a flag to check if the text is found
found = 0
# Walk through the directory
search_result = []
for dirpath, dirnames, filenames in os.walk(cwd):
for filename in filenames:
filename = os.path.join(dirpath, filename)
relFileName = os.path.relpath(filename, cwd)
# Check if the file matches any of the include patterns
if any(fnmatch.fnmatch(relFileName, pattern) for pattern in include_patterns):
# Check if the file matches any of the exclude patterns
if not any(fnmatch.fnmatch(relFileName, pattern) for pattern in exclude_patterns):
# Open the file and search for the text
try:
with open(filename, 'r') as file:
for line_no, line in enumerate(file, 1):
if re.search(r'\b' + re.escape(text) + r'\b', line):
search_result.append(f'Found "{text}" in file {relFileName} on line {line_no-1}: {line.strip()}')
found += len(line.strip())
if (len(search_result) > 100 or found > 5000):
sys.stderr.write("The search text is too long, try to shorten it.\n")
sys.exit(1)
except Exception:
pass
# Check if the text was found
if found == 0:
sys.stderr.write("Optimize the search text content, make sure the search text exists in the file.\n")
sys.exit(1)
# Print the result
print('\n'.join(search_result))
def main():
# Get the arguments from the command line
text = sys.argv[1]
include_files = sys.argv[2] if sys.argv[2] != '${include_files}' else None
exclude_files = sys.argv[3] if sys.argv[3] != '${exclude_files}' else None
# Call the search_text function
search_text(text, include_files, exclude_files)
sys.exit(0)
if __name__ == "__main__":
main()

View File

@ -1,15 +0,0 @@
{
"name": "load_file",
"description": "Load file content",
"type": ["file"],
"action": "load_file",
"args": [
{
"name": "fileName",
"description": "Specify the file, which content will be loaded",
"type": "string",
"from": "content.content.fileName"
}
],
"handler": ["cat", "${fileName}"]
}