ultralytics-actions 0.0.56__tar.gz → 0.0.57__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (21) hide show
  1. {ultralytics_actions-0.0.56 → ultralytics_actions-0.0.57}/PKG-INFO +3 -2
  2. {ultralytics_actions-0.0.56 → ultralytics_actions-0.0.57}/actions/__init__.py +1 -1
  3. {ultralytics_actions-0.0.56 → ultralytics_actions-0.0.57}/actions/update_markdown_code_blocks.py +77 -32
  4. {ultralytics_actions-0.0.56 → ultralytics_actions-0.0.57}/ultralytics_actions.egg-info/PKG-INFO +3 -2
  5. {ultralytics_actions-0.0.56 → ultralytics_actions-0.0.57}/LICENSE +0 -0
  6. {ultralytics_actions-0.0.56 → ultralytics_actions-0.0.57}/README.md +0 -0
  7. {ultralytics_actions-0.0.56 → ultralytics_actions-0.0.57}/actions/first_interaction.py +0 -0
  8. {ultralytics_actions-0.0.56 → ultralytics_actions-0.0.57}/actions/summarize_pr.py +0 -0
  9. {ultralytics_actions-0.0.56 → ultralytics_actions-0.0.57}/actions/summarize_release.py +0 -0
  10. {ultralytics_actions-0.0.56 → ultralytics_actions-0.0.57}/actions/utils/__init__.py +0 -0
  11. {ultralytics_actions-0.0.56 → ultralytics_actions-0.0.57}/actions/utils/common_utils.py +0 -0
  12. {ultralytics_actions-0.0.56 → ultralytics_actions-0.0.57}/actions/utils/github_utils.py +0 -0
  13. {ultralytics_actions-0.0.56 → ultralytics_actions-0.0.57}/actions/utils/openai_utils.py +0 -0
  14. {ultralytics_actions-0.0.56 → ultralytics_actions-0.0.57}/pyproject.toml +0 -0
  15. {ultralytics_actions-0.0.56 → ultralytics_actions-0.0.57}/setup.cfg +0 -0
  16. {ultralytics_actions-0.0.56 → ultralytics_actions-0.0.57}/tests/test_urls.py +0 -0
  17. {ultralytics_actions-0.0.56 → ultralytics_actions-0.0.57}/ultralytics_actions.egg-info/SOURCES.txt +0 -0
  18. {ultralytics_actions-0.0.56 → ultralytics_actions-0.0.57}/ultralytics_actions.egg-info/dependency_links.txt +0 -0
  19. {ultralytics_actions-0.0.56 → ultralytics_actions-0.0.57}/ultralytics_actions.egg-info/entry_points.txt +0 -0
  20. {ultralytics_actions-0.0.56 → ultralytics_actions-0.0.57}/ultralytics_actions.egg-info/requires.txt +0 -0
  21. {ultralytics_actions-0.0.56 → ultralytics_actions-0.0.57}/ultralytics_actions.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: ultralytics-actions
3
- Version: 0.0.56
3
+ Version: 0.0.57
4
4
  Summary: Ultralytics Actions for GitHub automation and PR management.
5
5
  Author-email: Glenn Jocher <glenn.jocher@ultralytics.com>
6
6
  Maintainer-email: Ultralytics <hello@ultralytics.com>
@@ -33,6 +33,7 @@ Requires-Dist: ruff>=0.9.1
33
33
  Requires-Dist: docformatter>=1.7.5
34
34
  Provides-Extra: dev
35
35
  Requires-Dist: pytest; extra == "dev"
36
+ Dynamic: license-file
36
37
 
37
38
  <a href="https://www.ultralytics.com/" target="_blank"><img src="https://raw.githubusercontent.com/ultralytics/assets/main/logo/Ultralytics_Logotype_Original.svg" width="320" alt="Ultralytics logo"></a>
38
39
 
@@ -22,4 +22,4 @@
22
22
  # ├── test_summarize_pr.py
23
23
  # └── ...
24
24
 
25
- __version__ = "0.0.56"
25
+ __version__ = "0.0.57"
@@ -8,10 +8,16 @@ from pathlib import Path
8
8
 
9
9
 
10
10
  def extract_code_blocks(markdown_content):
11
- """Extracts Python code blocks from markdown content using regex pattern matching."""
12
- pattern = r"^( *)```(?:python|py|\{[ ]*\.py[ ]*\.annotate[ ]*\})\n(.*?)\n\1```"
13
- code_block_pattern = re.compile(pattern, re.DOTALL | re.MULTILINE)
14
- return code_block_pattern.findall(markdown_content)
11
+ """Extracts Python and Bash code blocks from markdown content using regex pattern matching."""
12
+ # Python code blocks
13
+ py_pattern = r"^( *)```(?:python|py|\{[ ]*\.py[ ]*\.annotate[ ]*\})\n(.*?)\n\1```"
14
+ py_code_blocks = re.compile(py_pattern, re.DOTALL | re.MULTILINE).findall(markdown_content)
15
+
16
+ # Bash code blocks
17
+ bash_pattern = r"^( *)```(?:bash|sh|shell)\n(.*?)\n\1```"
18
+ bash_code_blocks = re.compile(bash_pattern, re.DOTALL | re.MULTILINE).findall(markdown_content)
19
+
20
+ return {"python": py_code_blocks, "bash": bash_code_blocks}
15
21
 
16
22
 
17
23
  def remove_indentation(code_block, num_spaces):
@@ -89,31 +95,62 @@ def format_code_with_ruff(temp_dir):
89
95
  print(f"ERROR running docformatter ❌ {e}")
90
96
 
91
97
 
92
- def generate_temp_filename(file_path, index):
93
- """Generates a unique temporary filename using a hash of the file path and index."""
94
- unique_string = f"{file_path.parent}_{file_path.stem}_{index}"
95
- unique_hash = hashlib.md5(unique_string.encode()).hexdigest()
96
- return f"temp_{unique_hash}.py"
98
+ def format_bash_with_prettier(temp_dir):
99
+ """Formats bash script files in the specified directory using prettier."""
100
+ try:
101
+ # Run prettier with explicit config path
102
+ result = subprocess.run(
103
+ "npx prettier --write --plugin=$(npm root -g)/prettier-plugin-sh/lib/index.cjs ./**/*.sh",
104
+ shell=True, # must use shell=True to expand internal $(cmd)
105
+ capture_output=True,
106
+ text=True,
107
+ )
108
+ if result.returncode != 0:
109
+ print(f"ERROR running prettier-plugin-sh ❌ {result.stderr}")
110
+ else:
111
+ print("Completed bash formatting ✅")
112
+ except Exception as e:
113
+ print(f"ERROR running prettier-plugin-sh ❌ {e}")
114
+
115
+
116
+ def generate_temp_filename(file_path, index, code_type):
117
+ """Creates unique temp filename with full path info for debugging."""
118
+ stem = file_path.stem
119
+ code_letter = code_type[0] # 'p' for python, 'b' for bash
120
+ path_part = str(file_path.parent).replace("/", "_").replace("\\", "_").replace(" ", "-")
121
+ hash_val = hashlib.md5(f"{file_path}_{index}".encode()).hexdigest()[:6]
122
+ ext = ".py" if code_type == "python" else ".sh"
123
+ filename = f"{stem}_{path_part}_{code_letter}{index}_{hash_val}{ext}"
124
+ return re.sub(r"[^\w\-.]", "_", filename)
97
125
 
98
126
 
99
- def process_markdown_file(file_path, temp_dir, verbose=False):
100
- """Processes a markdown file, extracting Python code blocks for formatting and updating the original file."""
127
+ def process_markdown_file(file_path, temp_dir, process_python=True, process_bash=True, verbose=False):
128
+ """Processes a markdown file, extracting code blocks for formatting and updating the original file."""
101
129
  try:
102
130
  markdown_content = Path(file_path).read_text()
103
- code_blocks = extract_code_blocks(markdown_content)
131
+ code_blocks_by_type = extract_code_blocks(markdown_content)
104
132
  temp_files = []
105
133
 
106
- for i, (num_spaces, code_block) in enumerate(code_blocks):
107
- if verbose:
108
- print(f"Extracting code block {i} from {file_path}")
109
- num_spaces = len(num_spaces)
110
- code_without_indentation = remove_indentation(code_block, num_spaces)
134
+ # Process all code block types based on flags
135
+ code_types = []
136
+ if process_python:
137
+ code_types.append(("python", 0))
138
+ if process_bash:
139
+ code_types.append(("bash", 1000))
140
+
141
+ for code_type, offset in code_types:
142
+ for i, (num_spaces, code_block) in enumerate(code_blocks_by_type[code_type]):
143
+ if verbose:
144
+ print(f"Extracting {code_type} code block {i} from {file_path}")
145
+
146
+ num_spaces = len(num_spaces)
147
+ code_without_indentation = remove_indentation(code_block, num_spaces)
148
+ temp_file_path = temp_dir / generate_temp_filename(file_path, i + offset, code_type)
111
149
 
112
- # Generate a unique temp file path
113
- temp_file_path = temp_dir / generate_temp_filename(file_path, i)
114
- with open(temp_file_path, "w") as temp_file:
115
- temp_file.write(code_without_indentation)
116
- temp_files.append((num_spaces, code_block, temp_file_path))
150
+ with open(temp_file_path, "w") as temp_file:
151
+ temp_file.write(code_without_indentation)
152
+
153
+ temp_files.append((num_spaces, code_block, temp_file_path, code_type))
117
154
 
118
155
  return markdown_content, temp_files
119
156
 
@@ -123,15 +160,18 @@ def process_markdown_file(file_path, temp_dir, verbose=False):
123
160
 
124
161
 
125
162
  def update_markdown_file(file_path, markdown_content, temp_files):
126
- """Updates a markdown file with formatted Python code blocks extracted and processed externally."""
127
- for num_spaces, original_code_block, temp_file_path in temp_files:
163
+ """Updates a markdown file with formatted code blocks."""
164
+ for num_spaces, original_code_block, temp_file_path, code_type in temp_files:
128
165
  try:
129
166
  with open(temp_file_path) as temp_file:
130
167
  formatted_code = temp_file.read().rstrip("\n") # Strip trailing newlines
131
168
  formatted_code_with_indentation = add_indentation(formatted_code, num_spaces)
132
169
 
133
- # Replace both `python` and `py` code blocks
134
- for lang in ["python", "py", "{ .py .annotate }"]:
170
+ # Define the language tags for each code type
171
+ lang_tags = {"python": ["python", "py", "{ .py .annotate }"], "bash": ["bash", "sh", "shell"]}
172
+
173
+ # Replace the code blocks with the formatted version
174
+ for lang in lang_tags[code_type]:
135
175
  markdown_content = markdown_content.replace(
136
176
  f"{' ' * num_spaces}```{lang}\n{original_code_block}\n{' ' * num_spaces}```",
137
177
  f"{' ' * num_spaces}```{lang}\n{formatted_code_with_indentation}\n{' ' * num_spaces}```",
@@ -146,8 +186,8 @@ def update_markdown_file(file_path, markdown_content, temp_files):
146
186
  print(f"Error writing file {file_path}: {e}")
147
187
 
148
188
 
149
- def main(root_dir=Path.cwd(), verbose=False):
150
- """Processes markdown files, extracts and formats Python code blocks, and updates the original files."""
189
+ def main(root_dir=Path.cwd(), process_python=True, process_bash=True, verbose=False):
190
+ """Processes markdown files, extracts and formats code blocks, and updates the original files."""
151
191
  root_path = Path(root_dir)
152
192
  markdown_files = list(root_path.rglob("*.md"))
153
193
  temp_dir = Path("temp_code_blocks")
@@ -158,12 +198,17 @@ def main(root_dir=Path.cwd(), verbose=False):
158
198
  for markdown_file in markdown_files:
159
199
  if verbose:
160
200
  print(f"Processing {markdown_file}")
161
- markdown_content, temp_files = process_markdown_file(markdown_file, temp_dir, verbose)
201
+ markdown_content, temp_files = process_markdown_file(
202
+ markdown_file, temp_dir, process_python, process_bash, verbose
203
+ )
162
204
  if markdown_content and temp_files:
163
205
  all_temp_files.append((markdown_file, markdown_content, temp_files))
164
206
 
165
- # Format all code blocks with ruff
166
- format_code_with_ruff(temp_dir)
207
+ # Format code blocks based on flags
208
+ if process_python:
209
+ format_code_with_ruff(temp_dir) # Format Python files
210
+ if process_bash:
211
+ format_bash_with_prettier(temp_dir) # Format Bash files
167
212
 
168
213
  # Update markdown files with formatted code blocks
169
214
  for markdown_file, markdown_content, temp_files in all_temp_files:
@@ -174,4 +219,4 @@ def main(root_dir=Path.cwd(), verbose=False):
174
219
 
175
220
 
176
221
  if __name__ == "__main__":
177
- main()
222
+ main(process_python=True, process_bash=False)
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: ultralytics-actions
3
- Version: 0.0.56
3
+ Version: 0.0.57
4
4
  Summary: Ultralytics Actions for GitHub automation and PR management.
5
5
  Author-email: Glenn Jocher <glenn.jocher@ultralytics.com>
6
6
  Maintainer-email: Ultralytics <hello@ultralytics.com>
@@ -33,6 +33,7 @@ Requires-Dist: ruff>=0.9.1
33
33
  Requires-Dist: docformatter>=1.7.5
34
34
  Provides-Extra: dev
35
35
  Requires-Dist: pytest; extra == "dev"
36
+ Dynamic: license-file
36
37
 
37
38
  <a href="https://www.ultralytics.com/" target="_blank"><img src="https://raw.githubusercontent.com/ultralytics/assets/main/logo/Ultralytics_Logotype_Original.svg" width="320" alt="Ultralytics logo"></a>
38
39